/* ============================================================================
   tokens.css — SINGLE SOURCE OF TRUTH for design tokens.

   Every other stylesheet in this app (base.css, components.css, views.css,
   decor.css, print.css) MUST consume these custom properties and MUST NOT
   redeclare them. Load order in <head> is: fonts.css, tokens.css, base.css,
   components.css, views.css, decor.css, print.css (print.css last, media
   print). fonts.css already defines --font-cinzel / --font-display /
   --font-rune-latin / --font-scroll / --font-sans — this file does not
   redefine those, it only references them.

   ART DIRECTION RULE (do not violate anywhere downstream):
   the frame never changes color, only the light does. Gold (--gold-*) is
   structure: frames, type, seals, buttons — always. --spirit / --spirit-rim /
   --spirit-glow is the ONLY color channel that changes per dragon species,
   and it is only ever used for aura/glow/particle/rim effects, never as a
   button fill or body-text color.

   --spirit is mutated at runtime by the orchestrator's JS via
   root.style.setProperty('--spirit', hex). Every file below must read it
   live (var(--spirit)) rather than caching a copy, since color-mix() based
   custom properties (--spirit-rim, --spirit-glow) recompute automatically
   whenever --spirit changes on :root.
   ============================================================================ */

:root {
  /* ---- 1. CORE PALETTE (fixed — do not add new base hexes elsewhere) ---- */
  --ink:            #0C0806;
  --vellum-dark:    #1A120B;
  --vellum-edge:    #2A1D12;
  --gold-leaf:      #D9A441;
  --gold-hi:        #F5D98B;
  --gold-dim:       #8A6A2F;
  --parchment:      #EFE2C4;
  --parchment-shade:#D8C398;
  --iron-gall:      #241708;

  /* per-species accent — THE ONLY variable the orchestrator's JS reassigns */
  --spirit:      #FFB800;
  --spirit-rim:  color-mix(in oklab, var(--spirit) 30%, var(--gold-leaf));
  --spirit-glow: color-mix(in oklab, var(--spirit) 55%, transparent);
  --spirit-glow-soft: color-mix(in oklab, var(--spirit) 28%, transparent);

  /* wax-seal red — reserved EXCLUSIVELY for the exported keepsake (decor.css).
     Never used as UI chrome, never a button, never a status color. */
  --seal-red:    #8C1D18;
  --seal-red-hi: #B23A2E;
  --seal-red-shadow: #4A0E0B;

  /* ---- 2. SEMANTIC SURFACES ---- */
  --surface-0: var(--ink);          /* app backdrop, deepest layer */
  --surface-1: var(--vellum-dark);  /* page / view background */
  --surface-2: var(--vellum-edge);  /* card / panel background */
  --surface-raised: color-mix(in oklab, var(--vellum-edge) 84%, var(--gold-leaf) 8%);
  --surface-sunken: color-mix(in oklab, var(--ink) 88%, var(--vellum-dark) 12%);
  --surface-overlay: color-mix(in oklab, var(--ink) 78%, transparent);

  /* ---- 3. SEMANTIC TEXT ----
     Contrast measured against the surface each is meant to sit on
     (WCAG relative-luminance formula, sRGB):
       --text-body      (#EFE2C4) on --surface-1 (#1A120B)  ≈ 13.8:1  (AA/AAA any size)
       --text-muted     (#D8C398) on --surface-1 (#1A120B)  ≈ 10.5:1  (AA/AAA any size)
       --text-heading   (#F5D98B) on --surface-1 (#1A120B)  ≈ 12.9:1  (AA/AAA any size)
       --text-accent    (#D9A441) on --surface-1 (#1A120B)  ≈  7.1:1  (AA any size)
       --text-on-gold   (#0C0806) on --gold-leaf (#D9A441)  ≈  9.3:1  (AA/AAA any size)
       --text-on-gold   (#0C0806) on --gold-hi   (#F5D98B)  ≈ 15.7:1  (AA/AAA any size)
     This is why buttons use dark ink text on a gold fill, never the reverse —
     the previous build put light text on gold (≈2.1:1, fails AA outright). */
  --text-body:    var(--parchment);
  --text-muted:   var(--parchment-shade);
  --text-heading: var(--gold-hi);
  --text-accent:  var(--gold-leaf);
  --text-on-gold: var(--ink);
  --text-on-spirit: var(--ink); /* if any small chip ever fills with --spirit-glow solidly */

  /* --gold-dim measured against --surface-1 is only ≈3.5:1 — large-text/
     bold/icon/border use ONLY (WCAG large-text floor is 3:1). Never body copy. */
  --text-decorative: var(--gold-dim);

  /* ---- 4. TYPOGRAPHY SCALE ---- */
  --fs-2xs: 0.6875rem;  /* 11px — legal/footnote */
  --fs-xs:  0.75rem;    /* 12px — captions, badges */
  --fs-sm:  0.8125rem;  /* 13px — secondary UI */
  --fs-base:0.9375rem;  /* 15px — body */
  --fs-md:  1.0625rem;  /* 17px */
  --fs-lg:  1.25rem;    /* 20px — sub-headings */
  --fs-xl:  1.625rem;   /* 26px — section headings */
  --fs-2xl: 2.125rem;   /* 34px — view titles */
  --fs-3xl: 2.75rem;    /* 44px — hero / chapter numerals */
  --lh-tight: 1.15;
  --lh-snug:  1.35;
  --lh-normal:1.6;
  --lh-loose: 1.85; /* narrative prose in --font-scroll reads better looser */
  --ls-wide: 0.06em;   /* small-caps label tracking */
  --ls-wider:0.12em;

  /* ---- 5. SPACING (4px base unit) ---- */
  --space-1: 0.25rem;  --space-2: 0.5rem;   --space-3: 0.75rem;
  --space-4: 1rem;     --space-5: 1.25rem;  --space-6: 1.5rem;
  --space-8: 2rem;     --space-10: 2.5rem;  --space-12: 3rem;
  --space-16: 4rem;    --space-20: 5rem;

  /* ---- 6. RADII ---- */
  --radius-sm:   6px;
  --radius-md:   10px;
  --radius-lg:   18px;
  --radius-xl:   28px;
  --radius-pill: 999px;

  /* ---- 7. BORDERS ---- */
  --border-hairline: 1px;
  --border-thin:      2px;
  --border-thick:      3px;
  --border-gold: var(--border-thin) solid var(--gold-leaf);
  --border-gold-dim: var(--border-hairline) solid color-mix(in oklab, var(--gold-leaf) 35%, transparent);

  /* ---- 8. SHADOWS ---- */
  --shadow-sm: 0 2px 6px rgba(0,0,0,0.35);
  --shadow-md: 0 8px 22px -4px rgba(0,0,0,0.55), 0 2px 6px rgba(0,0,0,0.4);
  --shadow-lg: 0 18px 44px -10px rgba(0,0,0,0.7), 0 4px 12px rgba(0,0,0,0.45);
  --shadow-inset-parchment: inset 0 0 32px rgba(74,46,17,0.35), inset 0 2px 0 rgba(255,255,255,0.18);
  --shadow-gold-glow: 0 0 0 1px color-mix(in oklab, var(--gold-leaf) 55%, transparent), 0 0 26px -4px color-mix(in oklab, var(--gold-leaf) 65%, transparent);
  --shadow-spirit-glow: 0 0 0 1px var(--spirit-rim), 0 0 34px -6px var(--spirit-glow);
  --shadow-focus: 0 0 0 3px color-mix(in oklab, var(--gold-hi) 55%, transparent);

  /* ---- 9. MOTION ---- */
  --ease-standard: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-in-out:   cubic-bezier(0.45, 0, 0.55, 1);
  --dur-fast:  150ms;
  --dur-base:  250ms;
  --dur-slow:  450ms;
  --dur-dice:  900ms;
  --dur-shimmer: 3.2s;

  /* ---- 10. Z-INDEX SCALE ---- */
  --z-bg:            0;   /* body::before grain/vignette, #particleCanvas */
  --z-app:           1;   /* normal document flow content */
  --z-decor:         5;   /* rune borders, capitals, ambient decor overlays */
  --z-sticky:       20;   /* header, nav-tabs */
  --z-dropdown:     30;
  --z-coachmark:    85;   /* contextual per-tab hint popover/bottom-sheet */
  --z-modal-overlay:90;
  --z-modal:        91;
  --z-toast:       100;
  --z-fx-flash:    200;   /* js/fx.js critImpact() flash overlay — always on top */
  --z-intro:       250;   /* one-time cinematic overlay — above everything, including fx-flash */

  /* ---- 11. GOLD FOIL / "HAMMERED METAL" TEXTURE ----
     Layered background-image: two repeating specular streak layers (a bright
     hairline highlight pass + a soft dark hairline shadow pass, both on a
     diagonal) over a base gradient — this is what makes it read as beaten
     metal instead of a flat CSS gradient. Used by .btn-primary, .card
     corner-fittings, and decor.css seals/frames. */
  --gold-foil:
    repeating-linear-gradient(115deg,
      rgba(255,255,255,0.32) 0px, rgba(255,255,255,0.32) 1.5px,
      rgba(255,255,255,0) 1.5px, rgba(255,255,255,0) 7px),
    repeating-linear-gradient(115deg,
      rgba(0,0,0,0.22) 0px, rgba(0,0,0,0.22) 1px,
      rgba(0,0,0,0) 1px, rgba(0,0,0,0) 9px),
    linear-gradient(155deg, var(--gold-hi) 0%, var(--gold-leaf) 48%, var(--gold-dim) 100%);

  --gold-foil-hover:
    repeating-linear-gradient(115deg,
      rgba(255,255,255,0.4) 0px, rgba(255,255,255,0.4) 1.5px,
      rgba(255,255,255,0) 1.5px, rgba(255,255,255,0) 7px),
    repeating-linear-gradient(115deg,
      rgba(0,0,0,0.18) 0px, rgba(0,0,0,0.18) 1px,
      rgba(0,0,0,0) 1px, rgba(0,0,0,0) 9px),
    linear-gradient(155deg, var(--gold-hi) 0%, var(--gold-leaf) 40%, var(--gold-leaf) 100%);

  /* ---- 12. VELLUM GRAIN (shared raster-free texture) ----
     One SVG feTurbulence tile, referenced by base.css (body texture),
     components.css (card/parchment fills) and decor.css (seal/frame fills).
     0 network requests — it's a data: URI. Percent-encoded manually
     (raw '<','>','#','%' would otherwise break the data: URI parser). */
  --noise-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch' result='t'/%3E%3CfeColorMatrix in='t' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");

  /* coarser variant for large parchment fills (Journal page, keepsake) so the
     grain doesn't look like screen-door mesh at bigger sizes */
  --noise-grain-coarse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.55' numOctaves='3' stitchTiles='stitch' result='t'/%3E%3CfeColorMatrix in='t' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Dice cube geometry — grouped separately since it's consumed only by the
   .dice-scene/.dice-cube/.dice-face rules in components.css, but must be a
   single authored constant so the JS rotation math in js/fx.js and the CSS
   translateZ() distance always agree (half of --dice-size). */
:root {
  --dice-size: 108px;
  --dice-half: calc(var(--dice-size) / 2);
}
