
/* ── Google Sans Flex (self-hosted — no external font CDN) ── */
@font-face {
  font-family: 'Google Sans Flex';
  src: url('GoogleSansFlex.woff2') format('woff2');
  font-weight: 100 900;
  font-display: swap;
}

/* ── Originals Design System Tokens ──
   The Limbo Strike palette (trade.css) re-points these for every brand; the
   operator skin (brand-mybc on <html>, set by app.js from the server's
   brand) only adds operator marks, never colours. */
:root{
  /* Colors */
  --bg: #171717;
  --bg-secondary: #171717;
  --surface-default: #262626;
  --surface-raised: #404040;
  --surface-overlay: #171717;
  --border-default: #262626;
  --border-strong: #525252;

  /* Content */
  --content-primary: #ffffff;
  --content-secondary: #d4d4d4;
  --content-tertiary: #737373;
  --content-disabled: #525252;
  --content-inverse: #171717;

  /* Brand */
  --brand-primary: #ffd106;
  --brand-rgb: 255, 209, 6;   /* brand-primary as r,g,b for glows/tints — rgba(var(--brand-rgb), a) */
  --brand-secondary: #fbbf24;
  --brand-highlight: #fcd34d;
  --brand-border: #ccab18;

  /* Action / CTA accent — decoupled from --brand-primary so a brand can use a
     different colour for its primary buttons than for its arena/logo accent.
     Buttons follow the brand accent; MYBC sets both to orange. */
  --action-primary: var(--brand-primary);
  --action-rgb: var(--brand-rgb);
  --action-secondary: var(--brand-secondary);
  --action-text: var(--content-inverse);

  /* Status */
  --status-success: #22c55e;
  --status-success-strong: #16a34a;
  --status-success-rgb: 34, 197, 94;
  --status-error: #f43f5e;
  --status-error-rgb: 244, 63, 94;

  /* Shadow */
  --shadow-neutral: #171717;

  /* Typography */
  --font-primary: 'Google Sans Flex', system-ui, sans-serif;
  --font-mono: 'Google Sans Flex', ui-monospace, monospace;
  /* Card rank — Figma specifies Noto Serif SC; matched with a serif stack. */
  --font-card: 'Noto Serif SC', Georgia, 'Times New Roman', serif;

  /* Radius */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-full: 9999px;

  /* ── Legacy aliases ──
     HiLo's original vocabulary, remapped onto the Originals tokens above so
     every pre-existing rule re-themes from the brand blocks with no rewrite
     (dice/styles.css carries the same alias layer). */
  --panel:        var(--surface-default);
  --board:        var(--bg);
  --card-bg:      var(--surface-default);
  --card-shadow:  var(--shadow-neutral);
  --elevated:     var(--surface-raised);
  --hairline:     var(--border-default);
  --toggle-bg:    var(--surface-default);
  --toggle-border:var(--border-strong);
  --input-border: var(--border-strong);
  --input-bg:     var(--surface-default);

  --text:         var(--content-primary);
  --text-75:      var(--content-secondary);
  --text-mid:     var(--content-tertiary);
  --text-dim:     var(--content-disabled);
  --text-dimmer:  var(--content-disabled);

  --accent:       var(--brand-primary);
  --accent-2:     var(--brand-secondary);
  --accent-border:var(--brand-border);
  --accent-glow:  rgba(var(--brand-rgb), 0.20);
  --accent-soft:  rgba(var(--brand-rgb), 0.10);

  --green:        var(--status-success);
  --green-bright: var(--brand-highlight);
  --green-bg:     rgba(var(--status-success-rgb), 0.14);
  --red:          var(--status-error);
  --red-bg:       rgba(var(--status-error-rgb), 0.15);
}


*{ box-sizing: border-box; margin: 0; padding: 0; }
/* html carries the bg too so iOS safe-area insets aren't white (Originals boilerplate). */
html{ background: var(--bg); }
html, body{
  height: 100dvh;
  background: var(--bg);
  color: var(--content-primary);
  font-family: var(--font-primary);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
body{ display: flex; }
#root{
  width: 100%; margin: 0 auto;
  height: 100dvh; display: flex;
}

/* Originals scrollbar */
::-webkit-scrollbar{ width: 4px; height: 4px; }
::-webkit-scrollbar-track{ background: transparent; }
::-webkit-scrollbar-thumb{ background: rgba(255, 255, 255, 0.08); border-radius: 2px; }
::-webkit-scrollbar-thumb:hover{ background: rgba(255, 255, 255, 0.15); }

/* ===== APP ===== */
.app{
  width: 100%; max-width: 100%; height: var(--app-height, 100%); max-height: var(--app-height, 100%);
  border-radius: 0;
  overflow: hidden; display: flex; flex-direction: column;
  background: var(--board);
  box-shadow: none;
}

/* ===== HEADER — Originals .m-header anatomy (keno/dice parity) ===== */
.app > *{ width: 100%; }
/* Labelled History pill — the desktop entry point to the rounds drawer. */
/* Desktop shows the icon row + History pill; mobile collapses to History + 3-dot. */

/* ===== CARD TRAIL ===== */

/* Trail group = tag + card chip + arrow */
@keyframes trailSlideDown {
  0% {
    transform: translateY(-30px);
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    transform: translateY(0);
    opacity: 1;
  }
}

/* Tags */

/* Card chip row */

/* Arrow connector */

/* ===== ROW — a single column: header / arena / controls ===== */
.side{
  flex: 0 0 auto;
  display: flex; flex-direction: column; gap: 8px;
  width: 100%; max-width: 520px; margin: 0 auto;
  padding: 0 14px 14px;
}
.row{
  display: flex; flex-direction: column;
  flex: 1 1 auto; min-height: 0; overflow: hidden;
}
.side::-webkit-scrollbar{ width: 3px; }
.side::-webkit-scrollbar-track{ background: transparent; }
.side::-webkit-scrollbar-thumb{ background: rgba(255, 255, 255, 0.12); border-radius: 2px; }
.main{
  flex: 1; min-height: 0; min-width: 0;
  display: flex; flex-direction: column; overflow: hidden;
}

/* ===== GAME BOARD ===== */
.board{
  flex: 1; min-height: 0;
  display: flex; align-items: center; justify-content: center;
  gap: clamp(6px, 2.5vw, 24px); padding: 0 clamp(8px, 3vw, 24px);
  /* Single source of truth for the arena scale — the card, the tiles and every
     label derive from it, and it answers to both viewport axes. */
  --cw: clamp(56px, min(31vw, 20vh), 180px);
  position: relative; overflow: visible;
  background: var(--bg);
}

/* Card frame (dark border around card) */

/* Deck bottom - 3D stacked cards effect */

/* Main card (white face inside the dark frame) */
.main-card{
  position: absolute; inset: 0;
  background: #FFFFFF; border-radius: inherit;
  border: max(1px, calc(var(--cw) * 0.0089)) solid #D6D6D6;
  box-sizing: border-box;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  padding-top: calc(var(--cw) * 0.1293 - max(1px, var(--cw) * 0.0089));
  gap: 0;
  z-index: 3; overflow: hidden;
}
.main-card.mc-red{ color: var(--red); }
.main-card.mc-black{ color: #171717; }
/* Awaiting server response: a soft breathing glow on the current card while a
   guess/cashout/skip is in flight. Toggled (delay-gated) from JS so a fast
   response doesn't flicker. */
@keyframes hiloAwaitGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--brand-rgb), 0); }
  50%      { box-shadow: 0 0 22px 3px var(--accent-border); }
}
.main-card.awaiting{ animation: hiloAwaitGlow 0.9s ease-in-out infinite; }
.main-card.mc-empty{ background: transparent; border: none; padding: 0; }
/* Face-down card back — brand fill + the Figma diamond lattice, drawn in CSS so
   it re-tints from --brand-primary on every brand. */

/* ===== CONTROLS — Originals .m-controls anatomy =====
   Action row on top; below it the segmented tab group and the bet bar joined
   into one r16 card outlined in --border-default (keno/blackjack idiom). */

/* ── Action row: secondary (Skip) + primary CTA ── */
/* Primary CTA reads --action-* (MYBC: white label on orange). */
/* Cash Out is semantic green on every brand — it reads as "collect". */

/* ── Segmented Higher / Lower group (.m-risk-chip idiom) ── */

/* ── Bet bar — joins the tab group into one card ── */

/* ── Free-round strip (keno FreeRoundBar) ── */

/* ===== FOOTER ===== */

/* ===== ALERT =====
   Validation and connection alerts (min/max bet, target range, bet failed,
   connecting) share the insufficient-balance toast's anatomy: a surface
   pill centred over the scene, the warning glyph in the error colour. */
.alert-toast{
  box-sizing: border-box;
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; min-height: 40px; max-width: calc(100% - 32px);
  background: var(--surface-default); border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  position: absolute; left: 50%; top: calc(60% - 16px);
  transform: translate(-50%, -50%);
  z-index: 60; animation: toast-pop .2s ease;
  font-family: var(--font-primary); font-weight: 400; font-size: 12px; line-height: 16px; color: #FFFFFF;
  text-align: left;
}
.alert-icon{
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 24px; height: 24px; border-radius: 50%;
  background: rgba(255, 77, 79, 0.16); color: var(--status-error);
  font-size: 13px; line-height: 1;
}

/* ===== MODALS ===== */
.modal-overlay{
  position: fixed; inset: 0; width: 100vw; height: 100vh;
  background: rgba(0, 0, 0, 0.5);
  z-index: 100; display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none; transition: opacity 0.25s;
}
.modal-overlay.show{ opacity: 1; pointer-events: auto; }
.modal{
  background: var(--panel); border: 1px solid var(--hairline); border-radius: 14px;
  width: min(420px, calc(100vw - 32px)); max-height: min(520px, 70dvh);
  overflow-y: auto; padding: 24px; position: relative;
  box-shadow: 0 24px 80px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.06);
}
.modal::-webkit-scrollbar{ width: 3px; }
.modal::-webkit-scrollbar-track{ background: transparent; }
.modal::-webkit-scrollbar-thumb{ background: rgba(255, 255, 255, 0.15); border-radius: 2px; }
.modal h2{ font-size: 16px; font-weight: 700; margin-bottom: 14px; }
.modal h3{ font-size: 13px; font-weight: 700; color: var(--accent); margin: 12px 0 6px; }
.modal p, .modal li{ font-size: 12px; line-height: 1.6; color: var(--text-75); }
.modal ul, .modal ol{ padding-left: 18px; margin-bottom: 8px; }
.modal li{ margin-bottom: 3px; }
.modal-close{
  position: absolute; top: 14px; right: 14px;
  width: 28px; height: 28px; background: var(--card-bg);
  border: 1px solid var(--hairline); border-radius: 8px;
  color: var(--text-mid); font-size: 18px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: all 0.2s;
}
.modal-close:hover{ border-color: var(--accent-border); color: var(--text); }

/* ===== ANIMATIONS ===== */
@keyframes cashoutPulse {
  0%, 100% { box-shadow: 0 4px 16px rgba(var(--status-success-rgb), 0.30), inset 0 1px 0 rgba(255,255,255,0.2); }
  50% { box-shadow: 0 6px 28px rgba(var(--status-success-rgb), 0.50), inset 0 1px 0 rgba(255,255,255,0.2); }
}
@keyframes alertSlide {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.95); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

/* ===== RESPONSIVE ===== */

/* Fluid app */
@media (max-width: 1168px){
  .app{ width: 100%; height: var(--app-height, 100%); border-radius: 0; box-shadow: none; }
}

/* Landscape phones */
@media (max-height: 500px) and (orientation: landscape) and (min-width: 500px){
  
  /* Two-column: card + Higher/Lower on the left, control rail on the right.
     !important to beat the max-width:860 column rules that co-match at ~844x390. */
  /* Compact the Originals controls so the whole card fits a 390px-tall rail. */

  /* Compact cards for the narrowed landscape board (both the center card and the
     LOWER/HIGHER odds cards). */
  .board{ gap: 14px !important; padding: 0 12px !important; }
}

/* ===== FREE BET */

/* Glows in the CTA colour (--action-rgb). */
@keyframes freeBetPulse {
  0%, 100% { box-shadow: 0 4px 16px rgba(var(--action-rgb), 0.30), inset 0 1px 0 rgba(255,255,255,0.2); }
  50% { box-shadow: 0 8px 32px rgba(var(--action-rgb), 0.50), inset 0 1px 0 rgba(255,255,255,0.2); }
}

/* ===== FREE BET SUMMARY MODAL ===== */
.free-bet-summary{ text-align: center; max-width: 360px; }
.fbs-icon{ width: 60px; height: 60px; margin: 0 auto 14px; display: flex; align-items: center; justify-content: center; border-radius: 16px; background: rgba(var(--brand-rgb), 0.14); border: 1px solid rgba(var(--brand-rgb), 0.30); color: var(--accent); }
.fbs-icon svg{ width: 28px; height: 28px; }
.free-bet-summary h2{ margin-bottom: 16px; }
.fbs-btn{
  display: block;
  width: 100%;
  height: 50px;
  margin-top: 16px;
  border: none;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--action-primary) 0%, var(--action-secondary) 100%);
  color: var(--action-text);
  font-family: inherit;
  font-weight: 800;
  font-size: 15px;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  box-shadow: 0 4px 16px rgba(var(--action-rgb), 0.30), inset 0 1px 0 rgba(255,255,255,0.2);
  transition: all 0.2s;
}
.fbs-btn:hover{
  filter: brightness(1.08);
  box-shadow: 0 6px 24px rgba(var(--action-rgb), 0.40), inset 0 1px 0 rgba(255,255,255,0.2);
  transform: translateY(-1px);
}

/* ===== FREE BET WELCOME MODAL ===== */
.free-bet-welcome{ text-align: center; max-width: 360px; }
.fbw-icon{ width: 64px; height: 64px; margin: 0 auto 14px; display: flex; align-items: center; justify-content: center; border-radius: 18px; background: rgba(var(--brand-rgb), 0.14); border: 1px solid rgba(var(--brand-rgb), 0.30); color: var(--accent); animation: fbwBounce 0.6s ease-out; }
.fbw-icon svg{ width: 34px; height: 34px; }
@keyframes fbwBounce { 0% { transform: scale(0); opacity: 0; } 50% { transform: scale(1.2); } 100% { transform: scale(1); opacity: 1; } }
.fbw-desc{ font-size: 15px; color: var(--text-mid); line-height: 1.5; margin-bottom: 4px; }
.fbw-hl{ color: var(--accent); font-weight: 800; }
.fbw-sub{ font-size: 13px; color: var(--text-mid); line-height: 1.6; margin-bottom: 18px; }
.fbw-sub strong{ color: var(--text); font-weight: 800; }
.fbs-played{ font-size: 14px; color: var(--text-mid); margin-bottom: 14px; }
.fbs-played strong{ color: var(--text); font-weight: 800; }
.fbs-total{ font-size: 20px; font-weight: 800; white-space: nowrap; margin: 4px 0 16px; }

/* --- standardized bet panel (parity with rps/mines/tower/limbo) --- */

/* ---- DESKTOP: controls as a floating card at bottom-center (limbo parity) ---- */

.fbw-btn{
  display: block;
  width: 100%;
  height: 50px;
  margin-top: 16px;
  border: none;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--action-primary) 0%, var(--action-secondary) 100%);
  color: var(--action-text);
  font-family: inherit;
  font-weight: 800;
  font-size: 15px;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  box-shadow: 0 4px 16px rgba(var(--action-rgb), 0.30), inset 0 1px 0 rgba(255,255,255,0.2);
  transition: all 0.2s;
  animation: freeBetPulse 2s ease-in-out infinite;
}
.fbw-btn:hover{
  filter: brightness(1.08);
  box-shadow: 0 6px 24px rgba(var(--action-rgb), 0.40), inset 0 1px 0 rgba(255,255,255,0.2);
  transform: translateY(-1px);
}

/* ── Loading Screen ── */
/* ── Loading screen — blackjack's, 1:1 (styles.css 4248-4341) ──────────────
   Sizes here were all guesses before: an 80px operator logo where blackjack
   puts a 200px game wordmark, a 160x3 bar instead of 135x4, no watermark at
   all, and a linear fill instead of blackjack's stepped one. */
.loading-screen{
  position: fixed; inset: 0; z-index: 9999;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  height: 100%; background: #0d0d0d;
}
.loading-content{
  display: flex; flex-direction: column; align-items: center; gap: 16px;
}
.loading-bar-wrap{
  width: 135px; height: 4px;
  background: #262626; border-radius: 32px; overflow: hidden;
}
.loading-bar{
  width: 0%; height: 100%;
  background: var(--action-primary);   /* fill matches the CTA colour per brand */
  border-radius: 32px;
  /* Width and its timing come from <LoadingBar> in app.jsx: 90% over the
     minimum loading time, the rest when the game is ready. */
}
/* ── Before the server has decided the brand (ported from dice) ──
   The loading screen shows only its #0d0d0d background until a server
   response names the brand (app.jsx: .loading-content--hidden while
   !BRAND_KNOWN). Once known, the wordmark, bar and text fade in
   together, already in the brand's colours. */
.loading-content{ transition: opacity 200ms ease-out; }
.loading-content--hidden{ opacity: 0; }
/* The watermark only renders once the brand is known; fade it in with the
   content rather than popping. */
.loading-watermark{ animation: loading-fade-in 200ms ease-out; }
@keyframes loading-fade-in { from { opacity: 0; } to { opacity: 1; } }
.loading-text{
  font-family: var(--font-primary); font-weight: 400;
  font-size: 10px; line-height: 1.4; color: #ffffff; text-align: center;
}
.loading-watermark{
  position: absolute; bottom: 80px; left: 50%; transform: translateX(-50%);
}
.loading-watermark img{ width: 171px; height: 38px; }

/* =============================================================================
   Provably-Fair + History drawers (ported from Tower — used by
   HiLoPfDrawer / HiLoHistoryDrawer). All CSS vars referenced below already
   exist in HiLo's :root, so no literal substitutions were needed.
   ============================================================================= */
.drawer-backdrop{
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 200;
  display: flex; align-items: flex-end; justify-content: center;
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s ease;
}
.drawer-backdrop.show{ opacity: 1; pointer-events: auto; }
.drawer-backdrop.show .drawer{ transform: translateY(0); }
.drawer{
  width: 100%; max-width: 480px; max-height: 80vh;
  display: flex; flex-direction: column;
  background: var(--bg-secondary);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  transform: translateY(100%);
  transition: transform 0.25s ease;
}
.drawer-header{
  display: flex; justify-content: space-between; align-items: center;
  padding: 16px; height: 64px; box-sizing: border-box; flex-shrink: 0;
  background: var(--bg-secondary);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.drawer-title{ font-family: var(--font-primary); font-weight: 600; font-size: 14px; color: var(--content-primary); }
.drawer-close{
  width: 40px; height: 40px;
  display: flex; justify-content: center; align-items: center;
  background: none; border: none; border-radius: var(--radius-md);
  cursor: pointer; color: var(--content-secondary);
}
.drawer-close:active{ background: var(--surface-default); }
.drawer-close svg{ width: 18px; height: 18px; }
.drawer-tabs{
  box-sizing: border-box;
  display: flex; align-items: center; padding: 8px;
  margin: 0 16px 16px;
  background: var(--surface-overlay);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
}
.drawer-tab{
  flex: 1; height: 34px;
  display: flex; justify-content: center; align-items: center;
  border: none; border-radius: var(--radius-md); background: transparent;
  filter: drop-shadow(0 1px 0 var(--bg-secondary));
  cursor: pointer;
  font-family: var(--font-primary); font-weight: 400; font-size: 12px;
  color: var(--content-primary);
}
.drawer-tab--active{ background: var(--surface-default); box-shadow: 0 1px 0 var(--bg-secondary); }
.drawer-content{
  background: var(--bg-secondary);
  overflow-y: auto; flex: 1;
  padding: 0 16px 16px;
}

/* Drawer → centered card on desktop */
@media (min-width: 681px){
  .drawer-backdrop{ align-items: center; }
  .drawer-backdrop.show .drawer{ transform: scale(1); opacity: 1; }
  .drawer{
    max-width: 480px; max-height: 70vh; border-radius: var(--radius-lg);
    transform: scale(0.9); opacity: 0;
    transition: transform 0.2s ease, opacity 0.2s ease;
  }
  .drawer-content{ border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
}

/* ── Drawer content primitives (dice/blackjack .pf-* spec) ── */
.pf-desc{ font-family: var(--font-primary); font-weight: 400; font-size: 12px; line-height: 1.6; color: var(--content-secondary); }
.drw-card{
  background: rgba(0,0,0,0.22); border-radius: var(--radius-lg);
  padding: 16px; display: flex; flex-direction: column; gap: 10px;
  margin-bottom: 12px;
}
.drw-card:last-child{ margin-bottom: 0; }
.drw-card-title{ font-weight: 500; font-size: 14px; color: var(--content-primary); text-align: center; }
.drw-stat-row{ display: flex; justify-content: space-between; align-items: center; height: 28px; }
.drw-stat-label{ font-size: 12px; line-height: 1.5; color: var(--content-secondary); }
.drw-stat-value{ font-size: 12px; font-weight: 600; color: var(--content-primary); }
.drw-stat-value.green{ color: #4ade80; }
.pf-steps{
  display: flex; flex-direction: column; gap: 4px; align-items: center;
  background: rgba(0,0,0,0.22); border-radius: var(--radius-lg);
  padding: 16px; overflow: hidden;
}
.pf-step{ display: flex; gap: 10px; align-items: center; width: 100%; overflow: hidden; }
.pf-step-icon{
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; min-width: 32px;
  background: var(--brand-primary); color: var(--content-inverse);
  border-radius: var(--radius-full); padding: 6px; overflow: hidden;
  font-size: 12px; font-weight: 700;
}
.pf-step-text{ flex: 1; min-width: 0; font-weight: 400; font-size: 12px; line-height: 1.6; color: var(--content-secondary); }
.pf-step-arrow{ display: flex; align-items: center; padding: 0 16px; width: 100%; }
.pf-step-arrow-line{ width: 0; height: 20px; border-left: 1px dashed var(--content-tertiary); }

/* Seed / verify rows */
.pf-input{
  display: flex; align-items: center; gap: 12px;
  min-height: 56px;
  background: var(--surface-overlay);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: 8px 12px 8px 16px; box-sizing: border-box; width: 100%;
}
.pf-input:focus-within{ border-color: var(--content-secondary); }
.pf-input-text{ display: flex; flex-direction: column; flex: 1; min-width: 0; }
.pf-input-label{ font-weight: 400; font-size: 12px; line-height: 1.5; color: var(--content-secondary); }
.pf-input-value{
  font-family: var(--font-primary); font-weight: 400; font-size: 14px; line-height: 1.5;
  color: var(--content-primary);
  background: none; border: none; outline: none; padding: 0; width: 100%;
}
.pf-input-value::placeholder{ color: var(--content-tertiary); }
.pf-input-value.mono{ font-family: var(--font-mono); font-size: 12px; word-break: break-all; }
.pf-input-value.green{ color: #4ade80; }
.pf-input-btn{
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; min-width: 32px;
  background: var(--surface-default); border: none; border-radius: var(--radius-md);
  cursor: pointer; color: var(--content-secondary);
}
.pf-input-btn:active{ transform: scale(0.92); }
.pf-input-btn svg{ width: 14px; height: 14px; }
.pf-btn{
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 48px; min-height: 48px;
  background: var(--surface-default);
  border: none; border-radius: var(--radius-md);
  font-family: var(--font-primary); font-weight: 600; font-size: 14px; line-height: 1.5;
  color: var(--content-primary); cursor: pointer;
}
.pf-btn:active{ transform: scale(0.98); }
.pf-btn:disabled{ opacity: 0.5; cursor: not-allowed; }

/* Casino-style: the app is unselectable, but seeds/hashes must be copyable. */
.pf-input, .pf-input *, .hist-seeds, .hist-seeds *,
.hist-seed-group, .hist-seed-group *{ user-select: text; -webkit-user-select: text; }

/* ===== HISTORY LIST ===== */
/* Ported 1:1 from blackjack (styles.css .hist-*) so both games read identically:
   same surfaces, chip sizes, expanded-detail card and money rows. */
.hist-list{ display: flex; flex-direction: column; gap: 8px; }
.hist-item{
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-default); border-radius: 16px;
  padding: 8px 0; overflow: hidden; cursor: pointer;
}
.hist-item--expanded{ flex-direction: column; gap: 8px; }
.hist-header{
  display: flex; align-items: center; justify-content: space-between;
  padding-left: 4px; padding-right: 8px; width: 100%; box-sizing: border-box;
}
.hist-left{ display: flex; align-items: center; min-width: 0; flex-shrink: 1; }
.hist-icon{
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; min-width: 40px; border-radius: 12px;
}
.hist-icon svg{ width: 20px; height: 20px; }
.hist-info{ display: flex; flex-direction: column; justify-content: center; min-width: 0; }
.hist-info-title{
  font-family: var(--font-primary); font-weight: 500; font-size: 14px;
  line-height: 1.5; color: var(--content-secondary); white-space: nowrap;
}
.hist-info-sub{
  font-family: var(--font-primary); font-weight: 400; font-size: 10px;
  line-height: 1.4; color: var(--content-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hist-right{ display: flex; align-items: center; flex-shrink: 0; margin-left: auto; }
.hist-chips{ display: flex; align-items: center; gap: 8px; justify-content: flex-end; }
.hist-mult-chip{
  display: flex; align-items: center; justify-content: center;
  height: 24px; min-width: 56px; padding: 4px 8px;
  background: var(--surface-raised); border-radius: 8px;
  box-shadow: 0px 1px 0px #171717;
  font-family: var(--font-primary); font-weight: 400; font-size: 12px;
  line-height: 1.6; color: var(--content-primary);
  white-space: nowrap; box-sizing: border-box;
}
.hist-payout-chip{
  display: flex; align-items: center; justify-content: center;
  height: 24px; min-width: 72px; padding: 4px 8px; border-radius: 8px;
  font-family: var(--font-primary); font-weight: 400; font-size: 12px;
  line-height: 1.6; white-space: nowrap;
}
.hist-payout-chip--win{ background: rgba(34,197,94,0.14); color: #22c55e; }
.hist-payout-chip--lose{ background: rgba(244,63,94,0.14); color: #f43f5e; }
.hist-chevron{
  display: flex; align-items: center; justify-content: center;
  padding: 8px; border-radius: 12px; background: none; border: none; cursor: pointer;
}
.hist-chevron svg{ width: 16px; height: 16px; }
.hist-details{ padding: 0 8px; width: 100%; box-sizing: border-box; }
.hist-details-inner{
  display: flex; flex-direction: column; gap: 12px;
  background: rgba(0,0,0,0.14); border-radius: 12px; padding: 10px;
  width: 100%; box-sizing: border-box;
}

/* ── HiLo round detail: the step trail, blackjack's .hist-hand adapted ── */
.hist-hand{ display: flex; flex-direction: column; gap: 6px; }
.hist-hand-head{ display: flex; align-items: center; gap: 8px; }
.hist-hand-label{ font-size: 12px; font-weight: 600; color: #a3a3a3; }
.hist-hand-total{
  font-size: 13px; font-weight: 700; color: #fff;
  background: #262626; border-radius: 6px; padding: 1px 7px;
}
.hist-hand-cards{ display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.hist-card{
  position: relative; width: 30px; height: 42px; border-radius: 5px;
  background: #fff; color: #0d0d0d; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-primary);
}
.hist-card--red{ color: #ff5959; }
.hist-card--bust{ box-shadow: 0 0 0 2px #f43f5e; }
.hist-card b{ position: absolute; top: 2px; left: 3px; font-size: 11px; font-weight: 800; line-height: 1; }
.hist-card i{ display: flex; align-items: center; justify-content: center; }
.hist-card i svg{ display: block; width: 12px; height: 12px; }
.hist-step-arrow{ display: flex; align-items: center; flex-shrink: 0; }
.hist-step-arrow svg{ width: 12px; height: 12px; display: block; }
.hist-step-arrow--down{ color: #E11D48; }
.hist-step-arrow--up{ color: #22C55E; }
.hist-step-arrow--skip{ color: var(--content-tertiary); }
.hist-step-arrow--skip svg{ width: 12px; height: 12px; }
.hist-money{
  display: flex; flex-direction: column; gap: 4px;
  border-top: 1px solid #262626; padding-top: 10px;
}
.hist-money-row{ display: flex; justify-content: space-between; font-size: 13px; color: #a3a3a3; }
.hist-money-row > span:last-child{ color: #fff; font-weight: 600; }
.hist-money-row--net > span:last-child.pos{ color: #22c55e; }
.hist-money-row--net > span:last-child.neg{ color: #f43f5e; }
.hist-seeds{ display: flex; flex-direction: column; gap: 12px; padding: 0 4px; }
.hist-seed-group{ display: flex; flex-direction: column; justify-content: center; }
.hist-seed-label{
  font-family: var(--font-primary); font-weight: 400; font-size: 12px;
  line-height: 1.5; color: var(--content-secondary);
}
.hist-seed-value{
  font-family: var(--font-primary); font-weight: 400; font-size: 12px;
  line-height: 1.4; color: var(--content-primary);
  word-break: break-all; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.hist-verify-btn{
  display: flex; align-items: center; justify-content: center; gap: 4px;
  width: 100%; height: 40px;
  background: var(--surface-default); border: none; border-radius: 12px;
  font-family: var(--font-primary); font-weight: 600; font-size: 12px;
  line-height: 1.6; color: var(--content-primary); cursor: pointer;
}
.hist-verify-btn:active{ transform: scale(0.98); }
.hist-verify-btn:disabled{ cursor: default; }
.hist-verify-btn svg{ width: 20px; height: 20px; }
.hist-pager{
  display: flex; justify-content: center; align-items: center;
  gap: 10px; margin-top: 12px; padding-top: 10px;
  border-top: 1px solid var(--hairline);
}
.hist-pager-btn{
  width: 28px; height: 28px; border-radius: 8px;
  border: 1px solid var(--toggle-border); background: transparent;
  color: var(--text-mid); font-size: 13px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: all 0.15s; font-family: inherit;
}
.hist-pager-btn:hover:not(:disabled){ border-color: var(--accent-border); color: var(--text); }
.hist-pager-btn:disabled{ opacity: 0.2; cursor: default; }
.hist-pager-info{ font-size: 11px; color: var(--text-mid); min-width: 40px; text-align: center; }
.hist-empty, .hist-loading{
  font-family: var(--font-primary); font-weight: 400; font-size: 14px;
  color: var(--content-tertiary); text-align: center; padding: 40px 0;
}

/* Mobile: free-round welcome/completed modals become a bottom-sheet drawer (mines parity) */
@media (max-width: 680px){
  .modal-overlay:not(.modal-overlay--fr){ align-items: flex-end; }
  .modal:not(.modal--fr){
    width: 100%; max-width: 100%; max-height: 88dvh;
    border-radius: 18px 18px 0 0; border-bottom: none;
    padding: 22px 18px calc(20px + env(safe-area-inset-bottom));
  }
  .modal:not(.modal--fr)::before{
    content: ''; display: block; width: 36px; height: 4px;
    background: var(--hairline); border-radius: 2px; margin: -4px auto 16px;
  }
  .modal-overlay.show .modal:not(.modal--fr){ animation: hilo-sheet-up 0.3s cubic-bezier(0.16,1,0.3,1); }
}
@keyframes hilo-sheet-up { from { transform: translateY(100%); } to { transform: translateY(0); } }

/* Free-round welcome / summary / auto-summary: flex column so the action button
   sits in normal flow BELOW the content (never overlapping the Net Profit value).
   Taller max-height keeps it on-screen without scrolling in short / iframe viewports. */
.modal.free-bet-welcome,
.modal.free-bet-summary{ display: flex; flex-direction: column; max-height: min(560px, 88dvh); }
.modal .fbw-btn,
.modal .fbs-btn{ flex-shrink: 0; }

/* ═══════════════════════════════════════════════════════════════════
   Game shell — Figma MYBC-ORIGINALS 432-17431
   All sizes are the design's own (377px-wide artboard); the desktop
   media query at the bottom only re-centres, it never re-styles.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Header — blackjack 1:1 (styles.css:1529-1611) ── */
.m-header{
  display: flex; justify-content: space-between; align-items: center;
  padding: 12px; height: 56px; box-sizing: border-box;
  flex-shrink: 0; position: relative; z-index: 20;
}
.m-header-btn{
  display: flex; justify-content: center; align-items: center;
  padding: 8px; background: #262626; border: none; cursor: pointer;
  border-radius: 8px;
  -webkit-tap-highlight-color: transparent;
}
.m-header-btn--lg{ width: 32px; height: 32px; border-radius: 12px; }
.m-header-btn svg{ width: 16px; height: 16px; }
.m-header-btn:active{ transform: scale(0.92); }
.m-header-actions{ display: flex; align-items: center; gap: 8px; }
.m-header-actions .m-header-btn{ width: 32px; height: 32px; border-radius: 8px; }
/* Centre slot — blackjack parks its hidden results strip here; HiLo shows the
   operator wordmark (Figma 432-17431). The asset already bakes its watermark
   opacity, so no extra dimming. */
.m-header-logo{ height: 26px; width: auto; max-width: 45%; object-fit: contain; display: block; pointer-events: none; }
.desktop-only{ display: none !important; }
.m-header-history-btn{
  display: flex; align-items: center; justify-content: center;
  padding: 8px 12px 8px 8px; gap: 4px; height: 37px;
  background: #262626; border-radius: 12px; border: none; cursor: pointer;
  font-family: var(--font-primary); font-weight: 600; font-size: 14px; color: #FFFFFF;
  -webkit-tap-highlight-color: transparent;
}
.m-header-history-btn span{ white-space: nowrap; }
.m-header-history-btn svg{ width: 16px; height: 16px; flex-shrink: 0; }
.m-header-history-btn:active{ transform: scale(0.95); }

/* ── Mobile 3-dot menu — blackjack 1:1 (styles.css:3276-3312) ── */
.m-menu-backdrop{ position: fixed; inset: 0; z-index: 99; }
.m-menu{
  position: absolute; top: 40px; right: 0; z-index: 100;
  display: flex; flex-direction: column; min-width: 160px;
  background: #262626; border: 1px solid #404040; border-radius: 12px;
  padding: 4px; box-shadow: 0 8px 24px rgba(0,0,0,0.4);
}
.m-menu-item{
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; background: none; border: none; border-radius: 8px;
  cursor: pointer; font-family: var(--font-primary);
  font-size: 13px; font-weight: 500; color: #D4D4D4; white-space: nowrap;
}
.m-menu-item:active{ background: #404040; }
.m-menu-item svg{ width: 16px; height: 16px; flex-shrink: 0; }
.skip-tile:active:not(:is(:disabled, .spent)){ transform: translateX(-50%) scale(0.94); }
.skip-tile:is(:disabled, .spent){
  cursor: not-allowed;
  background: var(--surface-default);   /* stays fully opaque over the card */
  color: var(--content-tertiary);
}
.skip-tile:is(:disabled, .spent) svg{ color: var(--content-tertiary); }

/* ── Controls card: trail / CTA / bet bar in one r16 outlined container ── */
.m-controls{
  display: flex; flex-direction: column; width: 100%;
  border: 1px solid var(--border-default); border-radius: var(--radius-lg);
  overflow: hidden;
}
.m-cta-row{ padding: 8px; border-top: 1px solid var(--border-default); }
/* CTA sized to blackjack's .m-btn-deal: 48px tall, 14px/600, 10px 16px of
   padding on mobile and 16px 20px on desktop. hilo's was 40px at 12px with no
   padding at all, which read noticeably smaller and lighter than blackjack's. */
.m-btn-bet{
  box-sizing: border-box;
  display: flex; align-items: center; justify-content: center; gap: 4px;
  width: 100%; height: 48px; padding: 10px 16px;
  background: var(--action-primary); border: none; border-radius: var(--radius-md);
  cursor: pointer;
  font-family: var(--font-primary); font-weight: 600; font-size: 14px;
  color: var(--action-text); white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
}
.m-btn-bet:active:not(:disabled){ transform: scale(0.98); }
.m-btn-bet:disabled{ opacity: 0.5; cursor: not-allowed; }
/* Cashout is a DARK tile with green label — not a green fill (Figma). */
.m-btn-bet--cashout{ background: var(--surface-default); color: #4ADE80; }
.m-btn-bet--free{ animation: freeBetPulse 2s ease-in-out infinite; }

/* ── Bet bar (parent/bet-input, 40px) ── */
/* ── Bet row — blackjack's, 1:1 (styles.css 3417-3550 + .m-bet-bar--bj) ────
   Order: [currency chip + balance] | divider | 1/2 | [− Bet value +] | 2X.
   Differences from what hilo had: the balance was --content-tertiary (#737373,
   the label grey) where blackjack uses --content-secondary; the amount was
   weight 500 where blackjack uses 400 white; the chips had no border; the
   centre gap was 8px against blackjack's 4px; and the steppers/chips were a
   size larger (24px vs 22px). */
.m-bet-bar{
  box-sizing: border-box;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  height: 42px; min-height: 42px; max-height: 42px; padding: 10px;
  border-top: 1px solid var(--border-default);
  transition: border-color 0.2s;
}
/* Insufficient balance / over max bet: the AMOUNT flashes red, not the bar's
   border — in hilo the bar sits inside the controls card with only a top
   border (the divider under Place Bet), so a red border read as a red line
   under the button (blackjack's bar is a bordered pill of its own). */
.m-bet-value{ transition: color 0.2s; }
.m-bet-bar--flash .m-bet-value{ color: var(--status-error); }
.m-bet-left{ display: flex; align-items: center; gap: 4px; flex-shrink: 0; min-width: 0; }
.m-bet-currency{
  display: flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; flex-shrink: 0;
  background: var(--surface-raised); box-shadow: 0 1px 0 var(--shadow-neutral);
  border-radius: var(--radius-full);
  font-size: 10px; font-weight: 600; color: var(--content-primary);
}
.m-bet-balance{
  font-size: 12px; font-weight: 400; line-height: 150%;
  color: var(--content-secondary);
  font-family: var(--font-primary); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.m-bet-divider{
  width: 0; height: 16px; margin: 0 4px;
  border-left: 1px solid var(--border-default); flex-shrink: 0;
}
.m-bet-center{ display: flex; align-items: center; justify-content: center; gap: 4px; flex: 1; min-width: 0; }
/* Figma chip_button (blackjack styles.css:3572): white@8% fill, no border,
   8px radius, 10px white label. −/+ are 24x24, 1/2 and 2X are 32x24. The base
   .m-bet-chip / .m-bet-adj rules in blackjack are overridden by this block, so
   the solid #404040/#262626 fills and the #525252 chip border I had taken from
   them were never what actually renders there. */
.m-bet-adj, .m-bet-chip{
  box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  width: 24px; min-width: 24px; height: 24px; padding: 4px; flex-shrink: 0;
  background: rgba(255, 255, 255, 0.08);
  border: none; box-shadow: 0 1px 0 var(--shadow-neutral);
  border-radius: var(--radius-sm);
  font-size: 10px; font-weight: 400; color: var(--content-primary);
  cursor: pointer; font-family: var(--font-primary);
  -webkit-tap-highlight-color: transparent;
}
.m-bet-chip{ width: 32px; min-width: 32px; }
.m-bet-adj:active:not(:disabled){ transform: scale(0.95); }
.m-bet-adj:disabled{ opacity: 0.4; cursor: not-allowed; }
.m-bet-ico{ display: flex; align-items: center; color: var(--brand-primary); }
.m-bet-ico svg{ width: 14px; height: 14px; }
.m-bet-label{ font-size: 12px; font-weight: 400; color: var(--content-tertiary); white-space: nowrap; }
.m-bet-value{
  font-size: 12px; font-weight: 400; color: var(--content-primary);
  font-family: var(--font-primary); font-variant-numeric: tabular-nums;
  min-width: 46px; text-align: center;
  cursor: pointer; white-space: nowrap;
}
.m-bet-value--disabled{ opacity: 0.4; cursor: not-allowed; }
.m-bet-input{
  width: 50px; height: 22px;
  background: var(--surface-default); border: 1px solid var(--surface-raised);
  border-radius: 6px; color: var(--content-secondary);
  font-size: 12px; text-align: center; outline: none;
  font-family: var(--font-primary); -moz-appearance: textfield;
}
.m-bet-input::-webkit-inner-spin-button, .m-bet-input::-webkit-outer-spin-button{ -webkit-appearance: none; margin: 0; }
.m-bet-right{ display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.m-bet-chip--half{ flex-shrink: 0; }
.m-bet-chip:active:not(:disabled){ transform: scale(0.95); }
.m-bet-chip:disabled{ opacity: 0.45; cursor: not-allowed; }
.history-empty{ font-size: 11px; color: var(--content-tertiary); align-self: center; white-space: nowrap; }
/* Narrow phones (<=400px): blackjack tightens the row so 2X never clips
   outside the card (blackjack styles.css:3590). */
@media (max-width: 400px){
  .m-bet-bar{ gap: 6px; padding: 10px 8px; }
  .m-bet-divider{ margin: 0 1px; }
  .m-bet-center{ gap: 3px; }
  .m-bet-value{ min-width: 0; }
}
@media (max-width: 420px){
  /* The generic "Bet" label is dropped for space — the amount speaks for
     itself. The free-round label is NOT: with the gift icon gone from this bar
     it is the only thing marking the stake as a free round, so it stays. */
  .m-bet-label:not(.m-bet-label--free){ display: none; }
  .m-bet-balance{ max-width: 72px; }
}
/* Face-down: the ported blackjack CardBackSVG fills the card slot. */
.main-card.mc-empty{ background: transparent; border: none; padding: 0; }

/* ── Desktop (blackjack parity) ──────────────────────────────────────────────
   The frame fills the viewport: the header stretches edge to edge with the icon
   row broken out and History labelled, the arena scales up, and only the
   controls card stays capped at 520px and centred. */
@media (min-width: 768px){
  .desktop-only{ display: flex !important; }
  .mobile-only{ display: none !important; }

  .m-header{ height: 64px; padding: 16px 24px; }
  .m-header-btn--lg{ width: 36px; height: 36px; border-radius: 12px; }
  .m-header-logo{ height: 30px; }

  /* Arena grows into the extra room. */
  .board{ --cw: clamp(96px, min(30vw, 24vh), 214px); }

  /* Bet row + CTA at blackjack's desktop sizes (blackjack styles.css:4770). */
  .m-bet-bar{ padding: 12px; height: auto; min-height: 0; max-height: none; }
  .m-btn-bet{ padding: 16px 20px; gap: 6px; }

  /* Only the controls column is capped. */
  .side{ padding: 0 0 20px; }
}

/* ── Card reveal flip — blackjack bjFlip (styles.css:754-779) ── */
/* Outgoing card lifts straight up off the deck (production cardFlyUp). It sits
   above the incoming card, so it uncovers it as it goes. */
.main-card.card-out{
  z-index: 20;
  animation: cardFlyUp 0.62s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}
@keyframes cardFlyUp {
  0%   { transform: translateY(0);                    opacity: 1; }
  15%  { transform: translateY(-20px);                opacity: 1; }
  85%  { transform: translateY(calc(-50vh - 60px));   opacity: 1; }
  100% { transform: translateY(calc(-50vh - 120px));  opacity: 0; }
}
@keyframes cardFlip { from { transform: rotateY(0deg); } to { transform: rotateY(180deg); } }

/* ── Ported keyframes (blackjack) ── */
@keyframes toast-pop {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes cardPop {
  0%   { transform: scale(0.5);  opacity: 0; }
  60%  { transform: scale(1.06); opacity: 1; }
  100% { transform: scale(1);    opacity: 1; }
}
@keyframes chipRise {
  0%   { transform: translateY(10px); opacity: 0; }
  100% { transform: translateY(0);    opacity: 1; }
}
@keyframes win-pulse {
  0%, 100% { text-shadow: 0 0 6px rgba(var(--status-success-rgb), 0.15); }
  50%      { text-shadow: 0 0 30px rgba(var(--status-success-rgb), 0.45); }
}

@media (prefers-reduced-motion: reduce){
  .hcard.entering, .hc-top.reveal, .hc-seam.reveal, .step-chip--new{ animation: none !important; }
}

/* ═══ Toasts — ported from blackjack (styles.css:1613-1861) ═══ */

.insufficient-toast{
  box-sizing: border-box;
  display: flex; align-items: center; gap: 8px;
  padding: 8px; height: 40px;
  background: var(--surface-default); border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  position: absolute; left: 50%; top: calc(60% - 16px);
  transform: translate(-50%, -50%);
  z-index: 10; animation: toast-pop .2s ease;
  font-family: var(--font-primary); font-weight: 400; font-size: 12px; color: #FFFFFF;
}
.insufficient-toast span{ white-space: nowrap; }

.round-toast{
  display: flex; align-items: center; gap: 4px;
  position: absolute; top: 33%; left: 50%;
  transform: translate(-50%, -50%);
  z-index: 10; animation: toast-pop .2s ease; white-space: nowrap;
}
.round-toast-chip, .round-toast-detail{
  display: flex; justify-content: center; align-items: center;
  padding: 3px 5px; height: 22px; border-radius: 6px;
  box-shadow: 0 1px 0 var(--shadow-neutral);
  font-family: var(--font-primary); font-weight: 400; font-size: 11px; line-height: 1.4;
  color: #FFFFFF; white-space: nowrap; box-sizing: border-box;
}
.round-toast-chip--win{ background: #22C55E; }
.round-toast-chip--lose{ background: #F43F5E; }
.round-toast-detail{ background: var(--surface-default); }

/* ── Free-round modals — blackjack's .overlay/.modal, 1:1 ─────────────────
   These were riding hilo's generic .modal, which the max-width:680px block
   turns into a bottom sheet with a grabber bar — so on mobile the free-round
   congratulations slid up as a DRAWER while blackjack shows a centred modal.
   These two opt out of that entirely and take blackjack's chrome: darker
   blurred scrim, gradient card, spring pop-in, and no close button (blackjack's
   free-round modals have none — you dismiss with the CTA). */
.modal-overlay--fr{
  background: rgba(0, 0, 0, 0.78);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  align-items: center !important;
  padding: 16px; box-sizing: border-box;
}
.modal--fr{
  background: var(--bg);                     /* #171717 — blackjack's --card/--bg-secondary */
  border: 1px solid var(--surface-raised);  /* #404040 — blackjack's --brd2 */
  border-radius: var(--radius-lg);
  width: 100%; max-width: 440px; max-height: 88vh;
  padding: 24px 16px; text-align: center;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.6);
  animation: pop-in 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.modal-overlay--fr .modal--fr::before{ content: none; }   /* no sheet grabber */
@keyframes pop-in {
  from { opacity: 0; transform: scale(0.92); }
  to   { opacity: 1; transform: scale(1); }
}

/* Free-round modals lead with the game wordmark, matching blackjack (which
   heads both with LOADING_LOGO at 120px). Scaled to that footprint. */
.fr-wordmark{
  display: flex; align-items: center; justify-content: center; gap: 11px;
  margin: 0 auto 16px;
  font-family: var(--font-primary); font-weight: 700;
  font-size: 25px; line-height: 1; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--content-primary);
}
.fr-wordmark .lw-tri{ width: 16px; height: 16px; }

/* ── Free-round bar — keno's, ported (keno/app.jsx:1456) ───────────────────
   Keno wraps the counter in its own pill instead of leaving it as loose text,
   which reads far better above the controls card. Keno sets this inline; here
   it is a class so the compression tiers can reach it. */
.fr-bar{
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  border-radius: 10px;
  background: var(--surface-default);
  border: 1px solid var(--border-default);
  font-size: 13px; color: var(--content-primary);
  box-sizing: border-box;
}
.fr-bar-ico{ color: var(--brand-primary); display: flex; }
.fr-bar-ico svg{ width: 15px; height: 15px; }
.fr-bar-text{ font-weight: 600; }
.fr-bar-win{
  margin-left: auto; font-weight: 700;
  font-family: var(--font-mono); color: var(--status-success);
}

/* Free-round modals lead with the game wordmark, matching blackjack (which
   heads both with LOADING_LOGO at 120px). Scaled to that footprint. */
.fr-wordmark{
  display: flex; align-items: center; justify-content: center; gap: 11px;
  margin: 0 auto 16px;
  font-family: var(--font-primary); font-weight: 700;
  font-size: 25px; line-height: 1; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--content-primary);
}
.fr-wordmark .lw-tri{ width: 16px; height: 16px; }

/* ── Free-round counter — blackjack's, 1:1 (styles.css 1701-1719) ──────────
   "Free Round x/N" left, running "Total Win: $X" right in green. hilo showed
   only the round count in the bet bar, with no running total anywhere. */
.free-round-counter{
  display: flex; align-items: center; justify-content: space-between;
  width: 100%; gap: 12px;
  padding: 0 4px 8px; box-sizing: border-box;
}
.free-round-counter-text{
  font-family: var(--font-primary); font-weight: 600; font-size: 13px;
  color: var(--content-primary);
}
.free-round-winnings{
  font-family: var(--font-mono); font-weight: 700; font-size: 13px;
  color: #22C55E;
}
@keyframes cashout-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes borderGlow {
  0%   { box-shadow: 0 0 0 0 rgba(74,222,128,0),        0 16px 48px rgba(0,0,0,0.5); }
  35%  { box-shadow: 0 0 56px 4px rgba(74,222,128,0.6), 0 16px 48px rgba(0,0,0,0.5); }
  100% { box-shadow: 0 0 40px 0 rgba(74,222,128,0.15),  0 16px 48px rgba(0,0,0,0.5); }
}
@keyframes borderGlowBig {
  0%   { box-shadow: 0 0 0 0 rgba(var(--brand-rgb),0),        0 16px 48px rgba(0,0,0,0.5); }
  35%  { box-shadow: 0 0 56px 4px rgba(var(--brand-rgb),0.6), 0 16px 48px rgba(0,0,0,0.5); }
  100% { box-shadow: 0 0 40px 0 rgba(var(--brand-rgb),0.15),  0 16px 48px rgba(0,0,0,0.5); }
}
.cashout-confetti, .win-confetti{
  position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none;
}
.win-confetti{ z-index: 12; }

/* ── Short embeds ─────────────────────────────────────────────────────────────
   Operators frame these games at wildly different sizes. The chrome (header +
   action row + controls card) is ~292px fixed, which on a short frame leaves the
   arena nothing and the card spills out of the board.

   The chrome is NOT touched until 460px. Above that the frame still has room to
   render the header and footer at full size, and shrinking the arena alone (the
   20vh term in --cw does that continuously) is enough — compressing the chrome
   there just made everything small for no reason. Below 460 the arena can no
   longer absorb it, so the chrome compresses, then compresses again at 380. */
@media (max-height: 460px){
  .m-header{ height: 48px; padding: 8px 12px; }
  .m-header-btn--lg{ width: 30px; height: 30px; }
  .m-header-history-btn{ height: 32px; padding: 6px 10px 6px 6px; font-size: 13px; }
  .m-header-logo{ height: 20px; }
  .m-cta-row{ padding: 6px; }
  .m-btn-bet{ height: 36px; }
  .m-bet-bar{ height: 36px; min-height: 36px; padding: 0 8px; }
  .m-bet-currency{ width: 20px; height: 20px; }
  .m-bet-adj, .m-bet-chip{ height: 20px; }
  .side{ padding: 0 10px 10px; gap: 8px; }
  .board{ padding: 0 10px; }
}
@media (max-height: 380px){
  .m-header{ height: 42px; padding: 6px 10px; }
  .m-btn-bet{ height: 32px; }
  .m-bet-bar{ height: 32px; min-height: 32px; }
  .side{ padding: 0 8px 8px; gap: 6px; }
}

/* Safety net: below the size the compressed chrome can absorb, let the frame
   scroll instead of silently clipping the bet bar. Nothing should ever be
   unreachable in an operator's iframe, whatever height they pick. */
@media (max-height: 300px){
  html, body{ overflow-y: auto; }
  .app{ height: auto; min-height: 100%; }
  .row{ overflow: visible; }
}
.mc-outgoing.flying{ display: block; }
.skip-tile:is(:disabled, .spent){ opacity: 0.35; background: #242427; color: var(--content-primary); }
.skip-tile:is(:disabled, .spent) svg{ color: #f2f2f2; }

/* ── CTA: "Cashout" is greyed until there is something to cash out, then
   brand-coloured like Place a bet (Figma after-bet vs cashout frames). ── */
.m-btn-bet--cashout{ background: var(--action-primary); color: var(--action-text); }
.m-btn-bet--cashout:disabled{ background: var(--surface-default); color: var(--content-disabled); opacity: 1; }
/* Same hold for the red multiplier — the badge itself only fades in at
   .resolved time, but keep the colour gated so a settled/instant path that
   shows the badge early cannot leak the result either. */
.hcard.bust:not(.resolved) .hc-mult--bust{ color: #E5E5E5; }
.hcard.muted .hc-flip{ opacity: 0.42; }
.hcard.muted .hc-mult{ color: #737373; }
.hcard.bust.resolved{ background: rgba(244, 63, 94, 0.16); }
/* The fade finishes in the first fifth of the travel, so the card is already
   solid while it is still out by the strip's right edge. Fading across the
   whole path meant it only became visible once it was most of the way in,
   which read as the card appearing mid-strip out of nowhere. */
@keyframes hcCardEnter {
  from { opacity: 0; transform: translateX(var(--enter-x, 160px)); }
  20%  { opacity: 1; }
  to   { opacity: 1; transform: translateX(0); }
}
.hcard.entering{
  animation: hcCardEnter var(--enter-dur, 300ms) var(--enter-ease, cubic-bezier(.22, .61, .36, 1)) both;
}
@keyframes hcBadgeIn { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: translateY(0); } }
@keyframes hcSeamPop { from { opacity: 0; transform: translateY(-50%) scale(.4); } to { opacity: 1; transform: translateY(-50%) scale(1); } }
.hc-top.reveal{ animation: hcBadgeIn 110ms ease-out both; }
.hc-seam.reveal{ animation: hcSeamPop 110ms cubic-bezier(.34, 1.56, .64, 1) both; }
.card-frame, .deck-card, .mc-slot, .mc-spin, .main-card{ border-radius: calc(var(--cw) * 0.143); }

/* ═══════════════════════════════════════════════════════════════════════════
   Figma Section 4 — exact mobile frame (377x698, node 470-3410)
   Every number below is read off the frame SVG; the arena scales with --cw
   (126px card in a 377px frame) and the chrome uses the frame's fixed sizes.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 767px){
  /* Frame: #171717 game panel, r24 top, on the operator's #0D0D0D page. */
  .app{ background: #171717; }
  .row{ background: #171717; }
  .board{ --cw: clamp(56px, min(33.4vw, 22vh), 180px); padding: 0 16px; }
  .side{ padding: 0 16px 16px; gap: 0; }
}
.skip-tile:active:not(:is(:disabled, .spent)){ transform: scale(0.94); }
.skip-tile:is(:disabled, .spent){ opacity: 1; background: #262626; color: #737373; }
.skip-tile:is(:disabled, .spent) svg, .skip-tile:is(:disabled, .spent) .skip-count{ color: #737373; }
.skip-tile:is(:disabled, .spent){ opacity: 0.6; }

/* Controls card: 344 wide, r16, 1px #262626, #171717 fill. */
.m-controls{ background: #171717; }
.m-cta-row{ padding: 9px 8px; }
.m-btn-bet{ height: 40px; padding: 8px 16px; border-radius: 12px; font-size: 12px; font-weight: 600; }
.m-btn-bet--cashout:disabled{ background: #262626; color: #525252; }
.m-btn-bet{ color: var(--action-text); }
.m-bet-bar{ height: auto; min-height: 0; padding: 8px; gap: 6px; }
.m-bet-currency{ width: 24px; height: 24px; background: #404040; }
.m-bet-balance{ color: #D6D6D6; font-size: 12px; font-weight: 400; }
.m-bet-divider{ width: 1px; height: 16px; background: #262626; margin: 0 6px; }
.m-bet-adj, .m-bet-chip{ height: 24px; min-width: 24px; padding: 0 6px; border-radius: 8px; background: rgba(255,255,255,0.08); color: #FFFFFF; font-size: 10px; font-weight: 600; }
.m-bet-chip{ min-width: 32px; }
.m-bet-label{ color: #A3A3A3; font-size: 12px; font-weight: 400; }
.m-bet-value{ color: #FFFFFF; font-size: 12px; font-weight: 600; }
.m-bet-right{ display: flex; gap: 4px; }

/* ═══ Desktop — Figma Hi-Lo "web/pre-bet" (1536x1080 operator page) ═══
   The game is a #171717 r32 panel on the #0D0D0D page: 24px icon tiles
   (info · sound · fairness) top-left, a "History" pill top-right, the arena
   in the middle and the SAME 344px controls block as the phone, centred.
   No side tiles, no wordmark, no operator nav inside the panel. */
@media (min-width: 768px){
  html, body{ background: #0D0D0D; }
  .app{ background: #171717; }
  .board{ --cw: clamp(96px, min(22vw, 26vh), 180px); }
  .side{ max-width: 344px; padding: 0 0 24px; }
}

/* Pixel pass against the 377x698 frame (side-by-side): the arena is
   top-aligned under the header (deck frame 12px below it, card at y77),
   the arc and K/A labels sit at the frame's offsets, the skip tab is never
   dimmed before a bet, and the bet bar keeps its "Bet" label. */
@media (max-width: 767px){
  .board{ align-items: flex-start; padding-top: calc(var(--cw) * 0.166); }
  .m-bet-label:not(.m-bet-label--free){ display: inline; }
  .m-bet-balance{ max-width: none; }
}
.skip-tile:is(:disabled, .spent){ opacity: 1; color: #FFFFFF; }
.skip-tile:is(:disabled, .spent) svg, .skip-tile:is(:disabled, .spent) .skip-count{ color: #FFFFFF; }

/* Desktop arena = the phone arena, scaled by --cw: deck top-aligned under
   the header, arc and K/A labels at the frame's offsets and centred on the
   card (frame: arc box 377 wide, labels 16px inside its edges). */
@media (min-width: 768px){
  .board{ align-items: flex-start; padding-top: calc(var(--cw) * 0.166); }
}

/* Below the 377px frame width the bet bar and nav cannot keep every label. */
@media (max-width: 359px){
  .m-bet-label:not(.m-bet-label--free){ display: none; }
  .m-bet-bar{ gap: 4px; padding: 8px 6px; }
  .m-bet-balance{ font-size: 11px; }
}

/* Desktop: arena + buttons + controls form one compact group, centred in the
   panel, with the phone frame's 25px between the buttons and the controls
   card — the deck no longer floats far above the buttons on tall screens. */
@media (min-width: 768px){
  .row{ justify-content: center; }
  .board{ flex: 0 0 auto; height: calc(var(--cw) * 2.22); min-height: 0; }
}

/* HIGH / LOW chips: high #22C55E@12% / #70FFB7 · low #FF1800@12% / #FFB5AD. */

/* Header shares the panel colour; 16px between the action buttons and the controls card. */
.m-header{ background: #171717; }

/* The frame's arena is a fixed 280px tall (header 56 → buttons 336) at
   377 wide = 2.222 card widths. Keep it fixed on phones too, so the buttons
   and controls stay at the design's rows and any extra height stays below. */

/* Responsive arena: the board fills whatever height the frame gives it and
   the deck + table + K/A group is centred in it; every table measure scales
   with the card width (--cw), so the composition is the frame's at any size. */
@media (max-width: 767px){
  .board{ align-items: center; padding-top: 0; }
}

/* Desktop footer at the original desktop sizes (520px column, 56px action
   tiles, 48px CTA), not the phone's 344px block. */
@media (min-width: 768px){
  .side{ max-width: 520px; }
  .m-cta-row{ padding: 10px 12px; }
  .m-btn-bet{ height: 48px; font-size: 14px; }
  .m-bet-bar{ padding: 12px; }
  .m-bet-adj, .m-bet-chip{ height: 28px; font-size: 12px; }
  .m-bet-chip{ min-width: 40px; }
  .m-bet-balance, .m-bet-label, .m-bet-value{ font-size: 14px; }
  .m-bet-currency{ width: 28px; height: 28px; }
  .board{ height: calc(var(--cw) * 2.4); }
}
/* Buttons → controls card: exactly 16px on desktop too (the column's own
   8px flex gap was adding to the 16px margin). */
.side{ gap: 0; }

/* Big screens: the arena must not float up to the header while the controls
   sit at the bottom. Arena + buttons + controls form one group centred in
   the panel; the arena is only as tall as the deck needs. */
@media (min-width: 768px){
  .row{ justify-content: center; }
  .main{ flex: 0 0 auto; }
  .board{ flex: 0 0 auto; height: auto; min-height: 0; align-items: center; padding: calc(var(--cw) * 0.2) 16px calc(var(--cw) * 0.1); }
}
/* Big screens: controls stay at the bottom; the arena sits directly above
   them (the free space goes under the header, not between deck and buttons). */
@media (min-width: 768px){
  .row{ justify-content: flex-start; }
  .main{ flex: 1 1 auto; justify-content: center; }
}

/* Desktop-width embeds with little height (casino panel 1213x645, laptop
   1366x700, 900x460): the card must shrink with the height so header +
   arena (2.25 card widths) + buttons + controls (≈360px) always fit; below
   ~520px the panel scrolls instead of clipping the deck. */
@media (min-width: 768px){
  .board{ --cw: clamp(96px, min(22vw, calc((100vh - 360px) / 2.25)), 180px); }
}
@media (min-width: 768px) and (max-height: 600px){
  .row{ overflow-y: auto; }
  .main{ justify-content: flex-start; }
}
@media (min-width: 768px) and (max-height: 600px){
  .main{ flex: 0 0 auto; overflow: visible; }
}

/* ═══ Casino iframes on phones: the operator's header and bottom nav can
   leave the game as little as ~450px. The card follows the height so header +
   arena (2.25 card widths) + buttons + controls always fit, and under 600px
   the chrome compresses (48px header, 36px buttons/CTA, 56px strip). ═══ */
@media (max-width: 767px){
  .board{ --cw: clamp(64px, min(33.4vw, calc((100vh - 300px) / 2.25)), 180px); }
}
@media (max-width: 767px) and (max-height: 600px){
  .board{ --cw: clamp(64px, min(33.4vw, calc((100vh - 240px) / 2.25)), 180px); }
  .m-header{ height: 48px; padding: 8px 12px; }
  .m-header-btn--lg{ width: 30px; height: 30px; }
  .m-cta-row{ padding: 6px 8px; }
  .m-btn-bet{ height: 36px; }
  .m-bet-bar{ padding: 6px 8px; }
  .m-bet-adj, .m-bet-chip, .m-bet-currency{ height: 22px; }
  .side{ padding-bottom: 8px; }
}
@media (max-width: 767px) and (max-height: 430px){
  .row{ overflow-y: auto; }
  .main{ flex: 0 0 auto; overflow: visible; }
  .board{ min-height: calc(var(--cw) * 2.25); }
}
/* Desktop-width but short (≤520px): same compressed chrome as short phones. */
@media (min-width: 768px) and (max-height: 600px){
  .board{ --cw: clamp(64px, min(22vw, calc((100vh - 240px) / 2.25)), 180px); padding: calc(var(--cw) * 0.12) 16px 0; }
  .m-header{ height: 48px; padding: 8px 16px; }
  .m-cta-row{ padding: 6px 8px; }
  .m-btn-bet{ height: 36px; }
  .m-bet-bar{ padding: 6px 8px; }
  .m-bet-adj, .m-bet-chip, .m-bet-currency{ height: 24px; }
  .side{ padding-bottom: 8px; }
}
/* Disabled Cashout (Figma 510-7452, first step before High/Low is chosen):
   328x40 r12, #222222 fill, #484848 12px/600 label, full opacity. */
.m-btn-bet--cashout:disabled{ background: #222222; color: #484848; opacity: 1; cursor: default; }
.m-btn-bet--cashout:disabled{ color: #484848 !important; background: #222222 !important; }
/* Cashout available (Figma 510-7454), every brand: dark #262626 tile with the
   green "Cashout {amount}" label, 40px, r12 — not the brand-coloured CTA. */
.m-btn-bet--cashout:not(:disabled){ background: #222222 !important; color: #4ADE80 !important; }
/* Header without the brand wordmark: the centre slot stays as a spacer so the
   left and right controls keep their positions. */
.m-header-logo--empty{ display: block; height: 1px; width: 1px; opacity: 0; pointer-events: none; }
img.fr-wordmark{ width: 140px; }
/* Free-round bar sits 16px above the HIGH/LOW buttons (the column has no gap). */
.fr-bar{ margin-bottom: 8px; }

/* With the free-round bar (40px + 8px gap) the arena is shorter: the card
   formulas subtract it so the deck never clips under the header. */
@media (max-width: 767px){
  .app--free .board{ --cw: clamp(64px, min(33.4vw, calc((100vh - 348px) / 2.25)), 180px); }
}
@media (max-width: 767px) and (max-height: 600px){
  .app--free .board{ --cw: clamp(64px, min(33.4vw, calc((100vh - 288px) / 2.25)), 180px); }
}
@media (min-width: 768px){
  .app--free .board{ --cw: clamp(96px, min(22vw, calc((100vh - 408px) / 2.25)), 180px); }
}
@media (min-width: 768px) and (max-height: 600px){
  .app--free .board{ --cw: clamp(64px, min(22vw, calc((100vh - 288px) / 2.25)), 180px); }
}

/* ── The ejected card passes over the header ──────────────────────────────
   Two things used to stop it: .center-col sits at z-index 1, below the
   header's 20, and .row/.main clip the board with overflow:hidden. motion.js
   sets .app--flyover for exactly the length of the flight, so the header keeps
   its colour and its menu layer, and the clipping is back before the next
   frame of ordinary play. .app itself stays clipped — that is the game edge. */
.app--flyover .center-col{ z-index: 30; }
.app--flyover .row, .app--flyover .main{ overflow: visible; }

/* cardPop came from blackjack, where the alert lands on a big felt: starting at
   half scale over a 90px box is a hard zoom that reads as a blip rather than a
   result. It settles up into place instead, over a slightly longer beat. */
@keyframes cashoutRise {
  0%   { transform: translateY(7px) scale(0.86); opacity: 0; }
  62%  { transform: translateY(0) scale(1.035); opacity: 1; }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}
.deck-stack.shuffling{ transform-style: preserve-3d; }
.deck-stack.shuffling .deck-card{ z-index: auto; }
/* Spent Skip stays a real button (so the card can shake "no"). */
.skip-tile.spent{ cursor: not-allowed; }

/* =============================================================================
   Figma "Overlay" base + the How-to-Play (.ab-*) and History (.hx-*) slots
   (Originals Design System 1664-26475 / 1696-5667, Hi-Lo 610-14325 / 632-41181).
   Mobile: a bottom sheet with a 24px top radius; desktop: the same sheet
   centred. Sheet #171717, sections #262626 r20, inner cards a dark alpha r16.
   ============================================================================= */
.drawer{ background: var(--bg); border-radius: 24px 24px 0 0; max-width: 480px; }
.drawer-header{
  background: var(--bg); border-radius: 24px 24px 0 0;
  height: 56px; padding: 0 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.drawer-title{ font-weight: 500; font-size: 16px; line-height: 24px; color: var(--content-primary); }
.drawer-close{ width: 36px; height: 36px; color: var(--content-primary); border-radius: 10px; }
.drawer-close svg{ width: 16px; height: 16px; }
.drawer-content{ background: var(--bg); padding: 16px; }
@media (min-width: 681px){
  .drawer{ border-radius: 24px; max-width: 420px; max-height: 80vh; }
  .drawer-header{ border-radius: 24px 24px 0 0; }
  .drawer-content{ border-radius: 0 0 24px 24px; }
}

/* ── About: intro, accordion sections, inner cards ── */
.ab-content{ display: flex; flex-direction: column; gap: 12px; }
.ab-intro{
  margin: 0 0 8px; padding: 0 4px;
  font-family: var(--font-primary); font-weight: 400; font-size: 14px; line-height: 20px;
  color: var(--content-secondary);
}
.ab-sec{
  background: var(--surface-default); border-radius: 16px;
  display: flex; flex-direction: column;
}
.ab-sec-head{
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; padding: 14px 16px 0;
  background: none; border: none; cursor: pointer; text-align: left;
  color: var(--content-primary); font-family: var(--font-primary);
}
.ab-sec-title{ font-weight: 500; font-size: 14px; line-height: 20px; color: var(--content-primary); }
.ab-chev{ width: 16px; height: 16px; flex-shrink: 0; color: var(--content-primary); transition: transform 0.18s ease; }
.ab-chev--open{ transform: rotate(180deg); }
.ab-sec-body{ display: flex; flex-direction: column; gap: 12px; padding: 16px 14px 14px; }
.ab-text, .ab-note{
  margin: 0; font-family: var(--font-primary); font-weight: 400; font-size: 12px; line-height: 16px;
  color: var(--content-secondary);
}
.ab-note{ color: var(--content-tertiary); text-align: center; padding: 0 8px; }
.ab-inner{
  background: rgba(0, 0, 0, 0.32); border-radius: 16px; padding: 16px;
  display: flex; flex-direction: column; gap: 12px;
}

/* Section 1: numbered steps */
.ab-steps{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.ab-steps li{
  display: flex; gap: 12px; align-items: flex-start;
  font-family: var(--font-primary); font-weight: 400; font-size: 12px; line-height: 16px;
  color: var(--content-secondary);
}
.ab-step-n{ flex: 0 0 12px; text-align: right; color: var(--content-primary); font-variant-numeric: tabular-nums; }
.ab-lr{ display: flex; justify-content: space-between; align-items: center; gap: 12px; font-family: var(--font-primary); font-size: 12px; line-height: 16px; }
.ab-lr span{ color: var(--content-secondary); }
.ab-lr b{ font-weight: 400; color: var(--content-primary); font-variant-numeric: tabular-nums; }

/* ── History list ── */
.hx-content{ padding-top: 12px; }
.hx-list{ display: flex; flex-direction: column; gap: 8px; }
.hx-item{
  background: var(--surface-default); border-radius: 20px; overflow: hidden;
}
.hx-head{
  display: flex; align-items: center; gap: 8px; width: 100%; min-height: 52px;
  padding: 10px 14px; background: none; border: none; cursor: pointer; text-align: left;
  font-family: var(--font-primary); color: var(--content-primary);
}
.hx-icon{ width: 20px; height: 20px; flex-shrink: 0; display: flex; }
.hx-ic{ width: 20px; height: 20px; display: block; }
.hx-item--win .hx-icon{ color: #22C55E; }
.hx-item--lose .hx-icon{ color: #F43F5E; }
.hx-txt{ display: flex; flex-direction: column; min-width: 0; flex: 1; gap: 0; }
.hx-txt b{ font-weight: 500; font-size: 14px; line-height: 20px; color: var(--content-primary); }
.hx-txt span{ font-weight: 400; font-size: 12px; line-height: 16px; color: var(--content-tertiary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hx-chip{
  display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: 8px;
  font-weight: 400; font-size: 12px; line-height: 16px; white-space: nowrap; flex-shrink: 0;
}
.hx-chip--win{ background: rgba(34, 197, 94, 0.14); color: #22C55E; }
.hx-chip--lose{ background: rgba(244, 63, 94, 0.14); color: #F43F5E; }
.hx-chev{ width: 16px; height: 16px; flex-shrink: 0; color: var(--content-primary); margin-left: 4px; transition: transform 0.18s ease; }
.hx-chev--open{ transform: rotate(180deg); }
.hx-body{ display: flex; flex-direction: column; gap: 10px; padding: 0 10px 10px; }
.hx-block{ background: rgba(255, 255, 255, 0.035); border-radius: 16px; overflow: hidden; }

/* Bet / Payout / Net */
.hx-money{ display: flex; flex-direction: column; gap: 8px; padding: 12px 16px; background: rgba(255, 255, 255, 0.05); }
.hx-block > .hx-money:first-child{ background: none; }
.hx-mr{ display: flex; justify-content: space-between; align-items: center; gap: 12px; font-family: var(--font-primary); font-size: 12px; line-height: 16px; }
.hx-mr span{ color: var(--content-secondary); }
.hx-mr b{ font-weight: 400; color: var(--content-primary); font-variant-numeric: tabular-nums; }
.hx-mr b.pos{ color: #22C55E; }
.hx-mr b.neg{ color: #F43F5E; }

/* Seeds + Verify Round */
.hx-seeds{ display: flex; flex-direction: column; gap: 12px; padding: 16px; }
.hx-seed{ display: flex; flex-direction: column; gap: 2px; font-family: var(--font-primary); }
.hx-seed span{ font-size: 12px; line-height: 16px; color: var(--content-tertiary); }
.hx-seed b{ font-weight: 400; font-size: 14px; line-height: 20px; color: var(--content-primary); word-break: break-all; }
.hx-seeds, .hx-seeds *{ user-select: text; -webkit-user-select: text; }
.hx-verify{
  margin-top: 2px; width: 100%; height: 40px; border-radius: 12px; border: none; cursor: pointer;
  background: rgba(255, 255, 255, 0.08); color: var(--content-primary);
  font-family: var(--font-primary); font-weight: 600; font-size: 14px; line-height: 20px;
}
.hx-verify:active:not(:disabled){ transform: scale(0.98); }
.hx-verify:disabled{ cursor: default; }
.hx-verify--ok{ background: rgba(34, 197, 94, 0.14); color: #22C55E; }
.hx-verify--fail{ background: rgba(244, 63, 94, 0.14); color: #F43F5E; }
.hx-vres{
  display: flex; flex-direction: column; gap: 4px; padding: 10px 12px; border-radius: 12px;
  font-family: var(--font-primary); font-size: 12px; line-height: 16px;
}
.hx-vres--ok{ background: rgba(34, 197, 94, 0.10); }
.hx-vres--fail{ background: rgba(244, 63, 94, 0.10); }
.hx-vres b{ font-weight: 600; color: var(--content-primary); }
.hx-vres--ok b{ color: #22C55E; }
.hx-vres--fail b{ color: #F43F5E; }
.hx-vres > span{ color: var(--content-secondary); }
.hx-vres-hash{ display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.hx-vres-hash em{ font-style: normal; font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--content-tertiary); }
.hx-vres-hash code{ font-family: var(--font-mono); font-size: 10px; line-height: 14px; word-break: break-all; color: var(--content-primary); }
.hx-vres-rows{ display: flex; flex-direction: column; gap: 2px; margin-top: 6px; padding-top: 6px; border-top: 1px solid rgba(255, 255, 255, 0.08); }
.hx-vres-rows > div{ display: flex; justify-content: space-between; gap: 8px; font-size: 11px; color: var(--content-secondary); }
.ab-inner{ background: #1a1a1a; }
/* History overlay rhythm (Hi-Lo file history/win, measured at 1:1) */
.drawer--history .drawer-header{ border-bottom: none; }
.hx-content{ padding-top: 0; }
.hx-list{ gap: 10px; }
.hx-body{ padding: 0 10px 8px; }
.hx-seeds{ padding: 12px; gap: 12px; }
.hx-verify{ margin-top: 4px; }
/* Collapsed section: the header carries the bottom padding itself (48px card) */
.ab-sec:not(.ab-sec--open) .ab-sec-head{ padding-bottom: 14px; }
/* History item icon sits on the title line (Figma), chip and chevron stay centred */
.hx-icon{ align-self: flex-start; }
@media (min-width: 768px){
  .board .table-svg--m{ display: none; }
  .board .table-svg--d{
    display: block;
    width: calc(var(--cw) * 3.4396); height: calc(var(--cw) * 1.357);
    left: calc(50% - var(--cw) * 1.7013); top: calc(var(--cw) * 0.079);
  }
  .board .table-rank{ top: calc(var(--cw) * 0.738); height: calc(var(--cw) * 0.4412); }
  .board .table-rank--l{ left: calc(50% - var(--cw) * 1.6962); }
  .board .table-rank--r{ left: calc(50% + var(--cw) * 1.6962); }
}

/* ── Desktop: footer = table width, compact chrome ────────────────────────
   The footer's outer edges sit on the table's outer line edges (x 0 → 506.5
   of the 512 box = 3.4026 card widths), so --cw is mirrored onto .side with
   the board's own formulas. The footer drops to the phone frame's rows
   (48 buttons, 68 strip, 40 CTA), ~35px shorter, and that height goes back
   to the card (360 → 325 reserved under the arena). */
@media (min-width: 768px){
  .board, .side{ --cw: clamp(96px, min(22vw, calc((100vh - 325px) / 2.25)), 180px); }
  .app--free .board, .app--free .side{ --cw: clamp(96px, min(22vw, calc((100vh - 373px) / 2.25)), 180px); }
  .side{ max-width: none; width: max(330px, calc(var(--cw) * 3.4026)); }
  .m-cta-row{ padding: 8px; }
  .m-btn-bet{ height: 40px; font-size: 13px; }
  .m-bet-bar{ padding: 8px; }
  .m-bet-adj, .m-bet-chip{ height: 26px; font-size: 11px; }
  .m-bet-chip{ min-width: 34px; }
  .m-bet-balance, .m-bet-label, .m-bet-value{ font-size: 13px; }
  .m-bet-currency{ width: 26px; height: 26px; }
}
@media (min-width: 768px) and (max-height: 600px){
  .board, .side{ --cw: clamp(64px, min(22vw, calc((100vh - 240px) / 2.25)), 180px); }
  .app--free .board, .app--free .side{ --cw: clamp(64px, min(22vw, calc((100vh - 288px) / 2.25)), 180px); }
  .m-cta-row{ padding: 6px 8px; }
  .m-btn-bet{ height: 36px; }
  .m-bet-bar{ padding: 6px 8px; }
  .m-bet-adj, .m-bet-chip, .m-bet-currency{ height: 24px; }
}

/* ── Desktop table scaled and centred to the design (1 Oct) ──────────────
   Measured off the designer's frame (card 207.6px): the table's line box is
   3.528 x 1.399 card widths (4% larger than before) and its centre sits
   0.82 cw under the card top, i.e. on the deck frame's centre (-0.0707 →
   1.7136 cw), so the deck overhangs the line equally above and below.
   1 vector unit = 3.528/505 = 0.006986 cw. The footer keeps matching the
   table's outer line edges (506.5 units). */
@media (min-width: 768px){
  .board .table-svg--d{
    width: calc(var(--cw) * 3.5769); height: calc(var(--cw) * 1.4112);
    left: calc(50% - var(--cw) * 1.7692); top: calc(var(--cw) * 0.1176);
  }
  .board .table-rank{ top: calc(var(--cw) * 0.8029); height: calc(var(--cw) * 0.4588); }
  .board .table-rank--l{ left: calc(50% - var(--cw) * 1.764); }
  .board .table-rank--r{ left: calc(50% + var(--cw) * 1.764); }
  .side{ width: max(330px, calc(var(--cw) * 3.5385)); }
}

/* ── Desktop arena fills the free height (1 Oct) ──────────────────────────
   The deck frame runs -0.0707 → 1.7136 cw (the table is centred on it) and
   the Skip tab hangs 0.0954 cw below it; the same overhang is reserved above,
   so the block is 1.975 cw and the TABLE sits exactly mid-arena. The arena is
   that plus 16px above and below, the card is sized from the height left between the header and
   the buttons. The footer stays pinned to the bottom (24px) and the table +
   deck stay centred between the header and the buttons; once the card
   reaches 180px the spare height is split above and below the arena.
   Reserved: header 53 + buttons/footer 258 + 2 x 16 = 343 (free rounds +48);
   short embeds (≤520): header 45 + footer 202 + 2 x 12 = 271 (+48).
   !important: the landscape-phone rule (max-height 500px) zeroes the padding. */
@media (min-width: 768px){
  .board, .side{ --cw: clamp(64px, min(22vw, calc((100vh - 343px) / 1.975)), 180px); }
  .app--free .board, .app--free .side{ --cw: clamp(64px, min(22vw, calc((100vh - 391px) / 1.975)), 180px); }
  .row{ justify-content: flex-start; }
  .main{ flex: 1 1 auto; justify-content: center; }
  .board{
    flex: 0 0 auto; min-height: 0; align-items: flex-start;
    height: calc(var(--cw) * 1.975 + 32px);
    padding: calc(16px + var(--cw) * 0.1661) 16px 0 !important;
  }
}
@media (min-width: 768px) and (max-height: 600px){
  .board, .side{ --cw: clamp(64px, min(22vw, calc((100vh - 271px) / 1.975)), 180px); }
  .app--free .board, .app--free .side{ --cw: clamp(64px, min(22vw, calc((100vh - 319px) / 1.975)), 180px); }
  .board{ height: calc(var(--cw) * 1.975 + 24px); padding-top: calc(12px + var(--cw) * 0.1661) !important; }
  .row{ overflow-y: auto; }
}
/* Desktop header: no bottom padding (1 Oct), the arena starts right under
   the tiles and gets that height back. */
@media (min-width: 768px){
  .m-header{ height: auto; min-height: 0; padding-bottom: 0; }
}

/* ── Bigger desktop arena (1 Oct) ─────────────────────────────────────────
   Deck + table grow together (one --cw): the 16px / 12px air above and
   below the arena drops to 4px and the card cap rises 180 → 200px. The table
   stays exactly mid-way between the header and the buttons.
   Reserved: header 53 + footer 258 + 2 x 4 = 319 (free rounds +48);
   short embeds: header 45 + footer 202 + 2 x 4 = 255 (+48). */
@media (min-width: 768px){
  .board, .side{ --cw: clamp(64px, min(22vw, calc((100vh - 319px) / 1.975)), 200px); }
  .app--free .board, .app--free .side{ --cw: clamp(64px, min(22vw, calc((100vh - 367px) / 1.975)), 200px); }
  .board{ height: calc(var(--cw) * 1.975 + 8px); padding-top: calc(4px + var(--cw) * 0.1661) !important; }
}
@media (min-width: 768px) and (max-height: 600px){
  .board, .side{ --cw: clamp(64px, min(22vw, calc((100vh - 255px) / 1.975)), 200px); }
  .app--free .board, .app--free .side{ --cw: clamp(64px, min(22vw, calc((100vh - 303px) / 1.975)), 200px); }
  .board{ height: calc(var(--cw) * 1.975 + 8px); padding-top: calc(4px + var(--cw) * 0.1661) !important; }
}

/* ── Desktop arena air back to 16px (1 Oct, live check at mybc.game) ──────
   At the operator's 1152x648 iframe the 4px air left the Skip tab touching
   the HIGH/LOW buttons. 16px between the Skip tab and the buttons (12px in
   short embeds), the same above the reserved overhang, table still mid-way.
   Reserved: header 53 + footer 258 + 2 x 16 = 343 (+48 free rounds);
   short: header 45 + footer 202 + 2 x 12 = 271 (+48). */
@media (min-width: 768px){
  .board, .side{ --cw: clamp(64px, min(22vw, calc((100vh - 343px) / 1.975)), 200px); }
  .app--free .board, .app--free .side{ --cw: clamp(64px, min(22vw, calc((100vh - 391px) / 1.975)), 200px); }
  .board{ height: calc(var(--cw) * 1.975 + 32px); padding-top: calc(16px + var(--cw) * 0.1661) !important; }
}
@media (min-width: 768px) and (max-height: 600px){
  .board, .side{ --cw: clamp(64px, min(22vw, calc((100vh - 271px) / 1.975)), 200px); }
  .app--free .board, .app--free .side{ --cw: clamp(64px, min(22vw, calc((100vh - 319px) / 1.975)), 200px); }
  .board{ height: calc(var(--cw) * 1.975 + 24px); padding-top: calc(12px + var(--cw) * 0.1661) !important; }
}

/* ── Skip tab → HIGH/LOW buttons: 24px at every height (1 Oct) ────────────
   Same 24px above the reserved overhang so the table stays mid-way.
   Reserved: header 53 + footer 258 + 2 x 24 = 359 (+48 free rounds);
   short: header 45 + footer 202 + 2 x 24 = 295 (+48). */
@media (min-width: 768px){
  .board, .side{ --cw: clamp(64px, min(22vw, calc((100vh - 359px) / 1.975)), 200px); }
  .app--free .board, .app--free .side{ --cw: clamp(64px, min(22vw, calc((100vh - 407px) / 1.975)), 200px); }
  .board{ height: calc(var(--cw) * 1.975 + 48px); padding-top: calc(24px + var(--cw) * 0.1661) !important; }
}
@media (min-width: 768px) and (max-height: 600px){
  .board, .side{ --cw: clamp(64px, min(22vw, calc((100vh - 295px) / 1.975)), 200px); }
  .app--free .board, .app--free .side{ --cw: clamp(64px, min(22vw, calc((100vh - 343px) / 1.975)), 200px); }
  .board{ height: calc(var(--cw) * 1.975 + 48px); padding-top: calc(24px + var(--cw) * 0.1661) !important; }
}
/* Header → deck frame and Skip tab → buttons: both exactly 24px. The block
   is the deck frame top (-0.0707 cw) → Skip bottom (1.809 cw) = 1.88 cw; no
   extra overhang is reserved above, so the table sits ~0.05 cw above centre. */
@media (min-width: 768px){
  .board, .side{ --cw: clamp(64px, min(22vw, calc((100vh - 359px) / 1.88)), 200px); }
  .app--free .board, .app--free .side{ --cw: clamp(64px, min(22vw, calc((100vh - 407px) / 1.88)), 200px); }
  .board{ height: calc(var(--cw) * 1.88 + 48px); padding-top: calc(24px + var(--cw) * 0.0707) !important; }
}
@media (min-width: 768px) and (max-height: 600px){
  .board, .side{ --cw: clamp(64px, min(22vw, calc((100vh - 295px) / 1.88)), 200px); }
  .app--free .board, .app--free .side{ --cw: clamp(64px, min(22vw, calc((100vh - 343px) / 1.88)), 200px); }
  .board{ height: calc(var(--cw) * 1.88 + 48px); padding-top: calc(24px + var(--cw) * 0.0707) !important; }
}

/* ── Short desktop embeds, 1 Oct ──────────────────────────────────────────
   The compact chrome (45px header, 40px buttons, 56px strip) now starts at
   600px tall instead of 520, so the card no longer drops from 120px at 520
   to 86px at 521. The footer keeps its table-matched width but never goes
   under 420px, so the bet bar ("100.00₾", +/-, 1/2, 2X) never overlaps. */
@media (min-width: 768px){
  .side{ width: max(420px, calc(var(--cw) * 3.5385)); }
}

/* Session-expired prompt (INVALID_SESSION on a token launch) — dice's
   .overlay + .modal, values inlined from dice's tokens (--card/--bg-secondary
   #171717, --brd2 #404040, --radius-lg 16px, --pad 12px, --tx2 #d4d4d4). */
.se-overlay{
  position: fixed; inset: 0; z-index: 10000;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.78);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  animation: se-fade-in 0.2s;
  padding: 12px;
}
.se-modal{
  background: linear-gradient(145deg, #171717, #171717);
  border: 1px solid #404040; border-radius: 16px;
  padding: 12px; max-width: 440px; width: 100%;
  text-align: center;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.6);
  animation: se-pop-in 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
  max-height: 88vh; overflow-y: auto;
  font-family: var(--font-primary);
}
.se-body{ text-align: center; padding: 24px 16px; }
.se-logo{ width: 80px; height: auto; margin-bottom: 16px; }
.se-title{ font-size: 22px; font-weight: 900; margin: 0 0 8px; color: #ffffff; }
.se-text{ font-size: 15px; color: #d4d4d4; margin: 0; line-height: 1.4; }
@keyframes se-fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
@keyframes se-pop-in {
  0%   { transform: scale(0.3); opacity: 0; }
  60%  { transform: scale(1.08); }
  100% { transform: scale(1); opacity: 1; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   LIMBO on the Originals chrome. Everything above this line is hilo's
   stylesheet with its card/deck/table/trail rules removed: tokens, header,
   controls card, bet bar, drawers, provably-fair, history, free-round
   modals, loading and session screens are hilo's / dice's, untouched. Below:
   the one-column layout (header / storm scene / controls), the storm scene
   itself (storm.js canvas + the cube), the target-multiplier row and the
   two-button action row, plus the auto-play drawer bits limbo adds.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Layout — hilo's .app / .row / .main / .side, minus the card formulas ──
   The scene (.main) takes whatever height the controls leave; the controls
   are the same 520px column dice and hilo centre on desktop. hilo's desktop
   rules that size .main/.side/.row from the card width (--cw) are earlier
   in the cascade and lose to these. */
.row { overflow: hidden; justify-content: flex-start; }
.main {
  flex: 1 1 auto; min-height: 0; min-width: 0;
  display: flex; flex-direction: column; justify-content: flex-start;
  overflow: hidden; position: relative; isolation: isolate;
  background: var(--bg);
}
.side {
  flex: 0 0 auto; display: flex; flex-direction: column; gap: 0;
  width: 100%; max-width: 520px; margin: 0 auto;
  padding: 0 16px 16px; box-sizing: border-box;
}
@media (min-width: 768px) {
  .side { max-width: 520px; width: 100%; padding: 0 0 24px; }
  .row { overflow: hidden; }
  .main { flex: 1 1 auto; overflow: hidden; }
}
@media (min-width: 768px) and (max-height: 600px) {
  .side { padding-bottom: 8px; }
  .main { flex: 1 1 auto; overflow: hidden; }
  .row { overflow: hidden; }
}

/* ── Storm scene (storm.js prepends its canvas into .main). The ambient layer,
   cube, particles, ripples and flash below are the game's own, kept as they
   were (the previous pass's styles.css), re-sized further down. ── */
/* storm.js mounts the canvas into .app, so the rain, lightning and the
   #0c091b base run behind the header and the controls too: one scene, no
   dark header/footer strips. The header and .row sit above it. */
.app { position: relative; isolation: isolate; background: #0c091b; }
.limbo-storm {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; z-index: 0;
}
.app > .m-header { background: transparent; }
.app > .row { position: relative; z-index: 1; background: transparent; }
/* The header and the controls overlap a canvas that repaints every frame.
   Phones composite them late (or not at all) unless they own a layer, so
   they get one up front, and the nebula blur, the costliest filter on a
   phone GPU, halves there. */
.app > .m-header, .side { will-change: transform; transform: translateZ(0); }
.m-controls { contain: paint; }
@media (max-width: 767px) { .nebula { filter: blur(40px); } .game-area.phase-counting .nebula { filter: blur(30px); } }
.main { background: transparent; }
.game-area {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 8px 16px 12px;
  position: relative; overflow: hidden;
}

/* ===== AMBIENT BACKGROUND ===== */
.bg-ambient {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
}
@media (prefers-reduced-motion: reduce) {
  .bg-ambient * { animation: none; }
}

/* Star field */
.stars {
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(1px 1px at 10% 20%, rgba(255,255,255,0.3) 0%, transparent 100%),
    radial-gradient(1px 1px at 30% 65%, rgba(255,255,255,0.2) 0%, transparent 100%),
    radial-gradient(1px 1px at 55% 15%, rgba(255,255,255,0.25) 0%, transparent 100%),
    radial-gradient(1px 1px at 70% 75%, rgba(255,255,255,0.15) 0%, transparent 100%),
    radial-gradient(1px 1px at 85% 40%, rgba(255,255,255,0.3) 0%, transparent 100%),
    radial-gradient(1px 1px at 45% 85%, rgba(255,255,255,0.2) 0%, transparent 100%),
    radial-gradient(1.5px 1.5px at 20% 50%, rgba(255,255,255,0.15) 0%, transparent 100%),
    radial-gradient(1px 1px at 65% 35%, rgba(255,255,255,0.25) 0%, transparent 100%),
    radial-gradient(1px 1px at 90% 10%, rgba(255,255,255,0.2) 0%, transparent 100%),
    radial-gradient(1.5px 1.5px at 5% 90%, rgba(255,255,255,0.15) 0%, transparent 100%),
    radial-gradient(1px 1px at 40% 45%, rgba(255,255,255,0.2) 0%, transparent 100%),
    radial-gradient(1px 1px at 75% 55%, rgba(255,255,255,0.15) 0%, transparent 100%);
  animation: starsTwinkle 6s ease-in-out infinite alternate;
}
@keyframes starsTwinkle {
  0% { opacity: 0.6; }
  100% { opacity: 1; }
}

/* Nebula clouds */
.nebula {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
}
.n1 {
  width: 300px;
  height: 300px;
  background: radial-gradient(circle, rgba(50, 80, 180, 0.12) 0%, rgba(30, 50, 140, 0.06) 50%, transparent 70%);
  top: -10%;
  right: -5%;
  animation: nebulaFlow1 25s ease-in-out infinite;
}
.n2 {
  width: 250px;
  height: 250px;
  background: radial-gradient(circle, rgba(100, 50, 180, 0.10) 0%, rgba(60, 30, 140, 0.05) 50%, transparent 70%);
  bottom: -5%;
  left: -5%;
  animation: nebulaFlow2 30s ease-in-out infinite;
}
@keyframes nebulaFlow1 {
  0%, 100% { transform: translate(0, 0) scale(1); opacity: 0.7; }
  25% { transform: translate(-20px, 15px) scale(1.05); opacity: 0.9; }
  50% { transform: translate(10px, -10px) scale(0.95); opacity: 0.6; }
  75% { transform: translate(15px, 20px) scale(1.08); opacity: 0.8; }
}
@keyframes nebulaFlow2 {
  0%, 100% { transform: translate(0, 0) scale(1); opacity: 0.6; }
  33% { transform: translate(20px, -15px) scale(1.1); opacity: 0.8; }
  66% { transform: translate(-15px, 10px) scale(0.9); opacity: 0.5; }
}

/* Rotating infinity rings */
.infinity-ring {
  position: absolute;
  border-radius: 50%;
  border: 1px solid transparent;
}
.ring-1 {
  width: 350px;
  height: 350px;
  top: 50%;
  left: 50%;
  margin: -175px 0 0 -175px;
  border-color: rgba(80, 120, 200, 0.06);
  animation: ringRotate 40s linear infinite;
}
.ring-2 {
  width: 280px;
  height: 280px;
  top: 50%;
  left: 50%;
  margin: -140px 0 0 -140px;
  border-color: rgba(80, 120, 200, 0.04);
  border-style: dashed;
  animation: ringRotate 30s linear infinite reverse;
}
.ring-3 {
  width: 420px;
  height: 420px;
  top: 50%;
  left: 50%;
  margin: -210px 0 0 -210px;
  border-color: rgba(80, 120, 200, 0.03);
  animation: ringRotate 50s linear infinite;
}
@keyframes ringRotate {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* Energy waves on counting */
.energy-wave {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 200px;
  height: 200px;
  margin: -100px 0 0 -100px;
  border-radius: 50%;
  border: 1px solid rgba(80, 140, 255, 0);
  opacity: 0;
}
.energy-wave.active {
  animation: waveExpand 0.6s ease-out forwards;
}
.wave-2.active {
  animation-delay: 0.15s;
}
@keyframes waveExpand {
  0% { transform: scale(0.5); opacity: 0; border-color: rgba(80, 140, 255, 0.4); }
  50% { opacity: 1; }
  100% { transform: scale(2.5); opacity: 0; border-color: rgba(80, 140, 255, 0); }
}

/* Phase-reactive */
.game-area.phase-counting .nebula { filter: blur(60px); }
.game-area.phase-counting .ring-1 { border-color: rgba(80, 140, 255, 0.10); }
.game-area.phase-counting .ring-2 { border-color: rgba(80, 140, 255, 0.07); }
.game-area.phase-counting .stars { animation-duration: 1s; }
.game-area.phase-result.result-win .n1 { background: radial-gradient(circle, rgba(14, 204, 104, 0.12) 0%, transparent 70%); }
.game-area.phase-result.result-win .n2 { background: radial-gradient(circle, rgba(14, 204, 104, 0.08) 0%, transparent 70%); }
.game-area.phase-result.result-win .ring-1 { border-color: rgba(14, 204, 104, 0.08); }
.game-area.phase-result.result-win .stars { opacity: 1; }

/* ===== CUBE ===== */
.cube-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  position: relative;
  z-index: 1;
}
.cube-track {
  position: relative;
  width: 420px;
  height: 240px;
  background: rgba(35, 32, 78, 0.7);
  border-radius: 16px;
  border: 2px solid rgba(47, 69, 83, 0.60);
  overflow: hidden;
  transition: border-color 0.4s, box-shadow 0.4s;
}
.cube-track.result-win,
.cube-track.result-lose {
  border-color: rgba(90, 140, 220, 0.40);
  box-shadow:
    0 0 40px rgba(90, 140, 220, 0.12),
    0 0 80px rgba(90, 140, 220, 0.05),
    inset 0 0 30px rgba(90, 140, 220, 0.03);
}
/* Awaiting server response: a soft breathing glow on the cube while the roll is
   in flight. Toggled (delay-gated) from JS so a fast roll doesn't flicker. */
@keyframes limboAwaitGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--brand-rgb), 0); border-color: var(--accent-border); }
  50%      { box-shadow: 0 0 24px 3px var(--accent-border); border-color: var(--accent); }
}
.cube-track.awaiting {
  animation: limboAwaitGlow 0.9s ease-in-out infinite;
}


/* Game phase animations */
.cube-track.phase-counting {
  animation: cubeZoomIn 0.3s ease-out forwards;
}
.cube-track.phase-result {
  animation: cubeBounce 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
.cube-track.phase-result.result-win {
  animation: cubeWinPop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

.cube-value.phase-result {
  animation: textReveal 0.4s ease-out forwards;
}
.cube-value.phase-result.result-win {
  animation: textWinPop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

@keyframes cubeZoomIn {
  0% { transform: scale(0.97); }
  100% { transform: scale(1); }
}

@keyframes cubeBounce {
  0% { transform: scale(1); }
  40% { transform: scale(1.03); }
  70% { transform: scale(0.99); }
  100% { transform: scale(1); }
}

@keyframes cubeWinPop {
  0% { transform: scale(1); box-shadow: 0 0 0 rgba(14, 204, 104, 0); }
  30% { transform: scale(1.05); box-shadow: 0 0 40px rgba(14, 204, 104, 0.2); }
  60% { transform: scale(0.98); }
  100% { transform: scale(1); box-shadow: 0 0 0 rgba(14, 204, 104, 0); }
}

@keyframes textReveal {
  0% { transform: scale(0.9); opacity: 0.7; }
  50% { transform: scale(1.06); }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes textWinPop {
  0% { transform: scale(1); }
  30% { transform: scale(1.15); }
  60% { transform: scale(0.95); }
  100% { transform: scale(1.05); }
}

/* Shimmer on win — light sweep across cube */
.cube-track.phase-result.result-win::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    105deg,
    transparent 30%,
    rgba(14, 204, 104, 0.12) 45%,
    rgba(255, 255, 255, 0.08) 50%,
    rgba(14, 204, 104, 0.12) 55%,
    transparent 70%
  );
  animation: shimmer 0.6s ease-out forwards;
  z-index: 5;
  border-radius: 14px;
  pointer-events: none;
}

@keyframes shimmer {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

/* Indicator line pulse on result */
.cube-indicator.result-win {
  height: 3px;
  box-shadow: 0 0 16px rgba(14, 204, 104, 0.8), 0 0 30px rgba(14, 204, 104, 0.4);
  background: rgba(14, 204, 104, 0.9);
}

/* ===== PARTICLES ===== */
.particle {
  position: absolute;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--green-bright);
  z-index: 10;
  pointer-events: none;
  animation: particleBurst 0.7s ease-out forwards;
  box-shadow: 0 0 6px var(--green);
}
@keyframes particleBurst {
  0% {
    transform: translate(0, 0) scale(1);
    opacity: 1;
  }
  100% {
    transform: translate(var(--tx), var(--ty)) scale(0);
    opacity: 0;
  }
}

/* ===== RIPPLE RINGS ===== */
.ripple {
  position: absolute;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  border: 2px solid rgba(90, 140, 220, 0.3);
  animation: rippleExpand 0.7s ease-out forwards;
  pointer-events: none;
  z-index: 0;
}
.ripple.result-win {
  border-color: rgba(14, 204, 104, 0.35);
}
.ripple-2 {
  animation-delay: 0.12s;
}
@keyframes rippleExpand {
  0% {
    transform: scale(0.3);
    opacity: 1;
  }
  100% {
    transform: scale(3);
    opacity: 0;
  }
}

/* ===== BACKGROUND FLASH ===== */
.bg-flash {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  border-radius: inherit;
  animation: bgFlash 0.5s ease-out forwards;
}
.bg-flash.win {
  background: radial-gradient(circle at center, rgba(14, 204, 104, 0.12) 0%, transparent 70%);
}
@keyframes bgFlash {
  0% { opacity: 1; transform: scale(0.8); }
  100% { opacity: 0; transform: scale(1.5); }
}

/* ===== FLOATING PAYOUT ===== */
.payout-float {
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 20px;
  font-weight: 800;
  color: var(--green-bright);
  text-shadow: 0 0 16px rgba(14, 204, 104, 0.5);
  pointer-events: none;
  z-index: 10;
  animation: floatUp 1.2s ease-out forwards;
  white-space: nowrap;
}
@keyframes floatUp {
  0% {
    opacity: 1;
    transform: translateX(-50%) translateY(0) scale(0.8);
  }
  30% {
    opacity: 1;
    transform: translateX(-50%) translateY(-10px) scale(1.1);
  }
  100% {
    opacity: 0;
    transform: translateX(-50%) translateY(-50px) scale(0.9);
  }
}

/* ===== GAME AREA PHASE BG ===== */
.game-area.phase-counting {
  background: radial-gradient(circle at center, rgba(90, 140, 220, 0.03) 0%, transparent 60%);
}
.game-area.phase-result.result-win {
  background: radial-gradient(circle at center, rgba(14, 204, 104, 0.04) 0%, transparent 60%);
}

.cube-fill {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 0%;
  border-radius: 0 0 14px 14px;
  transition: height 0.03s linear;
  background: rgba(90, 140, 220, 0.20);
}

/* Indicator line — rides on top of fill */
.cube-indicator {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: rgba(130, 175, 255, 0.8);
  z-index: 2;
  transition: bottom 0.05s linear;
  box-shadow: 0 0 10px rgba(90, 140, 220, 0.6), 0 0 20px rgba(90, 140, 220, 0.3);
}
.cube-indicator.animating {
  background: rgba(130, 175, 255, 0.9);
  box-shadow: 0 0 12px rgba(90, 140, 220, 0.7), 0 0 24px rgba(90, 140, 220, 0.35);
}

/* Multiplier value inside cube */
.cube-value {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 48px;
  font-weight: 800;
  color: #FFFFFF;
  z-index: 3;
  transition: color 0.4s, text-shadow 0.4s, transform 0.3s;
  letter-spacing: -0.02em;
  pointer-events: none;
}
.cube-value.animating {
  color: #FFFFFF;
}
.cube-value.result-win {
  color: var(--green-bright);
  text-shadow: 0 0 30px rgba(14, 204, 104, 0.5), 0 0 60px rgba(14, 204, 104, 0.2);
  transform: scale(1.05);
}
.cube-value.result-lose {
  color: #FFFFFF;
}


/* ── Cube (the multiplier panel) — sized to the scene, type on the Originals face ── */
.cube-wrap { width: 100%; }
.cube-track { width: min(420px, 100%); height: clamp(150px, 30vh, 240px); margin: 0; }
.cube-value { font-family: var(--font-primary); font-weight: 800; font-size: clamp(36px, 6vh + 8px, 56px); }
@media (max-width: 767px) {
  .cube-track { width: min(300px, 100%); height: clamp(132px, 24vh, 190px); }
  .cube-value { font-size: clamp(32px, 5vh + 8px, 44px); }
}
@media (min-width: 768px) and (max-height: 600px) {
  .cube-track { height: clamp(120px, 26vh, 180px); }
}

/* ── Controls card: [Bet · Auto] / target row / bet bar (dice's order) ── */
.m-cta-row { display: flex; align-items: center; gap: 8px; }
.m-cta-row .m-btn-bet { flex: 1 1 auto; min-width: 0; }
/* Auto: the second action tile, dice's .m-btn-cashout-new anatomy (dark tile,
   12px/600) with the loop icon; brand-coloured while a run is on (dice's
   engaged Auto chip). */
.m-btn-auto {
  box-sizing: border-box;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  height: 40px; padding: 8px 14px; flex: 0 0 auto;
  background: var(--surface-default); border: none; border-radius: 12px;
  cursor: pointer; font-family: var(--font-primary); font-weight: 600; font-size: 12px;
  color: var(--content-primary); white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
}
.m-btn-auto svg { width: 16px; height: 16px; flex-shrink: 0; }
.m-btn-auto:active:not(:disabled) { transform: scale(0.97); }
.m-btn-auto:disabled { opacity: 0.5; cursor: not-allowed; }
.m-btn-auto--on { background: var(--action-primary); color: var(--action-text); }
@media (min-width: 768px) { .m-btn-auto { height: 40px; font-size: 13px; padding: 8px 16px; } }
@media (min-width: 768px) and (max-height: 600px) { .m-btn-auto { height: 36px; } }

/* Target row — the bet bar's anatomy (same chips, steppers, value and
   divider) one row up: [⚡ win chance] | − target + | 2× 5× 10× 20×. */
.m-target-bar .m-bet-currency svg { width: 12px; height: 12px; color: var(--brand-primary); }
.m-target-bar .m-bet-label { display: none; }
@media (min-width: 768px) { .m-target-bar .m-bet-label { display: inline; } }
.m-bet-chip--active { background: var(--action-primary); color: var(--action-text); }
.m-bet-chip--active:disabled { opacity: 0.6; }
/* Four presets need ~325px of row; below 390px the 20× chip steps out, and
   on the 320px frame (272px of row) the 10× one too, the value box 40px. */
/* Five chips (2x 5x 10x 20x Max) on desktop; phones show 5x 10x Max. */
.m-target-bar .m-bet-chip--max { font-size: 11px; }
@media (max-width: 767px) {
  .m-target-bar .m-bet-chip--x2, .m-target-bar .m-bet-chip--x20 { display: none; }
}
/* 320px frame with the max target (1000.00x) in the box: tighter type and
   chips so the + stepper keeps its width. */
@media (max-width: 359px) {
  .m-target-bar .m-bet-value { min-width: 0; padding: 0 2px; font-size: 12px; letter-spacing: -0.02em; }
  .m-target-bar .m-bet-chip { width: 30px; min-width: 30px; }
  .m-target-bar .m-bet-right { gap: 4px; }
  .m-target-bar .m-bet-currency, .m-target-bar .m-bet-divider { display: none; }
}

/* ── Auto-play drawer (hilo's drawer + pf primitives) ── */
.auto-chips { display: flex; gap: 8px; }
.auto-chips .m-bet-chip { flex: 1; width: auto; min-width: 0; height: 36px; font-size: 13px; }
.pf-input-value.num { font-size: 16px; font-weight: 600; font-variant-numeric: tabular-nums; }
.pf-btn--primary { background: var(--action-primary); color: var(--action-text); }

/* Auto-play summary (the free-round summary's card, three stats) */
.fbs-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 12px; }
.fbs-stat {
  display: flex; flex-direction: column; gap: 2px; align-items: center;
  background: rgba(0, 0, 0, 0.22); border-radius: 12px; padding: 10px 8px;
}
.fbs-stat-label { font-family: var(--font-primary); font-size: 11px; color: var(--content-tertiary); }
.fbs-stat-val { font-family: var(--font-primary); font-size: 16px; font-weight: 700; color: var(--content-primary); }
.fbs-winnings {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 10px 12px; border-radius: 12px; background: rgba(0, 0, 0, 0.22);
  font-family: var(--font-primary); font-size: 14px;
}
.fbs-winnings-label { color: var(--content-secondary); }
.fbs-winnings-val { font-weight: 700; }

/* ── Game wordmark as type (limbo ships no wordmark asset) ── */
.loading-wordmark, .fr-wordmark, .se-logo--text {
  display: block; margin: 0 auto;
  font-family: var(--font-primary); font-weight: 900; line-height: 1;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--content-primary);
}
.loading-wordmark { font-size: 40px; }
.fr-wordmark { font-size: 25px; margin-bottom: 16px; }
.se-logo--text { font-size: 28px; margin-bottom: 16px; }

.ab-limits { gap: 12px; }
