/* tokens.css — GENERATED by theme/build-tokens.mjs. Do not hand-edit.
 *
 * Mode: picker
 * 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
 *
 * Two tokens are lifted here rather than taken at rest, both for WCAG 2.1 AA
 * (EN 301 549 / BFSG — a launch blocker, not a preference): --text-muted is
 * floored at 4.5:1 for body copy, --border-bright at 3:1 for the focus ring
 * (1.4.11). Both are no-ops on a document that already passes; across the 13
 * vendored documents exactly one value moves. The documents themselves stay
 * byte-identical to upstream.
 */

/* PAIRED — Base (base) at rest, Base Night (base-night) when the OS asks for dark.
 *
 * The pairing is APP CONFIG (theme.config.json), not a theme property —
 * neither document knows about the other. Which pole each belongs in is
 * COMPUTED from WCAG relative luminance of surfaces.bg; no theme carries a
 * `type` field and the schema forbids adding one.
 *
 * Zero JS. prefers-color-scheme is the browser telling the page what the
 * OS already decided; no script has to ask.
 */
:root {
  color-scheme: light dark;

  /* 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;
  /* the line length long-form copy is set to; editorial register, not full-bleed text */
  --measure: 68ch;
  --radius: 8px;
  --radius-lg: 14px;
  --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);

  /* ── 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: #FFFFFF;
  /* Canvas 2 — First elevation step above the ground — panels, cards, sidebars. */
  --surface: #F5F5F5;
  /* Canvas 3 — The middle rung of the elevation ladder — computed, not stored. · derived:
     mix(surface, surface-lift, .5) */
  --surface-high: #F2F2F2;
  /* Canvas 4 — Top of the elevation ladder — the highest a surface sits. */
  --surface-lift: #EFEFEF;
  /* Terminal — The terminal's own canvas, and the chrome around it. */
  --terminal: #FFFFFF;
  /* Border — Normal line weight — rules and dividers. */
  --border: #E6E6E6;
  /* 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: #8A8A8A;
  /* Field — The well a text field or search box is sunk into. */
  --input: #F2F2F2;
  /* Selected — The ground behind a selected row or chosen list item. */
  --highlight: #1E6BFF;
  /* 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 ─────────────────────────────────────────────────── */
  /* Primary — The colour the product is about — where the eye goes. */
  --accent: #1E6BFF;
  /* Primary Bright — Louder sibling of Primary. */
  --accent-bright: #0050E6;
  /* Primary Dim — Recessive accent, clamped to a 1.8–3.2:1 contrast band — framing and
     rules, never louder than body text. */
  --accent-dim: #A9C4FF;
  /* Primary — The colour the product is about — where the eye goes. · SITE-DERIVED floor:
     `--accent` used as TEXT, lifted to WCAG 1.4.3's 3:1 large-text bar against the ground
     it is worst on. `--accent` itself is unchanged and stays the fill. */
  --accent-on-bg: #1E6BFF;
  /* Primary — The colour the product is about — where the eye goes. · SITE-DERIVED floor:
     `--accent` used as SMALL TEXT (WCAG 1.4.3, 4.5:1) — the showcase's column-label tone.
     Separate from `--accent-on-bg` (3:1, large text) for the reason above. */
  --accent-text: #1C65F0;
  /* Secondary — The second voice. */
  --secondary: #3A3A3C;
  /* Secondary Bright — Louder sibling of Secondary. */
  --secondary-bright: #1C1C1E;
  /* Link — Web draws a hyperlink in this. Absent means Primary. · derived: falls back to
     accent — no document on disk stores one yet */
  --link: #1E6BFF;

  /* ── Semantics ───────────────────────────────────────────────── */
  /* Success — Additions, passing state. */
  --success: #2E7D32;
  /* Success Bright — Louder sibling of Success, floored so it never renders quieter. */
  --success-bright: #1B5E20;
  /* Warning — In-flight, uncommitted state. */
  --warning: #F59E0B;
  /* Error — Deletions, failure. */
  --error: #E5484D;
  /* Error Bright — Louder sibling of Error, floored so it never renders quieter. */
  --error-bright: #C62D33;
  /* Gold — A third semantic voice — not info. ANSI slots 3 and 6. */
  --gold: #F5C518;
  /* Success — Additions, passing state. · SITE-DERIVED floor: `--success` used as SMALL
     TEXT (WCAG 1.4.3, 4.5:1) — see `--accent-text` above. */
  --success-text: #2E7D32;
  /* Error — Deletions, failure. · SITE-DERIVED floor: `--error` used as SMALL TEXT (WCAG
     1.4.3, 4.5:1) — see `--accent-text` above. */
  --error-text: #C63E43;

  /* ── 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: #000000;
  /* Strong — The loudest step in the text ramp. */
  --text-bright: #000000;
  /* Secondary — Quieter than Body, still fully readable. */
  --text-secondary: #3A3A3C;
  /* 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: #6B6B6B;
  /* Code — Inline code and monospace runs inside prose. */
  --text-code: #3A3A3C;
  /* Selection — The caret and the wash behind selected text — the ink, not the ground. */
  --text-selection: #1E6BFF;
  /* Placeholder — Ghost text in an empty field. */
  --text-placeholder: #6B6B6B;

  /* ── 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: #FFFFFF;
  /* derived: mix(scrim, on-scrim, .62) */
  --on-scrim-quiet: #9E9E9E;
  /* derived: mix(scrim, on-scrim, .42) */
  --on-scrim-quietest: #6B6B6B;
  /* 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: #558FFF;
  /* SITE-DERIVED: as above. */
  --secondary-on-scrim: #929293;

  /* ── 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: #000000;
  /* SITE-DERIVED: `inkOn()` against the HOVER fill. `--ink-on-accent` is derived against
     `accents.accent` and is wrong on `accents.accentBright` for every theme whose bright
     sibling is darker than its accent — which is every light theme. */
  --ink-on-accent-bright: #FFFFFF;
  /* inkOn() */
  --ink-on-secondary: #FFFFFF;
  /* inkOn() */
  --ink-on-success: #FFFFFF;
  /* inkOn() */
  --ink-on-warning: #000000;
  /* inkOn() */
  --ink-on-error: #000000;

  /* ── Typography ────────────────────────────────────────────────
       SITE-MAINTAINED and identical across all 14 themes: a theme changes colour, never
       type. The documents' own `typography` blocks are not read — the site bundles no font
       files, so a named face it has not loaded would silently fall back (most of them to
       Georgia).
     */
  /* site-maintained; not derived from the theme document */
  --font-display: Inter, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  /* site-maintained; not derived from the theme document */
  --font-body: Inter, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  /* site-maintained; not derived from the theme document */
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000000;
    --surface: #141414;
    --surface-high: #1D1D1D;
    --surface-lift: #262626;
    --terminal: #000000;
    --border: #1F1F1F;
    --border-bright: #7A7A7A;
    --input: #1D1D1D;
    --highlight: #1E6BFF;
    --scrim: #000000;
    --accent: #1E6BFF;
    --accent-bright: #4D8BFF;
    --accent-dim: #16367A;
    --accent-on-bg: #1E6BFF;
    --accent-text: #3B7EFF;
    --secondary: #C7C7CC;
    --secondary-bright: #E5E5EA;
    --link: #1E6BFF;
    --success: #30D158;
    --success-bright: #5BE07D;
    --warning: #F59E0B;
    --error: #E5484D;
    --error-bright: #FF6369;
    --gold: #F5C518;
    --success-text: #30D158;
    --error-text: #E64F54;
    --text-primary: #FFFFFF;
    --text-bright: #FFFFFF;
    --text-secondary: #C7C7CC;
    --text-muted: #9A9A9A;
    --text-code: #C7C7CC;
    --text-selection: #1E6BFF;
    --text-placeholder: #9A9A9A;
    --text-on-scrim: #FFFFFF;
    --on-scrim-quiet: #9E9E9E;
    --on-scrim-quietest: #6B6B6B;
    --accent-on-scrim: #558FFF;
    --secondary-on-scrim: #C7C7CC;
    --ink-on-accent: #000000;
    --ink-on-accent-bright: #000000;
    --ink-on-secondary: #000000;
    --ink-on-success: #000000;
    --ink-on-warning: #000000;
    --ink-on-error: #000000;
    --font-display: Inter, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
    --font-body: Inter, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
    --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
  }
}

/* PICKER — every vendored document, selectable at runtime.
 *
 * `:root[data-theme="…"]` (specificity 0,1,1) outranks both the bare
 * `:root` above and the media-query copy of it (a media query adds no
 * specificity), so an explicit choice always wins over the OS pairing and
 * the pairing is what an untouched first visit gets.
 *
 * 🔴 Every theme is emitted as CSS here, so the browser never derives
 * anything: theme-picker.js only ever writes one attribute. That keeps the
 * AI-first bar — the rendered HTML is fully themed with JS off — and it is
 * why the picker deliberately does not apply colours itself ("the picker
 * chooses, the host derives"; here the host derived at build time).
 *
 * ⭐ EACH BLOCK CARRIES TWO SELECTORS, and the second is what lets a SUBTREE
 * wear a theme the page is not wearing. `:root[data-theme]` can only ever
 * dress the whole document; `[data-theme]` on its own dresses any element,
 * and every token below then resolves against THAT element for everything
 * inside it. That is what a site needs to draw an app whose panes each wear
 * their own theme — dboio/terminal-c#112, where a project's theme "begins
 * at a pane and stops at its edge" (ContentView.swift:862).
 *
 * ⚠️ Written as a selector LIST rather than as a bare `[data-theme]`, so the
 * root case keeps its 0,1,1 and the guarantee in the paragraph above is
 * unchanged. Each complex selector in a list matches with its own
 * specificity; dropping `:root[…]` would quietly demote the root case to
 * 0,1,0 and put it back in a tie with the media-query pairing.
 */

:root[data-theme="base-night"],
[data-theme="base-night"] {
  --bg: #000000;
  --surface: #141414;
  --surface-high: #1D1D1D;
  --surface-lift: #262626;
  --terminal: #000000;
  --border: #1F1F1F;
  --border-bright: #7A7A7A;
  --input: #1D1D1D;
  --highlight: #1E6BFF;
  --scrim: #000000;
  --accent: #1E6BFF;
  --accent-bright: #4D8BFF;
  --accent-dim: #16367A;
  --accent-on-bg: #1E6BFF;
  --accent-text: #3B7EFF;
  --secondary: #C7C7CC;
  --secondary-bright: #E5E5EA;
  --link: #1E6BFF;
  --success: #30D158;
  --success-bright: #5BE07D;
  --warning: #F59E0B;
  --error: #E5484D;
  --error-bright: #FF6369;
  --gold: #F5C518;
  --success-text: #30D158;
  --error-text: #E64F54;
  --text-primary: #FFFFFF;
  --text-bright: #FFFFFF;
  --text-secondary: #C7C7CC;
  --text-muted: #9A9A9A;
  --text-code: #C7C7CC;
  --text-selection: #1E6BFF;
  --text-placeholder: #9A9A9A;
  --text-on-scrim: #FFFFFF;
  --on-scrim-quiet: #9E9E9E;
  --on-scrim-quietest: #6B6B6B;
  --accent-on-scrim: #558FFF;
  --secondary-on-scrim: #C7C7CC;
  --ink-on-accent: #000000;
  --ink-on-accent-bright: #000000;
  --ink-on-secondary: #000000;
  --ink-on-success: #000000;
  --ink-on-warning: #000000;
  --ink-on-error: #000000;
  --font-display: Inter, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-body: Inter, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
}

:root[data-theme="base"],
[data-theme="base"] {
  --bg: #FFFFFF;
  --surface: #F5F5F5;
  --surface-high: #F2F2F2;
  --surface-lift: #EFEFEF;
  --terminal: #FFFFFF;
  --border: #E6E6E6;
  --border-bright: #8A8A8A;
  --input: #F2F2F2;
  --highlight: #1E6BFF;
  --scrim: #000000;
  --accent: #1E6BFF;
  --accent-bright: #0050E6;
  --accent-dim: #A9C4FF;
  --accent-on-bg: #1E6BFF;
  --accent-text: #1C65F0;
  --secondary: #3A3A3C;
  --secondary-bright: #1C1C1E;
  --link: #1E6BFF;
  --success: #2E7D32;
  --success-bright: #1B5E20;
  --warning: #F59E0B;
  --error: #E5484D;
  --error-bright: #C62D33;
  --gold: #F5C518;
  --success-text: #2E7D32;
  --error-text: #C63E43;
  --text-primary: #000000;
  --text-bright: #000000;
  --text-secondary: #3A3A3C;
  --text-muted: #6B6B6B;
  --text-code: #3A3A3C;
  --text-selection: #1E6BFF;
  --text-placeholder: #6B6B6B;
  --text-on-scrim: #FFFFFF;
  --on-scrim-quiet: #9E9E9E;
  --on-scrim-quietest: #6B6B6B;
  --accent-on-scrim: #558FFF;
  --secondary-on-scrim: #929293;
  --ink-on-accent: #000000;
  --ink-on-accent-bright: #FFFFFF;
  --ink-on-secondary: #FFFFFF;
  --ink-on-success: #FFFFFF;
  --ink-on-warning: #000000;
  --ink-on-error: #000000;
  --font-display: Inter, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-body: Inter, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
}

/* 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; }
}
