/* signal — graphite and one live cobalt. Structure lives in tokens.css;
   this file is colour, type and shape.

   ── Direction ─────────────────────────────────────────────────────────
   THESIS: contrast is spent, not sprinkled. One cobalt marks the place a
   decision is being made and nothing else borrows it. The arrangement
   this refuses is the default product-dashboard palette — mid-grey text,
   an accent tint smeared across every surface, and pillowy corners that
   make a destructive button look like a suggestion.
   OWN-WORLD: an anodised instrument faceplate. Cool graphite neutrals
   with a blue undertone, silk-screened labels, one cobalt indicator that
   reads as powered. Corners are cut, not moulded — 4px and 2px, the
   radius of a milled edge. Shadows are short and dense: a panel seated
   on a panel, never floating over it. Type is grotesk-first, the
   workshop label face rather than a display serif.
   MODE: operate. Assertive is not the same as loud — the page is calm
   graphite until something is actionable, and then it is unmistakable.
   RISK, stated: near-black plus one bright accent is a well-worn look,
   and the way this earns its own ground is restraint plus the shape
   axis, not a brighter blue. If a screen ends up with cobalt in four
   places, the theme is being used against its grain.
   FINISH: every pair in both schemes is measured below and gated by
   ui/contrast_test.go; the direction above is the contract the palette
   is audited against.

   ── One block, both schemes ───────────────────────────────────────────
   Every token is declared once, as light-dark(<light>, <dark>), under a
   single :root that sets color-scheme: light dark. The two rules at the
   bottom are the whole toggle: setting color-scheme on
   :root[data-theme=…] re-resolves every light-dark() in the file at
   once, in both directions. Tokens with one value in both schemes — the
   font stack, the radii — are written plain.

   light-dark() is a colour function: it may only stand where a <color>
   is expected. So a shadow token wraps its colour in it and writes the
   geometry once, outside the call — `0 4px 10px light-dark(a, b)`, never
   `light-dark(0 4px 10px a, …)`, which no browser would accept as a
   box-shadow.

   ── WCAG 2.2 AA, measured ─────────────────────────────────────────────
   Normal text needs 4.5:1; large text and UI component boundaries need
   3:1. Every pair below was computed from these exact hex values, in
   both schemes. If you change a token, recompute its rows.

   LIGHT                                     ratio      requirement
     --rst-text        on --rst-surface       19.32      4.5:1  text
     --rst-text        on --rst-bg            17.72      4.5:1  text
     --rst-text        on --rst-surface-2     16.93      4.5:1  text
     --rst-text        on --rst-accent-soft   16.68      4.5:1  text
     --rst-text-muted  on --rst-surface        8.76      4.5:1  text
     --rst-text-muted  on --rst-bg             8.04      4.5:1  text
     --rst-text-muted  on --rst-surface-2      7.68      4.5:1  text
     --rst-text-muted  on --rst-accent-soft    7.57      4.5:1  text
     --rst-text-faint  on --rst-surface        6.13      4.5:1  text
     --rst-text-faint  on --rst-bg             5.62      4.5:1  text
     --rst-text-faint  on --rst-surface-2      5.37      4.5:1  text
     --rst-text-faint  on --rst-accent-soft    5.29      4.5:1  text
     --rst-accent      on --rst-surface        5.50      4.5:1  text + focus ring
     --rst-accent      on --rst-bg             5.04      4.5:1  text + focus ring
     --rst-accent      on --rst-surface-2      4.82      4.5:1  text
     --rst-accent      on --rst-accent-soft    4.75      4.5:1  text
     --rst-on-accent   on --rst-accent         5.50      4.5:1  button label
     --rst-on-accent   on --rst-accent-strong  7.77      4.5:1  button label, hover
     --rst-line-strong on --rst-surface        4.70      3:1    control border
     --rst-line-strong on --rst-bg             4.31      3:1    control border
     --rst-line-strong on --rst-surface-2      4.12      3:1    control border
     pill neutral  fg on its own tint          8.36      4.5:1  text
     pill positive fg on its own tint          6.07      4.5:1  text
     pill warning  fg on its own tint          6.21      4.5:1  text
     pill negative fg on its own tint          6.00      4.5:1  text
     --rst-on-accent   on negative fg (fill)   7.58      4.5:1  danger button label

   DARK                                      ratio      requirement
     --rst-text        on --rst-surface       15.05      4.5:1  text
     --rst-text        on --rst-bg            16.30      4.5:1  text
     --rst-text        on --rst-surface-2     15.59      4.5:1  text
     --rst-text        on --rst-accent-soft   14.47      4.5:1  text
     --rst-text-muted  on --rst-surface        7.85      4.5:1  text
     --rst-text-muted  on --rst-bg             8.51      4.5:1  text
     --rst-text-muted  on --rst-surface-2      8.14      4.5:1  text
     --rst-text-muted  on --rst-accent-soft    7.55      4.5:1  text
     --rst-text-faint  on --rst-surface        6.58      4.5:1  text
     --rst-text-faint  on --rst-bg             7.13      4.5:1  text
     --rst-text-faint  on --rst-surface-2      6.82      4.5:1  text
     --rst-text-faint  on --rst-accent-soft    6.33      4.5:1  text
     --rst-accent      on --rst-surface        6.06      4.5:1  text + focus ring
     --rst-accent      on --rst-bg             6.56      4.5:1  text + focus ring
     --rst-accent      on --rst-surface-2      6.28      4.5:1  text
     --rst-accent      on --rst-accent-soft    5.82      4.5:1  text
     --rst-on-accent   on --rst-accent         6.79      4.5:1  button label
     --rst-on-accent   on --rst-accent-strong  9.77      4.5:1  button label, hover
     --rst-line-strong on --rst-surface        4.65      3:1    control border
     --rst-line-strong on --rst-bg             5.03      3:1    control border
     --rst-line-strong on --rst-surface-2      4.81      3:1    control border
     pill neutral  fg on its own tint          9.26      4.5:1  text
     pill positive fg on its own tint          9.07      4.5:1  text
     pill warning  fg on its own tint         10.00      4.5:1  text
     pill negative fg on its own tint          7.84      4.5:1  text
     --rst-on-accent   on negative fg (fill)   9.25      4.5:1  danger button label

   The tightest pair in the set is --rst-accent on --rst-accent-soft in
   light, at 4.75:1 against a 4.5:1 floor — the cobalt is as bright as it
   can be and still be readable as text on its own tint. Lighten it and
   the gate goes red; that is the intended tension.

   --rst-line is a hairline divider, not a control border, so 1.4.11's
   3:1 does not apply to it. Control borders use --rst-line-strong.

   --rst-header-rule is not in the table either, and deliberately so
   (design doc §6-v2.2): the page header's rule is decoration, not
   structure — the heading's size, weight and spacing carry the
   structure — so no contrast floor applies to it and it is not in
   ui/contrast_test.go's pair table. Do not argue it up to 3:1.

   --rst-shadow-pop, --rst-shadow-knob, --rst-shadow-lift and
   --rst-overlay are not in the table: they paint a translucent layer
   over whatever sits underneath, not text over a fixed background, so a
   contrast ratio does not apply.
   ──────────────────────────────────────────────────────────────────── */

:root {
  color-scheme: light dark;

  /* Type: grotesk first, on purpose. The stack asks for the neutral
     workhorse grotesks a machine actually has before it falls back to
     whatever the platform calls its UI face. No webfont: a theme is one
     stylesheet and must not open a connection. */
  --rst-font: "Helvetica Neue", Helvetica, "Segoe UI Variable Text", "Segoe UI", Roboto, Arial, ui-sans-serif, system-ui, sans-serif;

  /* Shape: milled, not moulded. */
  --rst-radius: 4px;
  --rst-radius-sm: 2px;
  --rst-radius-pill: 999px;

  /* Surfaces and lines: graphite with a blue undertone, so the cobalt
     reads as the only warm-running thing on the panel. */
  --rst-bg: light-dark(#f4f5f8, #0b0d10);
  --rst-surface: light-dark(#ffffff, #14171c);
  --rst-surface-2: light-dark(#eef0f4, #101318);
  --rst-line: light-dark(#dde0e7, #232830);
  --rst-line-strong: light-dark(#6d7482, #7b828f);

  /* The page header's rule, derived rather than authored: the cobalt
     folded into the line at 45%, so a theme that changes its accent
     gets a matching rule with no second value to keep in step. signal
     spends the tint it earns — the rule is visibly blue, which is the
     loudest this theme is anywhere it is not asking for a click.
     Decorative: it carries no contrast floor. */
  --rst-header-rule: color-mix(in oklab, var(--rst-accent) 45%, var(--rst-line));

  /* Text */
  --rst-text: light-dark(#0c0e12, #e9ebef);
  --rst-text-muted: light-dark(#454b57, #a4acb9);
  --rst-text-faint: light-dark(#5b6270, #959dac);

  /* Accent: one electric cobalt. It appears where a decision is made and
     nowhere else. */
  --rst-accent: light-dark(#1a56ff, #6d90ff);
  --rst-accent-strong: light-dark(#0f3fd6, #9ab2ff);
  --rst-accent-soft: light-dark(#e9eeff, #121a30);
  --rst-on-accent: light-dark(#ffffff, #05070d);

  /* Status tones: saturated and unambiguous. A pill is never the
     accent, so an error can never read as a link. */
  --rst-tone-neutral-fg: light-dark(#3b414d, #c6cdd8);
  --rst-tone-neutral-bg: light-dark(#e6e8ee, #232830);
  --rst-tone-positive-fg: light-dark(#08624a, #4fdba2);
  --rst-tone-positive-bg: light-dark(#d6efe6, #082720);
  --rst-tone-warning-fg: light-dark(#7a4708, #f3c669);
  --rst-tone-warning-bg: light-dark(#f8e5c2, #2a2009);
  --rst-tone-negative-fg: light-dark(#a8121f, #ff8f99);
  --rst-tone-negative-bg: light-dark(#fbdee0, #2e1418);

  /* Depth: short throw, tight blur, high alpha. Seated, not floating. */
  --rst-shadow-pop: 0 4px 10px light-dark(rgba(12, 14, 18, 0.22), rgba(0, 0, 0, 0.62));
  --rst-shadow-knob: 0 1px 2px light-dark(rgba(12, 14, 18, 0.45), rgba(0, 0, 0, 0.6));
  --rst-shadow-lift: 0 1px 2px light-dark(rgba(12, 14, 18, 0.2), rgba(0, 0, 0, 0.5));
  --rst-overlay: light-dark(rgba(9, 11, 16, 0.55), rgba(3, 4, 7, 0.72));
}

/* The whole toggle. Setting color-scheme re-resolves every light-dark()
   above, so an explicit choice beats the OS in both directions without
   restating a colour. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }
