/* tokens.css — GENERATED by theme/build-tokens.mjs. Do not hand-edit.
 *
 * Mode: riffmix → single
 * Source: theme/*.ColorTheme.json, vendored byte-identical from dbo-contracts
 *         and gated by scripts/sync-themes.mjs. Derived through
 *         theme/vendor/derive.mjs — the contract's own maths, not a copy.
 * Regenerate: npm run tokens
 *
 * Four tokens are lifted here rather than taken at rest, all for WCAG 2.1 AA
 * (EN 301 549 / BFSG — a launch blocker, not a preference): --text-muted,
 * --accent-text and --link are floored at 4.5:1 for type, --border-bright at
 * 3:1 for the focus ring (1.4.11). Each is a no-op on a document that already
 * passes. The documents themselves stay byte-identical to upstream; only what
 * a browser paints changes.
 *
 * ⚠️ THE FLOORS ARE MEASURED ON THE LIGHT GROUNDS, and on the WORST of them,
 * which is not the page background: the steel band is darker than paper, so
 * a check run against --bg alone passes a tier that fails on the workbench.
 * The artifact band is the opposite polarity and cannot share one value —
 * see the void-band block at the end of this file for the arithmetic and for
 * the names it re-binds.
 */

/* SINGLE — this site wears Riffmix Bands (riffmix) and nothing else.
 * Zero JS: no picker, no media query, no runtime derivation. The page is
 * correctly themed before a single byte of script has run, which is what
 * an agent reading the rendered HTML and a visitor with JS off both get.
 */
:root {
  color-scheme: light;

  /* House constants — not theme data; identical under every theme. */
  /* design.md: default tracking is tighter than the framework default — loose reads
     decorative, tight reads confident */
  --tracking-tight: -0.011em;
  /* DESIGN.md "Mark and type": the display face is set LOWERCASE at this tracking with
     line-height under 1. Its own token because it is roughly three times --tracking-tight
     and is wrong anywhere but a display line */
  --tracking-display: -0.035em;
  /* DESIGN.md: labels, captions and nav are 11px mono at this tracking — "a plate stamped
     on a machine". The one place on this site where tracking opens rather than closes */
  --tracking-mono: 0.14em;
  /* the line length long-form copy is set to; editorial register, not full-bleed text */
  --measure: 68ch;
  /* DESIGN.md "Shape": flat rectangles and one circle. No cards, no rounded corners */
  --radius: 0;
  /* as above — kept as a name so existing var() calls stay valid, deliberately valued 0 */
  --radius-lg: 0;
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2.5rem;
  --space-5: 4rem;
  --space-6: 6rem;
  /* design.md: under 200ms, ease-out, done */
  --motion-duration: 160ms;
  --motion-ease: cubic-bezier(0, 0, 0.2, 1);

  /* ── Bands ─────────────────────────────────────────────────────
       The grounds. A band is a full-bleed field of one flat colour; there are 5 and the
       alternation between them IS the design. Not all of them are worn by a band — the
       footer has one of its own, because a floor that shares the closing band's colour does
       not read as a floor. Resolved from theme.config.json's `bands` map (dotted paths into
       this document, never duplicated hexes) and emitted as literal hex so a re-scoped
       ground cannot make a band token move.
     */
  /* SITE-DERIVED alias: surfaces.terminal */
  --band-void: #000000;
  /* SITE-DERIVED alias: surfaces.carbon */
  --band-carbon: #222220;
  /* SITE-DERIVED alias: surfaces.graphite */
  --band-graphite: #282826;
  /* SITE-DERIVED alias: surfaces.bg */
  --band-paper: #EFEFED;
  /* SITE-DERIVED alias: surfaces.surface */
  --band-steel: #C9C9C6;
  /* SITE-DERIVED alias: text.primary */
  --ink: #111111;

  /* ── Surfaces ──────────────────────────────────────────────────
       The elevation ladder. `surface-high` is the derived rung-3 midpoint of surface and
       surface-lift; nothing is drawn on surface-lift itself.
     */
  /* Canvas — The ground everything else sits on. */
  --bg: #EFEFED;
  /* Canvas 2 — First elevation step above the ground — panels, cards, sidebars. */
  --surface: #C9C9C6;
  /* Canvas 3 — The middle rung of the elevation ladder — computed, not stored. · derived:
     mix(surface, surface-lift, .5) */
  --surface-high: #C9C9C6;
  /* Canvas 4 — Top of the elevation ladder — the highest a surface sits. */
  --surface-lift: #C9C9C6;
  /* Terminal — The terminal's own canvas, and the chrome around it. */
  --terminal: #000000;
  /* Border — Normal line weight — rules and dividers. */
  --border: #A9A9A5;
  /* Border Focus — Emphasised line weight — focus rings, active edges, and a widget's own
     perimeter. · SITE-DERIVED floor: this token is the widget perimeter AND the focus ring,
     and WCAG 2.1 1.4.11 sets 3:1 for both. Lifted against the ground it is worst on. A
     no-op on all 13 documents today (dbo-contracts#7 fixed them at rest) — it is here so a
     pasted or future theme cannot reintroduce an EN 301 549 / BFSG defect. */
  --border-bright: #111111;
  /* Field — The well a text field or search box is sunk into. */
  --input: #C9C9C6;
  /* Selected — The ground behind a selected row or chosen list item. */
  --highlight: #FFD9D6;
  /* Scrim — The wash laid over content this theme does not own — video, a photo, a foreign
     surface. · derived: the theme's own darkest token, so a light theme does not scrim with
     its page colour */
  --scrim: #000000;

  /* ── Accents ───────────────────────────────────────────────────
       The fill tier is stored as authored. The two tiers a browser draws as TYPE —
       `accent-text` and `link` — carry a 4.5:1 floor, because an accent chosen to be a good
       BUTTON is not thereby a readable WORD.
     */
  /* Primary — The colour the product is about — where the eye goes. */
  --accent: #FF4F45;
  /* Primary Bright — Louder sibling of Primary. */
  --accent-bright: #FF7A72;
  /* Primary Dim — Recessive accent, clamped to a 1.8–3.2:1 contrast band — framing and
     rules, never louder than body text. */
  --accent-dim: #B23A32;
  /* SITE-DERIVED floor: the accent drawn as TYPE (a small accent word, a counter, a focus
     ring), floored at 4.5:1 against the ground it is worst on. The FILL tier above is left
     at rest — darkening a button to fix a numeral is the wrong end of the problem. */
  --accent-text: #99302A;
  /* Secondary — The second voice. */
  --secondary: #111111;
  /* Secondary Bright — Louder sibling of Secondary. */
  --secondary-bright: #3A3A38;
  /* Link — Web draws a hyperlink in this. Absent means Primary. · derived: falls back to
     accent — no document on disk stores one yet · SITE-DERIVED floor: 4.5:1 against the
     worst ground. A hyperlink is body-sized type wherever it lands, so the AA text floor is
     the one that applies. */
  --link: #99302A;

  /* ── Semantics ───────────────────────────────────────────────── */
  /* Success — Additions, passing state. */
  --success: #2E6B3A;
  /* Success Bright — Louder sibling of Success, floored so it never renders quieter. */
  --success-bright: #3E8A4C;
  /* Warning — In-flight, uncommitted state. */
  --warning: #8A5A00;
  /* Error — Deletions, failure. */
  --error: #B3261E;
  /* Error Bright — Louder sibling of Error, floored so it never renders quieter. */
  --error-bright: #C4342B;
  /* Gold — A third semantic voice — not info. ANSI slots 3 and 6. */
  --gold: #8A6410;

  /* ── Text ──────────────────────────────────────────────────────
       Ink tiers. `text-muted` is the one that fails silently, so it is the one with a
       floor.
     */
  /* Body — Body text — the ink most content is set in. */
  --text-primary: #111111;
  /* Strong — The loudest step in the text ramp. */
  --text-bright: #050505;
  /* Secondary — Quieter than Body, still fully readable. */
  --text-secondary: #4A4A46;
  /* Muted — The quietest readable step — verify contrast with maths, not by eye. ·
     SITE-DERIVED band: floored at 4.5:1 (WCAG 2.1 AA body copy / BFSG), capped at the
     primary tier so "muted" stays muted. Moves exactly one of 13 documents. */
  --text-muted: #535350;
  /* Code — Inline code and monospace runs inside prose. */
  --text-code: #2A2A26;
  /* Selection — The caret and the wash behind selected text — the ink, not the ground. */
  --text-selection: #FFD9D6;
  /* Placeholder — Ghost text in an empty field. */
  --text-placeholder: #535350;

  /* ── Over a scrim ──────────────────────────────────────────────
       A card or a headline over media the site does not own — the pattern
       @copperdesign/lazy-video-backgrounds makes a house default. The contract derives the
       TYPE colour; the accent drawn there was measured failing on 6 of 10 themes and is
       lifted here.
     */
  /* On Scrim — Body ink for type sitting on a Scrim rather than on Canvas. */
  --text-on-scrim: #EFEFED;
  /* derived: mix(scrim, on-scrim, .62) */
  --on-scrim-quiet: #949493;
  /* derived: mix(scrim, on-scrim, .42) */
  --on-scrim-quietest: #646464;
  /* SITE-DERIVED: `onScrim()`, floored at the 3:1 WCAG 1.4.11 non-text bar against the
     worst pixel a 72%-opacity card can present over white footage. */
  --accent-on-scrim: #FF594F;
  /* SITE-DERIVED: as above. */
  --secondary-on-scrim: #929292;

  /* ── Ink on a filled ground ────────────────────────────────────
       For type drawn ON one of the fills above — a CTA button, a release-note pill, a
       badge. Never store one of these; the fill is fixed by meaning, so the author has no
       lever to reach the floor with.
     */
  /* inkOn(): 4.5:1 against the fill */
  --ink-on-accent: #050505;
  /* inkOn() */
  --ink-on-secondary: #EFEFED;
  /* inkOn() */
  --ink-on-success: #EFEFED;
  /* inkOn() */
  --ink-on-warning: #EFEFED;
  /* inkOn() */
  --ink-on-error: #EFEFED;

  /* ── Typography ────────────────────────────────────────────────
       The theme NAMES families; it ships no font files. A target that has not bundled the
       face falls back — bundling one is a licensing act, and a separate decision.
     */
  --font-display: "Cabinet Grotesk", sans-serif;
  --font-body: "General Sans", sans-serif;
  --font-mono: "IBM Plex Mono", monospace;
}

/* ── THE VOID BAND (#000000) — a scope where this vocabulary changes polarity
 *
 *
 * Every floor above is measured on the LIGHT grounds, because that is
 * where reading happens. It is not a choice that both polarities could
 * have been served: 4.5:1 on #000000 needs relative luminance >= 0.175
 * and 4.5:1 on the steel band needs <= 0.090, so no single value of an
 * ink tier can clear AA on both. A token set is one polarity.
 *
 * So a dark band does not get a second vocabulary — it gets the SAME
 * NAMES, re-bound. `color: var(--ink)` and `color: var(--accent-text)`
 * are then correct on every band and no author has to remember which
 * band they are writing for. Custom properties inherit, so one class on
 * the band element reaches everything inside it.
 *
 * 🔴 THE MEASUREMENT THIS EXISTS FOR: `--accent-text` is darkened to
 * #99302A to clear 4.5:1 on the steel band, and that value is 2.81:1 on
 * black — it FAILS on a void band and cannot be made to pass there. The
 * accent at rest (#FF4F45) is already 6.46:1 on black, so that is what
 * this scope binds. Neither axe nor Lighthouse would have told you: they
 * measure a computed colour against a computed background and will report
 * whichever pairing the markup happens to produce, which on a band this
 * rule does not match is the WRONG one, silently.
 *
 * ⚠️ KEYED ON MARKUP THIS FILE DOES NOT OWN. Any one of the three
 * selectors below works; a band that carries none of them gets the light
 * ladder on a dark ground and fails contrast without a warning. If the
 * band markup uses a fourth spelling, add it to DARK_BAND_SCOPES in
 * theme/build-tokens.mjs — do not restate these values in a stylesheet.
 */
[data-band="void"],
.band-void,
.band--void {
  /* the band IS the page here */
  --bg: #000000;
  /* no cards on this site, so no second ground inside a band */
  --surface: #000000;
  /* as above */
  --surface-high: #000000;
  /* as above */
  --surface-lift: #000000;
  /* as above */
  --input: #000000;
  /* mirrored: #111111 measures its own ratio on #EFEFED, reproduced against #000000 */
  --ink: #E3E3E1;
  /* mirrored from text.primary */
  --text-primary: #E3E3E1;
  /* mirrored from text.bright */
  --text-bright: #ECECEA;
  /* mirrored from text.secondary */
  --text-secondary: #9D9D9C;
  /* mirrored from text.muted, then the same floor-and-ceiling band the light tier carries —
     at least AA, never louder than primary */
  --text-muted: #929290;
  /* mirrored from text.code */
  --text-code: #C8C8C6;
  /* the accent AT REST: it already clears 4.5:1 on the void, where the darkened
     reading-band value would fail at 2.81:1 */
  --accent-text: #FF4F45;
  /* as above — a hyperlink on an artifact band */
  --link: #FF4F45;
  /* mirrored from surfaces.border — a hairline, non-text, so no floor */
  --border: #414140;
  /* mirrored from surfaces.borderBright, floored at the 3:1 WCAG 1.4.11 bar this token
     carries everywhere: it is the FOCUS RING, and a focus ring that only works on the light
     bands is a keyboard trap with a nice look */
  --border-bright: #E3E3E1;
}

/* ── THE CARBON BAND (#222220) — a scope where this vocabulary changes polarity
 *
 * THE SECOND DARK GROUND. Same mechanism as the block above, different
 * ground — every tier below is MIRRORED and FLOORED against this band's
 * own colour, not against the void's, because both of those operations
 * are functions of the ground. A shared block would have let one band's
 * arithmetic govern the other's field, which is the same class of
 * mistake as flooring `--accent-text` against `--bg` and shipping it
 * onto steel.
 *
 * It exists because `sign` and `cta-final` were both true black, butted,
 * and read as one long black run with no boundary — and neither could go
 * light. See DARK_BAND_SCOPES.
 *
 * ⚠️ KEYED ON MARKUP THIS FILE DOES NOT OWN. Any one of the three
 * selectors below works; a band that carries none of them gets the light
 * ladder on a dark ground and fails contrast without a warning. If the
 * band markup uses a fourth spelling, add it to DARK_BAND_SCOPES in
 * theme/build-tokens.mjs — do not restate these values in a stylesheet.
 */
[data-band="carbon"],
.band-carbon,
.band--carbon {
  /* the band IS the page here */
  --bg: #222220;
  /* no cards on this site, so no second ground inside a band */
  --surface: #222220;
  /* as above */
  --surface-high: #222220;
  /* as above */
  --surface-lift: #222220;
  /* as above */
  --input: #222220;
  /* mirrored: #111111 measures its own ratio on #EFEFED, reproduced against #222220 */
  --ink: #EFEFED;
  /* mirrored from text.primary */
  --text-primary: #EFEFED;
  /* mirrored from text.bright */
  --text-bright: #EFEFED;
  /* mirrored from text.secondary */
  --text-secondary: #B5B5B3;
  /* mirrored from text.muted, then the same floor-and-ceiling band the light tier carries —
     at least AA, never louder than primary */
  --text-muted: #A8A8A6;
  /* mirrored from text.code */
  --text-code: #E4E4E2;
  /* the accent AT REST: it already clears 4.5:1 on the void, where the darkened
     reading-band value would fail at 2.81:1 */
  --accent-text: #FF4F45;
  /* as above — a hyperlink on an artifact band */
  --link: #FF4F45;
  /* mirrored from surfaces.border — a hairline, non-text, so no floor */
  --border: #525250;
  /* mirrored from surfaces.borderBright, floored at the 3:1 WCAG 1.4.11 bar this token
     carries everywhere: it is the FOCUS RING, and a focus ring that only works on the light
     bands is a keyboard trap with a nice look */
  --border-bright: #EFEFED;
}

/* ── THE GRAPHITE BAND (#282826) — a scope where this vocabulary changes polarity
 *
 * THE SECOND DARK GROUND. Same mechanism as the block above, different
 * ground — every tier below is MIRRORED and FLOORED against this band's
 * own colour, not against the void's, because both of those operations
 * are functions of the ground. A shared block would have let one band's
 * arithmetic govern the other's field, which is the same class of
 * mistake as flooring `--accent-text` against `--bg` and shipping it
 * onto steel.
 *
 * It exists because `sign` and `cta-final` were both true black, butted,
 * and read as one long black run with no boundary — and neither could go
 * light. See DARK_BAND_SCOPES.
 *
 * ⚠️ KEYED ON MARKUP THIS FILE DOES NOT OWN. Any one of the three
 * selectors below works; a band that carries none of them gets the light
 * ladder on a dark ground and fails contrast without a warning. If the
 * band markup uses a fourth spelling, add it to DARK_BAND_SCOPES in
 * theme/build-tokens.mjs — do not restate these values in a stylesheet.
 */
[data-band="graphite"],
.band-graphite,
.band--graphite {
  /* the band IS the page here */
  --bg: #282826;
  /* no cards on this site, so no second ground inside a band */
  --surface: #282826;
  /* as above */
  --surface-high: #282826;
  /* as above */
  --surface-lift: #282826;
  /* as above */
  --input: #282826;
  /* mirrored: #111111 measures its own ratio on #EFEFED, reproduced against #282826 */
  --ink: #EFEFED;
  /* mirrored from text.primary */
  --text-primary: #EFEFED;
  /* mirrored from text.bright */
  --text-bright: #EFEFED;
  /* mirrored from text.secondary */
  --text-secondary: #BCBCBA;
  /* mirrored from text.muted, then the same floor-and-ceiling band the light tier carries —
     at least AA, never louder than primary */
  --text-muted: #AFAFAD;
  /* mirrored from text.code */
  --text-code: #ECECEA;
  /* the accent AT REST: it already clears 4.5:1 on the void, where the darkened
     reading-band value would fail at 2.81:1 */
  --accent-text: #FF4F45;
  /* as above — a hyperlink on an artifact band */
  --link: #FF4F45;
  /* mirrored from surfaces.border — a hairline, non-text, so no floor */
  --border: #575755;
  /* mirrored from surfaces.borderBright, floored at the 3:1 WCAG 1.4.11 bar this token
     carries everywhere: it is the FOCUS RING, and a focus ring that only works on the light
     bands is a keyboard trap with a nice look */
  --border-bright: #EFEFED;
}

/* prefers-reduced-motion — honoured once, here, so every consumer of the
 * motion tokens inherits it instead of each stylesheet remembering to.
 * design.md treats this as part of the AA floor, not a nicety.
 */
@media (prefers-reduced-motion: reduce) {
  :root { --motion-duration: 0.01ms; }
}
