/* ============================================================================
   Felix Ihno — Design Tokens (compiled)
   Direction B "Surveyor" · locked 2026-06-17 · @version 2.4.0
   (2.1.0: tint/state % + line-heights tokenised + gate-locked — no magic numbers left in the
    component layer beyond structural 50%/gradient stops. 2.0.0: scale foundation = Tailwind — type ladder (18px editorial base), radii (6/8/12),
    line-heights (Tailwind-derived). Identity unchanged. Gate locks the exact ladder.)
   Source of truth: design-tokens.json  ·  Spec: FELIX-IHNO-DESIGN-SYSTEM.md
   Tools @import this one file and build with the L2 semantic tokens ONLY.

   Themes:  :root = light            [data-theme="dark"] = warm dark
   Accent:  default clay   [data-accent="green"] [data-accent="oxblood"]
   Print:   @media print  → black-on-white, hue re-encodes to fill+rule+hatch
   Fonts:   self-host Newsreader · Hanken Grotesk · IBM Plex Mono (OFL) —
            see FELIX-IHNO-DESIGN-SYSTEM.md §Fonts. Print pipeline uses Charter.
   Contrast: computed locally (WCAG rel-luminance) 2026-06-17.
   ========================================================================== */

:root {
  /* ── L1 · PRIMITIVES (raw ingredients — referenced only by L2) ────────── */
  --warm-paper:   #F8F7F4;   --warm-surface: #FDFDF7;   /* v2.2: cooler/neutral cream (Anthropic-like) */
  --warm-900:     #29231C;   --warm-600:     #74675A;   --warm-400: #9A8E7D;
  --warm-hairline:#CDBFA9;   --warm-border:  #E0D5C4;
  --warm-dbg:     #1E1A16;   --warm-dsurf:   #261F19;
  --warm-d100:    #ECE3D6;   --warm-d300:    #AC9F8E;   --warm-d500: #7E7466;
  --warm-dborder: #3D352B;

  --clay:    #B0532F;  --clay-d:    #D2805C;
  --green:   #3C5A43;  --green-d:   #7FA383;
  --oxblood: #7C2E2A;  --oxblood-d: #C7766B;

  --sig-info-l:#3F5680; --sig-ok-l:#46743F; --sig-caution-l:#8A6310; --sig-danger-l:#9E3B2C;
  --sig-info-d:#9DB0E0; --sig-ok-d:#9CC79F; --sig-caution-d:#D9B566; --sig-danger-d:#E0917F;

  /* type scale · TAILWIND ladder (v2.0) · reading base 18px = --text-sm (= Tailwind text-lg).
     Surveyor's 18px editorial base kept; sizes are Tailwind's exact rem steps mapped around it.
     Hand-tuned (NOT a single ratio) — the industry default; gate locks the exact values.
     px @16: 12·14·16·18·20·24·30·36·48  (tw: xs·sm·base·lg·xl·2xl·3xl·4xl·5xl) */
  --text-3xs:.75rem; --text-2xs:.875rem; --text-xs:1rem; --text-sm:1.125rem;
  --text-md:1.25rem; --text-lg:1.5rem;  --text-xl:1.875rem; --text-2xl:2.25rem; --text-3xl:3rem; /* 3xl = display/hero anchor */
  /* line-heights · Tailwind-derived (v2.0): body=1.556 (tw lg 28/18), ui=1.5 (tw base, exact),
     snug=1.333 (tw 2xl headings), tight=1.1 (tw 4xl display). Gate-locked. */
  --lh-flat:1; --lh-tight:1.1; --lh-snug:1.333; --lh-ui:1.5; --lh-body:1.556; /* flat = single-line UI controls */
  --tracking-eyebrow:.14em; --tracking-tight:-.01em;
  --weight-reg:400; --weight-med:500; --weight-semi:600; --weight-bold:700;

  /* space · strict 4px grid · token name N = N×4px (so --space-5 = 20px, exactly).
     v1.5: filled 5/9/10 so every component dimension maps to a token — no raw px ≥4px
     in components.css (gate-enforced; only 1/2/3px borders/insets stay raw). */
  --space-1:.25rem; --space-2:.5rem; --space-3:.75rem; --space-4:1rem; --space-5:1.25rem;
  --space-6:1.5rem; --space-8:2rem; --space-9:2.25rem; --space-10:2.5rem; --space-12:3rem; --space-16:4rem;

  --radius-sm:6px; --radius-md:8px; --radius-lg:12px; /* v2.0: Tailwind radii (rounded-md/lg/xl) */
  --motion-fast:120ms; --motion-base:200ms; --ease-out:cubic-bezier(.2,.7,.3,1);

  /* ── L2 · SEMANTIC (components reference ONLY these) ──────────────────── */
  --color-bg:           var(--warm-paper);
  --color-surface:      var(--warm-surface);
  --color-text:         var(--warm-900);
  --color-text-muted:   var(--warm-600);   /* AA — secondary text */
  --color-text-faint:   var(--warm-400);   /* DECORATIVE ONLY — fails text contrast */
  --color-border:       var(--warm-border);
  --color-hairline:     var(--warm-hairline);

  --color-accent:       var(--clay);                                   /* default */
  --color-accent-soft:  color-mix(in srgb, var(--color-text) 8%, transparent); /* v2.4: neutral wash, NOT pale clay (lightened clay reads pink). Selection shown by accent bar/border. */
  --color-on-accent:    #FFF9F0;           /* text/icon on an accent fill */

  --color-signal-info:    var(--sig-info-l);
  --color-signal-ok:      var(--sig-ok-l);
  --color-signal-caution: var(--sig-caution-l);
  --color-signal-danger:  var(--sig-danger-l);

  --font-serif: 'Newsreader', Georgia, 'Times New Roman', serif;       /* editorial / headings / doc body */
  --font-sans:  'Hanken Grotesk', system-ui, -apple-system, sans-serif;/* UI / labels / data */
  --font-mono:  'IBM Plex Mono', ui-monospace, Menlo, monospace;
  --font-heading: var(--font-serif);
  --font-ui:      var(--font-sans);
  --font-code:    var(--font-mono);

  --shadow-card: 0 1px 2px rgba(41,35,28,.06);
  --shadow-pop:  0 4px 14px rgba(41,35,28,.10);

  /* ── L2.5 · DATA-VIZ + STATE (round-2 component layer, 2026-06-17) ─────── */
  --viz-depth-1:#EAD9C4; --viz-depth-2:#DDB78F; --viz-depth-3:#CB8E5C; --viz-depth-4:#B0532F; --viz-depth-5:#7E3A1E; /* sequential urgency ramp · far→near · calm, never red */
  --viz-band:#F0E5D4;        /* sparkline normal-range band */
  --viz-spark:#74675A;       /* sparkline stroke */
  --viz-spark-point:#B0532F; /* sparkline endpoint + last value */
  --viz-cat-1:#B0532F; --viz-cat-2:#3C5A43; --viz-cat-3:#3F5680; --viz-cat-4:#8A6310; --viz-cat-5:#7C2E2A;
  /* categorical = data MARKS, not text. Each series MUST also carry a non-color cue for mono:
     cat-1 solid·● · cat-2 dashed·■ · cat-3 dotted·▲ · cat-4 dash-dot·◆ · cat-5 long-dash·＋ */
  --color-focus-ring: color-mix(in srgb, var(--color-accent) 42%, transparent);

  /* ── tint + state MIX AMOUNTS (v2.1) — the ONLY blessed depth/state percentages.
     color-mix() in components references these (base-agnostic: ink OR accent), so no
     magic % scatters across the component layer. Gate-locked in check.mjs. ───────── */
  --wash-1: 3%;  --wash-2: 6%;  --wash-3: 11%;  /* faint fill · hover wash · pressed wash */
  --line-1: 9%;  --line-2: 18%;                 /* translucent hairline · strong/accent border */
  --fill-soft: 16%;                             /* signal / accent-soft fill */
  --mix-hover: 90%; --mix-active: 80%;          /* accent KEPT on hover · active (rest = ink → darken) */
  --line-hover: 55%;                            /* hairline → ink on field/chip hover */
}

/* ── base text rendering (root; reaches every consumer incl. token-only) ──── */
/* macOS renders text heavier than intended; antialiased crisps it. Lives here
   (not components.css) so reading surfaces that inline ONLY tokens.css get it. */
:root { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }

/* ── L3 · ACCENT VARIANTS (one identity, swap the accent by context) ────── */
[data-accent="green"]   { --color-accent: var(--green); }
[data-accent="oxblood"] { --color-accent: var(--oxblood); }

/* ── L3 · DARK THEME (warm — never blue-black) ──────────────────────────── */
[data-theme="dark"] {
  --color-bg:         var(--warm-dbg);
  --color-surface:    var(--warm-dsurf);
  --color-text:       var(--warm-d100);
  --color-text-muted: var(--warm-d300);
  --color-text-faint: var(--warm-d500);
  --color-border:     var(--warm-dborder);
  --color-hairline:   var(--warm-dborder);
  --color-accent:     var(--clay-d);
  --color-on-accent:  var(--warm-dbg);
  --color-signal-info:    var(--sig-info-d);
  --color-signal-ok:      var(--sig-ok-d);
  --color-signal-caution: var(--sig-caution-d);
  --color-signal-danger:  var(--sig-danger-d);
  --shadow-card: 0 1px 2px rgba(0,0,0,.35);
  --shadow-pop:  0 6px 18px rgba(0,0,0,.45);
  --viz-depth-1:#3A2C20; --viz-depth-2:#6A4530; --viz-depth-3:#96603F; --viz-depth-4:#C0764B; --viz-depth-5:#D2805C;
  --viz-band:#2B2219; --viz-spark:#AC9F8E; --viz-spark-point:#D2805C;
  --viz-cat-1:#D2805C; --viz-cat-2:#7FA383; --viz-cat-3:#9DB0E0; --viz-cat-4:#D9B566; --viz-cat-5:#C7766B;
}
[data-theme="dark"][data-accent="green"]   { --color-accent: var(--green-d); }
[data-theme="dark"][data-accent="oxblood"] { --color-accent: var(--oxblood-d); }

/* ── L3 · PRINT (mono laser: black on white; hue → fill + rule + hatch) ─── */
@media print {
  :root {
    --color-bg:#fff; --color-surface:#fff; --color-text:#000;
    --color-text-muted:#333; --color-text-faint:#555;
    --color-border:#000; --color-hairline:#000;
    --color-accent:#000; --color-accent-soft:transparent; --color-on-accent:#fff;
    --color-signal-info:#000; --color-signal-ok:#000;
    --color-signal-caution:#000; --color-signal-danger:#000;
    --shadow-card:none; --shadow-pop:none;
    --viz-depth-1:#E0E0E0; --viz-depth-2:#BDBDBD; --viz-depth-3:#8A8A8A; --viz-depth-4:#4D4D4D; --viz-depth-5:#000;
    --viz-band:#EAEAEA; --viz-spark:#000; --viz-spark-point:#000;
    --viz-cat-1:#000; --viz-cat-2:#000; --viz-cat-3:#000; --viz-cat-4:#000; --viz-cat-5:#000;
    --color-focus-ring:transparent;
    /* categorical series separate by dash + marker SHAPE (and SVG hatch fills), not color — see component layer */
  }
  /* status re-encodes by FILL + RULE (apply these classes on print surfaces): */
  .is-live    { font-weight:600; }                 /* solid fill + 2px rule  */
  .is-active  { }                                   /* half fill  + 1px rule  */
  .is-pending { }                                   /* hollow     + dotted    */
  /* urgency re-encodes as hatch density — use .hatch on the progress fill:   */
  .hatch { background:repeating-linear-gradient(45deg,#000 0,#000 2px,#fff 2px,#fff 4px); }
}

/* keyboard focus ring — on-brand, follows the active accent (round-2) */
:where(a,button,input,select,textarea,[tabindex]):focus-visible {
  outline:2px solid var(--color-accent); outline-offset:2px;
  box-shadow:0 0 0 4px var(--color-focus-ring); border-radius:var(--radius-sm);
}
/* skeleton shimmer (paused by reduced-motion below) */
@keyframes fi-shimmer { 0%{background-position:200% 0} 100%{background-position:-200% 0} }

@media (prefers-reduced-motion: reduce) { * { transition:none !important; animation:none !important; } }
