:root {
  /* ── colour ──
     Dark theme, re-measured 2026-09-25 with the light one. Page, card and
     raised surface were 1.07:1 / 1.09:1 apart, the seams 1.13-1.23:1 and
     --fg-mute 2.45:1 on a card. Same rules as the light theme now: surfaces
     that step, seams you can see, every text token at 4.5:1 or better where it
     is used. */
  /* "Mission Control" (redesign, 2026-10-02): a neutral, precise dark — no
     blue cast, one lime accent for the primary action, amber for what waits
     on the operator. The steps are the minimum the contrast suite asks for
     (page→card 1.12, card→raised 1.08, seams 1.25, text 4.5:1). */
  --bg: #050607;              /* page */
  --bg-elev: #16171a;         /* card: 1.12:1 above the page */
  --bg-elev-2: #1f2125;       /* raised inside a card: 1.12:1 above it */
  --bg-glass: rgba(22, 23, 26, 0.86);
  --border: rgba(255, 255, 255, 0.12);
  --border-soft: rgba(255, 255, 255, 0.07);
  /* A neutral outline you can actually see. --border is a seam between
     surfaces; this is for a control that has to look like one without
     borrowing the accent, which reads as a warning around a whole box. */
  --border-strong: rgba(255, 255, 255, 0.30);
  --border-glow: rgba(228, 242, 34, 0.18);

  --fg: #eef0f3;
  --fg-dim: #b6bcc6;
  --fg-mute: #8f949d;         /* 5.2:1 on --bg-elev-2, 5.8:1 on a card */

  --accent: #e4f222;          /* lime: the one primary action of a view */
  --accent-deep: #c8d41b;     /* the far end of a primary button's gradient */
  --accent-soft: rgba(228, 242, 34, 0.12);
  /* Text on a solid accent or status fill: dark ink on every fill here. The
     light theme's fills are deep enough for white, so it flips these back. */
  --on-accent: #08090a;
  --on-status: #08090a;
  --green: #3ccf7a;
  --green-soft: rgba(60, 207, 122, 0.13);
  --yellow: #f5a524;          /* attention: something waits on the operator */
  --yellow-soft: rgba(245, 165, 36, 0.13);
  --red: #f07178;
  --red-soft: rgba(240, 113, 120, 0.13);
  --blue: #4ea7fc;            /* done, unread */
  --blue-soft: rgba(78, 167, 252, 0.13);

  /* Geist for the interface, served by the WebUI itself (assets/fonts, no
     third-party request). The terminal does NOT use it: Geist Mono has no
     box-drawing glyphs (─ ╭ ⎿), and a fallback glyph of another width breaks
     the columns of every TUI — --term-font stays a system monospace that has
     them. */
  --mono: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  --font-sans: 'Geist', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --term-font: ui-monospace, 'SF Mono', Menlo, 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace;
  --shadow: 0 10px 30px rgba(0, 0, 0, 0.55);
  --shadow-sm: 0 4px 12px rgba(0, 0, 0, 0.35);

  --term-bg: #0b0c0e;
  --term-fg: #d6dae0;
  /* Fallbacks only. A pane carries its whole palette as custom properties set
     on the card itself (js/terminal-themes.js), so a per-session theme cannot
     leak into the rest of the app. These keep the terminal readable before the
     first paint and anywhere a theme has not been applied. */
  --term-dim: #8f949d;
  --term-cursor: #e4f222;
  --term-sel: rgba(78, 167, 252, 0.25);
  --pane-bar: var(--bg-elev-2);
  /* How far the floating pane bar recedes while you read. 45% keeps it out of
     the way on a dark terminal; on a light one it washes out to nothing, so the
     light theme sets its own. */
  --pane-bar-rest: 0.45;
  --scrollbar-thumb: rgba(255, 255, 255, 0.1);
  --scrollbar-thumb-hover: rgba(255, 255, 255, 0.2);

  /* What waits on the operator (a question, a permission, a gate): its own
     name, so attention is never confused with an error or a warning. */
  --attention: var(--yellow);
  --attention-soft: var(--yellow-soft);

  /* ── type: eight steps absorb the twenty ad-hoc sizes ── */
  --fs-2xs: 10px;   /* was 8.5 / 9.5 / 10 / 10.5 */
  --fs-xs:  11px;   /* was 11 / 11.5 */
  --fs-sm:  12px;   /* was 12 / 12.5 */
  --fs-md:  13px;   /* was 13 / 13.5 */
  --fs-lg:  14px;   /* was 14 / 14.5 */
  --fs-xl:  16px;   /* was 15 / 16 */
  --fs-2xl: 18px;   /* was 17 / 18 / 19 */
  --fs-3xl: 22px;   /* was 20 / 21 / 22 */

  --fw-medium: 500; --fw-semi: 600; --fw-bold: 700; --fw-black: 800;

  /* ── radius ── */
  --r-xs: 4px; --r-sm: 6px; --r-md: 8px; --r-lg: 12px; --r-xl: 16px; --r-full: 999px;

  /* ── space (4-based; every padding and gap composes from these) ── */
  --sp-1: 4px; --sp-2: 6px; --sp-3: 8px; --sp-4: 10px;
  --sp-5: 12px; --sp-6: 16px; --sp-7: 20px; --sp-8: 24px;

  /* Quanto do topo da janela a navegação já ocupa. Quem gruda no topo
     (`position: sticky`) precisa começar abaixo dela, senão fica escondido
     atrás — a barra de navegação é `sticky` e tem z-index maior. Vira 56px
     em telas estreitas, onde a navegação vira gaveta e sobra só o botão
     flutuante do menu. */
  --nav-h: 70px;

  /* ── semantic aliases: meaning, not appearance ── */
  --text: var(--fg); --text-dim: var(--fg-dim); --text-mute: var(--fg-mute);
  --surface: var(--bg-elev); --surface-raised: var(--bg-elev-2);
  --status-ok: var(--green);   --status-ok-soft: var(--green-soft);
  --status-warn: var(--yellow); --status-warn-soft: var(--yellow-soft);
  --status-danger: var(--red);  --status-danger-soft: var(--red-soft);

  /* Model colours live here ONCE. Previously declared three times
     (.badge.opus, .rsm-tag.opus, .mtag.model) and free to drift. */
  --model-opus: #a78bfa;   --model-opus-soft: rgba(139, 92, 246, 0.12);
  --model-sonnet: var(--accent); --model-sonnet-soft: var(--accent-soft);
  --model-haiku: var(--green);   --model-haiku-soft: var(--green-soft);
  /* Fable sits above Opus; it had no tone and badged in plain grey. */
  --model-fable: var(--yellow);  --model-fable-soft: var(--yellow-soft);

  /* ── motion + layers ── */
  --t-fast: 0.15s; --t-med: 0.25s;
  /* --z-backdrop dims the page for the mobile drawer and must sit BELOW the
     nav it reveals: above it, the scrim swallows every tap meant for a menu
     item. --z-shell is the floating menu button, which stays reachable. */
  --z-menu: 60; --z-backdrop: 90; --z-nav: 100; --z-shell: 110;
  --z-modal: 200; --z-toast: 300;
}

/* ─── Light theme ───
   Rebuilt 2026-09-25: "everything is too light to read". Measured before —
   page #f3f4f6 / card #fff / raised #f9fafb were three near-identical whites,
   the seams were 4-8% black (invisible on white), and --fg-mute was 2.5:1 on a
   card. The rules now: the page is visibly darker than a card, a raised
   surface is visibly darker than the card it sits on, every seam can be seen,
   and every text token clears 4.5:1 on the surfaces it is used on. */
:root[data-theme="light"] {
  /* The same neutral identity on paper: no blue cast, the lime deepened to
     an olive that carries white text and reads as text on a card. */
  --bg: #e4e6ea;              /* page: 1.26:1 below a card */
  --bg-elev: #ffffff;         /* card */
  --bg-elev-2: #f1f2f4;       /* raised inside a card: tiles, buttons, bars */
  --bg-glass: rgba(255, 255, 255, 0.92);
  --border: rgba(15, 16, 20, 0.16);
  --border-soft: rgba(15, 16, 20, 0.10);
  --border-strong: rgba(15, 16, 20, 0.42);
  --border-glow: rgba(79, 92, 0, 0.22);

  --fg: #111214;
  --fg-dim: #3d4048;
  --fg-mute: #5c606a;         /* 5.8:1 on --bg-elev-2 */

  --accent: #4f5c00;          /* olive lime: white on it 7.4:1, as text on a card 7.5:1 */
  --accent-deep: #3f4a00;
  --accent-soft: #eef3c2;
  --on-accent: #ffffff;
  --on-status: #ffffff;
  --green: #1a7f37;
  --green-soft: #d3f5dc;
  --yellow: #8a5a00;
  --yellow-soft: #fff1b8;
  --red: #c21f2b;
  --red-soft: #ffe3e0;
  --blue: #0b64c0;
  --blue-soft: rgba(11, 100, 192, 0.12);

  --shadow: 0 1px 2px rgba(15, 16, 20, 0.08), 0 8px 24px rgba(15, 16, 20, 0.08);
  --shadow-sm: 0 1px 3px rgba(15, 16, 20, 0.12);
  --term-bg: #f7f7f8;
  --term-fg: #1d1f23;
  --term-dim: #5c606a;
  --term-cursor: #4f5c00;
  --term-sel: rgba(11, 100, 192, 0.20);
  --pane-bar-rest: 0.8;
  --scrollbar-thumb: rgba(15, 23, 42, 0.28);
  --scrollbar-thumb-hover: rgba(15, 23, 42, 0.42);

  /* --model-opus carries a genuinely different value per theme (not derived
     from another colour token), so it is redeclared here on purpose. */
  --model-opus: #6f42c1; --model-opus-soft: #f0e8ff;
}

@media (prefers-reduced-motion: reduce) {
  :root { --t-fast: 0s; --t-med: 0s; }
}
