26126982e2
Adds a frameless window with custom title bar controls for Windows, including minimize, maximize/restore, and close buttons. Refactors theme color application to use CSS variables and color-mix for improved consistency and dynamic theming across home, settings, and main UI. Updates renderer and styles to support the new title bar, platform detection, and improved color handling. No changes to lock files.
763 lines
21 KiB
CSS
763 lines
21 KiB
CSS
html, body {
|
|
height: 100%;
|
|
margin: 0;
|
|
padding: 0;
|
|
/* Background now driven by theme */
|
|
background: var(--bg, #0b0d10);
|
|
color: var(--text, white);
|
|
font-family: 'Segoe UI', system-ui, -apple-system, Ubuntu, Roboto, sans-serif;
|
|
}
|
|
|
|
/* Global variables */
|
|
:root {
|
|
/* Space reserved on the left for system window controls (traffic lights on macOS).
|
|
Applied cross-platform per request to keep a consistent layout. */
|
|
--window-controls-offset: 80px; /* adjust if needed */
|
|
/* Space reserved on the right for Windows title bar controls */
|
|
--window-controls-width: 138px;
|
|
|
|
/* Design tokens */
|
|
--bg: #0b0d10;
|
|
--surface-1: #11131a;
|
|
--surface-2: #161925;
|
|
--surface-3: #1c2030;
|
|
--text: #e8e8f0;
|
|
--muted: #a4a7b3;
|
|
--outline: #2b3040;
|
|
--radius-sm: 8px;
|
|
--radius-md: 12px;
|
|
--radius-lg: 16px;
|
|
--shadow-1: 0 6px 20px rgba(0,0,0,.35);
|
|
--shadow-2: 0 12px 36px rgba(0,0,0,.45);
|
|
--blur: 12px;
|
|
/* Accent palette */
|
|
--accent-h: 265;
|
|
--accent-s: 86%;
|
|
--accent-l: 62%;
|
|
--accent: hsl(var(--accent-h) var(--accent-s) var(--accent-l));
|
|
--accent-600: hsl(var(--accent-h) var(--accent-s) 52%);
|
|
--accent-700: hsl(var(--accent-h) var(--accent-s) 46%);
|
|
|
|
/* URL bar and tab theme colors (defaults) */
|
|
--url-bar-bg: #1C2030;
|
|
--url-bar-text: #E0E0E0;
|
|
--url-bar-border: #3E4652;
|
|
--tab-bg: #161925;
|
|
--tab-text: #A4A7B3;
|
|
--tab-active: #1C2030;
|
|
--tab-active-text: #E0E0E0;
|
|
--tab-border: #2B3040;
|
|
}
|
|
|
|
/* TITLEBAR CONTAINER - holds tab bar and window controls */
|
|
#titlebar-container {
|
|
display: flex;
|
|
position: relative;
|
|
background: var(--tab-bg);
|
|
-webkit-app-region: drag;
|
|
}
|
|
|
|
/* TAB STRIP */
|
|
#tab-bar {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
gap: 2px;
|
|
flex: 1;
|
|
/* Default: small left padding for Windows/Linux (no traffic lights) */
|
|
padding: 6px 10px 0 10px;
|
|
background: var(--tab-bg);
|
|
border-bottom: 1px solid var(--tab-border);
|
|
overflow-x: auto; /* scroll when many tabs */
|
|
scrollbar-color: #444 #2a2a3c; /* thumb and track for Firefox */
|
|
scrollbar-width: thin; /* slimmer track */
|
|
/* Inherit drag from container */
|
|
-webkit-app-region: drag;
|
|
min-height: 38px;
|
|
}
|
|
|
|
/* NAVBAR LAYOUT */
|
|
#nav {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 10px 12px;
|
|
background: var(--url-bar-bg);
|
|
gap: 12px;
|
|
/* flatter header to reduce paint cost */
|
|
box-shadow: none;
|
|
/* Ensure the nav sits above embedded <webview> surfaces */
|
|
position: relative;
|
|
z-index: 10000;
|
|
-webkit-backdrop-filter: blur(var(--blur));
|
|
backdrop-filter: blur(var(--blur));
|
|
border-bottom: 1px solid var(--url-bar-border);
|
|
}
|
|
|
|
/* Make the top nav a draggable region on macOS when we use a hidden titlebar.
|
|
Interactive controls inside must opt-out with -webkit-app-region: no-drag. */
|
|
@supports (-webkit-app-region: drag) {
|
|
/* Make the top nav a draggable region, but only in its background/gaps. */
|
|
#nav { -webkit-app-region: drag; user-select: none; }
|
|
|
|
/* Interactive controls must explicitly opt-out of dragging. This keeps
|
|
the larger draggable area while preserving normal click behavior. */
|
|
#nav button,
|
|
#nav input,
|
|
#menu-popup,
|
|
.tab,
|
|
.tab *,
|
|
.new-tab-button,
|
|
.tab .tab-close,
|
|
#window-controls {
|
|
-webkit-app-region: no-drag;
|
|
}
|
|
|
|
/* Ensure the new-tab button (which sits on the tab strip) is not draggable */
|
|
#tab-bar .new-tab-button {
|
|
-webkit-app-region: no-drag;
|
|
}
|
|
}
|
|
|
|
.nav-left,
|
|
.nav-center,
|
|
.nav-right {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.nav-center {
|
|
flex: 1;
|
|
padding: 6px 10px;
|
|
border-radius: 999px; /* pill */
|
|
/* glassy, accented border */
|
|
background: var(--url-bar-bg);
|
|
border: 1px solid var(--url-bar-border);
|
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.04);
|
|
}
|
|
|
|
#favicon {
|
|
width: 16px;
|
|
height: 16px;
|
|
margin-right: 4px;
|
|
}
|
|
|
|
#url {
|
|
flex: 1;
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--url-bar-text);
|
|
font-size: 14px;
|
|
outline: none;
|
|
}
|
|
|
|
#url::placeholder {
|
|
color: rgba(255, 255, 255, 0.45);
|
|
}
|
|
|
|
/* Iconic circular chrome buttons */
|
|
.nav-left button,
|
|
.nav-right > button,
|
|
#reload-btn,
|
|
#menu-btn {
|
|
background: color-mix(in srgb, var(--url-bar-bg) 90%, var(--text) 10%);
|
|
color: var(--text);
|
|
border: 1px solid color-mix(in srgb, var(--text) 15%, transparent);
|
|
width: 34px;
|
|
height: 34px;
|
|
display: inline-grid;
|
|
place-items: center;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
/* subtle inner highlight adds edge definition */
|
|
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 8%, transparent);
|
|
transition: transform 120ms ease, box-shadow 120ms ease, filter 120ms ease;
|
|
line-height: 0; /* avoid vertical misalignment for glyphs */
|
|
padding: 0;
|
|
}
|
|
|
|
#downloads-btn svg { display:block; width: 18px; height: 18px; }
|
|
|
|
/* Downloads button chrome to match other nav buttons */
|
|
#downloads-btn {
|
|
background: color-mix(in srgb, var(--url-bar-bg) 90%, var(--text) 10%);
|
|
color: var(--text);
|
|
border: 1px solid color-mix(in srgb, var(--text) 15%, transparent);
|
|
width: 34px;
|
|
height: 34px;
|
|
display: inline-grid;
|
|
place-items: center;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 8%, transparent);
|
|
transition: transform 120ms ease, box-shadow 120ms ease, filter 120ms ease, color 120ms ease;
|
|
line-height: 0;
|
|
padding: 0;
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
}
|
|
#downloads-btn:hover { filter: brightness(1.05); box-shadow: 0 4px 14px rgba(0,0,0,0.35); color: var(--text); }
|
|
#downloads-btn:active { transform: translateY(1px) scale(0.98); }
|
|
#downloads-btn:focus-visible { outline: none; box-shadow: 0 0 0 2px rgba(123, 97, 255, 0.55); }
|
|
#downloads-btn:focus { outline: none; box-shadow: none; }
|
|
|
|
/* Match home-active chrome variant */
|
|
body:has(#home-container.active) #downloads-btn {
|
|
background: color-mix(in srgb, var(--url-bar-bg) 85%, var(--text) 15%);
|
|
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 10%, transparent);
|
|
}
|
|
|
|
.nav-left button:hover,
|
|
.nav-right > button:hover,
|
|
#reload-btn:hover,
|
|
#menu-btn:hover {
|
|
filter: brightness(1.05);
|
|
box-shadow: 0 4px 14px color-mix(in srgb, var(--bg) 50%, transparent);
|
|
}
|
|
|
|
.nav-left button:active,
|
|
.nav-right > button:active,
|
|
#reload-btn:active,
|
|
#menu-btn:active {
|
|
transform: translateY(1px) scale(0.98);
|
|
}
|
|
|
|
/* Primary action (Go button) keeps rectangular look but modernized */
|
|
.nav-center + button,
|
|
.nav-center button {
|
|
background: var(--accent);
|
|
color: var(--text);
|
|
border: 1px solid transparent;
|
|
padding: 8px 14px;
|
|
border-radius: 10px;
|
|
cursor: pointer;
|
|
transition: transform 120ms ease, box-shadow 120ms ease, filter 120ms ease;
|
|
}
|
|
.nav-center + button:hover,
|
|
.nav-center button:hover { box-shadow: 0 8px 20px color-mix(in srgb, var(--primary) 35%, transparent); }
|
|
.nav-center + button:active,
|
|
.nav-center button:active { transform: translateY(1px) scale(0.98); }
|
|
|
|
/* MENU DROPDOWN */
|
|
.menu-wrapper {
|
|
position: relative;
|
|
/* keep wrapper on a higher layer so absolute popup can composit above webviews */
|
|
z-index: 10001;
|
|
}
|
|
|
|
#menu-popup {
|
|
position: absolute;
|
|
top: 30px;
|
|
right: 0;
|
|
background: color-mix(in srgb, var(--url-bar-bg) 92%, var(--text) 8%);
|
|
border: 1px solid color-mix(in srgb, var(--primary) 25%, color-mix(in srgb, var(--accent) 18%, transparent));
|
|
border-radius: 14px;
|
|
padding: 8px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-width: 200px; /* wider dropdown */
|
|
box-shadow: var(--shadow-1);
|
|
/* Much higher z-index and force its own compositing layer so it renders above <webview> guests */
|
|
z-index: 20000;
|
|
-webkit-transform: translateZ(0);
|
|
transform: translateZ(0);
|
|
will-change: transform, opacity;
|
|
/* animated open/close */
|
|
opacity: 1;
|
|
transform-origin: top right;
|
|
transition: opacity 160ms ease, transform 160ms ease;
|
|
/* ensure interactions only when visible */
|
|
visibility: visible;
|
|
pointer-events: auto;
|
|
-webkit-backdrop-filter: blur(var(--blur));
|
|
backdrop-filter: blur(var(--blur));
|
|
}
|
|
|
|
#menu-popup button {
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text);
|
|
text-align: left;
|
|
padding: 8px 10px;
|
|
border-radius: 10px;
|
|
transition: background 120ms ease, filter 120ms ease;
|
|
}
|
|
|
|
#menu-popup button:hover {
|
|
background: color-mix(in srgb, var(--text) 8%, transparent);
|
|
}
|
|
|
|
/* Big Picture Mode button special style */
|
|
#bigpicture-btn {
|
|
background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 15%, transparent) 0%, color-mix(in srgb, var(--accent) 10%, transparent) 100%) !important;
|
|
border: 1px solid color-mix(in srgb, var(--primary) 30%, transparent) !important;
|
|
margin: 4px 0;
|
|
}
|
|
|
|
#bigpicture-btn:hover {
|
|
background: linear-gradient(135deg, rgba(123, 46, 255, 0.25) 0%, rgba(0, 198, 255, 0.15) 100%) !important;
|
|
border-color: rgba(123, 46, 255, 0.5) !important;
|
|
}
|
|
|
|
.hidden {
|
|
display: none;
|
|
}
|
|
|
|
/* Animate menu dropdown instead of removing from flow */
|
|
#menu-popup.hidden {
|
|
display: block; /* override global .hidden */
|
|
opacity: 0;
|
|
transform: translateY(-8px) scale(0.98);
|
|
visibility: hidden;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* Downloads mini popup anchored to the downloads button */
|
|
.downloads-wrapper { position: relative; z-index: 10002; }
|
|
#downloads-popup {
|
|
position: absolute;
|
|
top: 34px;
|
|
right: 0;
|
|
background: color-mix(in srgb, var(--url-bar-bg) 95%, var(--text) 5%);
|
|
border: 1px solid color-mix(in srgb, var(--primary) 18%, color-mix(in srgb, var(--accent) 14%, transparent));
|
|
border-radius: 12px;
|
|
min-width: 280px;
|
|
box-shadow: var(--shadow-1);
|
|
padding: 8px;
|
|
-webkit-backdrop-filter: blur(var(--blur));
|
|
backdrop-filter: blur(var(--blur));
|
|
transition: opacity 160ms ease, transform 160ms ease;
|
|
}
|
|
#downloads-popup.hidden { opacity: 0; transform: translateY(-6px); visibility: hidden; pointer-events: none; }
|
|
.downloads-pop-header { display:flex; align-items:center; justify-content:space-between; gap:8px; padding:4px 2px 8px; }
|
|
.downloads-pop-header > span { font-weight: 600; color: var(--text); }
|
|
.downloads-pop-header > button { background: transparent; border: none; color: var(--accent); cursor: pointer; }
|
|
.downloads-pop-list { display:flex; flex-direction: column; gap: 8px; max-height: 280px; overflow: auto; }
|
|
.downloads-empty { color: var(--tab-text); font-size: 12px; text-align: center; padding: 16px 8px; }
|
|
.dl-item { display:grid; grid-template-columns: 1fr auto; gap: 6px 8px; background: color-mix(in srgb, var(--text) 3%, transparent); border: 1px solid color-mix(in srgb, var(--text) 6%, transparent); border-radius: 10px; padding: 8px; }
|
|
.dl-file { font-size: 12px; color: var(--text); white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }
|
|
.dl-meta { font-size: 11px; color: var(--tab-text); }
|
|
.dl-actions { display:flex; gap:6px; }
|
|
.dl-actions button { background: transparent; color: var(--text); border: 1px solid color-mix(in srgb, var(--text) 12%, transparent); border-radius: 8px; padding: 4px 8px; cursor: pointer; }
|
|
.dl-progress { height: 4px; background: color-mix(in srgb, var(--text) 8%, transparent); border-radius: 3px; overflow: hidden; grid-column: 1 / -1; }
|
|
.dl-bar { height: 100%; background: var(--accent); width: 0%; transition: width .12s linear; }
|
|
|
|
/* Circular progress ring around downloads button */
|
|
#downloads-btn { position: relative; }
|
|
#downloads-btn .ring {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
width: 40px; /* slightly larger than 34px button for halo */
|
|
height: 40px;
|
|
transform: translate(-50%, -50%);
|
|
border-radius: 50%;
|
|
pointer-events: none;
|
|
}
|
|
#downloads-btn .ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
|
|
#downloads-btn .ring circle.bg { stroke: color-mix(in srgb, var(--text) 15%, transparent); stroke-width: 3; fill: none; }
|
|
#downloads-btn .ring circle.fg { stroke: var(--accent); stroke-width: 3; fill: none; stroke-linecap: round; transition: stroke-dashoffset .12s linear, opacity .12s ease; }
|
|
|
|
/* WEBVIEWS */
|
|
#webviews {
|
|
flex: 1;
|
|
display: flex;
|
|
width: 100%;
|
|
position: relative;
|
|
/* make sure webviews render on a separate base layer behind nav */
|
|
z-index: 0;
|
|
}
|
|
#webviews.hidden {
|
|
display: none;
|
|
}
|
|
|
|
#webviews webview {
|
|
flex: 1;
|
|
width: 100%;
|
|
height: 100%;
|
|
border: none;
|
|
display: none;
|
|
}
|
|
#webviews webview.active {
|
|
display: flex;
|
|
}
|
|
/* When webviews is hidden, collapse its flex size */
|
|
#webviews.hidden {
|
|
flex: 0;
|
|
}
|
|
|
|
/* HOME CONTAINER */
|
|
#home-container {
|
|
flex: 1;
|
|
display: none;
|
|
width: 100%;
|
|
position: relative;
|
|
z-index: 0;
|
|
}
|
|
|
|
#home-container.active {
|
|
display: flex;
|
|
}
|
|
|
|
#home-webview {
|
|
width: 100%;
|
|
height: 100%;
|
|
border: none;
|
|
display: none;
|
|
flex: 1;
|
|
position: relative;
|
|
z-index: 0;
|
|
}
|
|
/* Show home webview when container is active */
|
|
#home-container.active > #home-webview {
|
|
display: flex;
|
|
}
|
|
|
|
/* TABS */
|
|
.tab {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
-webkit-app-region: no-drag; /* allow HTML5 DnD to work */
|
|
padding: 4px 10px; /* slimmer padding */
|
|
margin: 0;
|
|
height: 28px; /* reduce overall tab height */
|
|
color: var(--tab-text);
|
|
/* sleek glass tile */
|
|
background: var(--tab-bg);
|
|
border: 1px solid var(--tab-border);
|
|
border-bottom: none; /* let it visually merge with the strip line */
|
|
border-radius: 10px 10px 0 0; /* slightly tighter radius */
|
|
cursor: pointer;
|
|
user-select: none;
|
|
max-width: 260px;
|
|
min-width: 120px;
|
|
flex: 0 1 180px; /* like Chrome: shrink when crowded */
|
|
overflow: hidden;
|
|
transition: background 120ms ease, color 120ms ease, box-shadow 120ms ease;
|
|
}
|
|
|
|
.tab:hover {
|
|
background: var(--tab-bg);
|
|
opacity: 0.85;
|
|
}
|
|
|
|
.tab.active {
|
|
color: var(--tab-active-text);
|
|
background: var(--tab-active);
|
|
box-shadow: 0 8px 22px color-mix(in srgb, var(--bg) 35%, transparent);
|
|
}
|
|
|
|
.tab.active::after {
|
|
content: "";
|
|
position: absolute;
|
|
left: 0;
|
|
right: 0;
|
|
top: 0;
|
|
height: 2px;
|
|
background: var(--accent);
|
|
}
|
|
|
|
.tab .tab-favicon {
|
|
width: 16px;
|
|
height: 16px;
|
|
border-radius: 2px;
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.tab .tab-title {
|
|
flex: 1 1 auto;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.tab .tab-close {
|
|
flex: 0 0 auto;
|
|
width: 22px;
|
|
height: 22px;
|
|
display: grid;
|
|
place-items: center;
|
|
border: none;
|
|
border-radius: 11px;
|
|
background: transparent;
|
|
color: var(--tab-text);
|
|
opacity: 0; /* hidden by default */
|
|
transition: background 120ms ease, color 120ms ease, opacity 120ms ease;
|
|
}
|
|
|
|
.tab:hover .tab-close,
|
|
.tab.active .tab-close { opacity: 1; }
|
|
.tab .tab-close:hover { background: color-mix(in srgb, var(--text) 20%, transparent); color: var(--text); }
|
|
.tab .tab-close:active { background: color-mix(in srgb, var(--text) 15%, transparent); }
|
|
|
|
/* New tab (+) button aligned to the right end of the strip */
|
|
.new-tab-button {
|
|
margin-left: 6px;
|
|
flex: 0 0 auto;
|
|
width: 26px; /* tighter button */
|
|
height: 26px;
|
|
display: grid;
|
|
place-items: center;
|
|
border-radius: 13px;
|
|
border: 1px solid color-mix(in srgb, var(--text) 18%, transparent);
|
|
background: color-mix(in srgb, var(--tab-bg) 90%, var(--text) 10%);
|
|
color: var(--text);
|
|
cursor: pointer;
|
|
transition: transform 120ms ease, background 120ms ease, color 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
|
|
}
|
|
.new-tab-button:hover { filter: brightness(1.06); box-shadow: 0 6px 16px color-mix(in srgb, var(--bg) 35%, transparent); }
|
|
.new-tab-button:active { transform: translateY(1px) scale(0.98); }
|
|
|
|
/* ZOOM CONTROLS */
|
|
.zoom-controls {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 6px 8px;
|
|
background: color-mix(in srgb, var(--text) 4%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--text) 7%, transparent);
|
|
border-radius: 10px;
|
|
}
|
|
.zoom-controls .zoom-label {
|
|
flex: 1;
|
|
font-size: 14px;
|
|
}
|
|
.zoom-controls button {
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text);
|
|
font-size: 16px;
|
|
cursor: pointer;
|
|
width: 28px;
|
|
height: 28px;
|
|
display: grid;
|
|
place-items: center;
|
|
border-radius: 8px;
|
|
transition: background 120ms ease;
|
|
}
|
|
.zoom-controls button:hover {
|
|
background: rgba(255,255,255,0.06);
|
|
}
|
|
#zoom-percent {
|
|
min-width: 38px;
|
|
text-align: center;
|
|
font-size: 13px;
|
|
color: var(--muted);
|
|
}
|
|
|
|
/* window controls (Windows/Linux only) - Firefox-style next to tabs */
|
|
#window-controls {
|
|
display: flex;
|
|
align-items: stretch;
|
|
align-self: stretch;
|
|
-webkit-app-region: no-drag;
|
|
background: transparent;
|
|
border-bottom: 1px solid var(--tab-border);
|
|
}
|
|
|
|
#window-controls button {
|
|
width: 46px;
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text);
|
|
cursor: pointer;
|
|
transition: background 120ms ease, color 120ms ease;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
-webkit-app-region: no-drag;
|
|
padding: 0;
|
|
}
|
|
|
|
#window-controls button svg {
|
|
width: 12px;
|
|
height: 12px;
|
|
pointer-events: none;
|
|
}
|
|
|
|
#window-controls button:hover {
|
|
background: rgba(255,255,255,0.1);
|
|
color: var(--text);
|
|
}
|
|
|
|
#window-controls #close-btn:hover {
|
|
background: #e81123;
|
|
color: white;
|
|
}
|
|
|
|
#window-controls #close-btn:hover svg path {
|
|
stroke: white;
|
|
}
|
|
|
|
/* Hide window controls on macOS via body class set by JS */
|
|
body.platform-darwin #window-controls {
|
|
display: none !important;
|
|
}
|
|
|
|
/* macOS: add left padding for traffic lights */
|
|
body.platform-darwin #tab-bar {
|
|
padding-left: var(--window-controls-offset);
|
|
}
|
|
|
|
#tab-bar::-webkit-scrollbar {
|
|
height: 8px; /* horizontal scrollbar height */
|
|
}
|
|
#tab-bar::-webkit-scrollbar-track {
|
|
background: #2a2a3c;
|
|
border-radius: 4px;
|
|
}
|
|
#tab-bar::-webkit-scrollbar-thumb {
|
|
background: #3f4152;
|
|
border-radius: 4px;
|
|
}
|
|
#tab-bar::-webkit-scrollbar-thumb:hover {
|
|
background: #56586a;
|
|
}
|
|
|
|
/* Tab animations */
|
|
.tab--flip {
|
|
transition: transform 180ms cubic-bezier(0.2, 0, 0, 1);
|
|
}
|
|
.tab--enter {
|
|
animation: tab-enter 160ms ease-out both;
|
|
}
|
|
.tab--closing {
|
|
animation: tab-exit 140ms ease-in both;
|
|
}
|
|
|
|
/* While dragging a tab, lift it slightly for feedback */
|
|
.tab--dragging {
|
|
transform: translateY(-2px) scale(1.04);
|
|
box-shadow: 0 10px 26px rgba(0,0,0,0.45);
|
|
z-index: 5;
|
|
transition: none !important; /* follow cursor without lag */
|
|
will-change: transform;
|
|
cursor: grabbing;
|
|
}
|
|
|
|
/* Show an insertion hint on hovered tab and nudge it */
|
|
.tab--drop-before,
|
|
.tab--drop-after {
|
|
position: relative;
|
|
}
|
|
.tab--drop-before { transform: translateX(-10px); }
|
|
.tab--drop-after { transform: translateX(10px); }
|
|
|
|
.tab--drop-before::before,
|
|
.tab--drop-after::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: 4px;
|
|
bottom: 0;
|
|
width: 2px;
|
|
border-radius: 2px;
|
|
background: linear-gradient(180deg, var(--accent), var(--accent-600));
|
|
opacity: 0.9;
|
|
}
|
|
.tab--drop-before::before { left: 0; }
|
|
.tab--drop-after::after { right: 0; }
|
|
|
|
@keyframes tab-enter {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(6px) scale(0.98);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: none;
|
|
}
|
|
}
|
|
|
|
@keyframes tab-exit {
|
|
to {
|
|
opacity: 0;
|
|
transform: translateY(-6px) scale(0.95);
|
|
}
|
|
}
|
|
|
|
/* Respect reduced motion preferences */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
* {
|
|
animation: none !important;
|
|
transition: none !important;
|
|
scroll-behavior: auto !important;
|
|
}
|
|
}
|
|
|
|
/* Focus rings for accessibility */
|
|
.nav-left button:focus-visible,
|
|
.nav-right > button:focus-visible,
|
|
#reload-btn:focus-visible,
|
|
.menu-wrapper #menu-btn:focus-visible,
|
|
.new-tab-button:focus-visible,
|
|
#menu-popup button:focus-visible,
|
|
.zoom-controls button:focus-visible,
|
|
.tab .tab-close:focus-visible,
|
|
#window-controls button:focus-visible {
|
|
outline: none;
|
|
box-shadow: 0 0 0 2px rgba(123, 97, 255, 0.55);
|
|
}
|
|
|
|
/* Keyboard-only ring around the entire address bar (input + Go) */
|
|
.nav-center:has(:focus-visible) {
|
|
box-shadow: 0 0 0 2px rgba(123, 97, 255, 0.55), inset 0 1px 0 rgba(255,255,255,0.05);
|
|
}
|
|
/* Fallback for engines without :has support */
|
|
@supports not selector(.nav-center:has(:focus-visible)) {
|
|
.nav-center:focus-within {
|
|
box-shadow: 0 0 0 2px rgba(123, 97, 255, 0.45), inset 0 1px 0 rgba(255,255,255,0.05);
|
|
}
|
|
}
|
|
|
|
/* Remove default click outline but keep keyboard focus via :focus-visible */
|
|
.nav-left button:focus,
|
|
.nav-right > button:focus,
|
|
#reload-btn:focus,
|
|
#menu-btn:focus,
|
|
#url:focus,
|
|
.nav-center button:focus,
|
|
.new-tab-button:focus,
|
|
#menu-popup button:focus,
|
|
.zoom-controls button:focus,
|
|
.tab .tab-close:focus,
|
|
#window-controls button:focus {
|
|
outline: none;
|
|
box-shadow: none;
|
|
}
|
|
|
|
/* Stronger chrome contrast when Home is visible - uses theme variables */
|
|
body:has(#home-container.active) #tab-bar {
|
|
background: color-mix(in srgb, var(--tab-bg) 92%, black);
|
|
border-bottom-color: color-mix(in srgb, var(--tab-border) 80%, transparent);
|
|
box-shadow: 0 10px 24px -12px rgba(0,0,0,0.6);
|
|
}
|
|
|
|
body:has(#home-container.active) #nav {
|
|
background: color-mix(in srgb, var(--url-bar-bg) 92%, black);
|
|
border-bottom: 1px solid color-mix(in srgb, var(--url-bar-border) 80%, transparent);
|
|
box-shadow: 0 14px 36px -16px rgba(0,0,0,0.7);
|
|
}
|
|
|
|
body:has(#home-container.active) .nav-center {
|
|
background: color-mix(in srgb, var(--url-bar-bg) 96%, black);
|
|
border: 1px solid color-mix(in srgb, var(--primary, var(--accent)) 45%, transparent);
|
|
}
|
|
|
|
body:has(#home-container.active) .nav-left button,
|
|
body:has(#home-container.active) .nav-right > button,
|
|
body:has(#home-container.active) #reload-btn,
|
|
body:has(#home-container.active) #menu-btn {
|
|
/* slightly lighter than nav to pop over Home - uses theme colors */
|
|
background: color-mix(in srgb, var(--url-bar-bg) 85%, var(--text) 15%);
|
|
border: 1px solid color-mix(in srgb, var(--text) 20%, transparent);
|
|
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 10%, transparent);
|
|
}
|
|
|
|
/* Elevate active tab a touch more over home */
|
|
body:has(#home-container.active) .tab.active {
|
|
box-shadow: 0 10px 26px -8px rgba(0,0,0,0.6);
|
|
}
|