/* =========================================================================
   wireon design system — tokens (v3 / functional disruption)
   Canonical source. Vendored verbatim into every wireon.ch app.
   Re-copy whenever the version comment below bumps.

   Version: wireon-design-system v3.6.0 — see VENDOR_VERSIONS
   (v3.6.0 over v3.4.0: registers the "sesame" theme — see CHANGELOG.md.)

   v3 over v2:
     - legacy aliases (--sp-N, --ink-NN, --ok/--err, --fg-1/2/3, --bg-1/2)
       are removed. apps that haven't migrated will now break loudly — that
       is the intended signal. use --s-N, --grey-NN, --success/--danger,
       --fg/--fg-muted/--fg-meta, --bg.
     - --dur-x added (0ms — hover-invert is instantaneous by design).
     - halftone band tokens added (--ht-dot / --ht-contrast / --ht-map).

   See DESIGN_SYSTEM.md (in this repo) for the rules of use and
   components.css for base component styles built on these tokens.
   ========================================================================= */

:root {
  /* --- ink & paper ----------------------------------------------------- */
  --ink:    #000000;
  --paper:  #ffffff;

  /* --- four greys. type and rules only. never as a fill. -------------- */
  --grey-80: #1b1b1b;   /* hard rules, near-ink type            */
  --grey-60: #727272;   /* secondary type, captions             */
  --grey-30: #afafaf;   /* tertiary type, disabled labels       */
  --grey-10: #e4e4e4;   /* hairline soft dividers, table rows   */

  /* --- two semantic status colors. banners and field errors only. ---- */
  --success: #0a7a3b;
  --danger:  #c8102e;

  /* --- surface roles. the active theme's canvas + its opposite. ------
         These are what the hover-invert primitive swaps, so inversion is
         theme-relative (ADR-0028 / G2): a theme that sets a dark canvas
         sets --surface dark + --on-surface light, and every hover state
         inverts toward the *active* theme's opposite, not literal paper.
         The default (monochrome "Functional Disruption") theme maps them
         straight onto ink/paper. */
  --surface:      var(--paper);   /* resting canvas of the active theme   */
  --on-surface:   var(--ink);     /* the canvas's opposite (inversion)    */

  /* --- roles. always reference these, never the raw colors. ---------- */
  --fg:           var(--ink);
  --fg-muted:     var(--grey-60);
  --fg-meta:      var(--grey-30);
  --fg-inverse:   var(--paper);
  --bg:           var(--paper);
  --bg-inverse:   var(--ink);
  --rule:         var(--ink);          /* hairline border, 1px default     */
  --rule-strong:  var(--ink);          /* 2px section / panel-title rule   */
  --rule-soft:    var(--grey-10);      /* table-row dividers               */
  --rule-muted:   var(--grey-30);      /* faded edges, dashed empties      */

  /* --- type ------------------------------------------------------------ */
  --font-display: "Inter", "Helvetica Neue", "Helvetica", Arial, sans-serif;
  --font-ui:      "Inter", "Helvetica Neue", "Helvetica", Arial, sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --t-display: 144px;
  --t-h1:      96px;
  --t-h2:      64px;
  --t-h3:      40px;
  --t-h4:      28px;
  --t-h5:      20px;
  --t-lead:    22px;
  --t-body:    15px;
  --t-small:   13px;
  --t-xs:      11px;       /* overlines, labels, badges */

  --lh-display: 0.88;
  --lh-h1:      0.92;
  --lh-h2:      0.96;
  --lh-h3:      1.04;
  --lh-h4:      1.15;
  --lh-body:    1.55;
  --lh-tight:   1.2;

  --tr-display: -0.045em;
  --tr-tight:   -0.02em;
  --tr-normal:  0;
  --tr-wide:    0.14em;    /* overline / button / label */

  /* --- spacing. one scale. 9 steps. ----------------------------------- */
  --s-1:   4px;
  --s-2:   8px;
  --s-3:  12px;
  --s-4:  16px;
  --s-5:  24px;
  --s-6:  32px;
  --s-7:  48px;
  --s-8:  64px;
  --s-9:  96px;

  /* --- lines ---------------------------------------------------------- */
  --bw-hair:  1px;   /* default border                                  */
  --bw-rule:  2px;   /* section rule, panel title, focus ring           */
  --bw-bar:   4px;   /* page-header top edge                            */
  --bw-block: 8px;   /* graphic punctuation, never functional           */

  --radius: 0;       /* there is no other value.                        */

  /* --- motion --------------------------------------------------------- */
  --ease:          cubic-bezier(0.2, 0.8, 0.2, 1);
  --dur-x:         0ms;    /* hover-invert is instantaneous by design */
  --dur-fast:      100ms;
  --dur:           180ms;
  --dur-slow:      400ms;
  --dur-cinematic: 800ms;

  /* --- layout --------------------------------------------------------- */
  --maxw:   1440px;
  --gutter: 64px;

  /* --- pattern tunables. patterns inherit currentColor (the ink),
         so they flip with hover-invert for free.                       */
  --stripe-w:    8px;
  --stripe-gap: 12px;

  /* halftone band (pure-CSS dot screen): grid pitch + the contrast()
     threshold that 1-bits it (keep ≈1.5× the pitch). --ht-map is the
     luminance ramp that aims the gradient; variants override it.
     Pitch matches the 20px dot-wash baseline so a band laid over the wash
     shares one grid. Override inline: style="--ht-dot:16px" */
  --ht-dot:      18px;
  --ht-contrast: 26;
  --ht-map: linear-gradient(0deg, #8a8a8a, #fff);
}

/* -------------------------------------------------------------------------
   theme layer (ADR-0028 / G1)
   ---------------------------------------------------------------------------
   :root above IS the default theme — monochrome "Functional Disruption".
   A theme overrides token *values* under a [data-wireon-theme="<id>"]
   selector; it never adds new token names and apps never redeclare tokens
   locally (INVARIANTS #13 stays a global hard floor). Set the attribute on
   <html> (or any subtree) from the resolved per-(app,user) preference; with
   no attribute, or an unknown id, the monochrome default applies.

   A theme owns the full set — colour, radius, spacing, type, hover. The
   minimum a colour theme sets is the four primitives the roles derive from
   (--ink, --paper, the greys, the status pair) plus the two surface roles
   so hover-invert stays theme-relative. Accessibility (#18) is a global
   floor every theme must clear.

   Registration template (a real theme lives in this file, so every
   consumer picks it up at re-vendor):

     [data-wireon-theme="my-theme"] {
       --ink:    #...;   --paper:  #...;
       --grey-80: #...;  --grey-60: #...;  --grey-30: #...;  --grey-10: #...;
       --success: #...;  --danger:  #...;
       --surface: var(--paper);  --on-surface: var(--ink);
       --radius: 0;      // themes may change this
     }

   Because the role tokens (--fg, --bg, --rule, …) and the surface roles
   reference the primitives via var(), overriding the primitives cascades
   through every component for free. A theme that wants a tinted canvas
   distinct from its brand ink/paper may set --surface / --on-surface
   directly.
   ------------------------------------------------------------------------- */

/* monochrome — the :root default, registered explicitly so a SUBTREE can
   opt back into it inside a themed page (e.g. the theme-switcher's swatch
   previews: each swatch carries data-wireon-theme="<id>" and must show
   that theme's ink/paper regardless of the page's active theme). On <html>
   the attribute is simply absent for monochrome; values mirror :root. */
[data-wireon-theme="monochrome"] {
  --ink:    #000000;
  --paper:  #ffffff;

  --grey-80: #1b1b1b;
  --grey-60: #727272;
  --grey-30: #afafaf;
  --grey-10: #e4e4e4;

  --success: #0a7a3b;
  --danger:  #c8102e;

  --surface:    var(--paper);
  --on-surface: var(--ink);
}

/* inkwell — the canonical dark theme (ADR-0028 / G2 reference). Inverts the
   monochrome canvas: a near-ink paper with light ink. Because the role and
   surface tokens derive from these primitives via var(), the whole system
   flips for free and hover-invert stays theme-relative (swaps toward the
   active theme's light opposite, not literal white). Registered in
   themes.json so the theme-switcher surface (E2) lists it. */
[data-wireon-theme="inkwell"] {
  --ink:    #f4f4f4;   /* "ink" is now light — type/rules on the dark canvas */
  --paper:  #141414;   /* the dark canvas                                    */

  --grey-80: #e4e4e4;  /* hard rules, near-ink type   */
  --grey-60: #9a9a9a;  /* secondary type, captions    */
  --grey-30: #5a5a5a;  /* tertiary type, disabled     */
  --grey-10: #2a2a2a;  /* hairline soft dividers      */

  --success: #4ade80;
  --danger:  #f87171;

  --surface:    var(--paper);   /* dark resting canvas        */
  --on-surface: var(--ink);     /* light opposite (inversion) */
}

/* verdigris — a tinted-paper light theme (ADR-0028). Proof that theming
   generalises beyond "invert the canvas": warm paper, deep verdigris ink.
   The accent rides through --ink (buttons, rules, fills are ink by rule),
   so no component changes — only these primitives. Status pair re-tuned
   to sit on the tinted paper (all pairs clear the AA floor: ink 9.6:1,
   grey-60 5.1:1, success 5.7:1, danger 5.2:1). Registered in themes.json
   so the theme-switcher surface (E2) lists it. */
[data-wireon-theme="verdigris"] {
  --ink:    #14433c;   /* deep verdigris — type, rules, fills          */
  --paper:  #f3efe4;   /* warm tinted paper                            */

  --grey-80: #20514a;  /* hard rules, near-ink type   */
  --grey-60: #54695f;  /* secondary type, captions    */
  --grey-30: #a9b3a4;  /* tertiary type, disabled     */
  --grey-10: #e4dfcf;  /* hairline soft dividers      */

  --success: #0e6b45;
  --danger:  #b23a1d;

  --surface:    var(--paper);   /* tinted resting canvas       */
  --on-surface: var(--ink);     /* verdigris opposite (invert) */
}

/* sesame — a warm bakery light theme (ADR-0028). Espresso ink on
   sesame-cream paper, with the radius the theme owns turned on (ADR-0028:
   zero radius is the monochrome theme's brand, not a global rule) and a
   grotesque type pairing carried through the font tokens (families fall
   back to the Inter/system stack wherever an app does not ship the font
   files — themes set token VALUES only, they never load assets).
   Status pair re-tuned for the cream paper; all text pairs clear the AA
   floor (ink 13.6:1, grey-60 5.4:1, success 5.2:1, danger 5.0:1).
   Registered in themes.json so the theme-switcher surface (E2) lists it. */
[data-wireon-theme="sesame"] {
  --ink:    #2a1e15;   /* espresso — type, rules, fills           */
  --paper:  #f3eadb;   /* sesame-cream canvas                     */

  --grey-80: #3d2f22;  /* hard rules, near-ink type   */
  --grey-60: #6b5d49;  /* secondary type, captions    */
  --grey-30: #a3947f;  /* tertiary type, disabled     */
  --grey-10: #e8ddc9;  /* hairline soft dividers      */

  --success: #2f6e3b;
  --danger:  #b5351f;

  --surface:    var(--paper);   /* warm resting canvas         */
  --on-surface: var(--ink);     /* espresso opposite (invert)  */

  --radius: 12px;

  --font-display: "Bricolage Grotesque", "Inter", "Helvetica Neue",
                  "Helvetica", Arial, sans-serif;
  --font-ui:      "Hanken Grotesk", "Inter", "Helvetica Neue",
                  "Helvetica", Arial, sans-serif;
}

/* The default (monochrome) theme is light and ignores the OS colour
   scheme; a registered dark theme (ADR-0028) may override color-scheme
   inside its own [data-wireon-theme] block. */
:root { color-scheme: light; }

::selection { background: var(--ink); color: var(--paper); }

/* Respect reduced-motion. Animations collapse to a near-zero duration;
   transitions stay long enough that focus/state changes are perceptible. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}
