/*
 * Herald — Design System Token Layer
 * §01 Color primitives → §02 Semantic intent → §03 Splat mechanism
 * §05 Dice pip tokens → §06 Spacing / Elevation / Radius → §09 Motion
 *
 * LOAD ORDER: tokens.css must precede all other Herald stylesheets.
 * See base.html link order: tokens → main → journal-theme → sheet-layout → dice-fab
 *
 * THREE-TIER RULE
 *   Tier 1 — Primitives  : raw ramps, never referenced by components directly.
 *   Tier 2 — Semantics   : intent tokens that components speak exclusively.
 *   Tier 3 — Tailwind    : reads semantic var() names, never raw hex.
 *
 * Raw hex appears ONLY inside this file's primitive block and the per-splat
 * [data-splat] overrides. Everywhere else: var(--token-name) only.
 */

/* =========================================================================
   §01 — PRIMITIVE RAMPS
   ========================================================================= */

:root {

  /* ── Parchment & Leather (warm neutrals) ── */
  --parchment-900: #150f0a;
  --parchment-800: #281e12;
  --parchment-700: #3a2c1a;
  --parchment-600: #58493a;
  --parchment-500: #7a6a54;
  --parchment-400: #9d8d77;
  --parchment-300: #c4b59c;

  /* ── Leather / Chrome (app shell nav — darker/lighter range than
       Parchment, which is reserved for sheet cards) ── */
  --leather-950: #110e0b;
  --leather-900: #1a1612;
  --leather-800: #2b2419;
  --leather-700: #3d3224;
  --leather-300: #bfb09a;

  /* ── Ink (deep ember-blacks) ── */
  --ink-900: #0a0605;   /* SCRIM */
  --ink-800: #15100b;   /* NAV  */

  /* ── Crimson / Blood (dried blood) ── */
  --crimson-900: #1a0a08;
  --crimson-800: #3d1810;
  --crimson-700: #5c2318;
  --crimson-600: #7d3124;
  --crimson-500: #a34335;
  --crimson-400: #c96856;
  --crimson-blood: #8B0000;   /* BLOOD — aggravated damage severity; named separately from the ramp */

  /* ── Warning (alert/caution — distinct from --danger crimson) ── */
  --warning-500: #FFC107;

  /* ── Gold Ramp (unified — tarnished gold through pale cream and dark brass) ── */
  --gold-700: #8b6914;   /* dark brass — tracker superficial/desperation fill */
  --gold-500: #b3a06a;   /* tarnished gold — headings, shell accent */
  --gold-400: #cdbb86;   /* action highlights, renown dots */
  --gold-300: #ddcfa6;
  --gold-200: #f0e6c4;
  --gold-100: #ffedb8;   /* pale cream — text-on-dark tracker labels */

  /* ── Ember (brighter amber glow accent — Tailwind ember.*; distinct hue from
       the muted Gold ramp above, used for glows/highlights sitewide) ── */
  --ember-500: var(--gold-shell);   /* #D4A843 — alias, defined in Shell block below */
  --ember-400: #e8c068;
  --ember-300: #f5d98a;
  --ember-200: var(--gold-100);      /* #ffedb8 */

  /* ── Silver Ramp (cool-neutral — Herald has no cool-neutral ramp otherwise;
       green-of-neutral on purpose, to sit beside WTA Camo rather than read as
       true chrome. WTA button rule/shine colours only — do not reuse as a
       general neutral. 300/500 are reserved for later button states, not
       orphaned. ── */
  --silver-200: #eef1ee;   /* near-white — WTA §Button rim-shine */
  --silver-300: #cfd6d2;   /* hover tint — reserved */
  --silver-400: #a7b0ac;   /* base — WTA §Button rule colour */
  --silver-500: #7c8783;   /* recessed / pressed edge — reserved */

  /* ── HTR Splat Ramp (Hunter's Flare — Blade Runner orange) ── */
  --htr-700: #993D00;
  --htr-500: #FF6A00;   /* --accent base; --accent-active: #993D00 set per splat */
  --htr-300: #FFB347;
  --htr-glow: #FF9933;
  --htr-caution: #FFD23F;

  /* ── VTM Splat Ramp (Wine — velvet) ── */
  --vtm-900: #1a0c14;   /* kept live — wizard.css & character_new.html read it
                            directly, outside the neuro-shadow that formerly
                            justified 800/600 here */
  --vtm-700: #3D0F22;
  --vtm-500: #6B1E3C;   /* --accent base; --accent-active: #3D0F22 set per splat */
  --vtm-300: #A85070;
  --vtm-silk: #C99AA8;  /* sheen on stat blocks/dividers only; never fill */

  /* ── WTA Splat Ramp (Camo — matte earthbound) ── */
  --wta-700: #3A4128;
  --wta-500: #5C6B3F;   /* --accent base */
  --wta-300: #8C9468;
  --wta-teeth: #DCD3B4;

  /* ── Rage / Frenzy ── */
  --alarm-red: #b52d1e;   /* general alarm (hunger crisis, etc.) — feeds --alarm */
  --wta-rage: #C81E32;   /* frenzy/fury UI ONLY — feeds --accent-alt under [data-splat="wta"]; never assigned to --accent */

  /* ── Blood Throughline (hue ~354°, per-splat blood motif) ── */
  --blood-laser:    #FF1F3D;  /* HTR */
  --blood-oxidized: #6E0D21;  /* VTM */
  --blood-dried:    #5C2A24;  /* WTA */

  /* ── Black-light (HTR sheet's ambient cursor-spotlight accent — a UV
       violet distinct from --htr-500's Hunter's Flare orange, which stays
       the accent for borders/buttons/glow-ring everywhere else) ── */
  --blacklight-violet: #8A2BE2;

  /* #fossil 2026-07-21: orphaned — the hidden blood-reveal on the HTR
       sheet moved off this cyan luminol-glow treatment onto --blood-laser
       (see htr-sheet.css .htr-blood-reveal) plus --blacklight-violet for
       its reflection tint, per live art direction. No remaining
       consumers; kept pending sign-off rather than deleted outright. */
  --htr-luminol:      #0BE8FF;
  --htr-luminol-core: #CFFBFF;
  --htr-luminol-halo: #0091B3;

  /* ── Shell (constant across all splats) ── */
  --gold-shell:   #D4A843;
  --parchment-bg: #2B2419;

  /* ── Meter Primitives (stat trackers — cool-hued utilities) ── */
  --steel-700: #28323f;
  --steel-400: #5f86ad;   /* WILL */
  --spirit-500: #2f7d96;  /* GNOSIS */
  --moss-900:   #1a2b1a;  /* GROUND */
  --moss-400:   #5b9d6b;  /* BRIGHT */

  /* ── Dice Pip Primitives (roll-feed die-face SVGs — chronicle_detail.html;
       regular/desperation/hunger/rage dice all share the value-tier fills
       below, distinguished by a per-type stroke and, for the "1" tier on
       desperation/hunger/rage only, a per-type "bad" fill/text) ── */
  --die-gold-dark:    #b8902e;   /* regular die crit stroke */
  --die-green:        #2d5a37;   /* value 6-9 fill, all die types */
  --die-green-light:  #aaddbb;   /* value 6-9 pip text, all die types */
  --die-green-dark:   #3d7a4a;   /* regular die success stroke */
  --die-blood-dark:   #8b1a10;   /* desperation/hunger die, value-1 fill */
  --die-pink-pale:    #ffdddd;   /* desperation/hunger die, value-1 pip text */
  --die-crimson-deep: #7d1010;   /* hunger die stroke */
  --die-blood-black:  #3d0808;   /* rage die, value-1 fill */
  --die-orange-hot:   #cc3333;   /* rage die stroke */
  --die-orange-pale:  #ff6644;   /* rage die, value-1 pip text */

}

/* =========================================================================
   §02 — SEMANTIC / INTENT TOKENS  (components speak only this tier)
   ========================================================================= */

:root {

  /* ── Background & Surface ── */
  --bg:           var(--parchment-900);   /* page ground          */
  --surface:      var(--parchment-800);   /* cards & inputs       */
  --border:       var(--parchment-600);   /* hairlines & rules; overridden per [data-splat] */
  --border-htr:   #6B4A2E;
  --border-vtm:   #4A2E3A;
  --border-wta:   #4F5638;

  /* ── Text ── */
  --text:         var(--parchment-300);   /* body copy            */
  --text-muted:   var(--parchment-400);   /* labels & hints       */
  --heading:      var(--gold-500);        /* titles & eyebrows    */

  /* ── Interactive / Accent (shell default = tarnished gold) ── */
  --accent:       var(--gold-500);        /* swapped per [data-splat] */

  /* --accent-alt previously had NO root-level default — it was declared
     only inside [data-splat="wta"] (§03 below). --accent has this same
     shell fallback so it degrades to gold if that selector ever fails to
     match (attribute set late by JS, wrong ancestor, etc.); --accent-alt
     had nothing to fall back to, so anywhere it was used — Rage's dot
     fill, its label, its "N / 5" value text — silently went fully
     invalid (transparent background / inherited text color) instead of
     just the wrong color. Root-caused via a live screenshot showing
     Rage's plain (unmasked, unanimated) label text rendering in the
     ambient text color instead of red, which ruled out every masking/
     animation/GPU-compositing theory tried before this. */
  --accent-alt:   var(--wta-rage);        /* swapped per [data-splat]; same value as [data-splat="wta"]'s own override below, just guaranteed to exist */

  /* ── Button Rule (§Button outline colour — brass shell/HTR/VTM off the
       Gold ramp; silver WTA override lives with the other splat swaps in
       §03) ── */
  --btn-rule:      var(--gold-500);
  --btn-hover-bg:  color-mix(in srgb, var(--accent) 12%, transparent);

  /* ── Button Shine (§Button rim-shine hover — a metallic near-white catch-
       light travelling along the rule/caps, not an accent-tinted glow;
       same near-white step as the metal's own ramp, brass/silver swapped
       alongside --btn-rule in §03) ── */
  --btn-shine:     var(--gold-200);

  /* ── Status ── */
  --danger:       var(--crimson-600);     /* errors, seals — always crimson, never a splat accent */
  --alarm:        var(--alarm-red);        /* alarm red — hunger crisis, frenzy-threshold alerts; NOT a splat accent */
  --warning:      var(--warning-500);     /* caution — desperation trackers, warning glows */
  --success:      var(--moss-900);        /* confirm toasts (dark moss ground) */
  --success-surface: #1e3b2a;             /* success-adjacent badge/outcome surface (lighter than --success) */

  /* ── Scrim ── */
  --scrim:        var(--ink-900);         /* modal backdrop       */

  /* ── Disabled ── */
  --disabled-opacity: 0.4;

  /* ── Meter & Damage States ── */
  --willpower:      var(--steel-400);     /* tracker fill — blue steel */
  --superficial:    var(--warning);       /* recoverable damage — yellow, matches WTA's existing convention */
  --aggravated:     var(--crimson-blood); /* blood damage severity (distinct from --danger which is UI error) */
  --renown-gold:    var(--gold-400);      /* WTA Renown dots */
  /* --success-bright is NOT a color-mix() derivation — moss-400 is a hardcoded sibling
     primitive. Lightening moss-900 algorithmically would not produce a value bright
     enough to read as an active/online indicator. */
  --success-bright: var(--moss-400);     /* online status / active success text */

}

/* ── State-delta derivations from --accent ──────────────────────────────── */
/*
 * color-mix() is supported in Chrome 111+, Firefox 113+, Safari 16.2+
 * (~91% global coverage). Hardcoded fallbacks ensure older clients get
 * shell-gold states; once the splat-specific accent swaps in, the
 * color-mix() values override correctly in supported browsers.
 */
:root {
  /* Fallbacks (shell gold only — splat accents won't auto-derive on older browsers) */
  --accent-hover:   var(--gold-400);     /* gold-500 + ~12% white */
  --accent-active:  #8a7a48;            /* gold-500 + ~14% black */
  --focus-ring: 0 0 0 2px rgba(179, 160, 106, 0.15), 0 0 0 1px var(--accent);
}

@supports (color: color-mix(in srgb, red, blue)) {
  :root {
    --accent-hover:  color-mix(in oklch, var(--accent), white 12%);
    --accent-active: color-mix(in oklch, var(--accent), black 14%);
  }
}

/* =========================================================================
   §03 — SPLAT MECHANISM
   Set [data-splat="htr|vtm|wta"] on any ancestor container — typically
   <body> for full-page sheet views, or a wrapper div for chronicle cards.
   All descendants inherit the correct --accent automatically.
   Shell chrome (nav, page containers without a splat ancestor) keeps gold.

   CRITICAL: --danger always resolves to crimson regardless of splat.
             WTA --accent-alt (rage-red) is for Rage-specific states ONLY.
             Never assign --accent-alt to --accent.
   ========================================================================= */

[data-splat="htr"] {
  --accent:        var(--htr-500);   /* #FF6A00 — Hunter's Flare (Blade Runner orange) */
  --accent-active: var(--htr-700);   /* #993D00 — pressed/active state */
  --border:        var(--border-htr);
  /* no accent-alt for HTR */
}

[data-splat="vtm"] {
  --accent:        var(--vtm-500);   /* #6B1E3C — Wine (velvet) */
  --accent-active: var(--vtm-700);   /* #3D0F22 — pressed/active state */
  --border:        var(--border-vtm);
  /* no accent-alt for VTM */
}

[data-splat="wta"] {
  --accent:        var(--wta-500);   /* #5C6B3F — Camo (matte earthbound) */
  --accent-active: color-mix(in oklch, var(--accent), black 14%);
  --accent-alt:    var(--wta-rage);  /* #C81E32 — Rage/frenzy UI ONLY, never assigned to --accent */
  --border:        var(--border-wta);
  --btn-rule:      var(--silver-400);
  --btn-shine:     var(--silver-200);
}

/* =========================================================================
   §05 — DICE PIP TOKENS  (roll-feed die-face SVGs — chronicle_detail.html)
   Value-tier fill/text is shared across all four die types (regular,
   desperation, hunger, rage); stroke and the "1"-tier fill/text are
   per-type — see the primitives above for which raw hex backs each.
   ========================================================================= */

:root {
  --die-pip-crit:          var(--gold-shell);    /* value 10 fill, all types */
  --die-pip-crit-text:     var(--leather-900);   /* value 10 pip text */
  --die-pip-success:       var(--die-green);     /* value 6-9 fill */
  --die-pip-success-text:  var(--die-green-light); /* value 6-9 pip text */
  --die-pip-low:           var(--leather-700);   /* value 1-5 (regular) / 2-5 (special) fill */
  --die-pip-low-text:      var(--parchment-500); /* same tier, pip text */

  --die-pip-bad:           var(--die-blood-dark);  /* desperation/hunger, value 1 fill */
  --die-pip-bad-text:      var(--die-pink-pale);   /* desperation/hunger, value 1 text */
  --die-pip-rage-bad:      var(--die-blood-black); /* rage, value 1 fill */
  --die-pip-rage-bad-text: var(--die-orange-pale); /* rage, value 1 text */

  --die-regular-stroke-crit:    var(--die-gold-dark);
  --die-regular-stroke-success: var(--die-green-dark);
  --die-regular-stroke-low:     var(--parchment-600);
  --die-desperation-stroke: var(--crimson-400);
  --die-hunger-stroke:      var(--die-crimson-deep);
  --die-rage-stroke:        var(--die-orange-hot);
}

/* =========================================================================
   §06 — SPACING SCALE  (4-based, 7 steps)
   Usage: gap: var(--space-sm); padding: var(--space-lg) var(--space-md);
   ========================================================================= */

:root {
  --space-xs:   4px;
  --space-sm:   8px;
  --space-md:  12px;
  --space-lg:  16px;
  --space-xl:  24px;
  --space-2xl: 32px;
  --space-3xl: 48px;
}

/* =========================================================================
   §06 — ELEVATION SCALE  (4 steps, e0–e3)
   e0 = flat/inset; e3 = floating modal
   Note: warm inset highlight on e2/e3 uses parchment-300 rgba, not neutral black.
   ========================================================================= */

:root {
  --shadow-e0: none;                                        /* flat — pair with 1px var(--border) border */
  --shadow-e1: 0 1px 3px rgba(0, 0, 0, 0.5);               /* raised element */
  --shadow-e2: inset 0 1px 0 rgba(196, 181, 156, 0.1),     /* card */
               0 2px 8px rgba(0, 0, 0, 0.6);
  --shadow-e3: inset 0 1px 0 rgba(196, 181, 156, 0.1),     /* floating / FAB */
               0 8px 24px rgba(0, 0, 0, 0.7);
}

/* =========================================================================
   §06 — RADIUS SCALE  (3 steps)
   ========================================================================= */

:root {
  --radius-sm:  3px;
  --radius-md:  6px;
  --radius-lg: 12px;
}

/* =========================================================================
   §07 — TEXTURE SYSTEM
   No binary photographic assets ship in this repo (design doc references
   assets/textures/*.jpg that don't exist here), so each token below is a
   procedural CSS approximation — layered gradients / SVG turbulence at a
   pre-baked low alpha — standing in for the leather / parchment / splat
   photo textures. Swap any token for a real url(...) later with no call-site
   changes required.
   Layer order (bottom → top): leather (body::before, fixed) → parchment
   (Card/Dialog surface) → splat (cyber/velvet/canvas).
   ========================================================================= */

:root {
  --texture-leather-opacity:   0.20;
  --texture-parchment-opacity: 0.20;
  --texture-splat-opacity:     0.12;

  --texture-leather:
    repeating-linear-gradient(0deg, transparent, transparent 2px,
      rgba(21, 15, 10, 0.5) 2px, rgba(21, 15, 10, 0.5) 4px),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='6' height='6' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");

  --texture-parchment:
    repeating-linear-gradient(0deg, transparent, transparent 2px,
      rgba(61, 50, 36, 0.15) 2px, rgba(61, 50, 36, 0.15) 4px),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4'%3E%3Cpath d='M0 0h1v1H0zm2 2h1v1H2z' fill='%233d3224' fill-opacity='0.25'/%3E%3C/svg%3E");

  /* Splat overlays — fine directional line patterns tinted per splat hue */
  --texture-cyber:
    repeating-linear-gradient(90deg, rgba(255, 106, 0, 0.28) 0px, rgba(255, 106, 0, 0.28) 1px, transparent 1px, transparent 24px),
    repeating-linear-gradient(0deg, rgba(255, 106, 0, 0.2) 0px, rgba(255, 106, 0, 0.2) 1px, transparent 1px, transparent 24px);
  --texture-velvet:
    repeating-linear-gradient(115deg, rgba(201, 154, 168, 0.5) 0px, rgba(201, 154, 168, 0.5) 2px, transparent 2px, transparent 10px);
  --texture-canvas:
    repeating-linear-gradient(45deg, rgba(220, 211, 180, 0.4) 0px, rgba(220, 211, 180, 0.4) 1px, transparent 1px, transparent 6px),
    repeating-linear-gradient(-45deg, rgba(220, 211, 180, 0.4) 0px, rgba(220, 211, 180, 0.4) 1px, transparent 1px, transparent 6px);

  --texture-splat: none;   /* overridden by [data-splat] below */
}

[data-splat="htr"] { --texture-splat: var(--texture-cyber); }
[data-splat="vtm"] { --texture-splat: var(--texture-velvet); }
[data-splat="wta"] { --texture-splat: var(--texture-canvas); }

/* =========================================================================
   §09 — MOTION TOKENS
   Decorative loops (despair-pulse, blood-pulse, spinner) must be gated
   behind prefers-reduced-motion — see individual component stylesheets.
   ========================================================================= */

:root {
  --motion-fast:      120ms;   /* taps, toggles, hovers             */
  --motion-base:      200ms;   /* tab slide, menu open, accent state */
  --motion-slow:      360ms;   /* modal & scrim, page transitions    */

  --ease-standard:    cubic-bezier(0.2, 0, 0, 1);   /* general transitions  */
  --ease-out:         cubic-bezier(0, 0, 0.2, 1);   /* exit animations      */
  --ease-emphasized:  cubic-bezier(0.3, 0, 0, 1);   /* strong emphasis      */
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-fast: 0ms;
    --motion-base: 0ms;
    --motion-slow: 0ms;
  }

  /*
   * Blanket gate: several decorative @keyframes across the sheet
   * stylesheets (alarmPulse, despairPulse, spin loaders,
   * shake, dotPulse, slideIn, skeleton-shimmer, …) hardcode their own
   * durations instead of reading var(--motion-*), so zeroing the tokens
   * above doesn't reach them. This is the standard universal override —
   * freezes every animation/transition on the page rather than requiring
   * each keyframe call site to opt in individually.
   */
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
