/* ========================================================================= maestro web — design system Register: product (a tool; design serves the task). Identity: precise, calm, alive. Monospace-as-UI; graphite chrome where the activity colours (green = alive) are the only hue on screen. Theme: dark (default) + light, all via OKLCH custom-property tokens. Palette: `data-palette` on swaps the accent + base tint (see the "palettes" section at the end of the token area); graphite is the bare document. ========================================================================= */ :root { /* ---- type ---- */ --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", "SFMono-Regular", "Cascadia Code", "Roboto Mono", Menlo, Consolas, "Liberation Mono", monospace; --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; --fs-11: 0.6875rem; --fs-12: 0.75rem; --fs-13: 0.8125rem; --fs-14: 0.875rem; --fs-15: 0.9375rem; --fs-17: 1.0625rem; --fs-20: 1.25rem; /* ---- spacing ---- */ --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; /* ---- radii ---- Terminal-native: crisp, near-square corners. Round dots (status, brand) use border-radius:50% directly and are unaffected; these tokens govern rectangles (buttons, inputs, cards, tags) and stay sharp on purpose. */ --r-1: 2px; --r-2: 3px; --r-3: 4px; --r-pill: 3px; /* ---- sizing ---- */ --row-h: 46px; --control-h: 30px; --tap: 40px; /* Height of the two top-of-pane bars (sidebar search + attach header) — shared so they line up across the split. */ --bar-h: 34px; /* ---- motion ---- */ --ease-out: cubic-bezier(0.22, 1, 0.36, 1); --dur-fast: 120ms; --dur: 180ms; --dur-slow: 240ms; /* ---- z-index scale ---- */ --z-sticky: 10; --z-backdrop: 40; --z-modal: 50; --z-toast: 60; /* ---- color: dark (default) ---- */ color-scheme: dark; --bg: oklch(0.172 0.006 256); --bg-grid: oklch(0.21 0.007 256); --surface: oklch(0.208 0.007 256); --surface-2: oklch(0.246 0.008 256); --surface-3: oklch(0.286 0.009 256); --border: oklch(0.312 0.01 256); --border-strong: oklch(0.395 0.012 256); --ink: oklch(0.945 0.004 256); --muted: oklch(0.72 0.008 256); --faint: oklch(0.58 0.008 256); /* graphite: the accent is ink itself — primary action, focus, selection. The activity colours below stay the only hue on screen. */ --accent: oklch(0.92 0.005 256); --accent-strong: oklch(0.97 0.003 256); --accent-ink: oklch(0.2 0.012 256); --accent-tint: oklch(0.92 0.005 256 / 0.1); --accent-ring: oklch(0.92 0.005 256 / 0.5); /* preview (docs/PREVIEW.md): a provisional view needs a colour that is not the accent, because the accent is what says "this is the one you picked". Defined once, off a single hue variable, so a palette whose accent already sits on that hue can move it (see periwinkle/orchid below); `light-dark()` keeps the light pair here instead of in all eighteen theme blocks. */ --preview-h: 305; --preview: light-dark( oklch(0.55 0.16 var(--preview-h)), oklch(0.78 0.14 var(--preview-h)) ); --preview-ink: light-dark( oklch(0.99 0.005 var(--preview-h)), oklch(0.19 0.045 var(--preview-h)) ); /* Opaque, not a wash: session rows read as fills, and a fill has to land on the same colour whatever tier the row was already painted. `--accent-fill` is the same recipe on the accent, so the two tiers differ by hue alone. */ --preview-tint: color-mix(in oklab, var(--preview) 30%, var(--surface-2)); --accent-fill: color-mix(in oklab, var(--accent) 30%, var(--surface-2)); --preview-ring: light-dark( oklch(0.55 0.16 var(--preview-h) / 0.5), oklch(0.78 0.14 var(--preview-h) / 0.6) ); --live: oklch(0.84 0.17 152); --live-glow: oklch(0.84 0.17 152 / 0.55); --danger: oklch(0.72 0.18 25); --danger-tint: oklch(0.72 0.18 25 / 0.14); --warn: oklch(0.82 0.14 85); --shadow-1: 0 1px 2px oklch(0 0 0 / 0.4); --shadow-2: 0 12px 28px -8px oklch(0 0 0 / 0.6), 0 2px 8px oklch(0 0 0 / 0.4); --term-bg: oklch(0.155 0.006 256); } :root[data-theme="light"], :root[data-theme="light"] body { color-scheme: light; --bg: oklch(0.985 0.002 256); --bg-grid: oklch(0.93 0.004 256); --surface: oklch(1 0 0); --surface-2: oklch(0.965 0.003 256); --surface-3: oklch(0.93 0.004 256); --border: oklch(0.892 0.005 256); --border-strong: oklch(0.82 0.008 256); --ink: oklch(0.26 0.012 256); --muted: oklch(0.47 0.012 256); --faint: oklch(0.62 0.012 256); --accent: oklch(0.27 0.01 256); --accent-strong: oklch(0.2 0.01 256); --accent-ink: oklch(0.985 0.002 256); --accent-tint: oklch(0.27 0.01 256 / 0.1); --accent-ring: oklch(0.27 0.01 256 / 0.45); --live: oklch(0.6 0.16 151); --live-glow: oklch(0.6 0.16 151 / 0.45); --danger: oklch(0.55 0.21 27); --danger-tint: oklch(0.55 0.21 27 / 0.1); --warn: oklch(0.66 0.15 75); --shadow-1: 0 1px 2px oklch(0.5 0.02 256 / 0.12); --shadow-2: 0 16px 36px -12px oklch(0.4 0.03 256 / 0.28), 0 2px 8px oklch(0.5 0.02 256 / 0.1); --term-bg: oklch(0.165 0.012 256); } /* Follow the OS when the user hasn't pinned a theme. */ @media (prefers-color-scheme: light) { :root:not([data-theme]) { color-scheme: light; --bg: oklch(0.985 0.002 256); --bg-grid: oklch(0.93 0.004 256); --surface: oklch(1 0 0); --surface-2: oklch(0.965 0.003 256); --surface-3: oklch(0.93 0.004 256); --border: oklch(0.892 0.005 256); --border-strong: oklch(0.82 0.008 256); --ink: oklch(0.26 0.012 256); --muted: oklch(0.47 0.012 256); --faint: oklch(0.62 0.012 256); --accent: oklch(0.27 0.01 256); --accent-strong: oklch(0.2 0.01 256); --accent-ink: oklch(0.985 0.002 256); --accent-tint: oklch(0.27 0.01 256 / 0.1); --accent-ring: oklch(0.27 0.01 256 / 0.45); --live: oklch(0.6 0.16 151); --live-glow: oklch(0.6 0.16 151 / 0.45); --danger: oklch(0.55 0.21 27); --danger-tint: oklch(0.55 0.21 27 / 0.1); --warn: oklch(0.66 0.15 75); --shadow-1: 0 1px 2px oklch(0.5 0.02 256 / 0.12); --shadow-2: 0 16px 36px -12px oklch(0.4 0.03 256 / 0.28), 0 2px 8px oklch(0.5 0.02 256 / 0.1); --term-bg: oklch(0.165 0.012 256); } } /* ---- palettes ---- `data-palette` on recolours the accent + base tint on top of the light/dark machinery above. Graphite (the default) is the bare document. Each palette ships a dark block, a pinned-light block, and a system-light block; `--live`/`--danger`/`--warn` stay semantic and are not redefined (except amber-phosphor, whose accent would collide with the stock warn). */ /* ice-cyan: signal-cyan accent on the slate base. */ :root[data-palette="ice-cyan"] { --bg: oklch(0.178 0.012 256); --bg-grid: oklch(0.215 0.014 256); --surface: oklch(0.214 0.014 256); --surface-2: oklch(0.252 0.016 256); --surface-3: oklch(0.292 0.018 256); --border: oklch(0.318 0.018 256); --border-strong: oklch(0.4 0.022 256); --ink: oklch(0.945 0.006 256); --muted: oklch(0.722 0.014 256); --faint: oklch(0.58 0.014 256); --accent: oklch(0.85 0.115 205); --accent-strong: oklch(0.89 0.12 205); --accent-ink: oklch(0.24 0.03 230); --accent-tint: oklch(0.85 0.115 205 / 0.12); --accent-ring: oklch(0.85 0.115 205 / 0.55); --term-bg: oklch(0.158 0.012 256); } :root[data-palette="ice-cyan"][data-theme="light"], :root[data-palette="ice-cyan"][data-theme="light"] body { --bg: oklch(0.985 0.003 256); --bg-grid: oklch(0.93 0.006 256); --surface: oklch(1 0 0); --surface-2: oklch(0.965 0.004 256); --surface-3: oklch(0.93 0.006 256); --border: oklch(0.892 0.008 256); --border-strong: oklch(0.82 0.012 256); --ink: oklch(0.26 0.014 256); --muted: oklch(0.47 0.016 256); --faint: oklch(0.62 0.016 256); --accent: oklch(0.52 0.1 220); --accent-strong: oklch(0.47 0.11 220); --accent-ink: oklch(0.99 0.005 220); --accent-tint: oklch(0.52 0.1 220 / 0.12); --accent-ring: oklch(0.52 0.1 220 / 0.5); --term-bg: oklch(0.165 0.012 256); } @media (prefers-color-scheme: light) { :root[data-palette="ice-cyan"]:not([data-theme]) { --bg: oklch(0.985 0.003 256); --bg-grid: oklch(0.93 0.006 256); --surface: oklch(1 0 0); --surface-2: oklch(0.965 0.004 256); --surface-3: oklch(0.93 0.006 256); --border: oklch(0.892 0.008 256); --border-strong: oklch(0.82 0.012 256); --ink: oklch(0.26 0.014 256); --muted: oklch(0.47 0.016 256); --faint: oklch(0.62 0.016 256); --accent: oklch(0.52 0.1 220); --accent-strong: oklch(0.47 0.11 220); --accent-ink: oklch(0.99 0.005 220); --accent-tint: oklch(0.52 0.1 220 / 0.12); --accent-ring: oklch(0.52 0.1 220 / 0.5); --term-bg: oklch(0.165 0.012 256); } } /* periwinkle: indigo base, blue-violet accent. */ :root[data-palette="periwinkle"] { --bg: oklch(0.175 0.018 278); --bg-grid: oklch(0.212 0.021 278); --surface: oklch(0.212 0.021 278); --surface-2: oklch(0.25 0.024 278); --surface-3: oklch(0.29 0.026 278); --border: oklch(0.318 0.026 278); --border-strong: oklch(0.4 0.028 278); --ink: oklch(0.93 0.012 278); --muted: oklch(0.71 0.02 278); --faint: oklch(0.57 0.022 278); --accent: oklch(0.75 0.125 275); --accent-strong: oklch(0.79 0.13 275); --accent-ink: oklch(0.18 0.04 278); --accent-tint: oklch(0.75 0.125 275 / 0.14); --accent-ring: oklch(0.75 0.125 275 / 0.55); /* This accent is already violet, so preview moves to cyan to stay legible as "not the accent". Set once here: the light blocks below don't touch it. */ --preview-h: 195; --term-bg: oklch(0.155 0.018 278); } :root[data-palette="periwinkle"][data-theme="light"], :root[data-palette="periwinkle"][data-theme="light"] body { --bg: oklch(0.982 0.004 278); --bg-grid: oklch(0.93 0.008 278); --surface: oklch(1 0 0); --surface-2: oklch(0.96 0.006 278); --surface-3: oklch(0.93 0.008 278); --border: oklch(0.885 0.01 278); --border-strong: oklch(0.82 0.014 278); --ink: oklch(0.27 0.02 278); --muted: oklch(0.47 0.02 278); --faint: oklch(0.62 0.02 278); --accent: oklch(0.5 0.17 272); --accent-strong: oklch(0.45 0.17 272); --accent-ink: oklch(0.99 0.005 272); --accent-tint: oklch(0.5 0.17 272 / 0.12); --accent-ring: oklch(0.5 0.17 272 / 0.5); --term-bg: oklch(0.165 0.018 278); } @media (prefers-color-scheme: light) { :root[data-palette="periwinkle"]:not([data-theme]) { --bg: oklch(0.982 0.004 278); --bg-grid: oklch(0.93 0.008 278); --surface: oklch(1 0 0); --surface-2: oklch(0.96 0.006 278); --surface-3: oklch(0.93 0.008 278); --border: oklch(0.885 0.01 278); --border-strong: oklch(0.82 0.014 278); --ink: oklch(0.27 0.02 278); --muted: oklch(0.47 0.02 278); --faint: oklch(0.62 0.02 278); --accent: oklch(0.5 0.17 272); --accent-strong: oklch(0.45 0.17 272); --accent-ink: oklch(0.99 0.005 272); --accent-tint: oklch(0.5 0.17 272 / 0.12); --accent-ring: oklch(0.5 0.17 272 / 0.5); --term-bg: oklch(0.165 0.018 278); } } /* amber-phosphor: CRT amber on warm graphite. `--warn` shifts orange so the awaiting colour stays distinct from the accent. */ :root[data-palette="amber-phosphor"] { --bg: oklch(0.178 0.008 70); --bg-grid: oklch(0.214 0.01 70); --surface: oklch(0.214 0.01 70); --surface-2: oklch(0.252 0.012 70); --surface-3: oklch(0.292 0.013 70); --border: oklch(0.318 0.014 70); --border-strong: oklch(0.4 0.016 70); --ink: oklch(0.94 0.008 78); --muted: oklch(0.72 0.014 75); --faint: oklch(0.58 0.014 75); --accent: oklch(0.83 0.14 78); --accent-strong: oklch(0.87 0.145 78); --accent-ink: oklch(0.25 0.05 78); --accent-tint: oklch(0.83 0.14 78 / 0.13); --accent-ring: oklch(0.83 0.14 78 / 0.55); --warn: oklch(0.76 0.15 55); --term-bg: oklch(0.158 0.008 70); } :root[data-palette="amber-phosphor"][data-theme="light"], :root[data-palette="amber-phosphor"][data-theme="light"] body { --bg: oklch(0.983 0.004 78); --bg-grid: oklch(0.93 0.007 78); --surface: oklch(1 0 0); --surface-2: oklch(0.962 0.005 78); --surface-3: oklch(0.93 0.007 78); --border: oklch(0.888 0.01 78); --border-strong: oklch(0.82 0.012 78); --ink: oklch(0.27 0.015 70); --muted: oklch(0.47 0.016 70); --faint: oklch(0.62 0.016 70); --accent: oklch(0.6 0.13 70); --accent-strong: oklch(0.55 0.13 70); --accent-ink: oklch(0.99 0.01 78); --accent-tint: oklch(0.6 0.13 70 / 0.12); --accent-ring: oklch(0.6 0.13 70 / 0.5); --warn: oklch(0.58 0.14 50); --term-bg: oklch(0.165 0.008 70); } @media (prefers-color-scheme: light) { :root[data-palette="amber-phosphor"]:not([data-theme]) { --bg: oklch(0.983 0.004 78); --bg-grid: oklch(0.93 0.007 78); --surface: oklch(1 0 0); --surface-2: oklch(0.962 0.005 78); --surface-3: oklch(0.93 0.007 78); --border: oklch(0.888 0.01 78); --border-strong: oklch(0.82 0.012 78); --ink: oklch(0.27 0.015 70); --muted: oklch(0.47 0.016 70); --faint: oklch(0.62 0.016 70); --accent: oklch(0.6 0.13 70); --accent-strong: oklch(0.55 0.13 70); --accent-ink: oklch(0.99 0.01 78); --accent-tint: oklch(0.6 0.13 70 / 0.12); --accent-ring: oklch(0.6 0.13 70 / 0.5); --warn: oklch(0.58 0.14 50); --term-bg: oklch(0.165 0.008 70); } } /* ember: warm orange-red accent. */ :root[data-palette="ember"] { --bg: oklch(0.18 0.009 50); --bg-grid: oklch(0.216 0.011 50); --surface: oklch(0.216 0.011 50); --surface-2: oklch(0.254 0.013 50); --surface-3: oklch(0.294 0.014 50); --border: oklch(0.32 0.015 50); --border-strong: oklch(0.4 0.017 50); --ink: oklch(0.94 0.007 50); --muted: oklch(0.72 0.013 50); --faint: oklch(0.58 0.013 50); --accent: oklch(0.74 0.15 45); --accent-strong: oklch(0.78 0.155 45); --accent-ink: oklch(0.2 0.04 45); --accent-tint: oklch(0.74 0.15 45 / 0.14); --accent-ring: oklch(0.74 0.15 45 / 0.55); --term-bg: oklch(0.158 0.009 50); } :root[data-palette="ember"][data-theme="light"], :root[data-palette="ember"][data-theme="light"] body { --bg: oklch(0.983 0.004 50); --bg-grid: oklch(0.93 0.006 50); --surface: oklch(1 0 0); --surface-2: oklch(0.962 0.005 50); --surface-3: oklch(0.93 0.006 50); --border: oklch(0.888 0.009 50); --border-strong: oklch(0.82 0.012 50); --ink: oklch(0.27 0.014 50); --muted: oklch(0.47 0.015 50); --faint: oklch(0.62 0.015 50); --accent: oklch(0.58 0.17 40); --accent-strong: oklch(0.53 0.17 40); --accent-ink: oklch(0.99 0.008 40); --accent-tint: oklch(0.58 0.17 40 / 0.11); --accent-ring: oklch(0.58 0.17 40 / 0.5); --term-bg: oklch(0.165 0.009 50); } @media (prefers-color-scheme: light) { :root[data-palette="ember"]:not([data-theme]) { --bg: oklch(0.983 0.004 50); --bg-grid: oklch(0.93 0.006 50); --surface: oklch(1 0 0); --surface-2: oklch(0.962 0.005 50); --surface-3: oklch(0.93 0.006 50); --border: oklch(0.888 0.009 50); --border-strong: oklch(0.82 0.012 50); --ink: oklch(0.27 0.014 50); --muted: oklch(0.47 0.015 50); --faint: oklch(0.62 0.015 50); --accent: oklch(0.58 0.17 40); --accent-strong: oklch(0.53 0.17 40); --accent-ink: oklch(0.99 0.008 40); --accent-tint: oklch(0.58 0.17 40 / 0.11); --accent-ring: oklch(0.58 0.17 40 / 0.5); --term-bg: oklch(0.165 0.009 50); } } /* orchid: muted violet accent on a faintly violet base. */ :root[data-palette="orchid"] { --bg: oklch(0.177 0.014 305); --bg-grid: oklch(0.213 0.017 305); --surface: oklch(0.213 0.017 305); --surface-2: oklch(0.251 0.02 305); --surface-3: oklch(0.291 0.021 305); --border: oklch(0.318 0.022 305); --border-strong: oklch(0.4 0.024 305); --ink: oklch(0.935 0.01 305); --muted: oklch(0.715 0.018 305); --faint: oklch(0.575 0.018 305); --accent: oklch(0.78 0.13 310); --accent-strong: oklch(0.82 0.135 310); --accent-ink: oklch(0.22 0.05 310); --accent-tint: oklch(0.78 0.13 310 / 0.14); --accent-ring: oklch(0.78 0.13 310 / 0.55); /* Same collision as periwinkle: an orchid accent needs a non-purple preview. */ --preview-h: 195; --term-bg: oklch(0.155 0.014 305); } :root[data-palette="orchid"][data-theme="light"], :root[data-palette="orchid"][data-theme="light"] body { --bg: oklch(0.983 0.004 305); --bg-grid: oklch(0.93 0.007 305); --surface: oklch(1 0 0); --surface-2: oklch(0.961 0.005 305); --surface-3: oklch(0.93 0.007 305); --border: oklch(0.886 0.01 305); --border-strong: oklch(0.82 0.013 305); --ink: oklch(0.27 0.018 305); --muted: oklch(0.47 0.018 305); --faint: oklch(0.62 0.018 305); --accent: oklch(0.5 0.17 308); --accent-strong: oklch(0.45 0.17 308); --accent-ink: oklch(0.99 0.005 308); --accent-tint: oklch(0.5 0.17 308 / 0.11); --accent-ring: oklch(0.5 0.17 308 / 0.5); --term-bg: oklch(0.165 0.014 305); } @media (prefers-color-scheme: light) { :root[data-palette="orchid"]:not([data-theme]) { --bg: oklch(0.983 0.004 305); --bg-grid: oklch(0.93 0.007 305); --surface: oklch(1 0 0); --surface-2: oklch(0.961 0.005 305); --surface-3: oklch(0.93 0.007 305); --border: oklch(0.886 0.01 305); --border-strong: oklch(0.82 0.013 305); --ink: oklch(0.27 0.018 305); --muted: oklch(0.47 0.018 305); --faint: oklch(0.62 0.018 305); --accent: oklch(0.5 0.17 308); --accent-strong: oklch(0.45 0.17 308); --accent-ink: oklch(0.99 0.005 308); --accent-tint: oklch(0.5 0.17 308 / 0.11); --accent-ring: oklch(0.5 0.17 308 / 0.5); --term-bg: oklch(0.165 0.014 305); } } /* ---------- reset / base ---------- */ * { box-sizing: border-box; } *:focus { outline: none; } html, body { height: 100%; margin: 0; /* No pull-to-refresh / scroll chaining — terminal scroll wins on touch. */ overscroll-behavior: none; } body { overflow-x: hidden; } body { background: var(--bg); color: var(--ink); font-family: var(--font-mono); font-size: var(--fs-15); line-height: 1.45; font-feature-settings: "ss01", "cv01"; -webkit-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; /* faint structural grid — terminal texture, not a CRT costume */ background-image: linear-gradient(var(--bg-grid) 1px, transparent 1px), linear-gradient(90deg, var(--bg-grid) 1px, transparent 1px); background-size: 100% 64px, 64px 100%; background-position: center top; /* dim the grid via opacity on a fixed overlay would cost a node; bake it low instead */ } #root { /* `--app-vh` tracks the *visual* viewport (set by useViewport) so the shell stays above the mobile soft keyboard; falls back to the layout viewport where `visualViewport` is unavailable. `--app-top` follows the layout viewport's scroll under the keyboard so the shell stays pinned to the visible region instead of drifting to the top. */ height: var(--app-vh, 100%); transform: translateY(var(--app-top, 0px)); display: flex; flex-direction: column; overflow: hidden; } a { color: inherit; text-decoration: none; } code { font-family: var(--font-mono); font-size: 0.92em; padding: 1px 5px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-1); } ::selection { background: var(--accent-tint); color: var(--ink); } button, input, select, textarea { font-family: inherit; font-size: inherit; color: inherit; } ::placeholder { color: var(--faint); opacity: 1; } :focus-visible { outline: 2px solid var(--accent-ring); outline-offset: 2px; border-radius: var(--r-1); } /* ---------- buttons ---------- Terminal-native: the brackets are the chrome. Default + primary wear [ brackets ]; ghost/icon drop them for quieter nav and single glyphs. */ .btn { appearance: none; border: 1px solid transparent; background: transparent; color: var(--ink); padding: 0 var(--sp-1); height: var(--control-h); min-height: var(--control-h); cursor: pointer; font-family: var(--font-mono); font-size: var(--fs-13); font-weight: 500; letter-spacing: 0.01em; display: inline-flex; align-items: center; justify-content: center; gap: 4px; white-space: nowrap; transition: color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out); } .btn::before { content: "["; color: var(--faint); } .btn::after { content: "]"; color: var(--faint); } .btn:hover { color: var(--accent); } .btn:hover::before, .btn:hover::after { color: var(--accent); } .btn:active { transform: translateY(1px); } .btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; } .btn-primary { color: var(--accent); font-weight: 600; } .btn-primary::before, .btn-primary::after { color: var(--accent); } .btn-primary:hover { background: var(--accent-tint); } /* Ghost: no brackets — quiet nav (back, disconnect, theme, kit) and icons. */ .btn-ghost { color: var(--muted); } .btn-ghost::before, .btn-ghost::after { content: none; } .btn-ghost:hover { color: var(--ink); background: var(--surface-2); } .btn-icon { width: var(--control-h); padding: 0; font-size: var(--fs-15); } .btn-icon::before, .btn-icon::after { content: none; } .btn-icon:hover { background: var(--surface-2); } /* ---------- app shell: sidebar + content ---------- */ .app-shell { flex: 1 1 auto; min-height: 0; } /* Desktop: persistent two-pane split. Sidebar holds the session list; the content pane shows the welcome state or the attached terminal. */ @media (min-width: 860px) { .app-shell { display: grid; grid-template-columns: var(--sidebar-w, clamp(220px, 22vw, 320px)) minmax(0, 1fr); } } .sidebar { display: flex; flex-direction: column; min-height: 0; height: 100%; overflow: hidden; position: relative; background: color-mix(in oklab, var(--surface) 26%, var(--bg)); border-right: 1px solid var(--border); } /* Drag-to-resize grip on the sidebar's right edge (desktop split only). */ .sidebar-resize { position: absolute; top: 0; right: -3px; width: 6px; height: 100%; cursor: col-resize; z-index: var(--z-sticky); touch-action: none; } .sidebar-resize:hover, .sidebar-resize:active { background: var(--accent-ring); } @media (max-width: 859px) { .sidebar-resize { display: none; } } /* Sidebar's own slim header: just the session search. */ /* The search input IS the header — it spans edge to edge, flush, with just a bottom rule for separation. No wrapper padding, no boxed border/radius. */ .sidebar-search { flex: 0 0 auto; } /* App-level actions (help, theme, spawn), pinned to the sidebar's foot. */ .sidebar-footer { display: flex; align-items: center; gap: var(--sp-2); flex: 0 0 auto; padding: var(--sp-2) var(--sp-3); border-top: 1px solid var(--border); } .sidebar-footer .spawn-btn { flex: 1 1 auto; } /* Palette picker: a ghost-button-shaped