/* Level Lab skeleton — PRODUCTION visual language (src/style.css + renderer.ts):
   blue→purple ground gradient, dark translucent purple HUD pills with mint numerals,
   glossy beveled tiles (drawn in canvas via art.js port of tGlossy), purple board
   panel with lavender grid, cyan drag guide, light overlay panels, green Retry. */

:root {
  /* page ground sampled from the live client (main.ts dynamic gradient) */
  --ground-top: #4a7bb0;
  --ground-mid: #6f74b6;
  --ground-bot: #a169b8;
  --pill-bg: rgba(74, 52, 120, 0.55);
  --pill-num: #b8f5cd; /* the mint score numerals */
  --text: #ffffff;
  --dim: #e4dcff;
  --accent: #3df0ff;
  --accent-2: #ffd45a;
  --panel-bg-0: rgba(246, 238, 255, 0.97);
  --panel-bg-1: rgba(228, 216, 250, 0.95);
  --panel-ink: #4a3d68;
  --panel-dim: #7d7099;
  --green: #7ede58;
  --green-deep: #4cb830;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  background: linear-gradient(180deg, var(--ground-top) 0%, var(--ground-mid) 52%, var(--ground-bot) 100%);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  touch-action: none;
  overflow: hidden;
  -webkit-user-select: none;
  user-select: none;
}

.hidden { display: none !important; }
.dim { color: var(--dim); font-size: 13.5px; line-height: 1.4; }

#perf-hud {
  position: fixed;
  left: 8px;
  bottom: max(8px, env(safe-area-inset-bottom));
  z-index: 9999;
  max-width: calc(100vw - 16px);
  padding: 4px 7px;
  border-radius: 6px;
  background: rgba(10, 8, 28, 0.82);
  color: #8fffc0;
  font: 10px/1.3 ui-monospace, SFMono-Regular, Menlo, monospace;
  pointer-events: none;
}

html[data-quality="lite"] #praise,
html[data-quality="lite"] .ui-icon {
  filter: none;
}

/* GenAI icons dropped inline in text/chips/buttons */
.ui-icon {
  display: inline-block;
  vertical-align: -0.2em;
  object-fit: contain;
  filter: drop-shadow(0 1px 2px rgba(20, 10, 45, 0.3));
  pointer-events: none;
}

.screen {
  position: fixed;
  inset: 0;
  max-width: 480px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: max(10px, env(safe-area-inset-top)) 12px max(10px, env(safe-area-inset-bottom));
}

/* ============================= MAP ============================= */

.map-header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 5;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: calc(max(6px, env(safe-area-inset-top)) + 2px) 12px 14px;
  /* soft scrim so the title/chips read over any biome */
  background: linear-gradient(180deg, rgba(30, 18, 64, 0.55), rgba(30, 18, 64, 0));
  pointer-events: none;
}
.map-header .chip { pointer-events: auto; }
.map-title { font-weight: 800; font-size: 15px; letter-spacing: 0.02em; white-space: nowrap; text-shadow: 0 1px 4px rgba(40, 20, 80, 0.4); }
.map-chips { display: flex; gap: 5px; flex-wrap: wrap; justify-content: flex-end; }
.chip {
  background: var(--pill-bg);
  border-radius: 12px;
  padding: 3px 10px;
  font-size: 12px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--pill-num);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 2px 8px rgba(40, 20, 80, 0.2);
}
.chip-streak { background: linear-gradient(135deg, #ff8a5c, #ffd166); color: #4a2500; }
.chip-boost { background: linear-gradient(135deg, #6be4ff, #7ede58); color: #0c3b45; }
.chip-lives { display: inline-flex; align-items: center; gap: 4px; }
.chip-lives.low { background: linear-gradient(135deg, #ff6b7d, #d92f4b); color: #fff; }
.chip-lives .chip-sub { font-weight: 700; opacity: 0.8; font-size: 11px; }
.heart-empty { filter: grayscale(1) brightness(0.55); opacity: 0.55; }

/* full-bleed: the WORLD is the screen — no bounding box, no border ring
   (founder round 13: the framed map read as a widget, not a place).
   The scroll fills the whole screen; header and Play button FLOAT over it. */
#screen-map { padding: 0; }
#map-scroll {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  touch-action: pan-y; /* body is touch-action:none — re-enable finger scroll on the map */
  scrollbar-width: none;
}
#map-scroll::-webkit-scrollbar { display: none; }

#map-path {
  position: relative;
  width: 100%;
  /* height set by JS: nodes laid bottom-up */
  /* GenAI journey backdrop: six biomes (meadow → forest → lakelands → highlands →
     tundra → peaks) with a milestone CROSSING baked onto every biome seam
     (build-map.sh) — its pixel height equals the JS map height exactly (1:1 vertical),
     so bridges/gates land precisely between node 5k and 5k+1 */
  background: url("./assets/map-journey.webp") center bottom / 100% 100% no-repeat;
}
.map-road { position: absolute; inset: 0; pointer-events: none; }
.map-node {
  position: absolute;
  z-index: 2; /* nodes (and their skull/chest markers) paint over crossing signs */
  width: 64px;
  height: 64px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-weight: 900;
  font-size: 19px;
  color: #fff;
  background: radial-gradient(circle at 34% 30%, #5a74c4, #3c5093 70%);
  box-shadow: 0 4px 0 rgba(15, 20, 50, 0.55), 0 8px 18px rgba(10, 14, 40, 0.35);
  border: none;
  cursor: pointer;
}
.map-node .stars { font-size: 11px; letter-spacing: 1px; color: var(--accent); line-height: 1; margin-top: 1px; }
.map-node.done { background: radial-gradient(circle at 34% 30%, #8ac926, #57961b 72%); }
.map-node.current {
  background: radial-gradient(circle at 34% 30%, #ffd166, #e09b1a 72%);
  color: #4a2c00;
  animation: node-pulse 1.6s ease-in-out infinite;
}
@keyframes node-pulse {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50% { transform: translate(-50%, -50%) scale(1.09); }
}
.map-node.locked {
  background: radial-gradient(circle at 34% 30%, #46507c, #333c63 72%);
  color: rgba(255, 255, 255, 0.55);
  cursor: default;
}
/* post-win unlock beat: the next node bounces open with a golden shockwave ring */
.map-node.unlock-pop { animation: unlock-pop 1.1s cubic-bezier(0.25, 1.5, 0.4, 1) 0.4s backwards; }
@keyframes unlock-pop {
  0% { transform: translate(-50%, -50%) scale(0); }
  55% { transform: translate(-50%, -50%) scale(1.45); }
  75% { transform: translate(-50%, -50%) scale(0.92); }
  100% { transform: translate(-50%, -50%) scale(1); }
}
.map-node.unlock-pop::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 4px solid rgba(255, 214, 92, 0.95);
  animation: unlock-ring 0.9s ease-out 0.85s both;
  pointer-events: none;
}
@keyframes unlock-ring {
  0% { transform: scale(0.6); opacity: 1; }
  100% { transform: scale(2.5); opacity: 0; }
}
/* chest marker at node scale (CC: special markers read as big as the node itself) */
.map-node .chest-ico { position: absolute; top: -30px; right: -26px; font-size: 30px; filter: drop-shadow(0 3px 5px rgba(0,0,0,0.45)); }
.map-node .chest-ico .ui-icon { filter: none; }
/* devil-head difficulty medallion perched ON the node, CC scale: the skull is the
   headline (~70% of node size), the number stays readable underneath */
.map-node.badged { width: 74px; height: 74px; font-size: 21px; }
.map-node.boss-node { width: 84px; height: 84px; font-size: 23px; }
.map-node .node-devil {
  position: absolute;
  top: -38px;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 1;
}
.map-node.boss-node .node-devil { top: -46px; }
.map-node .node-devil .ui-icon { filter: drop-shadow(0 3px 6px rgba(20, 10, 45, 0.6)); }
.node-badge {
  position: absolute;
  bottom: -17px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.08em;
  padding: 2.5px 10px;
  border-radius: 999px;
  pointer-events: none;
  box-shadow: 0 2px 5px rgba(10, 14, 40, 0.4);
}
.node-badge.hard { background: #b23bd8; }
.node-badge.superhard { background: #e0332e; }
.node-badge.boss { background: linear-gradient(135deg, #e0332e, #ff9d2e); }

/* Opaque cloud bank hiding everything beyond the horizon crossing. Solid fill on top,
   GenAI puffy fringe (map-clouds-down.png, solid color #e9e5fc) hanging off the bottom.
   height animates on milestone reveal (animateReveal). */
.map-clouds {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  background:
    url("./assets/map-clouds-down.webp") left bottom / 270px 95px repeat-x,
    linear-gradient(#e9e5fc, #e9e5fc) left top / 100% calc(100% - 93px) no-repeat;
  pointer-events: none;
  z-index: 3;
  transition: height 1.8s cubic-bezier(0.6, 0, 0.25, 1);
}
/* Crossing signpost: landmark name on the road; the horizon one doubles as the goal */
.cross-sign {
  position: absolute;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  pointer-events: none;
  z-index: 2;
}
.cross-sign .cs-name {
  display: flex;
  align-items: center;
  gap: 4px;
  background: rgba(20, 26, 58, 0.78);
  color: #fff;
  font-weight: 800;
  font-size: 11px;
  white-space: nowrap;
  padding: 3px 10px;
  border-radius: 10px;
  box-shadow: 0 2px 6px rgba(10, 14, 40, 0.35);
}
.cross-sign .cs-sub {
  background: linear-gradient(180deg, #ffd166, #e09b1a);
  color: #4a2c00;
  font-weight: 900;
  font-size: 10px;
  white-space: nowrap;
  padding: 2px 8px;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(10, 14, 40, 0.35);
}
/* season gates: golden banner — the next world announcing itself */
.cross-sign.season .cs-name {
  background: linear-gradient(180deg, #8a5cff, #5a2ec8);
  border: 1.5px solid rgba(255, 214, 102, 0.85);
  font-size: 12px;
  padding: 4px 12px;
}
.cross-sign.goal .cs-name {
  background: rgba(20, 26, 58, 0.9);
  border: 1px solid rgba(255, 209, 102, 0.65);
}
/* THE finish line (CC goal grammar): a big waving checkered flag over the goal
   crossing. (A checkered ribbon strip was tried under the flag but floated over
   the bridge art and read as a stray line — founder round 13 follow-up.) */
.cross-sign .cs-flag {
  position: absolute;
  top: -46px;
  left: 50%;
  transform: translateX(-50%) rotate(8deg);
  filter: drop-shadow(0 3px 6px rgba(10, 14, 40, 0.5));
  animation: flag-wave 1.8s ease-in-out infinite;
}
@keyframes flag-wave {
  0%, 100% { transform: translateX(-50%) rotate(8deg); }
  50% { transform: translateX(-50%) rotate(-4deg); }
}
.cross-sign.goal { animation: goal-bob 2.4s ease-in-out infinite; }
@keyframes goal-bob {
  0%, 100% { transform: translate(-50%, -50%); }
  50% { transform: translate(-50%, calc(-50% - 5px)); }
}
.map-gate {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  z-index: 2;
  font-weight: 900;
  color: var(--dim);
  font-size: 13px;
  background: rgba(20, 26, 58, 0.75);
  border: 1px dashed rgba(170, 180, 222, 0.4);
  padding: 10px 20px;
  border-radius: 14px;
}

.map-footer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  display: flex;
  gap: 10px;
  align-items: center;
  justify-content: center;
  padding: 26px 12px calc(max(12px, env(safe-area-inset-bottom)) + 4px);
  background: linear-gradient(0deg, rgba(30, 18, 64, 0.5), rgba(30, 18, 64, 0));
  pointer-events: none;
}
.map-footer button { pointer-events: auto; }
/* production primary button (.btn): cyan gradient with the hard drop ledge */
.cta-btn {
  background: linear-gradient(180deg, #15d9e8, #0fb1d2);
  border: none;
  color: #fff;
  font-weight: 900;
  font-size: 17px;
  padding: 12px 52px;
  border-radius: 14px;
  box-shadow: 0 6px 0 rgba(16, 99, 145, 0.38), 0 14px 24px rgba(17, 156, 194, 0.24);
  cursor: pointer;
  transition: transform 0.08s ease, filter 0.15s ease;
}
.cta-btn:active { transform: scale(0.95); filter: brightness(1.08); }
.pill-btn {
  background: var(--pill-bg);
  border: none;
  color: var(--text);
  padding: 10px 16px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 2px 8px rgba(40, 20, 80, 0.2);
}
.card .pill-btn { background: rgba(89, 66, 151, 0.14); color: var(--panel-ink); box-shadow: none; }

/* ============================= LEVEL ============================= */

.level-hud {
  width: 100%;
  display: grid;
  grid-template-columns: minmax(40px, 1fr) auto minmax(min-content, 1fr);
  align-items: center;
  column-gap: 6px;
  padding: 2px 2px 6px;
}
.icon-btn {
  justify-self: start;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  border: none;
  background: var(--pill-bg);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 2px 8px rgba(40, 20, 80, 0.2);
  color: #fff;
  font-size: 26px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

/* objective header — production .obj-item language */
.obj-row { display: flex; gap: 12px; justify-content: center; }
.obj-item { display: flex; flex-direction: column; align-items: center; gap: 1px; min-width: 34px; }
.obj-item img, .obj-item .gem-fallback { filter: drop-shadow(0 2px 4px rgba(20, 10, 45, 0.45)); }
.obj-cnt {
  font-size: 19px;
  font-weight: 900;
  color: #fff;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 6px rgba(30, 15, 60, 0.6);
}
.obj-item.pop .obj-cnt { animation: obj-pop 0.32s ease-out; }
.obj-item.is-done .obj-cnt { color: var(--green); }
.obj-item.pop img { animation: obj-pop 0.32s ease-out; }
@keyframes obj-pop {
  0% { transform: scale(1); }
  45% { transform: scale(1.45); }
  100% { transform: scale(1); }
}

.budget-pill {
  justify-self: end;
  display: flex;
  flex-direction: column;
  align-items: center;
  background: var(--pill-bg);
  border-radius: 14px;
  padding: 4px 16px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 2px 8px rgba(40, 20, 80, 0.2);
}
.budget-label { font-size: 9px; letter-spacing: 0.14em; color: var(--dim); font-weight: 700; opacity: 0.8; }
.budget-num { font-size: 22px; font-weight: 900; font-variant-numeric: tabular-nums; line-height: 1.1; color: var(--pill-num); }
.budget-pill.low .budget-num { color: #ff8a8a; animation: budget-blink 0.9s ease-in-out infinite; }
@keyframes budget-blink { 50% { opacity: 0.55; } }

/* ---- row DF (docs/56 §7b P0): the headline score ------------------------------------------
   Block Blast's score is the largest element on screen and it pays out on 100% of placements;
   ours was computed and never rendered, so ~60% of placements read as nothing happening. The
   digits are tabular so a rolling counter does not jitter the layout width. `.pop` is a
   one-shot scale kick re-armed per roll (see bumpScore). */
#score-hud {
  font-size: 42px;
  font-weight: 900;
  line-height: 1;
  color: #ffd76a;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  padding: 0 0 2px;
  text-shadow: 0 2px 10px rgba(40, 20, 80, 0.55), 0 0 18px rgba(255, 190, 70, 0.28);
  transition: color 140ms linear;
}
#score-hud.pop {
  animation: score-pop 260ms cubic-bezier(0.22, 1.4, 0.4, 1);
}
@keyframes score-pop {
  0% { transform: scale(1); }
  36% { transform: scale(1.16); }
  100% { transform: scale(1); }
}
/* combo tiers: the number itself gets hotter as the run gets bigger (docs/56 §4 axis 6's
   visual twin — they tint, we tint) */
#score-hud.t2 { color: #7df9ff; text-shadow: 0 2px 10px rgba(40, 20, 80, 0.55), 0 0 20px rgba(53, 241, 255, 0.45); }
#score-hud.t3 { color: #ff9df5; text-shadow: 0 2px 10px rgba(40, 20, 80, 0.55), 0 0 22px rgba(255, 120, 240, 0.5); }
/* when the score owns the top of the screen the level name steps back to a caption */
#screen-level.has-score #level-name { font-size: 12px; opacity: 0.7; font-weight: 700; }
/* …and the two transient pills that were parked in the now-occupied band move below it. The
   milestone ribbon at 12% landed exactly on the score's digits; both are viewport-relative, so
   they shift by roughly the score row's own height rather than by a guess. */
#screen-level.has-score #milestoneRibbon { top: 19%; }
#screen-level.has-score #comboBanner { top: 24%; }
#screen-level.has-score #banner { top: 30%; }

/* ---- row DF (docs/56 §2): the opening. Their tray slides in 0.4s after the board starts
   settling; ours appeared fully formed in a motionless frame. Per-slot delay is set inline
   by renderTray so the three pieces arrive as a little cascade rather than a block. */
#tray.tray-in .tray-slot {
  animation: tray-in 420ms cubic-bezier(0.18, 0.98, 0.32, 1) both;
}
@keyframes tray-in {
  from { transform: translateY(34px) scale(0.86); opacity: 0; }
  to { transform: translateY(0) scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  #tray.tray-in .tray-slot { animation: none; }
  #score-hud.pop { animation: none; }
}

#level-name {
  font-size: 15px;
  color: #fff;
  font-weight: 800;
  letter-spacing: 0.01em;
  padding-bottom: 4px;
  text-shadow: 0 1px 6px rgba(40, 20, 80, 0.45);
}

/* board panel + grid are drawn IN canvas with the production skin (art.js) */
#board {
  width: min(94vw, 430px);
  aspect-ratio: 1;
  background: transparent;
}

#tools { display: flex; gap: 10px; min-height: 40px; align-items: center; padding-top: 6px; }
.tool-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--pill-bg);
  border: 2px solid transparent;
  color: var(--text);
  padding: 5px 13px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 800;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.tool-btn .ui-icon { display: block; }
.tool-btn.armed { border-color: var(--accent); background: rgba(61, 240, 255, 0.18); }
.tool-btn:disabled { opacity: 0.3; }
/* tool-free levels: the banked inventory stays VISIBLE but reads as locked (small lock
   badge, desaturated) — hiding it made players think their tools were deleted */
.tool-btn.locked { position: relative; opacity: 0.55; filter: saturate(0.35); cursor: default; }
.tool-btn.locked .tool-lock {
  position: absolute;
  top: -5px;
  right: -3px;
  opacity: 1;
  filter: none;
  line-height: 0;
}
/* guided first use after the unlock ceremony: the armed tool pulses "tap the board!" */
.tool-btn.pulse { animation: tool-pulse 0.9s ease-in-out infinite; }

/* tool grant toast (grantToast in game.js): one centered card — big tool art with a
   golden halo, "You got Storm Hammer!" beneath. Non-blocking, self-dismissing. */
.grant-toast {
  position: fixed;
  left: 50%;
  top: 34%;
  z-index: 70;
  transform: translate(-50%, -50%) scale(0.4);
  opacity: 0;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 18px 26px 14px;
  border-radius: 22px;
  background:
    radial-gradient(ellipse at 50% 0%, rgba(255, 214, 102, 0.22), rgba(255, 214, 102, 0) 65%),
    linear-gradient(180deg, rgba(88, 62, 158, 0.97), rgba(58, 38, 116, 0.97));
  border: 1.5px solid rgba(255, 214, 102, 0.75);
  box-shadow:
    0 0 34px rgba(255, 194, 80, 0.4),
    0 12px 34px rgba(15, 8, 40, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.22);
  transition: transform 0.34s cubic-bezier(0.25, 1.65, 0.4, 1), opacity 0.22s ease-out;
}
.grant-toast.in { transform: translate(-50%, -50%) scale(1); opacity: 1; }
.grant-toast.out { transform: translate(-50%, -62%) scale(0.92); opacity: 0; transition: transform 0.3s ease-in, opacity 0.3s ease-in; }
.gt-icons { display: flex; gap: 14px; }
.gt-item { position: relative; display: inline-block; }
.gt-item img { filter: drop-shadow(0 0 16px rgba(255, 214, 102, 0.85)) drop-shadow(0 3px 8px rgba(20, 10, 45, 0.5)); }
.gt-count {
  position: absolute;
  right: -8px;
  bottom: -2px;
  background: linear-gradient(180deg, #ffd666, #f0a020);
  color: #4a2c08;
  font-size: 14px;
  font-weight: 900;
  padding: 1px 7px;
  border-radius: 10px;
  box-shadow: 0 2px 6px rgba(15, 8, 40, 0.5);
}
.gt-text {
  font-size: 15px;
  font-weight: 700;
  color: #e8dcff;
  text-shadow: 0 1px 4px rgba(20, 10, 45, 0.6);
}
.gt-text b {
  font-weight: 900;
  background: linear-gradient(180deg, #ffe9a8, #ffb340);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
@keyframes tool-pulse {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(61, 240, 255, 0.5); }
  50% { transform: scale(1.1); box-shadow: 0 0 0 9px rgba(61, 240, 255, 0); }
}

/* ---- tool unlock ceremony (new tool = a reveal moment, not a tray footnote) ---- */
.tu-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
  animation: tu-in 0.5s cubic-bezier(0.25, 1.5, 0.4, 1) backwards;
}
@keyframes tu-in {
  from { opacity: 0; transform: scale(0.6); }
  to { opacity: 1; transform: scale(1); }
}
.tu-stage { position: relative; width: 240px; height: 240px; display: grid; place-items: center; }
/* procedural golden sunburst (GenAI versions kept bleeding the chroma key into the
   inter-ray glow) — conic ray ticks under a warm radial core, faded out radially */
.tu-rays {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle, rgba(255, 246, 210, 0.95) 0%, rgba(255, 214, 92, 0.55) 26%, rgba(255, 214, 92, 0) 66%),
    repeating-conic-gradient(from 0deg, rgba(255, 199, 60, 0.85) 0deg 5deg, rgba(255, 199, 60, 0) 5deg 12deg);
  -webkit-mask-image: radial-gradient(circle, #000 0%, #000 52%, transparent 71%);
  mask-image: radial-gradient(circle, #000 0%, #000 52%, transparent 71%);
  animation: tu-spin 9s linear infinite;
}
@keyframes tu-spin { to { transform: rotate(360deg); } }
.tu-icon {
  position: relative;
  width: 128px;
  height: 128px;
  filter: drop-shadow(0 10px 22px rgba(20, 8, 45, 0.6));
  animation: tu-icon-pop 0.65s cubic-bezier(0.25, 1.7, 0.4, 1) 0.15s backwards;
}
@keyframes tu-icon-pop {
  from { transform: scale(0) rotate(-18deg); }
  to { transform: scale(1) rotate(0); }
}
.tu-kicker { font-size: 12px; font-weight: 900; letter-spacing: 0.22em; color: var(--accent); }
.tu-name {
  font-size: 34px;
  font-weight: 1000;
  background: linear-gradient(180deg, #fff3c4, #ffb52e);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 3px 6px rgba(20, 8, 45, 0.55));
}
.tu-how { max-width: 260px; font-size: 14px; color: rgba(255, 255, 255, 0.9); margin-bottom: 10px; }
@media (prefers-reduced-motion: reduce) {
  .tu-rays, .tool-btn.pulse { animation: none; }
}

/* ---- chest ceremony (level-10 style gift: wiggle → burst open → rewards fly out) ---- */
/* darker backdrop than regular overlays: the reveal owns the whole screen */
#chest-ceremony, #tool-unlock { background: rgba(24, 12, 50, 0.82); }
.cc-chest {
  position: relative;
  width: 160px;
  height: 160px;
  object-fit: contain;
  filter: drop-shadow(0 10px 22px rgba(20, 8, 45, 0.6));
}
.cc-chest.wiggle { animation: cc-wiggle 0.9s ease-in-out; }
@keyframes cc-wiggle {
  0%, 100% { transform: rotate(0); }
  15% { transform: rotate(-7deg) scale(1.02); }
  30% { transform: rotate(6deg) scale(1.03); }
  45% { transform: rotate(-5deg) scale(1.05); }
  60% { transform: rotate(4deg) scale(1.06); }
  75% { transform: rotate(-2deg) scale(1.08); }
}
.cc-chest.open { animation: cc-open-pop 0.55s cubic-bezier(0.25, 1.7, 0.4, 1); }
@keyframes cc-open-pop {
  0% { transform: scale(0.8); }
  55% { transform: scale(1.18); }
  100% { transform: scale(1); }
}
#chest-ceremony .tu-rays { opacity: 0; transition: opacity 0.4s ease; }
#chest-ceremony .tu-rays.lit { opacity: 1; }
.cc-rewards { display: flex; flex-direction: column; gap: 8px; min-height: 118px; align-items: center; padding-top: 4px; }
.cc-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 214, 92, 0.45);
  border-radius: 999px;
  padding: 6px 18px;
  font-size: 15px;
  font-weight: 800;
  color: #fff;
  animation: cc-chip-pop 0.5s cubic-bezier(0.25, 1.7, 0.4, 1) backwards;
}
@keyframes cc-chip-pop {
  from { opacity: 0; transform: translateY(26px) scale(0.5); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .cc-chest.wiggle, .cc-chest.open, .cc-chip { animation: none; }
}

/* production tray: pieces float directly on the ground, no slot wells */
#tray {
  width: min(94vw, 430px);
  height: 104px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  padding-top: 8px;
}
.tray-slot {
  border-radius: 12px;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.tray-slot canvas { pointer-events: none; }
.tray-slot.dragging { opacity: 0; } /* piece is picked UP — it rides the finger, not the tray */
.tray-slot.spent { opacity: 0; }
/* Lucky Swap: old hand whirls away, fresh hand pops in */
.tray-slot.swap-out { animation: swap-out 0.24s ease-in forwards; }
@keyframes swap-out {
  to { transform: rotate(50deg) scale(0.2); opacity: 0; }
}
.tray-slot.swap-in { animation: swap-in 0.32s cubic-bezier(0.25, 1.6, 0.4, 1) backwards; }
@keyframes swap-in {
  from { transform: rotate(-40deg) scale(0.2); opacity: 0; }
  to { transform: rotate(0) scale(1); opacity: 1; }
}

#drag-layer {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 20; /* above board + tray, below overlays (30) */
}

/* grants toast: pinned ABOVE the board (it used to sit under the tray, where long
   labels collided with the pieces) — compact pill, fades out once read */
#streak-note {
  margin: 0 0 4px;
  padding: 3px 14px;
  border-radius: 999px;
  background: rgba(40, 20, 80, 0.55);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
  font-size: 12px;
  font-weight: 800;
  color: var(--accent-2);
  max-width: 92vw;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: opacity 0.6s ease;
}
#streak-note.fade { opacity: 0; }

#banner {
  position: fixed;
  top: 24%;
  left: 50%;
  transform: translateX(-50%);
  font-size: 22px;
  font-weight: 900;
  padding: 6px 20px;
  border-radius: 999px;
  background: linear-gradient(135deg, #ff8fab, #ffd166);
  color: #2b1a00;
  z-index: 15;
  transition: transform 120ms ease-out, opacity 200ms;
  pointer-events: none;
}
#banner.pop { transform: translateX(-50%) scale(1.16); }

/* "COMBO N" pill (docs/53 §2): gold, overshoots in near the board top, early split exit */
#comboBanner {
  position: fixed;
  top: 17%;
  left: 50%;
  transform: translateX(-50%) scale(0);
  font-size: 19px;
  font-weight: 1000;
  font-style: italic;
  letter-spacing: 0.06em;
  padding: 5px 18px;
  border-radius: 999px;
  background: linear-gradient(160deg, #fff3c4, #ffcf3e 55%, #f59e0b);
  color: #4a2800;
  box-shadow: 0 4px 16px rgba(255, 190, 40, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.8);
  z-index: 15;
  opacity: 0;
  pointer-events: none;
}
#comboBanner.show { animation: combo-pop 1.3s cubic-bezier(0.24, 1.5, 0.4, 1) forwards; }
@keyframes combo-pop {
  0% { opacity: 0; transform: translateX(-50%) scale(0.4) rotate(-3deg); }
  16% { opacity: 1; transform: translateX(-50%) scale(1.12) rotate(1deg); }
  28% { transform: translateX(-50%) scale(1); }
  78% { opacity: 1; transform: translateX(-50%) scale(1); }
  100% { opacity: 0; transform: translateX(-50%) scale(1.35); }
}

/* goal splash (founder: "UI is not clear what the goal is") — BB pattern: goal chips
   pop in center-board, hold, then FLY into the HUD objective row */
#goalSplash {
  position: fixed;
  top: 30%;
  left: 50%;
  transform: translate(-50%, 0) scale(0.6);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 14px 26px 16px;
  border-radius: 20px;
  background: linear-gradient(165deg, rgba(255, 255, 255, 0.97), rgba(233, 226, 255, 0.97));
  box-shadow: 0 14px 40px rgba(24, 12, 60, 0.45);
  z-index: 15;
  opacity: 0;
  pointer-events: none;
}
#goalSplash .gs-eyebrow {
  font-size: 12px;
  font-weight: 1000;
  letter-spacing: 0.32em;
  color: #8a72c9;
}
#goalSplash .gs-chips {
  display: flex;
  gap: 14px;
  align-items: center;
}
#goalSplash .gs-chips .obj-item {
  display: flex;
  align-items: center;
  gap: 6px;
}
#goalSplash .gs-chips .obj-cnt {
  font-size: 30px;
  font-weight: 1000;
  color: #43346b;
}
#goalSplash .gs-words {
  font-size: 14.5px;
  font-weight: 800;
  color: #6a5d8a;
  max-width: 74vw;
  text-align: center;
}
#goalSplash.show {
  animation: gs-pop 0.34s cubic-bezier(0.24, 1.45, 0.42, 1) forwards;
}
@keyframes gs-pop {
  from { opacity: 0; transform: translate(-50%, 14px) scale(0.6); }
  to { opacity: 1; transform: translate(-50%, 0) scale(1); }
}
#goalSplash.show.fly {
  animation: none;
  opacity: 0;
  transform: translate(calc(-50% + var(--fly-x, 0px)), var(--fly-y, -30vh)) scale(0.18);
  transition: transform 0.46s cubic-bezier(0.5, 0, 0.7, 0.4), opacity 0.46s ease-in;
}

/* milestone ribbon (docs/53 §4): sweeps in from the right, parks, exits left */
#milestoneRibbon {
  position: fixed;
  top: 12%;
  left: 0;
  right: 0;
  margin: 0 auto;
  width: fit-content;
  font-size: 21px;
  font-weight: 1000;
  font-style: italic;
  padding: 7px 26px;
  border-radius: 14px;
  background: linear-gradient(120deg, #ff9c3f, #ff5e7e);
  color: #fff;
  -webkit-text-stroke: 0;
  text-shadow: 0 2px 0 rgba(120, 30, 0, 0.35);
  box-shadow: 0 6px 20px rgba(255, 199, 89, 0.4);
  z-index: 15;
  opacity: 0;
  transform: translateX(120vw);
  pointer-events: none;
}
#milestoneRibbon.show { animation: ribbon-sweep 2.4s cubic-bezier(0.3, 0.9, 0.3, 1) forwards; }
@keyframes ribbon-sweep {
  0% { opacity: 0; transform: translateX(120vw) rotate(2deg); }
  14% { opacity: 1; transform: translateX(2vw) rotate(-1deg); }
  20% { transform: translateX(0) rotate(0); }
  80% { opacity: 1; transform: translateX(-1vw); }
  100% { opacity: 0; transform: translateX(-130vw) rotate(-2deg); }
}

/* CC-style praise callout: GenAI word art slams in over the board, floats up, gone. */
#praise {
  position: fixed;
  top: 32%;
  left: 50%;
  z-index: 16;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  filter: drop-shadow(0 10px 22px rgba(20, 8, 45, 0.55));
  transform: translateX(-50%);
}
#praise img { display: block; width: min(62vw, 300px); }
#praise.t2 img { width: min(70vw, 340px); }
#praise.t3 img { width: min(78vw, 380px); }
#praise.fire img { width: min(58vw, 280px); }
#praise .mult {
  font-weight: 1000;
  font-style: italic;
  font-size: 24px;
  color: #ffd34f;
  -webkit-text-stroke: 4px rgba(70, 20, 8, 0.92);
  paint-order: stroke fill;
}
#praise.show { animation: praise-slam 0.95s cubic-bezier(0.22, 1.4, 0.36, 1) forwards; }
/* win-ceremony banner: bigger art, slower slam (rides the board detonation wave) */
#praise.clear img { width: min(88vw, 430px); }
#praise.clear.show { animation: praise-slam 1.7s cubic-bezier(0.22, 1.4, 0.36, 1) forwards; }
@keyframes praise-slam {
  0% { opacity: 0; transform: translateX(-50%) scale(2.1) rotate(-4deg); }
  14% { opacity: 1; transform: translateX(-50%) scale(1) rotate(-2deg); }
  24% { transform: translateX(-50%) scale(1.08) rotate(-2deg); }
  72% { opacity: 1; transform: translateX(-50%) translateY(-6px) scale(1) rotate(-2deg); }
  100% { opacity: 0; transform: translateX(-50%) translateY(-34px) scale(0.92) rotate(-2deg); }
}
@media (prefers-reduced-motion: reduce) {
  #praise.show { animation: none; opacity: 1; }
}

/* ============================= OVERLAYS ============================= */

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(45, 28, 82, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 30;
  padding: 20px;
}
/* production panel language (.panel in src/style.css): light lavender, dark ink */
.card {
  background: linear-gradient(180deg, var(--panel-bg-0), var(--panel-bg-1));
  border: 1px solid rgba(255, 255, 255, 0.62);
  border-radius: 18px;
  padding: 26px 28px 24px;
  text-align: center;
  max-width: 350px;
  width: 100%;
  color: var(--panel-ink);
  box-shadow: 0 28px 70px rgba(55, 42, 102, 0.38), 0 5px 0 rgba(89, 66, 151, 0.18);
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
}
.card h2 { font-size: 24px; color: var(--panel-ink); }
.card .dim { color: var(--panel-dim); }
.card-kicker { font-size: 12px; font-weight: 800; letter-spacing: 0.18em; color: var(--panel-dim); }
.card-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 0.1em;
  padding: 3px 12px 3px 6px;
  border-radius: 999px;
  color: #fff;
}
.card-badge.hard { background: #b23bd8; }
.card-badge.superhard { background: #e0332e; }
.card-badge.boss { background: linear-gradient(135deg, #e0332e, #ff9d2e); }
.gc-goal { display: flex; gap: 14px; justify-content: center; padding: 4px 0; }
.card .obj-cnt { color: var(--panel-ink); text-shadow: none; }
/* one plain sentence under the chips — icons alone don't explain line-play goals */
.gc-goal-text { font-size: 13.5px; font-weight: 800; color: var(--panel-ink); opacity: 0.85; }

.teach {
  background: rgba(89, 66, 151, 0.1);
  border: 1px solid rgba(89, 66, 151, 0.16);
  border-radius: 14px;
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: center;
}
.teach-title { font-weight: 900; color: #8a4fd0; font-size: 15px; }
.teach-body { font-size: 13.5px; line-height: 1.45; color: var(--panel-ink); }
#gc-teach-canvas { border-radius: 10px; }

.gc-grants { font-size: 13px; font-weight: 800; color: #c07c14; }

.wc-stars { min-height: 62px; display: flex; align-items: flex-end; justify-content: center; gap: 4px; }
.wc-star { width: 44px; height: 44px; filter: grayscale(1) opacity(0.22); transition: filter 0.15s; }
.wc-star.mid { width: 56px; height: 56px; margin-bottom: 4px; } /* candy-crush raised middle star */
.wc-star.on { filter: drop-shadow(0 3px 6px rgba(180, 110, 10, 0.45)); animation: star-pop 0.32s ease-out; }
@keyframes star-pop {
  0% { transform: scale(0.2); }
  55% { transform: scale(1.3); }
  100% { transform: scale(1); }
}
.wc-line { color: var(--panel-dim); font-size: 14px; }
.wc-chest, .wc-race {
  background: rgba(255, 181, 46, 0.14);
  border: 1px solid rgba(255, 181, 46, 0.45);
  border-radius: 14px;
  padding: 10px 16px;
  font-size: 14px;
  font-weight: 800;
  color: #9a6206;
}
.wc-chest {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.wc-chest span {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 6px;
}
.wc-next-goal {
  width: 100%;
  box-sizing: border-box;
  background: rgba(89, 66, 151, 0.09);
  border: 1px solid rgba(89, 66, 151, 0.18);
  border-radius: 14px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}
.wc-next-kicker {
  color: var(--panel-dim);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.16em;
}
.wc-next-name {
  color: var(--panel-ink);
  font-size: 17px;
  font-weight: 900;
}
.wc-next-objectives {
  min-height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}
.wc-next-tools {
  color: #8a5d12;
  font-size: 12px;
  font-weight: 750;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
.wc-next-hint {
  color: var(--panel-dim);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.3;
}

/* So Close — production full-screen language. SHOW DON'T TELL: word art title,
   sprite tally, gift art + tool sprites in the rescue card. Entrance is gentle
   (fade + soft rise) so it rides the sympathetic fail sfx, then the word art
   pops with the same overshoot curve as the praise slams / grant toast. */
#so-close { background: linear-gradient(180deg, #354984, #26335f 80%); flex-direction: column; }
#so-close:not(.hidden) { animation: sc-enter 0.4s ease-out both; }
@keyframes sc-enter {
  0% { opacity: 0; }
  100% { opacity: 1; }
}
.sc-inner { display: flex; flex-direction: column; align-items: center; gap: 10px; width: 100%; max-width: 340px; }
.sc-title { font-size: clamp(30px, 9vw, 42px); font-weight: 900; } /* still used by the no-lives gate */
#so-close:not(.hidden) .sc-inner { animation: sc-rise 0.45s cubic-bezier(0.22, 1.2, 0.36, 1) both; }
@keyframes sc-rise {
  0% { transform: translateY(18px) scale(0.97); }
  100% { transform: translateY(0) scale(1); }
}
.sc-art { width: min(76vw, 300px); filter: drop-shadow(0 10px 22px rgba(15, 8, 40, 0.45)); }
#so-close:not(.hidden) .sc-art { animation: sc-art-pop 0.55s cubic-bezier(0.25, 1.65, 0.4, 1) 0.08s both; }
@keyframes sc-art-pop {
  0% { opacity: 0; transform: scale(0.4) rotate(-3deg); }
  100% { opacity: 1; transform: scale(1) rotate(0deg); }
}
.sc-tally { display: flex; gap: 18px; padding: 2px 0 8px; }
.sc-tally .obj-item { min-width: 40px; }
.sc-streak { color: #ff9d9d; font-weight: 800; font-size: 13.5px; }
.sc-lives { display: flex; justify-content: center; gap: 3px; margin: 4px 0 2px; }
/* helping-hand gift card: golden-halo language of the grant toast — the opened
   gift art floats gently, the real tool sprites below it SHOW the contents */
.sc-rescue {
  margin: 2px 0;
  padding: 8px 22px 14px;
  border-radius: 18px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  background:
    radial-gradient(ellipse at 50% 12%, rgba(255, 214, 102, 0.2), rgba(255, 214, 102, 0) 62%),
    linear-gradient(180deg, rgba(88, 62, 158, 0.5), rgba(58, 38, 116, 0.55));
  border: 1.5px solid rgba(255, 214, 102, 0.6);
  box-shadow: 0 0 26px rgba(255, 194, 80, 0.22), 0 10px 26px rgba(15, 8, 40, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.16);
  transition: transform 0.35s cubic-bezier(0.5, 0, 0.75, 0.4), opacity 0.3s ease-in, margin 0.35s ease-in;
}
.sc-rescue.collapse { transform: scale(0.72); opacity: 0; pointer-events: none; }
.sc-gift {
  width: 108px;
  margin: -26px 0 -4px; /* art breaks the card's top edge, CC-offer style */
  filter: drop-shadow(0 0 18px rgba(255, 210, 90, 0.5)) drop-shadow(0 6px 12px rgba(15, 8, 40, 0.4));
  animation: sc-gift-float 2.8s ease-in-out infinite;
}
@keyframes sc-gift-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-7px); }
}
.sc-rescue-items { display: flex; gap: 14px; padding: 0 4px; }
.sc-gift-item { position: relative; display: inline-block; }
.sc-gift-item img { filter: drop-shadow(0 0 10px rgba(255, 214, 102, 0.55)) drop-shadow(0 2px 6px rgba(20, 10, 45, 0.5)); }
.sc-gift-count {
  position: absolute;
  right: -9px;
  bottom: -3px;
  background: linear-gradient(180deg, #ffd666, #f0a020);
  color: #4a2c08;
  font-size: 11.5px;
  font-weight: 900;
  font-style: normal;
  padding: 1px 6px;
  border-radius: 9px;
  box-shadow: 0 2px 5px rgba(15, 8, 40, 0.5);
}
.sc-rescue .cta-btn { padding: 10px 30px; font-size: 15px; border-radius: 14px; }
@media (prefers-reduced-motion: reduce) {
  #so-close:not(.hidden), #so-close:not(.hidden) .sc-inner, #so-close:not(.hidden) .sc-art { animation: none; }
  .sc-gift { animation: none; }
}
.nl-hearts { display: flex; justify-content: center; gap: 4px; margin: 10px 0; }
.nl-timer { font-size: 14.5px; color: var(--ink-soft); font-weight: 700; margin-bottom: 12px; }
.nl-timer b { color: var(--ink); font-variant-numeric: tabular-nums; }
.sc-retry {
  background: linear-gradient(180deg, var(--green), var(--green-deep));
  border: none;
  color: #fff;
  font-size: 17px;
  font-weight: 900;
  border-radius: 16px;
  padding: 13px 62px;
  box-shadow: 0 5px 0 #37881f, 0 10px 22px rgba(15, 8, 40, 0.45);
  cursor: pointer;
}
.sc-map { background: none; border: none; color: var(--dim); font-size: 14px; font-weight: 700; cursor: pointer; padding: 8px; }

/* ---- Episode Race: Champions-Race staging (podium → track → reward → CTA) ---- */
#race-panel { padding: 0; }
.race-surface {
  position: relative;
  width: 100%;
  max-width: 480px;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: max(14px, env(safe-area-inset-top)) 18px max(14px, env(safe-area-inset-bottom));
  background:
    radial-gradient(80% 30% at 50% 0%, rgba(255, 143, 171, 0.35), transparent),
    linear-gradient(180deg, #6c4bb8 0%, #4a3a94 45%, #35619e 100%);
}
.race-x {
  position: absolute;
  top: max(10px, env(safe-area-inset-top));
  right: 12px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  font-size: 20px;
  font-weight: 900;
  cursor: pointer;
}
.race-banner {
  font-size: 26px;
  font-weight: 900;
  letter-spacing: 0.02em;
  background: linear-gradient(180deg, #ffe9a8, #ffb52e);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 0 rgba(90, 40, 10, 0.45));
}
.race-sub { font-size: 13.5px; font-weight: 800; color: #ffe9f2; }
.race-podium { display: flex; align-items: flex-end; gap: 18px; padding: 2px 0; }
.podium-slot { position: relative; display: flex; flex-direction: column; align-items: center; }
.podium-slot img { width: 52px; height: 52px; object-fit: contain; filter: drop-shadow(0 3px 6px rgba(20, 10, 45, 0.5)); }
.podium-slot.p1 img { width: 72px; height: 72px; }
.podium-medal {
  margin-top: -8px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 900;
  color: #4a2c00;
  box-shadow: 0 2px 4px rgba(20, 10, 45, 0.4);
}
.m1 { background: linear-gradient(180deg, #ffe9a8, #ffb52e); }
.m2 { background: linear-gradient(180deg, #e8ecf5, #a9b4c9); }
.m3 { background: linear-gradient(180deg, #e8b98a, #b9764a); }
.race-track {
  position: relative;
  flex: 1;
  width: min(72%, 300px);
  border-radius: 26px 26px 14px 14px;
  /* the road: tan body + darker edges + dashed centerline, matching the map road grammar */
  background:
    linear-gradient(90deg, rgba(90, 62, 40, 0.55) 0 7%, transparent 7% 93%, rgba(90, 62, 40, 0.55) 93%),
    repeating-linear-gradient(180deg, rgba(120, 86, 52, 0.6) 0 10px, transparent 10px 26px) 50% 0 / 4px 100% no-repeat,
    linear-gradient(180deg, #eed3a0, #dfb87e);
  box-shadow: inset 0 0 0 3px rgba(90, 62, 40, 0.35), 0 10px 30px rgba(20, 10, 45, 0.35);
}
.race-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  text-align: center;
  color: #7a5a34;
  font-size: 13.5px;
  font-weight: 800;
  line-height: 1.6;
  padding: 12px;
}
.racer {
  position: absolute;
  transform: translate(-50%, 50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  transition: bottom 0.6s cubic-bezier(0.3, 1.4, 0.5, 1), left 0.4s ease;
  z-index: 1;
}
.racer-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 16px;
  font-weight: 900;
  color: #fff;
  background: radial-gradient(circle at 34% 28%, hsl(var(--h), 72%, 62%), hsl(var(--h), 72%, 42%) 75%);
  border: 2px solid rgba(255, 255, 255, 0.75);
  box-shadow: 0 3px 8px rgba(20, 10, 45, 0.45);
}
.racer-name { font-size: 10px; font-weight: 900; color: #5a3e28; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.35); }
.racer-count {
  position: absolute;
  top: -6px;
  right: -10px;
  min-width: 17px;
  height: 17px;
  border-radius: 999px;
  background: #fff;
  color: #4a3d68;
  font-size: 10.5px;
  font-weight: 900;
  display: grid;
  place-items: center;
  padding: 0 3px;
  box-shadow: 0 1px 3px rgba(20, 10, 45, 0.35);
}
.racer.you { z-index: 2; }
.racer.you .racer-avatar { width: 42px; height: 42px; border-color: #ffe9a8; box-shadow: 0 0 0 3px rgba(255, 213, 90, 0.55), 0 4px 10px rgba(20, 10, 45, 0.5); }
.racer.you .racer-name { color: #2f6b1c; font-size: 11px; }
.race-reward {
  display: flex;
  align-items: center;
  gap: 6px;
  background: rgba(20, 26, 58, 0.5);
  border-radius: 999px;
  padding: 8px 18px;
  font-size: 13.5px;
  font-weight: 800;
  color: #ffe9a8;
}

/* inventory rows */
#inv-rows { width: 100%; display: flex; flex-direction: column; gap: 6px; padding: 6px 0; }
.race-row {
  display: flex;
  justify-content: space-between;
  background: rgba(89, 66, 151, 0.1);
  border-radius: 10px;
  padding: 8px 14px;
  font-size: 14px;
  font-weight: 700;
  color: var(--panel-ink);
}
.race-row.you { background: rgba(76, 184, 48, 0.16); border: 1px solid rgba(76, 184, 48, 0.5); }
.race-row .pos { color: var(--panel-dim); margin-right: 8px; }

/* band wipe — production keyframes */
#band-wipe {
  position: fixed;
  left: 0;
  right: 0;
  top: 32%;
  height: 34%;
  z-index: 50;
  display: grid;
  place-items: center;
  visibility: hidden;
  /* production band (src/style.css .band-wipe) */
  background: linear-gradient(180deg, rgba(88, 108, 205, 0.97), rgba(58, 72, 160, 0.97));
  box-shadow: 0 0 40px rgba(20, 14, 55, 0.5);
  color: #fff;
}
#band-wipe.run { visibility: visible; animation: band-sweep 0.95s cubic-bezier(0.6, 0, 0.3, 1) forwards; }
@keyframes band-sweep {
  0% { transform: translateX(-102%); }
  38% { transform: translateX(0); }
  62% { transform: translateX(0); }
  100% { transform: translateX(102%); }
}
.bw-inner { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.bw-level { font-size: 15px; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; }
.bw-goal { font-size: 24px; font-weight: 900; display: flex; gap: 10px; align-items: center; }

@media (prefers-reduced-motion: reduce) {
  #band-wipe.run { animation: none; visibility: hidden; }
  .map-node.current { animation: none; }
  .cross-sign.goal, .cross-sign .cs-flag { animation: none; }
  .map-clouds { transition: none; }
}

/* Goal card up = one Play on screen (walkthrough finding: the card's CTA rendered in a
   column directly above the map footer's dimmed Play — two identical buttons stacked) */
body:has(#goal-card:not(.hidden)) .map-footer {
  opacity: 0;
  pointer-events: none;
}
