/* ============================================================================
   Design tokens — Rift of the Hollow Crown
   ----------------------------------------------------------------------------
   The single source for colour, depth, rhythm and timing. Nothing in the
   interface may hard-code a hex, a radius, a shadow or a duration; if a value
   is needed and is not here, it belongs here first.

   Names and values follow `docs/Game_UI_Design_System.md` §2. Where this file
   carries a token the design doc does not name, it is marked EXTRA and uses
   the doc's naming grammar so the set still reads as one scale.

   Two deviations from the doc, both deliberate and both recorded in
   docs/ideas/game-ui-design-system/PLAN.md §8:

     --t-fast is 90ms, not the doc's 120ms. docs/QUALITY.md Gate 2 requires
     touch feedback under 100ms, and a press that answers in 120ms reads as
     late. The gate wins over the token table.

     This file lives in styles/, not src/ui/. The repo keeps CSS in styles/
     and JS in src/.

   The look is "fantasy chunky": surfaces have thickness, not borders. Every
   raised thing carries the same three-part depth — a light bevel on its top
   edge, a body gradient, and a hard colour shelf underneath that reads as the
   object's own side rather than as a drop shadow.

   Lit from above and slightly left, consistently, everywhere.
   ========================================================================== */

:root {
  /* --- surfaces -----------------------------------------------------------
     Never a flat panel on a flat field. The app sits on an illustrated
     backdrop; panels are cold-dark stone that reads against it. */
  --ink-900: #0b111f;             /* nav bar, deepest panels, text on light */
  --ink-800: #121b30;             /* panel fill */
  --ink-700: #1c2842;             /* raised panel, plaque fill */
  --ink-600: #2a3042;             /* EXTRA — hairline risers between the above */
  --ink-500: #363d52;             /* EXTRA */
  --ink-400: #4a5268;             /* EXTRA */

  --panel-face: linear-gradient(180deg, #243052 0%, #16203a 54%, #111829 100%);
  --panel-face-raised: linear-gradient(180deg, #32406a 0%, #1f2a4a 56%, #16203a 100%);
  --panel-sunken: linear-gradient(180deg, #0a0f1c 0%, #121a2c 100%);
  --panel-veil: rgba(18, 27, 48, 0.86);   /* EXTRA — panel over artwork */

  /* --- gold ---------------------------------------------------------------
     Frames and primary actions. Anything the player owns or earns. */
  --gold-100: #fff1c2;            /* highlight / shine */
  --gold-200: #ffd98a;            /* EXTRA — between highlight and main */
  --gold-300: #f5c850;            /* main gold */
  --gold-400: #d1922f;            /* EXTRA — between main and mid */
  --gold-500: #c98e2b;            /* mid */
  --gold-800: #6b4210;            /* outline, deep shade */

  /* --- royal --------------------------------------------------------------
     Secondary actions: Stages, Change, Back. */
  --royal-400: #3d6be8;
  --royal-700: #1a347f;
  --royal-900: #14255c;           /* EXTRA — the shelf under a royal button */

  /* --- iron ---------------------------------------------------------------
     EXTRA. The other alloy: structure rather than reward. */
  --iron-200: #9fadc6;
  --iron-300: #76829a;
  --iron-400: #4e5870;
  --iron-500: #333b4f;

  --line: rgba(120, 142, 190, 0.22);        /* EXTRA — hairline divider */
  --line-strong: rgba(150, 175, 230, 0.4);  /* EXTRA */

  /* --- text --------------------------------------------------------------- */
  --text-cream: #fff4dc;          /* on dark */
  --text-ink: #3a2408;            /* on gold */
  --text-muted: #b9c2d6;
  --text-dim: #8591aa;            /* EXTRA — one step quieter than muted */
  --text-on-light: #1b2030;       /* EXTRA */

  /* --- states ------------------------------------------------------------- */
  --alert: #e53935;
  --success: #43c46b;
  --warn: #ffb020;
  --info: #5ea9ff;                /* EXTRA */
  --alert-deep: #8e221c;          /* EXTRA */
  --success-deep: #1d7d3c;        /* EXTRA */
  --warn-deep: #a6690f;           /* EXTRA */

  /* --- rarity -------------------------------------------------------------
     R grey · S purple · SR orange · SSR red · UR red-black.

     Rarity is what a hero was BORN as and never changes, so it paints the
     card bed — the thing under the art that is always there. The frame is
     spoken for by the awakening tier below, which is the axis the player
     actually moves. Two signals on one card only works because they sit on
     different parts of it.

     Each rarity carries four values: the hue it labels itself with, the deep
     stop, the bed the art sits on, and the glow it throws. Colour is never
     the only signal — the corner letter carries it too, so the ramp survives
     colour blindness. The -deep, -bed and -glow stops are EXTRA; the base
     hue is the doc's. */
  /* THE BEDS ARE THE SIGNAL, so they are saturated enough to be read as
     five different colours at a glance on a 70px tile.
     
     They were mixed down to near-black — #3b4250 through #5c1f22 — on the
     reasoning that a dark bed does not fight the art above it. At five
     across that was five dark rectangles: a player scanning a roster for
     their SSRs had to read the corner letter on every single tile,
     because nothing else distinguished them. The letter still carries it
     for anyone who cannot use the colour; the colour now carries it for
     everyone who can. */
  /* THE RAMP, as specified: green/teal, blue/cyan, violet, amber, red.
     
     Five distinct HUES rather than five brightnesses of one. The ramp was
     grey-violet-orange-red-red, which put SSR and UR a shade apart at the
     end where the distinction matters most, and made R and S the two
     dimmest things on a dark screen. Walking the spectrum instead means
     any two rarities differ in hue, not only in saturation — which is
     what survives a small tile, a cheap panel and most colour blindness.
     The corner letter still carries it for the rest.
     
     Each rarity has four stops: the hue it labels itself with, the deep
     stop, the bed the art sits on, and the glow it throws. */

  /* R — green/teal. Material: the thing you dismantle. */
  --r-r: #3fd6a0;
  --r-r-deep: #155e49;
  --r-r-bed: radial-gradient(118% 100% at 50% 6%, #2d9c78, #103a2e);
  --r-r-glow: rgba(63, 214, 160, 0);

  /* S — blue/cyan. */
  --r-s: #36b6ff;
  --r-s-deep: #0f537e;
  --r-s-bed: radial-gradient(118% 100% at 50% 6%, #2186cc, #0b2c47);
  --r-s-glow: rgba(54, 182, 255, 0.3);

  /* SR — purple/violet. */
  --r-sr: #a861ff;
  --r-sr-deep: #45218a;
  --r-sr-bed: radial-gradient(118% 100% at 50% 6%, #7a3fd6, #2a1352);
  --r-sr-glow: rgba(168, 97, 255, 0.42);

  /* SSR — amber. */
  --r-ssr: #ffb02e;
  --r-ssr-deep: #8a5406;
  --r-ssr-bed: radial-gradient(118% 100% at 50% 6%, #dd9015, #4a2c05);
  --r-ssr-glow: rgba(255, 176, 46, 0.5);

  /* UR — bright red. The top of the ramp, and the only red on it, so
     nothing else on a roster can be mistaken for one. */
  --r-ur: #ff3b3b;
  --r-ur-deep: #7a0f12;
  --r-ur-bed: radial-gradient(118% 100% at 50% 6%, #cf1f26, #3d0709);
  --r-ur-glow: rgba(255, 59, 59, 0.62);

  /* --- awakening tiers ----------------------------------------------------
     Twelve tiers, six colour families. The "+" steps share their base
     family's colour and add an ornament instead, so the ladder stays
     readable with the colour stripped out — a player who cannot tell the
     purple from the gold can still count the ornaments.

     These paint the FRAME. Rarity paints the bed. A card therefore says two
     things at once without either shouting over the other. */
  --aw-excellent: #b06bff;
  --aw-excellent-glow: rgba(176, 107, 255, 0.4);
  --aw-epic: #ffc13a;
  --aw-epic-glow: rgba(255, 193, 58, 0.45);
  --aw-legendary: #ff5436;
  --aw-legendary-glow: rgba(255, 84, 54, 0.5);
  --aw-mythic: #ff79d0;
  --aw-mythic-glow: rgba(255, 121, 208, 0.52);
  --aw-transcend: #4ce0e8;
  --aw-transcend-glow: rgba(76, 224, 232, 0.55);
  --aw-eternal: #e8f4ff;
  --aw-eternal-glow: rgba(200, 232, 255, 0.72);

  /* --- factions -----------------------------------------------------------
     A hue and a deep for each, used by the emblem, the card pattern and the
     battlefield tint. The -deep stops are EXTRA.

     Six peoples, not five elements. Human and Void sit at opposite ends of
     the hue circle from their counters so the wheel is legible at a glance:
     the four-step ring is already one step harder to recall than the three
     it replaced, and colour is what carries the difference. */
  --f-human: #4e8ad8;
  --f-human-deep: #1d3f70;
  --f-beast: #e27a3a;
  --f-beast-deep: #6e3410;
  --f-elf: #6fcf9b;
  --f-elf-deep: #235840;
  --f-covenant: #a855f7;
  --f-covenant-deep: #4a1d7a;
  --f-god: #ffd866;
  --f-god-deep: #8a6413;
  --f-void: #8b4dff;
  --f-void-deep: #4a2278;

  /* --- depth --------------------------------------------------------------
     EXTRA, and the whole reason the interface reads as objects rather than
     cards. `shelf` is the object's own thickness: a hard, unblurred band of
     its darker self. `cast` is the shadow it throws on what is behind. A
     raised element uses both; a flat one uses neither. */
  --shelf-sm: 0 2px 0;
  --shelf-md: 0 4px 0;
  --shelf-lg: 0 6px 0;
  --cast-sm: 0 3px 6px rgba(0, 0, 0, 0.4);
  --cast-md: 0 7px 16px rgba(0, 0, 0, 0.45);
  --cast-lg: 0 14px 34px rgba(0, 0, 0, 0.55);
  --bevel: inset 0 2px 0 rgba(255, 255, 255, 0.28);
  --bevel-strong: inset 0 3px 0 rgba(255, 255, 255, 0.45);
  --carve: inset 0 2px 7px rgba(0, 0, 0, 0.55);

  /* --- game text look ----------------------------------------------------
     Display text always gets a dark stroke so it reads on busy art. */
  --stroke-dark: 0 2px 0 rgba(0, 0, 0, 0.55);
  --glow-gold: 0 0 12px rgba(245, 200, 80, 0.55);

  /* --- shape --------------------------------------------------------------
     EXTRA. Named `rad-` rather than `r-`, because `--r-` is the rarity ramp
     and two scales sharing a prefix is how a token set starts rotting. */
  --rad-sm: 8px;
  --rad-md: 13px;
  --rad-lg: 18px;
  --rad-xl: 24px;
  --rad-pill: 999px;
  --frame-w: 3px;                 /* the metal edge on a framed thing */

  /* --- rhythm -------------------------------------------------------------
     A 4px base. The number in the name IS the pixel count, so --s6 is 24px.
     Tight inside a group, generous between groups. */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s6: 24px;
  --s8: 32px;
  --s12: 48px;                    /* EXTRA */

  /* Touch target floor. iOS asks 44pt, Android 48dp. 44 CSS px satisfies
     both once the 8px gap between controls is counted, and it is what the
     playtest gate enforces today. Raising it to 48 is a density decision,
     not a rename decision — tracked separately. */
  --tap: 44px;

  /* --- chrome ------------------------------------------------------------- */
  --topbar-h: 58px;               /* EXTRA */
  --navbar-h: 62px;               /* EXTRA */

  /* --- type ---------------------------------------------------------------
     Display carries the fantasy voice, body carries the reading, numerals
     carry anything the player compares. All three must have Vietnamese.
     Sizes are `fz-` rather than `t-`, because `--t-` is the motion scale. */
  --font-display: 'Philosopher', 'Be Vietnam Pro', serif;
  --font-body: 'Be Vietnam Pro', system-ui, sans-serif;
  --font-num: 'Be Vietnam Pro', system-ui, sans-serif;
  --num-feat: 'tnum' 1, 'lnum' 1;

  --fz-display-lg: clamp(1.75rem, 8vw, 2.6rem);
  --fz-display: clamp(1.3rem, 6vw, 1.75rem);
  --fz-title: 1.08rem;
  --fz-body: 0.92rem;
  --fz-small: 0.8rem;
  --fz-tiny: 0.7rem;

  /* --- motion -------------------------------------------------------------
     Nothing appears instantly. See the header note on --t-fast. */
  --t-fast: 90ms;                 /* press feedback, must beat 100ms */
  --t-quick: 170ms;               /* EXTRA — hover, small state changes */
  --t-base: 240ms;                /* screen and panel transitions */
  --t-slow: 400ms;                /* modals, reward reveals */
  --t-flourish: 900ms;            /* EXTRA — banners, star stamps */
  --t-idle: 3200ms;               /* EXTRA — breathing, shine sweep period */
  --stagger: 42ms;                /* EXTRA — between siblings entering */

  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in: cubic-bezier(0.5, 0, 0.75, 0);        /* EXTRA */
  --ease-back: cubic-bezier(0.34, 1.56, 0.64, 1);  /* overshoot, for pops */
  --ease-spring: cubic-bezier(0.16, 1.5, 0.3, 1);  /* EXTRA — snappier */

  /* --- layers -------------------------------------------------------------
     The five stacked layers of §1. Every screen is built from these and
     never from one flattened image. */
  --z-scene: 0;                   /* illustrated background, ambient motion */
  --z-world: 10;                  /* items anchored to positions in the scene */
  --z-hud: 20;                    /* fixed screen-edge chrome */
  --z-overlay: 30;                /* modals, reward popups, tooltips */
  --z-fx: 40;                     /* particles and flying rewards */
  --z-toast: 60;                  /* EXTRA — above even the FX layer */
}

/* The system setting is honoured by removing idle loops and overshoot, not by
   removing feedback: a press still has to answer. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --t-base: 1ms;
    --t-slow: 1ms;
    --t-flourish: 1ms;
    --t-idle: 1ms;
    --stagger: 0ms;
    --ease-back: linear;
    --ease-spring: linear;
  }
}


/* ===========================================================================
   Rarity, as a set of variables anything can opt into
   --------------------------------------------------------------------------
   `.rar-<letter>` on any element binds that rarity's four stops to the
   generic names, so a surface showing a hero writes `var(--rar-bed)`
   rather than knowing which rarity it is.

   This existed only inside `.kit-hero`, so the tile was the one place in
   the game where rarity was visible: portraits, reward chips, the rage
   orbs, the formation pads and the awakening plan rows all carried a
   `rar-ssr` class that matched no rule and painted the same slate grey
   whatever the hero was.

   Both spellings are bound. Hero data uses letters, but a few surfaces
   still receive the legacy word, and a class that matches nothing is
   exactly the failure this block is fixing.
   ========================================================================= */

.rar-r,   .rar-common    { --rar: var(--r-r);   --rar-deep: var(--r-r-deep);   --rar-bed: var(--r-r-bed);   --rar-glow: var(--r-r-glow); }
.rar-s,   .rar-rare      { --rar: var(--r-s);   --rar-deep: var(--r-s-deep);   --rar-bed: var(--r-s-bed);   --rar-glow: var(--r-s-glow); }
.rar-sr,  .rar-epic      { --rar: var(--r-sr);  --rar-deep: var(--r-sr-deep);  --rar-bed: var(--r-sr-bed);  --rar-glow: var(--r-sr-glow); }
.rar-ssr, .rar-legendary { --rar: var(--r-ssr); --rar-deep: var(--r-ssr-deep); --rar-bed: var(--r-ssr-bed); --rar-glow: var(--r-ssr-glow); }
.rar-ur,  .rar-mythic    { --rar: var(--r-ur);  --rar-deep: var(--r-ur-deep);  --rar-bed: var(--r-ur-bed);  --rar-glow: var(--r-ur-glow); }
