/* ============================================================================
   ICP.SUPPLY — COLOUR TOKENS. THE ONLY FILE IN THIS PROJECT THAT MAY DECLARE A
   COLOUR VALUE.
   ----------------------------------------------------------------------------
   Served from `public/` and linked from `index.html` ahead of every other
   stylesheet, so the tokens exist before the first paint and before the Vite
   bundle (`index.css`, `terminal.css`, `matrix-fx.css`) is parsed. Nothing else
   — no stylesheet, no component, no inline attribute, no canvas config —
   contains a hex literal, an `rgb()`, an `hsl()` or a CSS named colour. The
   canvas reads its inks back out of this file through `getComputedStyle`.

   TWO LAYERS.

   Layer 1 is the palette: four literals, and components never touch them.
   Layer 2 is the roles: named by the job the colour does, never by how it
   looks, and the only layer a component is allowed to consume. Every step
   softer than a primitive is produced by mixing a primitive toward `--ink`, so
   the ramp can never leave the palette — there is no way to introduce a fifth
   hue short of editing this block.

   CONTRAST, measured against `--ink` (#000703):
     --green-bright  14.9:1
     --green-mid      7.9:1
     --green-deep     5.5:1
   Body text needs 4.5:1 and headline figures need 7:1, so all three primitives
   clear the body floor and the top two clear the headline floor. #009a22 is
   therefore the darkest ink permitted on text: anything mixed below it is
   structural only. See `--text-faint`.
   ========================================================================== */

:root {
  /* ---- Layer 1: primitives. Literal values. Never referenced by a
     component — only by the semantic layer below. ---- */
  --green-bright: #00ff2b;
  --green-mid: #36ba01;
  --green-deep: #009a22;
  --ink: #000703;

  /* ---- Layer 2: semantic roles. The only layer components consume. ----

     THREE-TIER BRIGHTNESS HIERARCHY. Hue is gone as a way to separate
     categories, so rank is carried by brightness alone and the same three steps
     mean the same thing in every module:

       BRIGHT (--green-bright)  the datum — the figure the visitor came for
       MID    (--green-mid)     that datum's label, and the second category in
                                any two-category split
       DEEP   (--green-deep)    structural chrome — column headers, units,
                                timestamps, footer, supporting prose

     Read a screen top to bottom and the brightest thing in any group is always
     the number; the label is always one step back; the scaffolding is always
     two. */

  --bg: var(--ink);

  /* Text ramp. Only the first three may carry text. `--text-faint` is mixed
     BELOW #009a22 and so is barred from text entirely — it is the chrome tier,
     for hairlines, borders, bar tracks and inactive carets. A text element that
     wants to be quieter than `--text-muted` does not get to be: it stops at
     `--text-muted`, which is why the footer, the snapshot timestamp and
     level-2 row labels all sit there rather than one step down. */
  --text-primary: var(--green-bright); /* 14.9:1 */
  --text-secondary: var(--green-mid); /*  7.9:1 */
  --text-muted: var(--green-deep); /*  5.5:1 — the floor for any ink */
  --text-faint: color-mix(in srgb, var(--green-deep) 55%, var(--ink));

  /* The one element per view that must be seen first: the title, the tagline,
     the error state, the legend's section headings. */
  --accent: var(--green-bright);

  /* Value ramp. Parallel to the text ramp but named for what a number is worth
     rather than for how loud its surrounding copy is, so a total and a
     percentage in the same row can be ranked without either borrowing the
     other's label token. */
  --value-emphasis: var(--green-bright); /* totals, headline figures — 14.9:1 */
  --value-normal: var(--green-mid); /*  7.9:1 */
  --value-derived: var(--green-deep); /* percentages, secondary columns */

  /* Structure. `--rule` is the only thing that separates one surface from
     another: there are no lighter panel fills anywhere in this interface. It
     takes `--text-faint` rather than mixing its own near-identical step —
     hairlines and inert chrome are one tier wearing two names, and two
     independent mixes would be free to drift apart. */
  --rule: var(--text-faint);

  /* The single permitted raised surface, for the cases where a hairline cannot
     do the job on its own (hover states, and any future legend box or tooltip).
     12% of --green-deep into --ink is the ceiling — enough to register as a
     distinct plane, not enough to read as a lighter background. Always paired
     with a --rule border. */
  --surface-raised: color-mix(in srgb, var(--green-deep) 12%, var(--ink));

  /* SHARE BAR. Burn and mint sit two full brightness steps apart (14.9:1 vs
     7.9:1 against the track) rather than one, because a 6px bar is where a
     monochrome palette collapses into a single unreadable block first. The
     brightness step is backed by a NON-COLOUR CUE — see `.stats-bar-mint` in
     terminal.css, where mint is hatched and burn is a solid fill. */
  --bar-burn: var(--green-bright);
  --bar-mint: var(--green-mid);

  --focus-ring: var(--green-bright);

  /* Glow. Not decoration layered on a colour but a role of its own: a solid
     core, a mid halo and a deep outer falloff, so the bloom steps down through
     the palette instead of through an alpha ramp. */
  --glow-core: var(--green-bright);
  --glow-mid: var(--green-mid);
  --glow-outer: var(--green-deep);

  /* Matrix rain. The canvas cannot read a stylesheet, so `matrix-renderer.ts`
     and `glyph-atlas.ts` resolve these three off the canvas element with
     `getComputedStyle`. They are deliberately plain `var()` aliases of the
     primitives and never `color-mix()`: a computed custom property is returned
     with its `var()` substituted but its `color-mix()` intact, and canvas
     `fillStyle` would silently reject the latter.

     A falling stream is ONE ink. Head and trail are the same BRIGHT green and
     are told apart by the alpha ramp in `matrix-renderer.ts` alone — a stream
     is one character lit and the rest decaying behind it, not two colours in a
     row. The other two greens are the bloom under the leading glyph: MID is its
     core, DEEP its falloff. They are named for that job, since naming one of
     them `--rain-trail` once led to the trail being painted in the darker ink
     AND faded by alpha, which dimmed it twice and flattened the falloff that
     makes rain read as rain. */
  --rain-ink: var(--green-bright);
  --rain-bloom-core: var(--green-mid);
  --rain-bloom-halo: var(--green-deep);
}
