/* Display + numeric faces (open-source: Lilita One, Roboto Condensed — OFL),
   self-hosted same-origin so the sandbox CSP (font-src 'self') serves them. */
@font-face {
  font-family: "Lilita One"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/lilita-one.woff2") format("woff2");
}
@font-face {
  font-family: "Roboto Condensed"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url("fonts/roboto-condensed.woff2") format("woff2");
}

:root {
  --ground:      #0b0e15;
  --ground-2:    #0f131d;
  --recess:      #05070c;
  --surface:     #161d2a;
  --surface-2:   #1d2637;
  --frame:       #2a3346;
  --frame-hi:    #3d4a64;
  --line:        #212a3b;

  --ink:         #e9edf6;
  --ink-dim:     #8b94a8;
  --ink-faint:   #545d74;

  --gold:        #e6b667;
  --gold-deep:   #a9752b;
  --gold-hi:     #f7dca4;
  --cyan:        #55d7e3;

  --dash:        #38455f;
  --tag-bg:      #0c1017;

  --r-sm: 8px;  --r-md: 14px;  --r-lg: 22px;
  --sp-1: 6px;  --sp-2: 10px;  --sp-3: 16px;  --sp-4: 24px;

  --font-ui: system-ui, -apple-system, "SF Pro Text", "Segoe UI", Roboto, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;
}

* { box-sizing: border-box; }
/* author display rules (e.g. .action { display:grid }) must not resurrect an
   element the engine hid — hidden means hidden, everywhere */
[hidden] { display: none !important; }

html, body {
  margin: 0; height: 100%;
  background: var(--ground); color: var(--ink);
  font-family: var(--font-ui);
  -webkit-font-smoothing: antialiased;
}

.app {
  position: relative; min-height: 100dvh;
  display: flex; align-items: stretch; justify-content: center;
  overflow: hidden;
  background: radial-gradient(120% 80% at 50% -10%, #141b29 0%, var(--ground) 55%, #070a10 100%);
}

/* ---------- the portrait stage (the cabinet) ---------- */
/* device frame — the Mobile/Desktop toggle switches .app between view-mobile
   (default, portrait) and view-desktop (landscape), independent of the real
   browser width so both can be previewed on the same screen. */
.stage {
  position: relative; width: min(440px, 94vw); max-width: 440px;
  min-height: min(92dvh, 900px); align-self: center;
  display: grid; grid-template-rows: auto 1fr auto;
  padding: calc(env(safe-area-inset-top) + 12px) 14px calc(env(safe-area-inset-bottom) + 52px);
  gap: var(--sp-3); isolation: isolate;
  border: 1px solid var(--line); border-radius: 30px;
  box-shadow: 0 40px 120px -30px #000, 0 0 0 1px #ffffff08 inset;
  overflow: hidden;
}
/* on a real phone (not a preview) the mobile frame fills the screen */
@media (max-width: 500px) {
  .app.view-mobile .stage { width: 100vw; max-width: none; min-height: 100dvh; border: 0; border-radius: 0; }
}
/* desktop landscape frame */
.app.view-desktop .stage {
  width: min(1200px, 96vw); max-width: 1200px;
  min-height: 0; height: min(88dvh, 680px); border-radius: 20px;
  display: block; padding: 0;
}
/* reels centered; room reserved below for the control clusters */
.app.view-desktop .reelwrap { position: absolute; inset: 54px 0 210px; margin: 0;
  display: flex; align-items: center; justify-content: center; z-index: 1; }
.app.view-desktop .well { width: min(46%, 520px); }
/* logo top-left */
.app.view-desktop .topbar { display: contents; }
.app.view-desktop .logo { position: absolute; top: 22px; left: 28px; z-index: 4; }
.app.view-desktop .wallet { display: none; }              /* balance shown as a stat */
/* character on the right */
.app.view-desktop .mascot { display: block; position: absolute; right: 1.5%; top: 14%;
  height: 62%; width: 200px; z-index: 2; border-radius: 16px;
  background: linear-gradient(180deg, #ffffff0a, #ffffff03); }
.app:not(.scaffold).view-desktop .mascot { border: 1px dashed rgb(255 255 255 / 12%); }

/* their exact control geometry (measured off the live HUD) */
.app.view-desktop .controls { display: contents; }
.app.view-desktop .btn { width: 38px; height: 38px; border-radius: 8px; }
.app.view-desktop .btn svg { width: 30px; height: 30px; }
.app.view-desktop .buy, .app.view-desktop .spin { width: 160px; height: 145px; }
.app.view-desktop .buy .action-content { flex-direction: column; font-size: 0; }
.app.view-desktop .buy .action-content svg { width: 64px; height: 64px; }
/* Bigger than mobile's 58 by rule (Jerry: desktop "should be at least bigger than mobile"). */
.app.view-desktop .spin .action-content svg { width: 66px; height: 66px; }
.app.view-desktop .bet { display: none; }                 /* bet is a stat here, not a stepper */
.app.view-desktop .ctrl-item .ctrl-lbl { display: none; } /* icon-only side buttons */
/* __left : feature button + BALANCE, bottom-left, inset 28 */
.app.view-desktop .ctrl-side.left { position: absolute; left: 28px; bottom: 28px; z-index: 4;
  flex-direction: column; align-items: flex-start; gap: 12px; }
/* __right : spin + side-button column + BET, bottom-right, inset 28 */
.app.view-desktop .spin { position: absolute; right: 80px; bottom: 96px; z-index: 4; }
.app.view-desktop .ctrl-side.right { position: absolute; right: 28px; bottom: 123px; z-index: 4;
  flex-direction: column-reverse; gap: 14px; }   /* fast on top, auto at the bottom */
.app.view-desktop .betstat { position: absolute; right: 44px; bottom: 30px; z-index: 4; }

/* ===== MOBILE HUD — matches their measured __mobile layout (390-wide) =====
   feature button + BALANCE bottom-left · spin (118×98) centered · side-stack +
   BET bottom-right · 14px insets · balance/bet as stats, not a wallet pill. */
.app.view-mobile .wallet { display: none; }             /* balance is a bottom stat */
.app.view-mobile .bet { display: none; }                /* bet is a stat here */
.app.view-mobile .menu-btn { display: grid; }
.app.view-mobile .stat { display: block; }
.app.view-mobile .ctrl-item .ctrl-lbl { display: none; }
.app.view-mobile .stage { padding-bottom: calc(env(safe-area-inset-bottom) + 176px); }
/* dissolve the wrappers so every control positions directly on the stage */
.app.view-mobile .controls,
.app.view-mobile .ctrl-side,
.app.view-mobile .ctrl-item,
.app.view-mobile .betstat { display: contents; }
.app.view-mobile .btn { width: 34px; height: 34px; }
/* bottom-left: settings on top, feature (bonus) button under it, BALANCE below */
.app.view-mobile #menuBtn { position: absolute; left: 14px; bottom: 146px; z-index: 4; }
.app.view-mobile .buy { position: absolute; left: 14px; bottom: 82px; width: 52px; height: 52px;
  min-width: 0; padding: 0; z-index: 4; }
/* gap/padding zeroed: the hidden "Bonus Buy" text node is still a flex item, so
   the inherited 9px gap (and 14px side padding) pushed the gift glyph off-centre */
.app.view-mobile .buy .action-content { flex-direction: column; gap: 0; font-size: 0; }
.app.view-mobile .buy .action-content svg { width: 26px; height: 26px; }
.app.view-mobile .balance { position: absolute; left: 14px; bottom: 12px; z-index: 4; text-align: left; min-width: 0; }
/* centre: spin, flanked by the bet - / + steppers */
.app.view-mobile .spin { position: absolute; left: 50%; transform: translateX(-50%); bottom: 59px;
  width: 118px; height: 98px; z-index: 4; }
.app.view-mobile #betStatDown { position: absolute; left: 96px; bottom: 91px; z-index: 4; }
.app.view-mobile #betStatUp { position: absolute; right: 96px; bottom: 91px; z-index: 4; }
/* bottom-right MIRRORS the left: fast on top (like settings), AUTO as a
   flipped 52px feature panel (like the gift), BET below (like BALANCE) */
.app.view-mobile #turboBtn { position: absolute; right: 14px; bottom: 146px; z-index: 4; }
.app.view-mobile #autoBtn { position: absolute; right: 14px; bottom: 82px; width: 52px; height: 52px;
  background: none; border: 0; box-shadow: none; z-index: 4; }
.app.view-mobile #autoBtn:hover { background: none; box-shadow: none; filter: brightness(1.12); }
.app.view-mobile #autoBtn.is-active { background: none; box-shadow: none; color: var(--tg-accent); }
.app.view-mobile #autoBtn .auto-shape { display: block; width: 100%; height: 100%; opacity: 1;
  transform: scaleX(-1); }
.app.view-mobile #autoBtn .glyph { width: 26px; height: 26px; opacity: 1;
  filter: drop-shadow(0 2px 3px rgb(0 0 0 / .5)); }
.app.view-mobile .betstat .statcol { position: absolute; right: 14px; bottom: 12px; z-index: 4;
  align-items: center; text-align: center; min-width: 0; }
.app.view-mobile .betstat .betstep { display: grid; place-items: center; appearance: none; cursor: pointer;
  width: 34px; height: 34px; border-radius: 8px; background: rgb(0 0 0 / .4);
  border: 1px solid rgb(255 255 255 / .5); color: #fff; font-size: 20px; line-height: 1; }
/* invisible edge-bleed hit areas — visuals stay 34px, tap targets grow to
   ≥44px and run to the bezel (an edge you can slam against registers; a 14px
   dead margin is what makes corner buttons feel hard). The ± steppers lean
   AWAY from spin so the risky bet-up gap never narrows. */
.app.view-mobile #menuBtn::after { content: ""; position: absolute; top: -8px; bottom: -8px; left: -16px; right: -8px; }
.app.view-mobile .buy::after { content: ""; position: absolute; top: -4px; bottom: -6px; left: -16px; right: -6px; }
.app.view-mobile #turboBtn::after { content: ""; position: absolute; top: -8px; bottom: -8px; left: -8px; right: -16px; }
.app.view-mobile #autoBtn::after { content: ""; position: absolute; top: -4px; bottom: -6px; left: -6px; right: -16px; }
.app.view-mobile .betstat .betstep::after { content: ""; position: absolute; top: -8px; bottom: -8px; left: 0; right: 0; }
.app.view-mobile #betStatDown::after { left: -10px; }
.app.view-mobile #betStatUp::after { right: -10px; }

/* Region base position. MUST come before the overlay components (.bg/.mascot/
   .splash/.loader set position:absolute and rely on winning by source order —
   equal specificity, later-defined declarations below override this one). */
.region { position: relative; }

/* ---------- reusable LOGO CREST (per-game art slots into this) ---------- */
.crest {
  position: relative; display: inline-flex; align-items: center; gap: .45em;
  padding: .5em .85em; border-radius: 12px;
  background: linear-gradient(180deg, #212b3d, #141b28);
  border: 1px solid var(--frame-hi);
  box-shadow: 0 1px 0 #ffffff14 inset, 0 8px 24px -12px #000;
  color: var(--gold-hi);
}
.crest-gem { width: .68em; height: .68em; transform: rotate(45deg); border-radius: 2px;
  background: linear-gradient(135deg, var(--gold-hi), var(--gold-deep));
  box-shadow: 0 0 10px var(--gold); }
.crest-word { font: 800 1em/1 var(--font-ui); letter-spacing: .14em; text-transform: uppercase; }
.crest-sm { font-size: 11px; }
.crest-lg { font-size: 23px; padding: .62em 1.05em; border-radius: 16px; }

/* ---------- BACKGROUND ---------- */
.bg {
  position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(90% 55% at 50% 12%, #1a2536 0%, transparent 60%),
    linear-gradient(180deg, #10151f 0%, #0a0d14 60%, #070a10 100%);
  background-color: var(--ground-2);
}
.bg::after {
  content: ""; position: absolute; inset: -20%;
  background: radial-gradient(40% 30% at 30% 25%, #24406b33, transparent 70%),
              radial-gradient(40% 34% at 72% 62%, #3a2a5a2e, transparent 70%);
  animation: drift 14s ease-in-out infinite alternate;
}
@keyframes drift {
  from { transform: translate3d(-2%, -1%, 0) scale(1.02); opacity: .8; }
  to   { transform: translate3d(3%, 2%, 0)  scale(1.08); opacity: 1; }
}

/* ---------- TOP BAR ---------- */
.topbar { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-2); }
.logo {
  border-radius: var(--r-md); padding: 6px 8px;
  display: grid; place-items: center;
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line);
}
.wallet {
  display: inline-flex; align-items: center; gap: 8px; padding: 9px 14px; border-radius: 999px;
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line); box-shadow: 0 1px 0 #ffffff0d inset;
}
.wallet .diamond { width: 12px; height: 12px; transform: rotate(45deg); border-radius: 3px;
  background: linear-gradient(135deg, var(--cyan), #2b9aa6); }
.wallet .bal { font: 600 15px/1 var(--font-ui); font-variant-numeric: tabular-nums; }
.wallet .cur { color: var(--ink-dim); font-size: 12px; font-weight: 600; }

/* ---------- REEL HOUSE ---------- */
.reelwrap { align-self: center; width: 100%; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--sp-3); }
.well {
  width: 100%; aspect-ratio: 5 / 3.4; border-radius: var(--r-lg); padding: 10px;
  background: linear-gradient(180deg, #0a0e16, var(--recess)); border: 1px solid #000;
  box-shadow: 0 0 0 1px var(--frame), 0 0 0 6px #0c111b, 0 0 0 7px var(--frame-hi),
    0 24px 60px -22px #000, 0 2px 20px #0008 inset;
}
.grid { width: 100%; height: 100%; display: grid;
  grid-template-columns: repeat(5, 1fr); grid-template-rows: repeat(3, 1fr); gap: 6px; }
.cell { border-radius: 10px; background: linear-gradient(180deg, #121a28, #0d1420);
  box-shadow: 0 1px 0 #ffffff08 inset, 0 -8px 18px -12px #000 inset; display: grid; place-items: center; }
.cell .sym { width: 46%; height: 46%; border-radius: 9px;
  background: linear-gradient(150deg, #263349, #1a2334); box-shadow: 0 2px 8px #0006; opacity: .7; }
.app.spinning .cell .sym { animation: flick .28s ease both; }
@keyframes flick { 0% { transform: translateY(-6px); opacity: .2; } 100% { transform: translateY(0); opacity: .7; } }

/* ---------- MASCOT ---------- */
.mascot { position: absolute; right: 6px; top: 46%; width: 62px; height: 150px;
  transform: translateY(-50%); border-radius: var(--r-md); z-index: 2; }

/* ---------- CONTROLS — Terminal Games bet UI, reimplemented in our code ----------
   Action buttons (spin, bonus-buy) use their actual SVG shape (viewBox 112×72,
   the exact path, a gradient rim + a bottom-darkening fill). Side buttons use
   their exact plain spec (#0006 fill, 1px 50%-white rim, radius 8, oversized
   glyph at .5 opacity). Stat = orange Lilita One label over a white 900 value;
   active = green #45ff5f. Our own glyphs sit in the icon slots; every value is
   editable from here. */
:root { --tg-accent: #45ff5f; --tg-label: #ff9f1c; }
.controls { position: relative; display: flex; align-items: end; justify-content: space-between;
  gap: var(--sp-2); }
.controls::before {
  content: ""; position: absolute; inset: -48px -14px -22px; z-index: -1; pointer-events: none;
  background: linear-gradient(180deg, transparent, #05070cc9 68%);
}
.ctrl-side { display: flex; flex-direction: column; gap: 12px; }
.ctrl-side.left { align-items: flex-start; }
.ctrl-side.right { align-items: flex-end; }

.ctrl-item { display: flex; flex-direction: column; align-items: center; gap: 5px; }
.ctrl-lbl { font: 400 8.5px/1 var(--font-num); letter-spacing: .08em; text-transform: uppercase; color: rgb(255 255 255 / 55%); white-space: nowrap; }

/* side icon buttons — their exact plain-glass spec */
.btn {
  appearance: none; cursor: pointer; user-select: none; position: relative;
  display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border-radius: 8px;
  background: #0006; border: 1px solid rgb(255 255 255 / 50%); color: #fff;
  transition: transform .2s ease, border-color .2s ease, background-color .2s ease, box-shadow .2s ease;
}
.btn svg { width: 30px; height: 30px; opacity: .5; transition: opacity .2s ease; }
/* Paperclip's burger bars are drawn full-bleed and read heavy at the shared 30 — the one
   glyph Jerry called out as too big. */
.menu-btn svg { width: 21px; height: 21px; }
.btn:hover svg, .btn.is-active svg { opacity: 1; }
/* the rim lights up on hover — same feel as the tilted glass panels (whose
   gradient edge catches the brightness lift). Listed per view for the steppers
   because their view-scoped base rules outrank a bare :hover. */
.btn:hover,
.app.view-desktop .betstat .betstep:hover,
.app.view-mobile .betstat .betstep:hover {
  border-color: rgb(255 255 255 / 92%); background: rgb(0 0 0 / .62);
  box-shadow: 0 0 12px rgb(255 255 255 / 16%), 0 1px 0 rgb(255 255 255 / 30%) inset;
}
.btn:active { transform: scale(.93); }
.btn.is-active { border-color: var(--tg-accent); color: var(--tg-accent); background: #0009;
  box-shadow: 0 0 0 1px rgb(69 255 95 / .35), 0 0 16px rgb(69 255 95 / .2); }

/* bet stepper — orange Lilita label over white value */
.bet {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px; border-radius: 8px;
  background: #0006; border: 1px solid rgb(255 255 255 / 50%);
}
.bet button { appearance: none; border: 0; width: 32px; height: 32px; border-radius: 6px;
  background: #ffffff17; color: #fff; font-size: 20px; line-height: 1; cursor: pointer;
  display: grid; place-items: center; transition: background .16s ease; }
.bet button:hover { background: #ffffff30; }
.bet .amt { min-width: 66px; text-align: center; padding: 0 2px; }
.bet .amt small { display: block; color: var(--tg-label);
  font: 400 10px/1 "Lilita One", var(--font-ui); letter-spacing: .08em; text-transform: uppercase; margin-bottom: 2px; }
.bet .amt b { font: 900 18px/1 var(--font-num); color: #fff; letter-spacing: .01em;
  font-variant-numeric: tabular-nums; text-shadow: 0 2px 8px rgb(0 0 0 / .65); }

/* stat readout (balance / bet) — their measured __stat/__label/__value; shown in desktop */
.stat { display: none; min-width: 120px; text-align: center; }
.stat .lab { display: block; color: var(--tg-label);
  font: 400 14px/1 "Lilita One", var(--font-ui); letter-spacing: 0.08em; text-transform: uppercase; }
.stat .val { display: block; margin-top: 3px; color: #fff;
  font: 400 24px/1 Arial, system-ui, sans-serif; letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums; text-shadow: 0 2px 8px rgb(0 0 0 / .65); }
.balance { text-align: left; }          /* balance left-aligned (label + number) like theirs */
.balance .val { font-weight: 400; }     /* balance number unbold */
.betstat .val { font-weight: 900; }     /* bet number bold */
.app.view-desktop .stat { display: block; }

/* the mobile AUTO panel is the mirror of the gift panel; on desktop the same
   button dresses as a plain 38px square, so the shape only exists on mobile */
.auto-shape { display: none; }
/* the spin panel is the mirror of the bonus panel (their is-action-reversed) */
/* desktop uses the landscape spin shape (flipped = their reversed); mobile uses their bucket shape */
.spin .shape-desktop { transform: scaleX(-1); }
.spin .shape-mobile { display: none; }
.app.view-mobile .spin .shape-desktop { display: none; }
.app.view-mobile .spin .shape-mobile { display: block; }
/* settings/menu button — above bonus buy, desktop only */
.menu-btn { display: none; }
.app.view-desktop .menu-btn { display: grid; }
/* +/- steppers flanking the BET readout (desktop) */
/* padding: 0 matters — UA button padding shoves the glyph off-centre once it
   overflows the padded content box (centering falls back to start) */
.betstat .betstep { display: none; padding: 0;
  transition: border-color .2s ease, background-color .2s ease, box-shadow .2s ease; }
/* drawn glyphs, sized to carry the same visual mass as the auto/fast icons */
.betstat .betstep svg { width: 26px; height: 26px; opacity: .5; transition: opacity .2s ease; }
.betstat .betstep:hover svg, .betstat .betstep:active svg { opacity: 1; }
.betstat .statcol { display: flex; flex-direction: column; align-items: center; min-width: 92px; }
.app.view-desktop .betstat { display: flex; align-items: center; justify-content: center; gap: 12px; min-width: 0; }
.app.view-desktop .betstat .betstep { display: grid; place-items: center; appearance: none; cursor: pointer;
  width: 38px; height: 38px; border-radius: 8px; background: rgb(0 0 0 / .4);
  border: 1px solid rgb(255 255 255 / .5); color: #fff; font-size: 20px; line-height: 1; }

/* action buttons (spin, bonus-buy) — their actual SVG shape carries the look */
.action {
  appearance: none; border: 0; background: none; padding: 0; margin: 0;
  position: relative; cursor: pointer; user-select: none; display: grid; place-items: center;
  transition: transform .2s ease, filter .2s ease;
}
.action:hover { filter: brightness(1.12); }
.action:active { transform: scale(.96); }
.action-shape { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.action-content { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; gap: 9px; color: #fff; }
.action-content svg { filter: drop-shadow(0 2px 3px rgb(0 0 0 / .5)); }
/* spin uses their action-shape panel (rounded rect); only the icon is round */
.spin { width: 132px; height: 84px; }
/* 58 on the phone: the mobile trapezoid is 137x114 and the crescents at 44 floated in it
   (Jerry, 2026-08-25). Desktop keeps its own 52 override below. */
.spin .action-content svg { width: 58px; height: 58px; color: #fff; }
.buy { min-width: 150px; height: 56px; padding: 0 14px; }
.buy .action-content { font: 400 15px/1 "Lilita One", var(--font-ui); letter-spacing: .03em; }
.buy .action-content svg { width: 20px; height: 20px; }
.app.spinning .spin .action-content svg { animation: spinicon .5s cubic-bezier(.3,.1,.2,1); }
@keyframes spinicon { from { transform: rotate(0); } to { transform: rotate(360deg); } }

/* ================= ENTRY CARDS (reusable shell) ================= */
.splash {
  position: absolute; inset: 0; z-index: 20;
  background: linear-gradient(180deg, #0b0e15f2, #05070ce6), #05070c;
  backdrop-filter: blur(3px);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-4); padding: 28px 16px calc(env(safe-area-inset-bottom) + 28px);
  text-align: center; transition: opacity .35s ease, visibility .35s;
}
.splash.hidden { opacity: 0; visibility: hidden; pointer-events: none; }

.splash-logo { opacity: 0; transform: translateY(-14px) scale(.9); }
.splash.entered .splash-logo { animation: logoIn .55s cubic-bezier(.2,.85,.25,1) forwards, floaty 3.6s ease-in-out 1s infinite; }

.cards { display: flex; align-items: flex-start; justify-content: center; gap: 12px;
  width: 100%; max-width: 420px; perspective: 900px; }
.card-slot {
  flex: 1; min-width: 0; transform-style: preserve-3d;
  transform: perspective(700px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform .3s ease;
}
.card-slot.mid { margin-top: 34px; }

.card { opacity: 0; transform: translateY(30px) scale(.9); will-change: transform, opacity; }
.splash.entered .card-slot:nth-child(1) .card { animation: cardIn .6s cubic-bezier(.2,.85,.25,1) .15s forwards; }
.splash.entered .card-slot:nth-child(2) .card { animation: cardIn .6s cubic-bezier(.2,.85,.25,1) .28s forwards; }
.splash.entered .card-slot:nth-child(3) .card { animation: cardIn .6s cubic-bezier(.2,.85,.25,1) .41s forwards; }

.card-face { animation: bob 4.6s ease-in-out infinite; }
.card-slot:nth-child(2) .card-face { animation-delay: -1.5s; }
.card-slot:nth-child(3) .card-face { animation-delay: -.7s; }

.frame {
  position: relative; border-radius: var(--r-md); padding: 12px 10px 14px;
  background: linear-gradient(180deg, #1b2436, #10161f);
  border: 1px solid var(--frame-hi);
  box-shadow: 0 1px 0 #ffffff10 inset, 0 22px 44px -26px #000, 0 0 0 3px #0a0e16;
  display: flex; flex-direction: column; align-items: center; gap: 9px;
}
.frame::before, .frame::after {
  content: ""; position: absolute; top: 6px; width: 10px; height: 10px;
  border-top: 2px solid var(--gold-deep); opacity: .8;
}
.frame::before { left: 6px; border-left: 2px solid var(--gold-deep); border-top-left-radius: 6px; }
.frame::after { right: 6px; border-right: 2px solid var(--gold-deep); border-top-right-radius: 6px; }
.frame .art { width: 100%; aspect-ratio: 1; border-radius: 10px;
  background: repeating-linear-gradient(135deg, #1a2233 0 8px, #151d2b 8px 16px);
  background-color: #141b28; border: 1px dashed var(--dash); }
.frame .k { font: 800 11px/1.2 var(--font-ui); letter-spacing: .12em; text-transform: uppercase; color: var(--gold-hi); }
.frame .d { font-size: 10px; color: var(--ink-dim); line-height: 1.3; }

.continue { opacity: 0; font: 700 12px/1 var(--font-ui); letter-spacing: .22em;
  text-transform: uppercase; color: var(--ink-dim); }
.splash.entered .continue { animation: fadeIn .5s ease .95s forwards, blink 2.4s ease-in-out 1.4s infinite; }

/* ================= LOADING SCREEN (reusable shell) ================= */
.loader {
  position: absolute; inset: 0; z-index: 30;
  background: radial-gradient(90% 60% at 50% 40%, #10151fe0, #05070cf5), #05070c;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 26px;
  transition: opacity .5s ease, visibility .5s;
}
.loader.done { opacity: 0; visibility: hidden; pointer-events: none; }
.loader-logo { animation: floaty 3.2s ease-in-out infinite; }
.loadbar { width: 150px; height: 4px; border-radius: 999px; background: #141b28; overflow: hidden;
  border: 1px solid var(--line); }
.loadbar span { display: block; width: 40%; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  animation: sweep 1.25s ease-in-out infinite; }

/* ================= keyframes ================= */
@keyframes cardIn { from { opacity: 0; transform: translateY(30px) scale(.9); }
  to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes logoIn { from { opacity: 0; transform: translateY(-14px) scale(.9); }
  to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
@keyframes floaty { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
@keyframes fadeIn { to { opacity: 1; } }
@keyframes blink { 0%,100% { opacity: .45; } 50% { opacity: 1; } }
@keyframes sweep { 0% { transform: translateX(-160%); } 100% { transform: translateX(400%); } }

/* ================= SCAFFOLD overlay ================= */
/* (.region position:relative is defined ABOVE the overlay components on purpose) */
.tag {
  position: absolute; z-index: 9; top: 4px; left: 4px; display: none;
  align-items: center; gap: 6px; padding: 3px 8px; border-radius: 6px;
  background: var(--tag-bg); border: 1px solid var(--dash); color: var(--ink-dim);
  font: 500 10px/1 var(--font-mono); letter-spacing: .02em; white-space: nowrap; pointer-events: none;
}
.tag .dot { width: 7px; height: 7px; border-radius: 50%; border: 1px solid var(--gold); background: transparent; }
.region[data-state="built"] .tag { color: var(--gold-hi); border-color: var(--gold-deep); }
.region[data-state="built"] .tag .dot { background: var(--gold); }
.app.scaffold .tag { display: inline-flex; }
.app.scaffold .region::before {
  content: ""; position: absolute; inset: 0; z-index: 8;
  border: 1px dashed var(--dash); border-radius: inherit; pointer-events: none;
}
.app.scaffold .region[data-state="built"]::before { border-color: var(--gold-deep); }

/* dev-only affordance — top-right, clear of the logo (top-left) and the
   bottom-anchored controls; the wallet pill is hidden in both views */
.devbar {
  position: fixed; z-index: 40; right: 10px; top: 8px;
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 6px 4px 10px; border-radius: 999px;
  background: #0a0d14e6; border: 1px solid var(--line); box-shadow: 0 10px 30px -10px #000;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  font: 500 11px/1 var(--font-mono); color: var(--ink-dim); opacity: .82;
}
.devbar:hover { opacity: 1; }
.devbar b { color: var(--ink); font-weight: 600; }
.devbar .toggle {
  appearance: none; cursor: pointer; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--ink); font: 600 11px/1 var(--font-ui);
  letter-spacing: .04em; padding: 7px 11px; text-transform: uppercase;
}
.devbar .toggle.on { background: var(--gold); color: #241804; border-color: var(--gold-hi); }
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 999px; overflow: hidden; }
.segbtn { appearance: none; cursor: pointer; border: 0; background: transparent; color: var(--ink-dim);
  font: 600 11px/1 var(--font-ui); letter-spacing: .04em; padding: 7px 12px; text-transform: uppercase; }
.segbtn.on { background: var(--gold); color: #241804; }
/* on a real phone the stage fills the screen and the logo owns the top-left,
   so the bar drops below the topbar into the empty band above the reels */
@media (max-width: 500px) { .devbar { top: 58px; } }

@media (prefers-reduced-motion: reduce) {
  .bg::after, .spin, .loader-logo, .splash-logo, .card-face, .loadbar span,
  .splash.entered .card, .splash.entered .continue { animation: none !important; }
  .card { opacity: 1; transform: none; }
  .splash-logo, .continue { opacity: 1; }
  .card-slot { transition: none; }
}

/* ---- engine board (board-lines.mjs mounts a Pixi canvas into the well) ---- */
.well { position: relative; }
/* height is set by game.mjs from the game's cols:rows (a fixed aspect here is
   wrong for every geometry except one, and was why symbols swam in the well) */
.well.engine-on { aspect-ratio: auto; }
.well.engine-on .grid { display: none; }             /* placeholder grid retires */
.board-host { position: absolute; inset: 10px; border-radius: calc(var(--r-lg) - 4px); overflow: hidden; }
.board-host canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.win-toast {
  position: absolute; left: 50%; top: 38%; transform: translate(-50%, -30%);
  padding: 10px 22px; border-radius: 12px; z-index: 5; pointer-events: none;
  font: 800 clamp(20px, 4vw, 34px) 'Lilita One', system-ui, sans-serif;
  color: #eaf4d8; background: #05070ccc; border: 1px solid #ffffff42;
  letter-spacing: 0.04em; opacity: 0; transition: opacity 0.2s ease, transform 0.2s ease;
}
.win-toast.show { opacity: 1; transform: translate(-50%, -50%); }

/* ================= CONTROL STATES (engine-wired) ================= */
/* steppers pin at the ladder ends and freeze while a round is in flight */
.betstat .betstep:disabled, .bet button:disabled, .buy-step:disabled {
  opacity: .35; pointer-events: none;
}
.action.buy:disabled { opacity: .5; pointer-events: none; filter: grayscale(.4); }

/* three-speed button: one/two/three bolts for normal/fast/superfast */
#turboBtn .bolts { display: flex; align-items: center; justify-content: center; }
#turboBtn .bolt { width: 24px; height: 24px; }
#turboBtn .bolt2, #turboBtn .bolt3 { display: none; margin-left: -10px; }
#turboBtn[data-speed="fast"] .bolt { width: 20px; height: 20px; }
#turboBtn[data-speed="fast"] .bolt2 { display: block; }
#turboBtn[data-speed="superfast"] .bolt { width: 17px; height: 17px; }
#turboBtn[data-speed="superfast"] .bolt2,
#turboBtn[data-speed="superfast"] .bolt3 { display: block; margin-left: -8px; }

/* autoplay: the glyph yields to the remaining-count while a chain runs */
.auto-count {
  position: absolute; inset: 0; z-index: 1; display: grid; place-items: center;
  font: 400 16px/1 "Lilita One", var(--font-ui); color: var(--tg-accent);
  text-shadow: 0 2px 6px rgb(0 0 0 / .6); pointer-events: none;
}
.auto-count[hidden] { display: none; }
#autoBtn .glyph.is-hidden { visibility: hidden; }

/* ================= OVERLAY SYSTEM (glass modals over the stage) ================= */
.overlay {
  position: absolute; inset: 0; z-index: 25; display: flex;
  align-items: center; justify-content: center; padding: 16px;
}
.overlay[hidden] { display: none; }
.overlay .scrim {
  position: absolute; inset: 0; background: #05070cb8;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
.panel {
  position: relative; z-index: 1; width: min(400px, 100%); max-height: 100%;
  display: flex; flex-direction: column; gap: 10px;
  border-radius: 16px; padding: 16px;
  background: linear-gradient(180deg, #141c2af0, #090d15f7);
  border: 1px solid rgb(255 255 255 / 40%);
  box-shadow: 0 1px 0 #ffffff14 inset, 0 30px 80px -20px #000;
}
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.panel-title {
  font: 400 18px/1 "Lilita One", var(--font-ui); color: var(--tg-label);
  letter-spacing: .05em; text-transform: uppercase;
}
.panel-close {
  appearance: none; cursor: pointer; display: grid; place-items: center;
  width: 32px; height: 32px; padding: 0; border-radius: 8px;
  background: #0006; border: 1px solid rgb(255 255 255 / 50%); color: #fff;
  transition: border-color .2s ease, background-color .2s ease;
}
.panel-close svg { width: 18px; height: 18px; opacity: .7; }
.panel-close:hover { border-color: rgb(255 255 255 / 92%); background: rgb(0 0 0 / .62); }
.panel-close:hover svg { opacity: 1; }
.panel-sub {
  margin: 0; font: 400 10px/1 var(--font-ui); letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-dim);
}
.panel-section { display: flex; flex-direction: column; gap: 9px; }
.section-title {
  margin: 6px 0 0; font: 400 12px/1 "Lilita One", var(--font-ui);
  letter-spacing: .1em; text-transform: uppercase; color: var(--tg-label);
}

/* ---------- autoplay picker ---------- */
.auto-panel { width: min(320px, 100%); }
.auto-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
.auto-opt {
  appearance: none; cursor: pointer; padding: 12px 0; border-radius: 8px;
  background: #0006; border: 1px solid rgb(255 255 255 / 50%); color: #fff;
  font: 900 15px/1 var(--font-ui); font-variant-numeric: tabular-nums;
  transition: border-color .2s ease, background-color .2s ease, color .2s ease, box-shadow .2s ease;
}
.auto-opt:hover {
  border-color: var(--tg-accent); color: var(--tg-accent); background: #0009;
  box-shadow: 0 0 0 1px rgb(69 255 95 / .35), 0 0 16px rgb(69 255 95 / .2);
}

/* ---------- settings ---------- */
.snd-row { display: grid; grid-template-columns: 72px auto 1fr; align-items: center; gap: 12px; }
.snd-lab {
  font: 400 12px/1 "Lilita One", var(--font-ui); letter-spacing: .06em;
  text-transform: uppercase; color: #fff;
}
.snd-toggle {
  appearance: none; margin: 0; position: relative; width: 42px; height: 23px;
  border-radius: 999px; cursor: pointer;
  background: #0008; border: 1px solid rgb(255 255 255 / 45%);
  transition: background-color .2s ease, border-color .2s ease;
}
.snd-toggle::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 17px; height: 17px;
  border-radius: 50%; background: #8b94a8; transition: transform .2s ease, background-color .2s ease;
}
.snd-toggle:checked { background: rgb(69 255 95 / .18); border-color: var(--tg-accent); }
.snd-toggle:checked::after { transform: translateX(19px); background: var(--tg-accent); }
.snd-vol { width: 100%; margin: 0; accent-color: var(--tg-accent); }
.snd-vol:disabled { opacity: .35; }
.info-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 7px 0; border-bottom: 1px solid #ffffff12;
}
.info-row:last-child { border-bottom: 0; }
.info-lab {
  font: 400 11px/1 "Lilita One", var(--font-ui); letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-dim);
}
.info-val { font: 600 13px/1.2 var(--font-ui); color: #fff; text-align: right; }

/* ---------- bonus buy (Paperclip anatomy, our glass) ---------- */
.buy-panel { width: min(760px, 100%); }
.buy-cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  /* max-content, NOT auto: in a height-constrained scroll container Chrome
     resolves auto rows against the container height — 6 cards compressed to
     105px each and the bodies clipped (measured). max-content sizes rows to
     the card and lets the container actually scroll. */
  grid-auto-rows: max-content;
  gap: 12px; overflow-y: auto; min-height: 0; padding: 2px;
}
.buy-card {
  display: flex; flex-direction: column; border-radius: 12px; overflow: hidden;
  background: linear-gradient(180deg, #1b2436, #10161f);
  border: 1px solid var(--frame-hi);
  box-shadow: 0 1px 0 #ffffff10 inset, 0 14px 30px -18px #000;
}
.buy-card.is-disabled { opacity: .55; }
.buy-card-art {
  position: relative; height: 96px; flex: 0 0 auto; display: grid; place-items: center;
  background:
    radial-gradient(70% 90% at 50% 10%, #24406b55, transparent 70%),
    linear-gradient(160deg, #223048, #131a29);
  border-bottom: 1px solid #ffffff14;
}
.buy-card-art span {
  font: 400 34px/1 "Lilita One", var(--font-ui); color: var(--gold-hi);
  text-shadow: 0 0 18px rgb(230 182 103 / .45), 0 3px 8px #000a;
}
.buy-card-body {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 10px 10px 12px; text-align: center; flex: 0 0 auto;
}
.vol-row { display: flex; align-items: center; gap: 2px; }
.vol-row svg { width: 13px; height: 13px; }
.vol-row .vol-on { color: var(--cyan); }
.vol-row .vol-off { color: #2a3346; }
.buy-card-title {
  font: 400 13px/1.15 "Lilita One", var(--font-ui); letter-spacing: .05em;
  text-transform: uppercase; color: #fff;
}
.buy-card-amt {
  font: 900 19px/1 var(--font-num, var(--font-ui)); color: var(--gold-hi);
  font-variant-numeric: tabular-nums; text-shadow: 0 2px 8px rgb(0 0 0 / .65);
}
.buy-card-btn, .confirm-btn {
  appearance: none; cursor: pointer; width: 100%; padding: 9px 0; border-radius: 999px;
  background: rgb(69 255 95 / .14); border: 1px solid var(--tg-accent); color: var(--tg-accent);
  font: 400 13px/1 "Lilita One", var(--font-ui); letter-spacing: .08em; text-transform: uppercase;
  transition: background-color .2s ease, box-shadow .2s ease, filter .2s ease;
}
.buy-card-btn:hover, .confirm-btn:hover {
  background: rgb(69 255 95 / .26);
  box-shadow: 0 0 0 1px rgb(69 255 95 / .35), 0 0 16px rgb(69 255 95 / .22);
}
.buy-card-btn:disabled { pointer-events: none; filter: grayscale(.7); }
.buy-bottom {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding-top: 4px; border-top: 1px solid #ffffff12;
}
.buy-stat { text-align: left; }
.buy-stat .lab {
  display: block; font: 400 10px/1 "Lilita One", var(--font-ui);
  letter-spacing: .08em; text-transform: uppercase; color: var(--tg-label);
}
.buy-stat .val {
  display: block; margin-top: 2px; font: 700 16px/1 var(--font-ui); color: #fff;
  font-variant-numeric: tabular-nums;
}
.buy-stat.mid { text-align: center; min-width: 74px; }
.buy-betrow { display: flex; align-items: center; gap: 8px; }
.buy-step {
  appearance: none; cursor: pointer; display: grid; place-items: center;
  width: 32px; height: 32px; padding: 0; border-radius: 8px;
  background: #0006; border: 1px solid rgb(255 255 255 / 50%); color: #fff;
  font-size: 18px; line-height: 1;
  transition: border-color .2s ease, background-color .2s ease;
}
.buy-step:hover { border-color: rgb(255 255 255 / 92%); background: rgb(0 0 0 / .62); }

/* confirm step: a centered card over the dimmed mode grid (their flow) */
.buy-confirm { position: absolute; inset: 0; z-index: 2; display: flex;
  align-items: center; justify-content: center; padding: 14px; border-radius: inherit; }
.buy-confirm[hidden] { display: none; }
.confirm-scrim { position: absolute; inset: 0; background: #05070cd6; border-radius: inherit; }
.confirm-card {
  position: relative; width: min(320px, 100%); max-height: 100%; overflow-y: auto;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  border-radius: 14px; padding: 0 0 14px; overflow-x: hidden;
  background: linear-gradient(180deg, #1b2436, #10161f);
  border: 1px solid var(--frame-hi);
  box-shadow: 0 1px 0 #ffffff10 inset, 0 24px 60px -22px #000;
}
.confirm-card > * { margin: 0 16px; }
.confirm-art { width: 100%; height: 128px; margin: 0 0 4px; }
.confirm-vol { display: flex; }
.confirm-title {
  font: 400 16px/1.15 "Lilita One", var(--font-ui); letter-spacing: .05em;
  text-transform: uppercase; color: #fff; text-align: center;
}
.confirm-desc { font: 400 12px/1.45 var(--font-ui); color: var(--ink-dim); text-align: center; }
.confirm-amt {
  font: 900 24px/1 var(--font-num, var(--font-ui)); color: var(--gold-hi);
  font-variant-numeric: tabular-nums; text-shadow: 0 2px 8px rgb(0 0 0 / .65);
}
.confirm-btn { width: calc(100% - 32px); }
.confirm-back {
  appearance: none; cursor: pointer; background: none; border: 0; padding: 4px;
  font: 400 11px/1 var(--font-ui); letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-dim); transition: color .2s ease;
}
.confirm-back:hover { color: #fff; }

/* portrait: single-column card list, like their portrait buy screen */
.app.view-mobile .buy-cards { grid-template-columns: 1fr; }
.app.view-mobile .buy-panel { width: min(360px, 100%); }
@media (max-width: 500px) {
  .app.view-mobile .overlay { padding: 12px; }
}

/* ================= MOMENT LAYER ================= */
/* Big-win ladder plaque (MOMENT_RECIPES §1-2): scrim + Lilita One numerals;
   ONE linear count-up drives the number; tier classes escalate the treatment.
   z 26: above the game overlays (25), below the devbar (40). */
.bigwin {
  position: absolute; inset: 0; z-index: 26; display: flex;
  align-items: center; justify-content: center; padding: 24px;
  cursor: pointer; user-select: none;
  opacity: 0; transition: opacity .3s ease;
}
.bigwin.show { opacity: 1; }
.bigwin-scrim {
  position: absolute; inset: 0; background: #05070cd9;
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
.bigwin-card {
  position: relative; display: flex; flex-direction: column; align-items: center;
  gap: 6px; text-align: center; pointer-events: none;
}
.bigwin-title {
  font: 400 clamp(30px, 7vw, 52px)/1 "Lilita One", var(--font-ui);
  letter-spacing: .06em; color: var(--gold-hi);
  text-shadow: 0 0 24px rgb(230 182 103 / .55), 0 4px 14px #000c;
}
.bigwin-amount {
  font: 400 clamp(42px, 10vw, 76px)/1.1 "Lilita One", var(--font-ui);
  font-variant-numeric: tabular-nums; color: #fff;
  text-shadow: 0 0 30px rgb(230 182 103 / .4), 0 5px 18px #000d;
}
.bigwin-hint {
  margin-top: 14px; font: 700 10px/1 var(--font-ui); letter-spacing: .22em;
  text-transform: uppercase; color: var(--ink-dim);
  animation: blink 2.4s ease-in-out 1s infinite;
}
/* tier escalation: size + hue step up at each banner boundary */
.bigwin.tier-super .bigwin-title { color: #ffb84d; transform: scale(1.06); }
.bigwin.tier-mega  .bigwin-title { color: #ff7a5c; transform: scale(1.12); }
.bigwin.tier-epic  .bigwin-title { color: #ff5fd6; transform: scale(1.18); }
.bigwin.tier-max   .bigwin-title { color: #55d7e3; transform: scale(1.24); }
.bigwin.total .bigwin-title { color: var(--gold-hi); }
.bigwin-title, .bigwin-amount { transition: color .25s ease, transform .25s ease; }
/* banner beat: card pulse, retriggered per tier boundary */
.bigwin-card.pulse { animation: plaquePulse .45s cubic-bezier(.2,.85,.3,1); }
@keyframes plaquePulse {
  0% { transform: scale(1); } 30% { transform: scale(1.14); } 100% { transform: scale(1); }
}
/* §2a shockwave stand-in: full-stage kick on tier banners + gate commits
   (the reference is a ShockwaveFilter 50/450 over 0.5s on the whole stage) */
.stage.shock { animation: stageShock .5s ease-out; }
@keyframes stageShock {
  0% { transform: scale(1); filter: brightness(1); }
  18% { transform: scale(1.012); filter: brightness(1.25); }
  100% { transform: scale(1); filter: brightness(1); }
}
/* HUD held while the plaque/banner runs (depth-counted by the moment layer) */
.app.hud-held .controls button,
.app.hud-held .controls .stat,
.app.hud-held .controls .statcol,
.app.hud-held .controls .bet {
  opacity: .12; pointer-events: none; transition: opacity .25s ease;
}
/* free-spin banner + remaining-spins chip */
.fsbanner .fs-count { color: var(--gold-hi); }
.fs-chip {
  position: absolute; z-index: 6; top: 8px; left: 50%; transform: translateX(-50%);
  padding: 6px 14px; border-radius: 999px;
  background: #05070cd0; border: 1px solid var(--gold-deep);
  font: 400 11px/1 "Lilita One", var(--font-ui); letter-spacing: .1em;
  text-transform: uppercase; color: var(--gold-hi); white-space: nowrap;
}
.fs-chip b { color: #fff; font-weight: 400; margin-left: 4px; }
@media (prefers-reduced-motion: reduce) {
  .bigwin-card.pulse, .stage.shock, .bigwin-hint { animation: none !important; }
}

/* Mobile bet −/+ carried text glyphs; they are Paperclip chevrons now and need a box. */
.bet button svg { width: 16px; height: 16px; display: block; }

/* ---- bet amount menu + desktop action hover — Terminal Games, copied not approximated
   (mutiny v12, assets/index-Cf1Lye6j.css). Trigger = the whole bet stat as a chromeless
   button (tg-game-hud__bet-trigger); panel min(80vw,400px); grid
   repeat(auto-fit,minmax(72px,1fr)) gap 8px; option: 36px min-height, #ffffff14 fill,
   radius 10, Lilita 12px, hover #ffffff29 + translateY(-1px), active scale(.98),
   selected #45ff5f on #45ff5f24. The action-button hover juice is their is-action set:
   button scale(1.02); the feature (gift) icon tilts -10deg, the spin icon +10deg, on
   the .2s ease icon transition. Desktop-scoped — hover is a desktop sense, and a phone
   tap would leave the tilt stuck. */
.bet-trigger { appearance: none; padding: 0; color: inherit; text-align: inherit;
  background: transparent; border: 0; outline: none; cursor: pointer; font: inherit; }
.bet-trigger:disabled { cursor: default; opacity: 1; }
.bet-panel { width: min(80vw, 400px, calc(95vw - 28px)); }
.bet-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(72px, 1fr)); gap: 8px;
  max-height: min(52vh, 460px); overflow-y: auto; scrollbar-width: none; }
.bet-grid::-webkit-scrollbar { display: none; }
.bet-opt { appearance: none; cursor: pointer; display: grid; place-items: center;
  min-height: 36px; padding: 6px 8px; color: #ffffffeb;
  font: 400 12px/1 var(--font-num); text-align: center;
  background: #ffffff14; border: 0; border-radius: 10px; outline: none;
  transition: background-color .16s ease, transform .16s ease, color .16s ease; }
.bet-opt:hover { color: #fff; background: #ffffff29; transform: translateY(-1px); }
.bet-opt:active { color: #fff; transform: translateY(0) scale(.98); }
.bet-opt.is-selected { color: var(--tg-accent); background: #45ff5f24; }

/* And the SMALL buttons grow a touch on hover too (Jerry spotted it; measured):
   tg-game-hud__button:hover = scale(1.02); their steppers and menu-close run 1.04. */
.app.view-desktop .btn:hover:not(:disabled) { transform: scale(1.02); }
.app.view-desktop .betstat .betstep:hover:not(:disabled),
.panel-close:hover { transform: scale(1.04); }

.app.view-desktop .action { transition: transform .2s ease; }
.app.view-desktop .action:hover:not(:disabled) { transform: scale(1.02); }
.app.view-desktop .action:disabled:hover { transform: none; }
.app.view-desktop .action .action-content svg { transition: opacity .2s ease, transform .2s ease; }
.app.view-desktop .buy:hover:not(:disabled) .action-content svg { transform: rotate(-10deg); }
.app.view-desktop .spin:hover:not(:disabled) .action-content svg { transform: rotate(10deg); }
