/* ============================================================
   Fizz — design tokens
   Shaken soda on a summer day: a cool sky-blue field, chunky
   white toy panels with a hard navy bottom edge, six candy
   accents, Fredoka for titles, Nunito for reading and for every
   changing number (its digits are tabular; Fredoka's are not).
   Every colour, size, radius, edge, motion and layer value lives
   here; component sheets in styles/ reference these only.
   Copy the @import, :root, candy scopes, keyframes, reduced-motion
   block and base styles into the game's styles.css.
   ============================================================ */

/* Vendored fonts (Fredoka + Nunito, OFL, Latin + Latin Ext). Keep this line
   first and keep assets/fonts/ at this path relative to the stylesheet.
   Nothing is fetched from the network. */
@import url("assets/fonts/fonts.css");

:root {
  /* ── Surfaces (cool soda ramp) ─────────────────────────── */
  --soda-50:  #F2FAFF;   /* panel-2, zebra rows, shop cards */
  --soda-100: #E3F3FF;   /* page background */
  --soda-200: #C8EDFF;   /* sunk areas, tracks, disabled fills */
  --white:    #FFFFFF;   /* panels, buttons, cards */
  --field: linear-gradient(180deg, #8ED8FF, #C8EDFF);   /* the playfield sky; the only gradient */
  --field-top: #8ED8FF;
  --field-bottom: #C8EDFF;
  --field-ground: var(--lime-fill);

  /* ── Ink (navy) ────────────────────────────────────────── */
  --ink-900: #1E1B3A;    /* titles, numbers, text on candy fills — 14.6:1 on soda-100 */
  --ink-700: #3E3A62;    /* body — 9.3:1 on soda-100 */
  --ink-500: #605C86;    /* muted — 5.5:1 on soda-100, 6.2:1 on white (never on --field) */
  --ink-300: #A8A5C4;    /* disabled edges, lost hearts, off switch — never text */

  /* ── Candy accents ─────────────────────────────────────────
     fill  = buttons, badges, faces (text on it is --ink-900, ≥ 4.85:1)
     ink   = text, icons and meter fills on white, tint or a soda-200 track
             (≥ 5:1 on white, ≥ 4.8:1 on tint)
     tint  = pale ground
     shade = the toy's bottom edge (never a text background)              */
  --bubblegum-fill: #FF5CAB; --bubblegum-ink: #AE1663; --bubblegum-tint: #FFE3F0; --bubblegum-shade: #D13A86; /* hearts, player 2 */
  --tangerine-fill: #FF9226; --tangerine-ink: #9E4A00; --tangerine-tint: #FFE9D2; --tangerine-shade: #E06F00; /* combo, warning */
  --lemon-fill:     #FFD43B; --lemon-ink:     #775600; --lemon-tint:     #FFF5C9; --lemon-shade:     #E6B400; /* coins, stars, best */
  --lime-fill:      #5BE07A; --lime-ink:      #1F7A39; --lime-tint:      #DDF9E4; --lime-shade:      #2FB955; /* primary, success, progress */
  --soda-fill:      #3B9CFF; --soda-ink:      #0B55B8; --soda-tint:      #DCEEFF; --soda-shade:      #1F7BE0; /* selection, timer, player 1 */
  --grape-fill:     #A66BFF; --grape-ink:     #5F2EC2; --grape-tint:     #EDE3FF; --grape-shade:     #8249E6; /* power-ups */

  /* ── Semantic aliases (use these in components) ────────── */
  --bg:             var(--soda-100);
  --surface:        var(--white);
  --surface-2:      var(--soda-50);
  --surface-sunk:   var(--soda-200);
  --fg:             var(--ink-900);
  --fg-body:        var(--ink-700);
  --fg-muted:       var(--ink-500);
  --fg-faint:       var(--ink-300);   /* decorative only */
  --primary:        var(--lime-fill);
  --primary-shade:  var(--lime-shade);
  --fg-on-primary:  var(--ink-900);
  --fg-on-candy:    var(--ink-900);
  --success:        var(--lime-ink);
  --success-tint:   var(--lime-tint);
  --warning:        var(--tangerine-ink);
  --warning-fill:   var(--tangerine-fill);
  --warning-tint:   var(--tangerine-tint);
  --danger:         #B3122C;          /* white text 6.9:1 */
  --danger-fill:    #E8324C;          /* shapes only (crabs, timer end) */
  --danger-tint:    #FDE1E5;
  --danger-shade:   #7A0C1E;
  --fg-on-danger:   var(--white);
  --select:         var(--soda-fill);
  --select-ink:     var(--soda-ink);
  --reward:         var(--lemon-fill);
  --reward-ink:     var(--lemon-ink);
  --medal-gold:     #FFD43B;
  --medal-silver:   #C7CDE0;
  --medal-bronze:   #E0945A;

  /* ── HUD on the playfield ──────────────────────────────────
     No bare text on --field: every value sits in a .hud-chip.      */
  --hud-bg:   rgba(30, 27, 58, 0.88);  /* white ≥ 11:1 over any field colour */
  --hud-fg:   #FFFFFF;
  --hud-num:  var(--lemon-fill);       /* 8:1 on --hud-bg */
  --hud-muted: rgba(255, 255, 255, 0.78);
  --hud-rim:  0 0 0 2px rgba(255, 255, 255, 0.9);
  /* The only text allowed straight on the field: pops, countdown, logo */
  --text-stroke: 4px;
  --text-stroke-lg: 6px;
  --text-drop: 0 3px 0 var(--ink-900);
  --text-drop-lg: 0 6px 0 var(--ink-900);

  /* ── Washes (all the same navy) ────────────────────────── */
  --scrim:  rgba(30, 27, 58, 0.72);
  --hover:  rgba(30, 27, 58, 0.06);
  --press:  rgba(30, 27, 58, 0.12);
  --sheen:  rgba(255, 255, 255, 0.45);   /* 1 px inner highlight on toys */
  --sheen-strong: rgba(255, 255, 255, 0.62);   /* cooldown wash over a candy control */
  --sheen-faint:  rgba(255, 255, 255, 0.3);    /* highlight on --danger, marks on navy */
  --border: rgba(30, 27, 58, 0.14);      /* hairline dividers inside panels */

  /* ── Type ──────────────────────────────────────────────── */
  --font-display: "Fredoka", "Arial Rounded MT Bold", "Nunito", sans-serif;
  --font-ui: "Nunito", -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --font-num: "Nunito", -apple-system, "Segoe UI", Roboto, sans-serif;   /* scores, timers, coins, combo: Nunito's digits share one width, Fredoka's do not */
  --num-tabular: "tnum" 1, "lnum" 1;     /* with --font-num on every score, timer, coin, combo, so system fallbacks stay tabular too */

  --fs-xs:  12px;  --lh-xs:  1.3;
  --fs-sm:  14px;  --lh-sm:  1.35;
  --fs-md:  16px;  --lh-md:  1.45;   /* body, buttons */
  --fs-lg:  18px;  --lh-lg:  1.4;
  --fs-xl:  22px;  --lh-xl:  1.2;
  --fs-2xl: 28px;  --lh-2xl: 1.1;
  --fs-3xl: 40px;  --lh-3xl: 1;
  --fs-4xl: clamp(56px, 16vw, 88px); --lh-4xl: 0.95;

  --fw-regular: 500;       /* Nunito */
  --fw-bold: 700;
  --fw-black: 800;
  --fw-display: 600;       /* Fredoka */
  --fw-display-max: 700;
  --fw-num: 900;           /* Nunito numbers: heavy enough to sit with Fredoka */
  --tracking-caps: 0.08em;
  --tracking-display: 0.005em;

  /* ── Spacing (4 px rhythm) ─────────────────────────────── */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 40px;
  --space-9: 48px;
  --space-10: 64px;
  --gutter: 16px;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);

  /* ── Radii (nothing under 10 px) ───────────────────────── */
  --radius-sm: 10px;
  --radius-md: 16px;       /* buttons, cards */
  --radius-lg: 24px;       /* panels, sheets, the stage */
  --radius-xl: 32px;       /* title card, modal */
  --radius-pill: 999px;

  /* ── Borders and edges ─────────────────────────────────── */
  --bw: 2px;               /* ink "sticker" outline on every panel and button */
  --bw-thick: 3px;         /* selected, power-ups, current level */
  --edge: 4px;             /* hard bottom edge */
  --edge-lg: 6px;          /* game controls, --lg buttons, title and results cards */
  /* Outer ring --soda-ink: 7:1 on white, 6.2:1 on --bg, ≥ 4:1 on the field and seabed */
  --focus-ring: 0 0 0 3px var(--white), 0 0 0 6px var(--soda-ink);
  --focus-ring-inset: inset 0 0 0 3px var(--white), inset 0 0 0 6px var(--soda-ink);   /* rows inside a clipped list */
  --focus-ring-dark: 0 0 0 3px var(--ink-900), 0 0 0 6px var(--lemon-fill);            /* on navy and on the field */

  /* ── Shadows (toy depth: hard edges, never a blurred button shadow) ──
     --shadow-edge / -lg follow a .candy-* scope's shade (below);
     --shadow-edge-ink / -lg stay navy for white toys inside a scope.    */
  --shadow-edge-ink: 0 var(--edge) 0 var(--ink-900);
  --shadow-edge-ink-lg: 0 var(--edge-lg) 0 var(--ink-900);
  --shadow-float: 0 8px 0 rgba(30, 27, 58, 0.16);
  --shadow-sheet: 0 -4px 0 var(--ink-900), 0 -16px 40px rgba(30, 27, 58, 0.25);
  --shadow-pop: 0 12px 0 var(--ink-900), 0 24px 48px rgba(30, 27, 58, 0.35);

  /* ── Sizes ─────────────────────────────────────────────── */
  --control: 48px;         /* minimum button */
  --control-lg: 56px;
  --hit: 44px;             /* minimum touch target for anything tappable */
  --hud-h: 40px;           /* read-only chip */
  --hud-h-hit: 44px;       /* interactive chip */
  --icon: 20px;
  --icon-sm: 16px;
  --icon-lg: 24px;
  --icon-xl: 32px;
  --heart: 24px;
  --star: 56px;
  --ring: 48px;            /* timer ring */
  --ring-stroke: 6px;
  --bar-h: 12px;           /* timer / progress bar */
  --powerup: 56px;
  --action: 80px;          /* touch action button */
  --dpad-cell: 64px;
  --stick: 124px;
  --stick-thumb: 56px;
  --level: 72px;
  --card-w: 360px;         /* title and results cards */
  --bar-min: 96px;         /* timer bar */
  --progress-min: 120px;
  --progress-pip: 18px;
  --pip-w: 16px;           /* shop level pips */
  --pip-h: 10px;
  --hint-tail: 12px;       /* how far a hint's tail reaches past its outline */
  --shop-w: 140px;
  --shop-h: 168px;
  --row-h: 56px;           /* settings row */
  --switch-w: 52px;
  --switch-h: 32px;
  --switch-knob: 22px;
  --toddler-target: 72px;  /* toddler mode: every target at least this */
  --modal-w: 440px;
  --sheet-w: 440px;
  --column: 960px;         /* desktop game column */
  --side-w: 260px;         /* desktop side column from 1100 px */

  /* ── Motion (bouncy and short) ─────────────────────────── */
  --dur-fast: 120ms;       /* press, hover */
  --dur-base: 200ms;
  --dur-pop: 320ms;        /* pops, sheets, stars */
  --dur-slow: 480ms;
  --dur-count: 700ms;      /* score count-up */
  --dur-squash: 160ms;
  --dur-wiggle: 400ms;
  --dur-float: 800ms;      /* score pops rising */
  --dur-pulse: 1200ms;     /* the fastest loop allowed: under 1 cycle per second */
  --dur-bob: 1000ms;
  --dur-tick: 1000ms;      /* timer danger pulse: one per second */
  --dur-stagger: 120ms;    /* stars, list items */
  --dur-hold: 800ms;       /* how long a pop stays readable; timing, kept under reduced motion */
  --dur-step: 800ms;       /* one countdown step (1.25 per second) */
  --dur-toast: 2400ms;
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-pop: cubic-bezier(0.34, 1.56, 0.64, 1);      /* overshoot about 1.08 */
  --ease-squash: cubic-bezier(0.6, 0, 0.4, 1);
  --ease-bounce: linear(0, 0.4 20%, 0.9 45%, 1.05 65%, 0.98 85%, 1);

  /* ── Layers ────────────────────────────────────────────── */
  --z-field: 0;
  --z-actors: 10;
  --z-pops: 20;
  --z-hud: 30;
  --z-controls: 40;
  --z-sheet: 50;
  --z-toast: 60;
  --z-modal: 70;
  --z-countdown: 80;

  /* Default candy scope: a white toy with an ink edge */
  --c-fill: var(--white);
  --c-ink: var(--ink-900);
  --c-tint: var(--soda-50);
  --c-shade: var(--ink-900);
}

/* ============================================================
   Candy scopes — put one on a button, chip, power-up, shop item
   or zone; its components read --c-fill / --c-ink / --c-tint /
   --c-shade. The edge tokens are re-declared here so a scope's
   edge follows its own shade.
   ============================================================ */
.candy-bubblegum { --c-fill: var(--bubblegum-fill); --c-ink: var(--bubblegum-ink); --c-tint: var(--bubblegum-tint); --c-shade: var(--bubblegum-shade); }
.candy-tangerine { --c-fill: var(--tangerine-fill); --c-ink: var(--tangerine-ink); --c-tint: var(--tangerine-tint); --c-shade: var(--tangerine-shade); }
.candy-lemon     { --c-fill: var(--lemon-fill);     --c-ink: var(--lemon-ink);     --c-tint: var(--lemon-tint);     --c-shade: var(--lemon-shade); }
.candy-lime      { --c-fill: var(--lime-fill);      --c-ink: var(--lime-ink);      --c-tint: var(--lime-tint);      --c-shade: var(--lime-shade); }
.candy-soda      { --c-fill: var(--soda-fill);      --c-ink: var(--soda-ink);      --c-tint: var(--soda-tint);      --c-shade: var(--soda-shade); }
.candy-grape     { --c-fill: var(--grape-fill);     --c-ink: var(--grape-ink);     --c-tint: var(--grape-tint);     --c-shade: var(--grape-shade); }

:root, [class*="candy-"] {
  --shadow-edge: 0 var(--edge) 0 var(--c-shade, var(--ink-900));
  --shadow-edge-lg: 0 var(--edge-lg) 0 var(--c-shade, var(--ink-900));
}

/* ============================================================
   Keyframes — shared by every sheet
   ============================================================ */
@keyframes fz-pop {            /* arrive: .6 → 1.08 → 1; keeps a tilt set with --rot */
  0%   { transform: rotate(var(--rot, 0deg)) scale(0.6); opacity: 0; }
  60%  { transform: rotate(var(--rot, 0deg)) scale(1.08); opacity: 1; }
  100% { transform: rotate(var(--rot, 0deg)) scale(1); opacity: 1; }
}
@keyframes fz-pop-raised {     /* fz-pop for the raised middle results star */
  0%   { transform: translateY(-10px) scale(0.6); opacity: 0; }
  60%  { transform: translateY(-10px) scale(1.08); opacity: 1; }
  100% { transform: translateY(-10px) scale(1); opacity: 1; }
}
@keyframes fz-bump {           /* a HUD value ticks up (a beat, not an arrival: 1.12) */
  0%, 100% { transform: scale(1); }
  40%      { transform: scale(1.12); }
}
@keyframes fz-squash {         /* land, lose a heart */
  0%   { transform: scale(1.12, 0.88); }
  100% { transform: scale(1, 1); }
}
@keyframes fz-wiggle {         /* combo breaks, new best */
  0%, 100% { transform: rotate(0deg); }
  20% { transform: rotate(-4deg); }
  40% { transform: rotate(4deg); }
  60% { transform: rotate(-3deg); }
  80% { transform: rotate(2deg); }
}
@keyframes fz-float-up {       /* score pops rise and fade */
  0%   { transform: translate(-50%, 0) scale(0.7); opacity: 0; }
  15%  { transform: translate(-50%, -8px) scale(1.08); opacity: 1; }
  70%  { opacity: 1; }
  100% { transform: translate(-50%, -56px) scale(1); opacity: 0; }
}
@keyframes fz-fade-hold {      /* reduced motion: pops stay put and fade */
  0%, 70% { opacity: 1; }
  100% { opacity: 0; }
}
@keyframes fz-pulse-glow {     /* 1.2 s loop: ready, hurry */
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); }
  50%      { box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.55); }
}
@keyframes fz-pulse-danger {   /* timer ring under 10 %: one pulse per --dur-tick */
  0%, 100% { box-shadow: 0 0 0 var(--bw) var(--ink-900), var(--hud-rim); }
  50%      { box-shadow: 0 0 0 var(--bw) var(--ink-900), 0 0 0 6px var(--danger-fill); }
}
@keyframes fz-bob {            /* hint hand, idle actors: 1 s */
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
@keyframes fz-slide-up {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}
@keyframes fz-shake {          /* the field takes a hit: ±4 px, once, over --dur-base */
  0%, 100% { transform: translate(0, 0); }
  25%      { transform: translate(-4px, 2px); }
  50%      { transform: translate(4px, -2px); }
  75%      { transform: translate(-2px, 1px); }
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 0ms;
    --dur-base: 0ms;
    --dur-pop: 0ms;
    --dur-slow: 0ms;
    --dur-count: 0ms;
    --dur-squash: 0ms;
    --dur-wiggle: 0ms;
    --dur-float: 0ms;
    --dur-pulse: 0ms;
    --dur-bob: 0ms;
    --dur-tick: 0ms;
    --dur-stagger: 0ms;
  }
  *, *::before, *::after {
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}
/* Same switch for a page-level setting or a preview toggle */
.reduce-motion {
  --dur-fast: 0ms; --dur-base: 0ms; --dur-pop: 0ms; --dur-slow: 0ms; --dur-count: 0ms;
  --dur-squash: 0ms; --dur-wiggle: 0ms; --dur-float: 0ms; --dur-pulse: 0ms; --dur-bob: 0ms; --dur-tick: 0ms; --dur-stagger: 0ms;
}

/* ============================================================
   Base
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--fg-body);
  font-family: var(--font-ui);
  font-size: var(--fs-md);
  font-weight: var(--fw-regular);
  line-height: var(--lh-md);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

h1, h2, h3 { margin: 0; color: var(--fg); font-family: var(--font-display); font-weight: var(--fw-display); }
p { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
img, svg { display: block; max-width: 100%; }
::selection { background: var(--lemon-fill); color: var(--ink-900); }
[hidden] { display: none !important; }

:focus-visible { outline: none; box-shadow: var(--focus-ring); }

/* ============================================================
   Icons — assets/icons/ui-sprite.svg and game-sprite.svg
   (Phosphor fill). All paint with currentColor.
   <svg class="icon" aria-hidden="true"><use href="#heart"/></svg>
   ============================================================ */
.icon { width: var(--icon); height: var(--icon); flex: none; fill: currentColor; }
.icon--sm { width: var(--icon-sm); height: var(--icon-sm); }
.icon--lg { width: var(--icon-lg); height: var(--icon-lg); }
.icon--xl { width: var(--icon-xl); height: var(--icon-xl); }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ============================================================
   Type roles
   ============================================================ */
.t-display {
  font-family: var(--font-display);
  font-size: var(--fs-3xl);
  font-weight: var(--fw-display-max);
  line-height: var(--lh-3xl);
  letter-spacing: var(--tracking-display);
  color: var(--fg);
}
.t-title {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: var(--fw-display);
  line-height: var(--lh-xl);
  color: var(--fg);
}
.t-score {
  font-family: var(--font-num);
  font-size: var(--fs-2xl);
  font-weight: var(--fw-num);
  line-height: var(--lh-2xl);
  font-feature-settings: var(--num-tabular);
  color: var(--fg);
}
.t-num {
  font-family: var(--font-num);
  font-weight: var(--fw-num);
  font-feature-settings: var(--num-tabular);
}
.t-eyebrow {
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: var(--fw-black);
  line-height: var(--lh-xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--fg-muted);
}
.t-body {
  font-family: var(--font-ui);
  font-size: var(--fs-md);
  font-weight: var(--fw-regular);
  line-height: var(--lh-md);
  color: var(--fg-body);
}
.t-small { font-size: var(--fs-sm); line-height: var(--lh-sm); }
.t-muted { color: var(--fg-muted); }
/* The only text allowed bare on --field: white Fredoka with an ink stroke
   and a hard ink drop (pops, countdown, logo). */
.t-outline {
  font-family: var(--font-display);
  font-weight: var(--fw-display-max);
  color: var(--white);
  paint-order: stroke fill;
  -webkit-text-stroke: var(--text-stroke) var(--ink-900);
  text-shadow: var(--text-drop);
}

body { background: var(--field); }
.game-shell { min-height: 100dvh; display: grid; place-items: center; padding: var(--space-4); }
.game-card { width: 100%; max-width: calc(var(--card-w) + var(--space-10) * 2); padding: var(--space-6) var(--space-4); background: var(--surface); border: var(--bw) solid var(--ink-900); border-radius: var(--radius-lg); box-shadow: var(--shadow-edge-ink-lg); text-align: center; }
.game-card > * + * { margin-top: var(--space-5); }
.eyebrow { display: flex; align-items: center; justify-content: center; gap: var(--space-2); }
.game-title { font-size: var(--fs-2xl); }
.mystery { display: grid; place-items: center; margin-inline: auto; width: var(--stick); height: var(--stick); background: var(--c-tint); border: var(--bw) dashed var(--c-ink); border-radius: var(--radius-lg); color: var(--c-ink); font-size: var(--fs-4xl); }
.counters { display: flex; justify-content: center; flex-wrap: wrap; gap: var(--space-3); }
.guess-buttons { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-2); }
.guess-buttons .btn { min-width: var(--hit); min-height: var(--dpad-cell); padding: 0; font-family: var(--font-num); font-weight: var(--fw-num); font-size: var(--fs-2xl); }
.feedback { min-height: var(--control-lg); display: grid; place-items: center; padding: var(--space-3); border-radius: var(--radius-md); background: var(--c-tint); color: var(--c-ink); font-weight: var(--fw-bold); }
.rules { color: var(--fg-muted); font-size: var(--fs-sm); }
@media (max-width: 340px) { .guess-buttons { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.rules .icon { display: inline-block; vertical-align: middle; }
.loading-overlay { position: fixed; inset: 0; z-index: var(--z-countdown); display: grid; place-content: center; background: var(--surface); color: var(--fg); }
.loading-overlay--hidden { display: none; }
