/* The palette, in ONE place.
 *
 * These tokens used to live inline in app.html, which meant the sign-in page —
 * a separate HTML string in web.py — carried its own hardcoded colours and
 * drifted into looking like a different product. Both pages link this now, so
 * a change to a theme reaches the whole site.
 *
 * Midnight is the :root default; the other two override. Every theme sets the
 * complete set rather than patching a few, so a token can never fall through
 * to a value from another palette.
 */
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }

  /* Both selectors, deliberately. :root makes Midnight the default; the
     attribute makes it addressable, which is what lets the theme picker render
     a real preview of it while the console is in some other theme. Without the
     second selector a nested Midnight preview inherits whatever surrounds it
     and shows the wrong palette. */
  :root, [data-theme="midnight"] {
    --bg: #09090b; --rail: rgba(18, 18, 20, 0.85); --panel: rgba(24, 24, 27, 0.7); --panel2: rgba(39, 39, 42, 0.75); --hi: rgba(63, 63, 70, 0.8);
    --border: rgba(255, 255, 255, 0.08); --border2: rgba(255, 255, 255, 0.15);
    /* --faint carries most of the meta text in this console: handles, times,
       section labels, "nobody connected". It measured 2.57:1 here, 2.48:1 in
       Light and 2.84:1 in Grey — below the 4.5 body floor and below even
       the 3:1 UI floor, in all three. The values now clear 4.5:1 against each
       theme's WORST ground, which is its panel rather than its page.
       Measured, not eyeballed; re-measure before darkening any of them. */
    --text: #fafafa; --muted: #a1a1aa; --faint: #94949f;
    --accent: #3b82f6; --accentInk: #ffffff; --live: #10b981; --warn: #f59e0b; --danger: #ef4444;
    /* The colour a BUTTON or an unread BADGE wears, which is not always the
       theme's main colour. On the three built palettes the accent is the whole
       identity — violet, green, orange — and painting every call to action in
       it too left those themes reading as one flat wash. Defaults to the accent
       here, so a palette that wants one colour simply says nothing. */
    --action: var(--accent); --actionInk: var(--accentInk);
    --c-human: #3b82f6; --c-architect: oklch(0.62 0.13 250); --c-main: oklch(0.66 0.14 150); --c-chain: #71717a;
    /* The ground an INPUT WELL sits on — the search box, the composer, the
       theme strip, a rail tile — and the same well while it has focus.
       This used to be a literal rgba(0,0,0,.2) in app.html, which is a fine
       recess on a dark page and a grey slab on a light one: under Light it
       composited to rgb(201,200,198) on warm paper and dropped --faint to
       3.42:1 and --muted to 2.93:1, both under the 4.5 floor. A token lets
       each palette recess the way its own ground wants to, so the dark themes
       keep the wash they were designed with and Light can go the other way.
       Measured; re-measure before changing one. */
    --field: rgba(0,0,0,.2); --fieldOn: rgba(0,0,0,.3);
    /* Named families first, so anyone who happens to have them installed still
       gets them; a real system stack behind, so nobody waits on a network. */
    --fontUi: 'Inter', 'IBM Plex Sans', 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;
    --fontMono: 'JetBrains Mono', 'IBM Plex Mono', 'Cascadia Code', Consolas, 'SF Mono', Menlo, 'DejaVu Sans Mono', monospace;
    --radius: 16px; --wgrid: rgba(255,255,255,.03);
    --wshadow: 0 32px 64px -24px rgba(0,0,0,.8);
  }

  [data-theme="light"] {
    --bg:#f7f5f1; --rail:#efece5; --panel:#fbfaf7; --panel2:#ffffff; --hi:#f2efe8;
    --border:#e6e3dc; --border2:#e0ddd4; --text:#2b303b; --muted:#6a7180; --faint:#6b665a;
    /* --warn (0.60 -> 0.53) and --live (0.55 -> 0.51) darkened on 2026-08-24.
       Both measured under 4.5:1 as small text on a CARD — 3.95 and 4.38. The
       originals were checked against --panel, and a card paints --panel2, which
       is a shade lighter; the difference is small and it is the whole margin.
       Every other user of these two here is text on the same grounds, so all of
       them gain. Only the LIGHT palette moves — the dark themes measure fine. */
    --accent:oklch(0.58 0.13 265); --accentInk:#ffffff; --live:oklch(0.51 0.13 150); --warn:oklch(0.53 0.14 60); --danger:oklch(0.55 0.16 25);
    --c-human:oklch(0.62 0.14 45); --c-architect:oklch(0.55 0.13 265); --c-main:oklch(0.52 0.13 150); --c-chain:#8a8578;
    /* The one theme that recesses UPWARD. On warm paper an input well reads as
       whiter than the page, not darker — and it has to: --muted is already at
       4.50:1 against --bg here, so ANY darkening of the well pushes the theme
       strip's labels under the floor (a .05 black wash measured 4.26). White
       puts --muted at 4.90 and --faint at 5.72. Focus tints with the accent
       rather than with black, for the same reason: the focused well lands on
       rgb(243,245,251), --muted 4.51 and --faint 5.26. That 4.51 is the
       thinnest margin in the file — deepen this mix and it goes under. */
    --field:#ffffff; --fieldOn:color-mix(in srgb, var(--accent) 7%, #ffffff);
    /* Humanist, to keep Light visibly different from Midnight without a webfont.
       Bare 'Public Sans' with no fallback used to mean this theme silently
       rendered in the browser default whenever the CDN was unreachable. */
    --fontUi:'Public Sans', Seravek, 'Gill Sans Nova', Optima, 'Segoe UI', system-ui, sans-serif;
    --radius:13px; --wgrid:rgba(20,20,30,.05);
    --wshadow:0 24px 54px -22px rgba(20,20,30,.3);
  }

  [data-theme="grey"] {
    --bg:#2a2d36; --rail:#16181f; --panel:#23262f; --panel2:#20222b; --hi:#2e313c;
    --border:#3b3f4b; --border2:#454a57; --text:#e6e7ec; --muted:#9aa0ad; --faint:#949aab;
    --accent:oklch(0.72 0.11 265); --accentInk:#16181f; --live:oklch(0.75 0.13 155); --warn:oklch(0.78 0.13 75); --danger:oklch(0.66 0.16 25);
    --c-human:oklch(0.68 0.15 45); --c-architect:oklch(0.7 0.11 265); --c-main:oklch(0.72 0.13 155); --c-chain:#6b7280;
    --field:rgba(0,0,0,.2); --fieldOn:rgba(0,0,0,.3);
    /* Geometric, same reasoning as Light above. */
    --fontUi:'Space Grotesk', 'Segoe UI Variable Display', 'Avenir Next', Futura, 'Segoe UI', system-ui, sans-serif;
    --radius:13px; --wgrid:rgba(255,255,255,.045);
    --wshadow:0 26px 60px -22px rgba(0,0,0,.62);
  }

/* Tokyo — the city at night: indigo ground, neon on top. The accent is a
     violet rather than the usual blue, and `live` is a cyan, so the two signals
     stay apart at a glance. */
  [data-theme="tokyo"] {
    /* Deeper than it was. The ground, the panels and the glow all came down a
       step, because the purple people see is mostly SURFACE — a 28% violet wash
       across the whole page — not the accent itself. */
    --bg:#08070f; --rail:rgba(14,12,30,.9); --panel:rgba(20,18,44,.74); --panel2:rgba(32,28,64,.8); --hi:rgba(52,46,98,.82);
    --border:rgba(180,160,255,.11); --border2:rgba(180,160,255,.2);
    --text:#f4f1ff; --muted:#b0a6d8; --faint:#9c92c8;
    /* #8b5cf6 rather than #a855f7: a deeper violet, and the darkest one that
       still clears 4.5:1 as TEXT on this ground (4.64). The accent is not only
       a button here — it paints mentions and links — so anything darker buys a
       moodier page by making pings hard to read. Measured; re-measure before
       darkening it again. */
    --accent:#8b5cf6; --accentInk:#0b0a16; --live:#22d3ee; --warn:#fbbf24; --danger:#fb7185;
    /* Tokyo Night's yellow, against Tokyo Night's violet. */
    --action:#e0af68; --actionInk:#0b0a16;
    --c-human:#8b5cf6; --c-architect:#818cf8; --c-main:#22d3ee; --c-chain:#6d648f;
    --field:rgba(0,0,0,.2); --fieldOn:rgba(0,0,0,.3);
    --fontUi:'Inter','IBM Plex Sans','Segoe UI Variable Text','Segoe UI',system-ui,sans-serif;
    --radius:15px; --wgrid:rgba(190,170,255,.05);
    --wshadow:0 30px 60px -22px rgba(0,0,0,.8);
  }

  /* Jungle — canopy light on deep green. Warm amber for `warn` so it reads as
     a signal rather than as more foliage. */
  [data-theme="jungle"] {
    --bg:#08130f; --rail:rgba(12,28,22,.9); --panel:rgba(16,38,30,.72); --panel2:rgba(24,54,42,.78); --hi:rgba(38,80,62,.8);
    --border:rgba(160,255,210,.12); --border2:rgba(160,255,210,.2);
    --text:#eefaf3; --muted:#a3c9b6; --faint:#93bda9;
    --accent:#34d399; --accentInk:#062017; --live:#a3e635; --warn:#fbbf24; --danger:#f87171;
    /* Canopy light, literally: gold against the green rather than more of it.
       Deeper than --warn on purpose — a button that wore the warning colour
       exactly would read as one. */
    --action:#f0b429; --actionInk:#062017;
    --c-human:#34d399; --c-architect:#5eead4; --c-main:#a3e635; --c-chain:#5c7d6d;
    --field:rgba(0,0,0,.2); --fieldOn:rgba(0,0,0,.3);
    --fontUi:'Inter','IBM Plex Sans','Segoe UI Variable Text','Segoe UI',system-ui,sans-serif;
    --radius:14px; --wgrid:rgba(160,255,210,.045);
    --wshadow:0 28px 58px -22px rgba(0,0,0,.75);
  }

  /* Ember — the one I chose, and the only theme taken from the product itself:
     the favicon is an orange ring on black, and nothing in the console wore it.
     Warm charcoal rather than neutral grey, so the orange sits in the same
     family as its ground instead of on top of it. */
  [data-theme="ember"] {
    --bg:#14100e; --rail:rgba(28,21,17,.9); --panel:rgba(38,29,23,.74); --panel2:rgba(54,41,32,.8); --hi:rgba(78,58,44,.82);
    --border:rgba(255,190,140,.12); --border2:rgba(255,190,140,.2);
    --text:#fbf3ec; --muted:#cbb3a1; --faint:#bda691;
    --accent:#f97316; --accentInk:#14100e; --live:#4ade80; --warn:#fbbf24; --danger:#ef4444;
    /* The one place a cool colour earns its keep. Ember is orange on warm
       charcoal, so a yellow or amber button is just more of the accent; the
       sky blue is the spark against the coal, and it cannot be confused with
       --warn or --danger, which are both warm here. */
    --action:#38bdf8; --actionInk:#0a1520;
    --c-human:#f97316; --c-architect:#fb923c; --c-main:#4ade80; --c-chain:#8a7466;
    --field:rgba(0,0,0,.2); --fieldOn:rgba(0,0,0,.3);
    --fontUi:'Inter','IBM Plex Sans','Segoe UI Variable Text','Segoe UI',system-ui,sans-serif;
    --radius:14px; --wgrid:rgba(255,190,140,.05);
    --wshadow:0 28px 58px -22px rgba(0,0,0,.8);
  }

/* data-theme lands on #shell in the console and on <html> on the sign-in page,
   and body is the parent of the former — so the console needs this matched on
   #shell or body resolves :root and a light theme renders half dark. */
  #shell[data-theme="midnight"], html[data-theme="midnight"] body {
         background: radial-gradient(circle at 15% 50%, rgba(20, 30, 45, 0.4), var(--bg) 60%), var(--bg);
         background-attachment: fixed;
  }
  #shell[data-theme="tokyo"], html[data-theme="tokyo"] body {
         background: radial-gradient(circle at 12% 40%, rgba(88, 44, 150, 0.22), var(--bg) 62%), var(--bg);
         background-attachment: fixed;
  }
  #shell[data-theme="jungle"], html[data-theme="jungle"] body {
         background: radial-gradient(circle at 18% 55%, rgba(20, 120, 80, 0.26), var(--bg) 62%), var(--bg);
         background-attachment: fixed;
  }
  #shell[data-theme="ember"], html[data-theme="ember"] body {
         background: radial-gradient(circle at 14% 45%, rgba(190, 90, 30, 0.24), var(--bg) 62%), var(--bg);
         background-attachment: fixed;
  }
