/* ==========================================================================
 * Wish Pop: Bubble Shop — STYLES
 * Portrait, mobile-first, large & touch-friendly, low clutter.
 * ======================================================================== */
/* Bundled fantasy display font (offline) for buttons, headings, labels */
@font-face { font-family: 'Wishpop'; src: url('../fonts/medievalsharp.woff2') format('woff2'); font-weight: 400 700; font-display: swap; }
:root {
  color-scheme: dark;
  --ff-display: 'Wishpop', 'Georgia', 'Times New Roman', serif;   /* decorative — names & titles only */
  --ff-read: 'Georgia', 'Times New Roman', serif;                 /* readable — descriptions & longer text */
  --ff-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;  /* clean — numbers */
  --bg1: #3a2166; --bg2: #2a1a4a; --bg3: #160c2c;
  --ink: #fff0fb; --ink-dim: rgba(255,240,251,0.72);
  --card: rgba(255,255,255,0.10); --card2: rgba(255,255,255,0.06);
  --line: rgba(255,255,255,0.14);
  --pink: #ff7eb9; --purple: #c48bff; --good: #7ee08a; --gold: #ffd86b; --bad: #ff6b6b;
  --safe-t: env(safe-area-inset-top); --safe-b: env(safe-area-inset-bottom);
}
/* touch-action: manipulation on EVERY element disables double-tap-to-zoom
   (iPad/touch desktop) while still allowing normal taps, fast repeat taps, and
   scrolling. iOS Safari ignores user-scalable=no but honors this. */
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
html, body {
  width: 100%; height: 100%;
  overflow: hidden; overscroll-behavior: none; touch-action: manipulation;
  -webkit-user-select: none; user-select: none;
  background: var(--bg3);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
}
#app {
  position: fixed; inset: 0; margin: 0 auto; max-width: 520px;
  background: radial-gradient(circle at 50% 15%, var(--bg1) 0%, var(--bg2) 55%, var(--bg3) 100%);
  display: flex; flex-direction: column;
  padding: var(--safe-t) 14px var(--safe-b);
}

/* Screens */
.screen { display: none; flex: 1; min-height: 0; flex-direction: column; padding: 8px 0 12px; }
.screen.active { display: flex; animation: fade .25s ease; }
.boss-banner { margin: 4px 10px 0; padding: 8px 12px; text-align: center; font-weight: 800; font-size: 13px; border-radius: 12px;
  color: #2a1a4a; background: linear-gradient(90deg, #ffd76a, #ff9de0, #b98cff, #ffd76a); background-size: 300% 100%;
  animation: bossshine 3s linear infinite; box-shadow: 0 0 16px rgba(255,180,120,.5); }
@keyframes bossshine { 0% { background-position: 0% 0; } 100% { background-position: 300% 0; } }
.boss-emoji { animation: bossbob 1.4s ease-in-out infinite; filter: drop-shadow(0 0 14px rgba(255,200,120,.9)); }
@keyframes bossbob { 0%,100% { transform: translateY(0) scale(1); } 50% { transform: translateY(-6px) scale(1.06); } }
/* VIP guest — a star-gold banner distinct from the boss's pink shimmer */
.vip-banner { color: #3a2a08; background: linear-gradient(90deg, #ffe98a, #ffd24d, #fff0b0, #ffd24d); background-size: 300% 100%;
  box-shadow: 0 0 18px rgba(255,205,90,.6); }
.vip-emoji { animation: vipglow 1.6s ease-in-out infinite; filter: drop-shadow(0 0 16px rgba(255,215,100,.95)); }
@keyframes vipglow { 0%,100% { transform: scale(1); filter: drop-shadow(0 0 10px rgba(255,215,100,.7)); }
  50% { transform: scale(1.07); filter: drop-shadow(0 0 20px rgba(255,235,150,1)); } }
.screen.shake { animation: scrshake .58s cubic-bezier(.36,.07,.19,.97); }
@keyframes scrshake {
  10%,90% { transform: translateX(-2px); } 20%,80% { transform: translateX(4px); }
  30%,50%,70% { transform: translateX(-9px); } 40%,60% { transform: translateX(9px); }
}
@keyframes fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* Top HUD bar */
.hud {
  display: flex; align-items: center; justify-content: space-between;
  background: rgba(0,0,0,0.22); border-radius: 14px; padding: 8px 14px; margin-bottom: 8px;
  font-size: 15px; font-weight: 700;
}
.hud .gold { color: var(--gold); }
.hud .title { font-size: 14px; color: var(--ink-dim); font-weight: 600; }

/* Buttons */
.btn {
  border: none; border-radius: 16px; padding: 15px 22px; font-size: 18px; font-weight: 800;
  color: #fff; background: linear-gradient(90deg, var(--pink), var(--purple));
  box-shadow: 0 6px 18px rgba(0,0,0,0.28); cursor: pointer; width: 100%;
  transition: transform .08s ease, filter .1s ease;
}
.btn:active { transform: scale(0.97); filter: brightness(1.05); }
.btn.secondary { background: var(--card); color: var(--ink); box-shadow: none; }
.btn.good { background: linear-gradient(90deg, #7ee08a, #4fd1c5); color: #0d2a1a; }
.btn.small { padding: 10px 14px; font-size: 15px; width: auto; }
.btn[disabled] { opacity: .45; pointer-events: none; }
.row { display: flex; gap: 10px; }

/* Generic card */
.card { background: var(--card); border: 1px solid var(--line); border-radius: 18px; padding: 16px; }
.center { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 12px; }
.grow { flex: 1; min-height: 0; }
.spacer { flex: 1; }
.muted { color: var(--ink-dim); font-size: 14px; line-height: 1.5; }
.pill { display: inline-flex; align-items: center; gap: 6px; background: var(--card2); border: 1px solid var(--line);
        border-radius: 999px; padding: 5px 12px; font-size: 14px; font-weight: 700; }

/* Placeholder art token */
.ph {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 14px; background: var(--card2); border: 1px dashed var(--line);
  font-size: 34px; line-height: 1;
}
.ph.big { width: 118px; height: 118px; font-size: 62px; border-radius: 26px; }
/* When a real character IMAGE is dropped in (customer portraits/expressions),
   let it fill the space and drop the dashed placeholder frame. Emoji fallbacks
   keep the framed box. */
.ph.big:has(img.art) { width: auto; height: auto; min-width: 118px; background: none; border: none; }
.ph.big img.art { height: 128px; width: auto; max-width: 150px; }
/* Result-screen customer is shown bigger now that Round Recap is tucked behind a
   button (freeing vertical room). Goal is eventually as big as the arrival portrait. */
.ph.big img.result-face { height: 176px; max-width: 230px; }

/* --- Start screen --- */
#screen-start .logo { font-size: 44px; font-weight: 900; letter-spacing: .5px;
  background: linear-gradient(90deg, #fff0fb, #ffd6ea); -webkit-background-clip: text; background-clip: text; color: transparent; }
#screen-start .sub { font-size: 20px; font-weight: 800; color: var(--pink); margin-top: -4px; }
/* Custom brand logo (art/logo.webp) — replaces the text wordmark when present */
#screen-start .wp-logo { display: block; width: 82%; max-width: 300px; height: auto; margin: 0 auto; }
/* Logo stage: a soft pulsing glow behind it, gentle float, drifting sparkles */
.logo-stage { position: relative; display: flex; align-items: center; justify-content: center;
  width: 100%; padding: 22px 0; margin-bottom: 2px; }
.logo-stage::before { content: ""; position: absolute; width: 280px; height: 170px; border-radius: 50%;
  background: radial-gradient(ellipse, rgba(255,158,224,.38), rgba(180,140,255,.16) 55%, transparent 72%);
  filter: blur(8px); z-index: 0; animation: logoGlow 4s ease-in-out infinite; }
@keyframes logoGlow { 0%,100% { opacity: .7; transform: scale(.96); } 50% { opacity: 1; transform: scale(1.04); } }
.logo-float { position: relative; z-index: 2; animation: logoFloat 4.6s ease-in-out infinite; will-change: transform; }
@keyframes logoFloat { 0%,100% { transform: translateY(-5px); } 50% { transform: translateY(5px); } }
/* the realm's hanging sign sits BEHIND the logo and bobs with it — it looks like it hangs from
   the logo by its ropes. The logo image is layered in front (z-index 2). */
.logo-float > .wp-logo, .logo-float > .logo, .logo-float > .sub { position: relative; z-index: 2; }
.realm-sign { position: absolute; left: 50%; transform: translateX(-50%); z-index: 1; width: 62%; top: calc(100% - 30px);
  pointer-events: none; filter: drop-shadow(0 8px 9px rgba(0,0,0,.45)); }
.logo-sparkles { position: absolute; inset: -6px 0; overflow: hidden; z-index: 1; pointer-events: none; }
.lspark { position: absolute; top: -8%; border-radius: 50%;
  background: radial-gradient(circle, #fff, rgba(255,220,240,.95) 45%, rgba(255,158,224,0) 72%);
  box-shadow: 0 0 6px rgba(255,224,240,.9); opacity: 0;
  animation-name: lsparkFall; animation-timing-function: linear; animation-iteration-count: infinite; }
@keyframes lsparkFall {
  0% { transform: translateY(0) scale(.5); opacity: 0; }
  12% { opacity: 1; } 55% { opacity: .95; } 88% { opacity: .35; }
  100% { transform: translateY(150px) scale(1); opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .logo-float, .logo-stage::before, .lspark { animation: none; }
  .lspark { opacity: 0; } }
.bubble-emojis { font-size: 30px; letter-spacing: 6px; }

/* --- Menu / upgrades --- */
.up-grid { display: flex; flex-direction: column; gap: 8px; }
.up-card { display: flex; align-items: center; gap: 10px; background: var(--card2); border: 1px solid var(--line);
  border-radius: 12px; padding: 10px 12px; }
.up-card .up-body { flex: 1; }
.up-card .up-name { font-weight: 800; font-size: 14px; }
.up-card .btn.small { width: auto; white-space: nowrap; }

/* --- Customer screen --- */
.speech { position: relative; background: #fff; color: #3a2350; border-radius: 16px; padding: 14px 16px;
  font-style: italic; font-size: 16px; line-height: 1.35; box-shadow: 0 6px 16px rgba(0,0,0,0.25); }
.speech b { font-style: normal; }
.needs-row { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.need-chip { display: flex; align-items: center; gap: 7px; background: var(--card2); border: 1px solid var(--line);
  border-radius: 999px; padding: 6px 12px; font-weight: 700; font-size: 14px; }
.dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; vertical-align: 0; }
.need-chip .dot { width: 12px; height: 12px; }
.inv-tile .q .dot { width: 10px; height: 10px; margin-right: 2px; }
.need-chip.hidden-need { color: var(--ink-dim); font-style: italic; }
.stat-line { display: flex; justify-content: space-between; font-size: 15px; padding: 4px 2px; }
.stat-line span:last-child { font-weight: 800; }

/* --- Bubble queue --- */
.bubble-queue { display: flex; gap: 6px; flex-wrap: wrap; }
.bubble-queue .b { width: 16px; height: 16px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff, rgba(255,255,255,.35)); opacity: .9; }
.bubble-queue .b.popped { opacity: .2; }
.big-bubble { width: 150px; height: 150px; border-radius: 50%; cursor: pointer;
  background: radial-gradient(circle at 35% 30%, rgba(255,255,255,.95), rgba(180,140,255,.5) 55%, rgba(120,80,180,.35));
  border: 2px solid rgba(255,255,255,.35); box-shadow: 0 10px 30px rgba(0,0,0,.3);
  display: flex; align-items: center; justify-content: center; font-size: 40px; transition: transform .08s; }
.big-bubble:active { transform: scale(0.94); }

/* --- ASMR pop phase: a cluster of squishy bubbles you burst --- */
/* the hint floats OVER the wall (not in flow) so the bubble field can fill the whole area */
.pop-sub { position: absolute; left: 10px; right: 10px; top: calc(var(--safe-t) + 118px);
  text-align: center; font-size: 13px; margin: 0; z-index: 0; pointer-events: none; }
.pop-sub.timed { top: calc(var(--safe-t) + 150px); }
/* Courtyard stash pop: drop the hint into the clear band below the moved pet, above the mid gems */
.pop-sub.hint-lo { top: calc(var(--safe-t) + 372px); }
/* the bubbles are absolutely placed inside this big field (see layoutBubbleField) */
.bubble-field { position: relative; z-index: 1; flex: 1; min-height: 0; overflow: hidden; --bub: 68px; --amp: 16px; }
.pbubble { position: absolute; width: var(--bub,68px); height: var(--bub,68px); border: none; padding: 0; cursor: pointer;
  font-size: calc(var(--bub,68px) * 0.42);
  border-radius: 50%; display: flex; align-items: center; justify-content: center; color: rgba(255,255,255,.9);
  background: radial-gradient(circle at 34% 28%, rgba(255,255,255,.95), rgba(170,150,255,.42) 52%, rgba(120,80,180,.30) 100%);
  border: 1.5px solid rgba(255,255,255,.4); box-shadow: 0 6px 16px rgba(0,0,0,.28), inset 0 -6px 10px rgba(90,50,140,.35);
  animation: bfloat var(--dur, 6s) ease-in-out infinite; animation-delay: var(--del, 0s);
  -webkit-tap-highlight-color: transparent; }
.pbubble .sheen { position: absolute; top: 12%; left: 20%; width: 34%; height: 26%; border-radius: 50%;
  background: rgba(255,255,255,.7); filter: blur(1px); pointer-events: none; }
.pbubble.popped { animation: bpop .34s cubic-bezier(.3,1.4,.5,1) forwards; pointer-events: none; }
.pbubble.spawning { animation: bspawn .48s cubic-bezier(.2,1.5,.4,1) both; }
/* gentle wander around a wider area so you chase them a little */
@keyframes bfloat {
  0%,100% { transform: translate(0, 0); }
  25% { transform: translate(calc(var(--ax,0) * var(--amp,24px)), calc(var(--ay,0) * var(--amp,24px))); }
  50% { transform: translate(calc(var(--bx,0) * var(--amp,24px)), calc(var(--by,0) * var(--amp,24px))); }
  75% { transform: translate(calc(var(--cx,0) * var(--amp,24px)), calc(var(--cy,0) * var(--amp,24px))); }
}
@keyframes bpop {
  0% { transform: scale(1); }
  35% { transform: scale(1.35); box-shadow: 0 0 24px rgba(255,255,255,.85); filter: brightness(1.5); }
  100% { transform: scale(0); opacity: 0; }
}
@keyframes bspawn {
  0% { transform: scale(0); opacity: 0; }
  60% { transform: scale(1.2); opacity: 1; box-shadow: 0 0 18px rgba(140,233,255,.9); }
  100% { transform: scale(1); }
}
/* squeeze-and-hold: bubble swells while pressed */
.pbubble.squeezing { animation: bsqueeze 1s ease-out forwards; z-index: 6; }
@keyframes bsqueeze {
  0% { transform: scale(1); filter: brightness(1); }
  100% { transform: scale(1.85); filter: brightness(1.35); box-shadow: 0 0 30px rgba(255,255,255,.75), inset 0 -6px 10px rgba(90,50,140,.3); }
}
/* --- Pop-phase wooden wall backdrop + the rare "smash the X" treasure stash --- */
#screen-pop { position: relative; }   /* anchor the absolute hint + bubble field */
#screen-pop.pop-woodbg { position: relative; isolation: isolate; }
.pop-bg { position: absolute; top: 0; bottom: 0; left: -14px; right: -14px; z-index: -2; pointer-events: none;
  background-size: cover; background-position: center; background-repeat: no-repeat; background-color: #000; }
/* the X / hole / treasure sit BEHIND the floating bubbles, so tapping always pops a bubble
   first — the stash is a pure Easter egg you only reach once the bubbles above it clear. */
.pop-hole-layer { position: absolute; top: 0; bottom: 0; left: -14px; right: -14px; z-index: -1; pointer-events: none; }
.pop-hole-layer > * { pointer-events: auto; }
/* the bubble field lets empty-area taps fall through to the wall behind it */
.bubble-field { pointer-events: none; }
.bubble-field .pbubble { pointer-events: auto; }
/* King's Courtyard SECRET: the royal-arch stash as a rare pop backdrop. The dull gems sit
   behind the bubbles (same level as the wood X), so popping always wins a tap first; empty
   taps fall through to a gem's hotspot once the bubbles above it clear. */
/* Fills the game column edge to edge, exactly like the wood wall (the -14px undoes #app's
   side padding so it reaches the column's left/right). Same mobile framing as every screen. */
.pop-stash { position: absolute; top: 0; bottom: 0; left: -14px; right: -14px; z-index: -2;
  overflow: hidden; pointer-events: none; background: #453530; }
/* NORMAL pop (no gems): COVER the column, top-anchored, so it always fills. */
.pop-stash .stash-stage { position: absolute; inset: 0; }
.pop-stash .stash-bg { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center top;
  filter: brightness(0.72); }   /* dim the bright courtyard arch so it matches the before/after screens */
/* STASH pop (dull gems): fit by WIDTH so all five gems stay on-screen; blend the strip below. */
.pop-stash.has-gems .stash-stage { inset: auto; top: 0; left: 0; width: 100%; height: auto; }
.pop-stash.has-gems .stash-bg { height: auto; object-fit: initial; }
.pop-stash.has-gems .stash-stage::after { content: ""; position: absolute; left: 0; right: 0; top: 99%; height: 60vh;
  background: linear-gradient(#453530, #3a2c27); }
.pop-stash .stash-hit { pointer-events: auto; }
/* hide the top-left pet badge on a stash pop so it doesn't cover the upper-left gem */
/* the carved X is an invisible hotspot over the art — no hint (it's an Easter egg) */
.pop-x-target { position: absolute; transform: translate(-50%,-50%); border: none; background: none; padding: 0; cursor: pointer;
  border-radius: 50%; -webkit-tap-highlight-color: transparent; }
/* the treasure floating in the smashed hole — glows and pulses, tap to grab */
.pop-treasure { position: absolute; transform: translate(-50%,-50%); border: none; background: none; padding: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center; -webkit-tap-highlight-color: transparent;
  animation: popTreasureRise .45s cubic-bezier(.2,1.4,.4,1) both, popTreasureBob 1.9s ease-in-out infinite .45s; }
@keyframes popTreasureRise { 0% { transform: translate(-50%, calc(-50% + 14px)) scale(.4); opacity: 0; } 100% { transform: translate(-50%,-50%) scale(1); opacity: 1; } }
.pop-treasure-ic { display: flex; align-items: center; justify-content: center; font-size: 34px; line-height: 1;
  animation: popTreasurePulse 1.5s ease-in-out infinite; }
.pop-treasure .pearl-ic { width: 34px; height: 34px; }
.pop-treasure.gold  .pop-treasure-ic { filter: drop-shadow(0 0 9px rgba(255,208,90,.95)); }
.pop-treasure.dust  .pop-treasure-ic { filter: drop-shadow(0 0 9px rgba(150,220,255,.95)); }
.pop-treasure.pearl .pop-treasure-ic { filter: drop-shadow(0 0 9px rgba(255,190,235,.95)); }
@keyframes popTreasureBob { 0%,100% { transform: translate(-50%,-50%); } 50% { transform: translate(-50%, calc(-50% - 5px)); } }
@keyframes popTreasurePulse { 0%,100% { transform: scale(1); opacity: .9; } 50% { transform: scale(1.14); opacity: 1; } }
.pop-treasure.grabbed { animation: popTreasureGrab .42s ease-out forwards; pointer-events: none; }
@keyframes popTreasureGrab { 0% { transform: translate(-50%,-50%) scale(1); opacity: 1; } 100% { transform: translate(-50%, -170%) scale(1.6); opacity: 0; } }
/* wood splinters flung out when the wall smashes */
.pop-splinter { position: absolute; width: 9px; height: 9px; border-radius: 2px; transform: translate(-50%,-50%); pointer-events: none;
  box-shadow: 0 1px 2px rgba(0,0,0,.5); animation: popSplinter .6s ease-out forwards; }
@keyframes popSplinter { 0% { transform: translate(-50%,-50%) scale(1) rotate(0); opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.35) rotate(var(--rot)); opacity: 0; } }
.pop-splinter.chip { width: 6px; height: 6px; animation-duration: .42s; }
/* an ingredient that pops out and floats up — tap to catch it */
.ing-token { position: fixed; width: 52px; height: 52px; transform: translate(-50%,-50%); pointer-events: auto; cursor: pointer;
  border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 26px;
  background: radial-gradient(circle at 35% 30%, rgba(255,255,255,.96), rgba(150,200,255,.5) 55%, rgba(120,130,220,.4));
  border: 2px solid rgba(200,230,255,.9); box-shadow: 0 0 14px rgba(160,210,255,.7);
  animation: tokenin .32s cubic-bezier(.2,1.6,.4,1) both, ingbob var(--tdur,3s) ease-in-out infinite; }
.ing-token.caught { animation: tokencatch .26s ease-in forwards; }
/* gentle bob that stays on-screen (bounded) — never floats away uncatchable */
@keyframes ingbob {
  0%,100% { margin: 0; }
  33% { margin: var(--by1,-14px) 0 0 var(--bx1,10px); }
  66% { margin: var(--by2,14px) 0 0 var(--bx2,-10px); }
}

/* Charm celebration: a big spinning emoji with golden rays */
.charm-celebrate { position: absolute; inset: 0; z-index: 58; display: flex; align-items: center; justify-content: center; pointer-events: none; }
.charm-celebrate .ch { font-size: 84px; animation: charmpop 1.05s cubic-bezier(.2,1.4,.4,1) forwards;
  filter: drop-shadow(0 6px 16px rgba(0,0,0,.5)); }
.charm-celebrate .rays { position: absolute; width: 260px; height: 260px; border-radius: 50%;
  background: conic-gradient(from 0deg, rgba(255,227,138,.55), rgba(255,227,138,0) 22deg, rgba(255,227,138,.55) 45deg,
    rgba(255,227,138,0) 67deg, rgba(255,227,138,.55) 90deg, rgba(255,227,138,0) 112deg, rgba(255,227,138,.55) 135deg,
    rgba(255,227,138,0) 157deg, rgba(255,227,138,.55) 180deg, rgba(255,227,138,0) 202deg, rgba(255,227,138,.55) 225deg,
    rgba(255,227,138,0) 247deg, rgba(255,227,138,.55) 270deg, rgba(255,227,138,0) 292deg, rgba(255,227,138,.55) 315deg,
    rgba(255,227,138,0) 337deg, rgba(255,227,138,.55) 360deg);
  -webkit-mask: radial-gradient(circle, transparent 30%, #000 32%, #000 70%, transparent 72%);
  mask: radial-gradient(circle, transparent 30%, #000 32%, #000 70%, transparent 72%);
  animation: rayspin 1.05s ease-out forwards; }
@keyframes charmpop {
  0% { transform: scale(0) rotate(-90deg); opacity: 0; }
  45% { transform: scale(1.25) rotate(10deg); opacity: 1; }
  70% { transform: scale(1.1) rotate(-4deg); }
  100% { transform: scale(1.35) translateY(-14px); opacity: 0; }
}
@keyframes rayspin { 0% { transform: scale(.4) rotate(0deg); opacity: 0; } 40% { opacity: .9; } 100% { transform: scale(1.1) rotate(120deg); opacity: 0; } }

/* Bonus bubbles look distinct (golden) so you can spot them */
.pbubble.bonus {
  background: radial-gradient(circle at 34% 28%, rgba(255,255,255,.98), rgba(255,214,120,.6) 48%, rgba(255,150,60,.42) 100%);
  border-color: rgba(255,235,160,.95);
  box-shadow: 0 6px 16px rgba(0,0,0,.28), inset 0 -6px 10px rgba(180,110,30,.4), 0 0 0 rgba(255,220,130,.6);
  animation: bfloat var(--dur,6s) ease-in-out infinite, bonusglow 1.4s ease-in-out infinite; }
@keyframes bonusglow {
  0%,100% { box-shadow: 0 6px 16px rgba(0,0,0,.28), inset 0 -6px 10px rgba(180,110,30,.4), 0 0 6px 1px rgba(255,220,130,.5); }
  50% { box-shadow: 0 6px 16px rgba(0,0,0,.28), inset 0 -6px 10px rgba(180,110,30,.4), 0 0 20px 5px rgba(255,220,130,.95); }
}
.pbubble.bonus.spawning { animation: bspawn .48s cubic-bezier(.2,1.5,.4,1) both; } /* spawn-in wins over the glow */
.pbubble.rotten {
  background: radial-gradient(circle at 34% 28%, rgba(255,255,255,.88), rgba(180,130,30,.55) 48%, rgba(100,65,5,.42) 100%);
  border-color: rgba(180,120,20,.75);
  animation: bfloat var(--dur,6s) ease-in-out infinite, rotBubblePulse 2.2s ease-in-out infinite;
}
@keyframes rotBubblePulse { 0%,100% { box-shadow: 0 4px 10px rgba(0,0,0,.2), 0 0 8px rgba(160,100,0,.45); } 50% { box-shadow: 0 4px 14px rgba(0,0,0,.3), 0 0 20px rgba(200,120,0,.9); } }
.pbubble .bub-rot { position: absolute; top: -5px; right: -5px; font-size: 15px; pointer-events: none; z-index: 2; }
.pbubble.bonus.popped, .pbubble.big.popped { animation: bpopbig .5s cubic-bezier(.3,1.4,.5,1) forwards; }
@keyframes bpopbig {
  0% { transform: scale(1); }
  40% { transform: scale(1.7); box-shadow: 0 0 40px 10px rgba(255,220,130,.95); filter: brightness(1.7); }
  100% { transform: scale(0); opacity: 0; }
}

/* shockwave ring (bonus burst) */
.ring { position: fixed; border-radius: 50%; border: 3px solid rgba(255,220,130,.9); transform: translate(-50%,-50%);
  pointer-events: none; z-index: 59; animation: ringout .6s ease-out forwards; }
@keyframes ringout { 0% { width: 18px; height: 18px; opacity: .95; } 100% { width: 230px; height: 230px; opacity: 0; border-width: 1px; } }

/* a charm that pops out and floats — tap to catch it */
.catch-layer { position: fixed; inset: 0; pointer-events: none; z-index: 61; overflow: hidden; }
.charm-token { position: fixed; width: 64px; height: 64px; transform: translate(-50%,-50%); pointer-events: auto; cursor: pointer;
  border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 32px;
  background: radial-gradient(circle at 35% 30%, rgba(255,255,255,.98), rgba(255,215,120,.55) 52%, rgba(200,120,255,.42));
  border: 2px solid rgba(255,235,160,.95); box-shadow: 0 0 20px rgba(255,220,130,.85);
  animation: tokenin .42s cubic-bezier(.2,1.6,.4,1) both, ctfloat var(--tdur,2.8s) ease-in-out .42s infinite; }
.charm-token .lbl { position: absolute; bottom: -18px; left: 50%; transform: translateX(-50%); white-space: nowrap;
  font-size: 11px; font-weight: 800; color: #ffe38a; text-shadow: 0 1px 3px rgba(0,0,0,.7); }
.charm-token.caught { animation: tokencatch .3s ease-in forwards; }
@keyframes tokenin { 0% { transform: translate(-50%,-50%) scale(0); } 100% { transform: translate(-50%,-50%) scale(1); } }
@keyframes ctfloat {
  0%,100% { margin: 0 0; }
  33% { margin: calc(var(--ty1,-30px)) 0 0 var(--tx1,26px); }
  66% { margin: var(--ty2,20px) 0 0 var(--tx2,-24px); }
}
@keyframes tokencatch { 0% { transform: translate(-50%,-50%) scale(1); opacity: 1; } 100% { transform: translate(-50%,-50%) scale(1.8); opacity: 0; } }

.burst-layer { position: fixed; inset: 0; pointer-events: none; z-index: 60; overflow: hidden; }
.particle { position: fixed; border-radius: 50%; transform: translate(-50%, -50%);
  animation: fly .68s ease-out forwards; }
@keyframes fly {
  0% { transform: translate(-50%,-50%) scale(1); opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.3); opacity: 0; }
}
.reward-pop { position: fixed; transform: translate(-50%, -50%); white-space: nowrap; font-weight: 800; font-size: 14px;
  color: #fff; text-shadow: 0 2px 6px rgba(0,0,0,.6); animation: rwup 1s ease-out forwards; pointer-events: none; }
.reward-pop .e { font-size: 18px; }
.reward-pop.rare { font-size: 17px; color: #ffe38a; }
@keyframes rwup {
  0% { transform: translate(-50%,-50%) scale(.6); opacity: 0; }
  20% { transform: translate(-50%,-70%) scale(1.05); opacity: 1; }
  100% { transform: translate(-50%,-150%) scale(1); opacity: 0; }
}
.screen-flash { position: absolute; inset: 0; z-index: 55; pointer-events: none; opacity: 0;
  background: radial-gradient(circle at 50% 45%, rgba(255,230,150,.5), rgba(255,230,150,0) 60%); }
.screen-flash.go { animation: flashfade .5s ease-out; }
@keyframes flashfade { 0% { opacity: 1; } 100% { opacity: 0; } }
.mute-btn { position: absolute; top: 54px; right: 12px; z-index: 40; width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--card2); font-size: 18px; cursor: pointer; }
.mute-btn:active { transform: scale(0.92); }

/* --- ASMR scoop phase: shake the glitter off the scoop --- */
/* ===== SCOOP PHASE — full-bleed shop scene; the spoon dips into the glitter pile,
   a front glitter lip hides the dip, bubbles rise out when you shake ===== */
.scoop-bg { position: absolute; inset: 0; z-index: 0; background-size: cover; background-position: center; }
.scoop-front { position: absolute; inset: 0; z-index: 3; background-size: cover; background-position: center; pointer-events: none; }
/* floating chrome over the scene */
/* Shared HUD overlay (#round-hud): the pet badge (left), round timer + running tally (under it),
   and the ☰ menu (right). It's a child of #app spanning the whole column, so its absolutely-
   positioned children land in the SAME spot on scoop, pop, mix and home — regardless of each
   screen's own padding. It never blocks the game (pointer-events pass through except on controls). */
#round-hud { position: absolute; inset: 0; z-index: 41; pointer-events: none; }
#round-hud .petbadge { position: absolute; top: calc(var(--safe-t) + 12px); left: 15px; pointer-events: auto; }
#round-hud .round-menu { position: absolute; top: calc(var(--safe-t) + 18px); right: 14px; pointer-events: auto;
  width: 40px; height: 40px; border-radius: 11px; font-size: 20px; color: #ffe6b0;
  background: rgba(50,24,72,.7); border: 1.5px solid rgba(255,214,110,.55); cursor: pointer; }
#round-hud .round-menu:active { transform: scale(.92); }
/* home only: a tappable gold chip sits just left of the ☰ menu */
#round-hud .hud-gold { position: absolute; top: calc(var(--safe-t) + 18px); right: 62px; height: 40px; pointer-events: auto;
  display: flex; align-items: center; gap: 5px; padding: 0 12px 0 9px; border-radius: 12px; cursor: pointer;
  font-family: var(--ff-display); font-weight: 800; font-size: 18px; color: #fff;
  background: rgba(50,24,72,.7); border: 1.5px solid rgba(255,214,110,.55); }
#round-hud .hud-gold .hud-gold-ic { font-size: 19px; }
#round-hud .hud-gold:active { transform: scale(.94); }
/* the currency drop-down (tap the gold chip) */
/* absolute (relative to the #app game column), NOT fixed — otherwise on a wide screen (iPad) the
   right-aligned card lands at the viewport edge, far off the game column. */
.curr-ov { position: absolute; inset: 0; z-index: 96; }
.curr-card { position: absolute; top: calc(var(--safe-t) + 64px); right: 10px; min-width: 196px;
  background: linear-gradient(180deg, rgba(48,30,74,.98), rgba(26,15,46,.98)); border: 2px solid rgba(240,200,110,.6);
  border-radius: 16px; box-shadow: 0 10px 26px rgba(0,0,0,.55); padding: 8px; animation: fade .16s ease; }
.curr-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 10px; }
.curr-row + .curr-row { border-top: 1px solid rgba(255,255,255,.09); }
.curr-ic { font-size: 20px; width: 24px; text-align: center; }
.curr-name { flex: 1; color: #e9ddff; font-weight: 700; font-size: 15px; }
.curr-n { color: #fff; font-family: var(--ff-display); font-weight: 900; font-size: 17px; }
/* home top row is now the overlay (pet left, gold + menu right); reserve enough height that the
   logo below clears the pet badge */
.home-topspace { height: 34px; flex: 0 0 auto; }
/* running tally — one of our bubbles with the live count inside it, tucked under the pet */
.phase-count { position: absolute; z-index: 41; width: 54px; height: 54px; display: grid; place-items: center; pointer-events: none; }
.phase-count-bub { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 2px 6px rgba(0,0,0,.55)); }
.phase-count-n { position: relative; z-index: 2; font-family: var(--ff-display); font-size: 23px; font-weight: 900; color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,.9), 0 0 7px rgba(120,180,255,.75); }
/* the running tally tucks UNDER the pet — or drops below the round timer when the customer is timed */
.phase-count.under-pet   { top: calc(var(--safe-t) + 152px); left: 52px; }
.phase-count.under-timer { top: calc(var(--safe-t) + 232px); left: 52px; }
.phase-count.bumped { animation: phaseCountBumpPlain .28s ease; }
@keyframes phaseCountBumpPlain { 0% { transform: scale(1); } 40% { transform: scale(1.18); } 100% { transform: scale(1); } }
/* In-a-Rush countdown: a round badge docked under the pet — same look on scoop, pop and mix */
.rush-badge { width: 72px; height: 72px; border-radius: 50%; z-index: 42; pointer-events: none;
  background: radial-gradient(circle at 50% 34%, #ff5a5a, #c62828); border: 4px solid var(--gold); color: #fff;
  box-shadow: 0 4px 12px rgba(0,0,0,.5); display: flex; flex-direction: column; align-items: center; justify-content: center; }
.rush-badge b { font-size: 27px; line-height: 1; font-weight: 900; }
.rush-badge span { font-size: 10px; letter-spacing: .5px; opacity: .95; }
.rush-badge.urgent { animation: hgpulse .6s infinite; }
#round-hud .rush-badge.rt-rush { position: absolute; top: calc(var(--safe-t) + 152px); left: 43px; }
.scoop-head { position: absolute; top: calc(var(--safe-t) + 212px); left: 0; right: 0; z-index: 12; text-align: center; pointer-events: none; }
.scoop-head.timed { top: calc(var(--safe-t) + 292px); }
/* ☰ popup menu (round screens) */
.hudmenu-ov { position: fixed; inset: 0; z-index: 95; display: flex; align-items: center; justify-content: center; padding: 24px;
  background: rgba(10,6,20,.72); animation: fade .18s ease; }
.hudmenu-card { width: 84%; max-width: 300px; display: flex; flex-direction: column; gap: 10px; padding: 20px 18px;
  border-radius: 18px; background: linear-gradient(160deg, #2a1740, #170c26); border: 1.5px solid rgba(255,214,110,.4); box-shadow: 0 12px 34px rgba(0,0,0,.6); }
.hudmenu-title { text-align: center; font-family: var(--ff-display); font-size: 22px; color: #ffe6b0; margin-bottom: 2px; }
.hudmenu-item { padding: 13px 16px; border-radius: 13px; border: 1.5px solid rgba(255,214,110,.4); cursor: pointer;
  background: rgba(60,30,86,.7); color: #fff; font-family: var(--ff-display); font-size: 18px; }
.hudmenu-item:active { transform: scale(.97); }
.hudmenu-item.hm-close { background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.18); font-size: 16px; }
.scoop-sub { font-size: 13px; color: #ffe6a8; text-shadow: 0 2px 5px rgba(0,0,0,.85); }
.scoop-instr { font-size: 17px; font-weight: 800; min-height: 24px; margin: 2px 16px 0; color: #fff; text-shadow: 0 2px 6px rgba(0,0,0,.95); }
.scoop-controls { position: absolute; left: 0; right: 0; bottom: calc(var(--safe-b) + 8px); z-index: 12;
  padding: 0 10px; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.scoop-controls .row { width: 100%; max-width: 380px; }
.scoop-result { text-align: center; font-size: 13px; min-height: 16px; color: #ffe6a8; text-shadow: 0 2px 5px rgba(0,0,0,.85); }
/* the stage's bottom softly fades into the pile so a deep dip melts into the glitter
   (no hard clip line), while the front glitter hides the main dip */
.scoop-stage { position: absolute; inset: 0; z-index: 1; touch-action: none;
  user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; cursor: grab;
  -webkit-mask-image: linear-gradient(to bottom, #000 84%, transparent 97%); mask-image: linear-gradient(to bottom, #000 84%, transparent 97%); }
.scoop-stage:active { cursor: grabbing; }
/* spoon rests mid-screen (bowl above the pile); it dips down into the glitter to scoop */
/* the whole rig bobs gently in the air (bowl + glitter + bubbles move together) */
.scoop-craft { position: absolute; left: 50%; transform: translateX(-50%); top: 10%; bottom: 35%; width: 96%; max-width: 440px;
  display: flex; align-items: flex-end; justify-content: center; animation: craftFloat 3.4s ease-in-out infinite; }
@keyframes craftFloat { 0%,100% { transform: translateX(-50%) translateY(0); } 50% { transform: translateX(-50%) translateY(-8px); } }
.scoop-bowl { position: relative; font-size: 178px; line-height: 1; z-index: 2; will-change: transform; }
.scoop-bowl img.art { display: block; width: 1.7em; height: auto; filter: drop-shadow(0 12px 20px rgba(0,0,0,.55)); }
.scoop-bowl.jig { animation: sjig .2s ease; }
.scoop-bowl.diving { animation: sdive 1.15s ease-in-out; }
@keyframes sjig { 0%,100% { transform: translateX(0) rotate(0); } 20% { transform: translateX(-11px) rotate(-5deg); } 55% { transform: translateX(10px) rotate(4deg); } 82% { transform: translateX(-4px) rotate(-2deg); } }
/* dip in fairly quickly, LINGER deep in the glitter (so the glitter can fade in while the bowl
   is hidden in the pile), then rise back out slowly (heavy scoop). */
@keyframes sdive { 0% { transform: translateY(0); } 24% { transform: translateY(28vh) scale(.95); } 55% { transform: translateY(27vh) scale(.95); } 100% { transform: translateY(0); } }
/* bubbles rise from the CENTRE of the glitter in the sifter (the basket sits left of screen centre) */
/* bubbles spawn from random points across the FLAT glitter surface (this box maps to that
   red ellipse) — each begins as a gold glow, then grows into the bubble as it floats up */
.scoop-bubbles { position: absolute; left: 43%; bottom: 21%; transform: translateX(-50%); width: 34%; height: 8%; z-index: 4; }
.sbub { position: absolute; opacity: 0; } /* positioned per-bubble within the ellipse in JS */
.sbub.floatup { animation: sfloat 1.15s ease-in forwards; }
@keyframes sfloat {
  0%   { transform: translate(-50%,-50%) scale(.26); opacity: 0; }
  14%  { opacity: 1; }
  40%  { transform: translate(-50%, calc(-50% - 7vh)) scale(1); }
  100% { transform: translate(calc(-50% + var(--fx,0)), calc(-50% - 44vh)) scale(1); opacity: 0; } }
/* the gold glow that "becomes" the bubble (fades off as the bubble grows in) */
.sbub::before { content: ""; position: absolute; inset: -16%; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 50% 45%, #fff, #ffe38a 40%, rgba(255,190,70,.45) 64%, rgba(255,190,70,0) 78%); opacity: 0; }
.sbub.floatup::before { animation: sglow 1.15s ease-in forwards; }
@keyframes sglow { 0% { opacity: .95; } 42% { opacity: 0; } 100% { opacity: 0; } }
/* the glittery scoop is the SAME full spoon, layered exactly over the empty one. It carries
   class "art" too, so it gets its size from the identical rule (.scoop-bowl img.art) — the two
   layers can never differ in size. Only position/opacity differ here. Fading its opacity fills
   the scoop on the dip and empties it as you shake (opacity is cheap/composited — no per-frame redraw). */
.scoop-bowl img.scoop-glitter-tip { position: absolute; left: 0; top: 0; z-index: 1;
  opacity: 0; transition: opacity .4s ease; pointer-events: none; filter: none; }
.scoop-bowl img.scoop-glitter-tip.rainbow { filter: saturate(1.3) hue-rotate(18deg); }
/* trails of glitter + sparkle that rain down the screen and fade as you shake.
   Kept deliberately CHEAP (no clip-path / drop-shadow, tiny shadow) and capped in JS,
   so a vigorous shake can't flood a phone's GPU. */
.fall-glitter { position: absolute; z-index: 6; width: 4px; height: 15px; border-radius: 2px; pointer-events: none;
  background: linear-gradient(to bottom, rgba(255,240,180,0), var(--fc,#ffd76a) 55%, #fff);
  animation: fallGlit var(--fd,1.15s) cubic-bezier(.4,0,.85,1) forwards; }
@keyframes fallGlit {
  0% { opacity: 0; transform: translate(0,0) scaleY(.6); }
  12% { opacity: 1; }
  75% { opacity: .95; }
  100% { opacity: 0; transform: translate(var(--fx,0), var(--fy,420px)) scaleY(1.5); } }
.fall-spark { position: absolute; z-index: 6; width: var(--sz,8px); height: var(--sz,8px); border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 50% 50%, #fff 0%, var(--fc,#ffe38a) 45%, rgba(255,200,90,0) 82%);
  animation: fallSpark var(--fd,1.2s) cubic-bezier(.4,0,.85,1) forwards; }
@keyframes fallSpark {
  0% { opacity: 0; transform: translate(0,0) scale(.5); }
  14% { opacity: 1; }
  70% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--fx,0), var(--fy,420px)) scale(.3); } }

/* --- rare secret treasure: a stray pearl peeking out from behind the glitter --- */
/* the pearl art is full-bleed (z2) so it sits BEHIND the front glitter (z3) but in front of the spoon */
.scoop-secret { position: absolute; inset: 0; z-index: 2; background-size: cover; background-position: center;
  background-repeat: no-repeat; pointer-events: none; opacity: 0; }
/* appears INSTANTLY with the background (no fade/movement) so it's simply already there — never seen arriving */
.scoop-secret.shown { opacity: 1; }
.scoop-secret.popped { animation: secretPop .38s ease forwards; }
@keyframes secretPop { 0% { opacity: 1; transform: scale(1); } 55% { opacity: 1; transform: scale(1.16); } 100% { opacity: 0; transform: scale(1.32); } }
/* invisible tap target sitting over the peeking pearl — no glow, so it doesn't announce itself */
.secret-hit { position: absolute; z-index: 6; border: 0; background: transparent; border-radius: 50%; padding: 0;
  cursor: pointer; -webkit-tap-highlight-color: transparent; }
/* the popped prize floats there waiting to be grabbed */
.secret-prize { position: absolute; z-index: 6; border: 0; background: transparent; padding: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center; -webkit-tap-highlight-color: transparent;
  animation: secretBob 1.4s ease-in-out infinite; filter: drop-shadow(0 4px 8px rgba(0,0,0,.5)); }
.secret-prize-ic { font-size: 30px; line-height: 1; }
.secret-prize-ic img.art, .secret-prize-ic .pearl-ic { width: 34px; height: 34px; display: block; }
.secret-prize::after { content: ""; position: absolute; inset: -32%; border-radius: 50%; z-index: -1;
  background: radial-gradient(circle, rgba(255,240,180,.55), rgba(255,240,180,0) 68%); animation: secretGlow 1.4s ease-in-out infinite; }
@keyframes secretBob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
@keyframes secretGlow { 0%,100% { opacity: .5; transform: scale(.85); } 50% { opacity: 1; transform: scale(1.15); } }
.secret-prize.grabbed { animation: secretGrab .42s ease forwards; }
@keyframes secretGrab { 0% { transform: scale(1); opacity: 1; } 40% { transform: scale(1.3); } 100% { transform: translateY(-42px) scale(.4); opacity: 0; } }
.secret-spark { position: absolute; width: 8px; height: 8px; border-radius: 50%; z-index: 6; pointer-events: none;
  box-shadow: 0 0 6px rgba(255,240,200,.9); animation: secretSpark .6s ease-out forwards; }
@keyframes secretSpark { 0% { transform: translate(-50%,-50%) scale(1); opacity: 1; } 100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.2); opacity: 0; } }

/* --- +/- stepper buttons (treat quantity in the menu) --- */
.shelf-arrow { font-size: 20px; padding: 8px 14px; background: var(--card2); border: 1px solid var(--line);
  border-radius: 12px; cursor: pointer; user-select: none; }
.shelf-arrow:active { transform: scale(0.94); }

/* --- Familiar badge + confirm dialog --- */
.fam-badge { position: absolute; top: -4px; right: -4px; font-size: 13px;
  background: var(--gold); border-radius: 50%; width: 18px; height: 18px; display: flex; align-items: center; justify-content: center; }
.confirm-overlay { position: absolute; inset: 0; z-index: 46; display: flex; align-items: center; justify-content: center;
  background: rgba(10,4,22,0.6); animation: fade .15s ease; }
.confirm-card { background: var(--card); border: 1px solid var(--line); border-radius: 20px; padding: 22px 24px;
  text-align: center; max-width: 300px; box-shadow: 0 10px 30px rgba(0,0,0,.4); }
.confirm-msg { font-weight: 800; font-size: 17px; margin-bottom: 16px; }

/* --- Mixing --- */
.slots { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.slot { width: 44px; height: 44px; border-radius: 12px; border: 1px dashed var(--line);
  display: flex; align-items: center; justify-content: center; font-size: 24px; background: var(--card2); }
.slot.filled { border-style: solid; background: var(--card); animation: pop .25s ease; }
.slot.potent { box-shadow: 0 0 10px var(--gold); }
@keyframes pop { from { transform: scale(0.3); } to { transform: scale(1); } }
.meter { height: 12px; border-radius: 6px; background: rgba(255,255,255,0.14); overflow: hidden; }
.meter > i { display: block; height: 100%; border-radius: 6px; transition: width .35s ease; }
.meter.sweet { position: relative; overflow: visible; }
.meter.sweet > i { position: relative; z-index: 2; }
.meter.sweet .band { position: absolute; top: -2px; bottom: -2px; z-index: 1; border-radius: 5px;
  background: rgba(126,224,138,0.30); box-shadow: inset 0 0 0 1.5px var(--good); transition: left .35s ease, width .35s ease; }
.meter.sweet.hit { box-shadow: 0 0 10px var(--good); }
.meter.sweet.hit .band { background: rgba(126,224,138,0.5); animation: hitpulse .5s ease; }
@keyframes hitpulse { 0% { transform: scaleY(1); } 40% { transform: scaleY(1.5); } 100% { transform: scaleY(1); } }
.need-meter { margin: 5px 0; }
.need-meter .lbl { display: flex; justify-content: space-between; font-size: 13px; margin-bottom: 3px; }

/* Cauldron */
.cauldron-wrap { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; }
.cauldron { position: relative; width: 150px; height: 130px; overflow: hidden;
  border: 3px solid rgba(255,255,255,0.22); border-top-width: 5px;
  border-radius: 22px 22px 70px 70px / 22px 22px 55px 55px;
  background: rgba(255,255,255,0.05); box-shadow: inset 0 -8px 20px rgba(0,0,0,0.25); }
.cauldron .liquid { position: absolute; left: 0; right: 0; bottom: 0; transition: height .4s ease, background .4s;
  border-radius: 0 0 55px 55px; opacity: .85; }
.cauldron .pct { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-weight: 900; font-size: 26px; text-shadow: 0 2px 6px rgba(0,0,0,0.55); }
.cauldron .bub { position: absolute; bottom: 10%; width: 8px; height: 8px; border-radius: 50%;
  background: rgba(255,255,255,0.5); animation: rise 2.4s infinite ease-in; opacity: 0; }
.cauldron .b1 { left: 30%; animation-delay: .2s; } .cauldron .b2 { left: 52%; animation-delay: 1s; }
.cauldron .b3 { left: 70%; animation-delay: 1.7s; }
@keyframes rise { 0% { transform: translateY(0); opacity: 0; } 30% { opacity: .7; } 100% { transform: translateY(-70px); opacity: 0; } }
.cauldron.splash { animation: splash .4s ease; }
@keyframes splash { 0%,100% { transform: none; } 40% { transform: translateY(3px) scaleX(1.05); } }
.mix-hint { text-align: center; font-size: 13px; max-width: 320px; margin: 4px auto 0; }

/* Special-charm tray */
.charm-tray { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 4px; }
.charm-chip { background: var(--card); border: 1px solid var(--gold); color: var(--ink); border-radius: 999px;
  padding: 6px 12px; font-weight: 800; font-size: 13px; cursor: pointer; display: flex; align-items: center; gap: 5px; }
.charm-chip:active { transform: scale(0.94); }
.charm-chip span { font-weight: 700; }

/* 2-row swipeable inventory */
.inv-2row { display: grid; grid-auto-flow: column; grid-template-rows: repeat(2, 1fr); grid-auto-columns: 74px;
  gap: 8px; overflow-x: auto; padding: 8px 2px 4px; scroll-snap-type: x proximity; }
.inv-tile { scroll-snap-align: start; background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 6px 4px; text-align: center; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 2px; }
.inv-tile:active { transform: scale(0.94); }
.inv-tile .emoji { font-size: 24px; }
.inv-tile .nm { font-size: 11px; font-weight: 800; line-height: 1.1; }
.inv-tile .q { font-size: 12px; color: var(--ink-dim); line-height: 1.15; }
.inv-tile.wild { border-style: dashed; }
.inv-tile.potent { box-shadow: 0 0 8px var(--gold); border-color: var(--gold); }
.inv-tile.essence { border-style: dashed; border-color: rgba(255,255,255,.5); }
.orb { display: inline-block; width: 26px; height: 26px; border-radius: 50%;
  box-shadow: 0 0 7px rgba(255,255,255,.55), inset 0 -4px 6px rgba(0,0,0,.28); }
.slot .orb { width: 24px; height: 24px; }
/* knife cut mode: whole ingredients pulse, inviting a tap */
.inv-2row.cutting .inv-tile.cuttable { cursor: pointer; outline: 2px solid var(--gold); animation: cutpulse 1s ease-in-out infinite; }
@keyframes cutpulse { 0%,100% { box-shadow: 0 0 0 rgba(255,215,120,0); } 50% { box-shadow: 0 0 12px rgba(255,215,120,.85); } }

/* Triple-match celebration */
.triple-overlay { position: absolute; inset: 0; z-index: 45; display: flex; align-items: center; justify-content: center;
  background: rgba(10,4,22,0.6); animation: fade .2s ease; }
.triple-card { text-align: center; background: var(--card); border: 1px solid var(--gold); border-radius: 22px;
  padding: 24px 28px; box-shadow: 0 0 30px rgba(255,216,107,0.4); animation: pop .35s ease; }
.triple-card .tt { font-size: 26px; font-weight: 900; color: var(--gold); margin: 6px 0; }

/* --- Result --- */
.result-title { font-size: 30px; font-weight: 900; }
.result-title.win { color: var(--good); }
.result-title.lose { color: var(--bad); }
.result-title.perfect { color: var(--gold);
  background: linear-gradient(90deg, #ffd76a, #ff9ecf, #c48bff, #8fe9ff, #ffd76a);
  background-size: 300% 100%; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  animation: perfectshine 2.2s linear infinite, perfectpop .6s cubic-bezier(.2,1.5,.4,1); }
@keyframes perfectshine { 0% { background-position: 0% 0; } 100% { background-position: 300% 0; } }
@keyframes perfectpop { 0% { transform: scale(.4); opacity: 0; } 60% { transform: scale(1.18); } 100% { transform: scale(1); opacity: 1; } }

/* Two large streak badges on the result screen: overall Win Streak + Allergy-Free */
.result-streaks { display: flex; gap: 12px; justify-content: center; width: 100%; max-width: 340px; }
.streak-badge { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 1px; position: relative;
  padding: 9px 8px 8px; border-radius: 16px; border: 2px solid; background: rgba(20,12,32,.55); }
.streak-badge .sb-ico { font-size: 22px; line-height: 1; }
.streak-badge .sb-n { font-size: 30px; font-weight: 900; line-height: 1; color: #fff; text-shadow: 0 2px 4px rgba(0,0,0,.5); }
.streak-badge .sb-lbl { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .4px; opacity: .95; }
.streak-badge.fire { border-color: #ff8a3d; box-shadow: 0 0 12px rgba(255,138,61,.35); }
.streak-badge.fire .sb-lbl { color: #ffb680; }
.streak-badge.clean { border-color: #7ee08a; box-shadow: 0 0 12px rgba(126,224,138,.35); }
.streak-badge.clean .sb-lbl { color: #a7ecb0; }
.streak-badge.dim { opacity: .4; filter: saturate(.5); box-shadow: none; }
.streak-badge.pop { animation: sbpop .5s cubic-bezier(.2,1.5,.4,1); }
@keyframes sbpop { 0% { transform: scale(.6); } 60% { transform: scale(1.15); } 100% { transform: scale(1); } }
.streak-badge .sb-gain { position: absolute; top: -9px; right: -6px; background: #c48bff; color: #2a0f45;
  font-size: 12px; font-weight: 900; padding: 1px 7px; border-radius: 999px; box-shadow: 0 2px 6px rgba(0,0,0,.4);
  animation: sbpop .5s .15s cubic-bezier(.2,1.5,.4,1) backwards; }
.streak-badge .sb-gain.gold { background: var(--gold); color: #4a2e00; }
/* Result bottom actions: a small Round Recap button stacked above Next Customer */
.result-actions { display: flex; flex-direction: column; gap: 8px; flex-shrink: 0; }
.recap-btn { background: var(--card); color: var(--ink); box-shadow: none; border: 1px solid var(--line); font-size: 15px; padding: 11px 18px; }
/* Round Recap overlay (tucked behind the button to keep the result screen roomy) */
.recap-overlay { position: fixed; inset: 0; z-index: 90; display: flex; align-items: center; justify-content: center;
  background: rgba(6,3,12,.88); padding: 20px; animation: recapfade .18s ease; }
@keyframes recapfade { from { opacity: 0; } to { opacity: 1; } }
.recap-sheet { width: 100%; max-width: 348px; display: flex; flex-direction: column; gap: 12px; animation: sbpop .28s cubic-bezier(.2,1.4,.4,1); }
.recap-sheet .card { width: 100%; max-width: none; }
/* slightly bigger text in the recap for readability */
.recap-sheet .stat-line { font-size: 16.5px; padding: 5px 2px; }
.recap-sheet .card > div:first-child { font-size: 17px; }

/* ============================================================= */
/* New results screen — mirrors the customer-arrival layout      */
/* (same top bar, banner, and character frame), then a parchment */
/* panel with the total earned, reaction, and two streak badges. */
/* ============================================================= */
/* lift only the in-flow content above the realm background; the drifting bubble,
   confetti and particle layers keep their own absolute/fixed positioning */
#screen-result > .res-top, #screen-result > .res-body, #screen-result > .res-next { position: relative; z-index: 1; }
.res-top { margin: 2px 6px 4px; }
/* keep the realm + both currencies on one line (this screen always shows pearls) */
.res-top .cust-realm { font-size: 13px; white-space: nowrap; }
.res-top .cust-coin { font-size: 16px; padding: 3px 12px 3px 4px; }
.res-top .cust-coin img { height: 26px; }
.res-top .cust-coin.pearls { padding: 3px 10px; }
.res-body { flex: 0 1 auto; overflow: hidden; display: flex; flex-direction: column; align-items: center; gap: 2px; padding-bottom: 2px; }
/* banner & portrait reuse the arrival classes (.cust-banner/.cust-portrait) verbatim */
.res-banner { margin-bottom: -46px; }
.res-portrait { margin-bottom: -40px; }
/* the "Results" scroll — a tappable badge on the left, like the arrival badges */
.res-results { position: absolute; left: -13px; top: 15%; z-index: 8; width: 74px; padding: 0; border: none; background: none; cursor: pointer;
  animation: badgeBob 2.4s ease-in-out infinite; }
.res-results img { display: block; width: 100%; height: auto; filter: drop-shadow(0 3px 8px rgba(0,0,0,.5)); }
.res-results::after { content: ""; position: absolute; right: 4px; top: 2px; width: 14px; height: 14px; border-radius: 50%;
  background: #ff5a5a; border: 2px solid #fff; box-shadow: 0 1px 3px rgba(0,0,0,.45); animation: badgePing 1.6s ease-in-out infinite; }
.res-results:active { transform: scale(.93); }
/* parchment panel — 9-slice border-image so the ornate corners never squish;
   only the flat parchment middle stretches, whatever the content height */
.res-panel { position: relative; width: 97%; max-width: 400px; margin: 0 auto 0; box-sizing: border-box;
  border: 40px solid transparent; border-image: url('../art/ui/res_panel.png') 130 fill / 40px / 0 stretch;
  padding: 4px 6px 6px; z-index: 3;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px; }
.res-earned { font-family: var(--ff-body); font-weight: 800; font-size: 19px; color: #3a2408; display: flex; align-items: center; gap: 5px; }
.res-earned .res-coin { height: 25px; width: auto; }
.res-earned .res-cur .pearl-ic { width: 23px; height: 23px; }
.res-earned #rb-count, .res-earned #trash-count { font-family: var(--ff-body); font-size: 24px; display: inline-block; min-width: 14px; text-align: center; }
.res-earned #rb-count.bumped, .res-earned #trash-count.bumped { animation: rbbump .3s ease; }
.res-earned .res-dust { color: #7a3ea0; margin-left: 4px; display: inline-flex; align-items: center; gap: 3px; }
.res-earned .res-dust #rb-dust { font-family: var(--ff-body); font-size: 22px; display: inline-block; }
.res-earned .res-key { color: #b8860b; margin-left: 4px; display: inline-flex; align-items: center; gap: 3px; }
.res-earned.lose { color: #8a3320; }
/* allergy pay-cut pill beside Total Earned — pops in like the streak/tip tags */
.res-atag { display: inline-block; margin-left: 7px; font-family: var(--ff-body); font-weight: 900; font-size: 12.5px;
  padding: 2px 9px; border-radius: 999px; box-shadow: 0 2px 6px rgba(0,0,0,.4); vertical-align: middle; white-space: nowrap;
  animation: sbpop .5s .2s cubic-bezier(.2,1.5,.4,1) backwards; }
.res-atag.yellow { background: #f0b53a; color: #4a2e00; }
.res-atag.red { background: #d9463a; color: #fff; }
/* cap the reaction at 3 lines so it never crowds the badges below it */
.res-react { text-align: center; font-family: var(--ff-read); font-size: 18px; line-height: 1.32; color: #5a2a7a; max-width: 320px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; }
.res-hint { font-family: var(--ff-read); font-size: 12.5px; color: #7a5a2a; margin-top: 1px; text-align: center; }
.res-curse-warn { font-family: var(--ff-read); font-size: 13px; color: #8b6914; font-weight: 700; text-align: center; margin-top: 4px; padding: 4px 10px; background: rgba(139,105,20,.15); border-radius: 8px; border: 1px solid rgba(139,105,20,.35); }
.res-curse-warn .res-rot-ic { width: 20px; height: 20px; vertical-align: -5px; margin-right: 3px; }

/* ===== LADY GOTHEL STEAL OVERLAY ===== */
/* Overlay is pinned to the game column (max 520px), not the full viewport */
.gothel-steal-overlay {
  position: fixed; top: 0; bottom: 0;
  left: 50%; transform: translateX(-50%);
  width: 100%; max-width: 520px;
  z-index: 200; pointer-events: none; overflow: hidden;
  background: rgba(0,0,0,0);
  transition: background 0.8s ease;
}
.gothel-steal-overlay.dimmed { background: rgba(0,0,0,0.45); }
.gothel-steal-caption {
  position: absolute;
  bottom: calc(36px + var(--safe-b));
  left: 0; right: 0;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 0 20px;
  opacity: 0;
  transition: opacity 0.45s ease;
}
.gothel-steal-caption.show { opacity: 1; }
.gothel-steal-scene {
  position: absolute;
  left: 0; top: 22%;
  width: 85%;
  aspect-ratio: 1130 / 1392;
  transform: translateX(-130%);
  transition: transform 1.2s cubic-bezier(.25,.7,.35,1);
}
.gothel-steal-scene.in { transform: translateX(-20%); }
.gothel-steal-arm { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; }
.gothel-steal-fill {
  position: absolute;
  transform: scaleY(0);
  transform-origin: center bottom;
  transition: transform 1.4s cubic-bezier(.22,1,.36,1);
  opacity: 0.9;
  box-shadow: inset 0 -4px 14px rgba(0,0,0,.28), inset 0 6px 18px rgba(255,255,255,.18);
}
.gothel-steal-fill.filled { transform: scaleY(1); }
.gothel-steal-scene.glowing .gothel-steal-arm { animation: stealGlow 0.7s ease-in-out 3; }
@keyframes stealGlow {
  0%,100% { filter: drop-shadow(0 0 8px rgba(180,80,240,.25)); }
  50%      { filter: drop-shadow(0 0 28px rgba(200,80,255,.9)) drop-shadow(0 0 8px rgba(255,200,80,.6)); }
}
/* two ornate streak badges; the count sits in the frame's empty slot */
.res-badges { display: flex; gap: 10px; justify-content: center; align-items: flex-start; width: 100%; margin-top: 2px; }
.res-badge { position: relative; flex: 1 1 0; max-width: 176px; }
.res-badge img { display: block; width: 100%; height: auto; filter: drop-shadow(0 3px 7px rgba(0,0,0,.4)); }
.res-badge.dim { opacity: .5; filter: saturate(.5); }
.res-badge.pop { animation: sbpop .55s cubic-bezier(.2,1.5,.4,1); }
.res-n { position: absolute; left: 72%; top: 44.5%; transform: translate(-50%,-50%); z-index: 2;
  font-family: var(--ff-body); font-weight: 900; font-size: 33px; color: #6a4310; line-height: 1;
  text-shadow: 0 1px 0 rgba(255,250,235,.7); }
/* a reset streak reads red so it's clear it broke */
.res-n.zero { color: #cc2f22; }
.res-tag { position: absolute; top: 4%; right: -2px; z-index: 3; font-family: var(--ff-body); font-weight: 900;
  font-size: 12.5px; padding: 2px 8px; border-radius: 999px; box-shadow: 0 2px 6px rgba(0,0,0,.45);
  animation: sbpop .5s .15s cubic-bezier(.2,1.5,.4,1) backwards; white-space: nowrap; }
.res-tag.gold { background: var(--gold); color: #4a2e00; }
.res-tag.dust { background: #c48bff; color: #2a0f45; }
/* floating "Next Customer" button (baked-text wood plaque) */
/* float the button, centered in the gap between the panel and the screen bottom */
.res-next { align-self: center; width: 92%; max-width: 400px; margin: auto auto; padding: 0; border: none; background: none; cursor: pointer; flex-shrink: 0; }
.res-next img { display: block; width: 100%; height: auto; filter: drop-shadow(0 4px 10px rgba(0,0,0,.55)); }
.res-next:active { transform: scale(.98); }

/* Result-screen reward bubbles — a header that stays put, and bubbles that
   FLOAT freely all over the screen in their own overlay. */
.reward-bubbles { width: 100%; max-width: 320px; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.rb-total { font-weight: 800; font-size: 16px; }
.rb-total #rb-count { font-size: 20px; display: inline-block; }
.rb-total #rb-count.bumped { animation: rbbump .3s ease; }
@keyframes rbbump { 0% { transform: scale(1); } 45% { transform: scale(1.5); color: var(--gold); } 100% { transform: scale(1); } }
.rb-hint { font-size: 12px; }
/* full-screen drifting layer: transparent, only the bubbles catch taps */
.rb-float-layer { position: absolute; inset: 0; z-index: 14; pointer-events: none; overflow: hidden; }
.rbub-wrap { position: absolute; pointer-events: none; will-change: transform;
  animation: rbdrift 6s ease-in-out infinite; }
@keyframes rbdrift {
  0%   { transform: translate(0,0); }
  25%  { transform: translate(var(--dx1,14px), var(--dy1,-12px)); }
  50%  { transform: translate(var(--dx2,-10px), var(--dy2,14px)); }
  75%  { transform: translate(var(--dx3,12px), var(--dy3,10px)); }
  100% { transform: translate(0,0); }
}
.rbub { pointer-events: auto; border: none; cursor: pointer; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-weight: 900; color: #4a2e00; box-shadow: inset 0 3px 8px rgba(255,255,255,.6), 0 4px 12px rgba(0,0,0,.4);
  animation: rbin .4s cubic-bezier(.2,1.4,.4,1) backwards; -webkit-tap-highlight-color: transparent; }
.rbub.big { width: 76px; height: 76px; font-size: 17px;
  background: radial-gradient(circle at 38% 30%, #fff3c0, #ffd23f 55%, #ffab2e); }
.rbub.big .rb-amt { text-shadow: 0 1px 2px rgba(255,255,255,.5); }
.rbub.little { width: 36px; height: 36px; font-size: 17px;
  background: radial-gradient(circle at 38% 30%, #fff3c0, #ffd86b 60%, #f0b53c); }
/* stardust reward bubble — smaller than the big coin, purple, shows its amount */
.rbub.dust { width: 58px; height: 58px; font-size: 14px; color: #2a0f45;
  background: radial-gradient(circle at 38% 30%, #f3e0ff, #c48bff 58%, #9a5be0);
  box-shadow: inset 0 3px 8px rgba(255,255,255,.6), 0 4px 12px rgba(120,60,200,.5), 0 0 12px rgba(196,139,255,.6); }
.rbub.dust .rb-amt { text-shadow: 0 1px 2px rgba(255,255,255,.5); white-space: nowrap; }
/* win-streak bonus — its own medium fiery-gold bubble (mirrors the stardust one) */
.rbub.streak { width: 58px; height: 58px; font-size: 14px; color: #4a2e00;
  background: radial-gradient(circle at 38% 30%, #fff0c4, #ffb04a 56%, #ff7a2e);
  box-shadow: inset 0 3px 8px rgba(255,255,255,.6), 0 4px 12px rgba(220,110,30,.5), 0 0 12px rgba(255,150,60,.65); }
.rbub.streak .rb-amt { text-shadow: 0 1px 2px rgba(255,255,255,.5); white-space: nowrap; }
.rb-total .dust { color: #c48bff; margin-left: 8px; }
.rb-total #rb-dust { font-size: 20px; display: inline-block; }
.rb-total #rb-dust.bumped { animation: rbbump .3s ease; }
.rbub:active { transform: scale(.88); }
.rbub.popped { animation: rbpop .24s ease-out forwards; pointer-events: none; }
@keyframes rbin { 0% { transform: scale(0); } 100% { transform: scale(1); } }
@keyframes rbpop { 0% { transform: scale(1); } 45% { transform: scale(1.35); opacity: .85; } 100% { transform: scale(.2); opacity: 0; } }

/* Perfect celebration: confetti + sparkles */
.confetti-layer { position: absolute; inset: 0; z-index: 59; pointer-events: none; overflow: hidden; }
.confetti { position: absolute; top: -18px; width: 9px; height: 14px; border-radius: 2px; opacity: 0;
  animation: conffall 2s linear forwards; }
@keyframes conffall {
  0% { transform: translateY(-10px) rotate(0deg); opacity: 1; }
  100% { transform: translateY(105vh) translateX(var(--dx,0)) rotate(calc(var(--rot,180deg) * 4)); opacity: .9; }
}
.spk { position: absolute; font-size: 26px; opacity: 0; animation: spktwinkle 1.1s ease-out forwards; }
@keyframes spktwinkle { 0% { transform: scale(.3) rotate(0deg); opacity: 0; } 40% { transform: scale(1.2) rotate(20deg); opacity: 1; } 100% { transform: scale(.6) rotate(-10deg); opacity: 0; } }

/* Toast */
#toast { position: absolute; left: 50%; bottom: 90px; transform: translateX(-50%);
  background: rgba(0,0,0,.8); color: #fff; padding: 10px 16px; border-radius: 12px; font-weight: 700;
  font-size: 14px; opacity: 0; pointer-events: none; transition: opacity .2s; white-space: nowrap; z-index: 20; }
#toast.show { opacity: 1; }
/* On the mixing screen the ingredient tray sits at the bottom, so float charm/infused
   toasts UP near the top (above the cauldron) instead of over the ingredients. */
#screen-mix.active ~ #toast { top: calc(var(--safe-t) + 150px); bottom: auto; }

/* Familiar corner token */
.familiar { position: absolute; right: 14px; bottom: calc(78px + var(--safe-b)); z-index: 15;
  width: 54px; height: 54px; border-radius: 50%; background: var(--card); border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center; font-size: 30px; cursor: pointer; box-shadow: 0 4px 12px rgba(0,0,0,.3); }

/* Landscape nudge */
#rotate { position: fixed; inset: 0; z-index: 50; display: none; align-items: center; justify-content: center;
  flex-direction: column; text-align: center; background: linear-gradient(160deg, #2a1a4a, #150a28); padding: 24px; }
#rotate .e { font-size: 60px; margin-bottom: 14px; }
@media (orientation: landscape) and (max-height: 500px) {
  #rotate { display: flex; } #app { display: none; }
}

/* ==========================================================================
 * COSMETIC CAULDRON SKINS — recolor the pot shell (liquid color is unchanged)
 * ======================================================================== */
.cauldron.skin-cauldron_rose     { border-color: #ffb3c9; background: rgba(255,150,180,.12); box-shadow: inset 0 -8px 20px rgba(0,0,0,.22), 0 0 16px rgba(255,150,180,.35); }
.cauldron.skin-cauldron_emerald  { border-color: #6fe0a0; background: rgba(90,220,150,.12); box-shadow: inset 0 -8px 20px rgba(0,0,0,.22), 0 0 16px rgba(90,220,150,.35); }
.cauldron.skin-cauldron_sapphire { border-color: #7fb0ff; background: rgba(110,150,255,.12); box-shadow: inset 0 -8px 20px rgba(0,0,0,.22), 0 0 16px rgba(110,150,255,.35); }
.cauldron.skin-cauldron_amethyst { border-color: #c48bff; background: rgba(170,110,230,.14); box-shadow: inset 0 -8px 20px rgba(0,0,0,.22), 0 0 16px rgba(170,110,230,.4); }
.cauldron.skin-cauldron_gold     { border-color: #ffd76a; background: rgba(255,200,90,.12); box-shadow: inset 0 -8px 20px rgba(0,0,0,.22), 0 0 20px rgba(255,210,90,.5); }
.cauldron.skin-cauldron_pearlshell { border-color: #ffe9f3;
  background: linear-gradient(140deg, rgba(255,240,250,.20), rgba(200,235,255,.14) 55%, rgba(240,225,255,.18));
  box-shadow: inset 0 -8px 20px rgba(0,0,0,.2), 0 0 20px rgba(255,225,245,.55); }
.cauldron.skin-cauldron_tide     { border-color: #5fd6d0; background: rgba(50,180,190,.14); box-shadow: inset 0 -8px 20px rgba(0,0,0,.24), 0 0 18px rgba(60,190,200,.5); }
.cauldron.skin-cauldron_rainbow  { border-color: transparent;
  background:
    linear-gradient(rgba(40,26,74,.6), rgba(40,26,74,.6)) padding-box,
    conic-gradient(from 0deg, #ff6ea8, #ffd23f, #7ee08a, #6a7bd6, #c48bff, #ff6ea8) border-box;
  box-shadow: inset 0 -8px 20px rgba(0,0,0,.25), 0 0 18px rgba(196,139,255,.45); }
.cauldron.skin-cauldron_glass    { border-color: #cfe6ff;
  background: linear-gradient(160deg, rgba(220,240,255,.20), rgba(150,190,255,.10));
  box-shadow: inset 0 -8px 20px rgba(120,160,220,.25), inset 0 6px 14px rgba(255,255,255,.35), 0 0 22px rgba(180,215,255,.6); }

/* ==========================================================================
 * WISHING WELL
 * ======================================================================== */
.well-visual { position: relative; width: 120px; height: 120px; display: flex; align-items: center; justify-content: center; }
.well-emoji { font-size: 72px; animation: bobfloat 3s ease-in-out infinite; filter: drop-shadow(0 0 14px rgba(255,216,107,.6)); }
@keyframes bobfloat { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
.well-ripple { position: absolute; bottom: 6px; width: 90px; height: 18px; border-radius: 50%;
  background: radial-gradient(ellipse, rgba(255,216,107,.35), transparent 70%); animation: ripplepulse 3s ease-in-out infinite; }
@keyframes ripplepulse { 0%,100% { transform: scale(.8); opacity: .5; } 50% { transform: scale(1.1); opacity: .9; } }
.well-stage { min-height: 96px; width: 100%; max-width: 320px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.well-bubbles { display: flex; gap: 18px; }
.wbub { width: 62px; height: 62px; border: none; border-radius: 50%; cursor: pointer; font-size: 30px;
  background: radial-gradient(circle at 38% 30%, rgba(255,255,255,.9), rgba(150,220,255,.5) 60%, rgba(120,180,240,.35));
  box-shadow: inset 0 3px 8px rgba(255,255,255,.6), 0 4px 12px rgba(0,0,0,.35);
  animation: rbin .4s cubic-bezier(.2,1.4,.4,1) backwards, bobfloat 2.4s ease-in-out infinite; }
.wbub:nth-child(2) { animation-delay: 0s, .3s; } .wbub:nth-child(3) { animation-delay: 0s, .6s; }
.wbub:active { transform: scale(.9); }
.wbub.chosen { animation: rbpop .3s ease-out forwards; }
.wbub.fizz { animation: wfizz .4s ease-out forwards; pointer-events: none; }
@keyframes wfizz { to { transform: translateY(-16px) scale(.4); opacity: 0; } }
.well-prize { display: flex; flex-direction: column; align-items: center; gap: 4px; animation: rbin .45s cubic-bezier(.2,1.5,.4,1); }
.well-prize .wp-emoji { font-size: 58px; }
.well-prize .wp-label { font-weight: 900; font-size: 18px; }
.well-prize.jackpot .wp-emoji { font-size: 68px; animation: charmpop 1s cubic-bezier(.2,1.4,.4,1); }
.well-prize.jackpot .wp-label { color: var(--gold); }

/* --- Wishy's Wishing Well: top-down scene (well_bg), coin drop, rising bubbles --- */
.well-scene { position: relative; flex: 1; min-height: 0; width: 100%; overflow: hidden;
  background: url('../art/well_bg.webp') center 42% / cover no-repeat; }
/* buttons float over the well image (no solid bar) so the whole background shows */
.well-actions { position: absolute; left: 0; right: 0; bottom: 0; z-index: 8;
  padding: 8px 12px calc(8px + var(--safe-b)); gap: 10px; }
.well-actions .btn { box-shadow: 0 4px 14px rgba(0,0,0,.55), 0 0 0 2px rgba(255,255,255,.12); }
/* once Wishy's gone, only Back is in the foot row — centre it at a comfortable width */
.well-actions.solo { justify-content: center; }
.well-actions.solo .btn { flex: 0 1 260px; max-width: 300px; }
/* the Toss button sits on the cobblestones below the well (normal play, no Wishy) */
.well-toss-cobble { position: absolute; left: 50%; bottom: 17%; transform: translateX(-50%); z-index: 7; }
.well-toss-cobble .btn { width: auto; white-space: nowrap; padding: 17px 50px; font-size: 23px; box-shadow: 0 5px 16px rgba(0,0,0,.55), 0 0 0 2px rgba(255,255,255,.2); }
/* invisible anchor over the water hole (bg: centre x50%, ~43% down, radius ~28% of width) */
.well-circle { position: absolute; left: 50%; top: 48%; width: 56%; aspect-ratio: 1;
  transform: translate(-50%, -50%); pointer-events: none; }
/* Wishy floats in the water during the tutorial, his bubble filling the well circle */
.wishy-well { position: absolute; left: 50%; top: 43%; width: 66%; transform: translate(-50%, -50%);
  z-index: 4; animation: wishyBob 3.4s ease-in-out infinite; filter: drop-shadow(0 8px 18px rgba(0,0,0,.5)); }
.wishy-well .wishy-well-img.art { width: 100%; height: auto; max-width: none; display: block; }
.wishy-well.leaving { animation: wishyDive .9s ease-in forwards; }
@keyframes wishyBob { 0%,100% { transform: translate(-50%,-50%); } 50% { transform: translate(-50%, calc(-50% - 10px)); } }
@keyframes wishyDive { 0% { transform: translate(-50%,-50%) scale(1); opacity: 1; }
  100% { transform: translate(-50%, calc(-50% + 66px)) scale(.36); opacity: 0; } }
/* the tossed coin dropping into the water */
.well-coin { position: absolute; left: 50%; top: -8%; width: 26%; transform: translate(-50%, 0);
  z-index: 5; animation: wellCoinDrop .72s cubic-bezier(.5,0,.85,1) forwards; }
.well-coin .well-coin-img.art { width: 100%; height: auto; max-width: none; display: block; filter: drop-shadow(0 4px 8px rgba(0,0,0,.5)); }
@keyframes wellCoinDrop {
  0%   { top: -8%;  transform: translate(-50%, 0) scale(1) rotate(0); opacity: 1; }
  68%  { top: 44%;  transform: translate(-50%, -50%) scale(.66) rotate(230deg); opacity: 1; }
  100% { top: 50%;  transform: translate(-50%, -50%) scale(.24) rotate(340deg); opacity: 0; } }
/* three bubbles rising from the water into a pyramid (one above, two below) over the well */
.well-bubbles2 { position: absolute; inset: 0; z-index: 6; pointer-events: none; }
.wbub2 { position: absolute; left: var(--bl); top: var(--bt);
  width: 27%; aspect-ratio: 1; transform: translate(-50%, -50%); border: none; padding: 0; cursor: pointer;
  border-radius: 50%; pointer-events: auto;
  background: radial-gradient(circle at 36% 30%, rgba(255,255,255,.98), rgba(198,234,255,.82) 38%, rgba(120,184,238,.72) 64%, rgba(78,142,212,.6) 85%, rgba(64,124,196,.42));
  box-shadow: inset 0 -7px 15px rgba(56,114,184,.55), inset 0 5px 13px rgba(255,255,255,.9), 0 5px 14px rgba(0,0,0,.42), 0 0 0 2px rgba(255,255,255,.4), 0 0 16px rgba(150,210,255,.55);
  animation: wbubRise .55s cubic-bezier(.3,1,.5,1) var(--bd) backwards, wbubFloat 2.6s ease-in-out var(--bd) infinite; }
.wbub2-sheen { position: absolute; left: 22%; top: 15%; width: 28%; height: 24%; border-radius: 50%; background: rgba(255,255,255,.92); filter: blur(1px); }
@keyframes wbubRise { 0% { transform: translate(-50%, calc(-50% + 64px)) scale(.3); opacity: 0; } 100% { transform: translate(-50%,-50%) scale(1); opacity: 1; } }
@keyframes wbubFloat { 0%,100% { margin-top: 0; } 50% { margin-top: -7px; } }
.wbub2.chosen { animation: wbubChosen .34s ease-out forwards; z-index: 8; }
.wbub2.fizz { animation: wbubFizz .4s ease-out forwards; pointer-events: none; }
@keyframes wbubChosen { 0% { transform: translate(-50%,-50%) scale(1); } 45% { transform: translate(-50%,-50%) scale(1.4); } 100% { transform: translate(-50%,-50%) scale(0); opacity: 0; } }
@keyframes wbubFizz { to { transform: translate(-50%,-50%) scale(.2); opacity: 0; } }
/* the prize floating up out of the well */
.well-prize2 { position: absolute; left: 50%; top: -11%; transform: translate(-50%,-50%); z-index: 9;
  display: flex; flex-direction: column; align-items: center; text-align: center; width: 84%;
  animation: wellPrizeUp .5s cubic-bezier(.2,1.4,.4,1); }
.well-prize2.fade { opacity: 0; transition: opacity .4s ease; }
.wp2-emoji { font-size: 52px; filter: drop-shadow(0 4px 10px rgba(0,0,0,.55)); }
.wp2-label { font-family: var(--ff-body); font-weight: 900; font-size: 19px; color: #fff; text-shadow: 0 2px 5px rgba(0,0,0,.85); }
.well-prize2.jackpot .wp2-emoji { font-size: 62px; animation: charmpop 1s cubic-bezier(.2,1.4,.4,1); }
.well-prize2.jackpot .wp2-label { color: var(--gold); }
.wp2-sub { font-family: var(--ff-body); font-size: 12px; color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.9); margin-top: 2px; }
@keyframes wellPrizeUp { 0% { transform: translate(-50%, 30%) scale(.4); opacity: 0; } 100% { transform: translate(-50%,-50%) scale(1); opacity: 1; } }
/* Wishy's speech / status line over the stone, plus the top info chips.
   These use the plain body (story-mode) font — easier to read than the display face. */
.well-speech { position: absolute; left: 50%; top: 76px; bottom: auto; transform: translateX(-50%); z-index: 7;
  width: 92%; max-width: 360px; text-align: center; padding: 11px 16px; border-radius: 15px;
  background: rgba(20,12,36,.8); color: #f8f2ff; font-size: 16px; line-height: 1.4; font-weight: 500;
  box-shadow: 0 3px 12px rgba(0,0,0,.45); }
.well-speech b { color: #ffe08a; }
.well-dustchip { position: absolute; left: 50%; top: 10px; transform: translateX(-50%); z-index: 7;
  padding: 6px 18px; border-radius: 999px; background: rgba(20,12,36,.74); color: #f8f2ff;
  font-size: 16px; font-weight: 600; white-space: nowrap; box-shadow: 0 2px 8px rgba(0,0,0,.35); }
.well-dustchip b { color: #ffe08a; font-weight: 800; }
.well-odds-btn { position: absolute; right: 8px; top: 48px; z-index: 7; border: none; cursor: pointer;
  padding: 6px 12px; border-radius: 999px; background: rgba(20,12,36,.68); color: #e6ddf5;
  font-size: 13px; font-weight: 600; }
.well-odds-btn:active { transform: scale(.95); }
.well-odds-modal { position: absolute; inset: 0; z-index: 30; display: flex; align-items: center; justify-content: center;
  background: rgba(6,3,14,.62); animation: fade .2s ease; padding: 20px; }
.wom-card { width: 92%; max-width: 320px; }
/* Home-screen Well button (mirrors Dailies on the right) + its "new!" arrow.
   Extra #app on the selector out-specifies "#screen-start.has-home-bg > *" (which
   would otherwise force position:relative and drop it into the layout flow). */
#app #screen-start .home-well { position: absolute; right: 4px; top: 42%; transform: translateY(-50%); z-index: 3;
  width: 96px; background: none; border: none; padding: 0; cursor: pointer; }
.home-well:active { transform: translateY(-50%) scale(.93); }
.home-well.nudge-well { animation: wellNudge 1.1s ease-in-out infinite; }
@keyframes wellNudge { 0%,100% { transform: translateY(-50%); } 50% { transform: translate(3px, -50%); } }
.well-arrow { position: absolute; left: -30px; top: 40%; font-size: 30px; animation: wellArrow 1s ease-in-out infinite; filter: drop-shadow(0 2px 4px rgba(0,0,0,.6)); }
@keyframes wellArrow { 0%,100% { transform: translateX(0); } 50% { transform: translateX(8px); } }

/* ==========================================================================
 * WARDROBE (My Skins)
 * ======================================================================== */
.skin-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.skin-tile { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 10px 6px;
  border-radius: 14px; background: var(--card2); border: 1px solid var(--line); }
.skin-tile.on { border-color: var(--good); box-shadow: 0 0 10px rgba(126,224,138,.4); }
.skin-tile.locked { opacity: .8; }
.skin-chip { font-size: 34px; line-height: 1; }
.skin-name { font-size: 12px; font-weight: 700; text-align: center; min-height: 28px; display: flex; align-items: center; }
.skin-tag { font-size: 12px; font-weight: 800; padding: 4px 8px; border-radius: 10px; }
.skin-tag.equipped { color: var(--good); }
.skin-tile .btn.small { padding: 5px 10px; font-size: 12px; }

/* ==========================================================================
 * CUSTOM ART OVERRIDES (images dropped into /docs/art/ replace the emoji)
 * Images scale to wherever the emoji was, matching the surrounding font-size.
 * ======================================================================== */
img.art { height: 1em; width: auto; max-width: 1.3em; object-fit: contain;
  vertical-align: -0.16em; -webkit-user-drag: none; user-select: none; }
img.art.cust-big { max-width: none; width: auto; }               /* big character portrait */
.inv-tile .emoji img.art, .slot img.art { max-width: 1.15em; }
.skin-chip img.art.skin-art { height: 34px; width: 34px; max-width: 34px; }
.well-emoji img.art { height: 1em; width: auto; max-width: none; filter: drop-shadow(0 0 14px rgba(255,216,107,.6)); }

/* ---- Skin Shop (wardrobe): satchel-style sections + tap-for-detail tiles ---- */
.ward-purse { text-align: center; font-weight: 800; color: #ffe6a8; margin: 0 8px 8px; font-size: 14px; }
.ward-group { margin-bottom: 16px; }
.ward-group-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 2px 8px; }
.ward-group-name { font-family: var(--ff-display); font-size: 18px; color: #ffe7ac; }
.ward-cycle { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; font-size: 12px; color: #d8c9f5; cursor: pointer;
  background: rgba(16,10,30,.6); border: 1.5px solid rgba(240,200,110,.4); border-radius: 12px; padding: 5px 10px; }
.ward-cycle.on { color: #fff; border-color: var(--good); background: rgba(126,224,138,.18); }
.ward-cycle-box { width: 16px; height: 16px; border-radius: 4px; border: 1.5px solid rgba(240,200,110,.6); display: inline-flex;
  align-items: center; justify-content: center; font-size: 12px; font-weight: 900; color: #0a2a12; }
.ward-cycle.on .ward-cycle-box { background: var(--good); border-color: var(--good); }
.ward-cycle-n { background: rgba(0,0,0,.32); border-radius: 8px; padding: 1px 7px; font-size: 11px; color: #ffd873; }
.ward-empty { text-align: center; color: #cbbde8; font-size: 14px; line-height: 1.4; padding: 24px 16px; }
.ward-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.ward-tile { position: relative; min-width: 0; overflow: hidden; display: flex; flex-direction: column; align-items: center; gap: 3px; cursor: pointer;
  border-radius: 14px; border: 1px solid rgba(255,255,255,.12); padding: 8px 6px 7px;
  background: radial-gradient(circle at 50% 34%, rgba(120,90,180,.18), rgba(40,26,66,.5)); }
.ward-tile:active { transform: scale(.96); }
.ward-tile.on { border-color: var(--good); box-shadow: 0 0 10px rgba(126,224,138,.4); }
.ward-tile.locked .ward-art-wrap { filter: grayscale(.35) brightness(.82); }
.ward-art-wrap { width: 100%; min-width: 0; aspect-ratio: 1; display: flex; align-items: center; justify-content: center; }
.ward-art-wrap img.ward-art { width: 100%; height: 100%; max-width: 100%; object-fit: contain; filter: drop-shadow(0 3px 8px rgba(0,0,0,.45)); }
.ward-art-wrap .art-emoji.ward-art { font-size: 44px; line-height: 1; }
.ward-tile-name { font-size: 11px; font-weight: 700; color: #efe6ff; text-align: center; line-height: 1.12; min-height: 22px;
  display: flex; align-items: center; padding: 0 4px; }
.ward-tag { display: inline-block; margin-top: 1px; font-size: 10px; font-weight: 800; color: #ffd873;
  background: rgba(0,0,0,.5); border-radius: 8px; padding: 2px 8px; }
.ward-star { position: absolute; top: 4px; left: 5px; z-index: 2; width: 26px; height: 26px; border-radius: 50%; cursor: pointer; padding: 0;
  font-size: 16px; line-height: 1; color: #ffd45c; background: rgba(10,6,20,.55); border: 1px solid rgba(255,214,110,.4); }
.ward-star.on { color: #ffce3a; text-shadow: 0 0 8px rgba(255,206,58,.95); }
.ward-check { position: absolute; bottom: 5px; left: 5px; z-index: 2; width: 24px; height: 24px; border-radius: 7px; cursor: pointer; padding: 0;
  font-size: 15px; font-weight: 900; line-height: 1; color: #123; background: rgba(10,6,20,.5); border: 1.5px solid rgba(255,255,255,.5); }
.ward-check.on { background: var(--good); border-color: var(--good); color: #0a2a12; }
/* skin detail overlay */
.skd-overlay { position: fixed; inset: 0; z-index: 96; display: flex; align-items: center; justify-content: center; padding: 24px;
  background: rgba(10,6,20,.74); animation: fade .18s ease; }
.skd-card { width: 100%; max-width: 340px; background: linear-gradient(180deg, rgba(48,30,74,.98), rgba(26,15,46,.98));
  border: 2px solid rgba(240,200,110,.6); border-radius: 20px; box-shadow: 0 12px 30px rgba(0,0,0,.6); padding: 18px 18px 14px;
  display: flex; flex-direction: column; align-items: center; gap: 10px; }
.skd-big { width: 184px; height: 184px; display: flex; align-items: center; justify-content: center; }
.skd-big img.skd-art { width: 100%; height: 100%; max-width: none; object-fit: contain; filter: drop-shadow(0 6px 14px rgba(0,0,0,.5)); }
.skd-big .art-emoji.skd-art { font-size: 110px; line-height: 1; }
.skd-name { font-family: var(--ff-display); font-size: 22px; color: #ffe7ac; text-align: center; }
.skd-desc { font-size: 13px; color: #d9ccf2; text-align: center; line-height: 1.35; }
.skd-fav { font-weight: 800; font-size: 13px; color: #ffd45c; cursor: pointer; background: rgba(16,10,30,.6);
  border: 1.5px solid rgba(255,214,110,.45); border-radius: 12px; padding: 7px 16px; }
.skd-fav.on { color: #123; background: #ffce3a; border-color: #ffce3a; }
.skd-card .btn { width: 100%; max-width: 240px; }
.skd-need { font-size: 13px; font-weight: 700; color: #ffc234; text-align: center; padding: 2px 6px; }
.skd-equipped { font-weight: 800; color: var(--good); font-size: 15px; }
.skd-close { margin-top: 2px; background: none; border: none; color: #b8a6d8; font-weight: 700; font-size: 14px; cursor: pointer; padding: 6px; }

/* custom cauldron-pot image (optional) — replaces the color skin frame */
.cauldron.has-art { border: none !important; background-color: transparent !important;
  background-repeat: no-repeat; background-position: center; background-size: contain; box-shadow: none !important; }

/* custom full-screen background image (optional) */
#app.has-bg { background-size: cover; background-position: center; background-repeat: no-repeat; }
#app.has-bg::before { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(20,10,40,.35), rgba(20,10,40,.55)); }
#app.has-bg > .screen { position: relative; z-index: 1; }
/* Home-screen scene background (art/home_bg.jpg), shown crisp with NO darkening scrim.
   Breaks out of #app's side padding so the art runs edge to edge; padding keeps content inset. */
#screen-start.has-home-bg { position: relative; background-size: cover; background-position: center;
  margin: 0 -14px; padding-left: 14px; padding-right: 14px; }
#screen-start.has-home-bg > * { position: relative; z-index: 1; }
/* Fantasy display font on buttons and headings (body/stat text stays sans) */
.btn, .hud .title, .result-title, .realm-here, .home-build { font-family: var(--ff-display); }
/* ===== Home screen layout (mockup-based, beefed up for mobile) ===== */
#screen-start { position: relative; }
.home-bar { display: flex; align-items: center; gap: 9px; margin: 2px 6px 6px; padding: 7px 9px 7px 7px; border-radius: 22px;
  background: linear-gradient(180deg, rgba(58,38,86,.80), rgba(26,15,46,.88));
  border: 2px solid rgba(240,200,110,.6); box-shadow: 0 3px 12px rgba(0,0,0,.5), inset 0 0 16px rgba(120,80,160,.24); }
/* the home pet is now the shared framed badge in #round-hud; this just reserves its width in the bar */
.home-pet-spacer { width: 118px; height: 1px; flex: 0 0 auto; }
.home-res { display: flex; gap: 8px; flex: 1; }
.res-chip { display: flex; align-items: center; gap: 6px; padding: 8px 14px; border-radius: 15px; color: #fff; font-weight: 700; font-size: 19px;
  font-family: var(--ff-display); background: rgba(16,10,30,.72); border: 1.5px solid rgba(240,200,110,.45); box-shadow: inset 0 1px 3px rgba(0,0,0,.4); }
.res-ic { font-size: 20px; }
.home-gear { flex: 0 0 auto; width: 50px; height: 50px; border-radius: 50%; cursor: pointer; color: #ffdd88; font-size: 25px;
  background: radial-gradient(circle at 50% 35%, #3a2560, #201234); border: 2px solid rgba(240,200,110,.6); box-shadow: 0 0 8px rgba(255,210,110,.4); }
.home-gear:active { transform: scale(.92); }
.home-logo { display: flex; flex-direction: column; align-items: center; }
#screen-start .wp-logo { width: 100%; max-width: 448px; }
#screen-start .logo-stage { padding: 4px 0 4px; }
.home-play { position: relative; align-self: center; width: 84%; max-width: 348px; margin: 0 auto 42px; padding: 0; border: none; background: none; cursor: pointer; }
.home-play-bg { display: block; width: 100%; height: auto; animation: playPulse 1.6s ease-in-out infinite; }
@keyframes playPulse {
  0%, 100% { filter: drop-shadow(0 6px 14px rgba(0,0,0,.6)) drop-shadow(0 0 5px rgba(255,206,110,.45)); }
  50%      { filter: drop-shadow(0 6px 14px rgba(0,0,0,.6)) drop-shadow(0 0 20px rgba(255,214,120,.95)); }
}
@media (prefers-reduced-motion: reduce) { .home-play-bg { animation: none; filter: drop-shadow(0 6px 14px rgba(0,0,0,.6)); } }
.home-play-lbl { position: absolute; left: 0; right: 0; top: 56%; transform: translateY(-50%); text-align: center;
  font-family: var(--ff-display); font-weight: 700; font-size: 52px; letter-spacing: 1px; color: #fff;
  text-shadow: 0 3px 6px rgba(0,10,40,.75), 0 0 4px rgba(30,80,160,.9); }
.home-play:active { transform: scale(.97); }
.home-nav { display: flex; justify-content: space-between; align-items: flex-end; gap: 5px; padding: 6px 2px 0; }
.home-nav-btn { position: relative; flex: 1; min-width: 0; display: block; background: none; border: none; padding: 0; cursor: pointer; }
.nav-badge { display: block; width: 100%; height: auto; filter: drop-shadow(0 3px 8px rgba(0,0,0,.5)); }
.home-nav-btn .nav-badge { width: 87%; margin: 0 auto; }   /* the four bottom icons a touch smaller */
/* little count tag on a nav badge (e.g. active quests on the Satchel) */
.nav-count { position: absolute; top: 0; right: 6px; z-index: 3; min-width: 22px; height: 22px; padding: 0 5px; border-radius: 11px;
  background: #e0455a; color: #fff; font-size: 13px; font-weight: 800; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 3px rgba(0,0,0,.55); border: 2px solid #fff; }
.home-nav-btn:active { transform: scale(.92); }
/* round corner badges (Dailies / Well) */
.corner-badge { display: block; width: 100%; height: auto; filter: drop-shadow(0 3px 8px rgba(0,0,0,.5)); }
/* hover micro-interaction: home buttons grow a touch and glow golden */
.home-nav-btn .nav-badge, .home-daily .corner-badge, .home-well .corner-badge { transition: transform .16s ease, filter .16s ease; }
.home-play { transition: transform .16s ease; }
@media (hover: hover) {
  .home-nav-btn:hover .nav-badge, .home-daily:hover .corner-badge, .home-well:hover .corner-badge {
    transform: scale(1.1);
    filter: drop-shadow(0 4px 9px rgba(0,0,0,.5)) drop-shadow(0 0 13px rgba(255,214,120,.95));
  }
  .home-play:hover { transform: scale(1.04); }
}
/* Left-side Dailies plaque (opens the quests screen). The #screen-start prefix
   raises specificity so it beats the `.has-home-bg > *` position override. */
#screen-start .home-daily { position: absolute; left: 4px; top: 42%; transform: translateY(-50%); z-index: 3;
  width: 96px; background: none; border: none; padding: 0; cursor: pointer; }
.home-daily:active { transform: translateY(-50%) scale(.93); }
.daily-badge { position: absolute; top: 6px; right: 6px; z-index: 2; min-width: 24px; height: 24px; padding: 0 6px; border-radius: 12px;
  background: #e0455a; color: #fff; font-size: 14px; font-weight: 800; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 3px rgba(0,0,0,.55); border: 2px solid #fff; }
.home-build { text-align: center; font-size: 10px; color: rgba(255,255,255,.42); margin-top: 2px; }
/* ===== Customer screen (mockup-based, big character in an arched frame) ===== */
/* Customer screen: full-bleed, edge-to-edge scene image (uses the mg-full mechanism
   so #app padding is dropped while this screen is up). The image + scrim sit behind
   the customer cards, which stay above via z-index. */
#screen-customer { position: relative; }
.cust-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; background-size: cover; background-position: center; }
.cust-bg.has-realm-bg::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(24,14,40,.62) 0%, rgba(24,14,40,.34) 22%, rgba(24,14,40,.40) 60%, rgba(24,14,40,.72) 100%); }
#screen-customer > *:not(.cust-bg) { position: relative; z-index: 1; }
.cust-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 2px 6px 2px; }
/* arrival/result top bar with only the ☰ menu (top-right), matching the round screens */
.cust-top-menu { justify-content: flex-end; margin-top: calc(var(--safe-t) + 6px); position: relative; z-index: 20; }
.cust-menu { width: 40px; height: 40px; border-radius: 11px; font-size: 20px; color: #ffe6b0; flex: 0 0 auto;
  background: rgba(50,24,72,.7); border: 1.5px solid rgba(255,214,110,.55); cursor: pointer; }
.cust-menu:active { transform: scale(.92); }
.cust-realm { display: flex; align-items: center; gap: 5px; padding: 5px 12px; border-radius: 14px; font-family: var(--ff-display); font-size: 14px; color: #ffe6a8;
  background: linear-gradient(180deg, rgba(58,38,86,.85), rgba(26,15,46,.9)); border: 2px solid rgba(240,200,110,.6); box-shadow: 0 2px 8px rgba(0,0,0,.45); }
.cust-coin { display: flex; align-items: center; gap: 6px; padding: 3px 14px 3px 4px; border-radius: 16px; font-family: var(--ff-body); font-weight: 700; font-size: 18px; color: #fff;
  background: linear-gradient(180deg, rgba(58,38,86,.85), rgba(26,15,46,.9)); border: 2px solid rgba(240,200,110,.6); box-shadow: 0 2px 8px rgba(0,0,0,.45); }
.cust-coin img { height: 30px; width: auto; }
.cust-wallet { display: flex; align-items: center; gap: 6px; }
.cust-coin.pearls { padding: 3px 12px; border-color: rgba(150,210,255,.7); background: linear-gradient(180deg, rgba(40,60,96,.9), rgba(20,34,60,.92)); }
.pay-alt { white-space: nowrap; display: inline-flex; align-items: center; gap: 4px; }
.res-chip.pearls { color: #d8ecff; }
.cust-badge.pearl { background: radial-gradient(circle at 38% 32%, #eaf6ff, #6fb6e6 80%); border-color: #cfeaff; }
/* a glossy iridescent pearl, drawn in CSS — sizes with the surrounding font */
.pearl-ic { display: inline-block; width: 1em; height: 1em; border-radius: 50%; vertical-align: -0.14em; flex: none;
  background: radial-gradient(circle at 34% 28%, #ffffff 0%, #fdf3fb 24%, #f0dcf3 50%, #d3bce6 76%, #bb9ee0 100%);
  box-shadow: inset -0.12em -0.15em 0.22em rgba(120,80,160,.5), inset 0.09em 0.09em 0.16em rgba(255,255,255,.85), 0 0.04em 0.12em rgba(0,0,0,.35); }
.cust-badge.pearl .pearl-ic { width: 30px; height: 30px; }
.badge-modal-ic .pearl-ic { width: 46px; height: 46px; }
/* --- Item reveal: the "!" bubble that waits on screen, + the big glowing reveal --- */
/* The waiting "!" bubble floats dead-center of the play column (anchored to #app's
   centered box, not the raw viewport, so it stays on-screen on wide tablets too). */
.item-bubble { position: fixed; left: 50%; top: 50%; z-index: 82; width: 76px; height: 76px; border-radius: 50%; border: 3px solid #fff2c8; cursor: pointer; padding: 0;
  background: radial-gradient(circle at 38% 30%, #fff7da, #ffcf5a 58%, #ef9328); color: #7a3d08;
  box-shadow: 0 6px 18px rgba(0,0,0,.5), 0 0 22px rgba(255,200,90,.8); display: flex; align-items: center; justify-content: center;
  transform: translate(-50%, -50%); animation: ibBob 1.6s ease-in-out infinite; animation-delay: var(--ib-delay, 0s); }
/* Multi-drop (e.g. the Wolf's three buttons): a smaller bubble per item, fanned into a row,
   each showing that item's own art instead of a "!". */
.item-bubble.multi { width: 66px; height: 66px; }
.item-bubble .ib-art { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
.item-bubble .ib-art-img { width: 66%; height: 66%; object-fit: contain; filter: drop-shadow(0 1px 2px rgba(0,0,0,.4)); font-size: 30px; }
.item-bubble .ib-bang { font-family: var(--ff-display); font-weight: 900; font-size: 46px; line-height: 1; text-shadow: 0 1px 2px rgba(255,255,255,.55); }
.item-bubble .ib-count { position: absolute; right: -5px; top: -5px; min-width: 22px; height: 22px; padding: 0 5px; border-radius: 11px;
  background: #ff5a5a; border: 2px solid #fff; color: #fff; font-size: 13px; font-weight: 800; display: flex; align-items: center; justify-content: center; }
.item-bubble:active { animation: none; transform: translate(-50%, -50%) scale(.92); }
@keyframes ibBob { 0%,100% { transform: translate(-50%, -50%); } 50% { transform: translate(-50%, calc(-50% - 7px)); } }
/* When the player tries to move on without collecting it, the bubble swells big. */
.item-bubble.nudge { animation: ibNudge .6s ease; }
@keyframes ibNudge { 0% { transform: translate(-50%,-50%) scale(1); } 30% { transform: translate(-50%,-50%) scale(1.55); }
  55% { transform: translate(-50%,-50%) scale(.95); } 100% { transform: translate(-50%,-50%) scale(1); } }
.item-reveal-overlay { position: fixed; inset: 0; z-index: 90; display: flex; align-items: center; justify-content: center; padding: 26px;
  background: radial-gradient(circle at 50% 42%, rgba(24,14,44,.9), rgba(8,4,16,.97)); animation: fade .25s ease; }
.item-reveal-overlay.closing { animation: fade .2s ease reverse forwards; }
.ir-card { position: relative; width: 92%; max-width: 340px; display: flex; flex-direction: column; align-items: center; text-align: center;
  animation: irPop .42s cubic-bezier(.2,1.5,.4,1); }
.ir-burst { position: absolute; top: 2%; width: 360px; height: 360px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(255,236,170,.85) 0%, rgba(255,214,120,.4) 30%, transparent 66%); animation: irGlow 2.2s ease-in-out infinite; }
.ir-sparkles { position: absolute; top: 2%; width: 360px; height: 360px; pointer-events: none; }
.ir-sparkles i { position: absolute; left: 50%; top: 50%; width: 10px; height: 10px; margin: -5px; border-radius: 50%; background: #fff6cf;
  box-shadow: 0 0 8px #ffe08a; animation: irTwinkle 1.7s ease-in-out infinite; animation-delay: calc(var(--i) * .12s); }
/* Bigger art so the piece can be properly admired */
.ir-art { position: relative; z-index: 2; height: 288px; display: flex; align-items: center; justify-content: center; animation: irFloat 2.4s ease-in-out infinite; }
/* Only a soft depth shadow — NO silhouette glow. A glow that hugs the alpha edge
   traces a rectangle on tightly-cropped items (the sheep); the radial burst behind
   already supplies the golden halo. */
.ir-art .ir-img.art { height: 288px; width: auto; max-width: 88vw; filter: drop-shadow(0 10px 22px rgba(0,0,0,.55)); }
.ir-art .ir-emoji { font-size: 160px; filter: drop-shadow(0 8px 16px rgba(0,0,0,.5)); }
.ir-x { position: absolute; right: 4%; bottom: 6%; z-index: 3; font-family: var(--ff-body); font-weight: 900; font-size: 34px; color: #fff; text-shadow: 0 2px 4px rgba(0,0,0,.75); }
.ir-name { position: relative; z-index: 2; margin-top: 6px; font-family: var(--ff-display); font-size: 30px; color: #fff2c8; text-shadow: 0 2px 6px rgba(0,0,0,.7); }
.ir-desc { position: relative; z-index: 2; margin-top: 8px; max-width: 300px; font-family: var(--ff-read); font-size: 16px; line-height: 1.4; color: #ece0ff; }
.ir-add { position: relative; z-index: 2; margin-top: 20px; padding: 12px 30px; border-radius: 26px; border: 2px solid #7a4e1a; cursor: pointer;
  background: linear-gradient(180deg, #f7d488, #d49a3a); color: #4a2c08; font-family: var(--ff-display); font-size: 20px; box-shadow: 0 4px 12px rgba(0,0,0,.5); }
.ir-add:active { transform: scale(.96); }
/* Unified new-skin reward overlay — reuses the item-reveal burst/sparkles/card. A big picture of
   the earned skin, a kicker banner, and two choices (equip now / add to collection). */
.sr-kicker { position: relative; z-index: 2; font-family: var(--ff-display); font-size: 21px; letter-spacing: .5px;
  color: var(--gold, #ffd76a); text-shadow: 0 2px 6px rgba(0,0,0,.7); margin-bottom: 2px; }
.sr-img-wrap { position: relative; z-index: 2; height: 262px; display: flex; align-items: center; justify-content: center;
  animation: irFloat 2.4s ease-in-out infinite; }
.sr-img-wrap .sr-img.art { height: 262px; width: auto; max-width: 88vw; filter: drop-shadow(0 10px 22px rgba(0,0,0,.55)); }
.sr-img-wrap .sr-img.art-emoji { font-size: 150px; line-height: 1; filter: drop-shadow(0 8px 16px rgba(0,0,0,.5)); }
.sr-name { margin-top: 4px; }
.sr-btns { position: relative; z-index: 2; margin-top: 22px; display: flex; flex-direction: column; gap: 10px; width: 100%; max-width: 264px; }
.sr-btns .btn { width: 100%; margin: 0; }
@keyframes irPop { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: scale(1); } }
@keyframes irGlow { 0%,100% { transform: scale(.92); opacity: .82; } 50% { transform: scale(1.08); opacity: 1; } }
@keyframes irFloat { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
@keyframes irTwinkle { 0%,100% { opacity: .2; transform: rotate(calc(var(--i)*36deg)) translateY(-128px) scale(.6); } 50% { opacity: 1; transform: rotate(calc(var(--i)*36deg)) translateY(-140px) scale(1.2); } }
/* --- Inventory (Satchel): big-icon grid, grouped by quest --- */
.inv-screen { display: flex; flex-direction: column; gap: 14px; }
.inv-purse { width: 100%; margin: 0 0 14px; padding: 10px 14px; border-radius: 14px; cursor: pointer;
  border: 2px solid rgba(210,230,255,.45); background: linear-gradient(180deg, rgba(210,235,255,.14), rgba(180,215,255,.08));
  color: var(--ink, #f3ecff); font-family: var(--ff-display); font-size: 17px; display: flex; align-items: center; gap: 8px;
  box-shadow: 0 2px 10px rgba(0,0,0,.22); }
.inv-purse b { font-size: 20px; }
.inv-purse .muted { font-size: 12px; font-family: inherit; font-weight: 600; margin-left: auto; }
.inv-purse:active { transform: scale(.98); }
.inv-group { border-radius: 16px; }
.inv-group.quest { border: 2px solid rgba(255,214,120,.5); background: rgba(255,222,150,.06); padding: 8px 10px 12px; box-shadow: 0 2px 10px rgba(0,0,0,.25); }
.inv-group.story { border: none; padding: 2px 2px 4px; }
.inv-group-head { display: flex; align-items: center; justify-content: space-between; margin: 0 2px 8px; }
.inv-group-name { font-family: var(--ff-display); font-size: 18px; color: #ffe7ac; }
.inv-group.story .inv-group-name { color: #d3c4f2; }
.inv-group-count { font-family: var(--ff-body); font-weight: 800; font-size: 15px; color: #ffd873; background: rgba(0,0,0,.28); border-radius: 10px; padding: 2px 10px; }
.inv-items { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.inv-item { position: relative; aspect-ratio: 1; border-radius: 14px; border: 1px solid rgba(255,255,255,.12); cursor: pointer; padding: 6px;
  background: radial-gradient(circle at 50% 38%, rgba(255,255,255,.1), rgba(255,255,255,.03)); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.inv-group.story .inv-item { background: radial-gradient(circle at 50% 38%, rgba(180,160,230,.16), rgba(120,100,180,.05)); border-color: rgba(200,180,240,.22); }
.inv-item:active { transform: scale(.95); }
.inv-item .inv-art.art { width: 92%; height: 92%; max-width: none; object-fit: contain; filter: drop-shadow(0 3px 8px rgba(0,0,0,.4)); }
.inv-item .inv-emoji { font-size: 52px; line-height: 1; filter: drop-shadow(0 2px 5px rgba(0,0,0,.4)); }
.inv-empty { text-align: center; color: var(--muted); padding: 40px 20px; }
.inv-empty-ic { font-size: 64px; opacity: .5; margin-bottom: 12px; }
.inv-empty p { font-size: 14px; line-height: 1.5; max-width: 280px; margin: 0 auto; }
/* quest-info overlay (tap an item) */
.invq-overlay { position: fixed; inset: 0; z-index: 90; display: flex; align-items: center; justify-content: center; padding: 26px;
  background: rgba(12,6,24,.8); animation: fade .2s ease; }
.invq-card { position: relative; width: 94%; max-width: 350px; padding: 24px 28px 22px; text-align: center;
  background: url('../art/ui/name_plate.png') no-repeat center; background-size: 100% 100%; animation: irPop .3s cubic-bezier(.2,1.4,.4,1); }
.invq-kind { font-family: var(--ff-display); font-size: 13px; letter-spacing: 1px; color: #b5842a; margin-bottom: 4px; }
.invq-kind.story { color: #8a5ab0; }
.invq-title { font-family: var(--ff-display); font-size: 25px; color: #7a3410; margin-bottom: 8px; }
.invq-desc { font-family: var(--ff-read); font-size: 16px; line-height: 1.42; color: #4a3212; }
.invq-collection { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; margin: 14px 2px 2px; }
.invq-slot { aspect-ratio: 1; border-radius: 10px; display: flex; align-items: center; justify-content: center; overflow: hidden; background: rgba(90,60,20,.14); border: 1px solid rgba(90,60,20,.2); }
.invq-slot.got { background: rgba(120,80,30,.22); border-color: rgba(150,100,40,.4); }
.invq-slot .invq-slot-img.art { width: 88%; height: 88%; max-width: none; object-fit: contain; }
.invq-q { font-family: var(--ff-display); font-weight: 800; font-size: 18px; color: rgba(90,60,20,.4); }
.invq-progress { margin-top: 14px; font-family: var(--ff-read); font-size: 15px; line-height: 1.4; color: #6a4310; font-weight: 700; }
.invq-ok { margin-top: 16px; padding: 10px 30px; border-radius: 22px; border: 2px solid #7a4e1a; cursor: pointer;
  background: linear-gradient(180deg, #f7d488, #d49a3a); color: #4a2c08; font-family: var(--ff-display); font-size: 18px; }
.invq-ok:active { transform: scale(.96); }
.cust-banner { position: relative; width: 96%; max-width: 372px; margin: 0 auto -52px; z-index: 5; }
.cust-banner img { display: block; width: 100%; height: auto; filter: drop-shadow(0 4px 8px rgba(0,0,0,.5)); }
.cust-banner span { position: absolute; left: 8%; right: 8%; top: 46%; transform: translateY(-50%); text-align: center;
  font-family: var(--ff-display); font-size: 25px; color: #ffedc0; text-shadow: 0 2px 3px rgba(60,20,10,.8); line-height: 1; }
.cust-notice { max-width: 350px; text-align: center; font-size: 12.5px; font-weight: 700; color: #fff; padding: 5px 12px; border-radius: 12px; margin: 0 8px;
  background: rgba(30,18,50,.7); border: 1px solid rgba(240,200,110,.4); }
.cust-notice.boss { color: #ffd76a; } .cust-notice.rush { color: #ff9a5a; } .cust-notice.vip { color: #ffe08a; }
.cust-banner, .cust-portrait, .cust-nameplate, .cust-wishbox, .cust-bottombar { flex-shrink: 0; }
/* BIG character in a clean soft-box portrait (no ornate frame) — the character
   sits in a rounded window with a warm edge that fades into the nameplate below. */
.cust-portrait { position: relative; width: 90%; max-width: 400px; margin: 0 auto -56px; z-index: 1; }
.cust-char { position: relative; width: 100%; aspect-ratio: 0.92; margin: 0 auto; z-index: 1; overflow: hidden;
  border-radius: 26px; border: 3px solid rgba(255,220,150,.5); box-shadow: 0 14px 34px rgba(0,0,0,.55);
  display: flex; align-items: flex-start; justify-content: center; }
.cust-char img.art { height: calc(120% * var(--char-scale, 1)); width: auto; max-width: none; margin-top: calc(3% + var(--char-y, 0%)); transform: translateX(var(--char-x, 0%)); filter: drop-shadow(0 4px 10px rgba(0,0,0,.4)); }
.cust-char .art-emoji { position: absolute; top: 49%; left: 50%; transform: translate(-50%, -50%); margin: 0;
  font-size: 168px; line-height: 1; filter: drop-shadow(0 4px 8px rgba(0,0,0,.4)); }
/* soft fade at the bottom so the portrait crop blends into the nameplate */
.cust-char::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 22%; z-index: 3;
  pointer-events: none; background: linear-gradient(180deg, transparent, rgba(16,9,26,.55)); }
/* balloon customer (Frog Prince allergic): show the whole round frog, smaller, gently floating */
.cust-char.balloon-cust { align-items: center; overflow: visible; }
.cust-char.balloon-cust img.art { height: auto; max-height: 80%; max-width: 84%; width: auto;
  margin-top: 0; animation: custBalloon 3s ease-in-out infinite; }
.cust-char.balloon-cust::after { display: none; }
@keyframes custBalloon { 0%, 100% { transform: translateY(5px); } 50% { transform: translateY(-7px); } }
/* floating customer (Enchanted Portrait): whole portrait shown inside the normal
   character frame, sized to fit with headroom so it stays fully visible as it
   gently hovers up & down. */
.cust-char.float-cust { align-items: center; }
.cust-char.float-cust img.art { height: auto; max-height: 68%; max-width: 76%; width: auto;
  margin-top: 0; animation: custHover 3.2s ease-in-out infinite; }
.cust-char.float-cust::after { display: none; }
@keyframes custHover { 0%, 100% { transform: translateY(-6px); } 50% { transform: translateY(6px); } }
.cust-frame { display: none; }
/* purple name plaque below the arch — holds the customer NAME. The plaque is long
   and slim so it fits longer names without crowding. */
.cust-nameplate { position: relative; width: 92%; max-width: 384px; margin: 0 auto 0; z-index: 4; }
.cust-nameplate img { display: block; width: 100%; height: auto; filter: drop-shadow(0 3px 7px rgba(0,0,0,.5)); }
.cust-name { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 0 13%;
  font-family: var(--ff-display); font-size: 24px; color: #fff2d0; text-shadow: 0 2px 3px rgba(30,10,50,.8);
  white-space: nowrap; overflow: hidden; }
.cust-streak { position: absolute; top: 70px; right: 12px; z-index: 6; padding: 3px 10px; border-radius: 12px; font-weight: 800; font-size: 14px; color: #fff;
  background: linear-gradient(90deg,#ff8a3a,#ff5a5a); box-shadow: 0 1px 4px rgba(0,0,0,.5); }
/* flat parchment plate = the WISH box (name_plate.png stretched behind the text) */
.cust-wishbox { position: relative; width: 97%; max-width: 396px; margin: -26px auto 0; padding: 26px 32px 10px;
  z-index: 3; background: url('../art/ui/name_plate.png') no-repeat center; background-size: 100% 100%; }
/* FIXED height so short and longer (paginated) lines take the same space and
   never push the stat bar below out of view — the box stays put, no scrolling */
.cust-wish-text { display: flex; align-items: center; justify-content: center; height: 102px; overflow: hidden;
  text-align: center; font-family: 'Georgia', serif; font-size: 19px; line-height: 1.3; font-style: italic; color: #4a3212; }
/* paginated wish: leave room for the ▸ arrow, which reveals the next line */
.cust-wishbox.has-next { padding-right: 46px; }
.wish-next { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); z-index: 6;
  width: 36px; height: 36px; border-radius: 50%; border: 2px solid #7a4e1a; cursor: pointer;
  background: linear-gradient(180deg, #f7d488, #d49a3a); color: #4a2c08; font-size: 20px; font-weight: 900; line-height: 1;
  box-shadow: 0 2px 7px rgba(0,0,0,.45); display: flex; align-items: center; justify-content: center;
  animation: wishPulse 1.25s ease-in-out infinite; }
.wish-next:active { transform: translateY(-50%) scale(.94); }
@keyframes wishPulse { 0%,100% { transform: translateY(-50%) scale(1); } 50% { transform: translateY(-50%) scale(1.14); } }
@keyframes wishFade { from { opacity: .15; } to { opacity: 1; } }
@keyframes wishNudge { 0%,100% { transform: translateY(-50%) scale(1); } 25% { transform: translateY(-50%) scale(1.28); } 60% { transform: translateY(-50%) scale(1.28); } }
.cust-char.swap img.art { animation: wishFade .3s ease; }
.cust-wish-extra { margin-top: 6px; text-align: center; font-family: var(--ff-read); font-size: 13.5px; line-height: 1.22; color: #6a4310; }
.cust-wish-extra.boss { color: #9a3410; } .cust-wish-extra.rush { color: #a85410; } .cust-wish-extra.vip { color: #7a5210; }
/* --- special-customer badge bubbles (beside the portrait) + info overlay --- */
.cust-badges { position: absolute; left: -3px; top: 25%; z-index: 8; display: flex; flex-direction: column; gap: 10px; }
.cust-badge { position: relative; width: 56px; height: 56px; border-radius: 50%; border: 3px solid #ffe6a0; cursor: pointer; padding: 0;
  display: flex; align-items: center; justify-content: center; font-size: 27px; line-height: 1;
  background: radial-gradient(circle at 38% 32%, #fff7e0, #f0b64a 80%);
  box-shadow: 0 3px 11px rgba(0,0,0,.5), inset 0 0 0 2px rgba(255,255,255,.35);
  animation: badgeBob 2.1s ease-in-out infinite; }
.cust-badge.boss { background: radial-gradient(circle at 38% 32%, #fff0c0, #e0912a 80%); }
.cust-badge.rush { background: radial-gradient(circle at 38% 32%, #ffe1c2, #e06a2a 80%); border-color: #ffd2a6; }
.cust-badge:active { transform: scale(.92); }
/* little "tap me" dot so she knows it's interactive */
.cust-badge::after { content: ""; position: absolute; right: -2px; top: -2px; width: 15px; height: 15px; border-radius: 50%;
  background: #ff5a5a; border: 2px solid #fff; box-shadow: 0 1px 3px rgba(0,0,0,.45); animation: badgePing 1.6s ease-in-out infinite; }
@keyframes badgeBob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
@keyframes badgePing { 0%,100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.28); opacity: .65; } }
#screen-customer .badge-overlay { position: absolute; inset: 0; z-index: 45; display: flex; align-items: center; justify-content: center;
  padding: 26px; background: rgba(12,5,26,.72); animation: fade .18s ease; }
#screen-customer .badge-overlay.hidden { display: none; }
.badge-modal { position: relative; width: 90%; max-width: 332px; padding: 30px 32px 26px; text-align: center;
  background: url('../art/ui/name_plate.png') no-repeat center; background-size: 100% 100%; animation: pop .22s ease; }
.badge-modal-ic { font-size: 50px; line-height: 1; margin-bottom: 2px; filter: drop-shadow(0 3px 5px rgba(0,0,0,.35)); }
.badge-modal-title { font-family: var(--ff-display); font-size: 25px; color: #7a3410; margin-bottom: 8px; }
.badge-modal-text { font-family: var(--ff-read); font-size: 17px; line-height: 1.42; color: #4a3212; }
.badge-modal-ok { margin-top: 16px; padding: 9px 28px; border-radius: 22px; border: 2px solid #7a4e1a; cursor: pointer;
  background: linear-gradient(180deg, #f7d488, #d49a3a); color: #4a2c08; font-family: var(--ff-display); font-size: 18px; }
.badge-modal-ok:active { transform: scale(.96); }
/* stat banner — Payment · Target · Allergy — on a parchment plate like the wish box */
.cust-bottombar { display: flex; align-items: center; justify-content: space-around; gap: 4px;
  width: 97%; max-width: 396px; margin: 9px auto 0; padding: 6px 16px;
  background: url('../art/ui/name_plate.png') no-repeat center; background-size: 100% 100%; }
/* icon + value side by side (one row) so the box stays short */
.bcell { position: relative; flex: 1; min-width: 0; display: flex; flex-direction: row; align-items: center; justify-content: center; gap: 6px; text-align: center; cursor: help; }
.bic { height: 34px; width: auto; flex-shrink: 0; filter: drop-shadow(0 2px 3px rgba(0,0,0,.35)); }
.bval { font-family: var(--ff-body); font-weight: 700; font-size: 23px; color: #3a2408; line-height: 1; white-space: nowrap; }
/* hover (desktop) or tap-and-hold (mobile, via .tip-on) shows the label as a little tooltip */
.bcell::after, .bcell::before { position: absolute; left: 50%; z-index: 12; opacity: 0; pointer-events: none; transition: opacity .12s ease; }
.bcell::after { content: attr(data-tip); bottom: calc(100% + 8px); transform: translateX(-50%); white-space: nowrap;
  background: rgba(22,13,32,.95); color: #ffeccb; font-family: var(--ff-read); font-size: 14.5px; letter-spacing: .2px;
  padding: 5px 13px; border-radius: 10px; border: 1px solid rgba(255,255,255,.16); box-shadow: 0 5px 14px rgba(0,0,0,.55); }
.bcell::before { content: ""; bottom: calc(100% + 2px); transform: translateX(-50%); border: 6px solid transparent; border-top-color: rgba(22,13,32,.95); }
.bcell:hover::after, .bcell:hover::before, .bcell.tip-on::after, .bcell.tip-on::before { opacity: 1; }
.amark { font-weight: 800; font-size: 26px; line-height: 1; letter-spacing: 2px; }
.amark.ok { color: #2e8b3d; } .amark.x { color: #b23b2e; }
/* Start Scoop matches the results screen's Next Customer button: same width and
   floating placement, so the two screens flow into each other seamlessly. */
.cust-scoop { position: relative; align-self: center; width: 92%; max-width: 400px; margin: auto auto; padding: 0; border: none; background: none; cursor: pointer; flex-shrink: 0; }
.cust-scoop img { display: block; width: 100%; height: auto; filter: drop-shadow(0 4px 10px rgba(0,0,0,.55)); }
/* locked until the customer has finished speaking (multi-part wishes) */
.cust-scoop.locked img { filter: grayscale(.9) brightness(.72) drop-shadow(0 4px 10px rgba(0,0,0,.5)); }
.cust-scoop.locked { cursor: not-allowed; }
.cust-scoop.locked span { opacity: .6; }
.cust-scoop span { position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%); text-align: center;
  font-family: var(--ff-display); font-size: 30px; color: #fff8e0; text-shadow: 0 2px 4px rgba(20,40,10,.8); }
.cust-scoop:active { transform: scale(.98); }
.cust-scoop.wager { width: 58%; max-width: 214px; margin-top: 0; }
.cust-scoop.wager span { font-size: 18px; }
.cust-scoop-alt { align-self: center; margin: 1px auto 0; background: none; border: none; color: #ffe6a8; font-family: var(--ff-display); font-size: 14px; text-decoration: underline; cursor: pointer; }
/* VIP wager overlay — a dark scrim over the whole customer UI with the choice.
   Scoped to #screen-customer so it beats the .has-realm-bg > * position:relative rule. */
#screen-customer .vip-overlay { position: absolute; inset: 0; z-index: 40; display: flex; align-items: center; justify-content: center;
  padding: 22px; background: rgba(12,5,26,.72); animation: fade .2s ease; }
.vip-modal { width: 94%; max-width: 360px; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.vipo-banner { width: 100%; max-width: 332px; }
.vipo-banner img { display: block; width: 100%; height: auto; filter: drop-shadow(0 6px 14px rgba(0,0,0,.7)); }
.vip-panel { width: 98%; max-width: 360px; padding: 26px 32px 30px;
  background: url('../art/ui/name_plate.png') no-repeat center; background-size: 100% 100%; }
.vip-panel-text { text-align: center; font-family: var(--ff-read); font-size: 18px; line-height: 1.42; color: #4a3212; }
.vip-panel-text b { color: #7a3410; }
.vip-yes { position: relative; width: 76%; max-width: 292px; margin-top: 2px; padding: 0; border: none; background: none; cursor: pointer; }
.vip-yes img { display: block; width: 100%; height: auto; filter: drop-shadow(0 5px 12px rgba(0,0,0,.6)); }
.vip-yes span { position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%); text-align: center;
  font-family: var(--ff-display); font-size: 21px; color: #fff8e0; text-shadow: 0 2px 4px rgba(20,40,10,.85); }
.vip-yes:active { transform: scale(.98); }
.vip-no { background: none; border: none; color: #ffe6a8; font-family: var(--ff-display); font-size: 16px; text-decoration: underline; cursor: pointer; padding: 5px 8px; }

/* --- custom BUBBLE images (pop phase + scoop). Class sits on the container so
   current and future bubbles are covered without rewiring. --- */
.bubble-field.has-bubble-art .pbubble:not(.bonus) {
  background-image: var(--bubble-img); background-size: cover; background-position: center; background-repeat: no-repeat;
  border-color: transparent; box-shadow: none; }
.bubble-field.has-bubble-art .pbubble:not(.bonus) .sheen,
.bubble-field.has-bubble-art .pbubble:not(.bonus) .bglyph { display: none; }
.bubble-field.has-bonus-art .pbubble.bonus {
  background-image: var(--bubble-bonus-img); background-size: cover; background-position: center; background-repeat: no-repeat; }
.bubble-field.has-bonus-art .pbubble.bonus .sheen,
.bubble-field.has-bonus-art .pbubble.bonus .bglyph { display: none; }
.scoop-bubbles.has-bubble-art .sbub {
  width: 64px; height: 64px; margin: 0; background-image: var(--bubble-img);
  background-size: contain; background-position: center; background-repeat: no-repeat;
  filter: drop-shadow(0 0 6px rgba(255,230,150,.7)); }
.scoop-bubbles.has-bubble-art .sbub .bglyph { display: none; }

/* ==========================================================================
 * TRASH & RECYCLE
 * ======================================================================== */
/* trash "bubble" on the result screen (reuses the drifting .rbub-wrap layer) */
.rbub.tbub { background: radial-gradient(circle at 38% 30%, #d9c9a8, #b09a72 60%, #7d6a4a);
  color: #3a2e18; width: 72px; height: 72px; font-size: 36px; }
.rbub.tbub .art-emoji, .rbub.tbub img.art { max-width: 1.1em; }

/* recycle grid */
.trash-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; }
.trash-slot { aspect-ratio: 1 / 1; border-radius: 12px; background: var(--card2); border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center; font-size: 24px; }
.trash-slot.filled { cursor: pointer; background: rgba(180,150,100,.14); border-color: rgba(200,170,110,.4); }
.trash-slot.filled:active { transform: scale(.9); }
.trash-slot img.art.trash-face { max-width: 1.1em; }

/* --- recycling achievements --- */
.ach-bar { max-width: 340px; margin: 0 auto; width: 100%; }
.ach-top { display: flex; justify-content: space-between; font-size: 13px; font-weight: 800; margin-bottom: 4px; }
.ach-track { height: 10px; border-radius: 6px; background: var(--card2); border: 1px solid var(--line); overflow: hidden; }
.ach-track > i { display: block; height: 100%; background: linear-gradient(90deg, #ffd76a, #ff9ecf); border-radius: 6px; transition: width .3s ease; }
.skin-tile.ach { border-color: rgba(255,215,106,.5); }
.skin-tile.ach .skin-chip { filter: grayscale(.3) opacity(.85); }
.ach-big { font-size: 60px; line-height: 1; animation: charmpop 1s cubic-bezier(.2,1.4,.4,1); }
.ach-big img.art { height: 1em; width: auto; max-width: none; }

/* --- mystery Crumpled Bag + Gold Ring treasure in the recycle bin --- */
.trash-slot.bag { position: relative; cursor: pointer;
  background: rgba(205,185,140,.18); border-color: rgba(215,195,150,.55);
  animation: bagwiggle 2.2s ease-in-out infinite; }
@keyframes bagwiggle { 0%,100% { transform: rotate(-2.5deg); } 50% { transform: rotate(2.5deg); } }
.bag-q { position: absolute; top: -5px; right: -5px; width: 18px; height: 18px; border-radius: 50%;
  background: var(--gold); color: #3a2a00; font-size: 12px; font-weight: 900;
  display: flex; align-items: center; justify-content: center; box-shadow: 0 1px 4px rgba(0,0,0,.4); }
.trash-slot.treasure { border-color: var(--gold);
  background: radial-gradient(circle at 40% 30%, rgba(255,220,120,.4), rgba(255,180,60,.2));
  box-shadow: 0 0 12px rgba(255,210,100,.55); animation: treasureglow 1.6s ease-in-out infinite; }
@keyframes treasureglow { 0%,100% { box-shadow: 0 0 10px rgba(255,210,100,.45); } 50% { box-shadow: 0 0 18px rgba(255,220,120,.8); } }

/* --- HUD home/menu button (present on every screen's HUD) --- */
.hud-left { display: inline-flex; align-items: center; gap: 8px; }
.hud-menu { width: 30px; height: 30px; border-radius: 9px; padding: 0; cursor: pointer;
  border: 1px solid var(--line); background: rgba(255,255,255,.14); color: var(--ink);
  font-size: 16px; font-weight: 800; line-height: 1; display: flex; align-items: center; justify-content: center; }
.hud-menu:active { transform: scale(.9); filter: brightness(1.15); }

/* --- Pinch charm: a "shrunk" (half-magic) ingredient --- */
.inv-tile.shrunk { opacity: .82; }
.inv-tile.shrunk .emoji { position: relative; }
.inv-tile.shrunk .emoji > :first-child { transform: scale(.72); display: inline-block; }
.pinch-badge { position: absolute; bottom: -2px; right: -2px; font-size: 13px; line-height: 1;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.5)); }
.slot.shrunk { position: relative; }
.slot.shrunk > :first-child { transform: scale(.74); }
.slot .pinch-badge { bottom: 0; right: 0; font-size: 12px; }

/* --- In-a-Rush patience clock (fixed, persists across phases). Sits just below the pet-badge row
   so it reads the same on scoop, pop and mix. --- */
#rush-clock { position: fixed; top: calc(var(--safe-t) + 112px); left: 50%; transform: translateX(-50%);
  z-index: 45; display: none; flex-direction: column; align-items: center; gap: 3px; width: min(80%, 380px);
  background: rgba(30,15,20,.9); border: 1px solid rgba(255,140,120,.5); border-radius: 12px; padding: 6px 12px;
  box-shadow: 0 6px 16px rgba(0,0,0,.4); }
#rush-clock .rc-lbl { font-size: 13px; font-weight: 800; color: #ffd0b0; }
#rush-clock .rc-track { width: 100%; height: 7px; border-radius: 5px; background: rgba(255,255,255,.12); overflow: hidden; }
#rush-clock .rc-track > i { display: block; height: 100%; background: linear-gradient(90deg,#7ee08a,#ffd76a,#ff6b6b); border-radius: 5px; transition: width .2s linear; }
#rush-clock.urgent { animation: rushpulse .5s ease-in-out infinite; border-color: var(--bad); }
#rush-clock.urgent .rc-lbl { color: #ff9a8a; }
@keyframes rushpulse { 0%,100% { box-shadow: 0 6px 16px rgba(0,0,0,.4); } 50% { box-shadow: 0 0 16px rgba(255,80,80,.8); } }

/* --- win streak chip --- */
.streak-chip { display: inline-flex; align-items: center; gap: 6px; align-self: center; font-weight: 800; font-size: 14px;
  color: #ffb347; background: rgba(255,140,60,.14); border: 1px solid rgba(255,160,80,.4); border-radius: 999px; padding: 5px 14px; }

/* --- quests --- */
.q-badge { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%;
  background: var(--bad); color: #fff; font-size: 13px; font-weight: 900; margin-left: 4px; }
.quest-row { display: flex; align-items: center; gap: 10px; padding: 9px 4px; border-bottom: 1px solid var(--line); }
.quest-row:last-child { border-bottom: none; }
.quest-row.ready { background: rgba(126,224,138,.08); border-radius: 10px; }
.q-emoji { font-size: 26px; width: 30px; text-align: center; }
.q-body { flex: 1; min-width: 0; }
.q-desc { font-weight: 700; font-size: 14px; }
.q-track { height: 7px; border-radius: 5px; background: var(--card2); border: 1px solid var(--line); overflow: hidden; margin: 4px 0 3px; }
.q-track > i { display: block; height: 100%; background: linear-gradient(90deg,#7ee08a,#4fd1c5); border-radius: 5px; transition: width .3s ease; }
.q-sub { font-size: 11px; }
.q-rew { font-size: 12px; font-weight: 800; white-space: nowrap; }

/* --- Fairytale event: the Fairy's Matching game --- */
.fairy-baskets { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.fbasket { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 11px 6px; border-radius: 12px;
  background: var(--card2); border: 1px solid var(--line); color: var(--ink); font-weight: 700; font-size: 13px; cursor: pointer; }
.fbasket:active { transform: scale(.93); filter: brightness(1.1); }
.fbasket .dot { width: 15px; height: 15px; }
.fairy-tray { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.ftile { width: 92px; padding: 8px 4px; border-radius: 12px; cursor: pointer;
  background: var(--card2); border: 2px solid var(--line); color: var(--ink);
  display: flex; flex-direction: column; align-items: center; gap: 3px; }
.ftile .emoji { font-size: 28px; line-height: 1; } .ftile .nm { font-size: 11px; font-weight: 700; text-align: center; }
.ftile .qd { display: flex; gap: 2px; justify-content: center; margin-top: 2px; }
.ftile .qd .dot { width: 9px; height: 9px; }
.ftile.sel { border-color: var(--gold); box-shadow: 0 0 10px rgba(255,216,107,.55); transform: translateY(-2px); }
.ftile.done { pointer-events: none; }
.ftile.ok { border-color: var(--good); background: rgba(126,224,138,.12); }
.ftile.bad { border-color: var(--bad); background: rgba(255,107,107,.12); }
.fairy-result { text-align: center; font-weight: 800; margin: 8px 0; font-size: 15px; }
.fairy-result.win { color: var(--good); } .fairy-result.lose { color: var(--gold); }

/* --- Duel event --- */
.rps-row { display: flex; gap: 14px; justify-content: center; }
.rps-btn { width: 64px; height: 64px; border-radius: 16px; border: 1px solid var(--line); background: var(--card2);
  font-size: 32px; cursor: pointer; }
.rps-btn:active { transform: scale(.9); }
.duel-side { padding: 8px 10px; border-radius: 14px; background: var(--card2); border: 1px solid var(--line); }
.duel-side.foe { margin-bottom: 6px; }
.duel-side.mine { margin-top: 6px; border-color: rgba(126,224,138,.4); }
.duel-name { font-weight: 800; font-size: 14px; margin-bottom: 5px; display: flex; align-items: center; gap: 5px; }
.duel-name img.art { height: 1.2em; }
.duel-think, .duel-turn.foe { color: var(--gold); }
.duel-meter { display: flex; align-items: center; gap: 8px; margin: 3px 0; }
.duel-meter .dm-lbl { font-size: 11px; font-weight: 700; width: 62px; text-align: right; color: var(--ink-dim); }
.duel-meter .meter { flex: 1; height: 12px; }
.duel-turn { text-align: center; font-weight: 800; font-size: 13px; margin: 6px 0; }
.duel-turn.you { color: var(--good); }
.duel-pool-wrap { display: flex; flex-direction: column; min-height: 0; justify-content: center; }
.duel-pool { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; align-content: center; overflow-y: auto; max-height: 100%; padding: 4px 0; }
.duel-tile { width: 104px; padding: 12px 6px; border-radius: 14px; cursor: pointer;
  background: var(--card2); border: 1px solid var(--line); color: var(--ink);
  display: flex; flex-direction: column; align-items: center; gap: 5px; font-size: 13px; font-weight: 700; }
.duel-tile img.art { height: 42px; width: auto; }
.duel-tile .art-emoji { font-size: 34px; line-height: 1; }
.duel-tile span { text-align: center; line-height: 1.15; }
.duel-tile:active { transform: scale(.92); }
.duel-tile.off { opacity: .5; pointer-events: none; }
/* the sweet meter needs a base height in the duel (it's inline there) */
.duel-meter .meter.sweet { border-radius: 6px; background: rgba(255,255,255,.08); position: relative; overflow: visible; }
.duel-meter .meter.sweet > i { display: block; height: 100%; border-radius: 6px; }
/* Rumpelstiltskin spinning-wheel timing bar */
.rumpel-track { position: relative; width: 100%; max-width: 320px; height: 30px; border-radius: 15px;
  background: rgba(255,255,255,.08); border: 1px solid var(--line); overflow: hidden; }
.rumpel-band { position: absolute; top: 0; bottom: 0; border-radius: 6px;
  background: linear-gradient(180deg, #ffe58a, #f6c945); box-shadow: 0 0 12px rgba(246,201,69,.7); }
.rumpel-needle { position: absolute; top: -4px; bottom: -4px; left: 0; width: 5px; margin-left: -2.5px;
  border-radius: 3px; background: #fff; box-shadow: 0 0 8px rgba(255,255,255,.9); }
.rumpel-stat { font-weight: 800; font-size: 15px; }
.rumpel-stat.sub { font-weight: 600; font-size: 13px; color: var(--ink-dim); }
/* Rumpelstiltskin's spinning wheel — layered art (stand behind, wheel spinning, arrow on top),
   with a generated gold arc that peeks through the wheel's transparent channel, set in his room. */
.rumpel-scene { position: relative; flex: 1; min-height: 0; width: 100%; overflow: hidden; background: #191006; }
/* The "world" is the background image at its own aspect, sized to the scene width. The wheel lives
   INSIDE it (positioned by fractions measured from the reference), so bg and wheel always crop/scale
   together. We anchor it so the wheel's centre lands at mid-screen (its centre sits ~41% down the
   world), which drops everything lower and reveals more of the room up top. */
.rumpel-world { position: absolute; left: 0; top: 50%; width: 100%; aspect-ratio: 853 / 1844;
  transform: translateY(-40.85%); }
.rumpel-bg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.sw-stage { position: absolute; left: 9.85%; top: 25.16%; width: 81.48%; height: 43.71%; z-index: 2; }
.rumpel-stats { position: absolute; top: 8px; left: 50%; transform: translateX(-50%); z-index: 4;
  display: flex; flex-direction: column; align-items: center; gap: 1px; text-align: center;
  padding: 6px 18px; border-radius: 14px; background: rgba(24,14,34,.62); border: 1px solid rgba(255,255,255,.12); }
.rumpel-stats .rumpel-stat { color: #fff9ee; text-shadow: 0 1px 2px rgba(0,0,0,.6); }
/* Hint + Stop button float over the room (no solid bar) so more of the background shows.
   The Stop button matches the Wishing Well's toss button size. */
.rumpel-bottom { position: absolute; left: 50%; bottom: calc(12px + var(--safe-b)); transform: translateX(-50%); z-index: 7;
  display: flex; flex-direction: column; align-items: center; gap: 10px; width: 100%; }
.rumpel-hint { width: 92%; max-width: 340px; text-align: center; font-size: 13px; color: #f3e8d0; text-shadow: 0 1px 3px rgba(0,0,0,.9); }
.rumpel-bottom .rumpel-stop-btn { width: auto; white-space: nowrap; padding: 17px 50px; font-size: 23px;
  box-shadow: 0 5px 16px rgba(0,0,0,.55), 0 0 0 2px rgba(255,255,255,.2); }
/* Rumpelstiltskin standing in his story-mode scenes — he's a short character, so make him big and
   lift him off the floor so he sits higher on screen (feet tuck behind the speech card). */
.story-figure.rumpel { height: 88vh; bottom: 9%; }
.story-figure.rumpel img.story-face { max-width: 124vw; }
/* his wide arms-out poses (intro offer / loss) read bigger than the compact win pose — trim them */
.story-figure.rumpel.deal, .story-figure.rumpel.fume { height: 80vh; }
/* the gold-hoard pose is framed larger — shrink it so his hat isn't cropped */
.story-figure.rumpel.gold { height: 76vh; }
/* "🪙 +X" floating up over the wheel when you land a spin */
.rumpel-plus { position: absolute; left: 50%; top: 40%; transform: translate(-50%, -50%); z-index: 9;
  font-family: var(--ff-body); font-weight: 900; font-size: 34px; color: #ffd76a; white-space: nowrap;
  text-shadow: 0 2px 6px rgba(0,0,0,.9); pointer-events: none; animation: rumpelPlus 1s ease-out forwards; }
@keyframes rumpelPlus {
  0%   { opacity: 0; transform: translate(-50%, -20%) scale(.6); }
  25%  { opacity: 1; transform: translate(-50%, -50%) scale(1.12); }
  100% { opacity: 0; transform: translate(-50%, -120%) scale(1); } }
.story-below .rumpel-terms { font-size: 12.5px; font-weight: 700; color: #ffe9c0; text-align: center;
  background: rgba(20,12,30,.5); padding: 5px 14px; border-radius: 999px; }
.story-below .rumpel-btns { width: 100%; max-width: 400px; display: flex; flex-direction: column; gap: 8px; }
.story-below .rumpel-btns .btn { width: 100%; }
.rumpel-foot { display: flex; flex-direction: column; gap: 8px; padding: 8px 12px calc(8px + var(--safe-b)); }
.rumpel-foot .btn { width: 100%; }
/* Rumpelstiltskin's story-mode screens (intro / between / win-lose) — his room, blurred,
   with the character pose and dialogue over a soft scrim. */
.rumpel-story { position: relative; flex: 1; min-height: 0; width: 100%; overflow: hidden;
  background-position: center bottom; background-size: cover; background-repeat: no-repeat; background-color: #191006; }
.rumpel-scrim { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(18,10,26,.22) 0%, rgba(18,10,26,.66) 58%, rgba(18,10,26,.9) 100%); }
.rumpel-content { position: relative; z-index: 1; height: 100%; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 8px; padding: 6px 14px; text-align: center; overflow-y: auto; }
.rumpel-fig { height: min(30vh, 250px); width: auto; object-fit: contain; flex-shrink: 0;
  filter: drop-shadow(0 8px 16px rgba(0,0,0,.6)); user-select: none; -webkit-user-select: none; }
.rumpel-name { font-family: var(--ff-display); font-weight: 900; font-size: 22px; color: #ffe9b0; text-shadow: 0 2px 5px rgba(0,0,0,.85); }
.rumpel-content .speech { max-width: 320px; }
.rumpel-card { width: 100%; max-width: 320px; }
.muted.small { font-size: 12.5px; }
.sw-stage > img, .sw-stage > .sw-spin, .sw-spin > * { position: absolute; inset: 0; width: 100%; height: 100%; }
.sw-stage img { object-fit: contain; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.sw-stand { z-index: 0; }
.sw-spin  { z-index: 1; transform-origin: 41.68% 35.90%; will-change: transform; }
.sw-arrow { z-index: 2; }
.sw-color { overflow: visible; filter: drop-shadow(0 0 5px rgba(255,205,80,.85)); }
/* Gribble the Goblin — mouth-open junk-muncher: tap the trash he calls for and
   it flies up and shrinks into his gob. */
.gob-stage { position: relative; flex: 1; min-height: 0; width: 100%; overflow: hidden; display: flex; flex-direction: column;
  align-items: center; gap: 6px; padding: 6px 10px 10px; }
.gob-bg { position: absolute; inset: 0; z-index: 0; background: center/cover no-repeat; }
.gob-bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(18,10,6,.34) 0%, rgba(18,10,6,.04) 28%, rgba(18,10,6,.12) 60%, rgba(18,10,6,.6) 100%); }
.gob-stage > *:not(.gob-bg):not(.gob-count-big) { position: relative; z-index: 1; }
.gob-hud { display: flex; gap: 8px; width: 100%; justify-content: center; }
.gob-chip { display: flex; align-items: center; gap: 5px; padding: 4px 12px; border-radius: 999px; font-weight: 800; font-size: 15px;
  background: rgba(18,10,28,.55); border: 1px solid rgba(255,255,255,.22); color: #fff; }
.gob-chip b { color: #ffe08a; }
.gob-chip.danger { background: rgba(120,20,20,.62); border-color: #ff6a6a; }
.gob-chip.danger b { color: #ffb0b0; }
.gob-goblin { position: relative; flex: 0 0 auto; height: 32vh; display: flex; justify-content: center; }
.gob-goblin.cd { flex: 1; align-items: center; }
.gob-goblin-img { height: 100%; max-height: 40vh; width: auto; object-fit: contain; filter: drop-shadow(0 8px 16px rgba(0,0,0,.55)); }
.gob-mouth { position: absolute; left: 50%; top: 40%; width: 1px; height: 1px; }   /* fly-to-mouth target */
.gob-want-box { display: flex; justify-content: center; margin-top: -6px; }
.gob-want-frame { width: 92px; height: 92px; border-radius: 16px; display: flex; align-items: center; justify-content: center;
  background: rgba(255,213,120,.16); border: 2px solid rgba(255,213,120,.8); box-shadow: 0 0 16px rgba(255,213,120,.4);
  animation: gobWant 1s ease-in-out infinite; }
@keyframes gobWant { 0%,100% { transform: scale(1); } 50% { transform: scale(1.07); } }
.gob-want-frame img.art { height: 70px; width: auto; max-width: 84px; }
.gob-want-frame .art-emoji { font-size: 54px; line-height: 1; }
.gob-timer { height: 9px; width: 92%; max-width: 420px; border-radius: 5px; background: rgba(10,4,24,.5); overflow: hidden; border: 1px solid rgba(255,255,255,.2); }
.gob-timer > i { display: block; height: 100%; width: 100%; border-radius: 5px; background: linear-gradient(90deg,#ffe58a,#f6c945); }
.gob-fb { font-family: var(--ff-display); font-size: 18px; color: #fff; text-shadow: 0 2px 5px rgba(0,0,0,.85); min-height: 22px; text-align: center; }
.gob-fb .good { color: var(--good); } .gob-fb .bad { color: #ff8a7a; }
.gob-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; width: 100%; max-width: 440px; overflow-y: auto; padding: 2px; }
.gob-tile { position: relative; padding: 8px 4px 6px; border-radius: 14px; cursor: pointer; border: 1px solid rgba(255,255,255,.18);
  background: rgba(18,10,28,.52); display: flex; flex-direction: column; align-items: center; gap: 2px;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.gob-tile.wanted { border-color: rgba(255,213,120,.95); box-shadow: 0 0 12px rgba(255,213,120,.55); background: rgba(255,213,120,.15); }
.gob-tile-img { height: 60px; display: flex; align-items: center; justify-content: center; }
.gob-tile-img img.art { height: 60px; width: auto; max-width: 78px; }
.gob-tile-img .art-emoji { font-size: 44px; line-height: 1; }
.gob-tile:active { transform: scale(.9); }
.gob-count { font-size: 13px; font-weight: 800; color: #ffe08a; }
.gob-nope { width: auto; max-width: 92%; margin-top: 2px; padding: 11px 24px; }
.gob-nope[disabled] { opacity: .4; pointer-events: none; }
.gob-want-q { font-size: 54px; font-weight: 900; color: rgba(255,255,255,.55); }
/* the tapped piece popping up and flying into his mouth */
.gob-fly { position: fixed; z-index: 200; pointer-events: none; transform: translate(-50%,-50%); }
.gob-fly img.art { height: 66px; width: auto; max-width: none; filter: drop-shadow(0 4px 9px rgba(0,0,0,.6)); }
/* countdown number over the stage */
.gob-count-big { position: absolute; left: 50%; top: 46%; transform: translate(-50%,-50%); z-index: 5;
  font-size: 104px; font-weight: 900; line-height: 1; color: var(--gold);
  text-shadow: 0 0 24px rgba(255,216,107,.6); animation: gobcd .75s ease; }
.gob-count-big.go { color: var(--good); font-size: 72px; }
@keyframes gobcd { 0% { transform: translate(-50%,-50%) scale(1.6); opacity: 0; } 40% { transform: translate(-50%,-50%) scale(1); opacity: 1; } 100% { transform: translate(-50%,-50%) scale(1); opacity: 1; } }
/* Gribble's intro & win/lose slides use the shared .story-card layout, like Rumpel.
   His figures render a touch smaller than the default, except the thought-bubble
   pose (the bubble eats image height, so it needs to sit taller to read big). */
.story-figure.gribble { height: 74vh; }
.story-figure.gribble-think { height: 93vh; }
/* Feed the Wolf — keep Patience out of the red until the huntsman arrives */
.wolf-top { display: flex; align-items: center; gap: 12px; padding: 4px 2px 8px; }
.wolf-face { font-size: 52px; line-height: 1; flex: 0 0 auto; }
.wolf-face.angry { animation: wolfShake .35s linear infinite; }
@keyframes wolfShake { 0%,100% { transform: translateX(0) rotate(0); } 25% { transform: translateX(-3px) rotate(-4deg); } 75% { transform: translateX(3px) rotate(4deg); } }
.wolf-huntsman { flex: 1; min-width: 0; }
.wolf-hlbl { font-size: 12px; font-weight: 800; color: #d8c6ff; }
.wolf-hbar { height: 10px; border-radius: 6px; background: rgba(255,255,255,.09); overflow: hidden; margin-top: 4px; border: 1px solid rgba(255,255,255,.14); }
.wolf-hbar > i { display: block; height: 100%; width: 0%; border-radius: 6px; background: linear-gradient(90deg,#8fd0ff,#4f9cff); transition: width .12s linear; }
.wolf-modes { display: flex; flex-direction: column; gap: 8px; width: 100%; }
.wolf-bars { display: flex; flex-direction: column; gap: 6px; padding: 2px 2px 4px; }
.wolf-bar { }
.wolf-patience { padding: 2px 2px 6px; }
.wolf-plabel { font-size: 12px; font-weight: 800; color: #ffd0d0; margin-bottom: 3px; }
.wolf-sublbl { font-size: 10px; font-weight: 700; color: #c9b8ea; opacity: .85; }
.wolf-ptrack { position: relative; height: 20px; border-radius: 11px; background: rgba(0,0,0,.4); overflow: hidden; border: 1px solid rgba(255,255,255,.14); }
.wolf-green { position: absolute; top: 0; bottom: 0; background: rgba(126,224,138,.22); border-left: 2px solid rgba(126,224,138,.5); border-right: 2px solid rgba(126,224,138,.5); }
.wolf-green.lowzone { background: rgba(126,224,138,.16); }
.wolf-pfill { position: absolute; left: 0; top: 0; bottom: 0; width: 60%; border-radius: 12px 0 0 12px; transition: width .12s linear, background .3s; }
.wolf-pfill.green { background: linear-gradient(90deg,#5fbf6e,#7ee08a); }
.wolf-pfill.amber { background: linear-gradient(90deg,#e0a94f,#ffce6b); }
.wolf-pfill.danger { background: linear-gradient(90deg,#c0392b,#ff6b6b); animation: wolfPulse .5s ease-in-out infinite; }
@keyframes wolfPulse { 0%,100% { box-shadow: 0 0 0 rgba(255,107,107,0); } 50% { box-shadow: 0 0 14px rgba(255,107,107,.8); } }
.wolf-effects { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; min-height: 20px; }
.wolf-chip { font-size: 11px; font-weight: 800; color: #dff5e2; background: rgba(80,180,110,.28); border: 1px solid rgba(126,224,138,.5); border-radius: 999px; padding: 2px 8px; }
.wolf-chip.slow { color: #d8c6ff; background: rgba(150,110,230,.3); border-color: rgba(190,150,255,.55); }
/* objective banner: use up the huntsman's allergens before he arrives */
.wolf-obj { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px; min-height: 24px;
  font-size: 12px; font-weight: 800; color: #ffd6d6; padding: 3px 8px; border-radius: 10px;
  background: rgba(120,40,40,.28); border: 1px solid rgba(255,120,120,.4); margin: 2px 0; }
.wolf-obj:empty { display: none; }
.wolf-obj-lbl { color: #ffb0b0; }
.wolf-obj-item { font-weight: 900; padding: 1px 7px; border-radius: 999px; background: rgba(255,90,90,.25); border: 1px solid rgba(255,120,120,.55); }
.wolf-obj-item.done { color: #a7ecb0; background: rgba(126,224,138,.22); border-color: rgba(126,224,138,.5); }
.wolf-obj.clear { background: rgba(40,110,60,.28); border-color: rgba(126,224,138,.5); color: #a7ecb0; }
.wolf-obj.urgent { animation: wolfObjFlash .6s ease-in-out infinite; }
@keyframes wolfObjFlash { 0%,100% { box-shadow: 0 0 0 rgba(255,90,90,0); } 50% { box-shadow: 0 0 12px rgba(255,90,90,.8); } }
/* each bar sits directly above its own row of foods (feed the bar from the row under it) */
.wolf-groups { display: flex; flex-direction: column; gap: 9px; padding: 4px 2px 8px; transition: opacity .15s; }
.wolf-groups.cooling { opacity: .55; pointer-events: none; }
.wolf-group { display: flex; flex-direction: column; gap: 5px; padding: 7px; border-radius: 14px;
  background: rgba(255,255,255,.03); border: 1px solid rgba(255,255,255,.08); }
.wolf-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.wolf-tile { position: relative; padding: 8px 2px 6px; border-radius: 12px; cursor: pointer;
  background: var(--card2); border: 1px solid rgba(255,214,110,.35); color: var(--ink);
  display: flex; flex-direction: column; align-items: center; gap: 1px; font-weight: 700; }
.wolf-tile .wolf-emoji { font-size: 24px; line-height: 1; }
.wolf-tname { font-size: 9px; font-weight: 800; text-align: center; line-height: 1; }
.wolf-tfx { font-size: 10px; font-weight: 900; color: #ffd86b; text-align: center; line-height: 1.1; }
.wolf-count { position: absolute; top: 1px; right: 3px; font-size: 9px; font-weight: 800; color: var(--ink-dim); }
/* allergen (must-use-up) treats — pulsing red so they're impossible to miss */
.wolf-tile.allergen { border: 2px solid #ff5a5a; box-shadow: 0 0 10px rgba(255,60,60,.7);
  background: linear-gradient(180deg, rgba(150,35,35,.45), var(--card2) 70%); animation: wolfAllergGlow 1.2s ease-in-out infinite; }
@keyframes wolfAllergGlow { 0%,100% { box-shadow: 0 0 8px rgba(255,60,60,.55); } 50% { box-shadow: 0 0 18px 4px rgba(255,60,60,.95); } }
.wolf-tile.allergen.empty { animation: none; box-shadow: none; }
.wolf-allergen { position: absolute; top: -7px; left: -5px; font-size: 15px; z-index: 3; filter: drop-shadow(0 0 3px rgba(0,0,0,.9)); }
/* column-locked treats (Hard) — a clear dark lock cover, not just a fade */
.wolf-tile.locked { pointer-events: none; }
.wolf-tile.locked::after { content: "🔒"; position: absolute; inset: 0; border-radius: 12px; z-index: 4;
  display: flex; align-items: center; justify-content: center; font-size: 22px;
  background: rgba(8,5,18,.74); border: 2px solid rgba(150,130,255,.7); box-shadow: inset 0 0 10px rgba(120,100,220,.4); }
.wolf-tile:active { transform: scale(.92); }
.wolf-tile.empty { opacity: .3; }
.wolf-tile.pop { animation: wolfTilePop .25s ease; }
@keyframes wolfTilePop { 0% { transform: scale(1); } 45% { transform: scale(1.18); } 100% { transform: scale(1); } }
.wolf-cd { position: relative; height: 30px; border-radius: 12px; overflow: hidden; margin-top: 4px;
  background: rgba(0,0,0,.35); border: 1px solid rgba(255,255,255,.14); display: flex; align-items: center; justify-content: center; }
.wolf-cd > i { position: absolute; left: 0; top: 0; bottom: 0; width: 0%; background: rgba(255,214,110,.28); transition: width .1s linear; }
.wolf-cd > span { position: relative; font-size: 12px; font-weight: 800; color: #fff; z-index: 2; }
/* Rescue the Feast — catch tumbling dishes, set each in its home (Courtyard finale) */
/* ===== Rescue the Feast — the spinning banquet wheel ===== */
.feast-stage { position: relative; flex: 1; min-height: 0; overflow: hidden; background: #1a1330; }
.feast-bg { position: absolute; inset: 0; z-index: 0; background-size: cover; background-position: center; pointer-events: none; }
/* the wheel lives in a band across the top; its centre sits above the screen so only the lower arc shows */
.feast-wheelwrap { position: absolute; top: 0; left: 0; right: 0; height: 46%; overflow: hidden; z-index: 1; pointer-events: none; }
.feast-wheel { position: absolute; left: 50%; top: 0; width: 168%; aspect-ratio: 1 / 1; transform: translate(-50%, -70%); }
.feast-wheel-rot { position: absolute; inset: 0; will-change: transform; }
.feast-wheel-img { width: 100%; height: 100%; display: block; filter: drop-shadow(0 6px 14px rgba(0,0,0,.5)); }
.feast-onwheel { position: absolute; inset: 0; }
.feast-wfood { position: absolute; transform: translate(-50%, -50%); display: flex; justify-content: center; }
.feast-wfood img.feast-wfood-img { width: 100%; height: auto; max-width: none; display: block; filter: drop-shadow(0 3px 5px rgba(0,0,0,.45)); }
/* falling items */
.feast-fall { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.feast-faller { position: absolute; transform: translate(-50%, -50%); border: none; background: none; padding: 14px; cursor: pointer; pointer-events: auto; z-index: 2; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.feast-faller img.feast-faller-img { height: 8vh; width: auto; max-width: none; display: block; filter: drop-shadow(0 2px 6px rgba(0,0,0,.3)); pointer-events: none; }
/* per-item size tweaks: the wide loaf reads big, so trim bread and cake a touch */
.feast-faller.feast-k-bread img.feast-faller-img { height: 6.9vh; }
.feast-faller.feast-k-cake img.feast-faller-img { height: 7.4vh; }
.feast-faller:active img { transform: scale(.86); }
.feast-faller.nope img.feast-faller-img { animation: feastNope .5s ease; }
@keyframes feastNope { 0%,100% { filter: drop-shadow(0 2px 6px rgba(0,0,0,.3)); } 30%,70% { filter: drop-shadow(0 0 3px #ff4a4a) drop-shadow(0 0 12px rgba(255,60,60,.95)); } }
.feast-splash { position: absolute; transform: translate(-50%,-50%); font-size: 46px; z-index: 3; pointer-events: none; animation: feastSplash .5s ease-out forwards; }
@keyframes feastSplash { 0% { transform: translate(-50%,-50%) scale(.4); opacity: 0; } 30% { opacity: 1; } 100% { transform: translate(-50%,-32%) scale(1.2); opacity: 0; } }
/* score chips + timer */
.feast-hudline { position: absolute; top: 8px; left: 0; right: 0; display: flex; justify-content: center; gap: 8px; z-index: 4; pointer-events: none; }
.feast-chip { font-size: 12.5px; font-weight: 800; color: #fff; background: rgba(20,14,40,.6); border: 1px solid rgba(255,214,110,.4); border-radius: 999px; padding: 4px 11px; text-shadow: 0 1px 2px rgba(0,0,0,.6); }
.feast-chip b { color: #ffd76a; }
.feast-timerbar { position: absolute; top: 38px; left: 8%; right: 8%; height: 5px; border-radius: 4px; overflow: hidden; z-index: 4; background: rgba(0,0,0,.35); }
.feast-timerbar > i { display: block; height: 100%; width: 0%; border-radius: 4px; background: linear-gradient(90deg,#ffd76a,#ff9e4a); transition: width .12s linear; }
/* stations row + hand slots pinned to the bottom */
.feast-stations { position: absolute; left: 0; right: 0; bottom: 8px; display: flex; justify-content: space-between; align-items: flex-end; gap: 6px; z-index: 3; padding: 0 12px; }
/* generous tap target: the big top padding extends the hit box up into the fall path */
.feast-station { position: relative; flex: 1 1 0; min-width: 0; max-width: 104px; border: none; background: none; padding: 28px 4px 8px; box-sizing: border-box; cursor: pointer; display: flex; justify-content: center; align-items: flex-end; border-radius: 16px; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.feast-station img.feast-station-img { width: 100%; height: auto; max-width: none; display: block; filter: drop-shadow(0 4px 8px rgba(0,0,0,.5)); pointer-events: none; }
.feast-station:active { transform: scale(.94); }
/* correct placement: a green glow around the station's picture (not the tap box) */
.feast-station.good-pop img.feast-station-img { animation: feastStGood .55s ease; }
.feast-station.meh-pop img.feast-station-img { animation: feastStMeh .4s ease; }
@keyframes feastStGood { 0%,100% { filter: drop-shadow(0 4px 8px rgba(0,0,0,.5)); transform: scale(1); } 40% { filter: drop-shadow(0 0 7px #7ee08a) drop-shadow(0 0 18px rgba(126,224,138,.95)); transform: scale(1.08); } }
/* wrong placement: a RED glow around the station picture (plus a small shake) */
@keyframes feastStMeh { 0%,100% { filter: drop-shadow(0 4px 8px rgba(0,0,0,.5)); transform: translateX(0); } 25% { filter: drop-shadow(0 0 7px #ff5a5a) drop-shadow(0 0 18px rgba(255,70,70,.95)); transform: translateX(-4px); } 60% { filter: drop-shadow(0 0 7px #ff5a5a) drop-shadow(0 0 18px rgba(255,70,70,.95)); transform: translateX(4px); } }
.feast-hands { position: absolute; left: 0; right: 0; bottom: 144px; display: flex; justify-content: center; gap: 14px; z-index: 4; }
.feast-hands.full { animation: feastShake .3s ease; }
.feast-hold { width: 84px; height: 78px; border-radius: 16px; display: flex; align-items: center; justify-content: center; border: 2px dashed rgba(255,214,110,.5); background: rgba(20,14,40,.5); }
.feast-hold.has { border-style: solid; border-color: rgba(255,214,110,.85); background: rgba(255,214,110,.16); }
.feast-hold img.feast-hold-img { height: 62px; width: auto; max-width: 78px; display: block; }
.feast-stage.feast-shake { animation: feastShake .3s ease; }
@keyframes feastShake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }
@keyframes feastGood { 0% { transform: scale(1); box-shadow: 0 0 0 rgba(126,224,138,0); } 45% { transform: scale(1.12); box-shadow: 0 0 16px rgba(126,224,138,.9); border-color: #7ee08a; } 100% { transform: scale(1); } }
@keyframes feastMeh { 0%,100% { transform: translateX(0); } 30% { transform: translateX(-5px); } 60% { transform: translateX(5px); } }
/* Sky-High Savings — swipe to sway an ever-growing coin tower (Beanstalk finale) */
/* flex:1 + min-height:0 makes the sky fill the play column. Without it the sky collapsed
   to a thin strip at the top on iOS Safari (all children are absolutely positioned), so only
   touches near the top registered. Mirrors the carpet game, which fills correctly. */
.stack-sky { position: relative; flex: 1; min-height: 0; width: 100%; overflow: hidden;
  touch-action: none; cursor: grab; background: #170f2e; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.stack-sky:active { cursor: grabbing; }
.stack-sky.bump { animation: stackBump .32s ease-out; }
@keyframes stackBump { 0%,100% { transform: translate(0,0); } 20% { transform: translate(-6px,3px); } 45% { transform: translate(5px,-2px); } 70% { transform: translate(-3px,2px); } }
/* the lush beanstalk-valley backdrop, softly blurred so the coins pop in front */
.stack-bg { position: absolute; inset: -8px; z-index: 0; pointer-events: none;
  background: url('../art/beanstalk_sky.jpg') center center / cover no-repeat; filter: blur(2px) brightness(.82) saturate(1.05); }
.stack-item { position: absolute; transform: translateX(-50%); top: 0; width: 72px; height: 72px;
  background: center / contain no-repeat; will-change: top; z-index: 2; pointer-events: none;
  filter: drop-shadow(0 4px 7px rgba(0,0,0,.6)); }
.stack-item.gem { filter: drop-shadow(0 0 8px rgba(170,225,255,.7)) drop-shadow(0 4px 7px rgba(0,0,0,.55)); }
.stack-item.bad { width: 68px; height: 68px; animation: stackBadGlow 1.1s ease-in-out infinite; }
@keyframes stackBadGlow { 0%,100% { filter: drop-shadow(0 4px 7px rgba(0,0,0,.6)); } 50% { filter: drop-shadow(0 0 10px rgba(255,90,60,.95)) drop-shadow(0 4px 7px rgba(0,0,0,.5)); } }
/* A missed item keeps falling (behind the tower) to the bottom, dimmed so it reads as "got away" */
.stack-item.miss { opacity: .5; z-index: 1; }
/* The tower: coins/gems are positioned by top%, share a horizontal position (--tx), and the whole
   thing leans (--ang) around its top so the catch point never moves. */
.stack-tower { position: absolute; inset: 0; z-index: 3; pointer-events: none;
  --tx: 50%; --ang: 0deg; transform: rotate(var(--ang)); transform-origin: var(--tx) 46%; will-change: transform; }
.stack-coin2 { position: absolute; left: var(--tx); transform: translate(-50%,-50%); width: 86px; height: 46px;
  background: center / contain no-repeat; filter: drop-shadow(0 3px 4px rgba(0,0,0,.5)); }
.stack-coin2.gem { width: 84px; height: 48px; filter: drop-shadow(0 0 8px rgba(170,225,255,.65)) drop-shadow(0 3px 4px rgba(0,0,0,.5)); }
/* Hard-mode body-hit flourish: an impact spark + a floating −5 */
.stack-spark { position: absolute; transform: translate(-50%,-50%); font-size: 40px; z-index: 4; pointer-events: none;
  animation: stackSpark .4s ease-out forwards; }
@keyframes stackSpark { 0% { opacity: 1; transform: translate(-50%,-50%) scale(.5); } 100% { opacity: 0; transform: translate(-50%,-50%) scale(1.5); } }
.stack-pen { position: absolute; transform: translate(-50%,-50%); z-index: 5; pointer-events: none;
  font-family: var(--ff-display); font-weight: 800; font-size: 22px; color: #ff6a6a; text-shadow: 0 2px 5px rgba(0,0,0,.85);
  animation: stackPen .8s ease-out forwards; }
@keyframes stackPen { 0% { opacity: 0; transform: translate(-50%,-50%); } 20% { opacity: 1; } 100% { opacity: 0; transform: translate(-50%,-140%); } }
.stack-base { position: absolute; left: var(--tx); transform: translate(-50%,-50%); width: 96px; height: 16px; border-radius: 9px;
  background: linear-gradient(180deg, #ffe488, #e0a92e); box-shadow: 0 3px 7px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.65);
  border: 1px solid rgba(120,80,10,.5); }
.stack-tower.catch-good { animation: stackGood .28s ease; }
.stack-tower.catch-bad { animation: stackBad .34s ease; }
@keyframes stackGood { 0%,100% { transform: rotate(var(--ang)) scale(1); } 45% { transform: rotate(var(--ang)) scale(1.05); } }
@keyframes stackBad { 0%,100% { transform: rotate(var(--ang)); } 30% { transform: rotate(calc(var(--ang) - 4deg)); } 70% { transform: rotate(calc(var(--ang) + 4deg)); } }
.stack-hint { color: #cbbdf0; }
.stack-best { font-size: 11px; font-weight: 700; color: #ffd76a; opacity: .9; margin-left: 4px; }
/* Minimal floating HUD over the sky: counters in the corners, timer across the top */
.stack-overlay { position: absolute; top: 7px; left: 7px; right: 7px; z-index: 6; display: flex; align-items: flex-start;
  justify-content: space-between; gap: 8px; pointer-events: none; }
.stack-chip { display: flex; align-items: center; gap: 5px; padding: 4px 11px; border-radius: 999px; font-weight: 800; font-size: 15px;
  color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.75); background: rgba(18,10,34,.5); border: 1px solid rgba(255,255,255,.2);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
.stack-chip b { color: #ffe08a; }
.stack-chip.danger { background: rgba(120,20,20,.6); border-color: #ff6a6a; }
.stack-chip.danger b { color: #ffb0b0; }
.stack-chip-mid { background: rgba(18,10,34,.42); }
.stack-timer2 { flex: 1; max-width: 150px; height: 9px; margin-top: 7px; border-radius: 999px; overflow: hidden;
  background: rgba(18,10,34,.5); border: 1px solid rgba(255,255,255,.22); }
.stack-timer2 i { display: block; height: 100%; width: 0%; background: linear-gradient(90deg, #c58bff, #ffd76a); transition: width .12s linear; }
/* Spilled Wish-Wine — dab blooming drops off the King's cloak */
.wine-cloak { position: relative; flex: 1; min-height: 0; margin: 4px 2px; border-radius: 14px; overflow: hidden;
  background: #efe7d6 url('../art/wine_cloak.webp') center center / cover no-repeat; border: 1px solid rgba(0,0,0,.18);
  touch-action: manipulation; }
.wine-drop { position: absolute; transform: translate(-50%,-50%) rotate(var(--rot,0deg)); width: 32px; height: 32px; padding: 0; border: none; cursor: pointer;
  background: center / contain no-repeat; filter: drop-shadow(0 2px 5px rgba(0,0,0,.45)); z-index: 2; }
.wine-drop.urgent { animation: wineUrgent .5s ease-in-out infinite; filter: drop-shadow(0 0 12px rgba(255,90,150,.95)) drop-shadow(0 2px 4px rgba(0,0,0,.4)); }
@keyframes wineUrgent { 0%,100% { transform: translate(-50%,-50%) rotate(var(--rot,0deg)) scale(1); } 50% { transform: translate(-50%,-50%) rotate(var(--rot,0deg)) scale(1.09); } }
.wine-stain { position: absolute; transform: translate(-50%,-50%) rotate(var(--rot,0deg)); width: 132px; height: 132px;
  background: center / contain no-repeat; filter: brightness(.8) saturate(1.05) drop-shadow(0 1px 2px rgba(0,0,0,.35)); z-index: 1; pointer-events: none; }
.wine-sparkle { position: absolute; transform: translate(-50%,-50%); font-size: 32px; z-index: 3; pointer-events: none; animation: wineSpark .4s ease-out forwards; }
@keyframes wineSpark { 0% { opacity: 1; transform: translate(-50%,-50%) scale(.5); } 100% { opacity: 0; transform: translate(-50%,-50%) scale(1.5); } }
/* Jester's juggling balls — medium, bouncy, always tappable above the wine */
.wine-ball { position: absolute; transform: translate(-50%,-50%); width: 92px; height: 92px; padding: 0; border: none; background: transparent; cursor: pointer;
  z-index: 4; touch-action: manipulation; display: flex; align-items: center; justify-content: center;
  transition: top .06s linear, left .06s linear; will-change: top, left; }
.wine-ball-face { width: 74px; height: 74px; pointer-events: none; background: center / contain no-repeat;
  filter: drop-shadow(0 3px 5px rgba(0,0,0,.45)); }
.wine-ball.low .wine-ball-face { filter: drop-shadow(0 0 12px rgba(255,80,80,.95)) drop-shadow(0 3px 5px rgba(0,0,0,.4)); }
.wine-ball.toss .wine-ball-face { animation: wineToss .3s ease; }
@keyframes wineToss { 0%,100% { transform: scale(1); } 45% { transform: scale(1.2); } }
.wine-splat { position: absolute; transform: translate(-50%,-50%); font-size: 34px; z-index: 3; pointer-events: none; animation: wineSpark .45s ease-out forwards; }
/* Collection hunt — tracker chip + "found one!" flourish */
.hunt-chip { display: flex; width: fit-content; margin: 6px auto 0; align-items: center; gap: 5px; padding: 4px 12px; border-radius: 999px;
  background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.30); font-size: 13px; font-weight: 800; color: #fff;
  box-shadow: 0 2px 6px rgba(0,0,0,.3); }
.hunt-chip b { color: #ffe08a; }
.hunt-chip.bump { animation: huntChipBump .4s ease; }
@keyframes huntChipBump { 0%,100% { transform: scale(1); } 40% { transform: scale(1.22); } }
.hunt-find-fx { position: fixed; transform: translate(-50%,-50%); font-size: 42px; z-index: 60; pointer-events: none;
  filter: drop-shadow(0 0 8px rgba(255,240,150,.9)); animation: huntFindFloat 1s ease-out forwards; }
@keyframes huntFindFloat { 0% { opacity: 0; transform: translate(-50%,-50%) scale(.4); } 25% { opacity: 1; transform: translate(-50%,-50%) scale(1.25); } 100% { opacity: 0; transform: translate(-50%,-165%) scale(1); } }
/* a found sheep shows its own picture as it pops up */
.hunt-find-fx .hunt-find-img.art { height: 92px; width: auto; max-width: none; filter: drop-shadow(0 4px 10px rgba(0,0,0,.5)); }
/* Bo Peep hugging her sheep on the hunt-complete card */
.hunt-cel-fig { display: flex; justify-content: center; }
.hunt-cel-fig .hunt-cel-art.art { height: 200px; width: auto; max-width: none; filter: drop-shadow(0 8px 16px rgba(0,0,0,.45)); }
.hunt-cel-fig .art-emoji { font-size: 72px; }
/* the sheep collection grid in the Satchel */
.sheep-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 7px; margin-top: 10px; }
.sheep-slot { aspect-ratio: 1; border-radius: 12px; display: flex; align-items: center; justify-content: center; overflow: hidden;
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.14); }
.sheep-slot.got { background: rgba(255,240,190,.14); border-color: rgba(255,220,140,.4); }
.sheep-slot .sheep-slot-img.art { width: 88%; height: 88%; max-width: none; object-fit: contain; }
.sheep-slot .art-emoji { font-size: 26px; }
.sheep-q { font-family: var(--ff-display); font-size: 20px; font-weight: 800; color: rgba(255,255,255,.28); }
/* The Royal Ball — teach a clumsy courtier to dance (rhythm, then memory) */
.dance-hero { display: flex; justify-content: center; }
.dance-hero img { height: 190px; width: auto; filter: drop-shadow(0 8px 16px rgba(0,0,0,.4)); animation: danceIn .3s ease; }
/* Ballroom stage: big dancer centered → move announcement → beat meter → big buttons */
.dance-stage { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; align-items: center;
  gap: 6px; padding: 8px 10px 10px; overflow: hidden; border-radius: 14px;
  background: url('../art/ballroom_bg.jpg') no-repeat center bottom; background-size: cover; }
.dance-stage::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(20,8,40,.32) 0%, rgba(20,8,40,.04) 26%, rgba(20,8,40,.10) 62%, rgba(20,8,40,.58) 100%); }
.dance-stage > * { position: relative; z-index: 1; }
.dance-dancer { flex: 1; min-height: 0; display: flex; align-items: flex-end; justify-content: center; width: 100%; }
.dance-dancer-img { height: 100%; max-height: 50vh; width: auto; object-fit: contain;
  filter: drop-shadow(0 10px 18px rgba(0,0,0,.55)); transition: opacity .16s ease, transform .16s ease; }
.dance-dancer-img.swapping { opacity: 0; transform: translateY(8px) scale(.97); }
.dance-dancer-img.glow-good { animation: danceHop .5s ease; filter: drop-shadow(0 0 20px rgba(130,255,160,.95)) drop-shadow(0 10px 18px rgba(0,0,0,.55)); }
.dance-dancer-img.glow-bad { animation: danceWob .5s ease; }
/* warm-up Start button: floats in the upper-middle, above the dancer's head */
.dance-stage .dance-start { position: absolute; top: 8%; left: 50%; transform: translateX(-50%); z-index: 4; width: auto; max-width: 84%; padding: 13px 28px; white-space: nowrap; box-shadow: 0 6px 18px rgba(0,0,0,.55); animation: danceIn .4s ease-out; }
@keyframes danceIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes danceHop { 0%,100% { transform: translateY(0) rotate(0); } 40% { transform: translateY(-12px) rotate(-4deg); } 70% { transform: translateY(0) rotate(3deg); } }
@keyframes danceWob { 0%,100% { transform: rotate(0); } 25% { transform: translateX(-8px) rotate(-6deg); } 55% { transform: translateX(7px) rotate(5deg); } 80% { transform: translateX(-3px) rotate(-2deg); } }
.dance-announce { text-align: center; font-family: var(--ff-display); color: #fff; }
.dance-announce .dance-cue { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 54px; font-size: 24px; line-height: 1.1; text-shadow: 0 2px 5px rgba(0,0,0,.85); }
.dance-announce .dance-cue-ic { font-size: 24px; }
/* the "what's next" cue is now just the gold arrow icon (pops in each step) */
.dance-announce .dance-cue-arrow { height: 50px; width: auto; max-width: 96px; display: block; filter: drop-shadow(0 2px 6px rgba(0,0,0,.7)); animation: danceCueArrow .5s cubic-bezier(.2,1.5,.4,1); }
@keyframes danceCueArrow { 0% { transform: scale(.5); opacity: 0; } 60% { transform: scale(1.12); opacity: 1; } 100% { transform: scale(1); } }
.dance-announce .dance-sub { font-size: 12.5px; color: #ffe6b0; margin-top: 2px; text-shadow: 0 1px 3px rgba(0,0,0,.85); }
.dance-fb { font-weight: 800; }
/* The beat track: a marker slides left→right, hitting the green line on the beat */
.beat-track { position: relative; width: 92%; max-width: 430px; height: 26px; border-radius: 13px; background: rgba(10,4,24,.5);
  border: 1px solid rgba(255,255,255,.25); overflow: hidden; margin: 2px 0; }
.beat-zone { position: absolute; top: 0; bottom: 0; border-radius: 4px;
  background: linear-gradient(90deg, rgba(126,224,138,0), rgba(126,224,138,.35), rgba(126,224,138,0)); }
.beat-line { position: absolute; top: -2px; bottom: -2px; width: 4px; margin-left: -2px;
  background: #7ee08a; border-radius: 2px; box-shadow: 0 0 10px #7ee08a; }
.beat-marker { position: absolute; top: 4px; bottom: 4px; width: 16px; margin-left: -8px; left: 0;
  border-radius: 8px; background: linear-gradient(#fff, #c58bff); box-shadow: 0 0 12px #c58bff; }
.dance-grace { position: relative; height: 10px; border-radius: 6px; background: rgba(10,4,24,.5); overflow: hidden; border: 1px solid rgba(255,255,255,.2); }
.dance-grace.top { width: 92%; max-width: 430px; }
.dance-grace > i { display: block; height: 100%; border-radius: 6px; background: linear-gradient(90deg,#ffd76a,#ff9de0,#b98cff); transition: width .25s ease; }
.dance-grace-mark { position: absolute; top: -2px; bottom: -2px; width: 3px; margin-left: -1.5px; background: var(--gold); border-radius: 2px; box-shadow: 0 0 6px var(--gold); }
.dance-buttons { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; width: 100%; max-width: 440px; }
.dance-btn { position: relative; padding: 0; border: none; background: none; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 2px; }
.dance-btn img { display: block; width: 100%; height: auto; filter: drop-shadow(0 3px 7px rgba(0,0,0,.6)); }
.dance-btn-nm { font-family: var(--ff-display); font-size: 11px; color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.9); }
.dance-btn:active { transform: scale(.93); }
.dance-btn:active img { filter: drop-shadow(0 0 10px rgba(255,230,150,.9)) drop-shadow(0 3px 7px rgba(0,0,0,.6)); }
/* 3-2-1 shown as a translucent overlay so you can see the stage/buttons behind it */
.dance-countdown { position: absolute; inset: 0; z-index: 5; display: flex; align-items: center; justify-content: center;
  background: rgba(10,4,24,.42); pointer-events: none; }
.cd-num { font-family: var(--ff-body); font-weight: 800; font-size: 128px; line-height: 1; color: #fff;
  text-shadow: 0 4px 18px rgba(0,0,0,.85), 0 0 30px rgba(197,139,255,.75); animation: cdPop .8s ease; }
.cd-num.go { font-size: 70px; color: #ffe08a; }
@keyframes cdPop { 0% { transform: scale(.4); opacity: 0; } 30% { transform: scale(1.14); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
/* The Drury Lane Bake-Off — study a decorated treat, recreate it from memory */
.cake-stage2 { display: flex; flex-direction: column; align-items: center; flex: 1; min-height: 0; gap: 6px; padding: 6px 8px 10px;
  background: linear-gradient(180deg, rgba(30,15,45,.55) 0%, rgba(30,15,45,.12) 20%, rgba(30,15,45,.10) 66%, rgba(30,15,45,.50) 100%), url('../art/bakery_bg.jpg') center/cover;
  border-radius: 14px; }
.cake-caption { font-size: 14px; color: #fff3d6; font-weight: 800; text-align: center; min-height: 18px; text-shadow: 0 1px 4px rgba(0,0,0,.85), 0 0 2px rgba(0,0,0,.7); }
.cake-arena { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; width: 100%; }
.cake-view { position: relative; display: inline-block; line-height: 0; }
/* Fill the screen. Tall cakes (more tiers) bind to height, so they show large and
   the tiers shrink as new ones are added; the short single tier binds to width so
   it also fills the screen. Bigger while studying (no button row). */
/* widths are capped to the 520px game frame (min with a px value) so the cake never
   spills past the frame on tablets/desktop, where vw is much wider than the frame */
.cake-img { display: block; filter: drop-shadow(0 6px 14px rgba(0,0,0,.45)); }
.cake-img.tall { height: 69vh; width: auto; max-width: min(96vw, 500px); }
.cake-stage2.studying .cake-img.tall { height: 72vh; }
.cake-img.wide { width: min(90vw, 468px); height: auto; max-height: 60vh; }
.cake-stage2.studying .cake-img.wide { max-height: 70vh; }
.cake-spot { position: absolute; transform: translate(-50%, -50%); aspect-ratio: 1; padding: 0; border: none; background: none;
  display: flex; align-items: center; justify-content: center; pointer-events: none; }
/* treats auto-fill left to right, so the painted circles on the cake art are the
   only guide — a soft ring just marks where the NEXT treat will land */
.cake-spot.next::before { content: ""; position: absolute; width: 66%; height: 66%; border-radius: 50%;
  border: 3px solid rgba(255,235,170,.95); box-shadow: 0 0 12px rgba(255,216,107,.9), 0 0 3px rgba(0,0,0,.5);
  animation: cakePulse 1.2s ease-in-out infinite; }
@keyframes cakePulse { 0%,100% { opacity: .5; transform: scale(.9); } 50% { opacity: 1; transform: scale(1.08); } }
.cake-spot-ic, .cake-spot-ic.art { width: calc(100% * var(--dsz, 1.2)); height: calc(100% * var(--dsz, 1.2)); max-width: none; max-height: none; object-fit: contain; filter: drop-shadow(0 2px 4px rgba(0,0,0,.5)); }
.cake-spot .art-emoji { font-size: 26px; line-height: 1; }
/* finished tiers fade back while you memorise the fresh tier */
.cake-spot.done.dim { opacity: .32; transition: opacity .3s; }
/* the treats you're memorising get a warm glow */
.cake-spot.target .cake-spot-ic { animation: cakeGlow 1.4s ease-in-out infinite; }
@keyframes cakeGlow {
  0%,100% { filter: drop-shadow(0 2px 3px rgba(0,0,0,.45)) drop-shadow(0 0 4px rgba(255,225,150,.8)); }
  50%     { filter: drop-shadow(0 2px 3px rgba(0,0,0,.45)) drop-shadow(0 0 12px rgba(255,220,120,1)) drop-shadow(0 0 18px rgba(255,200,90,.7)); }
}
/* undo / redo flank the treat row, just above it */
.cake-actions { display: flex; justify-content: space-between; align-items: center; width: 100%; max-width: 348px; margin-bottom: 5px; }
.cake-act { font-family: var(--ff-display); font-size: 14px; font-weight: 800; color: #ffe6b0; background: rgba(60,30,80,.55);
  border: 2px solid rgba(255,255,255,.3); border-radius: 11px; padding: 6px 14px; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,.35); }
.cake-act:active { transform: scale(.94); }
.cake-act:disabled { opacity: .35; cursor: default; }
/* one compact row of six — small tiles, but the treat icon fills each one */
.cake-tools2 { display: grid; grid-template-columns: repeat(6, 1fr); gap: 5px; width: 100%; max-width: 348px; box-sizing: border-box; }
.cake-tool2 { aspect-ratio: 1; min-width: 0; border-radius: 13px; border: 2px solid rgba(255,255,255,.35);
  background: linear-gradient(160deg,#fff3d6,#ffd9ec 55%,#e9c8ff); box-shadow: 0 2px 6px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.7);
  display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 3px; overflow: visible; }
.cake-tool2.sel { border-color: var(--gold); background: linear-gradient(160deg,#fff6c9,#ffe08a 60%,#ffd76a);
  box-shadow: 0 0 14px rgba(255,216,107,.8), inset 0 1px 0 rgba(255,255,255,.8); transform: translateY(-2px) scale(1.06); z-index: 2; }
.cake-tool2:active { transform: scale(.92); }
.cake-tool2-ic, .cake-tool2-ic.art { width: 112%; height: 112%; max-width: none; max-height: none; object-fit: contain; filter: drop-shadow(0 2px 3px rgba(0,0,0,.35)); }
.cake-tool2 .art-emoji { font-size: 34px; line-height: 1; }
.cake-study-bar { width: 100%; max-width: 340px; height: 10px; border-radius: 6px; background: rgba(255,255,255,.15); overflow: hidden; }
.cake-study-bar > i { display: block; height: 100%; width: 100%; border-radius: 6px; background: linear-gradient(90deg,#ffd76a,#ff9de0); }
/* The Evil Queen — ransom brewing */
/* The Evil Queen's story-mode scene: she stands tall and HIGH so her face is never buried;
   figure beats keep their text minimal, and the info-heavy offer beat drops her entirely. */
/* She's a big image with a drop-shadow, so the default slide-up entrance repaints her every frame
   and lags. Give her a plain opacity fade on a promoted GPU layer instead — smooth, no jank. */
.story-figure.queen { height: 92vh; bottom: 0; will-change: opacity; transform: translateX(-50%) translateZ(0);
  animation: queenFigIn .28s ease-out; }
.story-figure.queen img.story-face { height: 100%; max-width: 100vw; }
@keyframes queenFigIn { from { opacity: 0; } to { opacity: 1; } }
.queen-card .story-below { gap: 9px; }
.queen-card.nofig { justify-content: center; }   /* offer beat has no figure — center the bargain */
.queen-offer-title { font-weight: 900; font-size: 19px; color: #fff6e6; letter-spacing: .3px;
  padding: 6px 18px; border-radius: 999px; background: linear-gradient(180deg, #b8517e, #8a3a63);
  box-shadow: 0 3px 10px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.25); }
.queen-terms { font-size: 12.5px; font-weight: 800; color: #ffe6f4; text-align: center; max-width: 400px;
  background: rgba(38,10,42,.62); padding: 6px 12px; border-radius: 11px; box-shadow: 0 2px 8px rgba(0,0,0,.4); }
.queen-terms b { color: #ffd34d; }
.queen-note { font-size: 12px; line-height: 1.42; color: #ece0ef; text-align: center; max-width: 344px;
  text-shadow: 0 1px 3px rgba(0,0,0,.7); }
.queen-note b { color: #ffcf6a; }
.queen-btns { width: 100%; max-width: 360px; display: flex; flex-direction: column; gap: 8px; }
.queen-btns .btn { width: 100%; }
.queen-stats { width: 100%; max-width: 330px; }
.queen-buys { display: flex; flex-direction: column; gap: 8px; width: 100%; max-width: 300px; }
.queen-foe { display: flex; align-items: center; gap: 10px; padding: 4px 2px; font-size: 13px; }
.queen-face { font-size: 38px; line-height: 1; }
.queen-brew-row { padding: 6px 2px; text-align: center; }
.queen-slots { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; align-items: center; min-height: 46px; margin-top: 4px; }
.queen-slot { width: 46px; height: 46px; border-radius: 11px; background: var(--card2); border: 1px solid rgba(224,123,224,.4);
  display: flex; align-items: center; justify-content: center; cursor: pointer; }
.queen-slot img.art { height: 28px; width: auto; }
.queen-slot .art-emoji { font-size: 26px; line-height: 1; }
.queen-slot:active { transform: scale(.9); }
/* Villain (Evil Queen) theming for the reused scoop / pop / mix pipeline */
body.villain #app { background: radial-gradient(circle at 50% 12%, #3a1550 0%, #22103a 52%, #0c1710 100%); }
body.villain .pbubble {
  background: radial-gradient(circle at 34% 28%, rgba(224,255,205,.95), rgba(120,210,90,.42) 52%, rgba(52,112,42,.30) 100%);
  border-color: rgba(190,255,150,.45);
  box-shadow: 0 6px 16px rgba(0,0,0,.42), inset 0 -6px 10px rgba(28,86,28,.42);
}
/* NOTE: the Evil Queen's scoop now has its own hand-painted art (purple chamber + amethyst
   sifter), so we do NOT hue-rotate it green any more — it shows its true colours. */
body.villain .cauldron .liquid { filter: saturate(1.25) hue-rotate(8deg); }
body.villain .scoop-instr, body.villain .pop-sub { color: #c9f5b0; }
.slot.removable { cursor: pointer; box-shadow: 0 0 0 1.5px rgba(255,140,140,.5) inset; }
.slot.removable:active { transform: scale(.9); }
.poison-badge { position: absolute; top: -6px; right: -6px; font-size: 14px; filter: drop-shadow(0 0 3px rgba(0,0,0,.6)); pointer-events: none; }
.inv-tile.poisoned, .slot.poisoned { box-shadow: 0 0 0 2px var(--bad) inset; }
/* Infused ingredients (built-in charm effect) — glow + effect label */
.inv-tile.infused { box-shadow: 0 0 0 2px rgba(255,216,107,.7) inset, 0 0 12px rgba(255,216,107,.35); }
.infused-tag { font-size: 9px; font-weight: 800; color: var(--gold); line-height: 1.1; margin-top: 2px; }
/* Realms — location chip on the start screen + the World Map */
.realm-here { display: inline-block; margin: 6px 0 2px; padding: 4px 12px; border-radius: 999px; font-weight: 800; font-size: 13px;
  background: rgba(255,255,255,.1); border: 1px solid var(--line); }
.realm-list { display: flex; flex-direction: column; gap: 10px; padding: 2px; }
.realm-card { display: flex; align-items: center; gap: 12px; padding: 12px; border-radius: 16px;
  background: var(--card); border: 1px solid var(--line); }
.realm-card.here { border-color: rgba(126,224,138,.6); box-shadow: 0 0 12px rgba(126,224,138,.2); }
.realm-card.locked { opacity: .82; }
.realm-icon { font-size: 40px; line-height: 1; flex: 0 0 auto; }
.realm-body { flex: 1; min-width: 0; }
.realm-name { font-weight: 800; font-size: 16px; }
.realm-cast { font-size: 17px; margin-top: 4px; letter-spacing: 2px; }
/* realm "story path" — chapters uncovered as you play events (framed as story, not a quota) */
.realm-story { display: flex; align-items: center; gap: 7px; margin-top: 6px; flex-wrap: wrap; }
.story-lbl { font-size: 11px; font-weight: 800; color: #d8c6ff; letter-spacing: .3px; }
.story-pips { display: inline-flex; gap: 5px; align-items: center; }
.story-pip { width: 9px; height: 9px; border-radius: 50%; background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.22); }
.story-pip.on { background: radial-gradient(circle at 35% 30%, #ffe9a8, #ffce54 60%, #f0a93c); border-color: #ffd86b; box-shadow: 0 0 6px rgba(255,206,84,.6); }
.realm-story.done .story-lbl { color: var(--gold); }
.realm-status { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; text-align: right; }
.realm-tag { font-size: 12px; font-weight: 700; }
.realm-tag.here { color: var(--good); }
.realm-cost { display: flex; gap: 8px; font-weight: 800; font-size: 13px; }
/* King's Courtyard palette (applied via body.realm-courtyard during that realm) */
body.realm-courtyard #app { background: radial-gradient(circle at 50% 12%, #4a2a6e 0%, #34205a 52%, #1c1230 100%); }
body.realm-courtyard .realm-here { background: linear-gradient(90deg, rgba(255,216,107,.22), rgba(185,140,255,.22)); border-color: rgba(255,216,107,.4); }

/* =======================================================================
 * MIXING SCREEN — redesign (v106): two-column layout, pet badge, cast bars,
 * ornate Serve button, sorted+stacked ingredient panel.
 * ===================================================================== */
.mixv { flex: 1; min-height: 0; display: flex; flex-direction: column;
  margin: -8px -14px -12px; padding: 6px 8px 8px;
  background: linear-gradient(rgba(24,10,34,.5), rgba(24,10,34,.66)), url('../art/mix_bg.jpg') center/cover no-repeat; }
/* header: pet badge (left), customer (center), menu (right) */
.mixv-head { display: flex; align-items: center; gap: 8px; padding: 2px 2px 4px; }
.petbadge { position: relative; width: 128px; height: 132px; flex: 0 0 auto; cursor: pointer;
  background: url('../art/pet_frame_dark.webp') center/contain no-repeat; }
.petbadge-pet { position: absolute; left: 50%; top: 32%; transform: translate(-50%,-50%);
  width: 86px; height: 86px; display: flex; align-items: center; justify-content: center; font-size: 64px; }
.petbadge-pet img.art { width: 84px !important; height: 84px !important; max-width: none; max-height: none; object-fit: contain; }
/* painted multi-face pets: fill the dark circle, let ears/head spill over the top rim, keep the
   treat scroll below visible. The pet element spans the whole frame so it can overflow the rim. */
.petbadge-pet:has(img.buddy-multi) { inset: 0; left: 0; top: 0; width: auto; height: auto; transform: none; display: block; }
.petbadge-pet img.buddy-multi { position: absolute; left: 50%; top: 56px; transform: translate(-50%,-50%);
  width: 120px !important; height: 120px !important; object-fit: contain; object-position: center;
  filter: drop-shadow(0 3px 4px rgba(0,0,0,.55)); pointer-events: none; }
.petbadge-count { position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 2;
  font-weight: 900; font-size: 17px; color: #4a2f0c; white-space: nowrap; letter-spacing: .3px; }
.mixv-cust { flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 5px;
  font-weight: 700; font-size: 13px; color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,.8); }
.mixv-cust span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mixv-cust img.art { width: 24px !important; height: 24px !important; max-width: none; max-height: none; object-fit: contain; vertical-align: middle; }
.mixv-menu { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 11px; font-size: 20px;
  color: #ffe6b0; background: rgba(50,24,72,.7); border: 1.5px solid rgba(255,214,110,.55); cursor: pointer; }
/* body: two columns */
.mixv-body { flex: 1; min-height: 0; display: flex; gap: 8px; }
.mixv-left { flex: 1.28; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: 5px; }
.mixv-right { flex: 1; min-width: 0; min-height: 0; display: flex; }
/* cauldron — bigger, with a stream of bubbles */
.mixv-cauldron { display: flex; align-items: center; justify-content: center; flex: 0 0 auto; padding: 4px 0 2px; }
.mixv .cauldron { width: min(58vw, 232px); height: min(30vh, 202px);
  border: 3px solid rgba(255,214,110,.55); border-top-width: 6px; border-radius: 26px 26px 74px 74px / 26px 26px 60px 60px;
  background: radial-gradient(ellipse at 50% 118%, rgba(96,52,132,.55), rgba(22,10,32,.78));
  box-shadow: inset 0 -12px 30px rgba(0,0,0,.55), inset 0 3px 10px rgba(255,214,110,.15), 0 8px 22px rgba(0,0,0,.45); }
.mixv .cauldron .pct { font-size: clamp(24px, 7.5vw, 36px); z-index: 3; }
.mixv .cauldron .liquid { opacity: .92; box-shadow: 0 -3px 10px rgba(255,255,255,.25); }
.cauldron .b4 { left: 42%; animation-delay: 1.4s; } .cauldron .b5 { left: 62%; animation-delay: .7s; }
/* slots row — smaller */
.mixv-slots { flex: 0 0 auto; }
.mixv-slots .slot { width: 34px; height: 34px; border-radius: 9px; font-size: 19px; }
.mixv-slots .slot .orb { width: 20px; height: 20px; }
.mixv-slots .slot img.art { max-width: 1.05em; }
/* meters area (scrolls if tall) */
.mixv-meters { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 5px; padding: 1px 2px 0 0; }
/* cast bar: color circle + track with fill + green target band */
.castbar { display: flex; align-items: center; height: 30px; flex: 0 0 auto; }
.cb-orb { width: 30px; height: 30px; flex: 0 0 auto; position: relative; z-index: 3; display: flex; align-items: center; justify-content: center;
  font-size: 15px; background: url('../art/cb_circle.webp') center/contain no-repeat; }
.cb-orb:not(.myst):not(.danger)::before { content: ""; position: absolute; inset: 26%; border-radius: 50%;
  background: radial-gradient(circle at 38% 32%, rgba(255,255,255,.75), var(--oc, #888)); box-shadow: 0 0 6px var(--oc, #888); }
.cb-track { flex: 1; height: 27px; position: relative; margin-left: -7px; overflow: hidden; border-radius: 13px;
  background: url('../art/cb_track.webp') left center/100% 100% no-repeat; }
.cb-band { position: absolute; top: 20%; bottom: 20%; z-index: 1; border-radius: 3px; background: rgba(126,224,138,.42); }
.cb-fill { position: absolute; left: 0; top: 24%; height: 52%; z-index: 2; border-radius: 7px; transition: width .35s ease, background .35s; }
.cb-name { position: absolute; left: 16px; top: 50%; transform: translateY(-50%); z-index: 4; font-size: 12px; font-weight: 700;
  color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.85); text-transform: capitalize; white-space: nowrap; }
.cb-stat { position: absolute; right: 9px; top: 50%; transform: translateY(-50%); z-index: 4; font-size: 12px; font-weight: 800; text-shadow: 0 1px 3px rgba(0,0,0,.85); }
.castbar.hit .cb-track { box-shadow: 0 0 9px var(--good); }
/* ornate Serve button */
.servebtn { position: relative; width: 100%; max-width: 262px; margin: 1px auto 0; aspect-ratio: 686 / 389; flex: 0 0 auto;
  background: url('../art/serve_unmet.webp') center/contain no-repeat; border: none; cursor: pointer; transition: transform .1s; }
.servebtn.met { background-image: url('../art/serve_met.webp'); }
.servebtn:active { transform: scale(.97); }
.servebtn:disabled { opacity: .55; filter: saturate(.6); cursor: default; }
.serve-label { position: absolute; left: 9%; right: 9%; top: 55%; height: 34%; display: flex; align-items: center; justify-content: center; gap: 6px; }
.serve-pct { color: #ffe9b0; font-weight: 800; text-shadow: 0 1px 3px rgba(0,0,0,.6); }
.servebtn.met .serve-pct { color: #16341a; text-shadow: 0 1px 2px rgba(255,255,255,.35); }
.serve-pct b { font-size: clamp(17px, 5vw, 27px); }
.serve-need { font-size: .58em; opacity: .85; font-weight: 700; }
.serve-hg { font-size: .74em; font-weight: 800; color: #ffe9b0; }
.serve-hg.urgent { color: #ff6b6b; animation: hgpulse .6s infinite; }
@keyframes hgpulse { 0%,100% { opacity: 1; } 50% { opacity: .4; } }
/* ingredient panel (right column) */
.ipanel { flex: 1; min-height: 0; display: flex; position: relative; padding: 15px 11px 17px;
  background: url('../art/panel_ingredients.webp') center/100% 100% no-repeat; }
.ipanel-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 2px 3px; }
.ipanel-scroll::-webkit-scrollbar { width: 5px; } .ipanel-scroll::-webkit-scrollbar-thumb { background: rgba(255,214,110,.4); border-radius: 3px; }
.itag { height: 25px; margin: 3px auto 6px; background-position: center; background-repeat: no-repeat; background-size: contain; }
.itag-charms { background-image: url('../art/tag_charms.webp'); width: 118px; }
.itag-ing { background-image: url('../art/tag_ingredients.webp'); width: 150px; }
.igrid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 4px; }
.ptile { position: relative; display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 0;
  padding: 5px 3px 6px; border-radius: 10px; cursor: pointer; background: rgba(38,18,52,.62);
  border: 1.5px solid rgba(255,214,110,.5); box-shadow: inset 0 0 8px rgba(0,0,0,.3); transition: transform .1s; }
.ptile:active { transform: scale(.93); }
.ptile-art { height: 36px; display: flex; align-items: center; justify-content: center; font-size: 27px; position: relative; }
.ptile-art img.art { width: 34px !important; height: 34px !important; max-width: none; max-height: none; object-fit: contain; }
.ptile-q { font-size: 12px; font-weight: 600; line-height: 1.2; color: #efe2ff; text-align: center; word-break: break-word; }
.ptile-q .dot { width: 9px; height: 9px; margin-right: 1px; }
.q-infused { color: var(--gold); font-weight: 700; }
.ptile-nm { font-size: 11.5px; font-weight: 700; line-height: 1.15; color: var(--gold); text-align: center; }
.ptile-count { position: absolute; top: 2px; right: 3px; background: rgba(0,0,0,.66); color: #fff; font-size: 11px; font-weight: 800; border-radius: 8px; padding: 0 5px; z-index: 4; }
.ptile-star { position: absolute; top: 1px; left: 3px; font-size: 12px; z-index: 4; }
.ptile.potent { border-color: var(--gold); box-shadow: 0 0 9px rgba(255,216,107,.5); }
.ptile.infused { border-color: #c9a0ff; box-shadow: 0 0 9px rgba(185,140,255,.5); }
.ptile.essence { border-style: dashed; }
.ptile.poisoned { border-color: var(--bad); }
.ptile.charm { background: rgba(60,30,86,.7); border-color: rgba(255,214,110,.7); }
.ptile.toolon { box-shadow: 0 0 11px var(--gold); border-color: var(--gold); }
.ipanel.cutting .ptile.cuttable { outline: 2px solid var(--gold); outline-offset: 1px; animation: cutpulse 1s ease-in-out infinite; }
.ptile.glow { animation: tileGlow 1.6s ease; }
@keyframes tileGlow { 0% { box-shadow: 0 0 3px #fff; } 25% { box-shadow: 0 0 16px 5px #9ff0e0; border-color: #9ff0e0; } 100% { box-shadow: inset 0 0 8px rgba(0,0,0,.3); } }
.ptile .poison-badge, .ptile .pinch-badge { position: absolute; }
.ptile .poison-badge { top: -2px; right: -2px; font-size: 13px; }
.ptile .pinch-badge { bottom: -2px; right: -2px; font-size: 12px; }
.ipanel-empty { color: var(--ink-dim); text-align: center; padding: 22px 8px; font-size: 13px; }
.mix-hint { text-align: center; font-size: 12px; margin: 2px auto 0; flex: 0 0 auto; }
.mix-hint.gold { color: var(--gold); }
.mix-hint.muted { color: var(--ink-dim); }

/* =======================================================================
 * MIXING SCREEN v2 — cauldron-hero layout (art-light placeholder pass).
 * Vertical stack: header · cauldron(+arcs,timer) · have/need · slots ·
 * bars · bottom tray (pinned charms + scrolling ingredient cards).
 * ===================================================================== */
.mixv2 { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 5px;
  margin: -8px -14px -12px; padding: 6px 10px 8px;
  background: url('../art/mix_bg.jpg?v=351') center top / cover no-repeat, #160c26; }
/* Evil Queen's mix chamber: her own backdrop, plus a lightning-strike layer (the same room lit
   blue) that JS flashes on at random then fades — like real lightning brightening the room. */
/* isolation:isolate makes .mixv2 its OWN stacking context, so the z-index:-1 flash layer sits
   ABOVE this background (between it and the cauldron) instead of hiding behind it. */
.mixv2.villain { isolation: isolate; background: url('../art/queen_mix_bg.jpg?v=370') center top / cover no-repeat, #140a24; }
/* King's Courtyard mixing chamber — same cover fit as the default mix backdrop */
.mixv2.courtyard { background: url('../art/courtyard_mix_bg.jpg?v=526') center top / cover no-repeat, #160c26; }
/* --- Courtyard ambience: soft window light + drifting dust (lives on #app, JS-toggled) ------
   Kept blurred and low-opacity so it reads as haze/dust in the air, matching the blurry bg.
   pointer-events:none so it never blocks taps; only visible when .show is set on the mix screen. */
#court-ambient { position: absolute; inset: 0; z-index: 3; pointer-events: none; overflow: hidden;
  opacity: 0; transition: opacity .6s ease;
  /* fade the whole layer out toward the bottom so motes don't distract from the needs bars + tray */
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 40%, rgba(0,0,0,.20) 70%, transparent 90%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 40%, rgba(0,0,0,.20) 70%, transparent 90%); }
#court-ambient.show { opacity: 1; }
/* three faint light shafts angling down from the dome windows; screen-blend so they only lighten */
.ca-beam { position: absolute; top: -12%; width: 46%; height: 96%; mix-blend-mode: screen;
  filter: blur(16px); transform-origin: top center; will-change: opacity;
  background: linear-gradient(178deg, rgba(255,248,214,.42) 0%, rgba(255,244,198,.20) 34%, rgba(255,240,190,0) 72%); }
.ca-b1 { left: 6%;  transform: rotate(9deg);  animation: caBeam 9s ease-in-out infinite; }
.ca-b2 { left: 34%; transform: rotate(-4deg); animation: caBeam 11s ease-in-out infinite .8s; opacity: .8; }
.ca-b3 { left: 60%; transform: rotate(6deg);  animation: caBeam 13s ease-in-out infinite 1.6s; opacity: .7; }
@keyframes caBeam { 0%,100% { opacity: .30; } 50% { opacity: .68; } }
/* blurred dust motes: soft round highlights that drift slowly upward, sway, and twinkle */
.ca-mote { position: absolute; bottom: -8%; border-radius: 50%; filter: blur(1.6px);
  mix-blend-mode: screen; opacity: 0; will-change: transform, opacity;
  background: radial-gradient(circle, rgba(255,250,228,.95) 0%, rgba(255,246,210,.5) 45%, rgba(255,244,200,0) 72%);
  animation: caMote var(--dur) linear infinite; animation-delay: var(--delay); }
@keyframes caMote {
  0%   { transform: translate3d(0,0,0); opacity: 0; }
  10%  { opacity: var(--op); }
  50%  { transform: translate3d(var(--drift), -55vh, 0); opacity: var(--op); }
  90%  { opacity: var(--op); }
  100% { transform: translate3d(0, -108vh, 0); opacity: 0; }
}
/* the "room lit blue" layer — the flash art fades in over the normal chamber (behind the cauldron)
   then fades out, like lightning through the window. JS drives the opacity at random. */
.mix-lightning { position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: 0;
  background: url('../art/queen_mix_flash.jpg?v=374') center top / cover no-repeat;
  filter: brightness(1.28) saturate(1.12); will-change: opacity; }
.m2-head { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.m2-cust { flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 6px; }
.m2-cust img.art { width: 40px !important; height: 40px !important; max-width: none; max-height: none; object-fit: contain;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.6)); }
/* stage: cauldron centered, timer floats above */
.m2-stage { position: relative; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; gap: 0; padding-top: 6px; margin-top: 22px; }
.m2-timer { flex: 0 0 auto; margin-top: auto; display: flex; justify-content: center; min-height: 0; margin-bottom: 1px; z-index: 6; }
.m2-timer-badge { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 74px; height: 74px;
  border-radius: 50%; background: radial-gradient(circle at 50% 34%, #ff5a5a, #c62828); border: 4px solid var(--gold);
  color: #fff; box-shadow: 0 4px 12px rgba(0,0,0,.5); }
.m2-timer-badge b { font-size: 26px; line-height: 1; font-weight: 900; }
.m2-timer-badge span { font-size: 10px; letter-spacing: .5px; opacity: .95; }
.m2-timer-badge.urgent { animation: hgpulse .6s infinite; }
.m2-cauldron { position: relative; display: flex; flex-direction: column; align-items: center; cursor: pointer; z-index: 3; }
.mixv2 .cauldron { width: min(66vw, 264px); height: min(30vh, 198px); position: relative; overflow: hidden;
  border-radius: 42% 42% 46% 46% / 26% 26% 74% 74%; border: 4px solid rgba(255,214,110,.6); border-top-width: 8px;
  background: radial-gradient(ellipse at 50% 26%, #462c68, #241436 72%);
  box-shadow: inset 0 -16px 34px rgba(0,0,0,.55), inset 0 4px 12px rgba(255,214,110,.14), 0 10px 26px rgba(0,0,0,.45); }
.m2-cauldron.ready .cauldron { animation: cauldronReady 1.1s ease-in-out infinite; border-color: var(--good); }
@keyframes cauldronReady { 0%,100% { box-shadow: inset 0 -16px 34px rgba(0,0,0,.55), 0 0 10px rgba(126,224,138,.5); } 50% { box-shadow: inset 0 -16px 34px rgba(0,0,0,.55), 0 0 26px 6px rgba(126,224,138,.8); } }
/* Sit the hint UP between the cauldron's legs (over the pot art), so it's clearly above the
   used-ingredient row instead of dropping onto it. */
.serve-hint { position: absolute; left: 0; right: 0; bottom: 5.5%; text-align: center; z-index: 6; pointer-events: none;
  font-size: 12px; font-weight: 800; color: var(--good); text-shadow: 0 1px 3px rgba(0,0,0,.85), 0 0 6px rgba(0,0,0,.65); }
.m2-cauldron.ready .serve-hint { animation: hgpulse 1s infinite; }
/* --- art cauldron: a glow line at the rim + rising bubbles, both coloured by the
   dominant magic (green the instant the wish is met); bubble count grows with the
   number of ingredients in the pot. The fx sit BEHIND the pot so they read as coming
   from inside. --mix-color / --pulse-color are set inline per render. --- */
.caul-art { position: relative; z-index: 1; width: min(96vw, 396px); aspect-ratio: 1500 / 990; overflow: visible; }
/* --- MIX LAYOUT: the % readout sits up top; the (bigger) cauldron drops low to nearly rest on
   the ingredient-slot row. Self-contained + reversible — to move the % back under the pot,
   change ONLY the .m2-readout order below from 20 to 45 (see note). Delete this whole block to
   restore the original centered layout. --- */
.mixv2 { justify-content: flex-start; position: relative; }
.m2-head    { order: 10; min-height: 132px; }   /* reserves the space the overlay pet floats over */
.m2-readout { order: 20; margin-top: -42px !important; }   /* % position — change to order: 45 to put it back under the cauldron */
.m2-readout b { font-size: clamp(34px, 12vw, 52px) !important; }   /* bigger % number */
.m2-timer   { position: absolute !important; top: 108px; left: 18px; margin: 0 !important; z-index: 8; }  /* In-a-Rush countdown docks under the pet badge */
.m2-stage   { order: 40; margin-top: auto !important; padding-top: 0 !important; z-index: 5 !important; }  /* flexible spacer pushes the pot low; layered in front of the slots */
.m2-slots   { order: 50; margin-top: -18px !important; } /* pot drops down to rest ON this row */
.m2-bars    { order: 60; }
.m2-tray    { order: 80; }   /* charms now live INSIDE the tray, pinned to its left */
/* the pot gets excited as it fills — a gentle bounce, then a bigger hop when the next drop is the last.
   Lives on the wrapper so it layers cleanly with the per-drop .splash on the image, and leaves the % text alone. */
.m2-cauldron { transform-origin: 50% 88%; }
.m2-cauldron.excited { animation: caulExcited 1.15s ease-in-out infinite; }
.m2-cauldron.excited-max { animation: caulExcitedBig .85s ease-in-out infinite; }
@keyframes caulExcited {
  0%,100% { transform: translateY(0) scaleX(1) scaleY(1); }
  50%     { transform: translateY(-1.5px) scaleX(1.006) scaleY(.996); } }
@keyframes caulExcitedBig {
  0%,100% { transform: translateY(0) scaleX(1) scaleY(1); }
  50%     { transform: translateY(-3.5px) scaleX(1.014) scaleY(.99); } }
.caul-art .caul-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain;
  filter: drop-shadow(0 10px 16px rgba(0,0,0,.5)); z-index: 2; pointer-events: none; }
.caul-art.splash { animation: splash .4s ease; }
/* Oven pot: firelight over the flame door. Screen-blend so it brightens the painted flames.
   Two layers on different tempos so the light never looks like a steady, mechanical pulse:
   a fast, irregular flicker (the dancing flames) + a slow warm halo (heat spilling out). */
.oven-fire, .oven-glow { position: absolute; z-index: 3; pointer-events: none; border-radius: 50%;
  mix-blend-mode: screen; will-change: opacity; }
/* brightness is set randomly from JS (startOvenFlicker); the transitions just smooth between
   the random targets, so the firelight flickers organically with no repeating pattern */
.oven-fire { left: 27%; top: 30%; width: 46%; height: 48%; filter: blur(9px); opacity: .82;
  background: radial-gradient(ellipse 60% 72% at 50% 58%, rgba(255,253,225,1), rgba(255,150,35,.95) 40%, rgba(225,55,0,0) 74%);
  transition: opacity .16s ease-out; }
.oven-glow { left: 2%; top: 10%; width: 96%; height: 82%; filter: blur(34px); opacity: .62;
  background: radial-gradient(circle, rgba(255,120,25,.78), rgba(170,35,0,0) 64%);
  transition: opacity .34s ease-out; }
/* Occasional embers + smoke: sparks and a wisp are spawned from JS (spawnOvenEmbers) every 5-10s.
   Each element carries its own --dx / --rise / --dur so no two drift alike. */
.oven-embers { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 4;
  pointer-events: none; overflow: visible; }
.oven-embers .ember { position: absolute; top: 46%; border-radius: 50%;
  background: radial-gradient(circle, #ffd27a 0%, #ff8a1e 42%, rgba(255,90,0,0) 74%);
  box-shadow: 0 0 12px 3px rgba(255,120,20,1), 0 0 22px 6px rgba(255,80,0,.7);
  mix-blend-mode: screen; opacity: 0;
  will-change: transform, opacity; animation: emberRise var(--dur, 1800ms) ease-out forwards; }
.oven-embers .ember-smoke { position: absolute; top: 42%; width: 44px; height: 44px;
  border-radius: 50%; background: radial-gradient(circle, rgba(90,84,78,.9), rgba(90,84,78,0) 68%);
  filter: blur(5px); opacity: 0; will-change: transform, opacity;
  animation: emberSmoke var(--dur, 3000ms) ease-out forwards; }
@keyframes emberRise {
  0%   { transform: translate(0, 0) scale(.7); opacity: 0; }
  14%  { opacity: 1; }
  70%  { opacity: .9; }
  100% { transform: translate(var(--dx, 0), var(--rise, -110px)) scale(.4); opacity: 0; }
}
@keyframes emberSmoke {
  0%   { transform: translate(0, 0) scale(.5); opacity: 0; }
  25%  { opacity: .85; }
  60%  { opacity: .6; }
  100% { transform: translate(var(--dx, 0), -140px) scale(3); opacity: 0; }
}
/* Queen's Mirror: face layer sits BEHIND the pot image (z 0 < image z 2) and shows through the
   transparent mirror oval. Each face art shares the pot's canvas, so it always lands in the mirror.
   A new face fades in over the previous one when you add an ingredient. */
.mirror-faces { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.mirror-face { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.mirror-face.fading { animation: faceFade .5s ease; }
@keyframes faceFade { from { opacity: 0; } to { opacity: 1; } }
/* outgoing face fades out and STAYS gone (forwards) — used for the fish bowl, whose fish sit at
   different spots so the old one must actually disappear rather than be covered by the new one */
.mirror-face.fading-out { animation: faceFadeOut .5s ease forwards; }
@keyframes faceFadeOut { from { opacity: 1; } to { opacity: 0; } }
/* dark, dormant mirror glass shown before the first ingredient (no face revealed yet) */
.mirror-dormant { position: absolute; left: 39.5%; top: 34%; width: 21%; height: 42%; border-radius: 50%;
  background: radial-gradient(circle, rgba(38,16,60,.82), rgba(12,6,26,.94) 72%); }
/* fx layer lives behind the pot image (z-index 1 < image z-index 2) */
.caul-fx { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.caul-fx.fx-in { animation: fxFadeIn .4s ease; }
@keyframes fxFadeIn { from { opacity: 0; } to { opacity: 1; } }
.caul-rim { position: absolute; left: var(--rim-l, 24%); right: var(--rim-r, 24%); top: var(--rim-t, 4%); height: 5%; border-radius: 50%;
  background: var(--mix-color, #c48bff); filter: blur(3.5px) saturate(2.3) brightness(1.5); pointer-events: none;
  box-shadow:
    0 0 5px 2px #fff,
    0 0 12px 4px rgba(255,255,255,.92),
    0 0 24px 9px var(--mix-color, #c48bff),
    0 0 46px 17px var(--mix-color, #c48bff),
    0 -10px 44px 19px var(--mix-color, #c48bff);
  animation: caulRim 1.7s ease-in-out infinite; }
@keyframes caulRim { 0%,100% { opacity: .84; } 50% { opacity: 1; } }
.caul-bubbles { position: absolute; left: var(--bub-l, 14%); right: var(--bub-r, 14%); top: var(--bub-t, 7%); height: 0; z-index: 1; pointer-events: none; }
.caul-bubbles.front { z-index: 3; }               /* bath: bubbles float in front of the tub art */
.caul-bubbles.fx-in { animation: fxFadeIn .4s ease; }
/* Per-skin rim anchoring. Most cauldrons have a flat rim at the top of the frame, so the shared
   defaults above sit on it. These two royal pots (King's Courtyard) have their real rim lower on
   the art, so they declare where the glow line + bubbles belong. The bubble bath also floats its
   glow ABOVE the pot art (fx-front) so the light reads as glowing bath water, not a hidden inner glow. */
.caul-art.skin-cauldron_royalbath { --rim-t: 17%; --rim-l: 15%; --rim-r: 15%; --bub-t: 16%; --bub-l: 17%; --bub-r: 17%; }
.caul-art.skin-cauldron_crown { --rim-t: 10%; --rim-l: 22%; --rim-r: 22%; --bub-t: 12%; --bub-l: 24%; --bub-r: 24%; }
/* Queen's Mirror: glow sits BEHIND the pot (rising over the rim like the classic). Her gold rim
   is very wide, so the default-width glow spread into a broad, weak, detached haze — narrowing it
   (bigger insets) concentrates it into a focused rise that hugs the rim. */
.caul-art.skin-cauldron_queen { --rim-t: 4%; --rim-l: 32%; --rim-r: 32%; }
/* Wishy's Fish Bowl: three stacked layers on one shared canvas — the back bowl (water) behind,
   the fish (mirror layer, z0) swimming in the middle, and the front bowl with its transparent
   porthole (caul-img, z2) on top. The back renders first in the DOM so it sits under the fish.
   The whole fish layer bobs up and down gently, so whichever fish is shown drifts in the water.
   Glow + bubbles are anchored to the water line, narrowed to sit inside the round bowl. */
.caul-art.skin-cauldron_wishy .caul-back { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; z-index: 0; pointer-events: none; }
.caul-art.skin-cauldron_wishy .mirror-faces { animation: fishFloat 4.2s ease-in-out infinite; will-change: transform; }
@keyframes fishFloat { 0%, 100% { transform: translateY(-1.4%); } 50% { transform: translateY(1.4%); } }
.caul-art.skin-cauldron_wishy { --rim-t: 22%; --rim-l: 22%; --rim-r: 22%; --bub-t: 24%; --bub-l: 24%; --bub-r: 24%; }
/* Pumpkin Carriage: the carriage is the pot art (caul-img, z2). A mouse leans OUT the door, so its
   layer is lifted in FRONT of the carriage (z3, above the art) — the inverse of the fish bowl. No
   floating; the mice just crossfade. A soft drop-shadow lifts each mouse off the door so it pops.
   Glow + bubbles rise from the gold rim opening at the very top of the pumpkin. */
.caul-art.skin-cauldron_carriage .mirror-faces { z-index: 3; }
.caul-art.skin-cauldron_carriage .mirror-face { filter: drop-shadow(0 5px 7px rgba(0,0,0,.5)); }
.caul-art.skin-cauldron_carriage { --rim-t: 3%; --rim-l: 26%; --rim-r: 26%; --bub-t: 5%; --bub-l: 28%; --bub-r: 28%; }
/* the .cbub box is a larger transparent TAP target; the visible bubble is drawn by ::before
   at the real (small) size, centred inside — so small bubbles are easy to catch by tap */
.cbub { position: absolute; top: 0; opacity: 0; will-change: transform, opacity;
  pointer-events: auto; cursor: pointer;   /* tap to pop — it's Wish POP, after all */
  animation-name: cbubRise; animation-timing-function: linear; animation-iteration-count: infinite; }
.cbub::before { content: ""; position: absolute; left: 50%; top: 50%; width: var(--sz, 12px); height: var(--sz, 12px);
  transform: translate(-50%, -50%); border-radius: 50%;
  background: radial-gradient(circle at 36% 32%, #fff, rgba(255,255,255,.55) 28%, var(--mix-color, #c48bff) 58%, var(--mix-color, #c48bff) 100%);
  box-shadow: 0 0 8px 2px var(--mix-color, #c48bff), 0 0 17px 5px var(--mix-color, #c48bff);
  filter: saturate(1.5) brightness(1.12); }
/* Royal Bubble Bath: its extra always-on "ambient" layer are iridescent soap/pearl bubbles — a
   rainbow sheen matching the pearls painted on the tub. The normal ingredient-coloured bubbles
   are unchanged. Still poppable (styling only). */
.caul-bubbles.ambient .cbub::before {
  background:
    radial-gradient(circle at 34% 27%, #fff 0%, rgba(255,255,255,.6) 12%, rgba(255,255,255,0) 30%),   /* glossy specular highlight */
    radial-gradient(circle at 50% 50%, rgba(255,255,255,.55) 0%, rgba(255,255,255,0) 34%),             /* bright core hides the conic hub */
    radial-gradient(circle, rgba(255,255,255,0) 58%, rgba(255,255,255,.34) 82%, rgba(255,255,255,0) 100%), /* thin-film rim shine */
    conic-gradient(from 210deg, #ffc2ec, #c2dbff, #c2ffe8, #fff4c2, #ffcfc2, #e0c2ff, #c2ecff, #ffc2ec); /* iridescent rainbow sheen */
  box-shadow: 0 0 10px 3px rgba(255,255,255,.5), 0 0 20px 7px rgba(196,210,255,.45);
  filter: saturate(1.35) brightness(1.06); }
@keyframes cbubRise {
  0% { transform: translateY(0) scale(.5); opacity: 0; }
  8% { opacity: .95; }
  88% { opacity: .8; }
  100% { transform: translateY(-100vh) scale(1.12); opacity: 0; } }
/* a glow that traces the cauldron's exact silhouette — invisible at rest, pulses once
   in the added ingredient's colour on each drop-in (via a coloured drop-shadow) */
.caul-art.pulsing .caul-img { animation: caulPulse .6s ease-out; }
@keyframes caulPulse {
  0%   { filter: drop-shadow(0 10px 16px rgba(0,0,0,.5)) drop-shadow(0 0 0 var(--pulse-color, #c9a3ff)); }
  28%  { filter: drop-shadow(0 10px 16px rgba(0,0,0,.5)) drop-shadow(0 0 22px var(--pulse-color, #c9a3ff)) drop-shadow(0 0 12px var(--pulse-color, #c9a3ff)) drop-shadow(0 0 5px var(--pulse-color, #c9a3ff)); }
  100% { filter: drop-shadow(0 10px 16px rgba(0,0,0,.5)) drop-shadow(0 0 0 var(--pulse-color, #c9a3ff)); } }
/* have / need readout — this IS the serve button now */
.m2-readout { flex: 0 0 auto; text-align: center; font-weight: 900; color: #fff; letter-spacing: .5px; line-height: 1; }
.m2-readout b { font-size: clamp(26px, 8vw, 38px); }
.m2-readout span { font-size: .82em; opacity: .9; margin-left: 3px; }
.m2-readout.met b { color: var(--good); text-shadow: 0 0 12px rgba(126,224,138,.6); }
/* copycat prize-ladder readout: current % / next-tier target, with the earned prize named under it */
.m2-readout.copycat .cc-readnum { display: block; }
.m2-readout.copycat .cc-prize { font-family: var(--ff-body); font-weight: 900; letter-spacing: .4px; margin-top: 2px;
  font-size: clamp(13px, 4.4vw, 18px); text-transform: uppercase; }
.m2-readout.copycat .cc-prize.none { color: #b9a9d6; opacity: .8; }
.m2-readout.copycat .cc-prize.won { color: var(--gold, #ffd86b); text-shadow: 0 0 10px rgba(255,216,107,.55); }
/* allergy danger chips — sit inside the bars panel, right under the need bars,
   stretched side by side to span the same full width so they read as one system */
.m2-allergs { flex: 0 0 auto; display: flex; gap: 6px; min-height: 0; }
.m2-allergs:not(:empty) { margin-top: 1px; padding-top: 6px; border-top: 1px dashed rgba(255,255,255,.14); }
.m2-allergs:empty { display: none; }
.allerg-chip { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; padding: 3px 9px 3px 8px; border-radius: 999px;
  background: rgba(30,14,20,.7); border: 1.5px solid var(--ac, #ff6b6b); box-shadow: 0 0 8px rgba(0,0,0,.4); }
.allerg-ic { flex: 0 0 auto; font-size: 15px; line-height: 1; }
.allerg-nm { flex: 0 0 auto; font-size: 13px; font-weight: 800; color: #fff; text-transform: capitalize; text-shadow: 0 1px 2px rgba(0,0,0,.6); white-space: nowrap; }
.allerg-meter { flex: 1; min-width: 20px; height: 8px; border-radius: 4px; overflow: hidden; background: rgba(0,0,0,.5); }
.allerg-meter i { display: block; height: 100%; border-radius: 4px; transition: width .3s ease, background .3s; }
.allerg-chip.zone-red { animation: hgpulse .9s infinite; }
/* slots row */
.m2-slots { flex: 0 0 auto; margin-top: auto; justify-content: center; gap: 6px; }
.m2-slots .slot { width: 38px; height: 38px; border-radius: 10px; font-size: 20px; border-color: rgba(255,214,110,.4); }
.m2-slots .slot .orb { width: 22px; height: 22px; }
.m2-slots .slot img.art { max-width: 1.1em; }
/* bars panel — need bars up top, allergy bars grouped underneath */
.m2-bars { flex: 0 0 auto; display: flex; flex-direction: column; gap: 5px; padding: 6px 8px; border-radius: 14px;
  background: rgba(18,10,30,.5); border: 1px solid rgba(255,214,110,.22); }
.m2-needs { display: flex; flex-direction: column; gap: 5px; }
.mbar { display: flex; align-items: center; gap: 7px; }
.mbar-lbl { flex: 0 0 74px; font-size: 12px; font-weight: 800; text-align: center; color: #fff; padding: 3px 4px; border-radius: 8px;
  background: var(--lc, #888); box-shadow: inset 0 -2px 4px rgba(0,0,0,.3); text-transform: capitalize; text-shadow: 0 1px 2px rgba(0,0,0,.4); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mbar-track { flex: 1; position: relative; height: 22px; border-radius: 12px; overflow: hidden; background: rgba(0,0,0,.4); border: 1px solid rgba(255,255,255,.12); }
.mbar-band { position: absolute; top: 0; bottom: 0; z-index: 1; background: rgba(126,224,138,.4); }
.mbar-fill { position: absolute; left: 0; top: 0; bottom: 0; z-index: 2; border-radius: 12px 0 0 12px; transition: width .35s ease, background .35s; }
.mbar.hit .mbar-track { box-shadow: 0 0 8px var(--good); }
/* bottom tray */
.m2-tray { flex: 0 0 auto; height: clamp(178px, 25vh, 212px); display: flex; gap: 7px; padding: 7px; border-radius: 14px;
  background: rgba(14,8,24,.62); border: 1px solid rgba(255,214,110,.25); }
/* charm column pinned to the LEFT of the tray — a single little column of charms that stays put
   while the ingredients scroll sideways beside it. Only appears when you actually hold charms. */
.m2-charmcol { flex: 0 0 auto; align-self: stretch; margin: -7px 1px -7px 0; display: grid; grid-template-columns: 38px;
  grid-auto-rows: 38px; gap: 4px; align-content: start; justify-content: center; overflow-y: auto;
  padding: 3px 7px 3px 0; border-right: 1px solid rgba(255,214,110,.28); }
.cslot { width: 38px; height: 38px; border-radius: 10px; position: relative; cursor: pointer; flex: 0 0 auto;
  background: rgba(60,30,86,.7); border: 1.5px solid rgba(255,214,110,.55); display: flex; align-items: center; justify-content: center; }
.cslot.empty { background: rgba(0,0,0,.25); border-style: dashed; border-color: rgba(255,255,255,.12); cursor: default; }
.cslot-ic { font-size: 20px; display: flex; }
.cslot-ic img.art { width: 26px !important; height: 26px !important; max-width: none; max-height: none; object-fit: contain; }
.cslot-n { position: absolute; bottom: -3px; right: -3px; background: rgba(0,0,0,.7); color: #fff; font-size: 10px; font-weight: 800; border-radius: 7px; padding: 0 3px; }
.cslot.on { border-color: var(--gold); box-shadow: 0 0 10px var(--gold); }
.cslot.cleanse-glow { border-color: #7ee08a; animation: cleansePulse 1s ease-in-out infinite; }
@keyframes cleansePulse { 0%,100% { box-shadow: 0 0 6px rgba(126,224,138,.7); } 50% { box-shadow: 0 0 15px 3px rgba(126,224,138,.95); } }
.cslot:active { transform: scale(.92); }
/* ingredient cards — 2 rows, scroll sideways. Card width is a fixed viewport measure (matching the
   original ~31.5%-of-full-tray size) so the charm column never squeezes the cards smaller — it just
   means slightly fewer are visible at once, with the rest a scroll away. */
.m2-ing { flex: 1; min-width: 0; display: grid; grid-auto-flow: column; grid-template-rows: repeat(2, 1fr); grid-auto-columns: clamp(104px, 29vw, 124px);
  gap: 6px; overflow-x: auto; overflow-y: hidden; padding: 1px 2px 4px; scroll-snap-type: x proximity; }
.m2-ing::-webkit-scrollbar { height: 5px; } .m2-ing::-webkit-scrollbar-thumb { background: rgba(255,214,110,.4); border-radius: 3px; }
.icard { scroll-snap-align: start; position: relative; display: flex; align-items: center; gap: 4px; min-width: 0; text-align: left;
  padding: 4px 5px; border-radius: 11px; cursor: pointer; background: rgba(46,24,64,.7); border: 1.5px solid rgba(255,214,110,.5); }
.icard:active { transform: scale(.96); }
.icard-l { flex: 0 0 auto; width: 38px; display: flex; flex-direction: column; align-items: center; gap: 1px; }
.icard-art { position: relative; width: 34px; height: 34px; display: flex; align-items: center; justify-content: center; font-size: 26px; }
.icard-art img.art { width: 32px !important; height: 32px !important; max-width: none; max-height: none; object-fit: contain; }
.icard-gem { position: absolute; bottom: -1px; left: -2px; width: 11px; height: 11px; border-radius: 50%; border: 1.5px solid rgba(255,255,255,.7); box-shadow: 0 0 4px rgba(0,0,0,.5); }
.icard-nm { font-size: 9px; font-weight: 700; line-height: 1.05; color: #efe2ff; text-align: center; max-width: 40px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.icard-desc { font-size: 7.5px; font-style: italic; color: #c97a20; text-align: center; max-width: 44px; line-height: 1.1; margin-top: 2px; }
.icard-r { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; justify-content: center; }
.mp { position: relative; display: flex; align-items: center; justify-content: center; gap: 1px; font-size: 10px; font-weight: 800; color: #fff; text-align: center; padding: 2px 2px; border-radius: 6px; height: 17px; line-height: 13px;
  background: var(--mc, #888); box-shadow: inset 0 -1px 3px rgba(0,0,0,.3); text-transform: uppercase; letter-spacing: .2px; overflow: visible; }
.mp-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; max-width: 100%; }
/* the allergy caution sits as a small corner badge (not inline) so it never eats the label's width;
   the pill's red ring already flags the allergen too. Long names (e.g. "Protection") drop a touch. */
.mp-warn { position: absolute; top: -5px; right: -4px; z-index: 2; pointer-events: none; font-size: 9px; line-height: 1; filter: drop-shadow(0 0 1px rgba(0,0,0,.9)); }
.mp.long .mp-txt { font-size: 8.4px; letter-spacing: -.2px; }
.mp.allergen { box-shadow: inset 0 -1px 3px rgba(0,0,0,.3), 0 0 0 1.6px #ff2d2d, 0 0 7px rgba(255,60,60,.7); }
.mp.hidden { background: rgba(255,255,255,.1); color: rgba(255,255,255,.55); border: 1px dashed rgba(255,255,255,.25); box-shadow: none; }
.mp.blank { background: transparent; box-shadow: none; }
.icard-fx { font-size: 9px; font-weight: 700; line-height: 1.15; color: #e6d2ff; text-align: center; margin-top: 1px;
  padding: 2px 4px; border-radius: 6px; background: rgba(150,100,230,.28); border: 1px solid rgba(201,160,255,.5); }
.icard-count { position: absolute; top: 3px; right: 4px; background: rgba(0,0,0,.7); color: #fff; font-size: 11px; font-weight: 800; border-radius: 8px; padding: 0 5px; z-index: 3; }
.icard-star { position: absolute; top: -5px; left: -4px; font-size: 13px; z-index: 3; filter: drop-shadow(0 0 3px rgba(255,216,107,.9)); }
.icard-inf { position: absolute; top: -5px; left: -4px; font-size: 13px; z-index: 3; filter: drop-shadow(0 0 3px rgba(150,200,255,.95)); }
/* Banish poof — a small purple burst where a villain-round ingredient vanished */
.poof-fx { position: fixed; z-index: 60; transform: translate(-50%, -50%); pointer-events: none; }
.poof-cloud { position: absolute; left: -24px; top: -24px; width: 48px; height: 48px; border-radius: 50%;
  background: radial-gradient(circle, rgba(198,140,240,.9), rgba(120,60,170,.45) 58%, transparent 72%);
  filter: blur(1px); animation: poofCloud .5s ease-out forwards; }
@keyframes poofCloud { 0% { transform: scale(.4); opacity: 0; } 30% { opacity: .95; } 100% { transform: scale(1.7); opacity: 0; } }
.poof-bit { position: absolute; left: 0; top: 0; width: 8px; height: 8px; margin: -4px; border-radius: 50%;
  background: radial-gradient(circle, #e6c2ff, #9a4fd0 70%); box-shadow: 0 0 6px rgba(180,110,230,.8);
  animation: poofBit .52s ease-out forwards; }
@keyframes poofBit { 0% { transform: translate(0,0) scale(1); opacity: 1; } 100% { transform: translate(var(--dx), var(--dy)) scale(.3); opacity: 0; } }
/* Cursed ingredient burst — a green toxic splatter, and the poison pill / splashed-card flash */
.poison-splat { position: fixed; z-index: 61; transform: translate(-50%, -50%); pointer-events: none; }
.ps-cloud { position: absolute; left: -30px; top: -30px; width: 60px; height: 60px; border-radius: 50%;
  background: radial-gradient(circle, rgba(150,220,70,.95), rgba(90,160,40,.5) 55%, transparent 72%);
  filter: blur(1px); animation: psCloud .55s ease-out forwards; }
@keyframes psCloud { 0% { transform: scale(.35); opacity: 0; } 25% { opacity: 1; } 100% { transform: scale(1.9); opacity: 0; } }
.ps-skull { position: absolute; left: 0; top: 0; font-size: 26px; animation: psSkull .7s ease-out forwards; }
@keyframes psSkull { 0% { transform: translate(-50%,-50%) scale(.3); opacity: 0; } 30% { transform: translate(-50%,-64%) scale(1.15); opacity: 1; } 100% { transform: translate(-50%,-150%) scale(.8); opacity: 0; } }
.ps-bit { position: absolute; left: 0; top: 0; width: 9px; height: 9px; margin: -4.5px; border-radius: 50%;
  background: radial-gradient(circle, #cdf27a, #6faa2e 70%); box-shadow: 0 0 6px rgba(140,210,60,.85);
  animation: psBit .6s ease-out forwards; }
@keyframes psBit { 0% { transform: translate(0,0) scale(1); opacity: 1; } 100% { transform: translate(var(--dx), var(--dy)) scale(.25); opacity: 0; } }
.mp.poison { box-shadow: inset 0 -1px 3px rgba(0,0,0,.3), 0 0 0 1.4px #3f6b16; }
.mp.rot { --mc: #8b6914; box-shadow: inset 0 -1px 3px rgba(0,0,0,.3), 0 0 0 1.4px #5d3f00; }
.icard.splash-hit { animation: splashHit .5s ease; }
@keyframes splashHit { 0%,100% { box-shadow: 0 0 0 rgba(150,220,70,0); } 40% { box-shadow: 0 0 13px 4px rgba(150,220,70,.9); } }
/* Potent = warm GOLD card; Infused = cool PURPLE card — kept clearly different at a glance */
.icard.potent { border-color: var(--gold); border-width: 2px; box-shadow: 0 0 11px rgba(255,216,107,.7);
  background: linear-gradient(150deg, rgba(255,201,74,.34), rgba(120,72,20,.55) 62%); }
.icard.infused { border-color: #a97bff; border-width: 2px; box-shadow: 0 0 11px rgba(150,120,255,.7);
  background: linear-gradient(150deg, rgba(139,96,255,.42), rgba(40,26,84,.72) 62%); }
.icard.essence { border-style: dashed; }
.icard.poisoned { border-color: var(--bad); }
.icard.rotten { border-color: #c0392b; border-width: 2px; box-shadow: 0 0 14px rgba(200,40,40,.65); animation: rotPulse 2s ease-in-out infinite; background: linear-gradient(150deg, rgba(160,20,20,.38), rgba(70,5,5,.62) 62%); }
.icard.rot-touched { border-color: #5d3f00; border-width: 1.5px; box-shadow: 0 0 7px rgba(140,70,0,.4); background: linear-gradient(150deg, rgba(100,70,10,.22), rgba(40,20,2,.44) 62%); }
@keyframes rotPulse { 0%,100% { box-shadow: 0 0 10px rgba(200,40,40,.5); } 50% { box-shadow: 0 0 22px rgba(230,60,60,.9); } }
.m2-tray.cutting .icard.cuttable { outline: 2px solid var(--gold); outline-offset: 1px; animation: cutpulse 1s ease-in-out infinite; }
.icard.glow { animation: tileGlow 1.6s ease; }
.icard .poison-badge { position: absolute; top: -3px; right: -3px; font-size: 13px; }
.icard .rot-badge { position: absolute; top: -5px; left: -5px; font-size: 16px; z-index: 2; filter: drop-shadow(0 0 4px rgba(180,100,0,.7)); }
.icard .pinch-badge { position: absolute; bottom: -3px; right: -3px; font-size: 12px; }
.icard .transmute-badge { position: absolute; top: -5px; right: -5px; font-size: 12px; z-index: 4; filter: drop-shadow(0 1px 2px rgba(0,0,0,.6)); }
.tray-empty { margin: auto; text-align: center; color: var(--ink-dim); font-size: 13px; line-height: 1.5; }

/* ---- FROST / THAW (ice realm) — a frozen piece's box fills with ice that DRAINS on a 25s clock ---- */
.icard.frozen { position: relative; overflow: hidden; border-color: rgba(150,214,255,.8);
  box-shadow: 0 0 10px rgba(120,200,255,.5), inset 0 0 12px rgba(150,214,255,.22); }
.icard.frozen > .icard-l, .icard.frozen > .icard-r { position: relative; z-index: 1; }
/* frozen-SOLID = still Potent: the usual gold potent outline (drops off once it hits Fresh) */
.icard.frozen.thaw-potent { border-color: var(--gold); border-width: 2px;
  box-shadow: 0 0 11px rgba(255,216,107,.7), inset 0 0 12px rgba(150,214,255,.22); }
.frost-fill { position: absolute; left: 0; right: 0; bottom: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(0deg, rgba(90,170,235,.62), rgba(165,224,255,.5));
  border-top: 2px solid rgba(215,242,255,.9); transition: height .3s linear; }
.icard.thaw-mid .frost-fill { background: linear-gradient(0deg, rgba(110,192,200,.6), rgba(184,236,222,.5)); }
.icard.thaw-warn { border-color: rgba(255,140,120,.9); animation: thawPulse 1s ease-in-out infinite; }
.icard.thaw-warn .frost-fill { background: linear-gradient(0deg, rgba(235,150,80,.62), rgba(255,204,124,.5)); border-top-color: rgba(255,222,172,.92); }
@keyframes thawPulse { 0%,100% { box-shadow: 0 0 8px rgba(255,120,90,.4); } 50% { box-shadow: 0 0 15px rgba(255,120,90,.75); } }
.frost-stage { position: absolute; top: 2px; left: 0; right: 0; z-index: 2; text-align: center; pointer-events: none;
  font-family: var(--ff-body); font-weight: 800; font-size: 9px; letter-spacing: .3px; color: #eaf7ff; text-shadow: 0 1px 2px rgba(0,20,40,.85); }
@media (prefers-reduced-motion: reduce) { .icard.thaw-warn { animation: none; } .frost-fill { transition: none; } }

/* ---- COPYCAT ROUNDS ---- the copycat's mirror row + slots -------------------- */
/* The tray is already a 2-row grid, so your card lands on top and its copy directly
   below. The copy row is tinted violet, locked (no taps), and has a sliding sheen. */
.icard.cc-copy { cursor: default; pointer-events: none; overflow: hidden;
  background: linear-gradient(150deg, rgba(120,74,196,.42), rgba(58,26,104,.66) 70%);
  border-color: rgba(190,150,255,.55); box-shadow: 0 0 9px rgba(150,110,255,.35) inset; }
.icard.cc-copy .icard-nm { color: #e8dcff; }
.icard.cc-copy.cc-blank { visibility: hidden; }
.mixv2.copycat .cc-tray { padding-bottom: 5px; }
/* the moving shine that marks a card as a copy */
.cc-sheen { position: absolute; top: 0; left: -60%; width: 45%; height: 100%; z-index: 1; pointer-events: none;
  background: linear-gradient(105deg, transparent, rgba(255,255,255,.28), transparent);
  transform: skewX(-18deg); animation: ccSheen 3.4s ease-in-out infinite; }
@keyframes ccSheen { 0%, 62% { left: -60%; } 100% { left: 150%; } }
/* the right half of the cauldron row = the copycat's mirrored copies */
.mixv2.copycat .m2-slots .slot.copy-slot { border-color: rgba(190,150,255,.55);
  background: rgba(120,74,196,.28); box-shadow: 0 0 7px rgba(150,110,255,.3) inset; position: relative; overflow: hidden; }
.mixv2.copycat .m2-slots .slot.copy-slot.filled { background: rgba(120,74,196,.5); }
/* the same sliding sheen the copy CARDS get, now on the copy SLOTS under the cauldron */
.mixv2.copycat .m2-slots .slot.copy-slot::after { content: ""; position: absolute; top: 0; left: -60%;
  width: 45%; height: 100%; z-index: 3; pointer-events: none;
  background: linear-gradient(105deg, transparent, rgba(255,255,255,.4), transparent);
  transform: skewX(-18deg); animation: ccSheen 3.4s ease-in-out infinite; }
/* a hair of extra space where your side meets the copycat's, so the mirror reads clearly */
.mixv2.copycat .m2-slots .slot.copy-start { margin-left: 7px; }
/* placement poof where a copy card vanishes into the pot */
.cc-poof { position: fixed; z-index: 60; pointer-events: none; transform: translate(-50%, -50%); }
.cc-poof .cc-poof-cloud { position: absolute; left: -16px; top: -16px; width: 32px; height: 32px; border-radius: 50%;
  background: radial-gradient(circle, rgba(210,180,255,.85), rgba(150,110,255,0) 70%); animation: ccPoofCloud .5s ease-out forwards; }
.cc-poof .cc-spark { position: absolute; left: 0; top: 0; width: 6px; height: 6px; margin: -3px; border-radius: 50%;
  background: #efe2ff; box-shadow: 0 0 5px rgba(200,160,255,.9); animation: ccPoofSpark .55s ease-out forwards; }
@keyframes ccPoofCloud { 0% { transform: scale(.3); opacity: .9; } 100% { transform: scale(1.5); opacity: 0; } }
@keyframes ccPoofSpark { 0% { transform: translate(0, 0) scale(1); opacity: 1; } 100% { transform: translate(var(--dx), var(--dy)) scale(.2); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .cc-sheen, .mixv2.copycat .m2-slots .slot.copy-slot::after { animation: none; display: none; } }
/* the copycat's dynamic ± third quality: green ring = adds to its bar, red/darkened = drains it */
.mp.signed { box-shadow: inset 0 -1px 3px rgba(0,0,0,.3), 0 0 0 1.6px rgba(255,255,255,.3); }
.mp.signed.plus { box-shadow: inset 0 -1px 3px rgba(0,0,0,.3), 0 0 0 1.7px #37d67a, 0 0 6px rgba(55,214,122,.55); }
.mp.signed.minus { background: linear-gradient(0deg, rgba(0,0,0,.5), rgba(0,0,0,.5)), var(--mc, #888);
  box-shadow: inset 0 -1px 3px rgba(0,0,0,.3), 0 0 0 1.7px #ff5b5b, 0 0 6px rgba(255,80,80,.5); }
/* an allergen being ADDED still wins the loud red danger ring */
.mp.signed.plus.allergen { box-shadow: inset 0 -1px 3px rgba(0,0,0,.3), 0 0 0 1.9px #ff2d2d, 0 0 8px rgba(255,60,60,.8); }
/* Thin black outline so light-colored magic labels stay readable on light pills
   (e.g. white "Light" on a pale-yellow chip). Skips small descriptions like .icard-fx. */
.mp, .mbar-lbl, .allerg-nm, .icard-nm, .m2-readout b, .m2-readout span,
.cslot-n, .icard-count, .m2-timer-badge b, .m2-timer-badge span {
  -webkit-text-stroke: .8px rgba(0,0,0,.92); paint-order: stroke fill;
  text-shadow: 0 1px 1px rgba(0,0,0,.5);
}

/* ===== MAGIC CARPET DASH (Forgotten Oasis flight) ===================== */
/* carpet skin picker on the intro */
.carpet-pick { display: flex; align-items: center; justify-content: center; gap: 10px; }
.carpet-pick-art { width: 96px; height: auto; filter: drop-shadow(0 6px 14px rgba(0,0,0,.5)); animation: carpetPickIn .25s ease; }
@keyframes carpetPickIn { from { transform: scale(.8); opacity: .3; } }
.carpet-pick-arrow { width: 44px; height: 44px; border-radius: 50%; border: none; font-size: 20px; color: #fff;
  background: rgba(255,255,255,.16); box-shadow: 0 2px 6px rgba(0,0,0,.3); cursor: pointer; }
.carpet-pick-arrow:active { transform: scale(.92); }
/* the flight */
.carpet-sky { position: relative; flex: 1; min-height: 0; width: 100%; margin: 6px 2px 0; border-radius: 16px; overflow: hidden;
  background: #160f38; touch-action: none; user-select: none; -webkit-user-select: none; }
.carpet-bg { position: absolute; top: 0; bottom: 0; left: -8%; width: 116%; z-index: 0; pointer-events: none;
  background: url('../art/oasis_sky.jpg') center center / cover no-repeat; will-change: transform; }
.carpet-arrow { position: absolute; top: 46%; font-size: 22px; color: #ffffff33; z-index: 1; pointer-events: none; }
.carpet-arrow.left { left: 10px; } .carpet-arrow.right { right: 10px; }
.carpet-star { position: absolute; transform: translate(-50%,-50%); width: 52px; height: 52px; z-index: 2;
  background: center / contain no-repeat; filter: drop-shadow(0 0 6px rgba(255,226,140,.7)); pointer-events: none;
  transition: left .05s linear, top .05s linear; will-change: top,left; }
.carpet-star.caught { animation: carpetCaught .45s forwards; }
@keyframes carpetCaught { to { transform: translate(-50%,-50%) scale(1.8); opacity: 0; } }
.carpet-star.bad { filter: drop-shadow(0 0 8px rgba(155,120,255,.9)); }
.carpet-star.bad.near { animation: carpetStarNear .5s infinite; }
@keyframes carpetStarNear { 50% { filter: drop-shadow(0 0 12px rgba(185,120,255,1)); } }
.carpet-star.smash { animation: carpetStarSmash .45s forwards; }
@keyframes carpetStarSmash { 0% { transform: translate(-50%,-50%) scale(1.2); } 100% { transform: translate(-50%,-50%) scale(.4) rotate(30deg); opacity: 0; } }
.carpet-cloud { position: absolute; transform: translate(-50%,-50%); height: auto; z-index: 4;
  background: center / contain no-repeat; aspect-ratio: 2 / 1; pointer-events: none;
  filter: drop-shadow(0 3px 10px rgba(0,0,0,.3)); transition: left .05s linear, top .05s linear; will-change: top,left; }
.carpet-planet { position: absolute; transform: translate(-50%,-50%); height: auto; z-index: 1; pointer-events: none;
  filter: drop-shadow(0 6px 22px rgba(0,0,0,.5)); transition: left .05s linear, top .05s linear; will-change: top,left; }
.carpet-rug { position: absolute; left: 50%; top: 78%; transform: translateX(-50%); width: 23%; max-width: 118px; height: auto; z-index: 3;
  filter: drop-shadow(0 6px 14px rgba(0,0,0,.5)); transition: transform .06s linear; }
.carpet-rug.hurt { animation: carpetHurt .4s; }
@keyframes carpetHurt { 0%,100% { filter: drop-shadow(0 6px 14px rgba(0,0,0,.5)); } 30% { filter: brightness(1.9) drop-shadow(0 0 9px #ff5a5a); } }
/* crash: the carpet tumbles and shrinks away behind the planet */
.carpet-rug.crash { animation: carpetCrash .95s ease-in forwards; }
@keyframes carpetCrash { 0% { transform: translateX(-50%) rotate(0deg) scale(1); } 100% { transform: translateX(-50%) translateY(28%) rotate(220deg) scale(.35); opacity: .2; } }
/* the fog that builds while you're inside a cloud — warm sunset haze that whites out your view */
.carpet-fog { position: absolute; inset: 0; z-index: 5; pointer-events: none; opacity: 0;
  background: radial-gradient(120% 90% at 50% 45%, rgba(255,236,205,.98), rgba(255,205,150,.96) 55%, rgba(240,170,120,.95) 100%); }
.carpet-sky.shake { animation: carpetShake .4s; }
@keyframes carpetShake { 0%,100% { transform: translateX(0); } 15% { transform: translate(-6px,3px); } 35% { transform: translate(6px,-2px); } 55% { transform: translate(-4px,2px); } 75% { transform: translate(4px,-1px); } }

/* ===== MOUSE BOUTIQUE — "Stitch & Scurry" (played over the shop background) ===== */
.bq-shop { position: relative; flex: 1; min-height: 0; width: 100%; margin: 4px 2px 0; border-radius: 14px; overflow: hidden;
  background: url('../art/boutique_bg.jpg') center center / 100% 100% no-repeat; touch-action: manipulation; }
/* transparent counters tucked in the top corners so the painted sign shows through */
.bq-hud { position: absolute; top: 6px; left: 6px; right: 6px; z-index: 5; display: flex; justify-content: space-between; pointer-events: none; }
.bq-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 9px; border-radius: 999px; font-weight: 800; font-size: 14px;
  color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.9); background: rgba(30,16,10,.42); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }
.bq-chip b { color: #ffe08a; }
.bq-chip.danger { background: rgba(120,20,20,.6); } .bq-chip.danger b { color: #ffb0b0; }
/* a station drop-zone sits over its painted table; the dress-in-progress appears here */
.bq-zone { position: absolute; transform: translate(-50%,-50%); z-index: 3; display: flex; flex-direction: column; align-items: center; }
.bq-zone .bq-slot { display: flex; align-items: center; justify-content: center; min-height: 20px; }
.bq-zone .bq-proc { width: 58px; height: 9px; margin-top: 3px; border-radius: 5px; background: rgba(0,0,0,.55); overflow: hidden; opacity: 0; transition: opacity .15s; box-shadow: 0 1px 2px rgba(0,0,0,.4); }
.bq-zone .bq-proc.on { opacity: 1; }
.bq-zone .bq-proc i { display: block; height: 100%; width: 0%; background: linear-gradient(90deg, #c58bff, #ffd76a); }
/* the incoming-orders shelf pinned to the bottom */
.bq-supply { position: absolute; left: 4px; right: 4px; bottom: 4px; z-index: 4; min-height: 152px;
  background: linear-gradient(0deg, rgba(20,10,6,.5), rgba(20,10,6,.05)); border-radius: 14px; padding: 6px; }
.bq-supply-slot { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; justify-content: center; min-height: 144px; }
/* an "order" = station-icon chips (remaining) + the dress sprite (its current stage) + patience bar, moving as one unit */
.bq-order { display: flex; flex-direction: column; align-items: center; gap: 2px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.bq-remain { display: flex; gap: 3px; align-items: center; justify-content: center; flex-wrap: wrap; max-width: 160px; min-height: 24px; }
.bq-ic { display: inline-flex; align-items: center; justify-content: center; width: 46px; height: 46px; border-radius: 10px;
  background: #f6efdd; box-shadow: 0 2px 4px rgba(0,0,0,.55); }
.bq-ic img { width: 34px; height: 34px; object-fit: contain; display: block; }
.bq-ic.now { box-shadow: 0 0 0 3px #ffd76a, 0 2px 4px rgba(0,0,0,.55); }
.bq-ic-done { font-size: 30px; }
.bq-dress { width: auto; height: 70px; max-width: 88px; object-fit: contain; pointer-events: none; filter: drop-shadow(0 3px 4px rgba(0,0,0,.55)); }
/* orders waiting in the line (their mice) sit bigger so they're easy to see and tap */
.bq-supply-slot .bq-dress { height: 104px; max-width: 116px; }
.bq-opat { width: 60px; height: 9px; border-radius: 5px; background: rgba(0,0,0,.55); overflow: hidden; box-shadow: 0 1px 2px rgba(0,0,0,.4); }
.bq-opat i { display: block; height: 100%; width: 100%; background: #7ee08a; transition: width .1s linear; }
.bq-opat i.amber { background: #ffcf5a; } .bq-opat i.danger { background: #ff6a6a; }
.bq-order.ready .bq-dress { animation: bqReady 1s ease-in-out infinite; }
@keyframes bqReady { 0%,100% { filter: drop-shadow(0 0 6px rgba(255,225,120,.85)) drop-shadow(0 0 2px rgba(255,255,255,.6)) drop-shadow(0 3px 4px rgba(0,0,0,.5)); transform: scale(1.0); } 50% { filter: drop-shadow(0 0 18px rgba(255,222,90,1)) drop-shadow(0 0 8px rgba(255,255,255,.9)) drop-shadow(0 3px 4px rgba(0,0,0,.5)); transform: scale(1.05); } }
/* one-shot bright flash the instant a station finishes a dress — makes "done!" unmistakable */
.bq-order.justdone .bq-dress { animation: bqJustDone .55s ease-out; }
@keyframes bqJustDone {
  0% { filter: drop-shadow(0 0 0 rgba(255,255,255,0)) drop-shadow(0 3px 4px rgba(0,0,0,.5)); transform: scale(1); }
  25% { filter: drop-shadow(0 0 26px rgba(255,255,255,1)) drop-shadow(0 0 40px rgba(255,220,100,1)) drop-shadow(0 3px 4px rgba(0,0,0,.5)); transform: scale(1.28); }
  100% { filter: drop-shadow(0 0 8px rgba(255,225,120,.85)) drop-shadow(0 3px 4px rgba(0,0,0,.5)); transform: scale(1); }
}
/* a quick expanding ring behind the dress at the moment it finishes */
.bq-order.justdone::before { content: ""; position: absolute; left: 50%; top: 46%; width: 20px; height: 20px; margin: -10px 0 0 -10px;
  border-radius: 50%; border: 3px solid rgba(255,235,140,.95); pointer-events: none; animation: bqRing .55s ease-out forwards; }
@keyframes bqRing { 0% { transform: scale(.4); opacity: .95; } 100% { transform: scale(4.2); opacity: 0; } }
.bq-order { position: relative; }
.bq-order.done .bq-dress { animation: bqDone .8s ease-in-out infinite; }
@keyframes bqDone { 0%,100% { filter: drop-shadow(0 0 5px rgba(126,224,138,.9)) drop-shadow(0 3px 4px rgba(0,0,0,.5)); transform: scale(1.02); } 50% { filter: drop-shadow(0 0 13px rgba(126,224,138,1)) drop-shadow(0 3px 4px rgba(0,0,0,.5)); transform: scale(1.08); } }
.bq-order.proc { opacity: .68; }
.bq-order.proc .bq-dress { filter: drop-shadow(0 3px 4px rgba(0,0,0,.5)) saturate(.85); }
.bq-order.nudge { animation: bqNudge .3s; }
@keyframes bqNudge { 0%,100% { transform: translateX(0); } 30% { transform: translateX(-5px); } 70% { transform: translateX(5px); } }
.bq-order.delivered { animation: bqDeliver .55s forwards; pointer-events: none; }
@keyframes bqDeliver { to { transform: translateY(-40px) scale(.55); opacity: 0; } }
.bq-order.lost { animation: bqLost .5s forwards; pointer-events: none; }
@keyframes bqLost { to { transform: translateY(22px) scale(.6) rotate(18deg); opacity: 0; } }

/* ===== STORY — Little Red's tale: full-screen illustrated dialogue cards ===== */
.story-card { position: relative; flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  padding: 18px 16px calc(16px + var(--safe-b)); overflow: hidden; background: #150b20; }
/* crossfading backdrop layers — the scene can drift (village → shop) across beats */
.story-bg { position: absolute; inset: 0; z-index: 0; background-position: center top; background-size: cover; background-repeat: no-repeat; }
.story-bg.top { opacity: 1; }
.story-bg.top.cross { opacity: 0; animation: storyBgCross .9s ease forwards; }
@keyframes storyBgCross { to { opacity: 1; } }
.story-scrim { position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, rgba(30,16,40,.14) 0%, rgba(24,12,32,.34) 52%, rgba(18,8,26,.72) 100%); }
/* Little Red stands LARGE, anchored to the bottom — her lower half tucks behind the text card */
.story-figure { position: absolute; left: 50%; bottom: 0; transform: translateX(-50%); z-index: 2; pointer-events: none;
  display: flex; align-items: flex-end; justify-content: center; height: 84vh; animation: storyFigIn .5s ease-out; }
/* keeps her horizontally centred the whole time (a clean slide up, no sideways jump) */
@keyframes storyFigIn { from { opacity: 0; transform: translateX(-50%) translateY(30px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }
/* Same rise-and-fade for the full-width shove containers (no translateX, so they come up from the
   bottom like every other figure instead of sliding in from the side). */
@keyframes storyFigInFlat { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }
img.story-face { height: 100%; width: auto; max-width: 96vw; object-fit: contain; object-position: bottom; filter: drop-shadow(0 8px 16px rgba(0,0,0,.5)); }
/* two-character (duo) art is wide — show it in the upper area, sized to fit the width with
   margin, so both pigs are fully visible above the dialogue (not squeezed edge-to-edge). */
.story-figure.wide { height: auto; bottom: auto; top: 20%; align-items: center; }
.story-figure.wide img.story-face { height: auto; width: auto; max-height: 52vh; max-width: 82vw; object-position: center; }
/* Stepsisters' shove beats: show the FULL two-figure art bottom-anchored, then slide it sideways
   so the shover sits off-screen — all you see of her is the arm reaching in. (No cropping: the art
   is intact, we just frame it in the slide.) The container spans the whole game column and clips at
   its edges; the nudge uses `left` in % of the COLUMN (NOT vw) so it's identical on phone and iPad. */
.story-figure.ss-shove-r, .story-figure.ss-shove-l { left: 0; right: 0; width: 100%; transform: none;
  height: 90vh; bottom: 0; top: auto; display: flex; align-items: flex-end; justify-content: center; overflow: hidden;
  animation: storyFigInFlat .5s ease-out; }
.story-figure.ss-shove-r img.story-face, .story-figure.ss-shove-l img.story-face { position: relative; height: 100%; width: auto; max-width: none; object-position: bottom; }
.story-figure.ss-shove-r img.story-face { left: 24%; }    /* centres Prunella; Griselda (right) slides off-screen, arm remains */
.story-figure.ss-shove-l img.story-face { left: -11%; }   /* centres Griselda; Prunella (left) slides off-screen, arm remains */
/* Both sisters, sulking: like a duo (wide) but a bit bigger. */
.story-figure.ss-duo-big { height: auto; bottom: auto; top: 7%; align-items: center; }
.story-figure.ss-duo-big img.story-face { height: auto; width: auto; max-height: 84vh; max-width: 96vw; object-position: center; }
/* Wishy the Fish sits in a round water-bubble — bottom-anchored at full height he's huge and
   clipped, so show him small and centred in the upper area with the whole bubble visible. */
.story-figure.round { height: auto; bottom: auto; top: 10%; align-items: center; }
.story-figure.round img.story-face { height: auto; width: auto; max-height: 44vh; max-width: 74vw; object-position: center; }
span.story-face { display: inline-flex; align-items: center; justify-content: center; height: 40vh; font-size: 32vh; line-height: 1; } /* emoji fallback */
.story-figure.scene { height: auto; bottom: auto; top: 16%; }
/* the Wolf (in all his disguises) sits a touch higher so more of him clears the dialogue */
.story-figure.wolf { bottom: 5%; }
/* emoji placeholder for characters without full-body art: float it up where it's visible */
.story-figure.emoji { height: auto; bottom: auto; top: 12%; align-items: center; }
.story-figure.emoji span.story-face { height: auto; font-size: 30vh; filter: drop-shadow(0 8px 16px rgba(0,0,0,.5)); }
/* an item handed over during a beat (e.g. giving Red the heart button) — a glowing
   chip floating in front of the character, gently offered up */
.story-give { position: absolute; left: 50%; top: 54%; transform: translate(-50%, -50%); z-index: 3;
  width: 118px; height: 118px; border-radius: 50%; border: 3px solid #fff2c8; pointer-events: none;
  background: radial-gradient(circle at 38% 30%, #fff7da, #ffd873 58%, #f0a63a);
  box-shadow: 0 8px 22px rgba(0,0,0,.5), 0 0 26px rgba(255,206,110,.85);
  display: flex; align-items: center; justify-content: center;
  animation: storyGiveIn .45s ease-out both, storyGiveBob 2.2s ease-in-out .45s infinite; }
.story-give .story-give-img { width: 66%; height: 66%; object-fit: contain; font-size: 52px;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.4)); }
@keyframes storyGiveIn { 0% { opacity: 0; transform: translate(-50%, calc(-50% + 28px)) scale(.6); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
@keyframes storyGiveBob { 0%,100% { transform: translate(-50%, -50%); } 50% { transform: translate(-50%, calc(-50% - 8px)); } }
/* an item the character is inspecting — held down to their side (not over the face),
   glowing and gently pulsing so the art shines */
.story-inspect { position: absolute; left: 73%; top: 57%; transform: translate(-50%, -50%); z-index: 3;
  pointer-events: none; display: flex; align-items: center; justify-content: center;
  filter: drop-shadow(0 8px 18px rgba(0,0,0,.55));
  animation: inspectIn .5s cubic-bezier(.3,1.5,.5,1) both, inspectPulse 1.9s ease-in-out .5s infinite; }
.story-inspect::before { content: ""; position: absolute; left: 50%; top: 50%; width: 150%; height: 150%;
  transform: translate(-50%, -50%); border-radius: 50%; z-index: -1;
  background: radial-gradient(circle, rgba(255,231,150,.7), rgba(255,205,90,.22) 52%, transparent 70%);
  animation: inspectGlow 1.9s ease-in-out .5s infinite; }
.story-inspect .story-inspect-img { width: auto; height: auto; max-width: 37vw; max-height: 23vh; }
.story-inspect span.story-inspect-img { font-size: 88px; line-height: 1; }
@keyframes inspectIn { 0% { opacity: 0; transform: translate(-50%, calc(-50% + 22px)) scale(.5) rotate(-9deg); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0); } }
@keyframes inspectPulse { 0%,100% { transform: translate(-50%, -50%) scale(1); } 50% { transform: translate(-50%, -50%) scale(1.07); } }
@keyframes inspectGlow { 0%,100% { opacity: .6; transform: translate(-50%, -50%) scale(1); } 50% { opacity: 1; transform: translate(-50%, -50%) scale(1.14); } }
/* the dialogue stack sits on top of everything, pinned to the bottom */
.story-below { position: relative; z-index: 3; width: 100%; display: flex; flex-direction: column; align-items: center; gap: 12px; }

/* gallery beats: Red holds up photos/a sketch — one big picture with ‹ › and dots */
.story-card.gallery-beat { justify-content: flex-end; }
.story-card.gallery-beat::before { content: ""; position: absolute; inset: 0; background: rgba(14,7,22,.5); z-index: 1; }
.story-gallery { position: relative; z-index: 2; flex: 1; min-height: 0; width: 100%; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 0 14px; }
.gal-frame { display: flex; align-items: center; justify-content: center; min-width: 0; }
img.gal-pic { max-height: 52vh; max-width: 66vw; width: auto; height: auto; object-fit: contain; filter: drop-shadow(0 12px 22px rgba(0,0,0,.6)); animation: galPop .32s ease-out; }
@keyframes galPop { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }
.gal-arrow { flex: none; width: 46px; height: 46px; border-radius: 50%; border: none; font-size: 28px; font-weight: 900; line-height: 1;
  color: #4a2b12; background: rgba(255,248,234,.92); box-shadow: 0 3px 9px rgba(0,0,0,.5); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.gal-arrow:active { transform: scale(.9); }
.gal-dots { position: absolute; bottom: 2px; left: 0; right: 0; display: flex; gap: 7px; justify-content: center; }
.gal-dot { width: 8px; height: 8px; border-radius: 50%; background: rgba(255,255,255,.4); box-shadow: 0 1px 2px rgba(0,0,0,.5); transition: background .15s, transform .15s; }
.gal-dot.on { background: #ffd76a; transform: scale(1.25); }

/* ===== STORY ZOOM — one smooth, continuous push straight in through the shop door ===== */
.zoom-cine { position: absolute; inset: 0; overflow: hidden; background: #150b20; }
.zoom-solo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 46%;
  transform-origin: 50% 47%; will-change: transform; animation: zoomSolo 2.6s cubic-bezier(.45,0,.75,.55) forwards; }
@keyframes zoomSolo { from { transform: scale(1); } to { transform: scale(2.6); } }
/* a soft cream veil that blooms at the very end, easing into the tutorial */
.zoom-veil { position: absolute; inset: 0; background: radial-gradient(120% 90% at 50% 48%, rgba(255,248,234,.95), rgba(255,244,224,1)); opacity: 0; pointer-events: none; animation: zoomVeil 2.6s ease-in forwards; }
@keyframes zoomVeil { 0%, 74% { opacity: 0; } 100% { opacity: 1; } }
.zoom-skip { position: absolute; bottom: calc(14px + var(--safe-b)); right: 16px; z-index: 3; color: #fff; font-size: 13px; font-weight: 700;
  padding: 6px 12px; border-radius: 999px; background: rgba(20,10,28,.42); backdrop-filter: blur(2px); animation: zoomSkipFade 2.6s ease forwards; }
@keyframes zoomSkipFade { 0%,70% { opacity: .9; } 100% { opacity: 0; } }
.story-figure.scene .story-scene { font-size: 76px; line-height: 1.15; text-align: center; filter: drop-shadow(0 6px 12px rgba(0,0,0,.5)); }
.story-scene { animation: storyFloat 3.4s ease-in-out infinite; }
.story-name { font-weight: 900; font-size: 20px; color: #fff6e6; letter-spacing: .3px;
  padding: 5px 18px; border-radius: 999px; background: linear-gradient(180deg, #b8517e, #8a3a63);
  box-shadow: 0 3px 10px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.25); }
.story-speech { width: 100%; max-width: 400px; font-size: 16.5px; line-height: 1.5; color: #3a2a1e; text-align: center;
  background: linear-gradient(180deg, #fff8ea, #f6ead2); border-radius: 18px; padding: 16px 18px;
  box-shadow: 0 6px 18px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.7); animation: storyIn .4s ease-out; }
.story-speech b { color: #a23c6e; } .story-speech i { color: #6a4a2c; }
/* Speaker-coloured dialogue (Stepsisters): Prunella deep purple, Griselda emerald — matches their
   gowns, so we can drop the "Name:" prefixes. Also overrides the default <b>/<i> colours inside. */
.story-speech .speak-p, .story-speech .speak-p b, .story-speech .speak-p i { color: #7d2ea6; font-weight: 700; }
.story-speech .speak-g, .story-speech .speak-g b, .story-speech .speak-g i { color: #0e7d42; font-weight: 700; }
/* Goldilocks' three-bears delivery — a tray of tappable teddy bears */
.story-card.goldi-deliver { padding-bottom: calc(26px + var(--safe-b)); }
/* SHORT characters (kids etc.) — a taller figure so they fill the upper/middle
   screen instead of sitting low. Applied via SHORT_FIGS/.tall in ui.js. */
.story-figure.tall { height: 92vh; }
.story-figure.tall img.story-face { max-width: 128vw; }   /* let medium-width poses fill the height rather than being width-capped */
.goldi-deliver .story-figure { height: 92vh; }   /* short kid — big boost so she fills the upper screen; feet tuck behind the bear tray below */
.goldi-deliver .story-figure img.story-face { max-width: 128vw; }
/* the "too big" reaction is a wide image with Goldilocks on the LEFT — crop to
   keep her centred; the giant bear runs off the right edge. */
.goldi-deliver .story-figure.crop img.story-face { width: 100vw; max-width: none; object-fit: cover; object-position: 26% bottom; }
/* a poster/photo prop (e.g. the blank tour poster) shows centred in the upper area, not bottom-anchored like a character */
.story-figure.poster { height: auto; bottom: auto; top: 7%; align-items: center; }
.story-figure.poster img.story-face { height: auto; width: auto; max-height: 64vh; max-width: 84vw; object-position: center;
  border-radius: 6px; box-shadow: 0 10px 30px rgba(0,0,0,.55); }
.goldi-deliver .story-below { gap: 9px; }
.goldi-tray { display: flex; align-items: flex-end; justify-content: center; gap: 18px; margin-top: 2px; }
.goldi-bear { position: relative; width: 92px; height: 92px; padding: 5px; border: none; cursor: pointer; border-radius: 50%; overflow: hidden;
  background: radial-gradient(circle at 50% 40%, rgba(255,242,208,.96), rgba(247,205,140,.92) 70%, rgba(208,148,68,.9));
  box-shadow: 0 4px 13px rgba(0,0,0,.55), inset 0 0 0 3px rgba(255,255,255,.4);
  display: flex; align-items: center; justify-content: center; animation: badgeBob 2.1s ease-in-out infinite; }
.goldi-bear:nth-child(2) { animation-delay: .3s; } .goldi-bear:nth-child(3) { animation-delay: .6s; }
.goldi-bear:active { transform: scale(.9); }
.goldi-bear .goldi-bear-img.art { height: 80px; width: auto; max-width: none; object-fit: contain; filter: drop-shadow(0 2px 4px rgba(0,0,0,.4)); }
.goldi-bear .art-emoji { font-size: 52px; line-height: 1; }
.goldi-hint { font-family: var(--ff-read); font-size: 14.5px; color: #ffe7ac; text-shadow: 0 1px 3px rgba(0,0,0,.8); letter-spacing: .3px; }
.btn.story-next { width: 100%; max-width: 400px; position: relative; overflow: visible; }

/* Beat-guard locked state: grayed out, untappable */
.btn.story-next.beat-locked {
  opacity: 0.28;
  pointer-events: none;
  filter: saturate(0) brightness(0.55);
  transform: scale(0.94);
  transition: none;
}

/* Simple, calm reveal: the locked button just fades back in (no bounce/sparkle) */
@keyframes beatReveal {
  0%   { opacity: 0.28; filter: saturate(0) brightness(0.55); transform: scale(0.97); }
  100% { opacity: 1; filter: saturate(1) brightness(1); transform: scale(1); }
}
.btn.story-next.beat-revealed {
  animation: beatReveal 0.3s ease-out forwards;
}

@keyframes storyIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes storyFloat { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }

/* ===== THE SATCHEL — main inventory of quest / keepsake items ===== */
.sat-item { display: flex; align-items: center; gap: 12px; padding: 10px 4px; border-bottom: 1px solid rgba(255,255,255,.08); }
.sat-item:last-child { border-bottom: none; }
.sat-ic { position: relative; flex: none; width: 52px; height: 52px; border-radius: 12px; display: flex; align-items: center; justify-content: center;
  font-size: 30px; background: linear-gradient(180deg, rgba(255,255,255,.14), rgba(255,255,255,.05)); box-shadow: inset 0 1px 0 rgba(255,255,255,.15); }
.sat-n { position: absolute; right: -4px; bottom: -4px; min-width: 18px; height: 18px; padding: 0 4px; border-radius: 9px; background: var(--gold, #ffcf5a);
  color: #3a2a10; font-size: 11px; font-weight: 900; display: flex; align-items: center; justify-content: center; box-shadow: 0 1px 3px rgba(0,0,0,.5); }
.sat-body { flex: 1; min-width: 0; }
.sat-name { font-weight: 800; font-size: 15px; }
.sat-from { font-size: 12px; opacity: .7; margin-top: 1px; }
.sat-note { font-size: 12.5px; margin-top: 3px; color: var(--good, #7ee08a); }
.sat-count { flex: none; font-weight: 900; font-size: 15px; opacity: .85; }
.sat-bar { height: 7px; border-radius: 4px; background: rgba(0,0,0,.35); overflow: hidden; margin-top: 5px; max-width: 180px; }
.sat-bar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, #c58bff, #ffd76a); }
.sat-item.locked .sat-ic { background: radial-gradient(circle at 50% 40%, rgba(255,224,130,.5), rgba(197,139,255,.28)); box-shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 0 12px rgba(255,215,120,.55); }
.sat-lock { position: absolute; top: -6px; left: -6px; font-size: 15px; animation: satSparkle 1.8s ease-in-out infinite; }
@keyframes satSparkle { 0%,100% { transform: scale(1) rotate(0); opacity: .85; } 50% { transform: scale(1.25) rotate(12deg); opacity: 1; } }
.sat-item.locked .sat-note { color: #ffd76a; }

/* ===== FULL-BLEED MINIGAMES — art fills the screen, header becomes a corner menu button ===== */
#app.mg-full { padding: var(--safe-t) 0 var(--safe-b); }
#app.mg-full > .screen { padding: 0; position: relative; }
/* the top HUD collapses to just a floating ☰ menu button in the corner */
#app.mg-full .hud { position: absolute; top: 8px; left: 10px; width: auto; margin: 0; padding: 0; background: none; z-index: 40; }
#app.mg-full .hud .title, #app.mg-full .hud .gold { display: none; }
#app.mg-full .hud .hud-left { gap: 0; font-size: 0; }            /* hides the 🐸 + treat count */
#app.mg-full .hud .hud-menu { font-size: 20px; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; color: #fff; background: rgba(18,10,28,.5); border: 1px solid rgba(255,255,255,.22);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); box-shadow: 0 2px 7px rgba(0,0,0,.45); }
/* hide the bottom hint line and let the play area go edge-to-edge */
#app.mg-full .stack-hint { display: none; }
#app.mg-full .carpet-sky, #app.mg-full .stack-sky, #app.mg-full .bq-shop,
#app.mg-full .wine-cloak, #app.mg-full .feast-stage, #app.mg-full .dance-stage, #app.mg-full .cake-stage2 { margin: 0; border-radius: 0; }
/* meter panels / top rows shift right so the floating ☰ menu doesn't cover them */
#app.mg-full .feast-hud, #app.mg-full .wolf-top { padding-left: 46px; }
#app.mg-full .cake-caption { padding-left: 40px; }
/* nudge each game's own top-left counter clear of the floating menu button */
#app.mg-full .bq-hud, #app.mg-full .stack-overlay { padding-left: 46px; }

/* ======================================================================= */
/* COACH — one-time spotlight tutorial tips + the How-to-Play reference     */
/* ======================================================================= */
/* Lady Gothel's evidence roams the floor — you have 5s to tap the runner to grab it. */
.clue-ov { position: fixed; inset: 0; z-index: 410; background: rgba(8,5,20,.72);
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); overflow: hidden;
  pointer-events: auto; touch-action: none; }   /* blocks all play underneath while you chase the clue */
/* big, semi-faded countdown numeral floating on top of the overlay */
.clue-count { position: fixed; inset: 0; z-index: 1; display: flex; align-items: center; justify-content: center;
  font-weight: 900; font-size: 42vh; line-height: 1; color: rgba(255,255,255,.24);
  pointer-events: none; text-shadow: 0 0 50px rgba(0,0,0,.5); }
.clue-count.beat { animation: clueBeat .5s ease-out; }
@keyframes clueBeat { 0% { transform: scale(1.3); color: rgba(255,240,190,.5); } 100% { transform: scale(1); color: rgba(255,255,255,.24); } }
.clue-count.out { opacity: 0; transition: opacity .2s ease; }
.clue-cap { position: fixed; left: 50%; top: 12%; transform: translateX(-50%); z-index: 4;
  width: min(90vw, 420px); text-align: center; background: linear-gradient(#251b40, #191130);
  color: #fff; border: 1px solid rgba(255,255,255,.15); border-radius: 16px; padding: 13px 16px;
  box-shadow: 0 14px 34px rgba(0,0,0,.55); }
.clue-cap.out { opacity: 0; transition: opacity .2s ease; }
.clue-cap .story-name { font-weight: 800; color: #d7a8ff; margin-bottom: 4px; }
.clue-cap .story-speech { font-size: 14.5px; line-height: 1.42; }
.clue-hint { display: block; margin-top: 7px; font-weight: 800; color: #ffe08a; }
/* the runner is positioned every frame by JS (translate x/y in viewport coords) */
.clue-runner { position: fixed; left: 0; top: 0; z-index: 3; will-change: transform;
  width: 90px; height: 90px; border-radius: 50%; border: none; padding: 0; cursor: pointer;
  background: radial-gradient(circle at 50% 42%, rgba(255,225,130,.55), rgba(255,205,90,.14) 62%, transparent 72%);
  display: flex; align-items: center; justify-content: center; touch-action: manipulation; }
.clue-runner-ic { font-size: 46px; line-height: 1; }
.clue-runner-ic.art, .clue-runner img.art { width: auto; height: auto; max-width: 82px; max-height: 82px; }
/* the "poof" when the clue escapes — a burst placed where it vanished */
.clue-poof { position: fixed; left: 0; top: 0; z-index: 4; width: 140px; height: 140px;
  display: flex; align-items: center; justify-content: center; font-size: 104px;
  opacity: 0; transform: scale(.3); pointer-events: none; }
.clue-poof.go { animation: cluePoof .74s ease-out forwards; }
@keyframes cluePoof { 0% { opacity: 0; transform: scale(.3); } 22% { opacity: 1; } 100% { opacity: 0; transform: scale(1.9); } }
.clue-grabbed { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -46%); z-index: 6;
  width: min(88vw, 360px); text-align: center; background: linear-gradient(#251b40, #191130);
  color: #fff; border: 1px solid rgba(255,255,255,.15); border-radius: 18px; padding: 20px 18px 18px;
  box-shadow: 0 18px 44px rgba(0,0,0,.6); opacity: 0; pointer-events: none;
  transition: opacity .28s ease, transform .28s ease; }
.clue-ov.show-grabbed .clue-grabbed { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%); }
.clue-ov.show-grabbed .clue-cap { opacity: 0; transition: opacity .2s ease; }
.clue-big-ic { font-size: 56px; line-height: 1; margin-bottom: 8px; min-height: 78px; display: flex; align-items: center; justify-content: center; }
.clue-big-ic-img.art, .clue-big-ic img.art { width: auto; height: auto; max-width: 96px; max-height: 78px; }
.clue-grabbed-name { font-weight: 800; font-size: 17px; margin-bottom: 6px; }
.clue-grabbed-note { font-size: 14px; line-height: 1.42; opacity: .95; margin-bottom: 14px; }
.clue-grabbed .btn { width: 100%; }

.coach-ov { position: fixed; inset: 0; z-index: 400; }
.coach-ov.out { opacity: 0; transition: opacity .19s ease; }
.coach-mask { position: fixed; background: rgba(8,5,20,.74); }
.coach-ring { position: fixed; border-radius: 16px; pointer-events: none;
  box-shadow: 0 0 0 3px rgba(255,222,120,.95), 0 0 22px 6px rgba(255,200,90,.5);
  animation: coachPulse 1.5s ease-in-out infinite; }
.coach-ov:not(.interact) .coach-ring { pointer-events: auto; }  /* block premature taps on the highlighted item */
@keyframes coachPulse {
  0%,100% { box-shadow: 0 0 0 3px rgba(255,222,120,.9), 0 0 18px 4px rgba(255,200,90,.4); }
  50%     { box-shadow: 0 0 0 4px rgba(255,238,155,1), 0 0 30px 11px rgba(255,205,95,.72); }
}
.coach-bubble { position: fixed; left: 50%; transform: translateX(-50%);
  width: min(88vw, 380px); background: linear-gradient(#251b40, #191130);
  color: #fff; border: 1px solid rgba(255,255,255,.15); border-radius: 16px;
  padding: 14px 16px 15px; box-shadow: 0 14px 34px rgba(0,0,0,.55); text-align: center; }
.coach-bubble.center { top: 50%; transform: translate(-50%, -50%); }
/* Highlighted spot too tall to sit outside of: pin the bubble to the bottom, in thumb reach. */
.coach-bubble.pinned { top: auto; bottom: calc(env(safe-area-inset-bottom, 0px) + 16px); }
.coach-bubble.pinned::before { display: none; }
.coach-bubble::before { content: ""; position: absolute; left: 50%; transform: translateX(-50%); border: 9px solid transparent; }
.coach-ov:not(.nohole) .coach-bubble:not(.above)::before { top: -18px; border-bottom-color: #251b40; }
.coach-ov:not(.nohole) .coach-bubble.above::before { bottom: -18px; border-top-color: #191130; }
.coach-bubble.center::before { display: none; }
.coach-head { display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 6px; }
.coach-emoji { font-size: 22px; line-height: 1; }
.coach-emoji img { width: 26px; height: 26px; vertical-align: middle; }
.coach-title { font-weight: 800; font-size: 16px; }
.coach-text { font-size: 14.5px; line-height: 1.42; opacity: .96; }
.coach-text b { color: #ffe08a; font-weight: 800; }
.coach-next { margin-top: 13px; }

.help-card { background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1);
  border-radius: 14px; padding: 12px 14px; margin-bottom: 10px; }
.help-h { font-weight: 800; font-size: 15.5px; margin-bottom: 5px; }
.help-b { font-size: 13.5px; line-height: 1.5; opacity: .9; }
.help-b b { color: #ffe08a; }

/* ======================================================================= */
/* KING'S COURTYARD — "Restore the Gems" hidden-stash puzzle                */
/* ======================================================================= */
/* the dark-stone bg blends any leftover strip on a very tall screen (art fits by WIDTH) */
.stash-wrap { position: absolute; inset: 0; overflow: hidden; background: #453530; }
.stash-wrap .stash-stage::after { content: ""; position: absolute; left: 0; right: 0; top: 99%; height: 60vh;
  background: linear-gradient(#453530, #3a2c27); }
/* Fit the art to the GAME COLUMN width (the 520px #app), top flush. Use 100% — NOT
   100vw — or a wide iPad blows the art up to the full viewport width and shows only
   the top slice. Fitting by width keeps all five edge gems on-screen & tappable. */
.stash-stage { position: absolute; top: 0; left: 0; width: 100%; }
.stash-bg { display: block; width: 100%; }
.stash-gem { position: absolute; z-index: 2; will-change: opacity, transform;
  transition: opacity .55s ease, transform .55s ease, filter .55s ease; }
.stash-gem.restored { opacity: 0; transform: scale(1.7); filter: brightness(2.2); pointer-events: none; }
.stash-hit { position: absolute; z-index: 4; transform: translate(-50%, -50%); padding: 0; border: none;
  width: 58px; height: 58px; background: transparent; border-radius: 50%;
  cursor: pointer; -webkit-tap-highlight-color: transparent; }
.stash-hit.done { display: none; }   /* no ring, no glow — the dull gems are the only clue */
/* mid-screen glow + stash reveal (positioned on the SCREEN so it's always centered) */
.stash-glow { position: absolute; left: 50%; top: 42%; transform: translate(-50%,-50%) scale(0); z-index: 3;
  width: 720px; height: 720px; border-radius: 50%; pointer-events: none; opacity: 0;
  background: radial-gradient(circle, rgba(255,244,200,.98) 0%, rgba(255,212,96,.62) 26%, rgba(255,190,60,0) 62%); }
.stash-glow.on { animation: stashGlow 1.3s ease-out forwards; }
@keyframes stashGlow { 0% { transform: translate(-50%,-50%) scale(0); opacity: 0; } 30% { opacity: 1; } 100% { transform: translate(-50%,-50%) scale(1); opacity: .82; } }
.stash-reveal { position: absolute; left: 50%; top: 42%; transform: translate(-50%,-50%) scale(.6); z-index: 5;
  display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; opacity: 0; pointer-events: none; }
.stash-reveal.on { opacity: 1; pointer-events: auto; animation: stashPop .5s cubic-bezier(.2,1.3,.5,1) forwards; }
@keyframes stashPop { to { transform: translate(-50%,-50%) scale(1); } }
.stash-treasure { font-size: 96px; filter: drop-shadow(0 0 24px rgba(255,215,110,.95)); animation: stashFloat 2.2s ease-in-out infinite; }
@keyframes stashFloat { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
.stash-reward { font-size: 24px; font-weight: 800; color: #ffe08a; text-shadow: 0 2px 6px rgba(0,0,0,.7), 0 0 14px rgba(255,210,90,.5); }

/* ---- Stepsisters' Bead Restring minigame ---- */
.beads-stage { position: absolute; inset: 0; overflow: hidden; background: #1c1230; }
.beads-bg { position: absolute; inset: 0; z-index: 0; background-size: cover; background-position: center top; background-repeat: no-repeat; }
/* transparent overlay JS-sized to the cover-placed mannequin image, so arcs+beads always track it */
.beads-scene { position: absolute; z-index: 2; pointer-events: none; }
/* end-screen keepsake photo: a framed crop of the mannequin wearing the finished necklaces */
.beads-photo { position: relative; overflow: hidden; width: 58vw; max-width: 236px; aspect-ratio: 0.9;
  border-radius: 12px; border: 4px solid #d9b25a; box-shadow: 0 6px 18px rgba(0,0,0,.45), inset 0 0 0 2px rgba(255,255,255,.15); background: #1c1230; }
.beads-photo-scene { position: absolute; }
.beads-photo-scene .beads-strings, .beads-photo-scene .beads-drape { position: absolute; inset: 0; }
.beads-hudline { position: absolute; top: 10px; left: 0; right: 0; display: flex; justify-content: center; gap: 10px; z-index: 6; pointer-events: none; }
.beads-chip { background: rgba(0,0,0,.55); color: #fff; border-radius: 12px; padding: 5px 12px; font-weight: 800; font-size: 14px; }
/* thin string-line guides drawn along the necklace arcs (behind the beads) */
.beads-strings { position: absolute; inset: 0; z-index: 2; pointer-events: none; width: 100%; height: 100%; }
/* strung beads draped along the mannequin's necklace arcs (positioned in %) */
.beads-drape { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.dbead { position: absolute; width: 3.6%; aspect-ratio: 1; transform: translate(-50%,-50%);
  background-size: contain; background-repeat: no-repeat; background-position: center; filter: drop-shadow(0 1px 1.5px rgba(0,0,0,.5)); transition: filter .35s ease; }
.dbead-done { filter: saturate(.28) brightness(.6) drop-shadow(0 1px 1.5px rgba(0,0,0,.5)); }   /* finished necklace — dimmed */
.dbead-in { animation: dbeadIn .3s ease; }
@keyframes dbeadIn { 0% { transform: translate(-50%,-50%) scale(0); } 60% { transform: translate(-50%,-50%) scale(1.4); } 100% { transform: translate(-50%,-50%) scale(1); } }
.beads-stage.beads-flash::after { content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none; background: radial-gradient(circle at 50% 34%, rgba(255,240,180,.55), rgba(255,240,180,0) 55%); animation: beadsFlash .5s ease forwards; }
@keyframes beadsFlash { 0% { opacity: 0; } 30% { opacity: 1; } 100% { opacity: 0; } }
.beads-fall { position: absolute; inset: 0; pointer-events: auto; z-index: 4; }
.bead { position: absolute; width: 58px; height: 58px; padding: 0; border: none; background: none; transform: translate(-50%,-50%);
  pointer-events: none; -webkit-tap-highlight-color: transparent;
  background-size: contain; background-repeat: no-repeat; background-position: center; filter: drop-shadow(0 3px 5px rgba(0,0,0,.45)); }
.bead.caught { animation: beadCaught .3s ease forwards; }
@keyframes beadCaught { to { transform: translate(-50%,-50%) scale(1.5); opacity: 0; } }
.bead.wrong { animation: beadWrong .32s ease forwards; }
@keyframes beadWrong { 0% { transform: translate(-50%,-50%) rotate(0); } 25% { transform: translate(-53%,-50%) rotate(-12deg); } 75% { transform: translate(-47%,-50%) rotate(12deg); } 100% { transform: translate(-50%,-50%) scale(.2); opacity: 0; } }
.bead.fade { animation: beadFade .4s ease forwards; }
@keyframes beadFade { to { opacity: 0; } }
/* the two shouting sisters, now up at the TOP of the screen (below the count), bigger */
.beads-tops { position: absolute; top: 46px; left: 0; right: 0; z-index: 6; display: flex; justify-content: space-between; align-items: flex-start; padding: 0 6px; pointer-events: none; }
.beads-corner { display: flex; flex-direction: column; gap: 1px; }
.beads-corner.ls { align-items: flex-start; } .beads-corner.rs { align-items: flex-end; }
.beads-sister { font-size: 30px; filter: drop-shadow(0 2px 4px rgba(0,0,0,.5)); margin: 0 8px; }
.beads-shout { position: relative; width: 47vw; max-width: 250px; aspect-ratio: 2.4; opacity: 0; transform: scale(.5); filter: drop-shadow(0 4px 6px rgba(0,0,0,.5)); }
.beads-shout .sb { position: absolute; inset: 0; background-size: contain; background-repeat: no-repeat; background-position: center; }
.beads-shout .beads-word { position: absolute; left: 6%; right: 6%; top: 39%; transform: translateY(-50%); text-align: center;
  font-weight: 900; font-size: clamp(22px, 6.6vw, 34px); letter-spacing: .5px; text-shadow: 0 1px 2px rgba(0,0,0,.45), 0 0 1px rgba(0,0,0,.5); }
.beads-shout.show { animation: beadShout .24s cubic-bezier(.2,1.5,.4,1) forwards; }
@keyframes beadShout { to { opacity: 1; transform: scale(1); } }
.beads-stage.beads-shake { animation: beadsShake .3s; }
@keyframes beadsShake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-7px); } 75% { transform: translateX(7px); } }
