/* ============================================================================
   DESIGN TOKENS — the single place where light and dark are decided.

   Everything else in the builder references these names, never a raw colour.
   That is the whole point: swapping a theme means changing values here, and a
   component written against tokens participates in dark mode automatically
   instead of needing its own html.dark-mode override. Scattering per-component
   dark rules is what makes a stylesheet unmaintainable.

   Three tiers, the usual hierarchy:
     primitive   raw values      --c-blue-600
     semantic    decisions       --bg-page, --text-body, --border
     component   local overrides --chrome-bg (in chrome.css)

   Loaded FIRST so every later sheet can consume the names.
   ============================================================================ */

/* ---------- tier 1: primitives ---------- */
:root {
    --c-white:      #ffffff;
    --c-black:      #000000;

    --c-gray-50:    #f9fafb;
    --c-gray-100:   #f3f4f6;
    --c-gray-200:   #e5e7eb;
    --c-gray-400:   #9ca3af;
    --c-gray-600:   #4b5563;
    --c-gray-800:   #1f2937;
    --c-gray-900:   #111827;

    /* Not pure black: a #000 canvas gives harsh contrast and haloed text. And
       for a green brand the dark canvas is a deep, DESATURATED green-charcoal,
       not a neutral slate — a branded dark mode tints its neutrals toward the
       brand hue so the palette still reads as "ours" at night. */
    --c-ink-900:    #0a1e14;
    --c-ink-800:    #103023;
    --c-ink-700:    #184734;

    /* A full green ramp, so a shade is a point on a deliberate scale rather than
       one of three ad-hoc values. Light mode leans on 600-800 (they clear
       contrast on white); dark mode uses 300-400 (a saturated green vibrates and
       goes muddy on ink, so the lighter end carries the accent there). */
    --c-green-50:   #f0fdf4;
    --c-green-100:  #dcfce7;
    --c-green-200:  #bbf7d0;
    --c-green-300:  #86efac;
    --c-green-400:  #4ade80;
    --c-green-500:  #22c55e;
    --c-green-600:  #16a34a;
    --c-green-700:  #15803d;
    --c-green-800:  #166534;
    --c-green-900:  #14532d;

    --c-orange-500: #f97316;
    --c-blue-600:   #2563eb;

    /* Status hues. Each has a light and a dark variant rather than one shade
       used in both modes: a colour that clears 4.5:1 on white usually fails on
       an ink background, and vice versa. */
    --c-amber-600:  #b45309;
    --c-amber-400:  #fbbf24;
    --c-red-600:    #b91c1c;
    --c-red-400:    #f87171;
    --c-blue-400:   #60a5fa;
}

/* ---------- tier 2: semantic — LIGHT (the default) ---------- */
:root {
    color-scheme: light;

    --bg-page:        var(--c-white);
    --bg-surface:     var(--c-white);
    --bg-raised:      var(--c-gray-50);
    --bg-sunken:      var(--c-gray-100);
    --bg-hover:       var(--c-gray-100);

    --text-heading:   var(--c-gray-900);
    --text-body:      var(--c-gray-800);
    /* An explicit muted colour, not opacity — dimming with opacity is what
       makes dark-mode text look washed out and fail contrast. */
    --text-muted:     var(--c-gray-600);
    --text-inverse:   var(--c-white);

    --border:         rgba(0, 0, 0, .18);
    --border-strong:  rgba(0, 0, 0, .32);
    --border-subtle:  rgba(0, 0, 0, .10);

    --accent:         var(--c-green-600);
    --accent-contrast: var(--c-white);
    --accent-warm:    var(--c-orange-500);
    /* A tinted fill for callouts and pills, and a darker ink for accent-coloured
       TEXT — the plain accent is chosen to sit under white, so it is too light to
       read as small text on a pale fill. */
    --accent-soft:    rgba(21, 128, 61, .10);
    --accent-strong:  var(--c-green-700);

    /* Links are their own decision. Reusing the accent means a link is only
       distinguishable from a heading by position. */
    --link:           var(--c-blue-600);
    --link-hover:     var(--c-green-700);

    --info:           var(--c-blue-600);
    --success:        var(--c-green-600);
    --warning:        var(--c-amber-600);
    --danger:         var(--c-red-600);

    --shadow-sm:      0 1px 3px rgba(0, 0, 0, .08);
    --shadow-menu:    0 12px 32px rgba(0, 0, 0, .16);

    /* Header is its own surface: themes paint it separately from the page. */
    --header-bg:      var(--c-white);
    --header-fg:      var(--c-green-700);
    --header-fg-hover: var(--c-green-600);
    --header-border:  var(--c-orange-500);

    /* Footer follows the mode like everything else. It reads as a distinct band
       by sitting one step back from the page (bg-sunken), not by being locked
       dark — a permanently dark footer is exactly what looked wrong on a light
       page. Muted text is a real colour, never opacity. */
    --footer-bg:      var(--bg-sunken);
    --footer-heading: var(--text-heading);
    --footer-fg:      var(--text-body);
    --footer-muted:   var(--text-muted);
    --footer-link:    var(--text-body);
    --footer-link-hover: var(--accent);
    --footer-border:  var(--border-subtle);
}

/* ---------- tier 2: semantic — DARK ----------
   ONE dark definition, and only one.

   This block used to be written twice — once for `.dark-mode`, again inside
   `@media (prefers-color-scheme: dark)`. Two copies of the same 25 tokens is two
   places to forget, and the copies had already drifted apart.

   It collapses to a single rule because js/theme-mode.js is a BLOCKING script in
   <head>: it reads the stored choice, falls back to the system preference, and
   stamps `dark-mode` or `light-mode` on <html> before the first paint. The media
   query was therefore only ever reached with JavaScript disabled — and in that
   case the site keeps its light palette, which is legible and correct, just not
   automatic. That is the trade the single source is worth.

   Add a token to the LIGHT block above and you must add it here too. */

:root.dark-mode {
    color-scheme: dark;

    --bg-page:        var(--c-ink-900);
    --bg-surface:     var(--c-ink-800);
    --bg-raised:      var(--c-ink-700);
    --bg-sunken:      var(--c-ink-900);
    --bg-hover:       rgba(255, 255, 255, .10);

    --text-heading:   var(--c-white);
    --text-body:      var(--c-gray-200);
    --text-muted:     var(--c-gray-400);
    --text-inverse:   var(--c-gray-900);

    --border:         rgba(255, 255, 255, .24);
    --border-strong:  rgba(255, 255, 255, .40);
    --border-subtle:  rgba(255, 255, 255, .12);

    /* The light-mode green and amber are chosen to contrast against white and go
       muddy on ink, so dark takes the lighter end of each hue instead. The plain
       --accent MUST be overridden here too (it was not, so accent buttons and
       icons stayed the dark green-600 and disappeared into the ink). On a light
       green fill the text on top is dark, not white. */
    --accent:         var(--c-green-400);
    --accent-contrast: var(--c-ink-900);
    --accent-warm:    var(--c-orange-500);
    --accent-soft:    rgba(74, 222, 128, .14);
    --accent-strong:  var(--c-green-300);

    --link:           var(--c-blue-400);
    --link-hover:     var(--c-green-400);

    --info:           var(--c-blue-400);
    --success:        var(--c-green-400);
    --warning:        var(--c-amber-400);
    --danger:         var(--c-red-400);

    --shadow-sm:      0 1px 3px rgba(0, 0, 0, .40);
    --shadow-menu:    0 12px 32px rgba(0, 0, 0, .45);

    --header-bg:      var(--c-ink-900);
    --header-fg:      var(--c-gray-200);
    --header-fg-hover: var(--c-white);
    --header-border:  var(--c-orange-500);
}

/* Switching themes should not animate every colour on the page at once. */
@media (prefers-reduced-motion: no-preference) {
    body { transition: background-color .2s ease, color .2s ease; }
}
