/* ============================================================
   F2 Technologies - Design Tokens  ·  v1.7
   The brand manual defines these decisions; the design system
   implements them. Keep these names stable across code + manual.
   Flat system — no gradients.

   v1.2 upstreams the design-system additions: type scale + weights,
   spacing scale, grid aliases, containers, pill radius, border width,
   elevation, focus ring — plus deprecated pre-1.2 aliases.

   Three layers:
     1. PRIMITIVE  raw, theme-agnostic values  (--f2-ink, --f2-amber …)
     2. SEMANTIC   purpose aliases that FLIP per theme  (--f2-surface, --f2-text …)
     3. COMPONENT  component contracts built on semantics  (--f2-btn-bg …)

   Theming:
     :root                       → dark (brand default — matches the manual)
     [data-theme="light"]        → light
     [data-theme="dark"]         → explicit dark
     [data-theme="auto"]         → follows the OS via prefers-color-scheme
   Only the SEMANTIC layer is redefined per theme; component + primitive
   tokens are declared once and resolve through the semantic layer.

   Accent note: amber as a FILL (ink text on top) passes AAA on both
   themes, but amber as TEXT on a light surface can't pass WCAG — so the
   accent splits into --f2-accent (fill) and --f2-accent-text (foreground),
   and only the text role darkens to amber-deep on light.
   ============================================================ */

:root {
  /* ========================================================
     LAYER 1 — PRIMITIVES  (raw values, never theme-dependent)
     ======================================================== */

  /* --- Core brand --- */
  --f2-ink:            #101216; /* primary dark surface          */
  --f2-bone:           #ECEAE2; /* primary text / light surface  */
  --f2-amber:          #E59A3C; /* Signal Amber — the only accent */

  /* --- Ink ramp (dark surfaces + dark text, derived from ink) --- */
  --f2-ink-900:        #0B0D11; /* deepest / sunken              */
  --f2-ink-800:        #101216; /* base dark surface             */
  --f2-ink-700:        #15181E; /* raised surface                */
  --f2-ink-600:        #1B1F26; /* card surface                  */
  --f2-ink-500:        #2A2F38; /* hairline-strong / secondary text on light */
  --f2-ink-400:        #3C414B; /* disabled edge / muted text on light */

  /* --- Gray ramp (text / labels) --- */
  --f2-gray-500:       #6E727C; /* faint labels                  */
  --f2-gray-400:       #8B8F99; /* secondary text on dark        */
  --f2-gray-300:       #A6A9B2; /* body on dark                  */
  --f2-gray-200:       #C7C8CE; /* high-emphasis secondary       */

  /* --- Paper ramp (light surfaces, derived from bone) — NEW in 1.1 --- */
  --f2-paper-100:      #F6F5F0; /* raised / card on light        */
  --f2-paper-200:      #ECEAE2; /* base light surface (= bone)    */
  --f2-paper-300:      #DEDBD0; /* sunken / subtle fill on light */
  --f2-paper-400:      #CFCBBE; /* hairline-strong on light      */
  --f2-paper-500:      #B7B2A3; /* faint / disabled edge on light */

  /* --- Amber tints --- */
  --f2-amber-soft:     #1B1610; /* amber-tinted surface on dark  */
  --f2-amber-wash:     #FBF1E2; /* amber-tinted surface on light — NEW */
  --f2-amber-press:    #C57E2E; /* amber pressed / fill hover    */
  --f2-amber-deep:     #9A5A14; /* accent TEXT on light (AA 4.53:1) — NEW */

  /* --- Chart series (PRODUCT UI ONLY — never marketing) — NEW in 1.4 ---
     Blue and violet are barred from brand and marketing surfaces; these exist
     so an interface can tell one data series from another, the same carve-out
     the status colours already have. After the 3:1 contrast floor, marks on ink
     sit in a lightness window ~0.115 wide, so hue has to carry identity — and
     green/yellow/orange/red are all spoken for by amber and the status trio.
     230–335° is the only arc left, and it holds exactly three. */
  --f2-azure:          #1C97F3; /* series 1 on dark              */
  --f2-azure-deep:     #1375BF; /* series 1 on light             */
  --f2-magenta:        #AF38A9; /* series 2 on dark              */
  --f2-magenta-deep:   #890F85; /* series 2 on light             */
  --f2-indigo:         #6659E2; /* series 3 on dark              */
  --f2-indigo-deep:    #4B35BC; /* series 3 on light             */

  /* --- Sequential ramp (one hue, azure, light → dark) — NEW in 1.4 ---
     For magnitude, not identity. Steps 400/500 are the series-1 values, so a
     chart mixing a series with a ramp stays in one family. */
  --f2-seq-100:        #D7EAFE;
  --f2-seq-200:        #ABD4FD;
  --f2-seq-300:        #6EB7FB;
  --f2-seq-400:        var(--f2-azure);      /* = series 1, dark  */
  --f2-seq-500:        var(--f2-azure-deep); /* = series 1, light */
  --f2-seq-600:        #0C5891;
  --f2-seq-700:        #063F6B;

  /* --- Status (flat, restrained) ---
     FILLS. Shared across themes, and unchanged: these are what a badge
     background, a chart mark or a border is drawn with, at any tint.
     For status as TEXT see the -deep trio below. */
  --f2-success:        #4FA873;
  --f2-warning:        #E0B341;
  --f2-error:          #D85C57;

  /* --- Status TEXT on light - NEW in 1.5 ---
     The same split amber has had since 1.1, applied to the status trio.
     The fills above were designed against ink and never re-stepped for bone,
     so used as *text* on a light surface they measure 2.17:1 (success),
     1.52:1 (warning) and 2.68:1 (error) - all far below AA. Derived by
     holding each hue and walking OKLab lightness down until the result clears
     4.5:1 both on bone and on the 14%-tinted badge surface it sits in:
     5.66 / 5.64 / 5.74 on bone, 5.05 / 5.25 / 4.94 on the tint, hue drift 0°.
     warning-deep sits ΔE 7.5 from amber-deep, wider than the 6.1 the fills
     already had, so "warning is held distinct from Signal Amber" survives. */
  --f2-success-deep:   #00693A; /* status text on light (AA 5.66:1 on bone) */
  --f2-warning-deep:   #735703; /* status text on light (AA 5.64:1 on bone) */
  --f2-error-deep:     #A62D2E; /* status text on light (AA 5.74:1 on bone) */

  /* --- How a status label is measured (the badge-tint convention) ---
     Settled in 1.7.2. Every "worst case" and every "on its tint" figure in
     this file means the same thing, so any of them can be reproduced:
       backdrop = the base FILL at 14% alpha, composited in 8-bit sRGB over
                  the surface the component sits on;
       label    = the matching -text token.
     14% is Badge, the highest alpha anything paints. Alert, Banner, Toast and
     the danger menu use 12% and FileUpload 8%, so none of them binds. The
     tint is always made from the fill, never from the -text colour, because
     that is what the components draw. The binding surface flips per theme:
     on dark it is the card #1B1F26, the lightest dark surface; on light it is
     the page #ECEAE2, the darkest light surface. 8-bit because that is what
     the browser actually paints, and it is what every figure here matches. */

  /* --- Status TEXT on dark: the error step ---
     Same split, other direction. On dark the success and warning fills read
     fine as text, but error does not: #D85C57 is 4.99:1 on the page surface,
     4.40:1 on a card, and 3.74:1 inside the 14% tint a status badge draws
     behind its own label - all against an AA floor of 4.5:1. Reducing that
     tint cannot fix it, because the untinted card is already under the floor.
     So error alone takes a lifted step on dark, derived the way the deep trio
     was: hue and chroma held (drift 0.10 degrees, 0.0000), OKLab lightness
     walked UP until it clears 4.5:1 on every dark surface a status label is
     painted on. Worst case 4.63:1 (badge tint over a card), 6.17:1 on the
     page surface. Success and warning keep aliasing their fill on dark. */
  --f2-error-lift:     #EB6D67; /* status text on dark (AA 4.63:1 worst case) */

  /* --- Hairline primitives --- */
  --f2-line:               rgba(236, 234, 226, 0.09); /* on dark        */
  --f2-line-strong:        rgba(236, 234, 226, 0.16); /* on dark        */
  --f2-line-ink:           rgba(16, 18, 22, 0.10);    /* on light — NEW */
  --f2-line-ink-strong:    rgba(16, 18, 22, 0.18);    /* on light — NEW */
  --f2-accent-line:        rgba(229, 154, 60, 0.35);  /* amber hairline */

  /* --- Type --- */
  --f2-font-display:   'Space Grotesk', system-ui, -apple-system, sans-serif;
  --f2-font-body:      'Space Grotesk', system-ui, -apple-system, sans-serif;
  --f2-font-mono:      'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* --- Type weights — NEW in 1.2 --- */
  --f2-fw-regular:     400;
  --f2-fw-medium:      500;
  --f2-fw-semibold:    600;
  --f2-fw-bold:        700;

  /* --- Type scale (px) — display geometric, tight tracking — NEW in 1.2 --- */
  --f2-size-display:   54px;
  --f2-size-h1:        40px;
  --f2-size-h2:        28px;
  --f2-size-h3:        21px;
  --f2-size-body-lg:   19px;
  --f2-size-body:      17px;
  --f2-size-body-sm:   15px;
  --f2-size-caption:   13px;
  --f2-size-mono-label: 12px;

  /* --- Line heights — NEW in 1.2 --- */
  --f2-lh-display:     1.0;
  --f2-lh-h1:          1.05;
  --f2-lh-h2:          1.15;
  --f2-lh-heading:     1.2;
  --f2-lh-body:        1.6;
  --f2-lh-caption:     1.5;

  /* --- Letter spacing — NEW in 1.2 --- */
  --f2-ls-display:     -0.035em;
  --f2-ls-h1:          -0.03em;
  --f2-ls-h2:          -0.02em;
  --f2-ls-tight:       -0.01em;
  --f2-ls-normal:      0;
  --f2-ls-mono-label:  0.16em;  /* uppercase mono labels */
  --f2-ls-mono-tag:    0.06em;

  /* --- Radius (rounded-square language) --- */
  --f2-radius-sm:      4px;   /* module cell                   */
  --f2-radius-control: 10px;  /* buttons / inputs — NEW         */
  --f2-radius-md:      14px;  /* cards                         */
  --f2-radius-lg:      20px;  /* app tile / keycap             */
  --f2-radius-pill:    999px; /* pills / badges — NEW in 1.2   */

  /* --- Border & elevation — NEW in 1.2 --- */
  --f2-border-width:   1px;
  --f2-elevation-overlay: 0 8px 28px rgba(11, 13, 17, 0.45); /* menus/dialogs only — the single permitted lift */

  /* --- Motion --- */
  --f2-ease:           cubic-bezier(0.2, 0, 0, 1);
  --f2-dur-fast:       120ms;
  --f2-dur-base:       220ms;
  --f2-dur-slow:       420ms;

  /* --- Grid / spacing (8px modular scale — scale NEW in 1.2) --- */
  --f2-unit:           8px;
  --f2-gap:            12px;  /* the modular-grid gap          */
  --f2-space-1:        4px;
  --f2-space-2:        8px;
  --f2-space-3:        12px;
  --f2-space-4:        16px;
  --f2-space-5:        24px;
  --f2-space-6:        32px;
  --f2-space-7:        48px;
  --f2-space-8:        64px;
  --f2-space-9:        96px;
  --f2-space-10:       128px;

  /* --- Grid pattern (aliases of unit / gap / radius-sm) --- */
  --f2-grid-cell:        var(--f2-unit);
  --f2-grid-gap:         var(--f2-gap);
  --f2-grid-cell-radius: var(--f2-radius-sm);

  /* --- Containers — NEW in 1.2 --- */
  --f2-container:        1200px;
  --f2-container-narrow: 760px;

  /* ========================================================
     LAYER 2 — SEMANTIC  (purpose aliases · DARK is the default)
     Redefined under [data-theme="light"] below. Nothing else
     needs to change to switch themes.
     ======================================================== */

  /* Surfaces */
  --f2-surface:          var(--f2-ink-800);   /* page background      */
  --f2-surface-raised:   var(--f2-ink-700);   /* panels, inputs       */
  --f2-surface-card:     var(--f2-ink-600);   /* cards                */
  --f2-surface-sunken:   var(--f2-ink-900);   /* wells, code blocks   */
  --f2-surface-accent:   var(--f2-amber-soft);/* amber-tinted fill    */

  /* Text  (dark · contrast on #101216: 15.6 / 8.0 / 5.8 / 3.9) */
  --f2-text:             var(--f2-bone);      /* primary              */
  --f2-text-secondary:   var(--f2-gray-300);  /* body / secondary     */
  --f2-text-muted:       var(--f2-gray-400);  /* muted / labels       */
  --f2-text-faint:       var(--f2-gray-500);  /* faint / disabled     */
  --f2-text-on-accent:   var(--f2-ink);       /* text on amber fill   */

  /* Accent — fill vs text are separate roles (see header note) */
  --f2-accent:           var(--f2-amber);       /* FILL: button bg, node, chip */
  --f2-accent-hover:     var(--f2-amber-press); /* fill hover / pressed        */
  --f2-accent-text:      var(--f2-amber);       /* FOREGROUND: links, icons, focus ring */
  --f2-accent-border:    var(--f2-accent-line); /* amber hairline              */

  /* Status - fill vs text, exactly as accent splits. On dark success and
     warning read fine as text, so those alias the fill; error does not clear
     AA on a card or inside its own badge tint, so it takes -lift. The light
     block re-steps all three. Use the -text token for a status LABEL, the
     bare one for a fill or border. */
  --f2-success-text:     var(--f2-success);
  --f2-warning-text:     var(--f2-warning);
  --f2-error-text:       var(--f2-error-lift);


  /* Charts — fixed slot order, never cycled. Amber is NOT a series: it is
     emphasis (selected series, current period, single-series charts), so a
     three-category stack spends none of the accent budget. */
  --f2-chart-1:          var(--f2-azure);
  --f2-chart-2:          var(--f2-magenta);
  --f2-chart-3:          var(--f2-indigo);
  --f2-chart-other:      var(--f2-gray-400);  /* residual — never a real category */
  --f2-chart-emphasis:   var(--f2-amber);
  --f2-chart-seq-min:    var(--f2-seq-600);   /* near zero — recedes into ink */
  --f2-chart-seq-max:    var(--f2-seq-200);   /* full magnitude               */

  /* Borders */
  --f2-border:           var(--f2-line);
  --f2-border-strong:    var(--f2-line-strong);
}

/* ============================================================
   LAYER 3 — COMPONENT  (built on semantics)
   Declared on :root AND on every [data-theme] scope. A custom
   property that references var() resolves at the element where
   it is DECLARED — so re-declaring the component layer inside
   each themed scope makes it re-resolve against that scope's
   semantics. This is what lets a <div data-theme="light"> inside
   a dark page theme correctly (scoped theming), not just :root.
   ============================================================ */
:root,
[data-theme] {
  /* Page */
  --f2-page-bg:          var(--f2-surface);
  --f2-page-fg:          var(--f2-text);

  /* Link / inline accent */
  --f2-link:             var(--f2-accent-text);
  --f2-link-hover:       var(--f2-accent-hover);

  /* Button — primary (amber fill, ink label) */
  --f2-btn-bg:           var(--f2-accent);
  --f2-btn-fg:           var(--f2-text-on-accent);
  --f2-btn-bg-hover:     var(--f2-accent-hover);
  --f2-btn-bg-active:    var(--f2-accent-hover);
  --f2-btn-bg-disabled:  var(--f2-surface-raised);
  --f2-btn-fg-disabled:  var(--f2-text-faint);
  --f2-btn-radius:       var(--f2-radius-control);
  --f2-btn-pad-y:        10px;
  --f2-btn-pad-x:        18px;

  /* Button — secondary (neutral outline) */
  --f2-btn2-bg:          transparent;
  --f2-btn2-fg:          var(--f2-text);
  --f2-btn2-border:      var(--f2-border-strong);
  --f2-btn2-bg-hover:    var(--f2-surface-raised);

  /* Card */
  --f2-card-bg:          var(--f2-surface-card);
  --f2-card-border:      var(--f2-border);
  --f2-card-radius:      var(--f2-radius-md);
  --f2-card-pad:         20px;

  /* Input */
  --f2-input-bg:         var(--f2-surface-raised);
  --f2-input-fg:         var(--f2-text);
  --f2-input-placeholder: var(--f2-text-muted);
  --f2-input-border:     var(--f2-border-strong);
  --f2-input-focus-ring: var(--f2-accent-text);
  --f2-input-radius:     var(--f2-radius-control);
  --f2-input-pad-y:      10px;
  --f2-input-pad-x:      14px;

  /* Divider */
  --f2-divider:          var(--f2-border);

  /* Focus ring & hairline — theme-derived, declared per scope */
  --f2-border-hairline:  var(--f2-border-width) solid var(--f2-border);
  --f2-ring:             0 0 0 2px var(--f2-surface), 0 0 0 4px var(--f2-accent-text);

  /* Deprecated pre-1.2 aliases — prefer the right-hand tokens */
  --f2-surface-overlay:  var(--f2-surface-card);
  --f2-accent-contrast:  var(--f2-text-on-accent);
  --f2-border-subtle:    var(--f2-border);
  --f2-focus:            var(--f2-accent-text);
}

/* ============================================================
   LIGHT THEME — remap the SEMANTIC layer only.
   Hierarchy inverts: darker = more emphasis on a bone surface.
   ============================================================ */
:root[data-theme="light"],
[data-theme="light"] {
  /* Surfaces */
  --f2-surface:          var(--f2-paper-200);  /* bone */
  --f2-surface-raised:   var(--f2-paper-100);
  --f2-surface-card:     var(--f2-paper-100);
  --f2-surface-sunken:   var(--f2-paper-300);
  --f2-surface-accent:   var(--f2-amber-wash);

  /* Text (on bone: 15.6 / 11.2 / 8.5 / 4.0 — all WCAG-pass) */
  --f2-text:             var(--f2-ink);
  --f2-text-secondary:   var(--f2-ink-500);
  --f2-text-muted:       var(--f2-ink-400);
  --f2-text-faint:       var(--f2-gray-500);
  --f2-text-on-accent:   var(--f2-ink);

  /* Accent — fill stays Signal Amber; TEXT darkens to amber-deep for AA */
  --f2-accent:           var(--f2-amber);
  --f2-accent-hover:     var(--f2-amber-press);
  --f2-accent-text:      var(--f2-amber-deep);
  --f2-accent-border:    var(--f2-accent-line);

  /* Status - fills stay; TEXT darkens for AA on bone, as accent-text does. */
  --f2-success-text:     var(--f2-success-deep);
  --f2-warning-text:     var(--f2-warning-deep);
  --f2-error-text:       var(--f2-error-deep);


  /* Charts — see the dark block. Emphasis takes amber-deep for the same reason
     accent-text does: a mark on bone has to be read, not merely seen. */
  --f2-chart-1:          var(--f2-azure-deep);
  --f2-chart-2:          var(--f2-magenta-deep);
  --f2-chart-3:          var(--f2-indigo-deep);
  --f2-chart-other:      var(--f2-ink-400);
  --f2-chart-emphasis:   var(--f2-amber-deep);
  --f2-chart-seq-min:    var(--f2-seq-200);
  --f2-chart-seq-max:    var(--f2-seq-700);

  /* Borders — ink-based hairlines on light */
  --f2-border:           var(--f2-line-ink);
  --f2-border-strong:    var(--f2-line-ink-strong);
}

/* Explicit dark (same as :root default) — for symmetry with light */
:root[data-theme="dark"],
[data-theme="dark"] {
  --f2-surface:          var(--f2-ink-800);
  --f2-surface-raised:   var(--f2-ink-700);
  --f2-surface-card:     var(--f2-ink-600);
  --f2-surface-sunken:   var(--f2-ink-900);
  --f2-surface-accent:   var(--f2-amber-soft);

  --f2-text:             var(--f2-bone);
  --f2-text-secondary:   var(--f2-gray-300);
  --f2-text-muted:       var(--f2-gray-400);
  --f2-text-faint:       var(--f2-gray-500);
  --f2-text-on-accent:   var(--f2-ink);

  --f2-accent:           var(--f2-amber);
  --f2-accent-hover:     var(--f2-amber-press);
  --f2-accent-text:      var(--f2-amber);
  --f2-accent-border:    var(--f2-accent-line);

  --f2-success-text:     var(--f2-success);
  --f2-warning-text:     var(--f2-warning);
  --f2-error-text:       var(--f2-error-lift);

  /* Charts — fixed slot order, never cycled. Amber is NOT a series: it is
     emphasis (selected series, current period, single-series charts), so a
     three-category stack spends none of the accent budget. */
  --f2-chart-1:          var(--f2-azure);
  --f2-chart-2:          var(--f2-magenta);
  --f2-chart-3:          var(--f2-indigo);
  --f2-chart-other:      var(--f2-gray-400);  /* residual — never a real category */
  --f2-chart-emphasis:   var(--f2-amber);
  --f2-chart-seq-min:    var(--f2-seq-600);   /* near zero — recedes into ink */
  --f2-chart-seq-max:    var(--f2-seq-200);   /* full magnitude               */

  --f2-border:           var(--f2-line);
  --f2-border-strong:    var(--f2-line-strong);
}

/* Opt-in OS following — only when explicitly set to "auto".
   The brand manual stays dark; nothing here touches it. */
@media (prefers-color-scheme: light) {
  :root[data-theme="auto"],
  [data-theme="auto"] {
    --f2-surface:          var(--f2-paper-200);
    --f2-surface-raised:   var(--f2-paper-100);
    --f2-surface-card:     var(--f2-paper-100);
    --f2-surface-sunken:   var(--f2-paper-300);
    --f2-surface-accent:   var(--f2-amber-wash);

    --f2-text:             var(--f2-ink);
    --f2-text-secondary:   var(--f2-ink-500);
    --f2-text-muted:       var(--f2-ink-400);
    --f2-text-faint:       var(--f2-gray-500);
    --f2-text-on-accent:   var(--f2-ink);

    --f2-accent:           var(--f2-amber);
    --f2-accent-hover:     var(--f2-amber-press);
    --f2-accent-text:      var(--f2-amber-deep);
    --f2-accent-border:    var(--f2-accent-line);

    /* Status TEXT darkens on bone, as accent-text does. */
    --f2-success-text:     var(--f2-success-deep);
    --f2-warning-text:     var(--f2-warning-deep);
    --f2-error-text:       var(--f2-error-deep);

    /* Charts — see the dark block. Emphasis takes amber-deep for the same reason
       accent-text does: a mark on bone has to be read, not merely seen. */
    --f2-chart-1:          var(--f2-azure-deep);
    --f2-chart-2:          var(--f2-magenta-deep);
    --f2-chart-3:          var(--f2-indigo-deep);
    --f2-chart-other:      var(--f2-ink-400);
    --f2-chart-emphasis:   var(--f2-amber-deep);
    --f2-chart-seq-min:    var(--f2-seq-200);
    --f2-chart-seq-max:    var(--f2-seq-700);

    --f2-border:           var(--f2-line-ink);
    --f2-border-strong:    var(--f2-line-ink-strong);
  }
}

/* Respect reduced-motion: zero out durations (consumers read these) */
@media (prefers-reduced-motion: reduce) {
  :root {
    --f2-dur-fast: 0ms;
    --f2-dur-base: 0ms;
    --f2-dur-slow: 0ms;
  }
}
