/* ============================================================================
   BetSystem widgets — "Lucky Tiger" theme
   Dark UI + orange (#ff8a00) brand, matched to the luckytiger.co.uk design system.
   ========================================================================== */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap');

.betsystem-widget, .bs-hero, .bs-overlay {
  --bs-orange: #ff8a00;
  --bs-orange-dp: #ff7a00;
  --bs-orange-br: #ffa23d;
  --bs-on-orange: #1a1207;
  --bs-gold: #e7c07a;
  --bs-bg: #0a0e17;
  --bs-panel: #12161f;
  --bs-elev: #171d28;
  --bs-elev2: #1c2432;
  --bs-line: #222b39;
  --bs-soft: #2a3340;
  --bs-text: #f3f5f8;
  --bs-muted: #8a94a3;
  --bs-faint: #7a8494;
  --bs-pos: #2fd07a;
  --bs-neg: #ff5a5f;
  --bs-live: #ff4d4f;
  --bs-accent: var(--bs-orange);
  font-family: 'Inter', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  color: var(--bs-text);
}

/* Cards / panels */
.bs-card { background: linear-gradient(180deg, var(--bs-elev), var(--bs-panel)); border: 1px solid var(--bs-line);
  border-radius: 14px; padding: 18px; margin: 10px 0; box-shadow: 0 8px 24px rgba(0,0,0,.35); }
.bs-card h3, .bs-card h4 { margin: 0 0 12px; font-weight: 700; letter-spacing: -.01em; }
.bs-card h3 { font-size: 17px; }
.betsystem-loading, .bs-loading { color: var(--bs-faint); font-size: 14px; }
.bs-hint { color: var(--bs-muted); font-size: 13px; margin: 6px 0; }

/* Buttons */
.bs-btn { background: linear-gradient(180deg, var(--bs-orange-br), var(--bs-orange)); color: var(--bs-on-orange);
  border: 0; border-radius: 10px; padding: 10px 16px; font-size: 14px; font-weight: 700; cursor: pointer;
  transition: transform .05s, filter .15s; box-shadow: 0 4px 14px rgba(255,138,0,.28); text-decoration: none; display: inline-block; }
.bs-btn:hover { filter: brightness(1.06); }
.bs-btn:active { transform: translateY(1px); }
.bs-btn-ghost { background: transparent; color: var(--bs-text); border: 1px solid var(--bs-soft); box-shadow: none; }
.bs-btn-ghost:hover { border-color: var(--bs-orange); color: var(--bs-orange); }
.bs-btn-sm { padding: 7px 12px; font-size: 13px; }
.bs-actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }

/* Balance */
.bs-balance-main { display: flex; flex-direction: column; }
.bs-label { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--bs-muted); }
/* --bs-text, not #fff: on the light `classic` skin a hardcoded white balance
   figure was white-on-white. */
.bs-amount { font-size: 30px; font-weight: 800; color: var(--bs-text); letter-spacing: -.02em; }
.bs-net { color: var(--bs-muted); font-size: 13px; margin-top: 4px; }

/* Forms */
.bs-auth label, .bs-limit-form label, .bs-range label, .bs-card label { display: block; font-size: 12px; color: var(--bs-muted); margin: 10px 0 5px; }
.bs-card input, .bs-card select, .bs-card textarea, .bs-redeem input {
  width: 100%; padding: 10px; background: var(--bs-field); border: 1px solid var(--bs-line); color: var(--bs-text);
  border-radius: 9px; box-sizing: border-box; font-size: 15px; }
.bs-card input:focus, .bs-card select:focus { outline: none; border-color: var(--bs-orange); }
.bs-tabs { display: flex; gap: 6px; margin-bottom: 12px; }
.bs-tabs button { flex: 1; padding: 9px; border: 1px solid var(--bs-line); background: var(--bs-elev2); color: var(--bs-text); border-radius: 9px; cursor: pointer; font-weight: 600; }
.bs-tabs button.active { background: var(--bs-orange); color: var(--bs-on-orange); border-color: var(--bs-orange); }
.bs-err { color: var(--bs-neg); font-size: 13px; margin-top: 8px; }
.bs-msg { color: var(--bs-orange); font-size: 13px; margin-top: 8px; }

/* Fixtures / odds */
.bs-fixture { border-top: 1px solid var(--bs-line); padding: 12px 0; }
.bs-fixture:first-child { border-top: 0; }
.bs-fixture-head { font-weight: 600; display: flex; justify-content: space-between; gap: 10px; align-items: center; margin-bottom: 10px; }
.bs-fixture-time { font-weight: 400; color: var(--bs-faint); font-size: 12px; }
.bs-odds { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.bs-odd { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 10px 6px; border: 1px solid var(--bs-line);
  border-radius: 10px; background: var(--bs-elev2); color: var(--bs-text); cursor: pointer; transition: border-color .15s, background .15s; }
.bs-odd:hover { border-color: var(--bs-orange); background: #202a3a; }
.bs-odd-name { font-size: 12px; color: var(--bs-muted); }
.bs-odd-bookmaker { font-size: 10px; text-transform: uppercase; letter-spacing: .04em; color: var(--bs-muted); opacity: .75; }
.bs-odd-price { font-weight: 800; color: var(--bs-orange); font-size: 15px; }

/* Catalogue nav */
.bs-cats, .bs-leagues { display: flex; gap: 6px; flex-wrap: wrap; }
.bs-cat, .bs-league { padding: 7px 13px; border: 1px solid var(--bs-line); background: var(--bs-elev2); color: var(--bs-text); border-radius: 999px; cursor: pointer; font-size: 13px; }
.bs-cat.active, .bs-league.active { background: var(--bs-orange); color: var(--bs-on-orange); border-color: var(--bs-orange); font-weight: 700; }
.bs-more { display: inline-block; margin-top: 8px; font-size: 12px; color: var(--bs-orange); text-decoration: none; font-weight: 600; }
.bs-market { border-top: 1px solid var(--bs-line); padding: 12px 0; }
.bs-market-h { font-weight: 700; font-size: 12px; margin-bottom: 8px; color: var(--bs-muted); text-transform: uppercase; letter-spacing: .05em; }
.bs-feats { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.bs-feat { border: 1px solid var(--bs-line); border-radius: 12px; padding: 14px; background: var(--bs-elev2); }
.bs-feat-league { font-size: 11px; color: var(--bs-orange); text-transform: uppercase; letter-spacing: .05em; }
.bs-feat-teams { font-weight: 700; margin: 4px 0 10px; }

/* Pills */
.bs-pill { display: inline-block; padding: 2px 9px; border-radius: 999px; background: var(--bs-soft); font-size: 11px; font-weight: 600; }
.bs-pill-ok, .bs-pill-won { background: rgba(47,208,122,.16); color: var(--bs-pos); }
.bs-pill-lost { background: rgba(255,77,79,.16); color: var(--bs-live); }
.bs-pill-pending { background: rgba(255,138,0,.16); color: var(--bs-orange); }
.bs-pill-void { background: var(--bs-soft); color: var(--bs-muted); }

/* Tables */
.bs-table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 13px; }
.bs-table th, .bs-table td { text-align: left; padding: 8px; border-bottom: 1px solid var(--bs-line); }
.bs-table th { color: var(--bs-muted); font-weight: 600; }
.bs-neg { color: var(--bs-neg); } .bs-pos { color: var(--bs-pos); }
.bs-range { display: flex; gap: 10px; align-items: end; flex-wrap: wrap; }
.bs-limit-form { display: grid; grid-template-columns: 1fr 1fr 1fr auto; gap: 8px; align-items: end; }
.bs-pending { background: rgba(255,138,0,.1); border: 1px solid rgba(255,138,0,.35); padding: 10px; border-radius: 10px; color: var(--bs-orange); font-size: 13px; margin: 8px 0; }
.bs-check { display: flex; align-items: center; gap: 8px; }
.bs-check input { width: auto; }

/* Betslip */
.bs-betslip-empty { color: var(--bs-muted); font-size: 13px; text-align: center; padding: 8px; }
.bs-slip-sel { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--bs-line); font-size: 14px; }
.bs-x { background: none; border: 0; color: var(--bs-neg); font-size: 18px; cursor: pointer; line-height: 1; }

/* Casino lobby */
.bs-lobby-bar { display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.bs-games { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.bs-game { border: 1px solid var(--bs-line); border-radius: 12px; overflow: hidden; text-align: center; background: var(--bs-elev2); transition: transform .12s, border-color .12s; }
.bs-game:hover { transform: translateY(-3px); border-color: var(--bs-orange); }
/* ---- game tile artwork -----------------------------------------------------
   The hue arrives as --bs-art-h, hashed from the game's slug in gameTile(), so
   a title keeps the same colour across reloads and across every brand. This
   used to be one hardcoded orange gradient for all 53 games, which made the
   lobby look like a spreadsheet AND clashed with every skin that is not tiger.
   Saturation is kept low enough that the tiles read as a set rather than a
   paint chart. */
.bs-game-thumb { position: relative; height: 104px; overflow: hidden;
  background:
    radial-gradient(130% 96% at 50% 118%, hsl(var(--bs-art-h, 32) 62% 46% / .48), transparent 72%),
    linear-gradient(152deg, hsl(var(--bs-art-h, 32) 38% 26%), hsl(calc(var(--bs-art-h, 32) + 38) 44% 13%)); }
.bs-game-art { position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 40px; line-height: 1; opacity: .92;
  filter: drop-shadow(0 3px 10px rgba(0,0,0,.5));
  transition: transform .18s ease; }
.bs-game:hover .bs-game-art { transform: scale(1.09) rotate(-3deg); }
/* The light skin needs the ground light, or a white card grows a dark hole. */
.bs-skin-classic .bs-game-thumb {
  background:
    radial-gradient(130% 96% at 50% 118%, hsl(var(--bs-art-h, 32) 72% 62% / .45), transparent 72%),
    linear-gradient(152deg, hsl(var(--bs-art-h, 32) 52% 88%), hsl(calc(var(--bs-art-h, 32) + 38) 46% 74%)); }
.bs-skin-classic .bs-game-art { filter: drop-shadow(0 2px 6px rgba(0,0,0,.22)); }
/* `mono` promises there is no colour in it. Keep that promise. */
.bs-skin-mono .bs-game-thumb { filter: saturate(0) contrast(1.06); }
.bs-skin-mono .bs-game-art { filter: saturate(0) drop-shadow(0 3px 10px rgba(0,0,0,.6)); }
@media (prefers-reduced-motion: reduce) {
  .bs-game:hover .bs-game-art { transform: none; }
}
.bs-game-cat { position: absolute; bottom: 6px; left: 6px; font-size: 11px; color: #fff; background: rgba(0,0,0,.45); padding: 2px 7px; border-radius: 6px; text-transform: capitalize; }
.bs-jp-badge { position: absolute; top: 6px; right: 6px; background: var(--bs-gold); color: var(--bs-on-gold); font-weight: 800; font-size: 11px; padding: 2px 7px; border-radius: 6px; }
.bs-game-name { font-weight: 700; font-size: 14px; padding: 10px 6px 2px; }
.bs-rtp { display: block; font-size: 11px; color: var(--bs-muted); margin-bottom: 8px; }
.bs-game .bs-btn { margin: 0 8px 10px; }

/* Game modal */
.bs-game-modal { max-width: 480px; width: 92vw; background: var(--bs-panel); }
.bs-game-modal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }

/* ---- PER-GAME SKIN ---------------------------------------------------------
   Variables are set on the overlay by gameModal(): --bs-g-h is the title's own
   hue, --bs-g-s/-l its family's temperament, --bs-g-glow how hard it burns.
   A slot runs warm and rich, an original runs hot and glows, and every table
   game shares one felt identity so a roulette wheel and a baccarat shoe read as
   the same room.

   Scope discipline: this themes the CHROME only — the header band, the ambient
   wash behind the card, the edge and the accent rule. Stake boxes, result
   numbers and controls are deliberately untouched, because tinting the surface
   a player reads a number off is a legibility bug wearing a costume. */
.bs-game-modal.bs-themed {
  position: relative;
  border: 1px solid hsl(var(--bs-g-h) var(--bs-g-s) 34% / .55);
  background:
    radial-gradient(120% 62% at 50% -8%,
      hsl(var(--bs-g-h) var(--bs-g-s) var(--bs-g-l) / .55), transparent 68%),
    var(--bs-panel);
  box-shadow:
    0 0 46px -14px hsl(var(--bs-g-h) var(--bs-g-s) 46% / calc(var(--bs-g-glow) * 1.1)),
    0 18px 50px -20px rgba(0,0,0,.75);
}
/* The band. One rule of colour across the top — the game announcing itself. */
.bs-game-modal.bs-themed::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(90deg,
    hsl(var(--bs-g-h) calc(var(--bs-g-s) + 18%) 52%),
    hsl(calc(var(--bs-g-h) + 42) calc(var(--bs-g-s) + 12%) 46%));
  opacity: calc(.55 + var(--bs-g-glow) * .5);
  border-radius: inherit; border-bottom-left-radius: 0; border-bottom-right-radius: 0;
  pointer-events: none;
}
.bs-game-modal.bs-themed > .bs-game-modal-head {
  position: relative;
  margin: -28px -28px 16px; padding: 16px 20px 14px;
  border-bottom: 1px solid hsl(var(--bs-g-h) var(--bs-g-s) 30% / .5);
  background: linear-gradient(180deg,
    hsl(var(--bs-g-h) var(--bs-g-s) calc(var(--bs-g-l) + 6%) / .60), transparent);
  border-top-left-radius: inherit; border-top-right-radius: inherit;
}
.bs-game-modal.bs-themed > .bs-game-modal-head strong,
.bs-game-modal.bs-themed > .bs-game-modal-head h3 {
  letter-spacing: -.01em;
  text-shadow: 0 1px 10px hsl(var(--bs-g-h) 70% 30% / calc(var(--bs-g-glow) * .8));
}

/* Light skin: the same theme at paper lightness, or a white card grows a
   dark hole exactly where the player looks first. */
.bs-skin-classic .bs-game-modal.bs-themed {
  border-color: hsl(var(--bs-g-h) var(--bs-g-s) 62% / .55);
  background:
    radial-gradient(120% 62% at 50% -8%,
      hsl(var(--bs-g-h) var(--bs-g-s) 78% / .55), transparent 68%),
    var(--bs-panel);
  box-shadow: 0 14px 40px -18px hsl(var(--bs-g-h) 40% 40% / .35);
}
.bs-skin-classic .bs-game-modal.bs-themed > .bs-game-modal-head {
  border-bottom-color: hsl(var(--bs-g-h) var(--bs-g-s) 66% / .6);
  background: linear-gradient(180deg, hsl(var(--bs-g-h) var(--bs-g-s) 84% / .7), transparent);
}
.bs-skin-classic .bs-game-modal.bs-themed > .bs-game-modal-head strong,
.bs-skin-classic .bs-game-modal.bs-themed > .bs-game-modal-head h3 { text-shadow: none; }

/* `mono` promises there is no colour in it. That includes the games. */
.bs-skin-mono .bs-game-modal.bs-themed,
.bs-skin-mono .bs-game-modal.bs-themed::before { filter: saturate(0); }

@media (prefers-reduced-motion: reduce) {
  .bs-game-modal.bs-themed { transition: none; }
}
.bs-demo-reel { font-size: 46px; letter-spacing: 10px; text-align: center; padding: 22px; background: var(--bs-well); border: 1px solid var(--bs-line); border-radius: 12px; margin-bottom: 10px; }
.bs-game-frame { width: 100%; height: 62vh; border: 0; border-radius: 10px; background: #000; }

/* Jackpots */
.bs-jp-row { display: flex; gap: 10px; flex-wrap: wrap; }
.bs-jp { flex: 1; min-width: 130px; display: flex; flex-direction: column; align-items: center; padding: 16px 12px; border-radius: 12px; color: var(--bs-on-gold);
  background: linear-gradient(135deg, var(--bs-gold), #ffe6a8); box-shadow: 0 8px 20px rgba(var(--bs-gold-rgb),.2); }
.bs-jp-grand { background: linear-gradient(135deg, var(--bs-orange), #ffcf7a); }
.bs-jp-major { background: linear-gradient(135deg, #ffb347, var(--bs-gold)); }
.bs-jp-name { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; font-weight: 700; }
.bs-jp-val { font-size: 24px; font-weight: 900; }

/* Promotions */
.bs-promos { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.bs-promo { border: 1px solid var(--bs-line); border-radius: 12px; padding: 16px; background: var(--bs-elev2); }
.bs-promo h4 { margin: 0 0 6px; color: var(--bs-orange); }
.bs-terms { font-size: 11px; color: var(--bs-faint); margin-top: 8px; }

/* Winners feed */
.bs-winners { list-style: none; padding: 0; margin: 0; max-height: 340px; overflow-y: auto; }
.bs-winners li { display: flex; align-items: center; gap: 8px; padding: 9px 0; border-bottom: 1px solid var(--bs-line); font-size: 14px; }
.bs-win-who { font-weight: 700; } .bs-win-detail { color: var(--bs-muted); font-size: 12px; margin-left: auto; }

/* Hero */
.bs-hero { position: relative; border-radius: 18px; padding: 56px 28px; overflow: hidden; text-align: center; color: #fff;
  background: radial-gradient(900px 380px at 50% -20%, rgba(255,138,0,.35), transparent), linear-gradient(160deg, #0a0e17, #1a1207); border: 1px solid var(--bs-line); }
.bs-hero h1 { font-size: clamp(28px, 5vw, 48px); margin: 0 0 12px; font-weight: 900; letter-spacing: -.02em; }
.bs-hero h1 span { color: var(--bs-hero-accent, var(--bs-orange)); }
.bs-hero p { opacity: .8; margin: 0 0 20px; font-size: clamp(15px,2vw,18px); }
.bs-hero-cta { display: flex; gap: 10px; justify-content: center; }
.bs-hero-rg { font-size: 11px; opacity: .55; margin-top: 20px; }

/* Referral / VIP */
.bs-refcode { font-size: 24px; font-weight: 900; letter-spacing: 4px; color: var(--bs-orange); background: var(--bs-field); border: 1px dashed var(--bs-orange); border-radius: 12px; padding: 16px; text-align: center; margin: 12px 0; }
.bs-vip { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
.bs-tier { border-radius: 12px; padding: 18px; color: #fff; text-align: center; }
.bs-tier-name { font-weight: 800; font-size: 16px; } .bs-tier-perk { font-size: 12px; opacity: .92; margin-top: 4px; }
.bs-tier-0 { background: linear-gradient(135deg,#7a4a1c,#a06a3f); } .bs-tier-1 { background: linear-gradient(135deg,#6b7178,#9aa2b0); color:#101319; }
.bs-tier-2 { background: linear-gradient(135deg,#c98a12,var(--bs-gold)); color:var(--bs-on-gold); } .bs-tier-3 { background: linear-gradient(135deg,var(--bs-orange-dp),var(--bs-orange-br)); color:var(--bs-on-orange); }

/* Bonuses */
.bs-bonus { border: 1px solid var(--bs-line); border-radius: 12px; padding: 14px; margin-bottom: 8px; background: var(--bs-elev2); }
.bs-bonus-h { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.bs-prog { height: 8px; background: var(--bs-field); border-radius: 999px; overflow: hidden; margin: 8px 0 2px; }
.bs-prog-bar { height: 100%; background: linear-gradient(90deg, var(--bs-orange), var(--bs-orange-br)); }
.bs-redeem { display: flex; gap: 8px; margin-top: 12px; }

/* Reality-check overlay */
.bs-overlay { position: fixed; inset: 0; background: rgba(var(--bs-well-rgb), .75); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 99999; }
.bs-overlay-card { background: var(--bs-panel); border: 1px solid var(--bs-line); border-radius: 16px; padding: 28px; max-width: 380px; text-align: center; color: var(--bs-text); }
.bs-overlay-actions { display: flex; gap: 10px; justify-content: center; margin-top: 16px; }
.bs-sg-links { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }

@media (max-width: 560px) { .bs-limit-form { grid-template-columns: 1fr 1fr; } .bs-odds { grid-template-columns: 1fr 1fr 1fr; } }

/* ============================================================================
   LUCKY TIGER signature components — matched to luckytiger.b-cdn.net
   ========================================================================== */
.betsystem-widget { --claw: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ff8a00' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M3.5 21.5 C9 17.5 12 12.5 12.5 4.5'/%3E%3Cpath d='M8.5 22.5 C14 18.5 17.5 13.5 18.5 6.5'/%3E%3Cpath d='M14 23 C18.5 20 21 16.5 22 10.5'/%3E%3C/svg%3E"); }

/* Section heading with orange bar */
.bs-sech { display:flex; align-items:center; gap:10px; margin:4px 2px 14px; }
.bs-sech h2 { margin:0; font-size:15px; font-weight:900; letter-spacing:.02em; text-transform:uppercase; position:relative; padding-left:13px; color:var(--bs-text); }
.bs-sech h2::before { content:""; position:absolute; left:0; top:2px; bottom:2px; width:4px; border-radius:3px; background:linear-gradient(180deg,var(--bs-orange-br),var(--bs-orange-dp)); }
.bs-sech .more { margin-left:auto; font-size:12px; color:var(--bs-orange); text-decoration:none; font-weight:700; }

/* Live hero scoreboard */
.bs-lt-hero { position:relative; overflow:hidden; border-radius:16px; padding:22px; border:1px solid var(--bs-line);
  background:radial-gradient(120% 140% at 85% 10%,rgba(255,138,0,.22),transparent 55%),linear-gradient(180deg,#1a1206,#0c0f17 70%); }
.bs-lt-hero .claw { position:absolute; right:-30px; top:-20px; width:260px; height:260px; opacity:.14; background:var(--bs-orange);
  -webkit-mask:var(--claw) center/contain no-repeat; mask:var(--claw) center/contain no-repeat; pointer-events:none; }
.bs-lt-row1 { display:flex; align-items:center; gap:10px; margin-bottom:16px; }
.bs-lt-live { display:inline-flex; align-items:center; gap:6px; font-size:11px; font-weight:900; letter-spacing:.1em; color:#fff; background:var(--bs-live); padding:4px 9px; border-radius:6px; }
.bs-lt-live::before { content:""; width:6px; height:6px; border-radius:50%; background:#fff; animation:bs-pulse 1.2s infinite; }
@keyframes bs-pulse { 0%,100%{opacity:1} 50%{opacity:.3} }
.bs-lt-comp { font-size:12px; font-weight:800; letter-spacing:.06em; text-transform:uppercase; color:var(--bs-muted); }
.bs-lt-clock { margin-left:auto; font-size:13px; color:var(--bs-orange); font-weight:800; }
.bs-lt-match { display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:16px; margin-bottom:20px; }
.bs-lt-team { display:flex; flex-direction:column; gap:5px; }
.bs-lt-team.r { align-items:flex-end; text-align:right; }
.bs-lt-team .nm { font-size:23px; font-weight:900; letter-spacing:-.01em; color:#fff; }
.bs-lt-team .mt { font-size:11.5px; color:var(--bs-muted); }
.bs-lt-score { display:flex; align-items:center; gap:14px; font-size:40px; font-weight:900; letter-spacing:-.02em; color:#fff; }
.bs-lt-mktlabel { font-size:10.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--bs-muted); margin-bottom:8px; }
.bs-lt-odds3 { display:grid; grid-template-columns:repeat(3,1fr); gap:10px; }

/* Boost / Tiger Special cards */
.bs-boosts { display:flex; gap:14px; overflow-x:auto; padding-bottom:6px; scrollbar-width:thin; scrollbar-color:var(--bs-orange) transparent; }
.bs-boost { flex:0 0 272px; scroll-snap-align:start; background:var(--bs-panel); border:1px solid var(--bs-line); border-radius:14px; padding:14px;
  position:relative; overflow:hidden; display:flex; flex-direction:column; gap:9px; box-shadow:0 8px 22px rgba(0,0,0,.35); transition:transform .16s,border-color .16s; }
.bs-boost::before { content:""; position:absolute; top:0; left:0; right:0; height:2px; background:linear-gradient(90deg,transparent,var(--bs-orange),transparent); }
.bs-boost:hover { transform:translateY(-3px); border-color:var(--bs-orange); }
.bs-boost .bt { display:flex; align-items:center; gap:8px; }
.bs-boost .ttl { font-size:11px; font-weight:900; letter-spacing:.09em; text-transform:uppercase; color:var(--bs-orange); }
.bs-boost .fire { margin-left:auto; font-size:11px; font-weight:800; color:var(--bs-muted); }
.bs-boost .mk { font-size:10.5px; color:var(--bs-muted); font-weight:800; text-transform:uppercase; letter-spacing:.05em; }
.bs-boost .legs { display:flex; flex-direction:column; gap:5px; }
.bs-boost .leg { display:flex; align-items:center; gap:8px; font-size:13px; font-weight:700; color:var(--bs-text); }
.bs-boost .leg .tk { color:var(--bs-orange); font-weight:900; }
.bs-boost .obx { display:flex; align-items:baseline; gap:9px; margin-top:2px; }
.bs-boost .was { font-size:14px; color:var(--bs-faint); text-decoration:line-through; font-weight:700; }
.bs-boost .arr { color:var(--bs-orange); font-weight:900; }
.bs-boost .now { font-size:25px; font-weight:900; color:var(--bs-text); letter-spacing:-.01em; }
.bs-boost .ret { font-size:11.5px; color:var(--bs-muted); }
.bs-boost .add { margin-top:auto; border:1px solid var(--bs-soft); border-radius:9px; padding:11px; cursor:pointer; font-size:12.5px; font-weight:900;
  letter-spacing:.04em; text-transform:uppercase; background:var(--bs-elev2); color:var(--bs-text); transition:.14s; }
.bs-boost .add:hover, .bs-boost.on .add { background:linear-gradient(180deg,var(--bs-orange-br),var(--bs-orange-dp)); color:var(--bs-on-orange); border-color:var(--bs-orange); }

/* Promo grid */
.bs-lt-promos { display:grid; grid-template-columns:repeat(auto-fill,minmax(230px,1fr)); gap:14px; }
.bs-lt-promo { position:relative; overflow:hidden; border-radius:14px; border:1px solid var(--bs-line); background:linear-gradient(180deg,var(--bs-elev),var(--bs-panel)); padding:18px; }
.bs-lt-promo::before { content:""; position:absolute; top:0; left:0; right:0; height:2px; background:linear-gradient(90deg,transparent,var(--bs-orange),transparent); }
.bs-lt-promo .em { font-size:26px; font-weight:900; color:var(--bs-orange); }
.bs-lt-promo .kick { font-size:10.5px; font-weight:900; letter-spacing:.1em; text-transform:uppercase; color:var(--bs-muted); margin:8px 0 4px; }
.bs-lt-promo .ph { font-size:18px; font-weight:900; color:var(--bs-text); margin-bottom:6px; }
.bs-lt-promo .pd { font-size:13px; color:var(--bs-muted); margin-bottom:12px; }
.bs-lt-promo .rg { font-size:10px; color:var(--bs-faint); margin-top:10px; }

/* Language switcher */
.bs-lang { display:inline-flex; gap:4px; background:var(--bs-elev2); border:1px solid var(--bs-line); border-radius:999px; padding:3px; }
.bs-lang-b { border:0; background:transparent; color:var(--bs-muted); font-size:12px; font-weight:800; padding:6px 11px; border-radius:999px; cursor:pointer; }
.bs-lang-b.active { background:var(--bs-orange); color:var(--bs-on-orange); }

/* ============================================================================
   10 SKIN PRESETS — pick one in Elementor (bs_skin), or override colours.
   Each just re-sets the --bs-* variables the whole widget system reads.
   ========================================================================== */
.bs-skin-tiger   { /* default = the :root values (orange/black) */ }
.bs-skin-neon    { --bs-orange:#ff2e9a; --bs-orange-br:#ff5cb4; --bs-orange-dp:#e0148a; --bs-on-orange:#0a0410; --bs-bg:#0a0713; --bs-panel:#140b22; --bs-elev:#1a1030; --bs-elev2:#221542; --bs-line:#33224f; --bs-soft:#3d2a5e; --bs-gold:#39e6ff; --bs-live:#ff3b6b; }
.bs-skin-royal   { --bs-orange:#c9a227; --bs-orange-br:#e3bf4a; --bs-orange-dp:#a9861a; --bs-on-orange:#14110a; --bs-bg:#0c0a1a; --bs-panel:#161231; --bs-elev:#1d1840; --bs-elev2:#241e4d; --bs-line:#332c63; --bs-soft:#3c357a; --bs-gold:#e3bf4a; }
.bs-skin-emerald { --bs-orange:#1fbf75; --bs-orange-br:#37e08e; --bs-orange-dp:#159a5c; --bs-on-orange:#04140c; --bs-bg:#06120d; --bs-panel:#0c1b15; --bs-elev:#11241c; --bs-elev2:#163026; --bs-line:#21453a; --bs-soft:#2b5a4a; --bs-gold:#9ff0c8; }
.bs-skin-sunset  { --bs-orange:#ff5a3c; --bs-orange-br:#ff7d63; --bs-orange-dp:#e6432a; --bs-on-orange:#1a0a06; --bs-bg:#140a0a; --bs-panel:#20100e; --bs-elev:#2a1512; --bs-elev2:#361b17; --bs-line:#4a2820; --bs-soft:#5c332a; --bs-gold:#ffce54; }
.bs-skin-ice     { --bs-orange:#2f9dff; --bs-orange-br:#5cb4ff; --bs-orange-dp:#1a82e6; --bs-on-orange:#04101c; --bs-bg:#080d15; --bs-panel:#0e1622; --bs-elev:#131e2e; --bs-elev2:#18273a; --bs-line:#243547; --bs-soft:#2f4459; --bs-gold:#8fd3ff; }
.bs-skin-mono    { --bs-orange:#e8e8ea; --bs-orange-br:#ffffff; --bs-orange-dp:#c9c9cf; --bs-on-orange:#0a0a0c; --bs-bg:#08080a; --bs-panel:#131316; --bs-elev:#1a1a1e; --bs-elev2:#222227; --bs-line:#2e2e34; --bs-soft:#3a3a42; --bs-gold:#bdbdc4; --bs-live:#ff5a5f; }
/* The one LIGHT skin. It also re-points the semantic colours: the dark-theme
   green/red/grey are ~3:1 on white, which is under AA for body text. */
/* CLASSIC IS THE ONLY LIGHT SKIN, and two of its tokens were a shade too pale
   to carry small text on a themed modal. Measured on the real rendered page:
   --bs-faint sat at 3.87 against the modal's own tint (the 9px uppercase deck
   labels and the roulette rack label), and --bs-neg at 4.24 in the modal header
   where the tint is strongest — the close X, on every game in the product.
   Neither is dramatic and both are exactly the kind of near-miss that never
   gets reported and never gets fixed.
   Darkened to 4.89 and 5.66 respectively, which keeps both hues plainly
   themselves. --bs-live is deliberately NOT darkened with --bs-neg: it is a
   decorative dot rather than text, and it should stay the brighter red.
   The dark skins were already clear and are untouched. */
.bs-skin-classic { --bs-orange:#0a58ca; --bs-orange-br:#2b74e0; --bs-orange-dp:#0847a8; --bs-on-orange:#ffffff; --bs-bg:#eef1f7; --bs-panel:#ffffff; --bs-elev:#ffffff; --bs-elev2:#f4f6fb; --bs-line:#dbe1ec; --bs-soft:#c7cfdd; --bs-text:#141a24; --bs-muted:#4f5a6a; --bs-faint:#59616d; --bs-gold:#a9781a; --bs-pos:#0c7a45; --bs-neg:#aa1c23; --bs-live:#c62129; }
.bs-skin-midnight{ --bs-orange:#6c8cff; --bs-orange-br:#8aa2ff; --bs-orange-dp:#5470e6; --bs-on-orange:#080b18; --bs-bg:#070912; --bs-panel:#0f1220; --bs-elev:#141829; --bs-elev2:#1a1f34; --bs-line:#262c45; --bs-soft:#333a58; --bs-gold:#b9c4ff; }
.bs-skin-candy   { --bs-orange:#ff4d8d; --bs-orange-br:#ff77a8; --bs-orange-dp:#e63a76; --bs-on-orange:#180810; --bs-bg:#0d0a12; --bs-panel:#181120; --bs-elev:#1f172a; --bs-elev2:#281d36; --bs-line:#382a49; --bs-soft:#463459; --bs-gold:#2ee6c8; --bs-live:#ff4d6d; }

/* ============================================================================
   BETSYSTEM — FOUNDATION: THE SKIN-FIX TOKENS
   (nine tokens; this is a palette/skin-correctness block, not a type,
    spacing or elevation system — see §4 for what it deliberately is not)
   ============================================================================

   WHERE THIS GOES
   ---------------
   ONE contiguous insert into assets/betsystem.css, BETWEEN line 270
   (`.bs-skin-candy { … }`) and line 272 (the "Editable radius + font" comment).
   Nothing is deleted. Nothing above line 270 is touched. The Google Fonts
   @import on line 5 stays exactly where it is (see §0).

   WHY HERE AND NOT AT LINE 7 — the ordering proof
   -----------------------------------------------
   Three blocks declare tokens today and all three are (0,1,0), so source order
   is the only tiebreak (the sheet has no @layer and no !important anywhere in
   the token system):

       :7        .betsystem-widget, .bs-hero, .bs-overlay   18 base tokens
       :259-270  .bs-skin-tiger … .bs-skin-candy            the ten skins
       :5294     .betsystem-widget, .bs-hero, .bs-overlay   --bs-t-* / --bs-sp-*

   A colour token added at :5294 would silently overwrite that colour in all ten
   skins, because :5294 is AFTER them. So new colour tokens must sit either
   before :259 or — as here — after :270 while declaring ONLY names no existing
   skin block sets. Both conditions hold:

     PRECONDITION (verify before applying): none of --bs-well, --bs-well-rgb,
     --bs-field, --bs-print, --bs-on-gold, --bs-gold-ink, --bs-gold-rgb,
     --bs-glass or --bs-hero-accent appears anywhere in lines 1–270. Confirmed
     today: all nine are absent from the whole 6,953-line sheet.

   That buys the single insert point AND lets the per-skin half of this block
   sit after the ten existing skin rules, where it has to be to override them.

   The declaration site does NOT move. It is still
   `.betsystem-widget, .bs-hero, .bs-overlay` — the same three selectors as :7 —
   because Elementor writes per-operator --bs-* overrides into the INLINE style
   attribute of `.betsystem-widget` (class-base-widget.php:170-173) and inline
   only beats a rule that targets the same element.

   …WITH ONE DELIBERATE EXCEPTION, AND HERE IS WHY (this is the correction the
   adversarial pass forced, and it is load-bearing):

     `.bs-hero` IS ITSELF IN THE :7 SELECTOR LIST, AND `.bs-hero` IS ALWAYS A
     DESCENDANT OF `.betsystem-widget`.

     class-base-widget.php:164-165 puts `data-betsystem` and
     `class="betsystem-widget bs-skin-<x>"` on the SAME div;
     betsystem-app.js:12971 boots `[data-betsystem]` roots;
     `renderHeroBanner()` at betsystem-app.js:1572 writes
     `root.innerHTML = '<div class="bs-hero">…'` into that div. It is the only
     `.bs-hero` emitter in either JS file.

     A DECLARED value on an element always beats an INHERITED one, whatever the
     specificity of the ancestor rule. So `.bs-hero` re-declares all 18 base
     tokens on itself at TIGER defaults, and `.bs-skin-classic { --bs-orange:
     #0a58ca }` — which matches the widget, an ancestor — never reaches it.
     Verified: `--bs-orange` resolves to #ff8a00 on `.bs-hero` on all ten skins.

     CONSEQUENCE 1 — a previously unrecorded product bug: THE HERO HAS NEVER
     BEEN SKINNED. `.bs-hero h1 span`, `.bs-hero-cta .bs-btn` and
     `.bs-hero-cta .bs-btn-ghost` all render tiger on every skin, and an
     operator's inline Elementor accent does not reach them either.

     CONSEQUENCE 2 — a token declared on that three-selector list is pinned to
     its base value inside the hero. That is harmless for --bs-well,
     --bs-well-rgb, --bs-field, --bs-print, --bs-on-gold, --bs-gold-ink,
     --bs-gold-rgb and --bs-glass (grepped: none of their consumers is inside
     the hero subtree), and FATAL for --bs-hero-accent, whose only consumer is.
     So --bs-hero-accent is declared on `.betsystem-widget` ALONE (§1b), where
     the skin blocks and Elementor's inline style both still win, and its
     consumer carries a `var(--bs-hero-accent, var(--bs-orange))` fallback for
     the frontend-demo case where there is no `.betsystem-widget` at all.

     WHAT IS *NOT* FIXED HERE: the rest of the hero subtree. The safe fix is not
     `.betsystem-widget .bs-hero { --bs-orange: inherit; … }` — that also
     inherits `--bs-text`, and on `classic` `.bs-hero-cta .bs-btn-ghost`'s
     `color: var(--bs-text)` #141a24 measures 1.74:1 on the hero's own
     radial-lit surface. Restating each skin on `.bs-hero` is a separate,
     ten-rule change with its own contrast table. Recorded, not attempted.

   WHAT THIS BLOCK IS FOR
   ----------------------
   `bs-skin-*` is emitted onto `.betsystem-widget` only (class-base-widget.php:165).
   Every game modal, the reality-check card and the live region are
   `document.body.appendChild(...)`, i.e. SIBLINGS of the widget, and the string
   "bs-skin" appears 0 times in 13,011 lines of betsystem-app.js. So for the whole
   life of this product all 21 games have rendered in default tiger whatever skin
   the operator picked. skin_propagation.md fixes that in JS.

   The moment it lands, `classic` — the one light skin — reaches a game modal for
   the first time, and every hardcoded near-black in the sheet becomes a hole
   punched through a white card: 33 live `#05070c` stage wells and 5 `#0d121b`
   input troughs. Every token here has enumerated consumers in substitutions.md;
   a token with no consumer is not in this file (see §4).

   THE CONTRACT
   ------------
   * TIGER IS BYTE-IDENTICAL except for the two changes named in §4 under
     "THE TIGER-VISIBLE CHANGES". Both are legibility corrections, both are
     computed, and both are listed rather than denied.
   * The nine other dark skins change in four ways and only four: their well and
     field stop being tiger's near-black; their gold GLOW stops being tiger's
     gold; their hero accent stops being tiger's orange; and five ink sites that
     hardcoded tiger's `#1a1207` start reading `var(--bs-on-orange)`.
   * classic changes a lot, all of it computed below.

   ============================================================================
   CONTRAST — every ink/surface pair this file creates or moves, all ten skins
   ============================================================================
   WCAG 2.2: 4.5:1 for text under 24px (or under 18.66px bold), 3:1 for larger
   text and for UI component boundaries (1.4.11). Computed with the sRGB
   relative-luminance formula, not estimated. Gradients are sampled at 101
   points, not at their end stops. **Any `opacity` in the ink's own rule is
   composited before the ratio is taken** — the previous draft of this table did
   not do that and reported four passes that were failures (see T3/T4).
   "today" rows are the shipped sheet.

   T1  --bs-print on --bs-well        (ink on a stage floor — needs 4.5)
       tiger 18.44 · neon 18.75 · royal 18.65 · emerald 18.33 · sunset 18.63
       ice 18.49 · mono 18.75 · classic 15.47 · midnight 18.74 · candy 18.67
       worst 15.47 (classic). PASS ×10.
       SCOPE NOTE: --bs-print is read by exactly two declarations, both inside
       the `.bs-skin-classic` pit rule in overrides.css §1. On the nine dark
       skins nothing reads it; their stages carry `var(--bs-text)` as they always
       did. It is the classic pit's ink token, declared globally only so the pit
       rule has one place to point at. The row above is what it WOULD measure on
       each skin, not a pairing that occurs on nine of them.

   T2  --bs-text on --bs-field        (every card input in the product — needs 4.5)
       new    tiger 17.18 · neon 17.96 · royal 17.45 · emerald 16.97 · sunset 17.51
              ice 17.35 · mono 17.88 · classic 14.74 · midnight 17.74 · candy 17.52
       today  17.18 on the nine dark skins — and 1.07 on classic, because :60
              hardcodes `background:#0d121b` under `color:var(--bs-text)` #141a24.
       worst 14.74 (classic). PASS ×10. Was FAIL ×1 by a factor of four.
       BOUNDARY (WCAG 1.4.11, 3:1 — the number the previous draft omitted):
              classic --bs-field #e8ecf4 vs --bs-panel #ffffff  = 1.18
              classic --bs-line  #dbe1ec vs --bs-panel #ffffff  = 1.31
              classic --bs-line  #dbe1ec vs the new fill        = 1.11
       A legible-but-invisible control is not a fix. overrides.css §4.1 gives
       the five §2 sites a `#7f8899` border — 3.57:1 on the card, 3.01:1 on the
       fill — and gives `.bs-prog`, which has no border at all, a 1px inset ring
       at the same value. Those two rules are not optional either.

   T3  --bs-on-gold (#1a1207) on the gold surfaces it inks
       on var(--bs-gold):  tiger 10.78 · neon 12.30 · royal 10.43 · emerald 13.91
                           sunset 12.53 · ice 11.41 · mono 9.92 · classic 4.75
                           midnight 10.94 · candy 11.71
       `.bs-jp`   (`var(--bs-gold)` → `#ffe6a8`, 101-pt): worst 4.75 (classic)
       `.bs-jp-major` (`#ffb347` → `var(--bs-gold)`)    : worst 4.75 (classic)
       `.bs-jp-grand` (`var(--bs-orange)` → `#ffcf7a`)  : **worst 2.88 (classic)**
              — the near stop of this gradient is the SKIN'S ORANGE, not a gold.
              The previous draft enumerated only the four hardcoded stops
              (#ffe6a8 15.12 · #ffcf7a 12.76 · #ffb347 10.40 · #c98a12 6.29) and
              so measured the far end of `.bs-jp-grand` and never the near one.
              Live class names: betsystem-app.js:1357
              `'<div class="bs-jp bs-jp-' + j.tier + '">'`.
              Per skin at the 0% stop: classic 2.88 (FAIL — `.bs-jp-name` 11px/700
              needs 4.5 and `.bs-jp-val` 24px/900 needs 3.0, both fail), neon 5.39,
              sunset 5.98, candy 5.91, midnight 6.03, ice 6.52, royal 7.66,
              emerald 7.73, tiger 7.84, mono 12.76.
              This is a LIVE defect in the shipped sheet on the light skin — the
              jackpot row is widget chrome, so `classic` already reaches it.
              FIXED in overrides.css §4.2 by giving `classic` (and only classic)
              a gold near stop, `#d9a441`: worst across the ramp 8.24:1.
       `.bs-tier-2` (`#c98a12` → `var(--bs-gold)`) — and here the opacity matters:
              betsystem.css:168 declares `.bs-tier-perk { font-size:12px; opacity:.92 }`.
              12px needs 4.5.
                 uncomposited: 6.29 on nine skins, 4.75 classic  → looks like a pass
                 composited @.92: 5.67 on nine skins, **4.37 classic → FAIL**
              FIXED in overrides.css §4.4, which sets `.bs-tier-perk { opacity: 1 }`
              at (0,1,0). That restores 6.29 / 4.75 and is one of the two
              tiger-visible changes in this package (§4).
       PASS ×10 after §4.2 and §4.4. Was FAIL on classic at two of the three
       jackpot tiers and at the tier-2 VIP plate.
       Dark ink on gold is correct on EVERY skin, so --bs-on-gold is dark on every
       skin and there is no per-skin override at all. The eight sites it replaces
       render byte-identically on all ten skins.

   T4  --bs-on-orange on var(--bs-orange) / -dp / -br
       new    tiger 7.84/7.09/9.25 · neon 6.00/4.55/7.31 · royal 7.79/5.48/10.61
              emerald 7.89/5.23/11.00 · sunset 6.22/4.77/7.68 · ice 6.74/4.91/8.60
              mono 16.17/12.00/19.78 · classic 6.44/8.48/5.24
              midnight 6.38/4.51/8.11 · candy 6.20/4.84/7.82
       today  the same SIX sites hardcode #1a1207: neon 5.39/4.09/6.57 (FAIL),
              midnight 6.03/4.27/7.67 (FAIL), classic 2.88/2.19/4.13 (FAIL ×3).
       worst 4.51 (midnight). PASS ×10. Was FAIL ×5 of 6.
       SIX, not five: substitutions.md §3b lists six rows (3.9–3.14) because
       betsystem.css:170 carries `#1a1207` twice — once for `.bs-tier-2` (§3.3,
       an --bs-on-gold site) and once for `.bs-tier-3` (§3.9, an --bs-on-orange
       site). The previous draft said "five" in the prose and listed six in the
       table; the total (8 + 6 = 14) was always right.
       `.bs-tier-3` composited @ .92 (`.bs-tier-perk`, 12px, needs 4.5):
              neon 4.38 · midnight 4.23 · sunset 4.45 · classic 4.70 · ice 4.54
              → three FAILS that the uncomposited row hides. overrides.css §4.4's
              `opacity: 1` restores the row above (worst 4.51 midnight). PASS ×10.
       Two per-skin corrections were needed to get there and both are below:
       neon --bs-on-orange #0a0410 → #050208 (4.47 → 4.55 on its own -dp) and
       classic --bs-orange-br #2b74e0 → #2569d0 (4.49 → 5.24 under white ink).
       INK vs MATERIAL: --bs-on-orange has 33 consumers. Two of them are not ink
       at all — betsystem.css:1731 `.bs-plink-btn-ball`'s
       `radial-gradient(circle at 34% 28%, #ffffff, var(--bs-on-orange) 78%)`
       (on classic that is #ffffff → #ffffff, a flat white disc: the highlight
       and the body collapse into one value) and betsystem.css:2083
       `.bs-craps-token`'s `repeating-conic-gradient(var(--bs-orange) 0 30deg,
       var(--bs-on-orange) 30deg 60deg)`. substitutions.md §3g re-literalises
       both to `#1a1207` — tiger's own value, so tiger is byte-identical — and
       this table therefore audits 31 ink consumers and excludes 2 materials,
       the same split §4.4 of substitutions.md makes for the physical literals.

   T5  --bs-gold-ink on the light-skin card surfaces
       WHAT THIS MEASURES, precisely, because the previous draft's "PASS ×10"
       was a statement about a token presented as a statement about the product:
       152 distinct lines in the sheet declare `color: var(--bs-gold)`
       (164 occurrences). The previous draft rewired ONE of them.
       On classic --bs-gold #a9781a measures 3.897:1 on --bs-panel #ffffff and
       3.60:1 on --bs-elev2 #f4f6fb — under AA for every one of them below the
       large-text threshold. Inside a stage the pit re-points --bs-gold to
       #e0b562 and they pass; outside a stage — every settlement banner, HUD,
       ladder, slip and odds tag, all of which the JS emits as SIBLINGS of the
       stage — they do not. Verified siblings: `.bs-slot-result` (js:1891, the
       `.bs-slot-window` closes at js:1915), `.bs-keno-rung` (js:6571, after the
       `.bs-keno-board` div closes), `.bs-plink-hud` (js:5974 vs boardHtml
       js:5910), `.bs-hilo-payout`/`-console` (js:6828-6831 vs feltHtml js:6750).
       substitutions.md §3c therefore rewires ALL 152, not one — which is SAFE
       because --bs-gold-ink aliases straight through to --bs-gold on the nine
       dark skins AND inside the classic pit, so 151 of the 152 are byte-identical
       everywhere except classic-outside-a-stage. The four sites that sit on a
       hardcoded DARK material outside every pit container are guarded by name in
       overrides.css §4.3 (`.bs-rw-table`, `.bs-snk-table`, `.bs-ckt-board`),
       which re-aliases --bs-gold-ink back to --bs-gold there.
       new    tiger 10.53/9.83/9.07 · neon 12.66/12.01/11.11 · royal 10.14/9.40/8.64
              emerald 13.33/12.20/10.62 · sunset 12.44/11.70/10.72
              ice 11.18/10.32/9.30 · mono 9.93/9.29/8.48 · classic 6.70/6.70/6.20
              midnight 11.00/10.40/9.62 · candy 11.64/10.93/10.06
              (panel / elev / elev2)
       today  identical on the nine dark skins; classic 3.90/3.90/3.60 — FAIL.
       worst 6.20 (classic). PASS ×10 across all 152 consumers. Was FAIL ×~40
       (the sub-24px ones on a card), of which the previous draft fixed one.
       Gold as a BORDER on classic (e.g. `.bs-crash-result-win`) is a graphical
       boundary at 3:1, not text: #a9781a is 3.90 on the card — it passes and is
       deliberately NOT rewired (border-color sites are untouched by §3c, which
       replaces the string `color:var(--bs-gold)` only).

   T6  --bs-hero-accent on `.bs-hero h1 span` (clamp(28px,5vw,48px)/900 → 3:1)
       THIS TABLE IS ENTIRELY REWRITTEN. The previous draft's "today classic
       3.00/2.88 — FAIL" was fiction: because `.bs-hero` re-declares the base
       tokens on itself (see the header), the hero renders TIGER #ff8a00 on all
       ten skins today, and has since the sheet shipped. There is no contrast
       defect to fix. What there is, is a skin-coherence defect.
       The hero surface is TWO layers, and the previous draft measured only one:
         `radial-gradient(900px 380px at 50% -20%, rgba(255,138,0,.35), transparent)`
         over `linear-gradient(160deg, #0a0e17, #1a1207)`.
       The h1 sits under the radial, so the worst case is the linear stops
       composited with the radial at its theoretical maximum α=.35 →
       #60390f and #6a3c05. All four surfaces are sampled below.
       today  ALL TEN SKINS render #ff8a00: 8.17 / 7.84 on the bare stops,
              4.25 / 3.93 under the radial. worst 3.93. Passing, on every skin,
              and identical on every skin — which is the bug.
       new    tiger    #ff8a00 (unchanged, byte-identical)  worst 3.93
              neon     #ff5cb4  3.29   (var(--bs-orange) #ff2e9a would be 2.70 — FAIL)
              royal    #c9a227  3.84
              emerald  #1fbf75  3.88
              sunset   #ff7d63  3.70   (#ff5a3c would be 3.00 — no margin)
              ice      #5cb4ff  4.17   (#2f9dff would be 3.27)
              mono     #e8e8ea  7.59
              classic  #7fb3ff  4.33   (#0a58ca would be 1.44 — FAIL by 2×)
              midnight #8aa2ff  3.84   (#6c8cff would be 3.02 — no margin)
              candy    #ff77a8  3.74   (#ff4d8d would be 2.96 — FAIL)
       worst 3.29 (neon). PASS ×10. The five skins that take `--bs-orange-br`
       rather than `--bs-orange` do so because their `--bs-orange` lands at or
       under 3.0 on the radial-lit surface; the rule is stated, not eyeballed.
       Tiger keeps `var(--bs-orange)` because tiger must not move.

   T7  Separation, informative — --bs-field and --bs-well against their own --bs-panel
       field:panel 1.03–1.06 on the nine dark skins, 1.18 on classic.
       well:panel  1.07–1.13 on the nine dark skins, 16.91 on classic.
       A trough is meant to be a shade; the BOUNDARY is the 1px border, and on
       classic that border is corrected to 3:1 in overrides.css §4.1 (see T2).

   T8  The scrim, informative — `.bs-overlay` rgba(var(--bs-well-rgb), .75) over
       the page, card separation: dark skins 1.07–1.12 (was 1.05–1.12 — a no-op,
       the wells are near-black either way), classic 7.86 (was 10.09). The card
       is separated by its border and shadow, not by the scrim; no threshold applies.

   T9  --bs-glass, the frosted plate (11 consumers, betsystem.css:557)
       `.bs-glass` is not a bevel: it is the entire background of eleven
       surfaces, four of which are a game's primary settlement readout
       (`.bs-plink-hud` js:5929, `.bs-hilo-payout` js:6782/6788,
       `.bs-hilo-console` js:6795, `.bs-sicbo-payout` js:9799) and three of which
       are already broken on classic TODAY in widget chrome (`.bs-wd-add` js:581,
       `.bs-wd-break` js:604, `.bs-chin-pay` js:10417). Its fill is pure white
       alpha, so on a white card it computes to the card and the plate vanishes;
       the only remaining boundary is `var(--bs-line)` #dbe1ec at 1.31:1.
       new    dark skins + inside the classic pit: byte-identical
              (`rgba(255,255,255,.06) → rgba(255,255,255,.015)`)
              classic on a card: `rgba(16,24,40,.07) → rgba(16,24,40,.02)`
              = #eeeff0 → #fafafb, 1.15:1 / 1.04:1 against `--bs-panel` #ffffff,
              inside a `--bs-line` border that overrides.css §3 lifts to
              #7f8899 = 3.57:1 in a game modal. The plate has an edge again.
       This is the one class pulled OUT of substitutions.md §4.5's 763-site
       greyscale deferral, and §4.5 now says why.

   T10 The classic "pit" ramp — the ink and accent ramp that makes a DARK stage
       legible inside a LIGHT card — is in overrides.css §1, with its own table,
       now including `--bs-soft`, which the previous draft declared and did not
       measure.

   T11 The classic GAME-MODAL ramp — `--bs-line` lifted from #dbe1ec (1.31:1)
       to #7f8899 (3.57:1 on the card, 3.30:1 on `--bs-elev2`, 3.01:1 on
       `--bs-field`) — is in overrides.css §3, with its own table and its own
       proof that `--bs-line` is never an ink (8 apparent `color:var(--bs-line)`
       grep hits are all `border-color` / `border-top-color`; 17 background hits
       are all rules, tracks and dotted separators, none carrying text).

   ========================================================================== */


/* ----------------------------------------------------------------------------
   0. THE TYPEFACE IS NOT TOUCHED.
   The `@import url('https://fonts.googleapis.com/css2?family=Inter…')` on line 5
   stays. The earlier proposal deleted it and replaced it with an @font-face
   pointing at ../fonts/InterVariable.woff2 — a file that does not exist, in a
   directory that does not exist (assets/ contains css/ and js/ and nothing
   else). That would have swapped the whole product to system-ui AND fired a
   404 on every page. So: no @font-face, no @import change, no font-weight
   token, no new font stack.
   Ship the woff2 first; then this decision can be revisited on its own.
   (adversarial finding 14)
   -------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   1. THE EIGHT TOKENS THAT ARE SAFE ON THE THREE-SELECTOR LIST
   Same three selectors as line 7. Not `:root` — Elementor's inline --bs-*
   overrides live on `.betsystem-widget` and must keep winning.
   Every one of these was checked against the `.bs-hero` shadowing trap
   described in the header: none of their consumers is inside the hero subtree,
   so pinning them to base values there has no effect.
   Consumer counts are exact and every site is listed in substitutions.md.
   -------------------------------------------------------------------------- */
.betsystem-widget, .bs-hero, .bs-overlay {

  /* The stage floor. The palette had four steps going UP from the page
     (bg → panel → elev → elev2) and nothing going DOWN, so 33 rules invented
     their own floor and froze it at tiger's #05070c: `.bs-felt`, every dice
     tray, every wheel stage, the plinko board, the slot reel window, the mines
     well, the keno board, the craps pit, the scratch ticket. On `classic` those
     are 33 black holes in a white modal.
     Consumers: 33 background sites (13 flat, 20 gradient). Zero borders,
     zero shadows — checked one by one, which is why this is a safe swap. */
  --bs-well: #05070c;

  /* The same colour as a triplet, because two sites need it with an alpha and
     the sheet has no --*-rgb token to read yet. `rgba(var(--x-rgb), a)` is the
     sheet's own idiom for alpha (color-mix() is used zero times here and is not
     introduced by this package).
     Consumers: 2 — `.bs-overlay`'s backdrop scrim (:180, the single most visible
     use of this colour in the product) and the roulette ball-track ring (:3686). */
  --bs-well-rgb: 5,7,12;

  /* The trough. Inputs, the referral code plate, the progress track, the 2FA
     key and its backup codes. Five flat `background` declarations, no borders,
     no gradients. :60 is the one that matters: it is EVERY card input in the
     product, and on `classic` it is currently a near-black box carrying #141a24
     ink at 1.07:1. Invisible. Its boundary is corrected in overrides.css §4.1;
     see T2.
     Consumers: 5. */
  --bs-field: #0d121b;

  /* Ink for anything sitting on a well, a felt or a night sky. Those surfaces
     are dark on all ten skins by construction (see the classic block below).
     Consumers: 2 declarations, both inside the classic stage rule in
     overrides.css §1. It is the classic pit's ink token; T1 says so. */
  --bs-print: #f2f5fa;

  /* Ink ON a gold surface. Eight rules currently hardcode #1a1207 on gold.
     Tokenising the ink without changing its value is deliberate: the number is
     right on every skin (T3), and naming it forecloses the mistake the earlier
     proposal made, which was to point these at white and take `.bs-jp` from
     15.12:1 to 1.23:1 on the light skin.
     Consumers: 8. */
  --bs-on-gold: #1a1207;

  /* Gold as TEXT, which is a different problem from gold as a SURFACE. Nine
     skins have no distinction to make and alias straight through, so they are
     byte-identical; the classic pit aliases it back for the same reason. Only
     `classic` outside a stage has to split them: #a9781a is a good jackpot plate
     and a bad label — 3.90:1 on a white card.
     Consumers: 152 (every `color: var(--bs-gold)` line in the sheet), minus the
     four re-aliased by container in overrides.css §4.3. See T5. */
  --bs-gold-ink: var(--bs-gold);

  /* Gold as a GLOW. Nine sites bolt an alpha onto tiger's gold literal
     `rgba(231,192,122,α)`, so on neon a win is cyan text inside a warm-gold
     halo, on mono a grey figure inside a gold halo, on candy teal inside gold.
     The previous draft declined this on the grounds that a --bs-*-rgb companion
     would have "no consumers"; it has nine, at betsystem.css:138, 280, 305, 574,
     1702, 4016, 4021, 5864, 6769 — and 280 is the very line the package already
     edits. The other five glow families (orange ×21, pos ×18, neg ×12,
     on-orange ×4, live ×2) are still deferred, and §4 now names them with counts
     rather than with a false premise.
     Consumers: 9. */
  --bs-gold-rgb: 231,192,122;

  /* The frosted plate. One consumer, betsystem.css:557, which supplies the
     entire background of eleven surfaces including four games' settlement
     readouts. Pure white alpha vanishes on a white card. See T9. */
  --bs-glass: linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.015));
}


/* ----------------------------------------------------------------------------
   1b. THE ONE TOKEN THAT MUST NOT BE ON `.bs-hero`.
   `.bs-hero` is in the :7 selector list AND is always a descendant of
   `.betsystem-widget` (class-base-widget.php:164-165 + betsystem-app.js:1572,
   :12971). A declared value beats an inherited one, so any token declared on
   `.bs-hero` is pinned there at its base value and no skin block can reach it.
   `--bs-hero-accent`'s only consumer IS in the hero, so it is declared on the
   widget alone and inherits down. `.bs-overlay` is excluded too: it renders no
   hero, so a declaration there would be a token with no consumer (§4).
   The consumer is written `var(--bs-hero-accent, var(--bs-orange))` so that a
   `.bs-hero` with no `.betsystem-widget` ancestor — which is every hero in
   frontend-demo/index.html, whose 19 roots are bare `<div data-betsystem>` —
   falls back to exactly what it renders today.
   Consumers: 1 (`.bs-hero h1 span`, :159). See T6.
   -------------------------------------------------------------------------- */
.betsystem-widget { --bs-hero-accent: var(--bs-orange); }


/* ----------------------------------------------------------------------------
   2. THE NINE DARK SKINS — well, field, gold-glow, hero accent, and two named
   ink corrections.
   These rules come AFTER :259-270 on purpose: that is the only way to extend a
   skin without editing it, and BRIEF rule 1 says append and override, never
   delete. Each well is that skin's own bg taken one step down, so a stage floor
   belongs to the palette it is in instead of being tiger's near-black wearing
   nine different costumes.

   HONEST NUMBER, because the previous draft implied more than it delivers:
   the maximum contrast ratio between any two of the nine dark wells is 1.023:1
   (emerald #020a06 vs mono #040405) and between any two fields 1.058:1. Contrast
   ratio is a LUMINANCE metric and these differ mostly in HUE, so they are not
   "identical" — but they are not a redesign either. The reason they cannot be
   bolder is structural and worth writing down: `.bs-felt` (:554) and ten other
   gradients run `var(--bs-elev) → var(--bs-well)`, so a well that rises above
   its own skin's `--bs-elev` inverts the ramp. neon's --bs-elev #1a1030 has a
   relative luminance of 0.0075; that is the ceiling. A genuinely per-skin stage
   floor needs `.bs-felt` restyled, not just a token — recorded in §4.

   `.bs-skin-tiger` is absent by design — its well IS #05070c, its field IS
   #0d121b, its gold IS #e7c07a and its hero accent IS `var(--bs-orange)`, so the
   base block above already states all four. The empty `.bs-skin-tiger { }` rule
   at :259 is left exactly as it is.

   TWO EXISTING TOKENS ARE OVERRIDDEN IN THIS FILE, not one: neon's
   `--bs-on-orange` here, and classic's `--bs-orange-br` in §3. Both are listed
   in §4.
   -------------------------------------------------------------------------- */

.bs-skin-neon {
  --bs-well: #05030c;  --bs-well-rgb: 5,3,12;   --bs-field: #100819;
  --bs-gold-rgb: 57,230,255;
  --bs-hero-accent: #ff5cb4;   /* #ff2e9a measures 2.70:1 on the hero's radial-lit
                                  surface — under the 3:1 large-text bar. 3.29:1. */
  /* #0a0410 measured 4.47:1 on this skin's own --bs-orange-dp #e0148a — three
     hundredths under AA for the 12.5px/900 boost button and the odds selection.
     #050208 measures 4.55:1 and is the same purple-black two shades down.
     THIS IS AN EXISTING TOKEN. It moves all 31 ink consumers of
     --bs-on-orange on this skin plus the six §3b substitutions. */
  --bs-on-orange: #050208;
}
.bs-skin-royal {
  --bs-well: #05040e;  --bs-well-rgb: 5,4,14;   --bs-field: #100d21;
  --bs-gold-rgb: 227,191,74;
  /* var(--bs-orange) #c9a227 measures 3.84:1 on the hero — kept. */
}
.bs-skin-emerald {
  --bs-well: #020a06;  --bs-well-rgb: 2,10,6;   --bs-field: #081611;
  --bs-gold-rgb: 159,240,200;
  /* var(--bs-orange) #1fbf75 measures 3.88:1 on the hero — kept. */
}
.bs-skin-sunset {
  --bs-well: #0a0403;  --bs-well-rgb: 10,4,3;   --bs-field: #190c0a;
  --bs-gold-rgb: 255,206,84;
  --bs-hero-accent: #ff7d63;   /* #ff5a3c is exactly 3.00:1 — no margin. 3.70:1. */
}
.bs-skin-ice {
  --bs-well: #03070c;  --bs-well-rgb: 3,7,12;   --bs-field: #0a111a;
  --bs-gold-rgb: 143,211,255;
  --bs-hero-accent: #5cb4ff;   /* #2f9dff 3.27 → 4.17. */
}
.bs-skin-mono {
  --bs-well: #040405;  --bs-well-rgb: 4,4,5;    --bs-field: #0c0c0f;
  --bs-gold-rgb: 189,189,196;
  /* var(--bs-orange) #e8e8ea measures 7.59:1 on the hero — kept. */
}
.bs-skin-midnight {
  --bs-well: #030409;  --bs-well-rgb: 3,4,9;    --bs-field: #0a0d18;
  --bs-gold-rgb: 185,196,255;
  --bs-hero-accent: #8aa2ff;   /* #6c8cff 3.02 — no margin. 3.84:1. */
}
.bs-skin-candy {
  --bs-well: #060409;  --bs-well-rgb: 6,4,9;    --bs-field: #120d19;
  --bs-gold-rgb: 46,230,200;
  --bs-hero-accent: #ff77a8;   /* #ff4d8d 2.96 — FAIL. 3.74:1. */
}


/* ----------------------------------------------------------------------------
   3. THE LIGHT SKIN — the only one that has to think.
   The opinionated call: white marble chrome, and THE WELL STAYS DARK. That is
   what a high-limit room looks like in daylight, and it buys something worth
   more than the aesthetic: because the well is dark on all ten skins, all 33
   well sites and every --bs-print pairing is correct BY CONSTRUCTION rather
   than by override. Nothing there can go dark-on-dark or white-on-white again.
   The price is that a dark stage inside a white card is a second lighting
   environment, and it needs its own ink and accent ramp — that is
   overrides.css §1, and it is not optional.
   -------------------------------------------------------------------------- */
.bs-skin-classic {
  --bs-well: #161d29;  --bs-well-rgb: 22,29,41;

  /* Not a near-black hole: a slate the page can see the edge of. --bs-print
     lands at 15.47:1 on it, and the 1px var(--bs-line) border those 33
     rules already carry frames it against the white card. */

  --bs-field: #e8ecf4;
  /* A trough, not a void. #141a24 ink on it is 14.74:1 (was 1.07:1 on the
     hardcoded #0d121b) and --bs-orange on it is 5.44:1 for the 24px/900 referral
     code. It sits only 1.18:1 below the white card, which is a SHADE and not a
     BOUNDARY — overrides.css §4.1 supplies the 3:1 boundary WCAG 1.4.11 wants
     for the five controls this token fills. See T2. */

  --bs-gold-ink: #7a5510;
  /* Surface-gold and text-gold split. #a9781a is a good jackpot plate and a bad
     label: 3.90:1 on the card. #7a5510 is 6.70:1 on the card and 6.20:1 on
     --bs-elev2. All 152 `color: var(--bs-gold)` lines read this; no gold
     SURFACE and no gold BORDER moves. See T5. */

  --bs-gold-rgb: 169,120,26;
  /* The nine gold glows follow the skin's gold rather than tiger's. */

  --bs-glass: linear-gradient(180deg, rgba(16,24,40,.07), rgba(16,24,40,.02));
  /* A white wash on a white card is nothing at all. #eeeff0 → #fafafb, and the
     `var(--bs-line)` border that `.bs-glass` already carries is lifted to 3.57:1
     inside a game modal by overrides.css §3. Re-aliased back to the white pair
     INSIDE a stage by overrides.css §1, because there the card is dark again.
     See T9. */

  --bs-hero-accent: #7fb3ff;
  /* The hero is hardcoded dark on every skin, so the light skin's accent has to
     run the other way here and only here. classic's --bs-orange #0a58ca measures
     1.44:1 on the hero's radial-lit surface; #7fb3ff measures 4.33:1. This is a
     coherence fix, not a contrast fix — today the hero renders TIGER on this
     skin like every other, at 3.93:1. See T6. */

  --bs-orange-br: #2569d0;
  /* Overriding an EXISTING token — one of two in this file (the other is neon's
     --bs-on-orange in §2). #2b74e0 under white ink is 4.49:1 — one hundredth
     under AA — and it is the top stop of the `.bs-odd-on` and `.bs-boost .add`
     gradients, i.e. the selected state of the sportsbook's primary control.
     #2569d0 is 5.24:1 and still 1.23:1 clear of --bs-orange so the gradient keeps
     its direction. Fifty sites read this token; the shift is 3% and it buys an
     AA pass on the two that carry text. */
}


/* ----------------------------------------------------------------------------
   4. WHAT IS DELIBERATELY *NOT* HERE — and why, so it does not come back
   ----------------------------------------------------------------------------
   Every token in this file has enumerated consumers in substitutions.md. These
   were proposed, priced, and left out because they do not:

   --bs-line-strong  A control-edge token introduced last time with an explicit
       WCAG 1.4.11 justification that it then missed in nine of ten skins
       (1.99–2.82:1 against the --bs-elev2 the controls are actually filled
       with). The requirement is real — the shipped --bs-line is 1.22–1.79:1 on
       every skin. This package does NOT close it product-wide. What it does
       instead is close it exactly where it wrote the components: the five
       `--bs-field` controls on classic (overrides.css §4.1, 3.57:1) and every
       border inside a game modal on classic (overrides.css §3, 3.57:1). A
       global token still needs `.bs-odd`, `.bs-cat`, `.bs-league`,
       `.bs-tabs button`, `.bs-pay`, `.bs-chip-amt` and `.bs-boost .add`
       restyled on nine dark skins, which is component work. Named, priced,
       and not shipped as a number without the components.
       (adversarial finding 4)

   --bs-r-base / --bs-r-1…6  The radius scale. `clamp(6px, var(--bs-radius,
       12px), 18px)` makes an operator's 0px "sharp corners" setting unreachable
       — the dial silently floors at 6px — and it re-values every button
       (7.2→9px) and the hero (18→16.08px) in a package that promises tiger is
       essentially unchanged. The three existing `--bs-radius` rules at :273-275
       are left exactly as they are. THE REAL DEFECT, stated here so it is not
       lost: those three fallbacks DISAGREE — `.bs-card` var(--bs-radius, 14px),
       `.bs-btn` calc(var(--bs-radius, 10px) * .72), `.bs-odd/.bs-boost/.bs-game/
       .bs-feat/.bs-promo` var(--bs-radius, 12px) — so the operator's dial is not
       neutral at ANY value: setting it to 12px moves the card 14→12 and the
       button 7.2→8.64 while `.bs-odd` stays put. Fixing that changes tiger
       geometry and belongs in its own commit with its own screenshots.
       (adversarial finding 18)

   --bs-plate  Proposed as a universal wash and then paired with --bs-print on
       `.bs-game-cat`, which computes to 1.10:1 on classic. `.bs-game-cat` is
       not on a well — it is on `.bs-game-thumb`, whose gradient is hardcoded —
       so it keeps its `#fff` on `rgba(0,0,0,.45)`, measured 18.99:1 over the
       dark end and 6.67:1 over the orange end. Leaving both alone is what keeps
       that pair correct; see substitutions.md §5.1. (adversarial finding 3)

   --bs-hi-rgb / --bs-lo-rgb and the six alpha steps  The right answer to 763
       hand-typed greyscale bevels and scrims. `.bs-glass` was pulled OUT of that
       deferral (T9) because it is a surface, not a bevel; the remaining 763 are
       out of scope for a package whose substitution list has to be
       site-by-site verifiable. Named here so the next pass starts from the
       census, not from scratch.

   --bs-orange-rgb / --bs-pos-rgb / --bs-neg-rgb / --bs-on-orange-rgb /
   --bs-live-rgb  The other five frozen glow families: `rgba(255,138,0,α)` ×21,
       `rgba(47,208,122,α)` ×18, `rgba(255,90,95,α)` ×12, `rgba(26,18,7,α)` ×4,
       `rgba(255,77,79,α)` ×2 — 57 sites. They have consumers; the previous
       draft's "adding six more with no consumers would be the same mistake as
       --bs-gold-ink shipping without one" was simply wrong about the facts.
       --bs-gold-rgb ships here because gold is the win channel and because
       `.bs-slot-win` (:280) is a line this package already edits. The other
       five are deferred on scope, not on principle, and this note is the
       correction of the premise.

   --bs-sky-0/1/2  The crash / limbo / ascend night sky. Its four hardcoded
       stops (#04070f, #050b1a, #071229, #0a1830) sit inside a 1.15:1 luminance
       band on every skin, so the most-watched surface in the product is one
       undifferentiated near-black with a white-dot starfield. That is a real
       finding and it is the highest visible return per line in the sheet; it is
       also a lighting model, not a token swap, and it is not in this commit.
       What IS in this commit is that the four sky stages keep their horizon on
       classic — overrides.css §1b — because substituting the bottom stop for
       classic's slate `--bs-well` inverted it (substitutions.md §4.3).

   --bs-heat / --bs-glow-* / --bs-motion / the type and spacing scales /
   the materials block  All would have had zero consumers in this commit.
       A token with no consumer is a comment that lints as code. Two such
       declarations were found in the previous draft of overrides.css §1
       (`--bs-field` and `--bs-live` inside the pit, whose consumers are all
       widget chrome that no game stage ever contains) and have been deleted.

   PER-SKIN --bs-pos / --bs-neg  Nine of ten skins inherit tiger's `#2fd07a`
       and `#ff5a5f`, so the win/loss channel is global while everything else is
       per-skin. On `mono` — a skin whose entire premise is greyscale —
       `--bs-gold` is #bdbdc4 and the inherited `--bs-neg` #ff5a5f is the only
       saturated colour in the skin, so on the settlement banner shared by six
       games (`.bs-crash-result-win { border-color: var(--bs-gold) }` :4076 vs
       `.bs-crash-result-bust { border-color: var(--bs-neg) }` :4079) LOSING IS
       LOUDER THAN WINNING. `.bs-crash-bustv` (:4080) also carries
       `box-shadow: 0 0 12px rgba(255,138,0,.35)` — a tiger-ORANGE halo on a red
       figure, on all ten skins. Both are real; both need a decision about the
       brand's red on nine skins, not a substitution. Recorded, not fixed.

   The two phantom classes `.bs-well` and `.bs-stage` are not styled anywhere in
   this package — they are emitted by neither file (0 hits in 13,011 lines of
   plugin JS, 0 in the CSS). The real names are per-game and are enumerated,
   grepped and listed in overrides.css §1. (adversarial finding 20)

   The invalid `--bs-line-strong:#476party` that shipped in the ice block of the
   earlier draft cannot recur: there is no --bs-line-strong, and every colour
   literal in this file was fed through a parser and a contrast calculator
   before it was written. (adversarial finding 17)

   THE TIGER-VISIBLE CHANGES — there are two, and they are named
   ------------------------------------------------------------
   The previous draft said "There isn't one in this file", which was true of the
   file and false of the package. Both of these are legibility corrections and
   both are computed:

   1. `.bs-tier-perk { opacity: .92 }` → `opacity: 1`
      (overrides.css §4.4, `:where(.bs-tier) .bs-tier-perk`, (0,1,0)).
      The 12px VIP perk line composites its ink at 92% over the tier gradient.
      Composited, `.bs-tier-2`'s perk is 4.37:1 on classic (FAIL) and
      `.bs-tier-3`'s is 4.23–4.45:1 on neon, midnight and sunset (FAIL ×3).
      At opacity 1 every one of them clears 4.5 and tiger moves 5.67→6.29
      (tier-2) and 6.37→7.09 (tier-3) — up, in both cases.
      STILL FAILING AFTER THIS, and recorded rather than papered over:
      `.bs-tier-1 .bs-tier-perk` is #101319 on the hardcoded silver gradient
      `#6b7178 → #9aa2b0` at 3.52:1 composited / 3.77:1 at opacity 1. Neither
      dark nor white ink clears 4.5 on that plate — white measures 4.93:1 at the
      dark end but 2.57:1 at the light end, so it is worse, not better. The
      silver tier needs a new gradient, on all ten skins, and that is not a
      token change.

   2. `.bs-plink-btn-ball` (:1731) and `.bs-craps-token` (:2083) stop reading
      `var(--bs-on-orange)` as a MATERIAL and take the literal `#1a1207`
      (substitutions.md §3g). Tiger's `--bs-on-orange` IS `#1a1207`, so tiger is
      byte-identical; the nine other dark skins move by a few units of near-black
      and classic stops rendering a 10px "shaded ball" as a flat white disc.

   Everything else in this package leaves `.bs-skin-tiger` byte-for-byte as it
   renders today, including substitutions.md §4.8: `.bs-odd:hover`'s hardcoded
   `#202a3a` is deliberately LEFT hardcoded, with the numbers, because no
   existing token substitutes for it without dropping `.bs-odd-price` under AA
   on six skins.
   -------------------------------------------------------------------------- */


/* Editable radius + font (fall back to defaults if not set) */
.bs-card { border-radius: var(--bs-radius, 14px); }
.bs-btn { border-radius: calc(var(--bs-radius, 10px) * .72); }
.bs-odd, .bs-boost, .bs-game, .bs-feat, .bs-promo { border-radius: var(--bs-radius, 12px); }
.betsystem-widget[style*="--bs-font"] { font-family: var(--bs-font), 'Inter', system-ui, sans-serif; }

/* Playable demo slot */
.bs-slot-msg { text-align:center; font-weight:800; margin:12px 0; min-height:22px; color:var(--bs-muted); }
.bs-slot-win { color:var(--bs-gold-ink); font-size:18px; text-shadow:0 0 18px rgba(var(--bs-gold-rgb),.5); }
.bs-slot-ctrls { display:flex; gap:10px; align-items:end; justify-content:center; }
.bs-slot-ctrls label { font-size:12px; color:var(--bs-muted); }
.bs-slot-ctrls input { width:90px; }
.bs-slot-ctrls .bs-btn { min-width:110px; }
.bs-slot-bal { text-align:center; margin-top:12px; color:var(--bs-muted); font-size:13px; }
.bs-demo-reel { animation: bs-reelpop .3s ease; }
@keyframes bs-reelpop { from { transform: scale(.96); opacity:.6 } to { transform: scale(1); opacity:1 } }

/* Bet builder */
.bs-odd-on { background:linear-gradient(180deg,var(--bs-orange-br),var(--bs-orange-dp)) !important; color:var(--bs-on-orange) !important; border-color:var(--bs-orange) !important; }
.bs-odd-on .bs-odd-name, .bs-odd-on .bs-odd-price, .bs-odd-on .bs-odd-bookmaker { color:var(--bs-on-orange) !important; }
.bs-bb-sum { display:flex; align-items:center; gap:14px; margin-top:12px; padding-top:12px; border-top:1px solid var(--bs-line); }
.bs-bb-sum small { display:block; font-size:10px; text-transform:uppercase; letter-spacing:.06em; color:var(--bs-muted); }
.bs-bb-sum b { font-size:22px; color:var(--bs-orange); }
.bs-bb-sum .bs-btn { margin-left:auto; }

/* Virtual racing */
.bs-vr-msg { font-weight:800; text-align:center; margin:10px 0 14px; min-height:22px; }
.bs-vr-runners { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.bs-vr-runner { display:flex; align-items:center; gap:10px; padding:11px 12px; border:1px solid var(--bs-line); border-radius:10px; background:var(--bs-elev2); color:var(--bs-text); cursor:pointer; text-align:left; transition:.14s; }
.bs-vr-runner:hover { border-color:var(--bs-orange); transform:translateY(-1px); }
.bs-vr-no { width:24px; height:24px; border-radius:50%; background:var(--bs-orange); color:var(--bs-on-orange); font-weight:900; display:flex; align-items:center; justify-content:center; font-size:12px; flex:none; }
.bs-vr-name { flex:1; font-weight:700; font-size:13px; }
.bs-vr-runner .bs-odd-price { color:var(--bs-orange); }
.bs-vr-win { border-color:var(--bs-gold) !important; box-shadow:0 0 18px rgba(var(--bs-gold-rgb),.4); }
.bs-vr-mine { border-color:var(--bs-muted); }
@media(max-width:520px){ .bs-vr-runners { grid-template-columns:1fr; } }

/* Cashier extras */
.bs-pays { display:flex; gap:6px; flex-wrap:wrap; margin-bottom:6px; }
.bs-pay { padding:8px 12px; border:1px solid var(--bs-line); background:var(--bs-elev2); color:var(--bs-text); border-radius:9px; font-weight:800; font-size:12px; cursor:pointer; }
.bs-pay.active { background:var(--bs-orange); color:var(--bs-on-orange); border-color:var(--bs-orange); }
.bs-quick { display:flex; gap:6px; margin:8px 0; }
.bs-chip-amt { padding:6px 12px; border:1px solid var(--bs-line); background:var(--bs-elev2); color:var(--bs-text); border-radius:999px; cursor:pointer; font-weight:700; }
.bs-kyc { margin-top:14px; padding-top:12px; border-top:1px solid var(--bs-line); }
.bs-kyc-box { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.bs-kyc-msg { color:var(--bs-orange); font-size:13px; }

/* Provably fair */
.bs-fair { margin-top:12px; font-size:11px; color:var(--bs-muted); border:1px solid var(--bs-line); border-radius:10px; padding:8px 12px; }
.bs-fair summary { cursor:pointer; font-weight:700; color:var(--bs-text); }
.bs-fair-row { margin-top:6px; word-break:break-all; }
.bs-fair code { color:var(--bs-orange); font-size:10px; }
.bs-fair-note { margin-top:6px; color:var(--bs-faint); }

/* Leaderboard */
.bs-lb-tabs { display:flex; justify-content:space-between; gap:10px; flex-wrap:wrap; margin-bottom:8px; }
.bs-lb-rank { font-weight:900; width:36px; }

/* Inbox */
.bs-note { border:1px solid var(--bs-line); border-radius:10px; padding:12px; margin-bottom:8px; background:var(--bs-elev2); cursor:pointer; }
.bs-note-unread { border-color:var(--bs-orange); }
.bs-note-h { display:flex; justify-content:space-between; align-items:center; gap:8px; }
.bs-note-b { font-size:13px; color:var(--bs-muted); margin-top:4px; }
.bs-note-t { font-size:11px; color:var(--bs-faint); margin-top:6px; }

/* VIP real */
.bs-vip-status { display:flex; justify-content:space-between; align-items:center; margin-bottom:12px; }
.bs-tier-on { outline:2px solid var(--bs-orange); outline-offset:1px; }

/* Casino tournaments */
.bs-pill-live { background: rgba(255,138,0,.16); color: var(--bs-orange); }
.bs-tours { display: flex; flex-direction: column; gap: 12px; }
.bs-tour { border: 1px solid var(--bs-line); border-radius: 14px; padding: 15px; background: var(--bs-elev2); }
.bs-tour-h { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.bs-tour-h strong { font-size: 15px; margin-right: 8px; }
.bs-tour-pool { text-align: right; line-height: 1.1; }
.bs-tour-pool span { font-size: 20px; font-weight: 800; color: var(--bs-pos); }
.bs-tour-pool small { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--bs-muted); }
.bs-tour-meta { display: flex; gap: 14px; flex-wrap: wrap; margin: 10px 0; font-size: 12px; color: var(--bs-muted); }
.bs-tour-foot { display: flex; gap: 8px; align-items: center; }
.bs-tour-board { margin-top: 12px; border-top: 1px solid var(--bs-line); padding-top: 10px; }
.bs-lb-me { outline: 2px solid var(--bs-orange); outline-offset: -2px; }
.bs-lb-me td { font-weight: 700; }

/* Affordability (open banking) inline */
.bs-afford-actions { display:flex; gap:8px; flex-wrap:wrap; margin-top:8px; }
.bs-afford-out { margin-top:8px; }

/* Live cash-out quote in My Bets */
.bs-cq { margin-top:6px; display:flex; gap:6px; flex-wrap:wrap; align-items:center; }
.bs-cq-prob { font-size:11px; color:var(--bs-muted); }
.bs-move { font-size:10px; padding:1px 6px; border-radius:999px; border:1px solid var(--bs-line); }
.bs-move-up { color:var(--bs-pos); border-color:rgba(47,208,122,.4); }
.bs-move-dn { color:var(--bs-live); border-color:rgba(255,77,79,.4); }

/* Two-factor auth (TOTP) */
.bs-2fa-on { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.bs-2fa-setup { border:1px solid var(--bs-line); border-radius:12px; padding:14px; background:var(--bs-elev2); }
.bs-2fa-key { display:inline-block; font-family:ui-monospace,Menlo,monospace; font-size:14px; letter-spacing:.14em;
  background:var(--bs-field); border:1px solid var(--bs-line); border-radius:8px; padding:9px 12px; word-break:break-all; }
.bs-2fa-confirm { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-top:8px; }
.bs-2fa-confirm input { width:150px; letter-spacing:.22em; text-align:center; font-size:16px; }
.bs-2fa-codes .bs-codes { display:grid; grid-template-columns:repeat(auto-fill,minmax(110px,1fr)); gap:7px; margin:10px 0; }
.bs-2fa-codes code { background:var(--bs-field); border:1px solid var(--bs-line); border-radius:7px; padding:7px 9px;
  font-family:ui-monospace,Menlo,monospace; font-size:13px; text-align:center; letter-spacing:.06em; }

/* Instant games (originals): Dice, Limbo, Crash, Mines, Plinko, Wheel, Keno, HiLo, Scratch */
.bs-row-tight { display:flex; gap:10px; align-items:end; justify-content:center; flex-wrap:wrap; margin-bottom:8px; }
.bs-row-tight label { font-size:12px; color:var(--bs-muted); display:flex; flex-direction:column; gap:4px; }
.bs-row-tight input { width:100px; }
.bs-toggle { display:flex; gap:6px; justify-content:center; margin-bottom:10px; }
.bs-toggle .bs-btn.active { outline:2px solid var(--bs-orange); outline-offset:1px; }
.bs-btn-win { background:linear-gradient(180deg, #38e08a, var(--bs-pos)); color:#06210f; }
.bs-btn-win:hover { filter:brightness(1.06); }

/* Crash */
.bs-crash-mult { font-size:40px; font-weight:900; letter-spacing:2px; color:var(--bs-text); transition:color .15s; }
.bs-crash-live { color:var(--bs-pos); text-shadow:0 0 22px rgba(47,208,122,.45); }

/* Mines */
.bs-mines-grid { display:grid; grid-template-columns:repeat(5,1fr); gap:6px; max-width:320px; margin:0 auto 12px; }
.bs-mine-tile { aspect-ratio:1; border:1px solid var(--bs-line); background:var(--bs-elev2); border-radius:8px;
  font-size:18px; cursor:pointer; color:var(--bs-text); }
.bs-mine-tile:hover:not(:disabled) { border-color:var(--bs-orange); }
.bs-mine-tile:disabled { cursor:default; }
.bs-mine-tile.revealed { background:var(--bs-elev); }
.bs-mine-tile.mine { background:rgba(255,90,95,.18); border-color:var(--bs-neg); }

/* Plinko */
.bs-plinko-path { text-align:center; padding:14px 8px; background:var(--bs-well); border:1px solid var(--bs-line);
  border-radius:12px; margin-bottom:10px; min-height:28px; line-height:1.9; word-spacing:2px; }
.bs-plinko-step { display:inline-block; font-size:15px; margin:0 1px; color:var(--bs-muted); }
.bs-plinko-step.right { color:var(--bs-pos); }
.bs-plinko-step.left { color:var(--bs-orange); }

/* Wheel */
.bs-wheel-strip { display:flex; gap:5px; overflow-x:auto; padding:10px 6px; background:var(--bs-well);
  border:1px solid var(--bs-line); border-radius:12px; margin-bottom:10px; }
.bs-wheel-seg { flex:0 0 auto; min-width:52px; text-align:center; padding:10px 6px; border-radius:8px;
  background:var(--bs-elev2); color:var(--bs-muted); font-weight:700; font-size:13px; }
.bs-wheel-seg.active { background:rgba(255,138,0,.2); color:var(--bs-orange); outline:2px solid var(--bs-orange); }

/* Keno */
.bs-keno-grid { display:grid; grid-template-columns:repeat(8,1fr); gap:5px; margin-bottom:10px; }
.bs-keno-num { aspect-ratio:1; border:1px solid var(--bs-line); background:var(--bs-elev2); border-radius:6px;
  font-size:12px; font-weight:700; cursor:pointer; color:var(--bs-text); }
.bs-keno-num:hover { border-color:var(--bs-orange); }
.bs-keno-num.picked { background:rgba(255,138,0,.22); border-color:var(--bs-orange); color:var(--bs-orange); }
.bs-keno-num.drawn { outline:2px solid var(--bs-muted); }
.bs-keno-num.hit { background:rgba(47,208,122,.25); border-color:var(--bs-pos); color:var(--bs-pos); outline:2px solid var(--bs-pos); }

/* HiLo */
.bs-hilo-card { font-size:38px; font-weight:800; letter-spacing:2px; }

/* Scratch card */
.bs-scratch-panels { display:flex; gap:8px; justify-content:center; margin-bottom:12px; }
.bs-scratch-panel { flex:1; max-width:110px; aspect-ratio:1; font-size:28px; border:2px dashed var(--bs-line);
  background:var(--bs-elev2); border-radius:10px; cursor:pointer; color:var(--bs-text); }
.bs-scratch-panel:hover:not(:disabled) { border-color:var(--bs-orange); }
.bs-scratch-panel.revealed { border-style:solid; background:var(--bs-elev); cursor:default; }

/* ============================================================================
   SHARED GAME VISUAL TOOLKIT — real dice / cards / coin, used across every
   instant game. Keep every accent on var(--bs-*) so all 10 skins keep working.
   ========================================================================== */

/* Dice */
.bs-dice-tray { display:flex; gap:12px; justify-content:center; align-items:center; padding:18px 8px;
  background:var(--bs-well); border:1px solid var(--bs-line); border-radius:12px; margin-bottom:10px; }
.bs-die { display:inline-block; filter:drop-shadow(0 6px 10px rgba(0,0,0,.45)); }
.bs-die-face { display:block; }
.bs-die.bs-die-rolling { animation:bs-die-tumble .55s cubic-bezier(.3,.6,.4,1) infinite; }
.bs-die.bs-die-landed { animation:bs-reelpop .35s cubic-bezier(.2,.9,.3,1.3); }
@keyframes bs-die-tumble { 0%{transform:rotate(0) scale(1)} 50%{transform:rotate(180deg) scale(.92)} 100%{transform:rotate(360deg) scale(1)} }

/* Playing cards */
.bs-pcard-row { display:flex; gap:8px; justify-content:center; flex-wrap:wrap; margin-bottom:10px; }
.bs-pcard { width:62px; height:88px; border-radius:9px; background:#fbf8f2; position:relative; flex:none;
  box-shadow:0 6px 16px rgba(0,0,0,.4), inset 0 0 0 1px rgba(0,0,0,.06);
  display:flex; align-items:center; justify-content:center; animation:bs-card-deal .32s cubic-bezier(.2,.9,.3,1.2); }
.bs-pcard-back { background:repeating-linear-gradient(135deg, var(--bs-orange) 0 7px, var(--bs-orange-dp) 7px 14px);
  box-shadow:0 6px 16px rgba(0,0,0,.4), inset 0 0 0 3px rgba(255,255,255,.18); }
.bs-pcard-red .bs-pcard-suit, .bs-pcard-red .bs-pcard-corner { color:#d1263b; }
.bs-pcard-black .bs-pcard-suit, .bs-pcard-black .bs-pcard-corner { color:#181818; }
.bs-pcard-suit { font-size:28px; line-height:1; }
.bs-pcard-corner { position:absolute; font-size:11px; font-weight:800; line-height:1.15; text-align:center; }
.bs-pcard-tl { top:6px; left:6px; }
.bs-pcard-br { bottom:6px; right:6px; transform:rotate(180deg); }
@keyframes bs-card-deal { from { transform:translateY(-14px) rotate(-3deg); opacity:0 } to { transform:none; opacity:1 } }

/* Coin */
.bs-coin-tray { display:flex; justify-content:center; padding:20px 8px; background:var(--bs-well); border:1px solid var(--bs-line); border-radius:12px; margin-bottom:10px; perspective:600px; }
.bs-coin { width:86px; height:86px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-size:15px; font-weight:900; text-transform:uppercase; letter-spacing:.03em;
  background:radial-gradient(circle at 35% 28%, var(--bs-gold), var(--bs-orange-dp) 75%); color:var(--bs-on-gold);
  box-shadow:0 10px 22px rgba(255,138,0,.35), inset 0 2px 5px rgba(255,255,255,.5), inset 0 -3px 6px rgba(0,0,0,.25); }
.bs-coin.bs-coin-flipping { animation:bs-coin-flip .8s cubic-bezier(.3,.55,.35,1); }
@keyframes bs-coin-flip { 0%{transform:rotateY(0) scale(1)} 45%{transform:rotateY(900deg) scale(1.08)} 100%{transform:rotateY(1440deg) scale(1)} }

/* Ascending trail (Crash / Limbo) */
.bs-ascend-stage { position:relative; height:150px; background:linear-gradient(180deg, #0a1830 0%, var(--bs-well) 85%);
  border:1px solid var(--bs-line); border-radius:12px; margin-bottom:10px; overflow:hidden; }
.bs-ascend-grid { position:absolute; inset:0; background-image:linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);
  background-size:24px 24px; }
.bs-ascend-trail { position:absolute; left:14px; bottom:14px; height:3px; border-radius:2px;
  background:linear-gradient(90deg, transparent, var(--bs-pos)); transform-origin:left center; }
.bs-ascend-craft { position:absolute; left:14px; bottom:14px; font-size:26px; line-height:1; transform:translate(-50%,50%);
  filter:drop-shadow(0 4px 8px rgba(0,0,0,.5)); transition:left .1s linear, bottom .1s linear; }
.bs-ascend-craft.bs-ascend-bust { animation:bs-ascend-burst .5s ease forwards; }
@keyframes bs-ascend-burst { 0%{transform:translate(-50%,50%) scale(1); opacity:1} 100%{transform:translate(-50%,50%) scale(2.2); opacity:0} }
.bs-ascend-mult { position:absolute; top:10px; left:0; right:0; text-align:center; font-size:34px; font-weight:900; color:var(--bs-text); text-shadow:0 2px 10px rgba(0,0,0,.6); }
.bs-ascend-mult.bs-ascend-live { color:var(--bs-pos); text-shadow:0 0 22px rgba(47,208,122,.5); }

/* Roulette wheel */
.bs-rw-stage { display:flex; justify-content:center; padding:14px 8px; background:var(--bs-well); border:1px solid var(--bs-line); border-radius:12px; margin-bottom:10px; }
.bs-rw-wheel-wrap { position:relative; width:180px; height:180px; }
.bs-rw-wheel { width:100%; height:100%; border-radius:50%; transition:transform 2.2s cubic-bezier(.15,.85,.25,1); }
.bs-rw-pointer { position:absolute; top:-6px; left:50%; transform:translateX(-50%); font-size:20px; z-index:2; filter:drop-shadow(0 2px 4px rgba(0,0,0,.6)); }
.bs-rw-hub { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:40px; height:40px; border-radius:50%;
  background:var(--bs-panel); border:2px solid var(--bs-orange); display:flex; align-items:center; justify-content:center;
  font-weight:900; font-size:15px; color:var(--bs-text); z-index:2; }
.bs-rw-red { fill:#c1272d; } .bs-rw-black { fill:#181818; } .bs-rw-green { fill:#0f8a4c; }

/* Prize wheel (the instant "Wheel" game) */
.bs-pw-stage { display:flex; justify-content:center; padding:14px 8px; background:var(--bs-well); border:1px solid var(--bs-line); border-radius:12px; margin-bottom:10px; }
.bs-pw-wrap { position:relative; width:190px; height:190px; }
.bs-pw-wheel { width:100%; height:100%; border-radius:50%; transition:transform 2.4s cubic-bezier(.12,.85,.2,1); }
.bs-pw-pointer { position:absolute; top:-6px; left:50%; transform:translateX(-50%); font-size:20px; z-index:2; filter:drop-shadow(0 2px 4px rgba(0,0,0,.6)); }

/* Plinko pegboard */
.bs-plink-board { position:relative; background:var(--bs-well); border:1px solid var(--bs-line); border-radius:12px; margin-bottom:10px; padding:10px 4px; overflow:hidden; }
.bs-plink-ball { position:absolute; width:12px; height:12px; border-radius:50%; background:radial-gradient(circle at 35% 30%,#fff,var(--bs-orange) 70%);
  box-shadow:0 0 8px rgba(255,138,0,.7); transition:left .28s cubic-bezier(.4,0,.2,1), top .28s cubic-bezier(.4,0,.2,1); }
.bs-plink-row { display:flex; justify-content:center; gap:16px; }
.bs-plink-peg { width:6px; height:6px; border-radius:50%; background:var(--bs-soft); }
.bs-plink-buckets { display:flex; gap:3px; margin-top:6px; }
.bs-plink-bucket { flex:1; text-align:center; font-size:10px; font-weight:800; padding:4px 2px; border-radius:5px; background:var(--bs-elev2); color:var(--bs-muted); }
.bs-plink-bucket.landed { background:rgba(255,138,0,.25); color:var(--bs-orange); outline:2px solid var(--bs-orange); }

/* Mines grid — upgraded tiles */
.bs-mine-tile { display:flex; align-items:center; justify-content:center; position:relative; overflow:hidden; }
.bs-mine-tile .bs-mine-icon { font-size:20px; animation:bs-reelpop .3s ease; }
.bs-mine-tile.mine { animation:bs-mine-shake .4s; }
@keyframes bs-mine-shake { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-3px)} 75%{transform:translateX(3px)} }

/* Keno ball draw */
.bs-keno-num.drawing { animation:bs-reelpop .25s ease; }

/* Scratch card — foil scratch-off surface */
.bs-scratch-panel { position:relative; }
.bs-scratch-panel canvas { position:absolute; inset:0; width:100%; height:100%; border-radius:8px; touch-action:none; cursor:pointer; }
.bs-scratch-panel .bs-scratch-prize { font-size:28px; }

@media (prefers-reduced-motion: reduce) {
  .bs-die.bs-die-rolling, .bs-coin.bs-coin-flipping, .bs-ascend-craft.bs-ascend-bust,
  .bs-pcard, .bs-mine-tile.mine, .bs-demo-reel, .bs-die.bs-die-landed { animation: none !important; }
  .bs-rw-wheel, .bs-pw-wheel, .bs-plink-ball, .bs-ascend-craft { transition: none !important; }
}

/* ============================================================================
   PREMIUM FX LAYER — shared celebration + surface treatments so every game
   reads as one product. Consumed via bsCelebrate() / bsCountUp() in JS.
   ========================================================================== */

/* Coin-shower burst. The modal is the positioning context. */
.bs-game-modal { position: relative; }
.bs-fx-burst { position:absolute; inset:0; pointer-events:none; overflow:hidden; z-index:5; border-radius:inherit; }
/* The celebration particle. Every value is a variable with the gold coin as
   its default, so anything that does not override them is unchanged — the
   per-game overrides live in the scenes block at the end of this file. */
.bs-fx-coin { position:absolute; top:-24px; display:block;
  width:var(--fx-w, 14px); height:var(--fx-h, 14px); border-radius:var(--fx-radius, 50%);
  background:var(--fx-ink, radial-gradient(circle at 34% 30%, #fff8dc, var(--bs-gold) 46%, var(--bs-orange-dp) 100%));
  box-shadow:var(--fx-shadow, 0 0 10px rgba(255,190,80,.65), inset 0 -2px 3px rgba(0,0,0,.3));
  animation-name:var(--fx-anim, bs-fx-fall); animation-timing-function:var(--fx-ease, cubic-bezier(.35,.1,.5,1));
  animation-fill-mode:forwards; }
@keyframes bs-fx-fall {
  0%   { transform:translate(0,0) rotate(0) scale(var(--bs-fx-scale,1)); opacity:0; }
  12%  { opacity:1; }
  100% { transform:translate(var(--bs-fx-drift,0), 420px) rotate(var(--bs-fx-rot,360deg)) scale(var(--bs-fx-scale,1)); opacity:0; }
}

/* Premium surfaces. --bs-felt-h lets a game tint the felt to its own identity
   while still deriving from the skin's own palette. */
.bs-felt { position:relative;
  background:
    radial-gradient(ellipse at 50% -10%, rgba(255,255,255,.07), transparent 60%),
    linear-gradient(180deg, var(--bs-elev), var(--bs-well) 90%);
  border:1px solid var(--bs-line); border-radius:14px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05), inset 0 -18px 34px rgba(0,0,0,.45); }
.bs-glass { background:var(--bs-glass);
  border:1px solid var(--bs-line); border-radius:12px; backdrop-filter:blur(3px); }
.bs-rail { height:3px; border-radius:2px; background:linear-gradient(90deg, transparent, var(--bs-orange), transparent); opacity:.5; }

/* Anticipation + emphasis */
.bs-fx-shimmer { position:relative; overflow:hidden; }
.bs-fx-shimmer::after { content:""; position:absolute; inset:0;
  background:linear-gradient(105deg, transparent 35%, rgba(255,255,255,.16) 50%, transparent 65%);
  transform:translateX(-100%); animation:bs-fx-sweep 1.25s linear infinite; }
@keyframes bs-fx-sweep { to { transform:translateX(100%); } }
.bs-fx-glow { animation:bs-fx-pulse 1.5s ease-in-out infinite; }
@keyframes bs-fx-pulse { 0%,100% { filter:drop-shadow(0 0 4px currentColor); } 50% { filter:drop-shadow(0 0 16px currentColor); } }
.bs-fx-pop { animation:bs-fx-popin .4s cubic-bezier(.2,.9,.3,1.4); }
@keyframes bs-fx-popin { from { transform:scale(.8); opacity:0; } to { transform:none; opacity:1; } }

/* The payout figure bsCountUp() writes into */
.bs-fx-payout { font-size:30px; font-weight:900; color:var(--bs-gold-ink); letter-spacing:-.01em;
  font-variant-numeric:tabular-nums; text-shadow:0 0 22px rgba(var(--bs-gold-rgb),.45); }

@media (prefers-reduced-motion: reduce) {
  .bs-fx-burst, .bs-fx-coin { display:none !important; }
  .bs-fx-shimmer::after, .bs-fx-glow, .bs-fx-pop { animation:none !important; }
}

/* ============================================================================
   CHINCHÓN — the Spanish deck (baraja española). The four suits map onto the
   familiar pips but keep Spanish-deck colouring (gold/red/blue/green) so it
   reads as a baraja rather than a poker deck.
   ========================================================================== */
.bs-sp-card { width:56px; height:80px; cursor:pointer; transition:transform .12s, box-shadow .12s; }
.bs-sp-card .bs-pcard-suit { font-size:24px; }
.bs-sp-row .bs-sp-card:hover { transform:translateY(-6px); }
.bs-sp-oros .bs-pcard-suit, .bs-sp-oros .bs-pcard-corner { color:#c8901a; }
.bs-sp-copas .bs-pcard-suit, .bs-sp-copas .bs-pcard-corner { color:#c0392b; }
.bs-sp-espadas .bs-pcard-suit, .bs-sp-espadas .bs-pcard-corner { color:#1f5f9e; }
.bs-sp-bastos .bs-pcard-suit, .bs-sp-bastos .bs-pcard-corner { color:#1d7a45; }
.bs-sp-joker { background:linear-gradient(145deg,#fdf6dd,#f3e2a8); }
.bs-sp-joker .bs-pcard-suit, .bs-sp-joker .bs-pcard-corner { color:#9a6b12; }
.bs-sp-empty { background:transparent; border:2px dashed var(--bs-line); box-shadow:none; animation:none; }
/* Held/selected + melded states reuse the same visual language as Video Poker. */
.bs-pcard-held { outline:3px solid var(--bs-orange); outline-offset:2px; transform:translateY(-8px); }
.bs-sp-melded { outline:2px solid var(--bs-pos); outline-offset:1px; }
.bs-sp-dim { opacity:.55; }

.bs-sp-table { display:flex; gap:14px; align-items:flex-end; justify-content:center; padding:12px 8px;
  background:var(--bs-well); border:1px solid var(--bs-line); border-radius:12px; margin-bottom:10px; }
.bs-sp-pile, .bs-sp-dwbox { display:flex; flex-direction:column; align-items:center; gap:5px; }
.bs-sp-pile-lbl { font-size:10px; text-transform:uppercase; letter-spacing:.08em; color:var(--bs-muted); font-weight:800; }
.bs-sp-count { font-size:12px; font-weight:800; color:var(--bs-muted); }
.bs-sp-dwbox { justify-content:center; min-width:74px; align-self:center; }
.bs-sp-dwval { font-size:30px; font-weight:900; color:var(--bs-text); line-height:1; }
.bs-sp-dwval.bs-sp-dwok { color:var(--bs-pos); text-shadow:0 0 16px rgba(47,208,122,.45); }
.bs-sp-seat { margin-bottom:10px; }
.bs-sp-seat-h { font-size:11px; text-transform:uppercase; letter-spacing:.07em; color:var(--bs-muted);
  font-weight:800; margin-bottom:6px; display:flex; gap:8px; align-items:baseline; }
.bs-sp-dw { color:var(--bs-faint); letter-spacing:0; text-transform:none; font-weight:600; }
.bs-sp-dealer-act { text-align:center; font-style:italic; }
.bs-sp-rules { line-height:1.55; }
@media (max-width:420px) { .bs-sp-card { width:46px; height:66px; } .bs-sp-card .bs-pcard-suit { font-size:19px; } }

/* ===== Mines — tile faces & board (visual upgrade) ===== */
.bs-mine-board { position:relative; padding:12px 10px 14px; margin-bottom:10px; border:1px solid var(--bs-line); border-radius:12px;
  background:radial-gradient(120% 90% at 50% 0%, rgba(255,138,0,.07), transparent 62%), var(--bs-well); }
.bs-mine-board .bs-mines-grid { margin-bottom:0; }
.bs-mine-board.bs-mine-busy .bs-mine-tile:not(.bs-mine-digging) { opacity:.72; pointer-events:none; }

.bs-mine-tile { background:linear-gradient(180deg, var(--bs-elev2) 0%, var(--bs-panel) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07), 0 3px 7px rgba(0,0,0,.4);
  transition:transform .12s ease, border-color .12s ease, box-shadow .12s ease, opacity .12s ease; }
.bs-mine-tile:hover:not(:disabled) { transform:translateY(-2px); box-shadow:inset 0 1px 0 rgba(255,255,255,.14), 0 6px 13px rgba(0,0,0,.45); }
.bs-mine-tile:active:not(:disabled) { transform:translateY(0) scale(.96); }
.bs-mine-cover { position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  background:linear-gradient(135deg, rgba(255,255,255,.075) 0 40%, rgba(255,255,255,0) 40% 60%, rgba(255,255,255,.035) 60% 100%); }
.bs-mine-cover::after { content:''; position:absolute; top:50%; left:50%; width:32%; height:32%;
  transform:translate(-50%,-50%) rotate(45deg); border:1px solid var(--bs-soft); border-radius:2px; opacity:.55; }
.bs-mine-tile:hover:not(:disabled) .bs-mine-cover::after { border-color:var(--bs-orange); opacity:.9; }

.bs-mine-tile.revealed { background:linear-gradient(180deg, rgba(47,208,122,.18), rgba(47,208,122,.05));
  border-color:rgba(47,208,122,.45); box-shadow:inset 0 0 12px rgba(47,208,122,.12); }
.bs-mine-tile.mine { background:radial-gradient(circle at 50% 45%, rgba(255,90,95,.38), rgba(255,90,95,.1) 72%);
  border-color:var(--bs-neg); box-shadow:inset 0 0 14px rgba(255,90,95,.28), 0 0 16px rgba(255,90,95,.2); }
.bs-mine-tile.bs-mine-ghost { background:var(--bs-elev); border-color:rgba(255,90,95,.3); box-shadow:none; }
.bs-mine-tile.bs-mine-ghost .bs-mine-icon { opacity:.3; filter:grayscale(.5); }

.bs-mine-tile .bs-mine-icon { position:relative; z-index:1; line-height:1; }
.bs-mine-tile .bs-mine-icon.bs-mine-gem { filter:drop-shadow(0 0 6px rgba(47,208,122,.55)); }
.bs-mine-tile .bs-mine-icon.bs-mine-bomb { filter:drop-shadow(0 0 7px rgba(255,90,95,.6)); }

.bs-mine-tile.bs-mine-digging { border-color:var(--bs-orange); animation:bs-mine-dig .7s ease-in-out infinite; }
@keyframes bs-mine-dig {
  0%,100% { box-shadow:inset 0 0 0 rgba(255,138,0,0), 0 3px 7px rgba(0,0,0,.4); }
  50% { box-shadow:inset 0 0 14px rgba(255,138,0,.5), 0 3px 7px rgba(0,0,0,.4); }
}

.bs-mine-stats { display:flex; flex-wrap:wrap; gap:6px; max-width:320px; margin:0 auto 10px; }
.bs-mine-stat { flex:1 1 66px; text-align:center; padding:7px 4px; border:1px solid var(--bs-line);
  border-radius:9px; background:var(--bs-elev2); }
.bs-mine-stat-l { display:block; font-size:9px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--bs-faint); }
.bs-mine-stat-v { display:block; margin-top:3px; font-size:13px; font-weight:800; color:var(--bs-text); }
.bs-mine-stat-v.bs-mine-safe { color:var(--bs-pos); }
.bs-mine-stat-v.bs-mine-danger { color:var(--bs-neg); }
.bs-mine-stat-v.bs-mine-mult { color:var(--bs-orange); }
.bs-mine-stat-v.bs-mine-pot { color:var(--bs-gold-ink); }

@media (prefers-reduced-motion: reduce) {
  .bs-mine-tile.bs-mine-digging, .bs-mine-tile .bs-mine-icon, .bs-mine-tile.mine { animation:none !important; }
  .bs-mine-tile, .bs-mine-tile:hover:not(:disabled) { transition:none; transform:none; }
}

/* Limbo — rocket climb toward the player's own target multiplier.
   Reuses the shared .bs-ascend-* stage (same as Crash); everything added here
   is scoped under .bs-limbo-* so Crash is untouched. */
.bs-limbo-stage { height:170px; }
.bs-limbo-stage .bs-ascend-grid { z-index:0; }
.bs-limbo-sky { position:absolute; inset:-24px 0 0; z-index:0; opacity:.75; pointer-events:none;
  background-image:
    radial-gradient(1.6px 1.6px at 14% 22%, rgba(255,255,255,.85), transparent 60%),
    radial-gradient(1.4px 1.4px at 38% 64%, rgba(255,255,255,.55), transparent 60%),
    radial-gradient(1.8px 1.8px at 63% 16%, rgba(255,255,255,.75), transparent 60%),
    radial-gradient(1.3px 1.3px at 81% 46%, rgba(255,255,255,.6), transparent 60%),
    radial-gradient(1.5px 1.5px at 92% 78%, rgba(255,255,255,.5), transparent 60%),
    radial-gradient(1.2px 1.2px at 26% 86%, rgba(255,255,255,.45), transparent 60%);
  animation:bs-limbo-drift 14s linear infinite; }
@keyframes bs-limbo-drift { from { transform:translateY(0); } to { transform:translateY(24px); } }
.bs-limbo-target { position:absolute; left:10px; right:10px; height:0; z-index:1;
  border-top:2px dashed var(--bs-orange); opacity:.85; }
.bs-limbo-target-tag { position:absolute; right:0; top:-10px; font-size:10px; font-weight:900; line-height:1.4;
  letter-spacing:.05em; text-transform:uppercase; white-space:nowrap; padding:2px 8px; border-radius:999px;
  color:var(--bs-orange); background:var(--bs-elev2); border:1px solid var(--bs-line); box-shadow:0 2px 6px rgba(0,0,0,.45); }
.bs-limbo-stage .bs-ascend-trail { z-index:2; }
.bs-limbo-stage.bs-limbo-lost .bs-ascend-trail { background:linear-gradient(90deg, transparent, var(--bs-neg)); }
.bs-limbo-stage .bs-ascend-craft { z-index:3;
  transition:left .45s cubic-bezier(.22,.9,.3,1), bottom .45s cubic-bezier(.22,.9,.3,1); }
.bs-limbo-stage .bs-ascend-craft.bs-limbo-climb { transition:left .12s linear, bottom .12s linear; }
.bs-limbo-stage .bs-ascend-craft.bs-limbo-busted { opacity:.3; filter:grayscale(1) drop-shadow(0 4px 8px rgba(0,0,0,.5)); }
.bs-limbo-stage .bs-ascend-mult { z-index:4; pointer-events:none; text-shadow:0 2px 12px rgba(0,0,0,.85); }
.bs-ascend-mult.bs-limbo-mult-lose { color:var(--bs-neg); text-shadow:0 0 20px rgba(255,90,95,.4); }
.bs-limbo-stage.bs-limbo-won { border-color:var(--bs-pos); box-shadow:inset 0 0 30px rgba(47,208,122,.18); }
.bs-limbo-stage.bs-limbo-won .bs-ascend-craft { animation:bs-limbo-cheer .55s ease .5s 2; }
@keyframes bs-limbo-cheer {
  0%, 100% { transform:translate(-50%,50%) scale(1); }
  50% { transform:translate(-50%,50%) scale(1.25); }
}
@media (prefers-reduced-motion: reduce) {
  .bs-limbo-sky, .bs-limbo-stage.bs-limbo-won .bs-ascend-craft { animation:none !important; }
  .bs-limbo-stage .bs-ascend-craft, .bs-limbo-stage .bs-ascend-craft.bs-limbo-climb { transition:none !important; }
}

/* ============================================================================
   KENO — draw board, lottery balls, ball-by-ball reveal
   Stage felt uses the same var(--bs-well) as the shared toolkit stages
   (.bs-dice-tray / .bs-plink-board / .bs-rw-stage); every other colour is a
   --bs-* token so all 10 skins keep driving it. The only fixed value is the
   printed ink on a ball face — a physical-object colour, like die pips.
   ========================================================================== */
.bs-keno-board { background:var(--bs-well); border:1px solid var(--bs-line); border-radius:12px;
  padding:10px; margin-bottom:10px; transition:box-shadow .3s ease; }
.bs-keno-board.is-win { box-shadow:0 0 0 1px var(--bs-pos), 0 0 26px -8px var(--bs-pos);
  animation:bs-keno-board-win .55s ease; }
@keyframes bs-keno-board-win { 0%{transform:scale(1)} 45%{transform:scale(1.012)} 100%{transform:scale(1)} }

/* Draw rail — the balls that have come out of the hopper so far. */
.bs-keno-rail { position:relative; overflow:hidden; display:flex; flex-wrap:wrap; gap:5px;
  align-items:center; justify-content:center; min-height:46px; padding:7px 8px; margin-bottom:8px;
  border:1px solid var(--bs-line); border-radius:10px; background:var(--bs-elev); }
.bs-keno-rail-hint { font-size:10px; font-weight:700; letter-spacing:.09em; text-transform:uppercase; color:var(--bs-faint); }
.bs-keno-rail.is-drawing::after { content:''; position:absolute; inset:0; pointer-events:none;
  background-image:linear-gradient(100deg, transparent 38%, rgba(255,255,255,.08) 50%, transparent 62%);
  animation:bs-keno-sweep 1.15s linear infinite; }
@keyframes bs-keno-sweep { from{transform:translateX(-70%)} to{transform:translateX(70%)} }
.bs-keno-slot { flex:none; width:30px; height:30px; border-radius:50%; border:1px dashed var(--bs-soft); opacity:.5; }

.bs-keno-ball { flex:none; width:30px; height:30px; border-radius:50%; display:flex; align-items:center;
  justify-content:center; font-size:12px; font-weight:900; letter-spacing:-.02em; color:var(--bs-on-gold);
  background-color:var(--bs-orange-dp);
  background-image:radial-gradient(circle at 34% 27%, var(--bs-gold), var(--bs-orange-dp) 78%);
  box-shadow:0 4px 10px rgba(0,0,0,.45), inset 0 2px 4px rgba(255,255,255,.45), inset 0 -3px 6px rgba(0,0,0,.28); }
.bs-keno-ball.hit { background-color:var(--bs-pos);
  background-image:radial-gradient(circle at 34% 27%, rgba(255,255,255,.85), rgba(255,255,255,0) 58%);
  box-shadow:0 4px 10px rgba(0,0,0,.45), 0 0 14px -4px var(--bs-pos), inset 0 -3px 6px rgba(0,0,0,.28); }
.bs-keno-ball-in { animation:bs-keno-ball-drop .34s cubic-bezier(.2,.9,.3,1.4); }
@keyframes bs-keno-ball-drop { 0%{transform:translateY(-16px) scale(.5); opacity:0}
  60%{transform:translateY(2px) scale(1.08); opacity:1} 100%{transform:none; opacity:1} }

/* Live picks / drawn / hits counters — updated in place during the reveal. */
.bs-keno-stats { display:flex; gap:6px; margin-bottom:8px; }
.bs-keno-stat { flex:1; display:flex; flex-direction:column; align-items:center; gap:1px;
  padding:5px 4px; border-radius:8px; background:var(--bs-elev2); border:1px solid var(--bs-line); }
.bs-keno-stat-v { font-size:15px; font-weight:900; line-height:1.1; color:var(--bs-text); }
.bs-keno-stat-k { font-size:9px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--bs-muted); }
.bs-keno-stat-hits .bs-keno-stat-v { color:var(--bs-pos); }

/* Ticket grid — tinting is done with a --bs-* overlay so skins drive it. */
.bs-keno-grid { gap:4px; margin-bottom:0; }
.bs-keno-num, .bs-keno-num.picked, .bs-keno-num.drawn, .bs-keno-num.hit {
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel)); }
.bs-keno-num { position:relative; overflow:hidden; display:flex; align-items:center; justify-content:center;
  padding:0; border-radius:8px; font-size:12px; font-weight:800;
  transition:transform .12s ease, box-shadow .15s ease, opacity .15s ease, border-color .15s ease; }
.bs-keno-num-v { position:relative; z-index:1; }
.bs-keno-num:hover { transform:translateY(-1px); border-color:var(--bs-orange); }
.bs-keno-num.picked { border-color:var(--bs-orange); color:var(--bs-orange); box-shadow:0 3px 9px rgba(0,0,0,.35); }
.bs-keno-num.picked::before { content:''; position:absolute; inset:0; background:var(--bs-orange); opacity:.22; }
.bs-keno-num.is-locked { opacity:.42; }
.bs-keno-num.is-locked:hover { transform:none; border-color:var(--bs-line); }
.bs-keno-num.drawn { outline:none; border-color:var(--bs-soft); color:var(--bs-muted);
  box-shadow:inset 0 0 0 2px var(--bs-soft); }
.bs-keno-num.hit { outline:none; border-color:var(--bs-pos); color:var(--bs-pos);
  box-shadow:inset 0 0 0 2px var(--bs-pos), 0 0 14px -4px var(--bs-pos); }
.bs-keno-num.hit::before { content:''; position:absolute; inset:0; background:var(--bs-pos); opacity:.24; }
.bs-keno-num.drawing { z-index:1; animation:bs-keno-num-pop .34s cubic-bezier(.2,.9,.3,1.45); }
@keyframes bs-keno-num-pop { 0%{transform:scale(.86)} 55%{transform:scale(1.18)} 100%{transform:scale(1)} }

@media (max-width: 420px) {
  .bs-keno-ball, .bs-keno-slot { width:26px; height:26px; font-size:11px; }
  .bs-keno-num { font-size:11px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-keno-rail.is-drawing::after, .bs-keno-ball-in, .bs-keno-num.drawing,
  .bs-keno-board.is-win { animation: none !important; }
  .bs-keno-num { transition: none !important; }
}

/* ---- PLINKO — real pegboard (chute → triangular peg field → bucket row) ----
   Geometry is percentage-based so the board, the pegs, the ball's real path and
   the bucket it lands in all stay on the same grid at any modal width: one
   bucket = 100/(rows+1) % of the board, one L/R deflection = half of that. */
.bs-plink-board { --bs-plink-fall: 88ms; padding: 12px 6px 8px;
  background-image: radial-gradient(120% 75% at 50% 0%, rgba(255,255,255,.07), rgba(255,255,255,0) 62%); }
.bs-plink-field { position: relative; height: clamp(190px, 56vw, 250px); }
.bs-plink-chute { position: absolute; top: -3px; left: 50%; transform: translateX(-50%); width: 36px; height: 10px;
  border: 1px solid var(--bs-line); border-top: 0; border-radius: 0 0 10px 10px;
  background: linear-gradient(180deg, var(--bs-elev2), var(--bs-elev)); }
.bs-plink-board .bs-plink-row { position: absolute; left: 0; right: 0; height: 0; display: block; gap: 0; }
.bs-plink-board .bs-plink-peg { position: absolute; top: 0; width: 5px; height: 5px;
  transform: translate(-50%, -50%); background: var(--bs-soft);
  box-shadow: 0 1px 1px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.35);
  transition: background .18s ease, box-shadow .18s ease, transform .18s ease; }
.bs-plink-board .bs-plink-peg.hit { background: var(--bs-gold); transform: translate(-50%,-50%) scale(1.55);
  box-shadow: 0 0 10px var(--bs-gold); }
.bs-plink-board .bs-plink-ball { width: 10px; height: 10px; z-index: 3; transform: translate(-50%, -50%);
  transition: left var(--bs-plink-fall) cubic-bezier(.45,.05,.55,.95), top var(--bs-plink-fall) cubic-bezier(.35,0,.75,1); }
.bs-plink-ball-ready { animation: bs-plink-ready 1.2s ease-in-out infinite; }
.bs-plink-ball-landed { animation: bs-plink-land .4s cubic-bezier(.2,.9,.3,1.4); }
@keyframes bs-plink-ready { 0%,100% { transform: translate(-50%,-50%) scale(1); } 50% { transform: translate(-50%,-34%) scale(1.14); } }
@keyframes bs-plink-land { 0% { transform: translate(-50%,-50%) scale(1); } 45% { transform: translate(-50%,-50%) scale(1.75); } 100% { transform: translate(-50%,-50%) scale(1); } }
.bs-plink-board .bs-plink-buckets { gap: 2px; margin-top: 9px; }
.bs-plink-board .bs-plink-bucket { position: relative; overflow: hidden; padding: 5px 0 6px; line-height: 1;
  font-size: clamp(7px, 2.1vw, 10px); border: 1px solid var(--bs-line); color: var(--bs-faint); }
.bs-plink-bucket::after { content: ''; position: absolute; inset: 0; background: var(--bs-orange); opacity: 0; }
.bs-plink-heat-1::after { opacity: .10; }
.bs-plink-heat-2::after { opacity: .20; }
.bs-plink-heat-3::after { opacity: .34; }
.bs-plink-board .bs-plink-heat-2, .bs-plink-board .bs-plink-heat-3 { color: var(--bs-text); }
.bs-plink-bucket-lbl { position: relative; z-index: 1; }
.bs-plink-board .bs-plink-bucket.landed { color: var(--bs-text); font-weight: 900; animation: bs-plink-bucket-hit .45s ease; }
.bs-plink-bucket.landed::after { opacity: .42; }
@keyframes bs-plink-bucket-hit { 0% { transform: translateY(-5px); } 55% { transform: translateY(3px) scale(1.06); } 100% { transform: translateY(0) scale(1); } }
.bs-plink-readout { text-align: center; font-size: 12px; font-weight: 800; letter-spacing: .02em;
  color: var(--bs-muted); min-height: 16px; margin-bottom: 8px; }
@media (prefers-reduced-motion: reduce) {
  .bs-plink-ball-ready, .bs-plink-ball-landed, .bs-plink-board .bs-plink-bucket.landed { animation: none !important; }
  .bs-plink-board .bs-plink-ball, .bs-plink-board .bs-plink-peg { transition: none !important; }
}

/* ---- COINFLIP — tossed two-sided coin ------------------------------------ */
.bs-coin-tray.bs-cf-tray { position:relative; flex-direction:column; align-items:center; justify-content:center;
  gap:12px; min-height:190px; padding:30px 12px 16px; overflow:hidden; }
.bs-coin-tray.bs-cf-tray::before { content:''; position:absolute; left:-10%; right:-10%; top:-34%; bottom:14%;
  background:radial-gradient(circle at 50% 46%, var(--bs-orange-dp), transparent 62%); opacity:.3; pointer-events:none; }
.bs-coin-tray.bs-cf-tray.is-win::before { background:radial-gradient(circle at 50% 46%, var(--bs-pos), transparent 62%);
  opacity:.34; animation:bs-cf-glow 1.1s ease-in-out 2; }
@keyframes bs-cf-glow { 0%,100%{opacity:.18} 50%{opacity:.46} }

.bs-cf-shadow { position:absolute; left:50%; bottom:38px; width:78px; height:12px; margin-left:-39px; border-radius:50%;
  background:rgba(0,0,0,.62); filter:blur(4px); z-index:0; }
.bs-cf-lift { position:relative; z-index:1; display:block; perspective:620px; }
.bs-coin-tray.bs-cf-tray.is-flipping .bs-cf-lift { animation:bs-cf-toss .8s cubic-bezier(.3,.55,.35,1) infinite; }
.bs-coin-tray.bs-cf-tray.is-flipping .bs-cf-shadow { animation:bs-cf-shadow-dip .8s cubic-bezier(.3,.55,.35,1) infinite; }
@keyframes bs-cf-toss { 0%,100%{transform:translateY(0)} 45%{transform:translateY(-24px)} }
@keyframes bs-cf-shadow-dip { 0%,100%{transform:scale(1); opacity:.62} 45%{transform:scale(.6); opacity:.24} }

.bs-coin.bs-cf-coin { position:relative; width:112px; height:112px; background:transparent;
  transform-style:preserve-3d; -webkit-transform-style:preserve-3d; }
/* keep it spinning if the network is still in flight — withMinDelay guarantees
   the floor of the toss, not the ceiling */
.bs-coin-tray.bs-cf-tray.is-flipping .bs-coin.bs-coin-flipping { animation-iteration-count:infinite; }
.bs-coin.bs-cf-coin.bs-cf-landed { animation:bs-cf-land .45s cubic-bezier(.2,.9,.3,1.25); }
@keyframes bs-cf-land { 0%{transform:translateY(-18px) rotateY(-160deg) scale(.88)} 58%{transform:translateY(0) rotateY(0deg) scale(1.07)} 100%{transform:none} }
.bs-coin.bs-cf-coin.is-good, .bs-coin.bs-cf-coin.is-win { outline:3px solid var(--bs-pos); outline-offset:6px; }
.bs-coin.bs-cf-coin.is-loss { outline:3px solid var(--bs-neg); outline-offset:6px; }

.bs-cf-side { position:absolute; inset:0; border-radius:50%; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:4px; color:var(--bs-on-gold);
  background:radial-gradient(circle at 35% 26%, var(--bs-gold), var(--bs-orange-dp) 78%);
  box-shadow:inset 0 2px 6px rgba(255,255,255,.5), inset 0 -4px 9px rgba(0,0,0,.28), inset 0 0 0 5px rgba(26,18,7,.1);
  backface-visibility:hidden; -webkit-backface-visibility:hidden; }
.bs-cf-front { transform:translateZ(1px); }
.bs-cf-back { transform:rotateY(180deg) translateZ(1px); }
.bs-cf-side::before { content:''; position:absolute; inset:9px; border-radius:50%;
  border:2px dotted rgba(26,18,7,.24); pointer-events:none; }
/* milled coin edge */
@supports ((-webkit-mask: radial-gradient(#000,#000)) or (mask: radial-gradient(#000,#000))) {
  .bs-cf-side::after { content:''; position:absolute; inset:0; border-radius:50%; pointer-events:none; opacity:.5;
    background:repeating-conic-gradient(from 0deg, rgba(26,18,7,.32) 0 4deg, rgba(255,255,255,.26) 4deg 8deg);
    -webkit-mask:radial-gradient(circle closest-side, transparent 0 calc(100% - 7px), #000 calc(100% - 7px) 100%);
    mask:radial-gradient(circle closest-side, transparent 0 calc(100% - 7px), #000 calc(100% - 7px) 100%); }
}
.bs-cf-art { display:block; }
.bs-cf-q { font-size:40px; font-weight:900; line-height:1; letter-spacing:0; opacity:.5; }
.bs-cf-name { font-size:10px; font-weight:900; letter-spacing:.11em; text-transform:uppercase; opacity:.74; }
.bs-cf-caption { position:relative; z-index:1; min-height:14px; font-size:11px; font-weight:800;
  letter-spacing:.09em; text-transform:uppercase; color:var(--bs-muted); text-align:center; }
.bs-coin-tray.bs-cf-tray.is-win .bs-cf-caption { color:var(--bs-pos); }

.bs-cf-streak { display:flex; align-items:center; gap:9px; margin:0 0 8px; padding:7px 10px;
  background:var(--bs-elev); border:1px solid var(--bs-line); border-radius:10px; }
.bs-cf-streak-lbl { font-size:10px; font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--bs-faint); }
.bs-cf-pips { display:flex; align-items:center; gap:5px; flex-wrap:wrap; flex:1; min-height:10px; }
.bs-cf-pip { box-sizing:border-box; width:10px; height:10px; border-radius:50%; flex:none; }
.bs-cf-pip.won { background:radial-gradient(circle at 35% 30%, var(--bs-gold), var(--bs-orange-dp)); }
.bs-cf-pip.next { border:1.5px dashed var(--bs-soft); animation:bs-pulse 1.5s ease-in-out infinite; }
.bs-cf-more { font-size:11px; font-weight:800; color:var(--bs-muted); }
.bs-cf-streak-n { font-size:13px; font-weight:900; color:var(--bs-text); font-variant-numeric:tabular-nums; }

.bs-cf-stats { display:flex; gap:8px; margin:0 0 4px; }
.bs-cf-stat { flex:1; display:flex; flex-direction:column; gap:2px; padding:8px 10px;
  background:var(--bs-elev2); border:1px solid var(--bs-line); border-radius:10px; }
.bs-cf-stat-k { font-size:10px; font-weight:800; letter-spacing:.09em; text-transform:uppercase; color:var(--bs-faint); }
.bs-cf-stat-v { font-size:16px; font-weight:900; color:var(--bs-text); font-variant-numeric:tabular-nums; }
.bs-cf-stat-win .bs-cf-stat-v { color:var(--bs-pos); }

.bs-cf-actions { flex-wrap:wrap; }
.bs-slot-ctrls .bs-cf-call { min-width:0; flex:1 1 40%; display:inline-flex; align-items:center; justify-content:center; gap:8px; }
.bs-slot-ctrls .bs-cf-cash { flex:1 1 100%; }
.bs-cf-call.is-calling { outline:2px solid var(--bs-gold); outline-offset:2px; }
.bs-cf-chip { width:22px; height:22px; flex:none; border-radius:50%; display:inline-flex; align-items:center; justify-content:center;
  background:rgba(0,0,0,.24); box-shadow:inset 0 1px 2px rgba(255,255,255,.22), inset 0 -1px 2px rgba(0,0,0,.25); }
.bs-cf-call-txt { line-height:1; }

@media (prefers-reduced-motion: reduce) {
  .bs-coin-tray.bs-cf-tray.is-flipping .bs-cf-lift,
  .bs-coin-tray.bs-cf-tray.is-flipping .bs-cf-shadow,
  .bs-coin-tray.bs-cf-tray.is-win::before,
  .bs-coin.bs-cf-coin.bs-cf-landed,
  .bs-cf-pip.next { animation:none !important; }
}

/* ============================================================================
   CRASH — ascending rocket stage (builds on the shared .bs-ascend-* scaffold)
   Position + multiplier are driven by ONE real elapsed-time clock in JS; this
   sheet only dresses it. Every brand colour stays on a --bs-* token.
   ========================================================================= */
.bs-crash-stage { height:220px; margin-bottom:12px;
  background:linear-gradient(180deg, #050b1a 0%, #0a1830 48%, var(--bs-well) 100%); }
/* night sky */
.bs-crash-stage::before { content:''; position:absolute; inset:0; pointer-events:none; opacity:.75;
  background-image:
    radial-gradient(1.6px 1.6px at 14% 20%, rgba(255,255,255,.80), transparent 60%),
    radial-gradient(1.2px 1.2px at 33% 11%, rgba(255,255,255,.60), transparent 60%),
    radial-gradient(1.8px 1.8px at 57% 25%, rgba(255,255,255,.55), transparent 60%),
    radial-gradient(1.2px 1.2px at 76% 13%, rgba(255,255,255,.70), transparent 60%),
    radial-gradient(1.4px 1.4px at 88% 33%, rgba(255,255,255,.50), transparent 60%),
    radial-gradient(1.2px 1.2px at 45% 42%, rgba(255,255,255,.40), transparent 60%),
    radial-gradient(1.5px 1.5px at 23% 52%, rgba(255,255,255,.35), transparent 60%); }
/* skin-tinted glow over the launch pad */
.bs-crash-horizon { position:absolute; left:0; right:0; bottom:0; height:48%; z-index:0; pointer-events:none;
  background:radial-gradient(120% 100% at 10% 100%, var(--bs-orange-dp), transparent 72%);
  opacity:.38; transition:opacity .3s ease; }
.bs-crash-stage.bs-crash-hot .bs-crash-horizon { opacity:.62; }

/* multiplier gridlines (2x / 5x / 10x), placed on the same log scale as the craft */
.bs-crash-gridline { position:absolute; left:0; right:0; height:0; z-index:1; pointer-events:none;
  border-top:1px dashed var(--bs-line); opacity:.7; font-style:normal; }
.bs-crash-gridline b { position:absolute; right:6px; top:-8px; padding:0 5px; border-radius:5px;
  font-size:10px; font-weight:800; line-height:16px; color:var(--bs-faint); background:rgba(0,0,0,.45); }

/* launch pad */
.bs-crash-pad { position:absolute; z-index:1; width:30px; height:9px; border-radius:50%;
  transform:translate(-50%,50%); pointer-events:none;
  background:radial-gradient(circle, var(--bs-orange) 0%, transparent 70%); opacity:.55; }

/* vapour trail */
.bs-crash-stage .bs-ascend-trail { height:4px; z-index:2; box-shadow:0 0 14px rgba(47,208,122,.45); }
.bs-crash-stage.bs-crash-flying .bs-ascend-trail { transition:width .1s linear, transform .1s linear; }
.bs-crash-stage.bs-crash-busted .bs-ascend-trail { box-shadow:0 0 14px rgba(255,90,95,.45);
  background:linear-gradient(90deg, transparent, var(--bs-neg)); }

/* the rocket */
.bs-crash-stage .bs-ascend-craft { font-size:30px; z-index:3; }
.bs-crash-glyph { display:inline-block; transform:rotate(-8deg); }
.bs-crash-stage.bs-crash-flying .bs-crash-glyph { animation:bs-crash-bob 1.1s ease-in-out infinite; }
@keyframes bs-crash-bob { 0%,100%{transform:rotate(-8deg) translateY(0)} 50%{transform:rotate(-3deg) translateY(-3px)} }
.bs-crash-flame { position:absolute; left:1px; bottom:0; width:15px; height:15px; border-radius:50%; opacity:0;
  background:radial-gradient(circle, var(--bs-gold) 0%, var(--bs-orange) 45%, transparent 72%); }
.bs-crash-stage.bs-crash-flying .bs-crash-flame,
.bs-crash-stage.bs-crash-igniting .bs-crash-flame { opacity:1; animation:bs-crash-thrust .26s ease-in-out infinite alternate; }
@keyframes bs-crash-thrust { from{transform:scale(.65) translate(-1px,1px); opacity:.55} to{transform:scale(1.3) translate(-5px,5px); opacity:.95} }
.bs-crash-stage.bs-crash-igniting .bs-ascend-craft { animation:bs-crash-shake .16s linear infinite; }
@keyframes bs-crash-shake { 0%,100%{transform:translate(-50%,50%)} 25%{transform:translate(-53%,52%)} 75%{transform:translate(-47%,48%)} }

/* the big number */
.bs-crash-stage .bs-ascend-mult { top:12px; font-size:36px; letter-spacing:1px; pointer-events:none;
  font-variant-numeric:tabular-nums; transition:color .18s ease; }
.bs-crash-stage.bs-crash-hot .bs-ascend-mult.bs-ascend-live { color:var(--bs-gold-ink); text-shadow:0 0 26px rgba(255,196,0,.45); }
.bs-crash-stage.bs-crash-busted .bs-ascend-mult { color:var(--bs-neg); text-shadow:0 0 22px rgba(255,90,95,.45); }

/* impact + the "it kept going" ghost marker after a successful cash-out */
.bs-crash-boom { position:absolute; z-index:4; font-size:34px; font-style:normal; line-height:1;
  transform:translate(-50%,50%); animation:bs-crash-boom .55s cubic-bezier(.2,.9,.3,1.3) forwards; }
@keyframes bs-crash-boom { 0%{transform:translate(-50%,50%) scale(.3); opacity:0} 35%{transform:translate(-50%,50%) scale(1.3); opacity:1} 100%{transform:translate(-50%,50%) scale(1); opacity:.92} }
.bs-crash-ghost { position:absolute; z-index:3; font-size:15px; font-style:normal; line-height:1; white-space:nowrap;
  transform:translate(-50%,50%); opacity:.5; }
.bs-crash-ghost b { margin-left:3px; font-size:10px; font-weight:800; vertical-align:middle; color:var(--bs-muted); }

/* MAX_MS auto-cash-out safety cap, shown as a fuse across the stage floor */
.bs-crash-cap { position:absolute; left:0; right:0; bottom:0; height:3px; z-index:4; background:rgba(255,255,255,.08); }
.bs-crash-cap-fill { display:block; width:0; height:100%; transition:width .1s linear;
  background:linear-gradient(90deg, var(--bs-orange), var(--bs-neg)); }
.bs-crash-cap-label { position:absolute; right:8px; bottom:9px; z-index:4; pointer-events:none;
  font-size:10px; font-weight:700; letter-spacing:.02em; color:var(--bs-faint); }
.bs-crash-cap-label b { color:var(--bs-muted); font-variant-numeric:tabular-nums; }

/* controls */
.bs-slot-ctrls .bs-crash-cash { display:inline-flex; flex-direction:column; align-items:center; gap:1px; min-width:152px; line-height:1.15; }
.bs-crash-cash-label { font-size:11px; font-weight:800; letter-spacing:.08em; text-transform:uppercase; opacity:.82; }
.bs-crash-cash-amt { font-size:17px; font-weight:900; font-variant-numeric:tabular-nums; }
.bs-crash-cash:not(:disabled) { animation:bs-crash-pulse 1.4s ease-in-out infinite; }
@keyframes bs-crash-pulse { 0%,100%{box-shadow:0 0 0 0 rgba(47,208,122,.45)} 60%{box-shadow:0 0 0 9px rgba(47,208,122,0)} }
.bs-crash-launch { font-weight:800; letter-spacing:.02em; }

@media (max-width:420px) {
  .bs-crash-stage { height:180px; }
  .bs-crash-stage .bs-ascend-mult { font-size:30px; }
  .bs-crash-stage .bs-ascend-craft { font-size:26px; }
}
@media (prefers-reduced-motion: reduce) {
  .bs-crash-stage.bs-crash-flying .bs-crash-glyph,
  .bs-crash-stage.bs-crash-flying .bs-crash-flame,
  .bs-crash-stage.bs-crash-igniting .bs-crash-flame,
  .bs-crash-stage.bs-crash-igniting .bs-ascend-craft,
  .bs-crash-boom,
  .bs-crash-cash:not(:disabled) { animation:none !important; }
  .bs-crash-stage.bs-crash-flying .bs-ascend-trail,
  .bs-crash-cap-fill, .bs-crash-horizon, .bs-crash-stage .bs-ascend-mult { transition:none !important; }
}


/* ---- Roulette: real 37-pocket European wheel + bet slip ------------------ */
/* Pocket paint (red/black/green) is a physical wheel material — like a die's
   ivory or a card's suit red — so it stays fixed across all 10 operator skins.
   Every other colour here is a var(--bs-*) token. */
.bs-rw-stage.bs-rw-felt { position:relative; padding:18px 8px 16px;
  background-image:radial-gradient(circle at 50% 42%, rgba(255,138,0,.12), transparent 62%),
    radial-gradient(circle at 50% 120%, rgba(255,255,255,.05), transparent 58%); }
.bs-rw-nums { position:absolute; top:0; left:0; right:0; bottom:0; display:block; }
.bs-rw-num { position:absolute; top:50%; left:50%; width:14px; height:11px; margin:-5.5px 0 0 -7px;
  font-size:8px; font-weight:800; line-height:11px; text-align:center; color:#fff;
  letter-spacing:-.02em; text-shadow:0 1px 1px rgba(0,0,0,.9); }
.bs-rw-rim { position:absolute; inset:0; border-radius:50%; pointer-events:none; z-index:1;
  box-shadow:inset 0 0 0 5px var(--bs-elev2), inset 0 0 0 7px rgba(0,0,0,.55),
    inset 0 0 20px rgba(0,0,0,.5), 0 14px 30px rgba(0,0,0,.55); }
.bs-rw-cone { position:absolute; top:50%; left:50%; width:96px; height:96px; margin:-48px 0 0 -48px;
  border-radius:50%; z-index:1; pointer-events:none;
  background:radial-gradient(circle at 50% 32%, var(--bs-elev2), var(--bs-panel) 72%);
  box-shadow:0 0 0 2px rgba(0,0,0,.45), inset 0 6px 14px rgba(0,0,0,.45); }
.bs-rw-ball { position:absolute; top:9px; left:50%; width:9px; height:9px; margin-left:-4.5px; border-radius:50%;
  background:radial-gradient(circle at 34% 30%, #fff, #b9bcc4 72%); box-shadow:0 2px 6px rgba(0,0,0,.65); z-index:3; }
.bs-rw-ball.bs-rw-ball-live { animation:bs-rw-ball-jig .42s ease-in-out infinite; }
@keyframes bs-rw-ball-jig { 0%,100%{ transform:translate(-7px,1px) } 50%{ transform:translate(7px,-1px) } }
/* Wind-up leg: same duration, accelerating curve; the landing leg falls back to
   the .bs-rw-wheel 2.2s ease-out already defined above. */
.bs-rw-wheel.bs-rw-launch { transition:transform 2.4s cubic-bezier(.32,.05,.62,.42); }

.bs-rw-result { display:flex; align-items:center; justify-content:center; gap:10px; margin-bottom:10px; }
.bs-rw-pocket { width:44px; height:44px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-size:19px; font-weight:900; color:#fff; animation:bs-reelpop .35s cubic-bezier(.2,.9,.3,1.3);
  box-shadow:0 6px 16px rgba(0,0,0,.45), inset 0 0 0 2px rgba(255,255,255,.22); }
.bs-rw-result-txt { font-size:12px; font-weight:800; letter-spacing:.06em; text-transform:uppercase; color:var(--bs-muted); }
.bs-rw-p-red { background:#c1272d; } .bs-rw-p-black { background:#181818; } .bs-rw-p-green { background:#0f8a4c; }

.bs-rw-history { display:flex; gap:5px; justify-content:center; flex-wrap:wrap; margin-bottom:10px; }
.bs-rw-hist { width:24px; height:24px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-size:11px; font-weight:800; color:#fff; opacity:.7; box-shadow:inset 0 0 0 1px rgba(255,255,255,.18); }
.bs-rw-hist:first-child { width:28px; height:28px; font-size:12px; opacity:1; animation:bs-reelpop .3s ease;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.3), 0 0 0 2px var(--bs-orange); }

.bs-rw-slip { display:flex; flex-direction:column; gap:5px; margin-bottom:10px; }
.bs-rw-slip-row { display:flex; align-items:center; gap:8px; padding:7px 10px; border-radius:9px;
  background:var(--bs-elev); border:1px solid var(--bs-line); font-size:13px; color:var(--bs-text); }
.bs-rw-slip-row.bs-rw-slip-hit { border-color:var(--bs-pos); background:rgba(47,208,122,.10); }
.bs-rw-slip-label { flex:1; font-weight:700; }
.bs-rw-slip-stake { font-weight:800; color:var(--bs-gold-ink); }
.bs-rw-slip-status { font-weight:800; }
.bs-rw-won { color:var(--bs-pos); } .bs-rw-lost { color:var(--bs-neg); }
.bs-rw-slip-x { padding:2px 8px; line-height:1.3; box-shadow:none; }
.bs-rw-slip-total { display:flex; justify-content:space-between; padding:2px 4px 0; font-size:12px; color:var(--bs-muted); }
.bs-rw-secttl { text-align:center; font-size:11px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--bs-faint); margin:10px 0 6px; }
.bs-rw-chip { position:relative; padding-left:26px; }
.bs-rw-chip::before { content:''; position:absolute; left:9px; top:50%; width:12px; height:12px; margin-top:-6px;
  border-radius:50%; box-shadow:inset 0 0 0 2px rgba(255,255,255,.4), 0 1px 3px rgba(0,0,0,.5); }
.bs-rw-chip-red::before { background:#c1272d; }
.bs-rw-chip-black::before { background:#181818; }
.bs-rw-spin-btn { min-width:150px; font-weight:900; letter-spacing:.06em; text-transform:uppercase; }

@media (prefers-reduced-motion: reduce) {
  .bs-rw-ball.bs-rw-ball-live, .bs-rw-pocket, .bs-rw-hist:first-child { animation:none !important; }
  .bs-rw-wheel.bs-rw-launch { transition:none !important; }
}


/* ---- Wheel (instant prize wheel) — real spinning wheel face -------------- */
.bs-pw-stage { padding:22px 8px 16px; }
.bs-pw-wrap { width:190px; height:190px; }
.bs-pw-pointer { top:-13px; font-size:22px; line-height:1; color:var(--bs-orange); }
.bs-pw-wheel { position:relative; overflow:hidden; background-color:var(--bs-elev2);
  box-shadow:inset 0 0 0 1px var(--bs-line), 0 14px 32px rgba(0,0,0,.55); will-change:transform; }
.bs-pw-wheel.bs-pw-winding { transition:transform .35s cubic-bezier(.4,0,.2,1); }
.bs-pw-rim { position:absolute; inset:-7px; border-radius:50%; pointer-events:none; border:5px solid var(--bs-elev);
  box-shadow:inset 0 0 0 2px var(--bs-soft), 0 10px 26px rgba(0,0,0,.45); }
.bs-pw-halo { position:absolute; inset:-7px; border-radius:50%; border:2px solid var(--bs-orange); opacity:0; pointer-events:none; }
.bs-pw-wrap.bs-pw-hit .bs-pw-rim { border-color:var(--bs-orange-dp); }
.bs-pw-wrap.bs-pw-hit .bs-pw-halo { animation:bs-pw-halo 1.1s ease-out 2; }
@keyframes bs-pw-halo { 0%{opacity:.9; transform:scale(1)} 100%{opacity:0; transform:scale(1.2)} }
.bs-pw-label { position:absolute; inset:0; display:flex; justify-content:center; align-items:flex-start; pointer-events:none; }
.bs-pw-label > span { margin-top:25px; font-size:10px; font-weight:800; line-height:1; white-space:nowrap;
  color:var(--bs-text); text-shadow:0 1px 2px rgba(0,0,0,.75); transform:rotate(-90deg); }
.bs-pw-label-top > span, .bs-pw-label-win > span { color:var(--bs-on-orange); text-shadow:none; }
.bs-pw-hub { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:54px; height:54px; border-radius:50%;
  background:linear-gradient(180deg, var(--bs-elev), var(--bs-panel)); border:2px solid var(--bs-orange); z-index:2;
  display:flex; align-items:center; justify-content:center; font-size:13px; font-weight:900; letter-spacing:-.02em;
  color:var(--bs-text); box-shadow:0 6px 16px rgba(0,0,0,.55); }
.bs-pw-t-hit { color:var(--bs-pos); } .bs-pw-t-low { color:var(--bs-muted); } .bs-pw-t-zero { color:var(--bs-neg); }
.bs-pw-hub.bs-pw-t-hit { border-color:var(--bs-pos); } .bs-pw-hub.bs-pw-t-zero { border-color:var(--bs-neg); }
.bs-pw-legend-head { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.08em; color:var(--bs-faint); margin:0 2px 5px; }
.bs-pw-seg-mult { display:block; font-size:13px; font-weight:800; line-height:1.1; }
.bs-pw-seg-odds { display:block; font-size:10px; font-weight:600; line-height:1.1; margin-top:3px; color:var(--bs-faint); }
.bs-wheel-seg.active .bs-pw-seg-mult, .bs-wheel-seg.active .bs-pw-seg-odds { color:var(--bs-orange); }
@media (max-width:400px) { .bs-pw-wrap { width:168px; height:168px; } .bs-pw-label > span { margin-top:21px; } }
@media (prefers-reduced-motion: reduce) {
  .bs-pw-wrap.bs-pw-hit .bs-pw-halo { animation:none !important; }
  .bs-pw-wheel, .bs-pw-wheel.bs-pw-winding { transition:none !important; }
}


/* ============================================================================
   Scratch card — a real foil scratch-off ticket. Every unopened panel carries an
   opaque <canvas> foil the player physically scratches away (destination-out
   brush); ~60% removed auto-pops the panel. Clicking still reveals instantly.
   ========================================================================== */
.bs-scratch-ticket { position:relative; background:linear-gradient(165deg, var(--bs-elev2), var(--bs-panel));
  border:1px solid var(--bs-line); border-radius:14px; padding:12px 12px 2px; margin-bottom:10px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 8px 20px rgba(0,0,0,.28); }
.bs-scratch-ticket::before { content:''; position:absolute; left:12px; right:12px; top:0; height:2px;
  background:repeating-linear-gradient(90deg, var(--bs-line) 0 5px, transparent 5px 10px); }
.bs-scratch-ticket.bs-scratch-won { border-color:var(--bs-pos); }
.bs-scratch-head { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:10px; }
.bs-scratch-tag { font-size:9px; font-weight:900; letter-spacing:.12em; text-transform:uppercase;
  padding:3px 9px; border-radius:999px; background:linear-gradient(180deg, var(--bs-orange-br), var(--bs-orange));
  color:var(--bs-on-orange); }
.bs-scratch-serial { font-size:10px; font-weight:700; letter-spacing:.1em; color:var(--bs-faint);
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace; }

.bs-scratch-panel { position:relative; overflow:hidden; padding:0; border-style:solid;
  display:flex; align-items:center; justify-content:center; box-shadow:inset 0 2px 8px rgba(0,0,0,.35); }
.bs-scratch-prize { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px; line-height:1; }
.bs-scratch-glyph { font-size:30px; line-height:1; filter:drop-shadow(0 3px 6px rgba(0,0,0,.45)); }
.bs-scratch-name { font-size:9px; font-weight:900; letter-spacing:.09em; text-transform:uppercase; color:var(--bs-muted); }
.bs-scratch-panel.revealed { animation:bs-reelpop .3s cubic-bezier(.2,.9,.3,1.3); }
.bs-scratch-panel.bs-scratch-hit { border-color:var(--bs-pos); background:var(--bs-elev2); }
.bs-scratch-panel.bs-scratch-hit .bs-scratch-name { color:var(--bs-pos); }
.bs-scratch-panel.bs-scratch-active { border-color:var(--bs-orange); }
.bs-scratch-panel.bs-scratch-active::after { content:''; position:absolute; inset:2px; border-radius:8px;
  border:2px solid var(--bs-orange); pointer-events:none; z-index:3; animation:bs-scratch-ring 1.9s ease-in-out infinite; }
@keyframes bs-scratch-ring { 0%,100%{ opacity:.12; transform:scale(.97) } 50%{ opacity:.6; transform:scale(1) } }

.bs-scratch-panel canvas { z-index:2; transition:opacity .28s ease; cursor:grab; }
.bs-scratch-panel canvas:active { cursor:grabbing; }
.bs-scratch-panel canvas.bs-scratch-idle { pointer-events:none; cursor:default; }
.bs-scratch-panel canvas.bs-scratch-cleared { opacity:0; }

.bs-scratch-panel.bs-scratch-printing::before { content:''; position:absolute; inset:0; z-index:4;
  background:linear-gradient(105deg, transparent 38%, var(--bs-soft) 50%, transparent 62%); opacity:.7;
  animation:bs-scratch-print 1.1s linear infinite; }
@keyframes bs-scratch-print { from { transform:translateX(-105%) } to { transform:translateX(105%) } }
.bs-scratch-tip { font-size:11px; color:var(--bs-faint); }

@media (prefers-reduced-motion: reduce) {
  .bs-scratch-panel.bs-scratch-active::after, .bs-scratch-panel.bs-scratch-printing::before,
  .bs-scratch-panel.revealed { animation:none !important; }
  .bs-scratch-panel canvas { transition:none !important; }
}


/* ============================================================================
   CARD GAMES — real felt tables for HiLo / Blackjack / Baccarat / Video Poker.
   Every colour is a --bs-* token so all 10 skin presets keep working; the only
   fixed colours are inside cardFaceHtml() itself (real card stock, not brand).
   ========================================================================== */
.bs-felt { position:relative; padding:14px 12px 12px; margin-bottom:10px; border:1px solid var(--bs-line);
  border-radius:14px; box-shadow:inset 0 0 44px rgba(0,0,0,.5);
  background:radial-gradient(120% 90% at 50% -20%, var(--bs-elev2), var(--bs-elev) 55%, var(--bs-panel) 100%); }
.bs-felt::before { content:''; position:absolute; inset:7px; border:1px dashed var(--bs-line); border-radius:10px;
  opacity:.5; pointer-events:none; }
.bs-felt-label { position:relative; display:flex; align-items:center; justify-content:space-between; gap:8px;
  margin:0 4px 7px; font-size:10px; font-weight:900; letter-spacing:.13em; text-transform:uppercase; color:var(--bs-muted); }
.bs-felt .bs-pcard-row { position:relative; margin-bottom:0; min-height:88px; align-items:center; }

/* Empty seat outline + "cards in flight" placeholder */
.bs-pcard-slot { width:62px; height:88px; flex:none; border-radius:9px;
  border:1px dashed var(--bs-line); background:rgba(0,0,0,.18); }
.bs-deal-pulse { display:inline-flex; animation:bs-deal-pulse 1.05s ease-in-out infinite; }
.bs-deal-pulse:nth-child(2) { animation-delay:.12s; }
.bs-deal-pulse:nth-child(3) { animation-delay:.24s; }
.bs-deal-pulse:nth-child(4) { animation-delay:.36s; }
.bs-deal-pulse:nth-child(5) { animation-delay:.48s; }
@keyframes bs-deal-pulse { 0%,100% { transform:translateY(0); opacity:.85 } 50% { transform:translateY(-7px); opacity:1 } }

/* ---- HiLo: one hero card next to the shoe -------------------------------- */
.bs-hilo-stage { position:relative; display:flex; align-items:center; justify-content:center; gap:22px; min-height:172px; }
.bs-hilo-big { display:inline-flex; }
.bs-hilo-big .bs-pcard, .bs-hilo-big .bs-pcard-slot { width:112px; height:158px; border-radius:13px; }
.bs-hilo-big .bs-pcard { box-shadow:0 14px 28px rgba(0,0,0,.5), inset 0 0 0 1px rgba(0,0,0,.07); }
.bs-hilo-big .bs-pcard-suit { font-size:56px; }
.bs-hilo-big .bs-pcard-corner { font-size:17px; line-height:1.1; }
.bs-hilo-big .bs-pcard-tl { top:9px; left:10px; }
.bs-hilo-big .bs-pcard-br { bottom:9px; right:10px; }
.bs-hilo-deck { position:relative; display:inline-flex; width:56px; height:80px; flex:none; }
.bs-hilo-deck .bs-pcard { position:absolute; width:56px; height:80px; border-radius:8px; }
.bs-hilo-deck .bs-pcard:nth-child(1) { left:7px; top:7px; opacity:.5; }
.bs-hilo-deck .bs-pcard:nth-child(2) { left:0; top:0; }
.bs-hilo-incoming { animation:bs-hilo-peek 1s ease-in-out infinite; }
@keyframes bs-hilo-peek { 0%,100% { transform:translateY(0) rotate(0) } 50% { transform:translateY(-11px) rotate(-4deg) } }
.bs-hilo-meter { display:flex; flex-wrap:wrap; gap:8px; justify-content:center; margin-bottom:2px; }
.bs-hilo-chip { display:inline-flex; align-items:baseline; gap:6px; padding:5px 12px; border-radius:999px;
  background:var(--bs-elev2); border:1px solid var(--bs-line); color:var(--bs-muted);
  font-size:10px; font-weight:800; letter-spacing:.08em; text-transform:uppercase; }
.bs-hilo-chip b { font-size:13px; letter-spacing:0; color:var(--bs-text); }
.bs-hilo-chip.up b { color:var(--bs-pos); }
.bs-hilo-actions { display:flex; gap:10px; justify-content:center; margin-bottom:10px; }
.bs-hilo-actions .bs-btn { flex:1; max-width:165px; display:inline-flex; align-items:center; justify-content:center;
  gap:7px; padding:12px 14px; font-size:15px; }
.bs-hilo-arrow { font-size:12px; opacity:.85; }
.bs-hilo-cash { flex:1; max-width:340px; }

/* ---- Blackjack: two seats on one felt ------------------------------------ */
.bs-bj-seat + .bs-bj-seat { margin-top:12px; padding-top:12px; border-top:1px dashed var(--bs-line); }
.bs-bj-total { min-width:32px; padding:2px 9px; border-radius:999px; text-align:center; letter-spacing:0;
  background:var(--bs-elev2); border:1px solid var(--bs-line); color:var(--bs-text); font-size:12px; font-weight:900; }
.bs-bj-total.win { color:var(--bs-pos); border-color:var(--bs-pos); }
.bs-bj-total.bust { color:var(--bs-neg); border-color:var(--bs-neg); }
.bs-bj-hole { display:inline-flex; }

/* ---- Baccarat: player / banker boxes -------------------------------------- */
.bs-bac-boxes { position:relative; display:flex; gap:10px; }
.bs-bac-box { flex:1; min-width:0; padding:8px 6px 6px; border-radius:12px; border:1px solid var(--bs-line);
  background:rgba(0,0,0,.2); transition:border-color .18s, box-shadow .18s; }
.bs-bac-box.win { border-color:var(--bs-orange); box-shadow:inset 0 0 0 1px var(--bs-orange), 0 0 22px -6px var(--bs-orange); }
.bs-bac-box .bs-pcard-row { gap:5px; min-height:70px; }
.bs-bac-box .bs-pcard, .bs-bac-box .bs-pcard-slot { width:48px; height:70px; border-radius:7px; }
.bs-bac-box .bs-pcard-suit { font-size:22px; }
.bs-bac-box .bs-pcard-corner { font-size:9px; }
.bs-bac-box .bs-pcard-tl { top:4px; left:5px; }
.bs-bac-box .bs-pcard-br { bottom:4px; right:5px; }
.bs-bac-pts { min-width:26px; padding:2px 8px; border-radius:999px; text-align:center; letter-spacing:0;
  background:var(--bs-elev2); border:1px solid var(--bs-line); color:var(--bs-text); font-size:12px; font-weight:900; }
.bs-bac-box.win .bs-bac-pts { color:var(--bs-orange); border-color:var(--bs-orange); }
.bs-bac-result { position:relative; margin-top:10px; text-align:center; color:var(--bs-orange);
  font-size:11px; font-weight:900; letter-spacing:.14em; text-transform:uppercase; }
.bs-bac-spots { display:flex; gap:8px; margin-bottom:10px; }
.bs-bac-spot { flex:1; padding:11px 6px; border-radius:12px; border:1px solid var(--bs-line);
  background:var(--bs-elev2); color:var(--bs-text); font-family:inherit; font-size:12px; font-weight:900;
  letter-spacing:.08em; text-transform:uppercase; cursor:pointer; transition:.15s; }
.bs-bac-spot:hover:not(:disabled) { border-color:var(--bs-orange); color:var(--bs-orange); transform:translateY(-1px); }
.bs-bac-spot:disabled { opacity:.45; cursor:default; }
.bs-bac-bets { display:flex; flex-wrap:wrap; gap:6px; justify-content:center; margin-bottom:10px; }
.bs-bac-bet { display:inline-flex; align-items:center; gap:6px; padding:5px 10px; border-radius:999px;
  background:var(--bs-elev2); border:1px solid var(--bs-line); color:var(--bs-text); font-size:11px; font-weight:800; }
.bs-bac-bet b { color:var(--bs-pos); }
.bs-bac-bet.won { border-color:var(--bs-pos); }
.bs-bac-bet.lost { opacity:.5; color:var(--bs-muted); text-decoration:line-through; }
.bs-bac-chip { width:10px; height:10px; flex:none; border-radius:50%; box-shadow:inset 0 0 0 1px rgba(0,0,0,.35);
  background:radial-gradient(circle at 34% 30%, var(--bs-gold), var(--bs-orange-dp) 78%); }
.bs-bac-x { margin:0; padding:0 0 0 2px; border:0; background:none; color:var(--bs-muted);
  font-size:12px; line-height:1; cursor:pointer; }
.bs-bac-x:hover { color:var(--bs-neg); }
.bs-bac-empty { text-align:center; }

/* ---- Video poker: tap-to-hold cards + rank ladder -------------------------- */
.bs-vp-ranks { display:flex; flex-wrap:wrap; gap:4px; justify-content:center; margin-bottom:10px; }
.bs-vp-rank { padding:3px 8px; border-radius:7px; border:1px solid var(--bs-line); background:var(--bs-elev2);
  color:var(--bs-faint); font-size:9px; font-weight:800; letter-spacing:.04em; }
.bs-vp-rank.hit { background:var(--bs-orange); border-color:var(--bs-orange); color:var(--bs-on-orange); }
.bs-vp-hand { position:relative; display:flex; flex-wrap:wrap; gap:7px; justify-content:center;
  align-items:flex-end; min-height:96px; padding-top:8px; }
.bs-vp-slot { position:relative; margin:0; padding:0; border:0; background:none; line-height:0; cursor:pointer; }
.bs-vp-slot:disabled { cursor:default; }
.bs-vp-slot .bs-pcard { transition:transform .14s ease; }
.bs-vp-slot:not(:disabled):hover .bs-pcard { transform:translateY(-6px); }
.bs-vp-slot.bs-pcard-held .bs-pcard { outline:3px solid var(--bs-orange); outline-offset:2px; }
.bs-vp-badge { position:absolute; top:-9px; left:50%; transform:translateX(-50%); z-index:3; white-space:nowrap;
  padding:2px 7px; border-radius:999px; background:var(--bs-orange); color:var(--bs-on-orange);
  font-size:9px; font-weight:900; letter-spacing:.12em; line-height:1.4; }
.bs-vp-result { text-align:center; font-weight:900; letter-spacing:.06em; color:var(--bs-gold-ink); }

@media (max-width:430px) {
  .bs-felt .bs-pcard, .bs-felt .bs-pcard-slot { width:48px; height:68px; border-radius:8px; }
  .bs-felt .bs-pcard-suit { font-size:21px; }
  .bs-felt .bs-pcard-corner { font-size:8px; }
  .bs-felt .bs-pcard-tl { top:4px; left:4px; }
  .bs-felt .bs-pcard-br { bottom:4px; right:4px; }
  .bs-felt .bs-pcard-row { min-height:68px; gap:6px; }
  .bs-hilo-stage { gap:14px; min-height:150px; }
  .bs-hilo-big .bs-pcard, .bs-hilo-big .bs-pcard-slot { width:96px; height:136px; border-radius:12px; }
  .bs-hilo-big .bs-pcard-suit { font-size:46px; }
  .bs-hilo-big .bs-pcard-corner { font-size:15px; }
  .bs-hilo-deck, .bs-hilo-deck .bs-pcard { width:46px; height:66px; }
  .bs-bac-box .bs-pcard, .bs-bac-box .bs-pcard-slot { width:38px; height:54px; border-radius:6px; }
  .bs-bac-box .bs-pcard-suit { font-size:17px; }
  .bs-bac-box .bs-pcard-row { gap:4px; min-height:54px; }
  .bs-vp-hand { gap:5px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-deal-pulse, .bs-hilo-incoming { animation:none !important; }
  .bs-vp-slot .bs-pcard, .bs-bac-box, .bs-bac-spot { transition:none !important; }
}


/* ============================================================================
   DICE / CRAPS / SIC BO — real dice tables + a percentile win-zone track.
   Every accent stays on var(--bs-*) so all 10 skin presets keep working; the
   only hardcoded values are the physical die pips and the #fff specular highlight; the inner well is var(--bs-well), which every other stage
   class already uses and the #fff specular highlight on the marker.
   ========================================================================== */

/* ---- Dice: slot-style percentile readout ---------------------------------- */
.bs-dice-stage { background:var(--bs-well); border:1px solid var(--bs-line); border-radius:12px; padding:16px 14px 12px; margin-bottom:10px; }
.bs-dice-readout { display:flex; justify-content:center; align-items:flex-end; gap:5px; margin-bottom:18px; }
.bs-dice-digit { display:inline-flex; align-items:center; justify-content:center; box-sizing:border-box; min-width:46px; height:64px; border-radius:9px;
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel)); border:1px solid var(--bs-line);
  box-shadow:inset 0 -10px 16px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.06);
  font-size:36px; font-weight:900; line-height:1; color:var(--bs-text); font-variant-numeric:tabular-nums; }
.bs-dice-digit.bs-dice-dot { min-width:14px; align-items:flex-end; padding-bottom:13px; background:none; border:0; box-shadow:none; color:var(--bs-muted); }
.bs-dice-readout.bs-dice-spinning .bs-dice-digit { color:var(--bs-muted); animation:bs-dice-digit-roll .16s linear infinite; }
.bs-dice-readout.bs-dice-spinning .bs-dice-digit.bs-dice-dot { animation:none; }
.bs-dice-readout.bs-dice-landed .bs-dice-digit { animation:bs-dice-settle .34s cubic-bezier(.2,.9,.3,1.3); }
.bs-dice-readout.bs-dice-hit .bs-dice-digit { color:var(--bs-pos); border-color:var(--bs-pos); text-shadow:0 0 18px currentColor; }
.bs-dice-readout.bs-dice-miss .bs-dice-digit { color:var(--bs-muted); }
@keyframes bs-dice-digit-roll { 0%{transform:translateY(-22%); opacity:.4} 50%{transform:translateY(0); opacity:1} 100%{transform:translateY(22%); opacity:.4} }
@keyframes bs-dice-settle { from{transform:scale(.88); opacity:.35} to{transform:none; opacity:1} }

/* ---- Dice: win-zone track ------------------------------------------------- */
.bs-dice-track-wrap { position:relative; height:20px; margin:0 8px; }
.bs-dice-track { position:absolute; left:0; right:0; top:6px; height:8px; border-radius:999px; overflow:hidden;
  border:1px solid var(--bs-line); box-shadow:inset 0 2px 5px rgba(0,0,0,.55); }
.bs-dice-track-fill { display:block; width:100%; height:100%; opacity:.72; }
.bs-dice-tick { position:absolute; top:0; width:2px; height:20px; margin-left:-1px; border-radius:1px;
  background:var(--bs-orange); color:var(--bs-orange); filter:drop-shadow(0 0 4px currentColor); }
.bs-dice-marker { position:absolute; top:2px; width:16px; height:16px; margin-left:-8px; border-radius:50%;
  background:radial-gradient(circle at 35% 30%, #fff, currentColor 72%);
  box-shadow:0 2px 6px rgba(0,0,0,.55); filter:drop-shadow(0 0 6px currentColor);
  animation:bs-dice-drop .42s cubic-bezier(.2,.9,.3,1.3); }
.bs-dice-marker-win { color:var(--bs-pos); }
.bs-dice-marker-lose { color:var(--bs-neg); }
@keyframes bs-dice-drop { from{transform:translateY(-16px) scale(.5); opacity:0} to{transform:none; opacity:1} }
.bs-dice-scale { display:flex; justify-content:space-between; align-items:center; gap:8px; margin-top:9px;
  font-size:11px; font-weight:800; letter-spacing:.03em; color:var(--bs-faint); font-variant-numeric:tabular-nums; }
.bs-dice-scale-mid { color:var(--bs-orange); text-transform:uppercase; letter-spacing:.07em; }

/* ---- Craps: two-die felt table -------------------------------------------- */
.bs-craps-stage { background:radial-gradient(ellipse at 50% 0%, rgba(255,255,255,.05), transparent 62%), var(--bs-well);
  border:1px solid var(--bs-line); border-radius:12px; padding:12px 10px 12px; margin-bottom:10px; }
.bs-craps-stage .bs-dice-tray { background:transparent; border:0; margin:0; padding:6px 4px; }
.bs-craps-phase { display:flex; gap:6px; justify-content:center; }
.bs-craps-chip { font-size:10px; font-weight:900; letter-spacing:.09em; text-transform:uppercase; padding:4px 11px;
  border-radius:999px; background:var(--bs-elev2); border:1px solid var(--bs-line); color:var(--bs-faint); }
.bs-craps-chip.on { background:var(--bs-orange); border-color:var(--bs-orange-br); color:var(--bs-on-orange); }
.bs-craps-total { text-align:center; margin:2px 0 10px; min-height:26px; }
.bs-craps-total-num { font-size:30px; font-weight:900; line-height:1; color:var(--bs-text); }
.bs-craps-total-lbl { font-size:10px; font-weight:900; letter-spacing:.11em; text-transform:uppercase; color:var(--bs-faint); margin-left:7px; }
.bs-craps-points { display:flex; gap:6px; justify-content:center; }
.bs-craps-pt { width:30px; height:30px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-size:13px; font-weight:800; background:var(--bs-elev); border:1px solid var(--bs-line); color:var(--bs-faint); }
.bs-craps-pt.on { background:var(--bs-orange); border-color:var(--bs-orange-br); color:var(--bs-on-orange);
  filter:drop-shadow(0 0 6px var(--bs-orange)); }
.bs-toggle.bs-craps-toggle .bs-btn { min-width:136px; }
.bs-craps-help { text-align:center; font-size:12px; line-height:1.45; color:var(--bs-muted); margin:0 0 12px; }

/* ---- Sic Bo: three-die table + bet slip ----------------------------------- */
.bs-sicbo-stage { background:radial-gradient(ellipse at 50% 0%, rgba(255,255,255,.05), transparent 62%), var(--bs-well);
  border:1px solid var(--bs-line); border-radius:12px; padding:6px 8px 12px; margin-bottom:10px; }
.bs-sicbo-stage .bs-dice-tray { background:transparent; border:0; margin:0; padding:10px 4px 8px; }
.bs-sicbo-readout { display:flex; gap:8px; justify-content:center; align-items:center; flex-wrap:wrap; min-height:30px; }
.bs-sicbo-total { font-size:28px; font-weight:900; line-height:1; color:var(--bs-text); font-variant-numeric:tabular-nums; }
.bs-sicbo-tag { font-size:10px; font-weight:900; letter-spacing:.09em; text-transform:uppercase; padding:4px 10px;
  border-radius:999px; background:var(--bs-elev2); border:1px solid var(--bs-line); color:var(--bs-muted); }
.bs-sicbo-tag.bs-sicbo-triple { background:var(--bs-orange); border-color:var(--bs-orange-br); color:var(--bs-on-orange); }
.bs-sicbo-slip { border:1px solid var(--bs-line); border-radius:10px; background:var(--bs-panel); overflow:hidden; margin-bottom:12px; }
.bs-sicbo-slip-head { display:flex; justify-content:space-between; align-items:center; gap:8px; padding:7px 10px;
  background:var(--bs-elev2); font-size:10px; font-weight:900; letter-spacing:.07em; text-transform:uppercase; color:var(--bs-faint); }
.bs-sicbo-bet { display:flex; align-items:center; gap:9px; padding:8px 10px; border-top:1px solid var(--bs-line); font-size:13px; }
.bs-sicbo-bet-label { flex:1; font-weight:700; color:var(--bs-text); }
.bs-sicbo-bet-stake { font-weight:700; color:var(--bs-muted); font-variant-numeric:tabular-nums; }
.bs-sicbo-bet-res { font-weight:900; font-variant-numeric:tabular-nums; }
.bs-sicbo-bet-win { color:var(--bs-pos); }
.bs-sicbo-bet-lose { color:var(--bs-neg); }
.bs-sicbo-bet.bs-sicbo-bet-won { box-shadow:inset 3px 0 0 var(--bs-pos); }
.bs-sicbo-bet.bs-sicbo-bet-lost { box-shadow:inset 3px 0 0 var(--bs-neg); opacity:.62; }
.bs-sicbo-slip .bs-sicbo-x { padding:3px 9px; font-size:12px; line-height:1.2; min-width:0; }
.bs-sicbo-empty { text-align:center; margin:0 0 12px; }
.bs-sicbo-build { border-top:1px solid var(--bs-line); padding-top:12px; margin-top:12px; margin-bottom:12px; }
.bs-sicbo-market { display:grid; grid-template-columns:repeat(auto-fit, minmax(80px, 1fr)); gap:6px; margin-bottom:12px; }
.bs-sicbo-market .bs-sicbo-mkt { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
  padding:9px 6px; min-width:0; text-align:center; }
.bs-sicbo-mkt-name { font-size:12px; font-weight:800; line-height:1.2; }
.bs-sicbo-mkt-odds { font-size:10px; font-weight:900; letter-spacing:.04em; opacity:.72; }
.bs-row-tight.bs-sicbo-num-row { align-items:flex-end; margin-bottom:7px; }
.bs-sicbo-odds-tag { font-size:12px; font-weight:900; color:var(--bs-gold-ink); padding-bottom:9px; font-variant-numeric:tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  .bs-dice-readout.bs-dice-spinning .bs-dice-digit,
  .bs-dice-readout.bs-dice-landed .bs-dice-digit,
  .bs-dice-marker { animation: none !important; }
}


/* ============================================================================
   VIDEO POKER — 9/6 Jacks or Better CABINET. A bezelled machine body holding a
   live paytable, a rail, and the felt hand deck; HELD lamps under each seat and
   a result banner that lands after the draw. Extends the existing .bs-vp-*
   rules above rather than replacing them. Every accent is a --bs-* token so all
   10 skin presets keep working; the only fixed values are neutral black/white
   shadow washes (no brand colour is ever hardcoded).
   ========================================================================== */

/* ---- Cabinet body --------------------------------------------------------- */
.bs-vp-cab { position:relative; margin-bottom:10px; padding:9px 9px 10px; border-radius:16px;
  border:1px solid var(--bs-line); overflow:hidden;
  background:linear-gradient(180deg, var(--bs-elev2) 0%, var(--bs-panel) 44%, var(--bs-bg) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07), inset 0 -22px 40px rgba(0,0,0,.45),
    0 12px 28px rgba(0,0,0,.35); }
.bs-vp-cab-win { border-color:var(--bs-gold);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09), inset 0 -22px 40px rgba(0,0,0,.4),
    0 0 34px -8px var(--bs-gold), 0 12px 28px rgba(0,0,0,.35); }
.bs-vp-cab-busy .bs-vp-pt { opacity:.72; }
/* Anticipation sweep across the whole machine while the server is resolving. */
.bs-vp-sweep { position:absolute; inset:0; z-index:4; pointer-events:none; border-radius:inherit; }
.bs-vp-rail { margin:9px 4px 8px; }

/* ---- Paytable ------------------------------------------------------------- */
.bs-vp-pt { position:relative; border-radius:11px; overflow:hidden; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(0,0,0,.36), rgba(0,0,0,.14));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04); transition:opacity .2s; }
.bs-vp-pt-head, .bs-vp-pt-row { display:grid; grid-template-columns:1fr auto auto;
  align-items:center; gap:10px; padding:3px 10px; }
.bs-vp-pt-head { padding-top:5px; padding-bottom:5px; background:rgba(0,0,0,.32);
  border-bottom:1px solid var(--bs-line); color:var(--bs-faint);
  font-size:8.5px; font-weight:900; letter-spacing:.16em; text-transform:uppercase; }
.bs-vp-pt-head span:nth-child(2), .bs-vp-pt-head span:nth-child(3) { text-align:right; }
.bs-vp-pt-row { position:relative; font-size:10.5px; font-weight:700; color:var(--bs-muted);
  border-top:1px solid rgba(255,255,255,.035); transition:color .18s, background .18s; }
.bs-vp-pt-head + .bs-vp-pt-row { border-top:0; }
.bs-vp-pt-name { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; letter-spacing:.03em; }
.bs-vp-pt-mult { min-width:34px; text-align:right; font-weight:900; color:var(--bs-text);
  font-variant-numeric:tabular-nums; }
.bs-vp-pt-cash { min-width:58px; text-align:right; font-size:10px; color:var(--bs-faint);
  font-variant-numeric:tabular-nums; }
.bs-vp-pt-prime .bs-vp-pt-mult { color:var(--bs-gold-ink); }
.bs-vp-pt-hit { background:linear-gradient(90deg, var(--bs-orange-dp), var(--bs-orange));
  animation:bs-vp-ptflash .85s ease-out 2; }
.bs-vp-pt-hit .bs-vp-pt-name, .bs-vp-pt-hit .bs-vp-pt-mult, .bs-vp-pt-hit .bs-vp-pt-cash { color:var(--bs-on-orange); }
.bs-vp-pt-hit .bs-vp-pt-name { font-weight:900; }
.bs-vp-pt-hit::before { content:''; position:absolute; left:0; top:0; bottom:0; width:3px; background:var(--bs-gold); }
@keyframes bs-vp-ptflash { 0%,100% { filter:none; } 50% { filter:brightness(1.35); } }

/* ---- Felt deck ------------------------------------------------------------ */
.bs-vp-felt { padding:10px 8px 8px; margin-bottom:0; }
.bs-vp-felt .bs-felt-label { margin:0 2px 6px; }
.bs-vp-phase { color:var(--bs-orange); letter-spacing:.1em; font-variant-numeric:tabular-nums; }
.bs-vp-felt-win { box-shadow:inset 0 0 0 1px var(--bs-gold), inset 0 -18px 34px rgba(0,0,0,.45); }
.bs-vp-hand { min-height:104px; padding-top:11px; padding-bottom:16px; perspective:900px; }

/* Seat states */
.bs-vp-ghost { cursor:default; pointer-events:none; }
.bs-vp-slot.bs-pcard-held .bs-pcard { transform:translateY(-7px);
  box-shadow:0 13px 24px rgba(0,0,0,.5), 0 0 0 1px var(--bs-orange), 0 0 22px -5px var(--bs-orange); }
.bs-vp-slot.bs-pcard-held:not(:disabled):hover .bs-pcard { transform:translateY(-10px); }
.bs-vp-badge { box-shadow:0 3px 9px rgba(0,0,0,.5); }
.bs-vp-slam { animation:bs-vp-slam .3s cubic-bezier(.2,.9,.25,1.5); }
@keyframes bs-vp-slam {
  0%   { transform:translateX(-50%) translateY(-14px) scale(1.6); opacity:0; }
  60%  { transform:translateX(-50%) translateY(0) scale(.9); opacity:1; }
  100% { transform:translateX(-50%) translateY(0) scale(1); opacity:1; }
}
/* Cabinet hold lamp under each seat */
.bs-vp-lamp { position:absolute; left:14%; right:14%; bottom:-11px; height:4px; border-radius:3px;
  background:var(--bs-line); box-shadow:inset 0 1px 1px rgba(0,0,0,.55);
  transition:background .16s, box-shadow .16s; }
.bs-vp-lamp.on { background:var(--bs-orange);
  box-shadow:0 0 12px -1px var(--bs-orange), inset 0 1px 0 rgba(255,255,255,.45); }

/* Cards only animate on a real deal/draw reveal — holding a card must not
   re-deal the whole hand. .bs-vp-in marks the seats that genuinely changed. */
.bs-vp-hand .bs-pcard { animation:none; }
.bs-vp-hand .bs-vp-in .bs-pcard { animation:bs-vp-flipin .44s cubic-bezier(.2,.9,.3,1.25) both;
  animation-delay:var(--bs-vp-d, 0ms); }
@keyframes bs-vp-flipin {
  0%   { transform:translateY(-26px) rotateY(78deg) scale(.9); opacity:0; }
  55%  { opacity:1; }
  100% { transform:none; opacity:1; }
}

/* ---- Result banner -------------------------------------------------------- */
.bs-vp-banner { position:relative; margin:0 0 10px; padding:11px 14px; border-radius:13px;
  text-align:center; overflow:hidden; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06); }
.bs-vp-ban-cat { font-size:11px; font-weight:900; letter-spacing:.18em; text-transform:uppercase;
  color:var(--bs-muted); }
.bs-vp-ban-pay { position:relative; display:flex; align-items:baseline; justify-content:center;
  gap:10px; margin-top:3px; }
.bs-vp-ban-mult { padding:2px 8px; border-radius:999px; border:1px solid var(--bs-line);
  background:rgba(0,0,0,.25); color:var(--bs-muted);
  font-size:12px; font-weight:900; letter-spacing:.04em; font-variant-numeric:tabular-nums; }
.bs-vp-ban-sub { margin-top:3px; font-size:11px; font-weight:700; color:var(--bs-faint); }
.bs-vp-ban-win { border-color:var(--bs-gold);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08), 0 0 30px -10px var(--bs-gold); }
.bs-vp-ban-win::before { content:''; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(70% 130% at 50% 0%, rgba(255,255,255,.10), transparent 62%); }
.bs-vp-ban-win .bs-vp-ban-cat { color:var(--bs-gold-ink); }
.bs-vp-ban-win .bs-vp-ban-mult { color:var(--bs-gold-ink); border-color:var(--bs-gold); }
.bs-vp-ban-push .bs-vp-ban-cat { color:var(--bs-text); }
.bs-vp-ban-push .bs-fx-payout { font-size:26px; color:var(--bs-text); text-shadow:none; }
.bs-vp-ban-lose { opacity:.92; }
.bs-vp-ban-lose .bs-vp-ban-cat { color:var(--bs-faint); }

/* ---- Draw control --------------------------------------------------------- */
.bs-vp-ctrls { justify-content:center; }
.bs-vp-draw { position:relative; flex:1; max-width:300px; display:inline-flex; align-items:center;
  justify-content:center; gap:8px; padding:12px 16px; font-size:15px; letter-spacing:.06em; }
.bs-vp-draw b { padding:1px 8px; border-radius:999px; background:rgba(0,0,0,.22);
  font-size:13px; font-variant-numeric:tabular-nums; }
.bs-vp-draw-ready::after { content:''; position:absolute; inset:-3px; border-radius:inherit;
  border:2px solid var(--bs-orange); opacity:0; pointer-events:none;
  animation:bs-vp-ready 1.6s ease-in-out infinite; }
@keyframes bs-vp-ready { 0%,100% { opacity:0; transform:scale(1); } 50% { opacity:.55; transform:scale(1.03); } }

@media (max-width:420px) {
  .bs-vp-cab { padding:7px 7px 8px; border-radius:14px; }
  .bs-vp-pt-head, .bs-vp-pt-row { gap:6px; padding-left:8px; padding-right:8px; }
  .bs-vp-pt-row { font-size:9.5px; }
  .bs-vp-pt-mult { min-width:26px; }
  .bs-vp-pt-cash { min-width:44px; font-size:9px; }
  .bs-vp-hand { min-height:92px; padding-top:10px; padding-bottom:15px; }
  .bs-vp-lamp { bottom:-10px; height:3px; }
  .bs-vp-banner { padding:10px 10px; }
  .bs-vp-ban-cat { font-size:10px; letter-spacing:.13em; }
  .bs-vp-draw { max-width:none; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-vp-slam, .bs-vp-pt-hit, .bs-vp-draw-ready::after, .bs-vp-hand .bs-vp-in .bs-pcard { animation:none !important; }
  .bs-vp-lamp, .bs-vp-pt-row, .bs-vp-pt { transition:none !important; }
}
/* ---- PLINKO v2 — the pegboard as a physical cabinet -----------------------
   Second visual pass. Everything is scoped under .bs-plink-v2 so it layers on
   top of the original pegboard rules without touching any shared class. All
   colour comes from --bs-* tokens, the inner well included (var(--bs-well)); the only fixed values are the physical
   well the stages already share), so every operator skin keeps driving it. */

/* Cabinet ------------------------------------------------------------------ */
.bs-plink-board.bs-plink-v2 { padding: 0 0 9px; margin-bottom: 8px; border-radius: 14px;
  background:
    radial-gradient(120% 70% at 50% -8%, rgba(255,255,255,.09), rgba(255,255,255,0) 58%),
    linear-gradient(180deg, var(--bs-elev) 0%, var(--bs-well) 72%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06), inset 0 -22px 42px rgba(0,0,0,.55),
    0 10px 26px -16px rgba(0,0,0,.95);
  transition: box-shadow .35s ease, border-color .35s ease; }
.bs-plink-board.bs-plink-v2.is-armed { border-color: var(--bs-orange-dp); }
.bs-plink-board.bs-plink-v2.is-win { border-color: var(--bs-gold);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06), inset 0 -22px 42px rgba(0,0,0,.55),
    0 0 30px -10px var(--bs-gold); }

.bs-plink-marquee { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 7px 11px 6px; border-bottom: 1px solid var(--bs-line);
  background: linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,0));
  font-size: 9px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  color: var(--bs-faint); }
.bs-plink-tier { color: var(--bs-orange); }
.bs-plink-marq-mid { color: var(--bs-muted); letter-spacing: .16em; }
.bs-plink-rowsn { font-variant-numeric: tabular-nums; }

.bs-plink-board.bs-plink-v2 .bs-plink-field { margin: 10px 7px 0; height: clamp(196px, 57vw, 258px); }

/* Light shaft down the middle of the well + glass sheen over the pegs */
.bs-plink-beam { position: absolute; top: 0; left: 50%; width: 74%; height: 100%;
  transform: translateX(-50%); pointer-events: none; z-index: 0;
  background: linear-gradient(180deg, rgba(255,255,255,.07), rgba(255,255,255,0) 58%);
  clip-path: polygon(40% 0, 60% 0, 100% 100%, 0 100%); }
.bs-plink-vig { position: absolute; inset: -2px; pointer-events: none; z-index: 2; border-radius: 10px;
  background:
    radial-gradient(125% 95% at 50% 10%, rgba(255,255,255,0) 46%, rgba(0,0,0,.44) 100%),
    linear-gradient(114deg, rgba(255,255,255,.055) 0%, rgba(255,255,255,0) 32%); }

/* Release chute ------------------------------------------------------------ */
.bs-plink-board.bs-plink-v2 .bs-plink-chute { top: -7px; width: 46px; height: 15px; z-index: 3;
  border: 1px solid var(--bs-line); border-top: 0; border-radius: 0 0 13px 13px;
  background: linear-gradient(180deg, var(--bs-elev2) 0%, var(--bs-elev) 55%, var(--bs-well) 100%);
  box-shadow: inset 0 -5px 9px rgba(0,0,0,.6), 0 2px 6px -3px rgba(0,0,0,.8); }
.bs-plink-board.bs-plink-v2 .bs-plink-chute > i { position: absolute; left: 50%; bottom: -1px;
  width: 22px; height: 2px; margin-left: -11px; border-radius: 2px; display: block;
  background: var(--bs-orange-dp); opacity: .45;
  transition: opacity .25s ease, background .25s ease, box-shadow .25s ease; }
.bs-plink-board.bs-plink-v2 .bs-plink-chute.is-armed > i { opacity: 1; background: var(--bs-gold);
  box-shadow: 0 0 12px var(--bs-gold); animation: bs-plink-arm 1s ease-in-out infinite; }
@keyframes bs-plink-arm { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }

/* Pegs — machined studs that flash gold on a real strike ------------------- */
.bs-plink-board.bs-plink-v2 .bs-plink-peg { width: 5px; height: 5px; opacity: .82;
  background: radial-gradient(circle at 34% 28%, #ffffff, var(--bs-soft) 72%);
  box-shadow: 0 1px 2px rgba(0,0,0,.7), inset 0 -1px 1px rgba(0,0,0,.3); }
.bs-plink-board.bs-plink-v2 .bs-plink-peg.hit { opacity: 1;
  background: radial-gradient(circle at 34% 28%, #ffffff, var(--bs-gold) 74%);
  transform: translate(-50%, -50%) scale(1.3);
  box-shadow: 0 0 11px -1px var(--bs-gold), inset 0 -1px 1px rgba(0,0,0,.25); }
.bs-plink-board.bs-plink-v2 .bs-plink-peg::after { content: ''; position: absolute; inset: -3px;
  border-radius: 50%; border: 1px solid var(--bs-gold); opacity: 0; pointer-events: none; }
.bs-plink-board.bs-plink-v2 .bs-plink-peg.bs-plink-strike { animation: bs-plink-peg-strike .34s ease-out; }
.bs-plink-board.bs-plink-v2 .bs-plink-peg.bs-plink-strike::after { animation: bs-plink-ring .44s ease-out; }
@keyframes bs-plink-peg-strike {
  0%   { transform: translate(-50%, -50%) scale(2.2); }
  55%  { transform: translate(-50%, -50%) scale(1.12); }
  100% { transform: translate(-50%, -50%) scale(1.3); }
}
@keyframes bs-plink-ring {
  0%   { opacity: .85; transform: scale(.55); }
  100% { opacity: 0;   transform: scale(3.6); }
}

/* Ball — real weight, specular highlight, comet streak while falling ------- */
.bs-plink-board.bs-plink-v2 .bs-plink-ball { width: 13px; height: 13px; z-index: 4;
  background: radial-gradient(circle at 34% 27%, #fffdf5 0%, var(--bs-gold) 40%, var(--bs-orange) 76%, var(--bs-orange-dp) 100%);
  box-shadow: 0 0 13px -1px var(--bs-orange), 0 3px 6px rgba(0,0,0,.6), inset 0 -2px 3px rgba(0,0,0,.35);
  transition: left var(--bs-plink-fall) cubic-bezier(.45,.05,.55,.95),
              top var(--bs-plink-fall) cubic-bezier(.3,0,.8,1); }
.bs-plink-board.bs-plink-v2 .bs-plink-ball::after { content: ''; position: absolute; left: 50%; bottom: 50%;
  width: 5px; height: 30px; margin-left: -2.5px; border-radius: 3px; pointer-events: none;
  opacity: 0; filter: blur(2.5px); transition: opacity .18s ease;
  background: linear-gradient(180deg, rgba(255,255,255,0), var(--bs-orange)); }
.bs-plink-board.bs-plink-v2 .bs-plink-ball.is-falling::after { opacity: .72; }
.bs-plink-trail { position: absolute; width: 9px; height: 9px; border-radius: 50%; z-index: 3;
  transform: translate(-50%, -50%); pointer-events: none; display: block;
  background: radial-gradient(circle, var(--bs-gold) 0%, rgba(0,0,0,0) 70%);
  animation: bs-plink-fade .5s ease-out forwards; }
@keyframes bs-plink-fade {
  0%   { opacity: .7; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0;  transform: translate(-50%, -50%) scale(.3); }
}

/* Buckets — colour-graded cups, cool centre to hot edges ------------------- */
.bs-plink-board.bs-plink-v2 .bs-plink-buckets { position: relative; gap: 2px; margin: 10px 7px 0; }
.bs-plink-board.bs-plink-v2 .bs-plink-bucket { position: relative; overflow: hidden; padding: 7px 0 8px;
  border: 1px solid var(--bs-line); border-top: 0; border-radius: 0 0 6px 6px;
  background: linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  box-shadow: inset 0 -7px 11px rgba(0,0,0,.45);
  color: var(--bs-faint); line-height: 1; font-weight: 900; letter-spacing: -.03em;
  font-size: clamp(5.5px, 1.95vw, 9px); font-variant-numeric: tabular-nums;
  transition: transform .2s ease, box-shadow .28s ease, color .28s ease; }
.bs-plink-board.bs-plink-v2 .bs-plink-bucket::before { content: ''; position: absolute; top: 0; left: 0; right: 0;
  height: 3px; z-index: 2; background: var(--bs-soft); }
.bs-plink-board.bs-plink-v2 .bs-plink-bucket::after { background: var(--bs-orange); opacity: 0; }
.bs-plink-board.bs-plink-v2 .bs-plink-heat-0::after { opacity: .05; }
.bs-plink-board.bs-plink-v2 .bs-plink-heat-1::after { opacity: .13; }
.bs-plink-board.bs-plink-v2 .bs-plink-heat-2::after { opacity: .23; }
.bs-plink-board.bs-plink-v2 .bs-plink-heat-3::after { opacity: .36;
  background: linear-gradient(180deg, var(--bs-orange), var(--bs-orange-dp)); }
.bs-plink-board.bs-plink-v2 .bs-plink-heat-4::after { opacity: .52;
  background: linear-gradient(180deg, var(--bs-gold), var(--bs-orange)); }
.bs-plink-board.bs-plink-v2 .bs-plink-heat-1::before { background: var(--bs-orange-dp); }
.bs-plink-board.bs-plink-v2 .bs-plink-heat-2::before { background: var(--bs-orange); }
.bs-plink-board.bs-plink-v2 .bs-plink-heat-3::before { background: var(--bs-orange-br); }
.bs-plink-board.bs-plink-v2 .bs-plink-heat-4::before { background: var(--bs-gold);
  box-shadow: 0 0 9px -1px var(--bs-gold); }
.bs-plink-board.bs-plink-v2 .bs-plink-heat-2,
.bs-plink-board.bs-plink-v2 .bs-plink-heat-3,
.bs-plink-board.bs-plink-v2 .bs-plink-heat-4 { color: var(--bs-text); }
/* Risk tier modulates how extreme the edges read */
.bs-plink-board.bs-plink-v2.bs-plink-r-high .bs-plink-heat-3::after { opacity: .46; }
.bs-plink-board.bs-plink-v2.bs-plink-r-high .bs-plink-heat-4::after { opacity: .7; }
.bs-plink-board.bs-plink-v2.bs-plink-r-low .bs-plink-heat-3::after { opacity: .26; }
.bs-plink-board.bs-plink-v2.bs-plink-r-low .bs-plink-heat-4::after { opacity: .36; }

.bs-plink-board.bs-plink-v2 .bs-plink-bucket.landed { color: var(--bs-text); transform: translateY(2px);
  box-shadow: inset 0 0 0 1px var(--bs-gold), 0 0 20px -5px var(--bs-gold); }
.bs-plink-board.bs-plink-v2 .bs-plink-bucket.landed::after { opacity: .64;
  background: linear-gradient(180deg, var(--bs-gold), var(--bs-orange-dp)); }
.bs-plink-board.bs-plink-v2 .bs-plink-bucket.landed::before { background: var(--bs-gold);
  box-shadow: 0 0 12px -1px var(--bs-gold); }
.bs-plink-burst { position: absolute; left: 50%; top: 0; width: 36px; height: 36px; margin: -18px 0 0 -18px;
  border-radius: 50%; pointer-events: none; z-index: 3; display: block;
  background: radial-gradient(circle, var(--bs-gold) 0%, rgba(0,0,0,0) 68%);
  animation: bs-plink-burst .55s ease-out forwards; }
@keyframes bs-plink-burst {
  0%   { opacity: .95; transform: scale(.2); }
  100% { opacity: 0;   transform: scale(1.7); }
}

/* Landing flag — the real multiplier, planted over the bucket it came from */
.bs-plink-flag { position: absolute; bottom: calc(100% + 7px); transform: translateX(-50%); z-index: 6;
  padding: 3px 8px; border-radius: 999px; white-space: nowrap; line-height: 1.15;
  font-size: 11px; font-weight: 900; letter-spacing: -.01em; font-variant-numeric: tabular-nums;
  color: var(--bs-text); border: 1px solid var(--bs-line);
  background: linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  box-shadow: 0 6px 16px -7px rgba(0,0,0,.95);
  animation: bs-plink-flag-in .42s cubic-bezier(.2,.9,.3,1.5); }
.bs-plink-flag::after { content: ''; position: absolute; left: 50%; top: 100%; margin-left: -4px;
  border: 4px solid transparent; border-top-color: var(--bs-line); }
.bs-plink-flag.is-win { color: var(--bs-on-orange); border-color: var(--bs-gold);
  background: linear-gradient(180deg, var(--bs-gold), var(--bs-orange));
  box-shadow: 0 0 22px -5px var(--bs-gold); }
.bs-plink-flag.is-win::after { border-top-color: var(--bs-gold); }
@keyframes bs-plink-flag-in {
  0%   { opacity: 0; transform: translateX(-50%) translateY(9px) scale(.7); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}

/* HUD — the two figures that matter -------------------------------------- */
.bs-rail.bs-plink-rail { max-width: 68%; margin: 0 auto 9px; }
.bs-plink-hud { display: flex; align-items: stretch; gap: 8px; padding: 9px 12px 10px; margin-bottom: 6px; }
.bs-plink-hud-cell { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 3px; }
.bs-plink-k { font-size: 9px; font-weight: 800; letter-spacing: .11em; text-transform: uppercase;
  color: var(--bs-faint); }
.bs-plink-hud-sep { width: 1px; align-self: stretch; display: block;
  background: linear-gradient(180deg, transparent, var(--bs-line), transparent); }
.bs-plink-mult { font-size: 25px; font-weight: 900; line-height: 1.05; letter-spacing: -.025em;
  font-variant-numeric: tabular-nums; color: var(--bs-text);
  transition: color .3s ease, text-shadow .3s ease; }
.bs-plink-pay { font-size: 20px; font-weight: 900; line-height: 1.05;
  font-variant-numeric: tabular-nums; color: var(--bs-muted); }
.bs-plink-hud.is-idle .bs-plink-mult, .bs-plink-hud.is-idle .bs-plink-pay { color: var(--bs-faint); }
.bs-plink-hud.is-flat .bs-plink-mult { color: var(--bs-muted); }
.bs-plink-hud.is-win .bs-plink-mult { color: var(--bs-gold-ink); text-shadow: 0 0 20px rgba(var(--bs-gold-rgb),.45); }
.bs-plink-sub { text-align: center; font-size: 11px; font-weight: 700; letter-spacing: .02em;
  color: var(--bs-muted); min-height: 15px; margin-bottom: 8px; }

/* Recent real multipliers */
.bs-plink-hist { display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: 4px; margin-bottom: 9px; }
.bs-plink-hist-k { font-size: 9px; font-weight: 800; letter-spacing: .11em; text-transform: uppercase;
  color: var(--bs-faint); margin-right: 2px; }
.bs-plink-chip { padding: 2px 7px 3px; border-radius: 999px; font-size: 10px; font-weight: 800;
  font-variant-numeric: tabular-nums; border: 1px solid var(--bs-line);
  background: var(--bs-elev2); color: var(--bs-muted); }
.bs-plink-chip.is-up { border-color: var(--bs-orange-dp); color: var(--bs-orange); }
.bs-plink-chip.is-hot { border-color: var(--bs-gold); color: var(--bs-gold-ink);
  box-shadow: 0 0 11px -3px var(--bs-gold); }
.bs-plink-chip.is-new { animation: bs-plink-chip-in .35s cubic-bezier(.2,.9,.3,1.45); }
@keyframes bs-plink-chip-in { from { transform: scale(.6); opacity: 0; } to { transform: none; opacity: 1; } }

/* Risk selector + drop button --------------------------------------------- */
.bs-plink-risk { margin-bottom: 8px; }
.bs-plink-risk .bs-plink-risk-btn { display: inline-flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 4px; line-height: 1.1; }
.bs-plink-pips { display: inline-flex; gap: 3px; }
.bs-plink-pips i { display: block; width: 4px; height: 4px; border-radius: 50%; background: var(--bs-soft); }
.bs-plink-pips i.on { background: var(--bs-orange); }
.bs-plink-risk-btn.active .bs-plink-pips i { background: rgba(0,0,0,.28); }
.bs-plink-risk-btn.active .bs-plink-pips i.on { background: var(--bs-on-orange); }
.bs-plink-drop { display: inline-flex; align-items: center; justify-content: center; gap: 7px; }
.bs-plink-btn-ball { display: block; width: 10px; height: 10px; border-radius: 50%; opacity: .92;
  background: radial-gradient(circle at 34% 28%, #ffffff, #1a1207 78%);
  box-shadow: 0 1px 4px rgba(0,0,0,.4); }
.bs-plink-drop:disabled .bs-plink-btn-ball { animation: bs-plink-btn-drop .9s ease-in-out infinite; }
@keyframes bs-plink-btn-drop {
  0%, 100% { transform: translateY(-3px); opacity: .45; }
  50%      { transform: translateY(3px);  opacity: 1; }
}

@media (max-width: 420px) {
  .bs-plink-board.bs-plink-v2 .bs-plink-field { height: clamp(178px, 55vw, 220px); margin: 8px 5px 0; }
  .bs-plink-board.bs-plink-v2 .bs-plink-buckets { margin: 9px 5px 0; gap: 1px; }
  .bs-plink-marquee { font-size: 8px; letter-spacing: .08em; padding: 6px 8px 5px; }
  .bs-plink-hud { padding: 8px 6px 9px; gap: 4px; }
  .bs-plink-mult { font-size: 21px; }
  .bs-plink-pay { font-size: 17px; }
  .bs-plink-flag { font-size: 10px; padding: 2px 6px; }
  .bs-plink-hist-k { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-plink-board.bs-plink-v2 .bs-plink-chute.is-armed > i,
  .bs-plink-board.bs-plink-v2 .bs-plink-peg.bs-plink-strike,
  .bs-plink-board.bs-plink-v2 .bs-plink-peg.bs-plink-strike::after,
  .bs-plink-trail, .bs-plink-burst, .bs-plink-flag, .bs-plink-chip.is-new,
  .bs-plink-drop:disabled .bs-plink-btn-ball { animation: none !important; }
  .bs-plink-trail, .bs-plink-burst { display: none !important; }
  .bs-plink-board.bs-plink-v2 .bs-plink-ball,
  .bs-plink-board.bs-plink-v2 .bs-plink-ball::after,
  .bs-plink-board.bs-plink-v2 .bs-plink-peg,
  .bs-plink-board.bs-plink-v2 .bs-plink-bucket,
  .bs-plink-board.bs-plink-v2 .bs-plink-chute > i { transition: none !important; }
}
/* ============================================================================
   DICE — second pass. A machined instrument panel: HUD figures, a nixie-style
   percentile readout, and the hero win-zone rail with a grabbable target handle.
   Every accent still resolves from var(--bs-*); the only literals are the
   var(--bs-well) inner well every stage already uses, and neutral white/black
   specular + shadow overlays (physical light, not brand colour).
   ========================================================================== */

/* ---- Stage: brushed-metal well with a vignette ---------------------------- */
.bs-dice-stage { position:relative; overflow:visible; margin-bottom:12px; padding:13px 14px 12px;
  border:1px solid var(--bs-line); border-radius:16px;
  background:
    radial-gradient(ellipse at 50% -16%, rgba(255,255,255,.085), transparent 62%),
    repeating-linear-gradient(90deg, rgba(255,255,255,.022) 0 1px, transparent 1px 34px),
    linear-gradient(180deg, var(--bs-elev) 0%, var(--bs-well) 78%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07), inset 0 -26px 46px rgba(0,0,0,.6), 0 12px 28px rgba(0,0,0,.42); }
.bs-dice-stage::after { content:''; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  background:radial-gradient(ellipse at 50% 44%, transparent 40%, rgba(0,0,0,.4) 100%); }
.bs-dice-stage > * { position:relative; z-index:1; }
.bs-dice-stage-won { border-color:var(--bs-gold);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09), inset 0 -26px 46px rgba(0,0,0,.55),
    0 12px 28px rgba(0,0,0,.42), 0 0 40px -14px var(--bs-gold);
  animation:bs-dice-flash .9s ease-out; }
@keyframes bs-dice-flash { 0% { filter:brightness(1.5); } 100% { filter:none; } }

/* ---- HUD: the three figures the player decides on ------------------------- */
.bs-dice-hud { display:grid; grid-template-columns:repeat(3,1fr); gap:6px; margin-bottom:11px; }
.bs-dice-cell { min-width:0; padding:6px 6px 7px; border-radius:10px; text-align:center;
  background:linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.012));
  border:1px solid var(--bs-line); box-shadow:inset 0 1px 0 rgba(255,255,255,.06); }
.bs-dice-cell b { display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-size:8.5px; font-weight:900; letter-spacing:.12em; text-transform:uppercase; color:var(--bs-faint); }
.bs-dice-cell span { display:block; margin-top:3px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-size:14px; font-weight:900; line-height:1.15; color:var(--bs-text); font-variant-numeric:tabular-nums; }
.bs-dice-cell-key { border-color:var(--bs-soft); }
.bs-dice-cell-key span { color:var(--bs-gold-ink); }

/* ---- Readout: machined numeral cells -------------------------------------- */
.bs-dice-readout { gap:6px; margin-bottom:9px; }
.bs-dice-digit { position:relative; overflow:hidden; min-width:54px; height:74px; border-radius:12px; font-size:42px;
  background:linear-gradient(180deg, var(--bs-elev2) 0%, var(--bs-panel) 46%, var(--bs-well) 100%);
  border:1px solid var(--bs-line); color:var(--bs-text); text-shadow:0 2px 6px rgba(0,0,0,.6);
  box-shadow:inset 0 -15px 24px rgba(0,0,0,.62), inset 0 1px 0 rgba(255,255,255,.1), 0 5px 12px rgba(0,0,0,.45); }
.bs-dice-digit::before { content:''; position:absolute; left:0; right:0; top:0; height:46%; pointer-events:none;
  background:linear-gradient(180deg, rgba(255,255,255,.1), transparent); }
.bs-dice-digit::after { content:''; position:absolute; left:0; right:0; top:50%; height:1px; pointer-events:none;
  background:rgba(0,0,0,.5); }
.bs-dice-digit.bs-dice-dot { min-width:12px; height:74px; overflow:visible; padding-bottom:16px; box-shadow:none; }
.bs-dice-digit.bs-dice-dot::before, .bs-dice-digit.bs-dice-dot::after { display:none; }
.bs-dice-readout.bs-dice-landed .bs-dice-digit { animation:bs-dice-settle .38s cubic-bezier(.2,.9,.3,1.35) backwards; }
.bs-dice-readout.bs-dice-hit .bs-dice-digit { color:var(--bs-gold-ink); border-color:var(--bs-gold); text-shadow:0 0 20px currentColor;
  box-shadow:inset 0 -15px 24px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.14), 0 0 26px -6px var(--bs-gold); }
.bs-dice-readout.bs-dice-miss .bs-dice-digit { color:var(--bs-muted); opacity:.88; }

/* ---- Verdict beat --------------------------------------------------------- */
.bs-dice-verdict { display:flex; align-items:center; justify-content:center; gap:10px; min-height:40px; margin-bottom:8px; }
.bs-dice-vtag { display:inline-block; padding:4px 11px; border-radius:999px;
  font-size:10px; font-weight:900; letter-spacing:.16em; text-transform:uppercase; line-height:1.4;
  background:var(--bs-elev2); border:1px solid var(--bs-line); color:var(--bs-faint); }
.bs-dice-vtag-win { background:linear-gradient(180deg, var(--bs-orange-br), var(--bs-orange));
  border-color:var(--bs-orange-br); color:var(--bs-on-orange); box-shadow:0 0 20px -5px var(--bs-orange); }
.bs-dice-vtag-lose { color:var(--bs-muted); }
.bs-dice-vidle { font-size:11px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:var(--bs-faint); }
.bs-dice-vsub { font-size:17px; font-weight:900; color:var(--bs-muted); font-variant-numeric:tabular-nums; }
.bs-dice-verdict .bs-fx-payout { font-size:27px; line-height:1.1; }

/* ---- Hero rail: win zone vs lose zone, target handle, landed marker ------- */
.bs-dice-rail { position:relative; height:66px; margin:0 9px; touch-action:none; cursor:ew-resize;
  -webkit-user-select:none; user-select:none; }
.bs-dice-rail-busy { cursor:default; }
.bs-dice-rail-track { position:absolute; left:0; right:0; top:30px; height:24px; border-radius:8px; overflow:hidden;
  background:linear-gradient(180deg, var(--bs-well), rgba(0,0,0,.4)); border:1px solid var(--bs-line);
  box-shadow:inset 0 3px 9px rgba(0,0,0,.72), 0 1px 0 rgba(255,255,255,.04); }
.bs-dice-zone { position:absolute; top:0; bottom:0; }
.bs-dice-zone-lose { background:
    repeating-linear-gradient(135deg, rgba(255,255,255,.05) 0 5px, transparent 5px 10px),
    linear-gradient(180deg, var(--bs-elev2), var(--bs-panel)); }
.bs-dice-zone-win { background:var(--bs-pos); opacity:.82; }
.bs-dice-zone-win::after { content:''; position:absolute; inset:0;
  background:linear-gradient(180deg, rgba(255,255,255,.3), rgba(255,255,255,0) 52%, rgba(0,0,0,.3)); }
.bs-dice-ruler { position:absolute; inset:0; pointer-events:none; background:
    repeating-linear-gradient(90deg, rgba(0,0,0,.58) 0 2px, transparent 2px 25%),
    repeating-linear-gradient(90deg, rgba(0,0,0,.34) 0 1px, transparent 1px 10%); }
.bs-dice-scan { position:absolute; top:0; bottom:0; left:0; width:28%; margin-left:-14%; pointer-events:none;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.24), transparent);
  animation:bs-dice-sweep 1.05s ease-in-out infinite; }
@keyframes bs-dice-sweep { 0% { left:0; } 50% { left:100%; } 100% { left:0; } }

.bs-dice-handle { position:absolute; top:19px; left:50%; z-index:5; width:18px; height:46px; margin:0; padding:0;
  transform:translateX(-50%); border-radius:7px; cursor:ew-resize;
  background:linear-gradient(180deg, var(--bs-orange-br), var(--bs-orange-dp));
  border:1px solid var(--bs-orange-br);
  box-shadow:0 4px 10px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.42), 0 0 18px -4px var(--bs-orange);
  transition:transform .12s ease, box-shadow .12s ease; }
.bs-dice-handle-grip { position:absolute; inset:2px; border-radius:5px; pointer-events:none; opacity:.62;
  background:repeating-linear-gradient(180deg, rgba(0,0,0,.34) 0 1px, transparent 1px 4px); }
.bs-dice-handle-bub { position:absolute; left:50%; bottom:calc(100% + 5px); transform:translateX(-50%);
  padding:2px 7px; border-radius:6px; white-space:nowrap; pointer-events:none;
  font-size:10.5px; font-weight:900; line-height:1.3; letter-spacing:.02em; font-variant-numeric:tabular-nums;
  background:linear-gradient(180deg, var(--bs-orange-br), var(--bs-orange)); color:var(--bs-on-orange);
  box-shadow:0 3px 8px rgba(0,0,0,.5); }
.bs-dice-rail:hover .bs-dice-handle, .bs-dice-rail-drag .bs-dice-handle {
  box-shadow:0 5px 14px rgba(0,0,0,.65), inset 0 1px 0 rgba(255,255,255,.5), 0 0 26px -3px var(--bs-orange); }
.bs-dice-rail-drag .bs-dice-handle { transform:translateX(-50%) scaleY(1.07); }
.bs-dice-rail-busy .bs-dice-handle { opacity:.5; }

.bs-dice-marker { position:absolute; z-index:4; top:42px; left:0; width:22px; height:22px; margin:0;
  transform:translate(-50%,-50%); border:2px solid rgba(255,255,255,.55);
  background:radial-gradient(circle at 34% 28%, #fff 6%, currentColor 62%, rgba(0,0,0,.55) 100%);
  box-shadow:0 3px 9px rgba(0,0,0,.65), 0 0 18px currentColor; filter:none;
  animation:bs-dice-snap .5s cubic-bezier(.16,1.05,.3,1.25); }
.bs-dice-marker::before { content:''; position:absolute; inset:-6px; border-radius:50%; border:2px solid currentColor;
  animation:bs-dice-ring .75s ease-out forwards; }
.bs-dice-marker::after { content:''; position:absolute; left:50%; top:100%; width:2px; height:11px; margin-left:-1px;
  background:linear-gradient(180deg, currentColor, transparent); opacity:.8; }
.bs-dice-marker-stale { opacity:.38; box-shadow:none; }
.bs-dice-marker-stale::before { display:none; }
@keyframes bs-dice-snap {
  0%   { transform:translate(-50%,-210%) scale(.35); opacity:0; }
  55%  { transform:translate(-50%,-50%) scale(1.35); opacity:1; }
  100% { transform:translate(-50%,-50%) scale(1); opacity:1; }
}
@keyframes bs-dice-ring { 0% { transform:scale(.45); opacity:.85; } 100% { transform:scale(2.2); opacity:0; } }

/* ---- Axis + zone legend --------------------------------------------------- */
.bs-dice-axis { position:relative; height:13px; margin:0 9px; }
.bs-dice-axis-lbl { position:absolute; top:0; font-size:9.5px; font-weight:800; letter-spacing:.05em;
  color:var(--bs-faint); font-variant-numeric:tabular-nums; }
.bs-dice-zonebar { display:flex; align-items:center; justify-content:center; gap:7px; margin-top:6px;
  font-size:10px; font-weight:900; letter-spacing:.1em; text-transform:uppercase; color:var(--bs-faint); }
.bs-dice-swatch { width:9px; height:9px; border-radius:2px; background:var(--bs-pos); box-shadow:0 0 9px -1px var(--bs-pos); }
.bs-dice-zoneval { color:var(--bs-pos); letter-spacing:.02em; font-variant-numeric:tabular-nums; }

/* ---- Result tape ---------------------------------------------------------- */
.bs-dice-div { margin:11px 0 0; }
.bs-dice-history { display:flex; align-items:center; gap:5px; margin-top:8px; overflow-x:auto;
  scrollbar-width:none; -ms-overflow-style:none; }
.bs-dice-history::-webkit-scrollbar { display:none; }
.bs-dice-hist-lbl { flex:0 0 auto; font-size:8.5px; font-weight:900; letter-spacing:.13em;
  text-transform:uppercase; color:var(--bs-faint); }
.bs-dice-pill { flex:0 0 auto; padding:3px 7px; border-radius:6px; font-size:10.5px; font-weight:900;
  font-variant-numeric:tabular-nums; background:var(--bs-elev2); border:1px solid var(--bs-line); color:var(--bs-muted); }
.bs-dice-pill-win { color:var(--bs-pos); border-color:var(--bs-pos); box-shadow:inset 0 0 14px -7px var(--bs-pos); }
.bs-dice-pill-lose { color:var(--bs-neg); border-color:var(--bs-line); opacity:.72; }

/* ---- Controls ------------------------------------------------------------- */
.bs-slot-ctrls .bs-dice-roll { min-width:148px; letter-spacing:.04em; }
.bs-dice-msg-win { color:var(--bs-pos); }

@media (max-width:420px) {
  .bs-dice-stage { padding:11px 10px 10px; border-radius:14px; }
  .bs-dice-hud { gap:5px; }
  .bs-dice-cell { padding:5px 4px 6px; }
  .bs-dice-cell b { font-size:7.5px; letter-spacing:.06em; }
  .bs-dice-cell span { font-size:12.5px; }
  .bs-dice-readout { gap:4px; }
  .bs-dice-digit { min-width:44px; height:62px; font-size:32px; border-radius:10px; }
  .bs-dice-digit.bs-dice-dot { min-width:10px; height:62px; padding-bottom:12px; }
  .bs-dice-verdict { min-height:34px; margin-bottom:6px; }
  .bs-dice-verdict .bs-fx-payout { font-size:23px; }
  .bs-dice-rail { height:60px; margin:0 6px; }
  .bs-dice-rail-track { top:26px; height:22px; }
  .bs-dice-handle { top:18px; height:42px; width:16px; }
  .bs-dice-handle-bub { font-size:10px; padding:2px 6px; }
  .bs-dice-marker { top:37px; width:20px; height:20px; }
  .bs-dice-axis { margin:0 6px; }
  .bs-dice-hist-lbl { display:none; }
  .bs-dice-pill { padding:3px 5px; font-size:10px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-dice-scan, .bs-dice-marker::before { display:none !important; }
  .bs-dice-marker, .bs-dice-stage-won { animation:none !important; }
  .bs-dice-handle { transition:none !important; }
}
/* ============================================================================
   CRAPS — a real table: number boxes with a travelling ON/OFF puck, a sunken
   dice pit, and the PASS LINE / DON'T PASS bars drawn on the felt itself.
   Every colour is a --bs-* token (the only fixed values are black shadow
   washes and white specular highlights, i.e. lighting, not brand).
   ========================================================================== */
.bs-craps-felt { padding:12px 12px 13px; }
.bs-craps-felt .bs-felt-label { margin:0 0 9px; }
.bs-craps-phase-tag { display:inline-flex; align-items:center; padding:4px 11px; border-radius:999px;
  background:var(--bs-elev2); border:1px solid var(--bs-line); color:var(--bs-muted);
  letter-spacing:.12em; transition:background .3s, color .3s, border-color .3s; }
.bs-craps-phase-tag.on { background:var(--bs-orange); border-color:var(--bs-orange-br); color:var(--bs-on-orange); }
.bs-craps-yourbet { color:var(--bs-faint); letter-spacing:.09em; text-align:right; }
.bs-craps-yourbet b { color:var(--bs-text); }

/* ---- Puck lane + point boxes (one shared 7-column geometry) --------------- */
.bs-craps-lane { position:relative; height:27px; margin:0 2px 2px; }
.bs-craps-puck { position:absolute; top:50%; left:7.143%; transform:translate(-50%,-50%);
  display:flex; align-items:center; justify-content:center; width:40px; height:25px; border-radius:999px;
  font-size:9px; font-weight:900; letter-spacing:.14em;
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel)); color:var(--bs-faint);
  border:2px solid var(--bs-line);
  box-shadow:0 4px 9px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.09);
  transition:left .58s cubic-bezier(.62,-0.3,.35,1.3), background .35s, color .35s, border-color .35s, box-shadow .35s; }
.bs-craps-puck::after { content:''; position:absolute; bottom:-9px; left:50%; margin-left:-5px;
  border:5px solid transparent; border-top-color:var(--bs-line); transition:border-top-color .35s; }
.bs-craps-puck.on { background:linear-gradient(180deg, var(--bs-orange-br), var(--bs-orange));
  border-color:var(--bs-orange-br); color:var(--bs-on-orange);
  box-shadow:0 5px 14px rgba(0,0,0,.5), 0 0 0 1px var(--bs-orange-br), inset 0 1px 0 rgba(255,255,255,.28);
  animation:bs-craps-puck-set .5s cubic-bezier(.2,.9,.3,1.5); }
.bs-craps-puck.on::after { border-top-color:var(--bs-orange); }
@keyframes bs-craps-puck-set {
  0%   { transform:translate(-50%,-50%) scale(1); }
  45%  { transform:translate(-50%,-64%) scale(1.16); }
  100% { transform:translate(-50%,-50%) scale(1); }
}

.bs-craps-boxes { display:grid; grid-template-columns:repeat(7,1fr); gap:5px; margin:0 2px 11px; }
.bs-craps-home { align-self:center; justify-self:center; width:24px; height:24px; border-radius:50%;
  border:1px dashed var(--bs-line); background:rgba(0,0,0,.28);
  box-shadow:inset 0 2px 5px rgba(0,0,0,.5); }
.bs-craps-box { display:flex; align-items:center; justify-content:center; height:35px; border-radius:9px;
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  border:1px solid var(--bs-line); color:var(--bs-muted);
  font-size:17px; font-weight:900; font-variant-numeric:tabular-nums; line-height:1;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06), inset 0 -8px 14px rgba(0,0,0,.38);
  transition:color .3s, border-color .3s, background .3s; }
.bs-craps-box.on { color:var(--bs-gold-ink); border-color:var(--bs-gold);
  background:linear-gradient(180deg, var(--bs-elev), var(--bs-well));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08), inset 0 -8px 16px rgba(0,0,0,.55); }

/* ---- The dice pit (sunken well with a pyramid-rubber back wall) ----------- */
.bs-craps-pit { position:relative; overflow:hidden; padding:8px 10px 11px; margin:0 0 10px; border-radius:12px;
  background:radial-gradient(ellipse at 50% -20%, rgba(255,255,255,.07), transparent 60%), var(--bs-well);
  border:1px solid var(--bs-line);
  box-shadow:inset 0 3px 18px rgba(0,0,0,.9), inset 0 0 0 1px rgba(255,255,255,.03);
  transition:border-color .3s, box-shadow .3s; }
.bs-craps-wall { position:absolute; left:0; right:0; top:0; height:9px; opacity:.5; pointer-events:none;
  background:repeating-linear-gradient(135deg, var(--bs-line) 0 2px, transparent 2px 7px); }
.bs-craps-pit .bs-dice-tray { background:transparent; border:0; margin:0; padding:14px 4px 8px; gap:22px; }
.bs-craps-pit .bs-die { transform:rotate(var(--bs-craps-rot, 0deg));
  filter:drop-shadow(0 8px 12px rgba(0,0,0,.65)); }
.bs-craps-pit .bs-die.bs-craps-die-set { animation:bs-craps-land .46s cubic-bezier(.2,.85,.3,1.35) both; }
@keyframes bs-craps-land {
  0%   { transform:translateY(-20px) rotate(calc(var(--bs-craps-rot, 0deg) - 200deg)) scale(.78); opacity:.35; }
  62%  { transform:translateY(4px) rotate(calc(var(--bs-craps-rot, 0deg) + 10deg)) scale(1.05); opacity:1; }
  100% { transform:translateY(0) rotate(var(--bs-craps-rot, 0deg)) scale(1); opacity:1; }
}
.bs-craps-pit.won { border-color:var(--bs-gold);
  box-shadow:inset 0 3px 18px rgba(0,0,0,.9), 0 0 0 1px var(--bs-gold), 0 8px 26px rgba(0,0,0,.5); }
.bs-craps-pit.lost { border-color:var(--bs-neg); }
.bs-craps-pit.won::after, .bs-craps-pit.lost::after { content:''; position:absolute; inset:0; pointer-events:none;
  animation:bs-craps-flash .8s ease-out both; }
.bs-craps-pit.won::after  { background:radial-gradient(ellipse at 50% 55%, var(--bs-gold), transparent 70%); }
.bs-craps-pit.lost::after { background:radial-gradient(ellipse at 50% 55%, var(--bs-neg), transparent 70%); }
@keyframes bs-craps-flash { 0% { opacity:.34; } 100% { opacity:0; } }

/* The one number that dominates the screen. */
.bs-craps-total { position:relative; display:flex; align-items:center; justify-content:center; gap:11px;
  min-height:44px; margin:0; text-align:center; }
.bs-craps-total-num { font-size:44px; font-weight:900; line-height:1; letter-spacing:-.03em; color:var(--bs-text);
  font-variant-numeric:tabular-nums; text-shadow:0 3px 14px rgba(0,0,0,.8); }
.bs-craps-pit.won .bs-craps-total-num  { color:var(--bs-gold-ink); }
.bs-craps-pit.lost .bs-craps-total-num { color:var(--bs-muted); }
.bs-craps-total-meta { display:flex; flex-direction:column; align-items:flex-start; gap:3px; }
.bs-craps-total-meta b { font-size:9px; font-weight:900; letter-spacing:.15em; text-transform:uppercase; color:var(--bs-faint); }
.bs-craps-total-meta i { font-style:normal; font-size:9px; font-weight:900; letter-spacing:.1em; text-transform:uppercase;
  color:var(--bs-orange); padding:3px 8px; border-radius:999px;
  border:1px solid var(--bs-orange-br); background:var(--bs-soft); }
.bs-craps-total-lbl { font-size:11px; font-weight:900; letter-spacing:.18em; text-transform:uppercase;
  color:var(--bs-faint); margin:0; }

/* ---- Shooter's roll strip ------------------------------------------------- */
.bs-craps-hist { display:flex; align-items:center; gap:8px; margin:0 2px 10px; }
.bs-craps-hist-lbl { flex:none; font-size:9px; font-weight:900; letter-spacing:.14em; text-transform:uppercase; color:var(--bs-faint); }
.bs-craps-hist-row { display:flex; gap:4px; overflow-x:auto; scrollbar-width:none; }
.bs-craps-hist-row::-webkit-scrollbar { display:none; }
.bs-craps-hist-pip { flex:none; display:inline-flex; align-items:center; justify-content:center;
  min-width:21px; height:21px; padding:0 4px; border-radius:6px; font-style:normal;
  font-size:11px; font-weight:800; font-variant-numeric:tabular-nums;
  background:var(--bs-elev); border:1px solid var(--bs-line); color:var(--bs-muted); }
.bs-craps-hist-pip.pt { color:var(--bs-gold-ink); border-color:var(--bs-gold); }
.bs-craps-hist-pip.seven { color:var(--bs-neg); border-color:var(--bs-neg); }
.bs-craps-hist-pip.last { box-shadow:0 0 0 1px var(--bs-orange-br); }

.bs-craps-divider { margin:0 8px 11px; }

/* ---- PASS LINE / DON'T PASS bars ----------------------------------------- */
.bs-craps-lines { display:flex; flex-direction:column; gap:8px; }
.bs-craps-line { position:relative; box-sizing:border-box; width:100%; overflow:hidden;
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:10px 12px 10px 16px; border-radius:11px; cursor:pointer; text-align:left;
  font:inherit; color:var(--bs-text); -webkit-appearance:none; appearance:none;
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  border:1px solid var(--bs-line);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06), 0 3px 10px rgba(0,0,0,.38);
  transition:transform .14s, border-color .2s, box-shadow .2s, background .2s; }
.bs-craps-line::before { content:''; position:absolute; left:0; top:0; bottom:0; width:4px;
  background:var(--bs-line); transition:background .25s; }
.bs-craps-line:hover:not([disabled]) { transform:translateY(-2px); border-color:var(--bs-orange-br); }
.bs-craps-line:active:not([disabled]) { transform:translateY(0) scale(.995); }
.bs-craps-line-txt { display:flex; flex-direction:column; gap:3px; min-width:0; }
.bs-craps-line-txt b { font-size:13px; font-weight:900; letter-spacing:.14em; text-transform:uppercase; line-height:1.15; }
.bs-craps-line-txt i { font-style:normal; font-size:10px; font-weight:700; letter-spacing:.05em; color:var(--bs-faint); }
.bs-craps-line.on { border-color:var(--bs-orange-br);
  background:linear-gradient(180deg, var(--bs-soft), var(--bs-panel));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09), 0 0 0 1px var(--bs-orange-br), 0 6px 16px rgba(0,0,0,.45); }
.bs-craps-line.on::before { background:var(--bs-orange); }
.bs-craps-line.on .bs-craps-line-txt b { color:var(--bs-orange); }
.bs-craps-line.locked .bs-craps-line-txt i { color:var(--bs-orange); }
.bs-craps-line.paid { border-color:var(--bs-gold);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09), 0 0 0 1px var(--bs-gold), 0 6px 20px rgba(0,0,0,.5); }
.bs-craps-line.paid::before { background:var(--bs-gold); }
.bs-craps-line.paid .bs-craps-line-txt b { color:var(--bs-gold-ink); }
.bs-craps-line[disabled] { cursor:default; opacity:.45; }
.bs-craps-line.on[disabled] { opacity:1; }

/* The bet itself: a real chip sitting on the line. */
.bs-craps-stack { display:flex; align-items:center; gap:8px; flex:none; }
.bs-craps-stack b { font-size:12px; font-weight:900; color:var(--bs-text); font-variant-numeric:tabular-nums; }
.bs-craps-stack-empty { flex:none; width:26px; height:26px; border-radius:50%;
  border:1px dashed var(--bs-line); opacity:.55; }
.bs-craps-token { position:relative; flex:none; width:26px; height:26px; border-radius:50%;
  background:
    radial-gradient(circle at 50% 50%, var(--bs-orange-dp) 0 41%, transparent 42%),
    repeating-conic-gradient(var(--bs-orange) 0 30deg, #1a1207 30deg 60deg);
  box-shadow:0 3px 7px rgba(0,0,0,.6), inset 0 0 0 1px rgba(0,0,0,.35);
  animation:bs-craps-token-in .4s cubic-bezier(.2,.9,.3,1.5); }
.bs-craps-token::after { content:''; position:absolute; inset:5px; border-radius:50%;
  border:1px solid rgba(255,255,255,.24); }
@keyframes bs-craps-token-in {
  from { transform:translateY(-11px) rotate(-100deg) scale(.55); opacity:0; }
  to   { transform:none; opacity:1; }
}

/* ---- Result plate --------------------------------------------------------- */
.bs-craps-result { display:flex; align-items:center; justify-content:space-between; gap:12px;
  margin:11px 0 0; padding:9px 14px; border-radius:11px;
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  border:1px solid var(--bs-line); box-shadow:inset 0 1px 0 rgba(255,255,255,.05); }
.bs-craps-result-lbl { font-size:11px; font-weight:900; letter-spacing:.15em; text-transform:uppercase; color:var(--bs-muted); }
.bs-craps-result-zero { font-size:11px; font-weight:900; letter-spacing:.1em; text-transform:uppercase; color:var(--bs-faint); }
.bs-craps-payout { font-size:26px; line-height:1.05; }
.bs-craps-result-win { border-color:var(--bs-gold); background:linear-gradient(180deg, var(--bs-elev), var(--bs-panel)); }
.bs-craps-result-win .bs-craps-result-lbl { color:var(--bs-gold-ink); }
.bs-craps-result-lose .bs-craps-result-lbl { color:var(--bs-neg); }
.bs-craps-result-push .bs-craps-result-lbl { color:var(--bs-muted); }
.bs-craps-result-push .bs-craps-payout { color:var(--bs-text); text-shadow:none; }

/* ---- Controls ------------------------------------------------------------- */
.bs-btn.bs-craps-roll { min-width:158px; font-weight:900; letter-spacing:.05em; }
.bs-slot-ctrls .bs-craps-roll { flex:0 1 auto; }

@media (max-width:420px) {
  .bs-craps-felt { padding:10px 9px 11px; }
  .bs-craps-yourbet { letter-spacing:.04em; }
  .bs-craps-lane { height:24px; margin:0 0 2px; }
  .bs-craps-puck { width:34px; height:22px; font-size:8px; letter-spacing:.1em; border-width:2px; }
  .bs-craps-boxes { gap:4px; margin:0 0 10px; }
  .bs-craps-box { height:31px; font-size:15px; border-radius:7px; }
  .bs-craps-home { width:20px; height:20px; }
  .bs-craps-pit { padding:7px 7px 10px; }
  .bs-craps-pit .bs-die-face { width:56px; height:56px; }
  .bs-craps-pit .bs-dice-tray { gap:16px; padding:12px 4px 6px; }
  .bs-craps-total-num { font-size:36px; }
  .bs-craps-hist-lbl { display:none; }
  .bs-craps-divider { margin:0 2px 10px; }
  .bs-craps-line { padding:9px 10px 9px 14px; }
  .bs-craps-line-txt b { font-size:12px; letter-spacing:.08em; }
  .bs-craps-payout { font-size:22px; }
  .bs-craps-result { padding:8px 11px; }
  .bs-btn.bs-craps-roll { min-width:120px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-craps-puck, .bs-craps-puck::after, .bs-craps-line, .bs-craps-box,
  .bs-craps-phase-tag, .bs-craps-pit { transition:none !important; }
  .bs-craps-puck.on, .bs-craps-token, .bs-craps-pit .bs-die.bs-craps-die-set,
  .bs-craps-pit.won::after, .bs-craps-pit.lost::after { animation:none !important; }
  .bs-craps-pit.won::after, .bs-craps-pit.lost::after { opacity:0; }
  .bs-craps-line:hover:not([disabled]) { transform:none; }
}
/* ============================================================================
   SLOTS — a real cabinet, not a text box. Lit marquee, three separately
   bevelled reel wells behind glass on a single payline, motion-blurred reels
   that stop left-to-right, and a payout panel that scales with the win.
   Every colour is a --bs-* token so all 10 skins keep working; the only fixed
   colours are the inner well (var(--bs-well), as the other stages use) and
   neutral black/white alpha for glass, shadow and bevel.
   ========================================================================== */
.bs-slot-mach { position:relative; overflow:hidden; margin-bottom:12px;
  padding:9px 10px 11px; border:1px solid var(--bs-line); border-radius:16px;
  background:radial-gradient(125% 85% at 50% -18%, var(--bs-elev2), var(--bs-elev) 52%, var(--bs-panel) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07), inset 0 -26px 42px rgba(0,0,0,.5), 0 14px 30px rgba(0,0,0,.34); }
/* Cabinet vignette — keeps the reels the brightest thing on the stage. */
.bs-slot-mach::after { content:''; position:absolute; inset:0; z-index:2; pointer-events:none; border-radius:inherit;
  background:radial-gradient(120% 92% at 50% 42%, transparent 44%, rgba(0,0,0,.44) 100%); }

/* ---- Topper: bulb runs either side of a lit marquee ---------------------- */
.bs-slot-topper { position:relative; z-index:1; display:flex; align-items:center; justify-content:center;
  gap:9px; padding:3px 2px 9px; }
.bs-slot-bulbs { display:inline-flex; gap:6px; flex:0 0 auto; }
.bs-slot-bulb { width:6px; height:6px; border-radius:50%; background:var(--bs-soft);
  animation:bs-slot-bulb 1.8s ease-in-out infinite; }
.bs-slot-bulb:nth-child(2) { animation-delay:.15s; }
.bs-slot-bulb:nth-child(3) { animation-delay:.30s; }
.bs-slot-bulb:nth-child(4) { animation-delay:.45s; }
.bs-slot-bulb:nth-child(5) { animation-delay:.60s; }
@keyframes bs-slot-bulb {
  0%,100% { background:var(--bs-soft); box-shadow:none; }
  50%     { background:var(--bs-gold); box-shadow:0 0 9px var(--bs-gold); }
}
.bs-slot-marquee { flex:0 1 auto; min-width:0; max-width:56%; padding:3px 12px; border-radius:9px;
  border:1px solid var(--bs-line); color:var(--bs-gold-ink);
  background:linear-gradient(180deg, rgba(255,255,255,.08), rgba(255,255,255,0));
  font-size:12px; font-weight:900; letter-spacing:.17em; text-transform:uppercase;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; text-shadow:0 0 14px currentColor; }
.bs-slot-mach-fs .bs-slot-marquee { border-color:var(--bs-gold); }

/* ---- Reel window: the near-black well the payline runs through ----------- */
.bs-slot-window { position:relative; z-index:1; padding:9px 30px; border-radius:12px;
  background:var(--bs-well); border:1px solid var(--bs-line);
  box-shadow:inset 0 4px 14px rgba(0,0,0,.9), inset 0 -4px 14px rgba(0,0,0,.9), 0 1px 0 rgba(255,255,255,.05);
  transition:box-shadow .3s, border-color .3s; }
.bs-slot-window-tease { border-color:var(--bs-gold); box-shadow:inset 0 4px 14px rgba(0,0,0,.9), 0 0 24px -8px var(--bs-gold); }
/* Sits UNDER the reels, so it reads through the gutters and the gaps — the way
   a real single-line machine draws its payline. */
.bs-slot-payline { position:absolute; left:10px; right:10px; top:50%; margin-top:-1px; height:2px; z-index:0;
  border-radius:2px; color:var(--bs-orange); opacity:.4;
  background:linear-gradient(90deg, transparent, var(--bs-orange), transparent);
  transition:opacity .3s, background .3s, box-shadow .3s; }
.bs-slot-payline-hot { opacity:1; color:var(--bs-gold-ink);
  background:linear-gradient(90deg, transparent, var(--bs-gold), transparent);
  box-shadow:0 0 18px currentColor; }
.bs-slot-mark { position:absolute; top:50%; z-index:2; transform:translateY(-50%); font-size:10px; line-height:1;
  color:var(--bs-soft); transition:color .3s, text-shadow .3s; }
.bs-slot-mark-l { left:11px; }
.bs-slot-mark-r { right:11px; }
.bs-slot-mach-hot .bs-slot-mark { color:var(--bs-gold-ink); text-shadow:0 0 10px currentColor; }

/* ---- Three separate bevelled reels --------------------------------------- */
.bs-slot-reels { position:relative; z-index:1; display:flex; gap:8px; }
.bs-slot-reel { position:relative; flex:1 1 0; min-width:0; height:96px; overflow:hidden; border-radius:9px;
  border:1px solid var(--bs-line); background-color:var(--bs-well);
  background-image:linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,0) 38%, rgba(0,0,0,.55));
  box-shadow:inset 0 3px 9px rgba(0,0,0,.9), inset 0 -3px 9px rgba(0,0,0,.9), 0 1px 0 rgba(255,255,255,.04);
  transition:box-shadow .3s, border-color .3s; }
/* Curved glass in front of the strip. */
.bs-slot-reel-glass { position:absolute; inset:0; z-index:3; pointer-events:none; border-radius:inherit;
  background:linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,.03) 20%, transparent 46%, rgba(0,0,0,.4)); }
.bs-slot-strip { position:absolute; left:0; right:0; top:0; z-index:1;
  display:flex; flex-direction:column; transform:translateY(-33.333%); will-change:transform; }
.bs-slot-cell { height:96px; display:flex; align-items:center; justify-content:center; }
.bs-slot-cell-ghost { opacity:.3; }
.bs-slot-glyph { display:block; font-size:44px; line-height:1;
  filter:drop-shadow(0 3px 6px rgba(0,0,0,.75)); }
.bs-slot-glyph-mono { font-size:32px; font-weight:900; letter-spacing:.02em; color:var(--bs-gold-ink); }

.bs-slot-reel-spin { border-color:var(--bs-soft); }
.bs-slot-reel-spin .bs-slot-strip { animation:bs-slot-spin .15s linear infinite; filter:blur(1.3px); }
@keyframes bs-slot-spin { from { transform:translateY(-66.667%); } to { transform:translateY(0); } }

/* Near-miss hold: reels 1+2 already matched, so reel 3 slows and burns gold. */
.bs-slot-reel-tease { border-color:var(--bs-gold);
  box-shadow:inset 0 3px 9px rgba(0,0,0,.9), 0 0 20px -3px var(--bs-gold);
  animation:bs-slot-tease .62s ease-in-out infinite; }
.bs-slot-reel-tease .bs-slot-strip { animation-duration:.42s; filter:blur(.5px); }
@keyframes bs-slot-tease { 0%,100% { filter:brightness(1); } 50% { filter:brightness(1.32); } }

.bs-slot-reel-land .bs-slot-strip { animation:bs-slot-land .44s cubic-bezier(.2,.85,.3,1.2); }
@keyframes bs-slot-land {
  0%   { transform:translateY(-54%); }
  55%  { transform:translateY(-28.5%); }
  78%  { transform:translateY(-35.5%); }
  100% { transform:translateY(-33.333%); }
}

/* ---- Win state ----------------------------------------------------------- */
.bs-slot-mach-hot .bs-slot-reel { border-color:var(--bs-gold);
  box-shadow:inset 0 3px 9px rgba(0,0,0,.85), 0 0 18px -4px var(--bs-gold); }
.bs-slot-mach-hot .bs-slot-cell-main .bs-slot-glyph { animation:bs-slot-hit 1.15s ease-in-out infinite; }
@keyframes bs-slot-hit { 0%,100% { transform:scale(1); } 50% { transform:scale(1.09); } }
.bs-slot-mach-jp { border-color:var(--bs-gold); }
.bs-slot-mach-jp::before { content:''; position:absolute; inset:-45%; z-index:0; pointer-events:none; opacity:.2;
  background:conic-gradient(from 0deg, transparent 0 68%, var(--bs-gold) 80%, transparent 90%);
  animation:bs-slot-sweep 2.8s linear infinite; }
@keyframes bs-slot-sweep { to { transform:rotate(360deg); } }

/* ---- Lower deck: stake / last win / free spins ---------------------------- */
.bs-slot-rail { position:relative; z-index:1; margin:10px 4px 9px; }
.bs-slot-deck { position:relative; z-index:1; display:flex; gap:7px; }
.bs-slot-deck-cell { flex:1 1 0; min-width:0; padding:6px 6px 7px; text-align:center; }
.bs-slot-deck-k { display:block; font-size:9px; font-weight:900; letter-spacing:.12em; text-transform:uppercase;
  color:var(--bs-faint); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.bs-slot-deck-v { display:block; margin-top:2px; font-size:14px; font-weight:900; color:var(--bs-text);
  font-variant-numeric:tabular-nums; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.bs-slot-deck-hot .bs-slot-deck-v { color:var(--bs-gold-ink); text-shadow:0 0 12px currentColor; }

/* ---- The beat between commit and payoff ---------------------------------- */
.bs-slot-anticip { border:1px solid var(--bs-line); border-radius:12px; padding:8px 12px;
  color:var(--bs-text); letter-spacing:.03em; background:rgba(0,0,0,.22); }

.bs-slot-result { position:relative; display:flex; flex-direction:column; align-items:center; gap:3px;
  margin:12px 0 10px; padding:10px 12px 11px; border-radius:14px; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,0)); }
.bs-slot-result-label { font-size:10px; font-weight:900; letter-spacing:.2em; text-transform:uppercase;
  color:var(--bs-muted); }
.bs-slot-result-win { border-color:var(--bs-gold);
  box-shadow:0 0 30px -10px var(--bs-gold), inset 0 0 26px -16px var(--bs-gold); }
.bs-slot-result-win .bs-slot-result-label { color:var(--bs-gold-ink); }
.bs-slot-payout { font-variant-numeric:tabular-nums; }
/* A sub-stake return is money back, not a win — it must not look like one. */
.bs-slot-result-flat .bs-slot-payout { font-size:23px; color:var(--bs-text); text-shadow:none; }
.bs-slot-multi { padding:2px 11px; border-radius:999px; border:1px solid var(--bs-line);
  background:rgba(0,0,0,.28); font-size:12.5px; font-weight:900; color:var(--bs-muted);
  font-variant-numeric:tabular-nums; }
.bs-slot-result-win .bs-slot-multi { color:var(--bs-gold-ink); border-color:var(--bs-gold); }
.bs-slot-note { font-size:11px; color:var(--bs-muted); }
.bs-slot-ribbon { padding:3px 15px; border-radius:999px; color:var(--bs-on-orange);
  background:linear-gradient(180deg, var(--bs-gold), var(--bs-orange));
  box-shadow:0 7px 18px -7px var(--bs-gold);
  font-size:11px; font-weight:900; letter-spacing:.24em; text-transform:uppercase;
  animation:bs-slot-ribbon 1.25s ease-in-out infinite; }
@keyframes bs-slot-ribbon { 0%,100% { transform:translateY(0) scale(1); } 50% { transform:translateY(-2px) scale(1.045); } }

/* ---- Controls ------------------------------------------------------------ */
.bs-slot-actions { display:flex; gap:8px; flex-wrap:wrap; justify-content:center; }
.bs-slot-actions .bs-slot-spin { min-width:132px; font-weight:900; letter-spacing:.06em; text-transform:uppercase; }
.bs-slot-actions .bs-slot-fs-btn { border-color:var(--bs-gold); color:var(--bs-gold-ink); }
.bs-slot-actions .bs-slot-fs-btn:hover { border-color:var(--bs-orange); color:var(--bs-orange); }
.bs-slot-actions .bs-btn[disabled] { opacity:.42; cursor:not-allowed; filter:grayscale(.4); box-shadow:none; }

@media (max-width:420px) {
  .bs-slot-reel, .bs-slot-cell { height:78px; }
  .bs-slot-glyph { font-size:35px; }
  .bs-slot-glyph-mono { font-size:26px; }
  .bs-slot-window { padding:8px 22px; }
  .bs-slot-reels { gap:6px; }
  .bs-slot-marquee { max-width:48%; font-size:10px; letter-spacing:.1em; }
  .bs-slot-bulbs { gap:4px; }
  .bs-slot-deck-v { font-size:12.5px; }
  .bs-slot-actions { width:100%; }
  .bs-slot-actions .bs-slot-spin, .bs-slot-actions .bs-slot-fs-btn { flex:1 1 100%; min-width:0; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-slot-bulb, .bs-slot-ribbon, .bs-slot-mach-jp::before,
  .bs-slot-reel-tease, .bs-slot-mach-hot .bs-slot-cell-main .bs-slot-glyph { animation:none !important; }
  .bs-slot-reel-land .bs-slot-strip { animation:none !important; }
  .bs-slot-reel-spin .bs-slot-strip { animation-duration:.6s; filter:none; }
}
/* ============================================================================
   KENO v2 — draw machine, ivory lottery balls, engraved ticket, prize ladder
   Second pass over the original Keno block above: same markup contract, deeper
   materials. Every colour is a --bs-* token except the physical ball shell /
   printed ink and the near-black inner-well, exactly as the shared toolkit
   stages already do, so all 10 operator skins keep driving it.
   ========================================================================== */

/* ---- The table the round sits on ---------------------------------------- */
.bs-keno-board { position:relative; overflow:hidden; padding:12px 11px; margin-bottom:10px;
  border:1px solid var(--bs-line); border-radius:16px;
  background:
    radial-gradient(125% 88% at 50% 46%, rgba(0,0,0,0) 38%, rgba(0,0,0,.55) 100%),
    radial-gradient(130% 90% at 50% -18%, rgba(255,255,255,.08), rgba(255,255,255,0) 58%),
    linear-gradient(180deg, var(--bs-elev) 0%, var(--bs-well) 92%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.055), inset 0 0 58px rgba(0,0,0,.6),
    0 14px 30px -20px rgba(0,0,0,.95);
  transition: box-shadow .3s ease; }
.bs-keno-board.is-win { box-shadow: inset 0 1px 0 rgba(255,255,255,.055), inset 0 0 58px rgba(0,0,0,.5),
  0 0 0 1px var(--bs-pos), 0 0 36px -10px var(--bs-pos), 0 14px 30px -20px rgba(0,0,0,.95); }

/* ---- Hopper header: label + drum + status readout ------------------------ */
.bs-keno-hopper { position:relative; display:flex; align-items:center; justify-content:space-between;
  gap:8px; margin:0 2px 7px; }
.bs-keno-hopper-lab { display:flex; align-items:center; gap:7px; min-width:0;
  font-size:10px; font-weight:900; letter-spacing:.15em; text-transform:uppercase; color:var(--bs-muted);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.bs-keno-drum { flex:none; display:block; width:13px; height:13px; border-radius:50%;
  border:2px solid var(--bs-soft); border-top-color:var(--bs-orange);
  background:radial-gradient(circle at 34% 30%, rgba(255,255,255,.2), rgba(255,255,255,0) 62%); }
.bs-keno-board.is-drawing .bs-keno-drum { border-top-color:var(--bs-orange-br);
  animation:bs-keno-drum-spin .72s linear infinite; }
@keyframes bs-keno-drum-spin { to { transform:rotate(360deg); } }
.bs-keno-status { flex:none; font-size:10px; font-weight:900; letter-spacing:.13em; text-transform:uppercase;
  color:var(--bs-faint); font-variant-numeric:tabular-nums; }
.bs-keno-board.is-drawing .bs-keno-status { color:var(--bs-orange); }
.bs-keno-board.is-win .bs-keno-status { color:var(--bs-pos); }
.bs-keno-rule { position:relative; margin:0 0 9px; }

/* ---- Draw rail: a recessed tray the balls drop into ---------------------- */
.bs-keno-rail { position:relative; overflow:hidden; display:flex; flex-wrap:wrap; gap:6px;
  align-items:center; justify-content:center; min-height:52px; padding:9px 10px; margin-bottom:9px;
  border:1px solid var(--bs-line); border-radius:16px;
  background:linear-gradient(180deg, rgba(0,0,0,.6), rgba(0,0,0,.26));
  box-shadow: inset 0 4px 9px rgba(0,0,0,.72), inset 0 -1px 0 rgba(255,255,255,.05); }
.bs-keno-slot { flex:none; width:30px; height:30px; border-radius:50%; opacity:1;
  border:1px solid var(--bs-line);
  background:radial-gradient(circle at 50% 38%, rgba(0,0,0,.6), rgba(0,0,0,.12));
  box-shadow: inset 0 2px 5px rgba(0,0,0,.7); }
.bs-keno-rail.is-drawing .bs-keno-slot { animation:bs-keno-socket 1.3s ease-in-out infinite; }
@keyframes bs-keno-socket { 0%,100% { opacity:.5; } 50% { opacity:.9; } }

/* Ivory lottery ball: shell, specular, printed number disc. The shell and the
   printed ink are physical-object colours (same licence as the ivory die faces
   in the shared toolkit); the matched state is driven by var(--bs-pos) so the
   skin still owns the "hit" semantic. */
.bs-keno-ball { position:relative; flex:none; width:30px; height:30px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background-color:#e9e3d4;
  background-image:radial-gradient(circle at 33% 26%, #ffffff 0%, #f4eddd 32%, #cec5b1 76%, #a69c87 100%);
  box-shadow:0 5px 12px rgba(0,0,0,.55), inset 0 -4px 7px rgba(0,0,0,.22),
    inset 0 3px 5px rgba(255,255,255,.75); }
.bs-keno-ball::after { content:''; position:absolute; top:13%; left:21%; width:31%; height:22%;
  border-radius:50%; transform:rotate(-18deg); pointer-events:none;
  background:linear-gradient(180deg, rgba(255,255,255,.95), rgba(255,255,255,0)); }
.bs-keno-ball-disc { position:relative; z-index:1; display:flex; align-items:center; justify-content:center;
  width:70%; height:70%; border-radius:50%; font-style:normal; font-size:11px; font-weight:900;
  letter-spacing:-.03em; color:var(--bs-on-gold); font-variant-numeric:tabular-nums;
  background:rgba(255,255,255,.5); box-shadow:inset 0 0 0 1px rgba(0,0,0,.13); }
.bs-keno-ball.hit { background-color:var(--bs-pos);
  background-image:radial-gradient(circle at 33% 26%, rgba(255,255,255,.9) 0%, rgba(255,255,255,.22) 34%, rgba(0,0,0,.22) 84%);
  box-shadow:0 5px 12px rgba(0,0,0,.55), 0 0 20px -3px var(--bs-pos),
    inset 0 -4px 7px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.35); }
.bs-keno-ball.hit .bs-keno-ball-disc { background:rgba(255,255,255,.92); box-shadow:inset 0 0 0 1px rgba(0,0,0,.2); }
.bs-keno-ball-in { animation:bs-keno-ball-land .42s cubic-bezier(.18,.85,.28,1.35); }
@keyframes bs-keno-ball-land {
  0% { transform:translateY(-26px) scale(.55); opacity:0; }
  55% { transform:translateY(3px) scale(1.1); opacity:1; }
  78% { transform:translateY(-2px) scale(.98); }
  100% { transform:none; opacity:1; } }
.bs-keno-ball.hit.bs-keno-ball-in::before { content:''; position:absolute; inset:-4px; border-radius:50%;
  border:2px solid var(--bs-pos); pointer-events:none;
  animation:bs-keno-ring .62s ease-out forwards; }
@keyframes bs-keno-ring { from { transform:scale(.7); opacity:.9; } to { transform:scale(1.75); opacity:0; } }

/* ---- Live counters ------------------------------------------------------- */
.bs-keno-stats { position:relative; display:flex; gap:5px; margin-bottom:9px; }
.bs-keno-stat { flex:1 1 0; min-width:0; display:flex; flex-direction:column; align-items:center; gap:2px;
  padding:6px 3px 5px; border-radius:9px; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.012));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);
  transition: box-shadow .22s ease, border-color .22s ease; }
.bs-keno-stat-v { font-size:16px; font-weight:900; line-height:1; color:var(--bs-text);
  font-variant-numeric:tabular-nums; }
.bs-keno-stat-k { font-size:8px; font-weight:800; letter-spacing:.11em; text-transform:uppercase;
  color:var(--bs-faint); }
.bs-keno-stat-hits .bs-keno-stat-v { color:var(--bs-pos); }
.bs-keno-stat-pays .bs-keno-stat-v { font-size:14px; color:var(--bs-muted); }
.bs-keno-stat-pays.is-live { border-color:var(--bs-gold);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), 0 0 18px -6px var(--bs-gold); }
.bs-keno-stat-pays.is-live .bs-keno-stat-v { color:var(--bs-gold-ink); }

/* ---- The ticket ---------------------------------------------------------- */
.bs-keno-ticket { position:relative; padding:9px 7px 7px; border-radius:12px;
  border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.035), rgba(0,0,0,.28));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05), inset 0 -10px 20px rgba(0,0,0,.4); }
.bs-keno-ticket::before { content:''; position:absolute; left:10px; right:10px; top:-1px; height:4px;
  pointer-events:none; background-repeat:repeat-x; background-size:8px 8px; background-position:0 -2px;
  background-image:radial-gradient(circle, var(--bs-bg) 45%, rgba(0,0,0,0) 47%); }
.bs-keno-ticket-head { position:relative; display:flex; align-items:center; justify-content:space-between;
  gap:8px; margin:0 3px 8px; font-size:9px; font-weight:800; letter-spacing:.12em; text-transform:uppercase;
  color:var(--bs-faint); }
.bs-keno-ticket-head b { color:var(--bs-orange); font-variant-numeric:tabular-nums; }

.bs-keno-grid { display:grid; grid-template-columns:repeat(8,1fr); gap:4px; margin:0; }
.bs-keno-num, .bs-keno-num.picked, .bs-keno-num.drawn, .bs-keno-num.hit {
  background:linear-gradient(180deg, var(--bs-elev2) 0%, var(--bs-panel) 100%); }
.bs-keno-num { position:relative; overflow:hidden; aspect-ratio:1; display:flex; align-items:center;
  justify-content:center; padding:0; border:1px solid var(--bs-line); border-radius:9px;
  color:var(--bs-muted); font-size:12px; font-weight:800; font-variant-numeric:tabular-nums; cursor:pointer;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06), 0 2px 5px rgba(0,0,0,.35);
  transition: transform .13s ease, box-shadow .18s ease, opacity .18s ease,
    border-color .18s ease, color .18s ease; }
.bs-keno-num-v { position:relative; z-index:2; }
.bs-keno-num:hover { transform:translateY(-1px); border-color:var(--bs-orange); color:var(--bs-text); }
.bs-keno-num.picked { border-color:var(--bs-orange); color:var(--bs-on-orange);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 4px 12px -3px rgba(0,0,0,.6),
    0 0 14px -6px var(--bs-orange); }
.bs-keno-num.picked::before { content:''; position:absolute; inset:0; z-index:1;
  background:linear-gradient(180deg, var(--bs-orange-br), var(--bs-orange-dp)); }
.bs-keno-num.is-locked { opacity:.4; cursor:default; }
.bs-keno-num.is-locked:hover { transform:none; border-color:var(--bs-line); color:var(--bs-muted); }
.bs-keno-num.drawn { opacity:.72; border-color:var(--bs-soft); color:var(--bs-muted); outline:none;
  box-shadow: inset 0 0 0 2px var(--bs-soft), inset 0 2px 6px rgba(0,0,0,.5); }
.bs-keno-num.hit { border-color:var(--bs-pos); color:var(--bs-text); opacity:1; outline:none;
  box-shadow: inset 0 0 0 2px var(--bs-pos), 0 0 20px -5px var(--bs-pos), 0 4px 12px -3px rgba(0,0,0,.6); }
.bs-keno-num.hit::before { content:''; position:absolute; inset:0; z-index:1; opacity:.55;
  background:linear-gradient(180deg, var(--bs-pos), rgba(0,0,0,.3)); }
.bs-keno-num.drawing { z-index:3; animation:bs-keno-num-land .42s cubic-bezier(.2,.9,.3,1.5); }
@keyframes bs-keno-num-land { 0% { transform:scale(.82); } 50% { transform:scale(1.22); } 100% { transform:scale(1); } }

/* While the hopper runs the ticket is inert, unpicked cells recede and the
   player's own spots stay lit — all the tension sits on the numbers they chose. */
.bs-keno-board.is-drawing .bs-keno-grid { pointer-events:none; }
.bs-keno-board.is-drawing .bs-keno-num:not(.picked) { opacity:.5; }
.bs-keno-board.is-drawing .bs-keno-num.picked:not(.hit) { animation:bs-keno-armed 1.5s ease-in-out infinite; }
@keyframes bs-keno-armed {
  0%,100% { box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 0 13px -6px var(--bs-orange); }
  50% { box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 0 22px -2px var(--bs-orange); } }

/* ---- Prize ladder — the payout visibly builds as hits accumulate ---------- */
.bs-keno-ladder { display:flex; align-items:center; gap:8px; margin:0 0 10px; }
.bs-keno-ladder-lab { flex:none; font-size:9px; font-weight:900; letter-spacing:.12em;
  text-transform:uppercase; color:var(--bs-faint); }
.bs-keno-rungs { flex:1 1 auto; min-width:0; display:flex; gap:4px; padding:2px;
  overflow-x:auto; scrollbar-width:none; -ms-overflow-style:none; }
.bs-keno-rungs::-webkit-scrollbar { display:none; }
.bs-keno-rung { flex:1 0 auto; min-width:38px; display:flex; flex-direction:column; align-items:center; gap:1px;
  padding:4px 3px; border-radius:8px; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease, opacity .2s ease; }
.bs-keno-rung-k { font-size:9px; font-weight:900; color:var(--bs-faint); font-variant-numeric:tabular-nums; }
.bs-keno-rung-v { font-size:10px; font-weight:900; letter-spacing:-.02em; color:var(--bs-muted);
  font-variant-numeric:tabular-nums; }
.bs-keno-rung.is-passed { opacity:.5; border-color:var(--bs-soft); }
.bs-keno-rung.is-live { transform:translateY(-2px); border-color:var(--bs-gold);
  box-shadow:0 0 18px -6px var(--bs-gold); }
.bs-keno-rung.is-live .bs-keno-rung-k, .bs-keno-rung.is-live .bs-keno-rung-v { color:var(--bs-gold-ink); }
.bs-keno-rung.is-won { transform:translateY(-2px); border-color:var(--bs-gold); opacity:1;
  background:linear-gradient(180deg, var(--bs-gold), var(--bs-orange-dp));
  box-shadow:0 0 26px -6px var(--bs-gold); }
.bs-keno-rung.is-won .bs-keno-rung-k, .bs-keno-rung.is-won .bs-keno-rung-v { color:var(--bs-on-orange); }
.bs-keno-ladder-empty { justify-content:center; padding:7px 10px; border:1px dashed var(--bs-line);
  border-radius:10px; font-size:9px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--bs-faint); text-align:center; }

/* ---- Payout plaque ------------------------------------------------------- */
.bs-keno-payout { display:flex; flex-direction:column; align-items:center; gap:3px;
  margin:0 0 10px; padding:11px 12px; border-radius:14px; border:1px solid var(--bs-gold);
  background:
    radial-gradient(120% 140% at 50% 0%, rgba(255,255,255,.1), rgba(255,255,255,0) 62%),
    linear-gradient(180deg, var(--bs-elev), var(--bs-panel));
  box-shadow:0 0 36px -14px var(--bs-gold), inset 0 1px 0 rgba(255,255,255,.09); }
.bs-keno-payout-lab { font-size:9px; font-weight:900; letter-spacing:.14em; text-transform:uppercase;
  color:var(--bs-muted); text-align:center; }

@media (max-width: 420px) {
  .bs-keno-board { padding:10px 8px; }
  .bs-keno-hopper-lab { letter-spacing:.1em; }
  .bs-keno-rail { gap:5px; padding:8px 7px; min-height:48px; }
  .bs-keno-ball, .bs-keno-slot { width:27px; height:27px; }
  .bs-keno-ball-disc { font-size:10px; }
  .bs-keno-num { font-size:11px; border-radius:8px; }
  .bs-keno-stats { gap:4px; }
  .bs-keno-stat-v { font-size:14px; }
  .bs-keno-stat-pays .bs-keno-stat-v { font-size:12px; }
  .bs-keno-ladder-lab { display:none; }
  .bs-keno-rung { min-width:34px; }
  .bs-keno-rung-v { font-size:9px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-keno-board.is-drawing .bs-keno-drum,
  .bs-keno-rail.is-drawing .bs-keno-slot,
  .bs-keno-board.is-drawing .bs-keno-num.picked:not(.hit),
  .bs-keno-ball-in,
  .bs-keno-ball.hit.bs-keno-ball-in::before,
  .bs-keno-num.drawing { animation: none !important; }
  .bs-keno-num, .bs-keno-rung, .bs-keno-stat, .bs-keno-board { transition: none !important; }
}
/* ============================================================================
   WHEEL — premium prize-wheel pass. Appended after the first-pass .bs-pw-*
   rules so it wins at equal specificity while inheriting everything it does
   not restate. Every colour is a var(--bs-*) token; the only literals are
   light and shadow (rgba white/black) and the var(--bs-well) inner well, exactly as
   the rest of the sheet already does.
   ========================================================================== */

/* ---- The table ---------------------------------------------------------- */
/* .bs-felt supplies the surface; this only lays it out and adds the vignette. */
.bs-pw-stage { display:flex; flex-direction:column; align-items:center; gap:11px;
  padding:18px 12px 15px; margin-bottom:10px; border-radius:14px; overflow:hidden; }
.bs-pw-stage::before { content:''; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  background:
    radial-gradient(120% 74% at 50% 2%, rgba(255,255,255,.055), rgba(0,0,0,0) 58%),
    radial-gradient(135% 105% at 50% 48%, rgba(0,0,0,0) 38%, rgba(0,0,0,.5) 100%); }
.bs-pw-stage > * { position:relative; z-index:1; }
.bs-pw-stage.bs-pw-stage-hit { box-shadow:inset 0 0 70px -22px var(--bs-orange-dp),
  inset 0 1px 0 rgba(255,255,255,.06), inset 0 -18px 34px rgba(0,0,0,.45); }

.bs-pw-tags { display:flex; width:100%; justify-content:space-between; align-items:center; gap:8px; }
.bs-pw-tag { font-size:9px; font-weight:800; letter-spacing:.11em; text-transform:uppercase;
  color:var(--bs-faint); padding:4px 9px; border-radius:999px; border:1px solid var(--bs-line);
  background:rgba(255,255,255,.028); white-space:nowrap; }
.bs-pw-tag b { color:var(--bs-text); font-weight:900; letter-spacing:.03em; }
.bs-pw-tag-top b { color:var(--bs-gold-ink); font-variant-numeric:tabular-nums; }

/* ---- The wheel itself --------------------------------------------------- */
.bs-pw-wrap { width:216px; height:216px; }
/* Brushed-metal outer bezel — a conic sweep of the skin's own neutrals. */
.bs-pw-bezel { position:absolute; inset:-15px; border-radius:50%; pointer-events:none;
  background:conic-gradient(var(--bs-elev2), var(--bs-soft) 11%, var(--bs-elev) 25%, var(--bs-soft) 41%,
    var(--bs-elev2) 54%, var(--bs-soft) 69%, var(--bs-elev) 83%, var(--bs-elev2));
  box-shadow:0 22px 46px rgba(0,0,0,.62), inset 0 1px 0 rgba(255,255,255,.09), inset 0 0 0 1px rgba(0,0,0,.4); }
.bs-pw-rim { position:absolute; inset:-9px; border-radius:50%; pointer-events:none;
  border:6px solid var(--bs-elev);
  box-shadow:inset 0 0 0 2px var(--bs-soft), inset 0 0 20px rgba(0,0,0,.65), 0 8px 20px rgba(0,0,0,.5); }
.bs-pw-halo { position:absolute; inset:-9px; border-radius:50%; border:2px solid var(--bs-orange); opacity:0; pointer-events:none; }

.bs-pw-wheel { position:relative; overflow:hidden; border-radius:50%; background-color:var(--bs-elev2);
  transition:transform 3s cubic-bezier(.15,.83,.12,1); will-change:transform;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.55), 0 0 0 1px var(--bs-soft), 0 16px 34px rgba(0,0,0,.6); }
.bs-pw-wheel.bs-pw-winding { transition:transform .35s cubic-bezier(.4,0,.2,1); }
/* Glass dome — a fixed light source that does NOT rotate with the face. */
.bs-pw-wrap::after { content:''; position:absolute; inset:0; border-radius:50%; pointer-events:none; z-index:1;
  background:
    radial-gradient(ellipse 76% 60% at 50% 7%, rgba(255,255,255,.15), rgba(255,255,255,0) 62%),
    radial-gradient(circle at 50% 52%, rgba(0,0,0,0) 56%, rgba(0,0,0,.42) 100%); }

/* Rim bulbs: brass studs at rest, chasing marquee while the wheel is in flight. */
.bs-pw-studs { position:absolute; inset:-9px; border-radius:50%; pointer-events:none; z-index:3; }
.bs-pw-stud { position:absolute; inset:0; display:flex; justify-content:center; }
.bs-pw-stud::before { content:''; width:5px; height:5px; margin-top:1px; border-radius:50%;
  background:radial-gradient(circle at 36% 30%, rgba(255,255,255,.85), var(--bs-soft) 60%, rgba(0,0,0,.65));
  box-shadow:0 0 0 1px rgba(0,0,0,.45); animation-delay:var(--bs-pw-d,0ms); }
.bs-pw-busy .bs-pw-stud::before { animation-name:bs-pw-stud-chase; animation-duration:1.05s;
  animation-timing-function:ease-in-out; animation-iteration-count:infinite; }
@keyframes bs-pw-stud-chase {
  0%,100% { box-shadow:0 0 0 1px rgba(0,0,0,.45); }
  45%     { box-shadow:0 0 0 1px rgba(0,0,0,.45), 0 0 10px 2px var(--bs-orange); }
}

/* Slice labels, radial along the outer band. */
.bs-pw-label > span { margin-top:24px; font-size:11px; font-weight:900; line-height:1; letter-spacing:.01em;
  white-space:nowrap; font-variant-numeric:tabular-nums; color:var(--bs-text);
  text-shadow:0 1px 2px rgba(0,0,0,.8); transform:rotate(-90deg); }
.bs-pw-label-zero > span { color:var(--bs-faint); text-shadow:none; }
.bs-pw-label-top > span, .bs-pw-label-win > span { color:var(--bs-on-orange); text-shadow:0 1px 0 rgba(255,255,255,.3); }

/* The winning wedge igniting. Screen-blended inside the wheel's own stacking
   context so it lights exactly the arc the server landed on and nothing else. */
.bs-pw-ignite { position:absolute; inset:0; border-radius:50%; pointer-events:none; opacity:0;
  mix-blend-mode:screen;
  animation:bs-pw-ignite 1.15s cubic-bezier(.2,.7,.3,1) 2 forwards; }
@keyframes bs-pw-ignite { 0% { opacity:.78; } 55% { opacity:.1; } 100% { opacity:.3; } }

/* Light rays behind the wheel on a paying result. */
.bs-pw-rays { position:absolute; inset:-34px; border-radius:50%; pointer-events:none; opacity:0;
  background:repeating-conic-gradient(var(--bs-gold) 0deg 4deg, rgba(0,0,0,0) 4deg 17deg);
  -webkit-mask-image:radial-gradient(closest-side, #000 58%, rgba(0,0,0,0) 100%);
  mask-image:radial-gradient(closest-side, #000 58%, rgba(0,0,0,0) 100%); }
.bs-pw-wrap.bs-pw-hit .bs-pw-rays { animation:bs-pw-rays 2.2s ease-out 1 both; }
@keyframes bs-pw-rays {
  0%   { opacity:0; transform:rotate(0) scale(.82); }
  22%  { opacity:.4; }
  100% { opacity:0; transform:rotate(34deg) scale(1.12); }
}

/* Hub — a machined boss carrying the single most important number. */
.bs-pw-hub { width:70px; height:70px; z-index:2; flex-direction:column; gap:1px; padding:0 4px;
  background:radial-gradient(circle at 42% 28%, var(--bs-soft), var(--bs-panel) 68%);
  border:2px solid var(--bs-orange);
  box-shadow:0 8px 20px rgba(0,0,0,.65), inset 0 1px 0 rgba(255,255,255,.16), 0 0 0 5px rgba(0,0,0,.32); }
.bs-pw-hub-k { font-size:7px; font-weight:800; letter-spacing:.14em; text-transform:uppercase;
  color:var(--bs-faint); line-height:1; white-space:nowrap; }
.bs-pw-hub-v { font-size:19px; font-weight:900; line-height:1.05; letter-spacing:-.03em;
  font-variant-numeric:tabular-nums; color:var(--bs-text); }
.bs-pw-hub.bs-pw-t-hit  .bs-pw-hub-v { color:var(--bs-pos); }
.bs-pw-hub.bs-pw-t-low  .bs-pw-hub-v { color:var(--bs-muted); }
.bs-pw-hub.bs-pw-t-zero .bs-pw-hub-v { color:var(--bs-neg); }

/* Pointer peg — pivots at the head so the tip flicks as slices pass. */
.bs-pw-pointer { position:absolute; top:-27px; left:50%; transform:translateX(-50%); z-index:4;
  font-size:0; line-height:0; filter:drop-shadow(0 4px 7px rgba(0,0,0,.65)); }
.bs-pw-peg { display:block; transform-origin:50% 27%; }
.bs-pw-peg-svg { display:block; }

/* ---- Result plate ------------------------------------------------------- */
.bs-pw-rail { width:64%; max-width:200px; }
.bs-pw-plate { width:100%; max-width:250px; min-height:66px; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:2px; padding:9px 12px; border-radius:12px;
  border:1px solid var(--bs-line); text-align:center; overflow:hidden;
  background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.012));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05); }
.bs-pw-plate-k { font-size:9px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:var(--bs-faint); }
.bs-pw-plate-idle { letter-spacing:.05em; text-transform:none; font-size:11px; font-weight:700; }
.bs-pw-plate-wait { font-size:11px; font-weight:700; color:var(--bs-muted); }
.bs-pw-plate-v { font-variant-numeric:tabular-nums; line-height:1.08; }
.bs-pw-plate-v.bs-pw-plate-zero { font-size:25px; font-weight:900; color:var(--bs-muted); letter-spacing:-.01em; }
.bs-pw-plate-x { font-size:10px; font-weight:800; color:var(--bs-muted); font-variant-numeric:tabular-nums; letter-spacing:.04em; }
.bs-pw-plate-won { border-color:var(--bs-orange-dp);
  background:linear-gradient(180deg, rgba(255,255,255,.075), rgba(255,255,255,.02));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.1), inset 0 0 26px rgba(255,255,255,.05), 0 6px 20px rgba(0,0,0,.4); }
.bs-pw-plate-won .bs-pw-plate-x { color:var(--bs-gold-ink); }

/* ---- Paytable legend ---------------------------------------------------- */
.bs-wheel-strip { gap:6px; padding:10px 8px; border-radius:12px;
  background:linear-gradient(180deg, var(--bs-panel), var(--bs-well) 85%); }
.bs-wheel-seg { min-width:64px; padding:8px 7px 7px; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05); transition:transform .14s ease, border-color .14s ease; }
.bs-wheel-seg.active { transform:translateY(-2px); }
.bs-pw-seg-top { border-color:var(--bs-gold); }
.bs-pw-seg-chip { display:block; width:100%; height:4px; border-radius:3px; margin-bottom:6px;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.35); }
.bs-pw-seg-bar { display:block; height:3px; border-radius:2px; background:var(--bs-line); margin-top:6px; overflow:hidden; }
.bs-pw-seg-bar > i { display:block; height:100%; border-radius:2px; background:var(--bs-soft); }
.bs-wheel-seg.active .bs-pw-seg-bar > i { background:var(--bs-orange); }
.bs-pw-seg-top .bs-pw-seg-bar > i { background:var(--bs-gold); }

/* ---- Controls ----------------------------------------------------------- */
.bs-pw-ctrl-head { font-size:9px; font-weight:800; letter-spacing:.13em; text-transform:uppercase;
  color:var(--bs-faint); text-align:center; margin:0 0 7px; }
.bs-pw-risks .bs-pw-risk { display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:5px; padding:9px 10px; line-height:1.1; min-width:76px; }
.bs-pw-risk-n { font-size:12px; font-weight:800; letter-spacing:.02em; }
.bs-pw-risk-m { display:flex; gap:3px; }
.bs-pw-pip { width:5px; height:5px; border-radius:50%; background:currentColor; opacity:.24; }
.bs-pw-pip.on { opacity:.95; }
.bs-pw-risks .bs-pw-risk:disabled { opacity:.42; cursor:not-allowed; }
.bs-pw-risks .bs-pw-risk:disabled:hover { filter:none; }

.bs-pw-actions { margin-top:2px; }
.bs-pw-actions-busy input { opacity:.42; cursor:not-allowed; }
.bs-pw-actions-busy label { opacity:.6; }
.bs-pw-spin { min-width:136px; font-weight:900; letter-spacing:.08em; text-transform:uppercase; }
.bs-pw-spin:disabled { opacity:.5; cursor:not-allowed; }
.bs-pw-spin:disabled:hover { filter:none; }

/* ---- Phone -------------------------------------------------------------- */
@media (max-width:420px) {
  .bs-pw-stage { padding:16px 8px 13px; gap:9px; }
  .bs-pw-wrap { width:186px; height:186px; }
  .bs-pw-bezel { inset:-12px; }
  .bs-pw-rays { inset:-24px; }
  .bs-pw-label > span { margin-top:20px; font-size:10px; }
  .bs-pw-hub { width:62px; height:62px; }
  .bs-pw-hub-v { font-size:17px; }
  .bs-pw-plate { min-height:60px; }
  .bs-pw-plate .bs-fx-payout { font-size:26px; }
  .bs-pw-risks .bs-pw-risk { min-width:0; flex:1 1 0; padding:9px 4px; }
  .bs-pw-tag { font-size:8px; padding:3px 7px; letter-spacing:.08em; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-pw-ignite,
  .bs-pw-wrap.bs-pw-hit .bs-pw-rays,
  .bs-pw-busy .bs-pw-stud::before { animation:none !important; }
  .bs-pw-ignite { opacity:.3; }
  .bs-pw-wheel, .bs-pw-wheel.bs-pw-winding { transition:none !important; }
  .bs-wheel-seg, .bs-wheel-seg.active { transition:none !important; transform:none !important; }
}
/* ============================================================================
   HILO — second pass. A dealt table: the beaten card stays on the left for
   comparison, the hero card physically TURNS OVER onto whatever the API
   returned, and the compounding multiplier / cash-out value is the loudest
   thing on screen. Every colour is a --bs-* token so all 10 skins keep
   working; the only fixed values are neutral black/white shadow alphas the
   other stages already use.
   ========================================================================== */
.bs-hilo-felt { position:relative; overflow:hidden; padding:12px 12px 14px; }
.bs-hilo-felt::after { content:''; position:absolute; inset:0; z-index:0; pointer-events:none; border-radius:inherit;
  background:radial-gradient(72% 58% at 50% 36%, rgba(255,255,255,.07), transparent 64%),
             radial-gradient(124% 98% at 50% 0%, transparent 44%, rgba(0,0,0,.34) 100%); }
.bs-hilo-felt .bs-felt-label, .bs-hilo-stage, .bs-hilo-ruler { position:relative; z-index:1; }
.bs-hilo-felt.is-win { box-shadow:inset 0 0 44px rgba(0,0,0,.5), inset 0 0 0 1px var(--bs-gold), 0 0 34px -14px var(--bs-gold); }
.bs-hilo-felt.is-bust { box-shadow:inset 0 0 44px rgba(0,0,0,.5), inset 0 0 0 1px var(--bs-neg); }

/* Streak rail in the felt label */
.bs-hilo-streak { display:inline-flex; align-items:center; gap:6px; }
.bs-hilo-streak em { font-style:normal; color:var(--bs-faint); }
.bs-hilo-streak b { font-size:11px; letter-spacing:0; color:var(--bs-text); font-variant-numeric:tabular-nums; }
.bs-hilo-pips { display:inline-flex; gap:3px; }
.bs-hilo-pips i { width:5px; height:5px; border-radius:50%; background:var(--bs-pos); box-shadow:0 0 7px -1px var(--bs-pos); }

/* Table columns: beaten card · hero card · shoe */
.bs-hilo-stage { gap:16px; align-items:center; }
.bs-hilo-col { display:flex; flex-direction:column; align-items:center; gap:7px; min-width:0; }
.bs-hilo-cap { display:block; font-size:9px; font-weight:900; letter-spacing:.14em; text-transform:uppercase;
  color:var(--bs-faint); white-space:nowrap; font-style:normal; }
.bs-hilo-col-past .bs-pcard, .bs-hilo-col-past .bs-pcard-slot { opacity:.66; transform:rotate(-3deg) scale(.94); }
.bs-hilo-col-past .bs-pcard { animation:bs-hilo-discard .36s cubic-bezier(.2,.9,.3,1.2); }
@keyframes bs-hilo-discard {
  from { transform:translate(34px,-16px) rotate(7deg) scale(1); opacity:0 }
  to   { transform:rotate(-3deg) scale(.94); opacity:.66 }
}
.bs-hilo-delta { display:inline-flex; align-items:center; justify-content:center; min-width:38px; min-height:17px;
  padding:1px 7px; border-radius:999px; border:1px solid var(--bs-line); background:var(--bs-elev2);
  color:var(--bs-muted); font-size:10px; font-weight:900; font-variant-numeric:tabular-nums; }
.bs-hilo-delta.is-up { color:var(--bs-pos); border-color:var(--bs-pos); }
.bs-hilo-delta.is-down { color:var(--bs-neg); border-color:var(--bs-neg); }
.bs-hilo-delta.is-void { visibility:hidden; }

/* Hero card — a real two-sided card on a 3D hinge */
.bs-hilo-hero { position:relative; display:block; flex:none; width:112px; height:158px; perspective:1000px; }
.bs-hilo-flipper { position:absolute; inset:0; transform-style:preserve-3d;
  transition:transform .55s cubic-bezier(.22,.75,.2,1); }
.bs-hilo-flipper.bs-hilo-flipped { transform:rotateY(180deg); }
.bs-hilo-face { position:absolute; inset:0; border-radius:13px;
  backface-visibility:hidden; -webkit-backface-visibility:hidden; }
.bs-hilo-face-front { transform:rotateY(180deg); }
.bs-hilo-face .bs-pcard, .bs-hilo-face .bs-pcard-slot { width:100%; height:100%; border-radius:13px; animation:none; }
.bs-hilo-face .bs-pcard { box-shadow:0 18px 32px rgba(0,0,0,.55), inset 0 0 0 1px rgba(0,0,0,.08), inset 0 1px 0 rgba(255,255,255,.6); }
.bs-hilo-face-back .bs-pcard-back::after { content:''; position:absolute; left:50%; top:50%; width:46%; height:31%;
  transform:translate(-50%,-50%); border-radius:50%; border:2px solid rgba(255,255,255,.34);
  box-shadow:inset 0 0 0 3px rgba(0,0,0,.12); }
.bs-hilo-hero.is-turning { animation:bs-hilo-hover 1.1s ease-in-out infinite; }
@keyframes bs-hilo-hover { 0%,100% { transform:translateY(0) rotate(0) } 50% { transform:translateY(-6px) rotate(-1.4deg) } }
.bs-hilo-hero.is-ok::after, .bs-hilo-hero.is-no::after { content:''; position:absolute; inset:-6px; border-radius:19px;
  pointer-events:none; }
.bs-hilo-hero.is-ok::after { box-shadow:0 0 0 2px var(--bs-pos), 0 0 28px -6px var(--bs-pos); }
.bs-hilo-hero.is-no::after { box-shadow:0 0 0 2px var(--bs-neg), 0 0 28px -6px var(--bs-neg); }
.bs-hilo-hero.is-late.is-ok::after, .bs-hilo-hero.is-late.is-no::after,
.bs-hilo-delta.is-late { animation:bs-hilo-late .34s ease .58s both; }
@keyframes bs-hilo-late { from { opacity:0 } to { opacity:1 } }

/* The call the player made, ribboned under the hero card */
.bs-hilo-callbadge { position:absolute; left:50%; bottom:-12px; transform:translateX(-50%); z-index:3;
  display:inline-flex; align-items:center; gap:5px; padding:3px 10px; border-radius:999px; white-space:nowrap;
  background:var(--bs-elev2); border:1px solid var(--bs-line); color:var(--bs-muted);
  font-size:9px; font-weight:900; letter-spacing:.12em; text-transform:uppercase; }
.bs-hilo-callbadge .bs-hilo-arrow { font-size:9px; opacity:1; }
.bs-hilo-callbadge.is-live { color:var(--bs-orange); border-color:var(--bs-orange); box-shadow:0 0 20px -6px var(--bs-orange); }
.bs-hilo-callbadge.is-ok { color:var(--bs-pos); border-color:var(--bs-pos); }
.bs-hilo-callbadge.is-no { color:var(--bs-neg); border-color:var(--bs-neg); }

/* Shoe — one more silhouette behind the existing two, for depth */
.bs-hilo-deck::before { content:''; position:absolute; left:13px; top:13px; width:100%; height:100%;
  border-radius:8px; background:rgba(0,0,0,.32); border:1px solid var(--bs-line); opacity:.55; }

/* Rank ruler: restates the rank already face-up, never implies odds */
.bs-hilo-ruler { display:flex; gap:2px; margin:14px 2px 0; padding:4px; border-radius:999px;
  background:rgba(0,0,0,.28); border:1px solid var(--bs-line); box-shadow:inset 0 1px 3px rgba(0,0,0,.45); }
.bs-hilo-tick { flex:1 1 0; min-width:0; padding:3px 0; border-radius:999px; text-align:center; font-style:normal;
  font-size:9px; font-weight:900; color:var(--bs-faint); font-variant-numeric:tabular-nums; }
.bs-hilo-tick.is-hi { color:var(--bs-pos); opacity:.6; }
.bs-hilo-tick.is-lo { color:var(--bs-neg); opacity:.6; }
.bs-hilo-tick.is-now { opacity:1; color:var(--bs-on-orange);
  background:linear-gradient(180deg, var(--bs-orange-br), var(--bs-orange-dp));
  box-shadow:0 3px 9px -3px var(--bs-orange), inset 0 1px 0 rgba(255,255,255,.35); }

/* Console — multiplier + cash-out value, the emotional centre */
.bs-hilo-console { display:flex; align-items:stretch; gap:10px; padding:10px 12px; margin-bottom:10px; }
.bs-hilo-metric { flex:1 1 0; min-width:0; display:flex; flex-direction:column; align-items:center; gap:4px; }
.bs-hilo-metric-sep { flex:none; width:1px; background:linear-gradient(180deg, transparent, var(--bs-line), transparent); }
.bs-hilo-mult, .bs-hilo-cashval { font-size:26px; font-weight:900; line-height:1.05; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; }
.bs-hilo-mult { color:var(--bs-text); }
.bs-hilo-mult.is-live { color:var(--bs-pos); text-shadow:0 0 22px rgba(47,208,122,.35); }
.bs-hilo-cashval { color:var(--bs-gold-ink); }
.bs-hilo-console.is-idle .bs-hilo-mult, .bs-hilo-console.is-idle .bs-hilo-cashval { color:var(--bs-faint); text-shadow:none; }

/* Settled: payout or busted run */
.bs-hilo-payout { display:flex; flex-direction:column; align-items:center; gap:4px; padding:12px; margin-bottom:10px; text-align:center; }
.bs-hilo-payout.is-win { border-color:var(--bs-gold); box-shadow:0 0 34px -14px var(--bs-gold), inset 0 1px 0 rgba(255,255,255,.08); }
.bs-hilo-bustfig { font-size:26px; font-weight:900; line-height:1.05; color:var(--bs-muted);
  font-variant-numeric:tabular-nums; text-decoration:line-through; }
.bs-hilo-payout-sub { font-size:11px; font-weight:800; color:var(--bs-muted); font-variant-numeric:tabular-nums; }

/* The run so far, one chip per correct call */
.bs-hilo-ladder { display:flex; align-items:center; gap:8px; margin:0 2px 10px; }
.bs-hilo-steps { display:flex; gap:5px; overflow-x:auto; padding:1px; scrollbar-width:none; }
.bs-hilo-steps::-webkit-scrollbar { display:none; }
.bs-hilo-step { flex:none; padding:3px 8px; border-radius:999px; border:1px solid var(--bs-line); background:var(--bs-elev2);
  color:var(--bs-muted); font-style:normal; font-size:10px; font-weight:800; font-variant-numeric:tabular-nums; }
.bs-hilo-step.is-now { color:var(--bs-pos); border-color:var(--bs-pos); }

/* Message line sits under the console, so it supports rather than competes */
.bs-hilo-msg .bs-slot-msg { margin:2px 0 10px; font-size:13px; min-height:20px; }
.bs-hilo-msg .bs-slot-win { font-size:15px; }

/* Calls — physical keys rather than flat accent buttons */
.bs-hilo-actions .bs-hilo-call { color:var(--bs-text); border:1px solid var(--bs-line);
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-elev));
  box-shadow:0 8px 18px rgba(0,0,0,.34), inset 0 1px 0 rgba(255,255,255,.07);
  font-weight:900; letter-spacing:.03em; padding:11px 14px;
  transition:transform .12s ease, border-color .15s ease, box-shadow .15s ease; }
.bs-hilo-actions .bs-hilo-call .bs-hilo-arrow { display:inline-flex; align-items:center; justify-content:center;
  width:22px; height:22px; flex:none; border-radius:50%; font-size:10px; font-style:normal; opacity:1;
  background:var(--bs-elev); border:1px solid var(--bs-line); }
.bs-hilo-actions .bs-hilo-call.is-hi .bs-hilo-arrow { color:var(--bs-pos); border-color:var(--bs-pos); }
.bs-hilo-actions .bs-hilo-call.is-lo .bs-hilo-arrow { color:var(--bs-neg); border-color:var(--bs-neg); }
.bs-hilo-actions .bs-hilo-call:hover:not(:disabled) { transform:translateY(-2px); border-color:var(--bs-orange);
  box-shadow:0 12px 24px rgba(0,0,0,.42), inset 0 1px 0 rgba(255,255,255,.09); }
.bs-hilo-actions .bs-hilo-call:disabled { opacity:.38; transform:none; box-shadow:none; cursor:default; filter:none; }

/* Cash out — the escape hatch, lit while it is worth taking */
.bs-slot-ctrls .bs-hilo-cash { display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:12px 16px; font-weight:900; letter-spacing:.04em; }
.bs-hilo-cash b { font-size:17px; font-variant-numeric:tabular-nums; }
.bs-hilo-cash:disabled { opacity:.38; box-shadow:none; cursor:default; filter:none; }
.bs-hilo-cash.is-live { animation:bs-hilo-cashpulse 2.1s ease-in-out infinite; }
@keyframes bs-hilo-cashpulse {
  0%,100% { box-shadow:0 4px 14px rgba(0,0,0,.34); }
  50%     { box-shadow:0 6px 20px rgba(0,0,0,.4), 0 0 0 3px rgba(255,255,255,.12); }
}
.bs-hilo-deal { min-width:120px; font-weight:900; letter-spacing:.04em; }

@media (max-width:430px) {
  .bs-hilo-felt { padding:10px 8px 12px; }
  .bs-hilo-stage { gap:10px; }
  .bs-hilo-hero { width:96px; height:136px; }
  .bs-hilo-face, .bs-hilo-face .bs-pcard, .bs-hilo-face .bs-pcard-slot { border-radius:12px; }
  .bs-hilo-cap { font-size:8px; letter-spacing:.1em; }
  .bs-hilo-tick { font-size:8px; padding:2px 0; }
  .bs-hilo-ruler { gap:1px; margin-top:12px; }
  .bs-hilo-mult, .bs-hilo-cashval, .bs-hilo-bustfig { font-size:21px; }
  .bs-hilo-delta { min-width:32px; font-size:9px; }
  .bs-hilo-actions .bs-hilo-call { padding:10px 8px; font-size:14px; gap:6px; }
  .bs-hilo-actions .bs-hilo-call .bs-hilo-arrow { width:19px; height:19px; }
  .bs-hilo-cash b { font-size:15px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-hilo-flipper { transition:none !important; }
  .bs-hilo-hero.is-turning, .bs-hilo-cash.is-live,
  .bs-hilo-hero.is-late.is-ok::after, .bs-hilo-hero.is-late.is-no::after,
  .bs-hilo-delta.is-late { animation:none !important; }
  .bs-hilo-col-past .bs-pcard { animation:none !important; }
  .bs-hilo-actions .bs-hilo-call { transition:none !important; }
}
/* ============================================================================
   LIMBO — altitude run against the player's own target line (second pass)
   Builds on the shared .bs-ascend-* scaffold; every rule below is scoped to
   .bs-limbo-* so Crash (which shares that scaffold) is untouched. Craft
   position is driven entirely from JS in % of the stage box, so this sheet only
   dresses it. Brand colour never leaves a --bs-* token; the only hardcoded
   values are the physical night sky and the black ink on a gold flag.
   ========================================================================= */
.bs-limbo-stage { height:230px; margin-bottom:12px;
  background:linear-gradient(180deg, #050b1a 0%, #0a1830 44%, var(--bs-well) 100%); }
/* cockpit vignette — sits above the craft, below the readout */
.bs-limbo-stage::after { content:''; position:absolute; inset:0; z-index:4; pointer-events:none;
  background:radial-gradient(125% 95% at 50% 42%, transparent 42%, rgba(0,0,0,.5) 100%); }

/* launch-pad bloom, brightening as the engine spools and the craft climbs */
.bs-limbo-glow { position:absolute; left:0; right:0; bottom:0; height:46%; z-index:0; pointer-events:none;
  background:radial-gradient(120% 100% at 8% 100%, var(--bs-orange-dp), transparent 72%);
  opacity:.28; transition:opacity .35s ease; }
.bs-limbo-stage.bs-limbo-flying .bs-limbo-glow { opacity:.55; }
.bs-limbo-stage.bs-limbo-won .bs-limbo-glow { opacity:.5; }
.bs-limbo-stage.bs-limbo-igniting .bs-limbo-glow { opacity:.82; }
.bs-limbo-pad { position:absolute; left:6%; bottom:8%; z-index:1; width:36px; height:10px; border-radius:50%;
  transform:translate(-50%,50%); pointer-events:none; opacity:.5; transition:opacity .3s ease;
  background:radial-gradient(circle, var(--bs-orange) 0%, transparent 70%); }
.bs-limbo-stage.bs-limbo-flying .bs-limbo-pad,
.bs-limbo-stage.bs-limbo-igniting .bs-limbo-pad { opacity:.85; }

/* the win zone: everything above the target line */
.bs-limbo-band { position:absolute; left:0; right:0; top:0; z-index:1; pointer-events:none;
  color:var(--bs-pos); background:linear-gradient(0deg, currentColor, transparent 72%);
  opacity:.10; transition:opacity .3s ease; }
.bs-limbo-stage.bs-limbo-won .bs-limbo-band { color:var(--bs-gold-ink); opacity:.22; }
.bs-limbo-stage.bs-limbo-lost .bs-limbo-band { opacity:.05; }

/* altitude ruler — 1.00x ground line, geometric midpoint, target squared */
.bs-limbo-gauge { position:absolute; inset:0; z-index:1; pointer-events:none; }
.bs-limbo-tick { position:absolute; left:0; right:0; height:0; border-top:1px dashed var(--bs-line); opacity:.55; }
.bs-limbo-tick-base { border-top-style:solid; opacity:.9; }
.bs-limbo-tick b { position:absolute; left:7px; top:-8px; padding:0 5px; border-radius:5px; line-height:16px;
  font-size:9.5px; font-weight:800; color:var(--bs-faint); background:rgba(0,0,0,.45);
  font-variant-numeric:tabular-nums; }

/* the target line the craft either clears or falls short of */
.bs-limbo-stage .bs-limbo-target { left:0; right:0; height:2px; z-index:2; opacity:1; border-top:0;
  color:var(--bs-orange); box-shadow:0 0 12px -2px currentColor;
  background:repeating-linear-gradient(90deg, currentColor 0 10px, transparent 10px 19px); }
.bs-limbo-stage.bs-limbo-won .bs-limbo-target { color:var(--bs-gold-ink); }
.bs-limbo-stage.bs-limbo-lost .bs-limbo-target { color:var(--bs-orange-dp); box-shadow:none; opacity:.72; }
.bs-limbo-stage .bs-limbo-target-tag { right:8px; top:-11px; padding:2px 9px;
  color:var(--bs-on-orange); background:var(--bs-orange); border:1px solid var(--bs-orange-br);
  box-shadow:0 2px 8px rgba(0,0,0,.5); font-variant-numeric:tabular-nums; }
.bs-limbo-stage.bs-limbo-won .bs-limbo-target-tag { background:var(--bs-gold); border-color:var(--bs-gold); color:var(--bs-on-gold); }
.bs-limbo-zone { position:absolute; left:7px; top:-10px; padding:1px 6px; border-radius:5px;
  font-size:9px; font-weight:900; letter-spacing:.13em; text-transform:uppercase; white-space:nowrap;
  color:var(--bs-pos); background:rgba(0,0,0,.45); }
.bs-limbo-stage.bs-limbo-won .bs-limbo-zone { color:var(--bs-gold-ink); }
.bs-limbo-stage.bs-limbo-lost .bs-limbo-zone { color:var(--bs-muted); }

/* vapour trail — colour flows from the element so skins drive it */
.bs-limbo-stage .bs-ascend-trail { left:6%; bottom:8%; height:3px; z-index:2; color:var(--bs-pos);
  background:linear-gradient(90deg, transparent, currentColor); box-shadow:0 0 12px -2px currentColor;
  transition:width .55s cubic-bezier(.16,.86,.28,1), transform .55s cubic-bezier(.16,.86,.28,1); }
.bs-limbo-stage.bs-limbo-flying .bs-ascend-trail { transition:width .1s linear, transform .1s linear; }
.bs-limbo-stage.bs-limbo-won .bs-ascend-trail { color:var(--bs-gold-ink); }
.bs-limbo-stage.bs-limbo-lost .bs-ascend-trail { color:var(--bs-neg); }

/* the craft */
.bs-limbo-stage .bs-ascend-craft { left:6%; bottom:8%; z-index:3; font-size:28px;
  transition:left .55s cubic-bezier(.16,.86,.28,1), bottom .55s cubic-bezier(.16,.86,.28,1); }
.bs-limbo-stage .bs-ascend-craft.bs-limbo-climb { transition:left .1s linear, bottom .1s linear; }
.bs-limbo-glyph { display:inline-block; font-style:normal; transform:rotate(-6deg); }
.bs-limbo-stage.bs-limbo-flying .bs-limbo-glyph { animation:bs-limbo-bob 1.05s ease-in-out infinite; }
@keyframes bs-limbo-bob { 0%,100% { transform:rotate(-6deg) translateY(0); } 50% { transform:rotate(-2deg) translateY(-2px); } }
.bs-limbo-flame { position:absolute; left:2px; bottom:1px; width:15px; height:15px; border-radius:50%; opacity:0;
  background:radial-gradient(circle, var(--bs-gold) 0%, var(--bs-orange) 45%, transparent 72%); }
.bs-limbo-stage.bs-limbo-flying .bs-limbo-flame,
.bs-limbo-stage.bs-limbo-igniting .bs-limbo-flame { opacity:1; animation:bs-limbo-thrust .26s ease-in-out infinite alternate; }
@keyframes bs-limbo-thrust { from { transform:scale(.6) translate(-1px,1px); opacity:.55; } to { transform:scale(1.3) translate(-5px,5px); opacity:.95; } }
.bs-limbo-stage.bs-limbo-igniting .bs-ascend-craft { animation:bs-limbo-shake .16s linear infinite; }
@keyframes bs-limbo-shake { 0%,100% { transform:translate(-50%,50%); } 25% { transform:translate(-53%,52%); } 75% { transform:translate(-47%,48%); } }
.bs-limbo-boom { display:inline-block; font-style:normal;
  animation:bs-limbo-boom .5s cubic-bezier(.2,.9,.3,1.3) forwards; }
@keyframes bs-limbo-boom { 0% { transform:scale(.3); opacity:0; } 40% { transform:scale(1.35); opacity:1; } 100% { transform:scale(1); opacity:.92; } }

/* the headline number + its caption / verdict stamp */
.bs-limbo-stage .bs-ascend-mult { top:12px; z-index:5; font-size:38px; line-height:1; letter-spacing:.5px;
  font-variant-numeric:tabular-nums; transition:color .18s ease; }
.bs-ascend-mult.bs-limbo-mult-win { color:var(--bs-gold-ink); text-shadow:0 0 26px currentColor; }
.bs-limbo-sub { position:absolute; top:56px; left:0; right:0; z-index:5; text-align:center;
  pointer-events:none; min-height:22px; }
.bs-limbo-sub-t { font-size:11px; font-weight:800; letter-spacing:.11em; text-transform:uppercase; color:var(--bs-faint); }
.bs-limbo-verdict { display:inline-block; padding:4px 13px; border-radius:999px; background:rgba(0,0,0,.55);
  border:1px solid currentColor; font-size:11.5px; font-weight:900; letter-spacing:.14em; text-transform:uppercase; }
.bs-limbo-verdict-win { color:var(--bs-gold-ink); box-shadow:0 0 18px -4px currentColor; }
.bs-limbo-verdict-lose { color:var(--bs-neg); }

/* recent REAL results */
.bs-limbo-hist { display:flex; align-items:center; gap:5px; margin:0 0 8px; overflow:hidden; }
.bs-limbo-hist-k { flex:0 0 auto; margin-right:2px; font-size:9.5px; font-weight:800; letter-spacing:.1em;
  text-transform:uppercase; color:var(--bs-faint); }
.bs-limbo-pill { flex:0 0 auto; padding:3px 7px; border-radius:999px; border:1px solid var(--bs-line);
  background:var(--bs-elev2); font-size:11px; font-weight:800; font-style:normal; font-variant-numeric:tabular-nums; }
.bs-limbo-pill-win { color:var(--bs-pos); border-color:var(--bs-pos); }
.bs-limbo-pill-lose { color:var(--bs-muted); }

/* payout headline (bsCountUp writes into .bs-limbo-payout) */
.bs-limbo-payline { display:flex; align-items:baseline; justify-content:center; gap:10px; margin:2px 0; }
.bs-limbo-payline-k { font-size:11px; font-weight:800; letter-spacing:.12em; text-transform:uppercase; color:var(--bs-muted); }

/* readout console */
.bs-limbo-console { display:flex; gap:8px; margin:0 0 10px; padding:9px 10px; text-align:center; }
.bs-limbo-cell { flex:1 1 0; min-width:0; }
.bs-limbo-cell-k { display:block; margin-bottom:3px; font-size:9.5px; font-weight:800; letter-spacing:.1em;
  text-transform:uppercase; color:var(--bs-faint); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.bs-limbo-cell-v { display:block; font-size:16px; font-weight:900; color:var(--bs-text); font-variant-numeric:tabular-nums; }
.bs-limbo-cell-pos { color:var(--bs-gold-ink); }

/* controls */
.bs-limbo-ctl { margin-bottom:8px; }
.bs-limbo-ctl input { width:120px; text-align:center; font-weight:800; font-variant-numeric:tabular-nums; }
.bs-limbo-ctl input:disabled { opacity:.45; cursor:not-allowed; }
.bs-limbo-presets { flex-wrap:wrap; margin-bottom:10px; }
.bs-limbo-chip { min-width:0; padding:5px 10px; font-variant-numeric:tabular-nums; }
.bs-limbo-chip:disabled { opacity:.42; cursor:not-allowed; }
.bs-slot-ctrls .bs-limbo-launch { font-weight:900; letter-spacing:.07em; text-transform:uppercase; }
.bs-slot-ctrls .bs-limbo-launch:disabled { opacity:.5; }

@media (max-width:420px) {
  .bs-limbo-stage { height:190px; }
  .bs-limbo-stage .bs-ascend-mult { top:10px; font-size:30px; }
  .bs-limbo-sub { top:46px; }
  .bs-limbo-stage .bs-ascend-craft { font-size:24px; }
  .bs-limbo-cell-k { font-size:9px; letter-spacing:.06em; }
  .bs-limbo-cell-v { font-size:14px; }
  .bs-limbo-payout { font-size:26px; }
  .bs-limbo-chip { padding:5px 8px; font-size:12px; }
  .bs-limbo-ctl input { width:104px; }
}
@media (prefers-reduced-motion: reduce) {
  .bs-limbo-stage.bs-limbo-flying .bs-limbo-glyph,
  .bs-limbo-stage.bs-limbo-flying .bs-limbo-flame,
  .bs-limbo-stage.bs-limbo-igniting .bs-limbo-flame,
  .bs-limbo-stage.bs-limbo-igniting .bs-ascend-craft,
  .bs-limbo-boom { animation:none !important; }
  .bs-limbo-stage .bs-ascend-craft,
  .bs-limbo-stage .bs-ascend-craft.bs-limbo-climb,
  .bs-limbo-stage .bs-ascend-trail,
  .bs-limbo-stage.bs-limbo-flying .bs-ascend-trail,
  .bs-limbo-stage .bs-ascend-mult,
  .bs-limbo-glow, .bs-limbo-pad, .bs-limbo-band { transition:none !important; }
}
/* ============================================================================
   BACCARAT — Punto Banco, the high-roller table. Restrained luxury: a real
   felt with the three betting boxes laid on it, chips stacked on the chosen
   box, both hands turned one card at a time, and a winning side that ignites.
   Every colour is a --bs-* token so all 10 skin presets keep working; the only
   fixed values are neutral white/black light-and-shadow on physical objects
   (chip stock, card edges).
   ========================================================================== */

/* ---- Bead plate: the last dozen REAL coups -------------------------------- */
.bs-bac-road { display:flex; align-items:center; gap:9px; margin:0 2px 9px; min-height:20px; }
.bs-bac-road-cap { flex:none; font-size:8px; font-weight:900; letter-spacing:.2em;
  text-transform:uppercase; color:var(--bs-faint); }
.bs-bac-beads { display:flex; flex-wrap:wrap; gap:4px; }
.bs-bac-bead { width:18px; height:18px; flex:none; border-radius:50%; display:inline-flex;
  align-items:center; justify-content:center; font-style:normal; font-size:9px; font-weight:900;
  letter-spacing:0; line-height:1; animation:bs-bac-bead-in .3s cubic-bezier(.2,.9,.3,1.4); }
.bs-bac-bead-player { background:var(--bs-elev2); color:var(--bs-text);
  box-shadow:inset 0 0 0 1.5px var(--bs-soft), 0 1px 3px rgba(0,0,0,.4); }
.bs-bac-bead-banker { background:radial-gradient(circle at 35% 28%, var(--bs-orange-br), var(--bs-orange-dp) 80%);
  color:var(--bs-on-orange); box-shadow:0 1px 3px rgba(0,0,0,.45); }
.bs-bac-bead-tie { background:var(--bs-elev); color:var(--bs-pos);
  box-shadow:inset 0 0 0 1.5px var(--bs-pos), 0 1px 3px rgba(0,0,0,.4); }
@keyframes bs-bac-bead-in { from { transform:scale(.4); opacity:0 } to { transform:none; opacity:1 } }

/* ---- The felt ------------------------------------------------------------- */
.bs-felt.bs-bac-felt { padding:13px 12px 12px;
  background:
    radial-gradient(115% 78% at 50% -14%, rgba(255,255,255,.07), transparent 62%),
    radial-gradient(120% 90% at 50% -20%, var(--bs-elev2), var(--bs-elev) 55%, var(--bs-panel) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05), inset 0 0 52px rgba(0,0,0,.55),
    0 12px 30px -16px rgba(0,0,0,.85); }
/* Table vignette — sits above the surface, under every control. */
.bs-felt.bs-bac-felt::after { content:''; position:absolute; inset:0; border-radius:inherit;
  pointer-events:none; background:radial-gradient(132% 96% at 50% 6%, transparent 54%, rgba(0,0,0,.34) 100%); }
.bs-felt.bs-bac-felt.is-dealing { box-shadow:inset 0 1px 0 rgba(255,255,255,.05),
  inset 0 0 52px rgba(0,0,0,.55), 0 0 34px -13px var(--bs-orange); }
.bs-felt.bs-bac-felt.is-won { box-shadow:inset 0 1px 0 rgba(255,255,255,.06),
  inset 0 0 52px rgba(0,0,0,.5), 0 0 46px -14px var(--bs-gold); }

.bs-bac-crest { position:relative; z-index:1; display:flex; align-items:center; gap:10px; margin:0 2px 9px; }
.bs-bac-crest i { flex:1; height:1px; background:linear-gradient(90deg, transparent, var(--bs-line)); }
.bs-bac-crest i:last-child { background:linear-gradient(90deg, var(--bs-line), transparent); }
.bs-bac-crest span { flex:none; font-size:9px; font-weight:900; letter-spacing:.3em;
  text-transform:uppercase; color:var(--bs-faint); }

/* ---- The two hands -------------------------------------------------------- */
.bs-bac-boxes { z-index:1; gap:9px; align-items:stretch; }
.bs-bac-boxes::before { content:''; position:absolute; left:50%; top:4px; bottom:4px; width:1px;
  transform:translateX(-.5px); pointer-events:none;
  background:linear-gradient(180deg, transparent, var(--bs-line) 22%, var(--bs-line) 78%, transparent); }
.bs-bac-box { display:flex; flex-direction:column; padding:8px 6px 6px; border-radius:12px;
  background:linear-gradient(180deg, rgba(255,255,255,.035), rgba(0,0,0,.28));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);
  transition:border-color .2s, box-shadow .2s, opacity .25s, filter .25s; }
.bs-bac-box.win { border-color:var(--bs-gold);
  background:linear-gradient(180deg, rgba(255,255,255,.07), rgba(0,0,0,.2));
  box-shadow:inset 0 0 0 1px var(--bs-gold), inset 0 1px 0 rgba(255,255,255,.08),
    0 0 30px -7px var(--bs-gold);
  animation:bs-bac-ignite .75s cubic-bezier(.2,.9,.3,1.15); }
.bs-bac-box.is-dead { opacity:.46; filter:saturate(.5); }
@keyframes bs-bac-ignite {
  0%   { box-shadow:inset 0 0 0 1px var(--bs-gold), 0 0 0 0 rgba(0,0,0,0); }
  45%  { box-shadow:inset 0 0 0 2px var(--bs-gold), 0 0 42px 2px var(--bs-gold); }
  100% { box-shadow:inset 0 0 0 1px var(--bs-gold), inset 0 1px 0 rgba(255,255,255,.08), 0 0 30px -7px var(--bs-gold); }
}

/* Our own turn animation replaces the generic deal drop, so a repaint mid-coup
   never re-animates a card that is already face-up. */
.bs-bac-cell { display:inline-flex; }
.bs-bac-box .bs-pcard { animation:none; }
.bs-bac-cell.bs-bac-reveal .bs-pcard { animation:bs-bac-turn .34s cubic-bezier(.2,.85,.3,1.08) both; }
@keyframes bs-bac-turn {
  0%   { transform:perspective(520px) rotateY(84deg) translateY(-5px); opacity:.2; }
  55%  { opacity:1; }
  100% { transform:none; opacity:1; }
}

.bs-bac-pts { min-width:30px; padding:2px 9px; font-size:14px; font-variant-numeric:tabular-nums;
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07), 0 1px 3px rgba(0,0,0,.4); }
.bs-bac-box.win .bs-bac-pts { color:var(--bs-gold-ink); border-color:var(--bs-gold);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09), 0 0 16px -4px var(--bs-gold); }
.bs-bac-pts-bump { animation:bs-bac-bump .32s cubic-bezier(.2,.9,.3,1.5); }
@keyframes bs-bac-bump { 0%{transform:scale(1)} 42%{transform:scale(1.3)} 100%{transform:scale(1)} }

.bs-bac-natrow { height:17px; margin-top:5px; text-align:center; }
.bs-bac-nat { display:inline-block; padding:2px 9px; border-radius:999px;
  font-size:8px; font-weight:900; letter-spacing:.16em; text-transform:uppercase;
  color:var(--bs-gold-ink); box-shadow:inset 0 0 0 1px var(--bs-gold);
  opacity:0; transform:translateY(-4px); transition:opacity .28s ease, transform .28s ease; }
.bs-bac-nat.is-on { opacity:1; transform:none; }

/* ---- Verdict strip -------------------------------------------------------- */
.bs-bac-verdict { position:relative; z-index:1; display:flex; align-items:center;
  justify-content:center; min-height:28px; margin:10px 0 2px; }
.bs-bac-verdict-txt { display:inline-block; padding:5px 15px; border-radius:999px;
  font-size:11px; font-weight:900; letter-spacing:.2em; text-transform:uppercase;
  color:var(--bs-muted); line-height:1.3; }
.bs-bac-verdict-total b, .bs-bac-verdict-total { letter-spacing:.1em; color:var(--bs-text);
  font-variant-numeric:tabular-nums; }
.bs-bac-verdict-hint { letter-spacing:.06em; text-transform:none; font-weight:800; font-size:11px; }
.bs-bac-verdict.is-settled .bs-bac-verdict-txt { color:var(--bs-gold-ink);
  background:linear-gradient(180deg, rgba(255,255,255,.07), rgba(0,0,0,.3));
  box-shadow:inset 0 0 0 1px var(--bs-gold), 0 0 28px -9px var(--bs-gold);
  animation:bs-bac-verdict-in .5s cubic-bezier(.2,.9,.3,1.35); }
.bs-bac-verdict.is-lost .bs-bac-verdict-txt { color:var(--bs-muted);
  background:linear-gradient(180deg, rgba(255,255,255,.03), rgba(0,0,0,.28));
  box-shadow:inset 0 0 0 1px var(--bs-line); }
@keyframes bs-bac-verdict-in { from { transform:scale(.82); opacity:0 } to { transform:none; opacity:1 } }

.bs-bac-rail { position:relative; z-index:1; margin:9px 6px 11px; }

/* ---- Betting boxes on the felt -------------------------------------------- */
.bs-bac-spots { position:relative; z-index:1; display:flex; gap:7px; margin:0; }
.bs-bac-spot { position:relative; flex:1 1 0; min-width:0; display:flex; flex-direction:column;
  align-items:center; justify-content:flex-end; gap:3px; padding:9px 4px 8px; border-radius:12px;
  border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.055), rgba(0,0,0,.3));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07), 0 3px 10px -4px rgba(0,0,0,.7);
  color:var(--bs-text); font-family:inherit; cursor:pointer;
  transition:transform .16s ease, box-shadow .16s ease, border-color .16s ease, opacity .25s ease; }
.bs-bac-spot::before { content:''; position:absolute; inset:4px; border-radius:9px;
  border:1px dashed var(--bs-line); opacity:.5; pointer-events:none; }
.bs-bac-spot-name { font-size:11px; font-weight:900; letter-spacing:.12em; text-transform:uppercase; line-height:1.2; }
.bs-bac-spot-odds { font-size:9px; font-weight:800; letter-spacing:.06em; color:var(--bs-faint);
  font-variant-numeric:tabular-nums; line-height:1.2; }
.bs-bac-spot:hover:not(:disabled) { transform:translateY(-2px); border-color:var(--bs-orange);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 10px 20px -8px rgba(0,0,0,.85); }
.bs-bac-spot:active:not(:disabled) { transform:translateY(0); }
.bs-bac-spot:disabled { cursor:default; }
.bs-bac-spot.has-chips { border-color:var(--bs-orange); }
.bs-bac-spot.is-dead { opacity:.4; }
.bs-bac-spot.is-winner { opacity:1; border-color:var(--bs-gold);
  box-shadow:inset 0 0 0 1px var(--bs-gold), 0 0 30px -8px var(--bs-gold);
  animation:bs-bac-ignite .75s cubic-bezier(.2,.9,.3,1.15); }
.bs-bac-spot.is-winner .bs-bac-spot-name { color:var(--bs-gold-ink); }
.bs-bac-spot-pay { font-size:12px; font-weight:900; color:var(--bs-pos);
  font-variant-numeric:tabular-nums; line-height:1.2; }

/* Chips sitting on the box */
.bs-bac-stack { display:flex; flex-direction:column; align-items:center; justify-content:flex-end;
  gap:3px; min-height:49px; }
.bs-bac-stack.is-empty { justify-content:center; }
.bs-bac-stack.is-empty::before { content:''; width:23px; height:23px; border-radius:50%;
  border:1px dashed var(--bs-line); opacity:.55; }
.bs-bac-discs { position:relative; width:24px; height:33px; }
.bs-bac-disc { position:absolute; left:0; bottom:calc(var(--bs-bac-i, 0) * 3px);
  width:24px; height:24px; border-radius:50%;
  background:
    repeating-conic-gradient(from 8deg, rgba(255,255,255,.92) 0deg 13deg, rgba(0,0,0,.34) 13deg 45deg);
  box-shadow:0 2px 5px rgba(0,0,0,.55), inset 0 0 0 1px rgba(0,0,0,.4);
  animation:bs-bac-chip-in .3s cubic-bezier(.2,.9,.3,1.4); }
.bs-bac-disc::after { content:''; position:absolute; inset:4px; border-radius:50%;
  background:radial-gradient(circle at 36% 28%, var(--bs-gold), var(--bs-orange-dp) 88%);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.3), inset 0 -2px 3px rgba(0,0,0,.28),
    inset 0 2px 3px rgba(255,255,255,.4); }
@keyframes bs-bac-chip-in { from { transform:translateY(-9px) scale(.7); opacity:0 } to { transform:none; opacity:1 } }
.bs-bac-stake-amt { font-size:11px; font-weight:900; letter-spacing:0;
  font-variant-numeric:tabular-nums; line-height:1.2; }
.bs-bac-spot.is-winner .bs-bac-stake-amt { color:var(--bs-gold-ink); }

/* ---- Payout hero ---------------------------------------------------------- */
.bs-bac-payout { display:flex; flex-direction:column; align-items:center; gap:1px; margin:13px 0 0; }
.bs-bac-payout-cap { font-size:10px; font-weight:900; letter-spacing:.24em;
  text-transform:uppercase; color:var(--bs-muted); }
.bs-bac-payout-amt { line-height:1.06; }

/* ---- Bet slip + chip denomination picker ---------------------------------- */
.bs-bac-bets { margin-bottom:9px; }
.bs-bac-bet { padding:5px 11px; background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05); font-variant-numeric:tabular-nums; }
.bs-bac-bet.won { border-color:var(--bs-gold); color:var(--bs-gold-ink); }
.bs-bac-bet.won b { color:var(--bs-pos); }
.bs-bac-denoms { display:flex; gap:6px; justify-content:center; margin:0 0 10px; }
.bs-bac-denom { flex:0 1 auto; min-width:54px; padding:6px 9px; border-radius:999px;
  border:1px solid var(--bs-line); background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  color:var(--bs-muted); font-family:inherit; font-size:11px; font-weight:900;
  font-variant-numeric:tabular-nums; cursor:pointer;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);
  transition:color .15s ease, border-color .15s ease, box-shadow .15s ease, background .15s ease; }
.bs-bac-denom:hover:not(:disabled) { color:var(--bs-text); border-color:var(--bs-soft); }
.bs-bac-denom.is-active { color:var(--bs-on-orange); border-color:var(--bs-orange);
  background:linear-gradient(180deg, var(--bs-orange-br), var(--bs-orange));
  box-shadow:0 4px 13px -5px var(--bs-orange), inset 0 1px 0 rgba(255,255,255,.28); }
.bs-bac-denom:disabled { opacity:.38; cursor:default; }
.bs-slot-ctrls .bs-bac-deal { min-width:150px; letter-spacing:.06em; }

@media (max-width:420px) {
  .bs-felt.bs-bac-felt { padding:11px 8px 10px; }
  .bs-bac-boxes { gap:6px; }
  .bs-bac-box { padding:7px 4px 5px; }
  .bs-bac-box .bs-pcard, .bs-bac-box .bs-pcard-slot { width:38px; height:54px; border-radius:6px; }
  .bs-bac-box .bs-pcard-suit { font-size:17px; }
  .bs-bac-box .bs-pcard-corner { font-size:8px; }
  .bs-bac-box .bs-pcard-row { gap:3px; min-height:54px; }
  .bs-bac-pts { min-width:26px; padding:2px 7px; font-size:12px; }
  .bs-bac-crest span { letter-spacing:.2em; }
  .bs-bac-verdict-txt { padding:5px 11px; font-size:10px; letter-spacing:.14em; }
  .bs-bac-spots { gap:5px; }
  .bs-bac-spot { padding:8px 2px 7px; }
  .bs-bac-spot-name { font-size:9px; letter-spacing:.05em; }
  .bs-bac-spot-odds { font-size:8px; }
  .bs-bac-stake-amt, .bs-bac-spot-pay { font-size:10px; }
  .bs-bac-stack { min-height:44px; }
  .bs-bac-discs { width:22px; height:29px; }
  .bs-bac-disc { width:22px; height:22px; }
  .bs-bac-denoms { gap:5px; }
  .bs-bac-denom { flex:1 1 0; min-width:0; padding:6px 2px; font-size:10px; }
  .bs-bac-beads { gap:3px; }
  .bs-bac-bead { width:15px; height:15px; font-size:8px; }
  .bs-bac-payout-amt { font-size:26px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-bac-bead, .bs-bac-box.win, .bs-bac-spot.is-winner, .bs-bac-disc,
  .bs-bac-pts-bump, .bs-bac-cell.bs-bac-reveal .bs-pcard,
  .bs-bac-verdict.is-settled .bs-bac-verdict-txt { animation:none !important; }
  .bs-bac-box, .bs-bac-spot, .bs-bac-nat, .bs-bac-denom { transition:none !important; }
}

/* ===== Mines — deep pass: pressable caps, jewel reveals, live cash-out HUD =====
   Every colour is a var(--bs-*) token except physical materials (the graphite
   mine casing, the near-black inner well) and neutral black/white shading, so
   all 10 operator skins re-tint the whole board for free. All rules are scoped
   under the game-specific .bs-mines-* prefix. */

/* ---- Head-up display: running multiplier + what cashing out is worth now ---- */
.bs-mines-hud { position:relative; overflow:hidden; display:flex; align-items:stretch; gap:10px;
  max-width:344px; margin:0 auto 8px; padding:10px 12px;
  border:1px solid var(--bs-line); border-radius:14px;
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07), 0 8px 20px rgba(0,0,0,.4);
  transition:border-color .25s ease, opacity .25s ease; }
.bs-mines-hud::before { content:''; position:absolute; left:0; right:0; top:0; height:1px;
  background:linear-gradient(90deg, transparent, var(--bs-soft), transparent); }
.bs-mines-hud.is-idle { opacity:.62; }
.bs-mines-hud-cell { flex:1 1 0; min-width:0; display:flex; flex-direction:column; align-items:center; gap:3px; text-align:center; }
.bs-mines-hud-k { font-size:9px; font-weight:900; letter-spacing:.14em; text-transform:uppercase; color:var(--bs-faint); }
.bs-mines-hud-v { font-size:25px; font-weight:900; line-height:1.04; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; color:var(--bs-text); }
.bs-mines-hud-v.bs-mines-mult { color:var(--bs-orange); }
.bs-mines-hud-v.bs-mines-pot { color:var(--bs-gold-ink); }
.bs-mines-hud.is-live .bs-mines-pot { filter:drop-shadow(0 0 9px currentColor); }
.bs-mines-hud-div { width:1px; align-self:stretch; flex:none;
  background:linear-gradient(180deg, transparent, var(--bs-line), transparent); }
.bs-mines-hud.is-hot { border-color:var(--bs-gold); }
.bs-mines-hud.is-hot::after { content:''; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  border:1px solid var(--bs-gold); animation:bs-mines-hot 1.8s ease-in-out infinite; }
@keyframes bs-mines-hot { 0%,100% { opacity:.22; } 50% { opacity:.85; } }

/* ---- Progress toward clearing every safe tile ---- */
.bs-mines-meter { position:relative; height:5px; max-width:344px; margin:0 auto 8px; border-radius:3px; overflow:hidden;
  background:var(--bs-bg); box-shadow:inset 0 1px 2px rgba(0,0,0,.65); }
.bs-mines-meter-fill { display:block; height:100%; border-radius:3px;
  background:linear-gradient(90deg, var(--bs-pos), var(--bs-gold));
  transition:width .5s cubic-bezier(.2,.8,.3,1); }

/* ---- Counters ---- */
.bs-mines-tags { display:flex; gap:6px; justify-content:center; max-width:344px; margin:0 auto 10px; }
.bs-mines-tag { flex:1 1 0; min-width:0; text-align:center; padding:5px 4px; border-radius:10px;
  border:1px solid var(--bs-line); background:var(--bs-elev);
  font-size:14px; font-weight:900; color:var(--bs-text); font-variant-numeric:tabular-nums; line-height:1.1; }
.bs-mines-tag b { display:block; margin-top:2px; font-size:8px; font-weight:800; letter-spacing:.12em;
  text-transform:uppercase; color:var(--bs-faint); }
.bs-mines-tag.is-gem { color:var(--bs-pos); }
.bs-mines-tag.is-mine { color:var(--bs-neg); }

/* ---- Settled panel: the payout beat ---- */
.bs-mines-result { position:relative; overflow:hidden; display:flex; flex-direction:column; align-items:center; gap:2px;
  max-width:344px; margin:0 auto 8px; padding:11px 12px 12px;
  border:1px solid var(--bs-line); border-radius:14px;
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07), 0 8px 22px rgba(0,0,0,.45); }
.bs-mines-result > * { position:relative; z-index:1; }
.bs-mines-result::before { content:''; position:absolute; inset:0; pointer-events:none; z-index:0; }
.bs-mines-result.is-win { border-color:var(--bs-gold); }
.bs-mines-result.is-win::before { background:radial-gradient(120% 85% at 50% 0%, var(--bs-gold), transparent 64%); opacity:.15; }
.bs-mines-result.is-loss { border-color:var(--bs-neg); }
.bs-mines-result.is-loss::before { background:radial-gradient(120% 85% at 50% 0%, var(--bs-neg), transparent 64%); opacity:.13; }
.bs-mines-result-k { font-size:9px; font-weight:900; letter-spacing:.16em; text-transform:uppercase; color:var(--bs-faint); }
.bs-mines-result-loss { font-size:27px; font-weight:900; line-height:1.05; color:var(--bs-neg);
  font-variant-numeric:tabular-nums; opacity:.85; }
.bs-mines-result-sub { font-size:11px; font-weight:700; color:var(--bs-muted); font-variant-numeric:tabular-nums; }

/* ---- The field: a rivetted case around a black inner well ---- */
.bs-mines-board { position:relative; max-width:344px; margin:0 auto 10px; padding:7px 8px 9px;
  border:1px solid var(--bs-line); border-radius:16px;
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07), 0 12px 28px rgba(0,0,0,.5); }
.bs-mines-board::before, .bs-mines-board::after { content:''; position:absolute; top:10px; width:5px; height:5px;
  border-radius:50%; opacity:.55; box-shadow:0 1px 1px rgba(0,0,0,.6);
  background:radial-gradient(circle at 34% 30%, rgba(255,255,255,.55), rgba(255,255,255,.05) 72%); }
.bs-mines-board::before { left:10px; }
.bs-mines-board::after { right:10px; }
.bs-mines-strip { display:flex; align-items:center; justify-content:space-between; gap:8px; padding:2px 14px 7px;
  font-size:9px; font-weight:900; letter-spacing:.16em; text-transform:uppercase; color:var(--bs-faint); }
.bs-mines-strip-k { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.bs-mines-strip-v { display:inline-flex; align-items:center; gap:5px; flex:none; color:var(--bs-muted); }
.bs-mines-strip-v b { font-weight:900; letter-spacing:.1em; }
.bs-mines-dot { width:6px; height:6px; flex:none; border-radius:50%; background:var(--bs-neg); opacity:.4; }
.bs-mines-board.is-live .bs-mines-dot { opacity:1; animation:bs-mines-armed 1.6s ease-in-out infinite; }
@keyframes bs-mines-armed { 0%,100% { opacity:.35; transform:scale(.75); } 50% { opacity:1; transform:scale(1.2); } }

.bs-mines-well { position:relative; overflow:hidden; padding:9px; border-radius:12px;
  background:radial-gradient(120% 100% at 50% -10%, rgba(255,255,255,.05), transparent 62%), var(--bs-well);
  box-shadow:inset 0 0 42px rgba(0,0,0,.9), inset 0 1px 0 rgba(255,255,255,.05); }
.bs-mines-vignette { position:absolute; inset:0; pointer-events:none; border-radius:inherit;
  background:radial-gradient(115% 90% at 50% 45%, transparent 48%, rgba(0,0,0,.6) 100%); }
.bs-mines-idle { position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  pointer-events:none; border-radius:inherit;
  background:radial-gradient(90% 70% at 50% 50%, rgba(0,0,0,.5), rgba(0,0,0,.78)); }
.bs-mines-idle-badge { padding:7px 15px; border-radius:999px; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.08), rgba(255,255,255,.02));
  font-size:10px; font-weight:900; letter-spacing:.13em; text-transform:uppercase; color:var(--bs-muted); }

/* ---- Tiles: a bevelled cap that flips over to a face ---- */
.bs-mines-tiles { display:grid; grid-template-columns:repeat(5,1fr); gap:6px; }
.bs-mines-tile { position:relative; aspect-ratio:1; padding:0; margin:0; border:0; background:none; border-radius:11px;
  perspective:620px; cursor:pointer; -webkit-tap-highlight-color:transparent;
  transition:transform .14s cubic-bezier(.2,.85,.3,1.25), filter .18s ease, opacity .18s ease; }
.bs-mines-tile:disabled { cursor:default; }
.bs-mines-flip { position:absolute; inset:0; transform-style:preserve-3d; }
.bs-mines-face { position:absolute; inset:0; overflow:hidden; display:flex; align-items:center; justify-content:center;
  border-radius:11px; border:1px solid var(--bs-line);
  backface-visibility:hidden; -webkit-backface-visibility:hidden; }
.bs-mines-back { background:linear-gradient(168deg, var(--bs-elev2) 0%, var(--bs-panel) 58%, var(--bs-bg) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14), inset 0 -3px 6px rgba(0,0,0,.5), 0 3px 7px rgba(0,0,0,.55);
  transition:border-color .14s ease, box-shadow .14s ease; }
.bs-mines-back::after { content:''; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(152deg, rgba(255,255,255,.1) 0 33%, rgba(255,255,255,0) 33% 67%, rgba(0,0,0,.18) 67% 100%); }
.bs-mines-cap { position:relative; z-index:1; width:32%; height:32%; border-radius:3px;
  border:1px solid var(--bs-soft); opacity:.5; transform:rotate(45deg);
  transition:border-color .14s ease, opacity .14s ease; }
.bs-mines-front { transform:rotateY(180deg); background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel)); }
.bs-mines-front::before { content:''; position:absolute; inset:0; pointer-events:none; opacity:0; }
.bs-mines-tile.is-revealed .bs-mines-flip { transform:rotateY(180deg); }

.bs-mines-board.is-live .bs-mines-tile:not(:disabled):hover { transform:translateY(-3px); }
.bs-mines-board.is-live .bs-mines-tile:not(:disabled):hover .bs-mines-back {
  border-color:var(--bs-orange);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.2), inset 0 -3px 6px rgba(0,0,0,.5), 0 9px 17px rgba(0,0,0,.6); }
.bs-mines-board.is-live .bs-mines-tile:not(:disabled):hover .bs-mines-cap { border-color:var(--bs-orange); opacity:1; }
.bs-mines-tile:not(:disabled):active { transform:translateY(0) scale(.93); }
.bs-mines-board.is-busy .bs-mines-tile:not(.is-digging) { opacity:.55; filter:saturate(.65); }

/* Revealed faces */
.bs-mines-tile.is-gem .bs-mines-front { border-color:var(--bs-pos); }
.bs-mines-tile.is-gem .bs-mines-front::before { opacity:.22;
  background:radial-gradient(circle at 50% 45%, var(--bs-pos), transparent 70%); }
.bs-mines-tile.is-mine .bs-mines-front { border-color:var(--bs-neg); }
.bs-mines-tile.is-mine .bs-mines-front::before { opacity:.4;
  background:radial-gradient(circle at 50% 50%, var(--bs-neg), transparent 72%); }
.bs-mines-tile.is-ghost .bs-mines-front { border-color:var(--bs-line); background:var(--bs-panel); }
.bs-mines-tile.is-ghost .bs-mines-front::before { opacity:.12;
  background:radial-gradient(circle at 50% 50%, var(--bs-neg), transparent 72%); }
.bs-mines-tile.is-ghost .bs-mines-icon { opacity:.45; filter:none; }

.bs-mines-icon { position:relative; z-index:1; display:block; width:62%; max-width:36px; line-height:0; }
.bs-mines-icon svg { display:block; width:100%; height:auto; }
.bs-mines-gemwrap { color:var(--bs-pos); filter:drop-shadow(0 2px 3px rgba(0,0,0,.55)) drop-shadow(0 0 7px currentColor); }
.bs-mines-bomb { color:var(--bs-neg); filter:drop-shadow(0 2px 3px rgba(0,0,0,.55)) drop-shadow(0 0 6px currentColor); }

/* Specular twinkle on a cut stone — white is a highlight, not a brand accent. */
.bs-mines-spark { position:absolute; width:9px; height:9px; opacity:0; pointer-events:none;
  background:linear-gradient(to right, transparent 45%, #fff 50%, transparent 55%),
             linear-gradient(to bottom, transparent 45%, #fff 50%, transparent 55%);
  animation:bs-mines-twinkle 2.6s ease-in-out infinite; }
.bs-mines-spark-a { top:2%; right:-4%; }
.bs-mines-spark-b { bottom:6%; left:-6%; width:7px; height:7px; animation-delay:1.2s; }
@keyframes bs-mines-twinkle {
  0%,74%,100% { opacity:0; transform:scale(.3) rotate(0deg); }
  86% { opacity:.95; transform:scale(1) rotate(50deg); }
}

/* The reveal itself: a real flip, then the stone pops in. */
.bs-mines-tile.is-fresh .bs-mines-flip { animation:bs-mines-flipin .52s cubic-bezier(.25,.85,.35,1.05) both; }
@keyframes bs-mines-flipin {
  0% { transform:rotateY(0deg) scale(1); }
  45% { transform:rotateY(90deg) scale(1.11); }
  100% { transform:rotateY(180deg) scale(1); }
}
.bs-mines-tile.is-fresh .bs-mines-icon { animation:bs-mines-jewelpop .42s .28s cubic-bezier(.2,.9,.3,1.5) both; }
@keyframes bs-mines-jewelpop { from { transform:scale(.45); opacity:0; } to { transform:none; opacity:1; } }

/* Digging: the tapped cap lifts and scans while the server answers. */
.bs-mines-tile.is-digging { z-index:2; }
.bs-mines-tile.is-digging .bs-mines-back { border-color:var(--bs-orange); animation:bs-mines-dig .62s ease-in-out infinite; }
@keyframes bs-mines-dig { 0%,100% { transform:translateY(0); } 50% { transform:translateY(-3px); } }
.bs-mines-tile.is-digging .bs-mines-back::before { content:''; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(circle at 50% 50%, var(--bs-orange), transparent 72%);
  animation:bs-mines-scan .62s ease-in-out infinite; }
@keyframes bs-mines-scan { 0%,100% { opacity:.1; } 50% { opacity:.46; } }

/* Detonation. */
.bs-mines-tile.is-boom { z-index:3; }
.bs-mines-tile.is-boom::after { content:''; position:absolute; left:50%; top:50%; width:14px; height:14px;
  margin:-7px 0 0 -7px; border-radius:50%; border:2px solid var(--bs-neg); pointer-events:none;
  animation:bs-mines-shock .8s .18s cubic-bezier(.15,.7,.3,1) 2 both; }
@keyframes bs-mines-shock { from { transform:scale(.35); opacity:.9; } to { transform:scale(7); opacity:0; } }
.bs-mines-board.is-boom { animation:bs-mines-shake .46s cubic-bezier(.36,.07,.19,.97) both; }
@keyframes bs-mines-shake {
  10%,90% { transform:translateX(-2px); }
  20%,80% { transform:translateX(3px); }
  30%,50%,70% { transform:translateX(-5px); }
  40%,60% { transform:translateX(5px); }
}
.bs-mines-board.is-boom .bs-mines-well { animation:bs-mines-flash .55s ease-out both; }
@keyframes bs-mines-flash {
  0% { box-shadow:inset 0 0 0 2px var(--bs-neg), inset 0 0 46px rgba(0,0,0,.9); }
  100% { box-shadow:inset 0 0 0 0 transparent, inset 0 0 42px rgba(0,0,0,.9); }
}

/* Untouched mines cascade open once the board is dead. */
.bs-mines-tile.is-ghost .bs-mines-flip { animation:bs-mines-ghostin .42s ease-out both; animation-delay:var(--bs-mines-d, 0ms); }
@keyframes bs-mines-ghostin { from { transform:rotateY(0deg); } to { transform:rotateY(180deg); } }

/* ---- Controls ---- */
.bs-mines-risk { display:flex; align-items:center; gap:10px; max-width:344px; margin:0 auto 9px; padding:7px 12px;
  border:1px solid var(--bs-line); border-radius:11px; background:var(--bs-elev); }
.bs-mines-risk-k { font-size:9px; font-weight:900; letter-spacing:.14em; text-transform:uppercase; color:var(--bs-faint); }
.bs-mines-risk-bar { flex:1 1 auto; height:5px; border-radius:3px; overflow:hidden;
  background:var(--bs-bg); box-shadow:inset 0 1px 2px rgba(0,0,0,.65); }
.bs-mines-risk-bar i { display:block; height:100%; border-radius:3px; background:var(--bs-pos); transition:width .25s ease; }
.bs-mines-risk-v { font-size:11px; font-weight:900; letter-spacing:.06em; text-transform:uppercase; color:var(--bs-pos); }
.bs-mines-risk.is-md .bs-mines-risk-bar i { background:var(--bs-orange); }
.bs-mines-risk.is-md .bs-mines-risk-v { color:var(--bs-orange); }
.bs-mines-risk.is-hi .bs-mines-risk-bar i { background:var(--bs-neg); }
.bs-mines-risk.is-hi .bs-mines-risk-v { color:var(--bs-neg); }
.bs-mines-presets { flex-wrap:wrap; margin-bottom:8px; }
.bs-mines-presets .bs-btn { min-width:44px; font-variant-numeric:tabular-nums; }

.bs-slot-ctrls .bs-mines-cash { position:relative; display:inline-flex; flex-direction:column; align-items:center;
  gap:1px; min-width:174px; line-height:1.15; }
.bs-mines-cash-k { font-size:11px; font-weight:800; letter-spacing:.09em; text-transform:uppercase; opacity:.85; }
.bs-mines-cash-v { font-size:18px; font-weight:900; font-variant-numeric:tabular-nums; }
.bs-mines-cash:not(:disabled)::after { content:''; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  border:2px solid var(--bs-pos); animation:bs-mines-cashring 1.5s ease-out infinite; }
@keyframes bs-mines-cashring { 0% { transform:scale(1); opacity:.55; } 100% { transform:scale(1.13); opacity:0; } }
.bs-mines-cash.is-cashing { opacity:.7; }

@media (max-width:420px) {
  .bs-mines-hud-v { font-size:21px; }
  .bs-mines-hud { padding:9px 10px; }
  .bs-mines-tiles { gap:5px; }
  .bs-mines-well { padding:7px; }
  .bs-mines-tag { font-size:13px; }
  .bs-mines-icon { width:66%; }
  .bs-slot-ctrls .bs-mines-cash { min-width:142px; }
  .bs-mines-result-loss { font-size:24px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-mines-tile.is-fresh .bs-mines-flip,
  .bs-mines-tile.is-fresh .bs-mines-icon,
  .bs-mines-tile.is-ghost .bs-mines-flip,
  .bs-mines-tile.is-digging .bs-mines-back,
  .bs-mines-tile.is-digging .bs-mines-back::before,
  .bs-mines-tile.is-boom::after,
  .bs-mines-board.is-boom,
  .bs-mines-board.is-boom .bs-mines-well,
  .bs-mines-board.is-live .bs-mines-dot,
  .bs-mines-spark,
  .bs-mines-hud.is-hot::after,
  .bs-mines-cash:not(:disabled)::after { animation:none !important; }
  .bs-mines-tile.is-ghost .bs-mines-flip { transform:rotateY(180deg); }
  .bs-mines-tile, .bs-mines-back, .bs-mines-cap, .bs-mines-meter-fill, .bs-mines-risk-bar i { transition:none !important; }
  .bs-mines-board.is-live .bs-mines-tile:not(:disabled):hover { transform:none; }
}
/* ============================================================================
   BLACKJACK — a real table: tinted felt with a vignette, the classic printed
   arc, a shoe the cards fly out of, a sequenced deal, a 3D hole-card turn and
   proper casino-chip hand totals. Every colour is a --bs-* token (the card
   stock itself is drawn by the shared cardFaceHtml()), so all 10 operator
   skins keep working unmodified.
   ========================================================================== */
.bs-bj-table { position:relative; padding-top:12px; }

/* Cloth: a tint pulled from the skin's own positive hue + a table vignette, on
   its own layer (not ::after) so .bs-fx-shimmer can still own the felt's
   pseudo-element while a deal is in flight. */
.bs-bj-cloth { position:absolute; inset:0; border-radius:14px; overflow:hidden; pointer-events:none; }
.bs-bj-cloth::before { content:''; position:absolute; inset:0;
  background:radial-gradient(120% 88% at 50% -6%, var(--bs-pos), transparent 66%); opacity:.10; }
.bs-bj-cloth::after { content:''; position:absolute; inset:0;
  background:radial-gradient(102% 74% at 50% 44%, transparent 36%, rgba(0,0,0,.5) 100%); }

/* The shoe the deal animation flies out of. */
.bs-bj-shoe { position:absolute; top:9px; right:11px; width:30px; height:41px; z-index:2; }
.bs-bj-shoe i { position:absolute; inset:0; display:block; border-radius:5px;
  background:repeating-linear-gradient(135deg, var(--bs-orange) 0 4px, var(--bs-orange-dp) 4px 8px);
  box-shadow:0 3px 8px rgba(0,0,0,.5), inset 0 0 0 1px rgba(255,255,255,.16); }
.bs-bj-shoe i:nth-child(1) { transform:translate(5px,-5px) rotate(6deg); opacity:.32; }
.bs-bj-shoe i:nth-child(2) { transform:translate(2px,-2px) rotate(3deg); opacity:.6; }

/* Seats */
.bs-bj-seat { position:relative; }
.bs-bj-head { position:relative; justify-content:flex-start; gap:8px; align-items:center;
  min-height:34px; margin-bottom:4px; }
.bs-bj-tag { margin-right:auto; }
.bs-bj-seat-dealer .bs-bj-head { padding-right:40px; }
.bs-bj-row { position:relative; gap:9px; }

/* Hand total as a real chip: edge notches, a recessed centre, tabular figure. */
.bs-bj-chip { position:relative; display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:34px; height:34px; border-radius:50%; letter-spacing:0;
  background:
    repeating-conic-gradient(from 8deg, var(--bs-soft) 0deg 15deg, transparent 15deg 45deg),
    radial-gradient(circle at 34% 26%, var(--bs-elev2), var(--bs-panel) 82%);
  box-shadow:0 4px 10px rgba(0,0,0,.5), inset 0 0 0 1px rgba(255,255,255,.08);
  transition:box-shadow .25s ease; }
.bs-bj-chip-face { display:flex; align-items:center; justify-content:center; width:24px; height:24px;
  border-radius:50%; background:var(--bs-elev); box-shadow:inset 0 0 0 1px var(--bs-line);
  font-size:13px; font-weight:900; line-height:1; color:var(--bs-text); font-variant-numeric:tabular-nums; }
.bs-bj-chip-win { box-shadow:0 4px 10px rgba(0,0,0,.5), 0 0 20px -4px var(--bs-pos), inset 0 0 0 1px rgba(255,255,255,.08); }
.bs-bj-chip-win .bs-bj-chip-face { color:var(--bs-pos); box-shadow:inset 0 0 0 1px var(--bs-pos); }
.bs-bj-chip-bust { box-shadow:0 4px 10px rgba(0,0,0,.5), 0 0 20px -4px var(--bs-neg), inset 0 0 0 1px rgba(255,255,255,.08); }
.bs-bj-chip-bust .bs-bj-chip-face { color:var(--bs-neg); box-shadow:inset 0 0 0 1px var(--bs-neg); }
.bs-bj-chip-bj { box-shadow:0 4px 10px rgba(0,0,0,.5), 0 0 26px -3px var(--bs-gold), inset 0 0 0 1px rgba(255,255,255,.1); }
.bs-bj-chip-bj .bs-bj-chip-face { color:var(--bs-gold-ink); box-shadow:inset 0 0 0 1px var(--bs-gold); }
.bs-bj-chip-pop { animation:bs-bj-chip-pop .42s cubic-bezier(.2,.9,.3,1.5); }
@keyframes bs-bj-chip-pop { 0% { transform:scale(.72) rotate(-14deg) } 60% { transform:scale(1.14) rotate(4deg) } 100% { transform:none } }

/* The wager sitting on the table. */
.bs-bj-bet { display:inline-flex; align-items:center; gap:5px; padding:4px 9px 4px 6px; border-radius:999px;
  background:rgba(0,0,0,.3); border:1px solid var(--bs-line); color:var(--bs-text);
  font-size:11px; font-weight:800; letter-spacing:0; font-variant-numeric:tabular-nums; }
.bs-bj-bet i { width:11px; height:11px; flex:none; border-radius:50%;
  background:radial-gradient(circle at 34% 30%, var(--bs-gold), var(--bs-orange-dp) 78%);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.4); }

/* Cards: gently fanned, dealt out of the shoe one at a time. */
.bs-bj-card { display:inline-flex; flex:none; }
.bs-bj-card > .bs-pcard, .bs-bj-flip-face > .bs-pcard { animation:none; }
.bs-bj-card:not(.bs-bj-flip) > .bs-pcard { transform-origin:50% 100%; }
.bs-bj-row .bs-bj-card:nth-child(1):not(.bs-bj-flip) > .bs-pcard { transform:rotate(-2.4deg); }
.bs-bj-row .bs-bj-card:nth-child(2):not(.bs-bj-flip) > .bs-pcard { transform:rotate(-.6deg); }
.bs-bj-row .bs-bj-card:nth-child(3):not(.bs-bj-flip) > .bs-pcard { transform:rotate(1.4deg); }
.bs-bj-row .bs-bj-card:nth-child(4):not(.bs-bj-flip) > .bs-pcard { transform:rotate(3deg); }
.bs-bj-row .bs-bj-card:nth-child(n+5):not(.bs-bj-flip) > .bs-pcard { transform:rotate(4.4deg); }
.bs-bj-card-in { animation:bs-bj-deal .38s cubic-bezier(.2,.85,.3,1.15) backwards; }
@keyframes bs-bj-deal {
  from { opacity:0; transform:translate(58px,-64px) rotate(17deg) scale(.86); }
  to   { opacity:1; transform:none; }
}
/* The hole card is the secret on the table — a hairline of gold marks it. */
.bs-bj-hole-card > .bs-pcard-back {
  box-shadow:0 6px 16px rgba(0,0,0,.45), inset 0 0 0 3px rgba(255,255,255,.18),
             0 0 0 1px var(--bs-gold), 0 0 18px -6px var(--bs-gold); }

/* The turn. Resting state is the revealed face, so with animation suppressed
   the real card is simply shown rather than left face-down. */
.bs-bj-flip { perspective:1000px; }
.bs-bj-flip-inner { display:grid; transform-style:preserve-3d; transform:rotateY(180deg);
  animation:bs-bj-reveal .64s cubic-bezier(.36,.82,.34,1) backwards;
  animation-delay:var(--bs-bj-flip-delay, 0ms); }
.bs-bj-flip-face { grid-area:1 / 1; backface-visibility:hidden; -webkit-backface-visibility:hidden; }
.bs-bj-flip-front { transform:rotateY(180deg); }
@keyframes bs-bj-reveal {
  0%   { transform:rotateY(0deg) scale(1); }
  55%  { transform:rotateY(96deg) scale(1.1); }
  100% { transform:rotateY(180deg) scale(1); }
}

/* The printed arc: "dealer must stand on 17" curved along the table line. */
.bs-bj-arc { position:relative; margin:4px 0 2px; line-height:0; }
.bs-bj-arc svg { display:block; width:100%; max-width:100%; height:auto; aspect-ratio:400 / 44; }
.bs-bj-arc-a { stroke:var(--bs-gold); stroke-width:1.1; opacity:.4; }
.bs-bj-arc-b { stroke:var(--bs-gold); stroke-width:.5; opacity:.24; }
.bs-bj-arc-t { fill:var(--bs-gold); opacity:.62; font-size:10.5px; font-weight:800;
  letter-spacing:1.1px; text-transform:uppercase; }

/* A natural gets its own treatment: gold rail on the felt + a stamped band. */
.bs-bj-table.bs-bj-natural { border-color:var(--bs-gold);
  box-shadow:inset 0 0 44px rgba(0,0,0,.5), inset 0 0 0 1px var(--bs-gold), 0 0 34px -12px var(--bs-gold); }
.bs-bj-ribbon { position:relative; margin:11px auto 1px; max-width:250px; padding:7px 14px; text-align:center;
  border-radius:999px; background:linear-gradient(180deg, var(--bs-gold), var(--bs-orange-dp));
  color:var(--bs-on-orange); font-size:12px; font-weight:900; letter-spacing:.22em; text-transform:uppercase;
  box-shadow:0 8px 20px -6px var(--bs-gold), inset 0 1px 0 rgba(255,255,255,.4);
  animation:bs-bj-ribbon-in .5s cubic-bezier(.2,.9,.3,1.5) backwards; }
@keyframes bs-bj-ribbon-in { from { opacity:0; transform:scale(.7) rotate(-6deg); } to { opacity:1; transform:none; } }

/* Result: one dominant figure, then the supporting detail. */
.bs-bj-msg { letter-spacing:.05em; }
.bs-bj-outcome { position:relative; margin:12px 0; padding:12px 14px 11px; text-align:center;
  border-radius:14px; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.012));
  animation:bs-bj-outcome-in .46s cubic-bezier(.2,.9,.3,1.35) backwards; }
@keyframes bs-bj-outcome-in { from { opacity:0; transform:translateY(10px) scale(.97); } to { opacity:1; transform:none; } }
.bs-bj-outcome-tag { font-size:13px; font-weight:900; letter-spacing:.2em; text-transform:uppercase; color:var(--bs-muted); }
.bs-bj-payout { display:block; margin:5px 0 1px; }
.bs-bj-outcome-sub { font-size:13px; font-weight:700; color:var(--bs-text); margin-top:3px; }
.bs-bj-outcome-totals { margin-top:7px; font-size:10px; font-weight:800; letter-spacing:.11em;
  text-transform:uppercase; color:var(--bs-faint); }
.bs-bj-outcome-totals b { color:var(--bs-text); font-size:12px; font-variant-numeric:tabular-nums; }
.bs-bj-outcome-win { border-color:var(--bs-pos); box-shadow:0 0 30px -12px var(--bs-pos); }
.bs-bj-outcome-win .bs-bj-outcome-tag { color:var(--bs-pos); }
.bs-bj-outcome-bj { border-color:var(--bs-gold); box-shadow:0 0 40px -10px var(--bs-gold); }
.bs-bj-outcome-bj .bs-bj-outcome-tag { color:var(--bs-gold-ink); }
.bs-bj-outcome-lose .bs-bj-outcome-tag { color:var(--bs-neg); }
.bs-bj-outcome-push .bs-bj-payout { color:var(--bs-muted); text-shadow:none; }

/* Actions: two decisive buttons, and a disabled state that reads deliberate. */
.bs-bj-actions { display:flex; gap:10px; justify-content:center; margin:0 0 4px; }
.bs-bj-act { flex:1 1 0; min-width:0; max-width:200px; display:inline-flex; flex-direction:column;
  align-items:center; justify-content:center; gap:2px; padding:11px 10px 9px; line-height:1.1; }
.bs-bj-act b { font-size:16px; font-weight:900; letter-spacing:.04em; }
.bs-bj-act i { font-style:normal; font-size:10px; font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; opacity:.72; }
.bs-bj-act:disabled { opacity:.34; cursor:default; box-shadow:none; }
.bs-bj-act:disabled:hover { filter:none; transform:none; }
.bs-btn-ghost.bs-bj-act:disabled:hover { border-color:var(--bs-soft); color:var(--bs-text); }
.bs-bj-note { text-align:center; margin:2px 0 8px; font-size:12px; }
.bs-bj-deal { min-width:132px; font-weight:900; letter-spacing:.05em; }

@media (max-width:420px) {
  .bs-bj-shoe { display:none; }
  .bs-bj-seat-dealer .bs-bj-head { padding-right:0; }
  .bs-bj-head { min-height:30px; }
  .bs-bj-chip { width:30px; height:30px; }
  .bs-bj-chip-face { width:21px; height:21px; font-size:12px; }
  .bs-bj-row { gap:6px; }
  .bs-bj-bet { font-size:10px; padding:3px 8px 3px 5px; }
  .bs-bj-act b { font-size:14px; }
  .bs-bj-act i { font-size:9px; letter-spacing:.05em; }
  .bs-bj-ribbon { font-size:11px; letter-spacing:.14em; }
  .bs-bj-outcome-tag { font-size:12px; letter-spacing:.14em; }
  .bs-bj-arc-t { font-size:11.5px; letter-spacing:.5px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-bj-card-in, .bs-bj-flip-inner, .bs-bj-outcome, .bs-bj-ribbon, .bs-bj-chip-pop { animation:none !important; }
  .bs-bj-chip { transition:none !important; }
}
/* ============================================================================
   ROULETTE — second pass: a real table.
   The wheel gains frets, a recessed ball track and a ball that orbits the rim
   then drops into the pocket the server actually returned; the flat row of bet
   buttons is replaced by the genuine felt layout (zero, 3x12 numbers, the 2:1
   column boxes, the dozens rail and the six even-money boxes) with chips that
   visibly stack on every bet placed.
   Table + pocket paint (red / black / green) and the ivory ball are physical
   materials — like a die's ivory or a card's suit red — so they stay fixed
   across all 10 operator skins. EVERY other colour here is a var(--bs-*) token.
   ========================================================================== */

/* ---- Stage: the wheel sits in a lit, vignetted well ---------------------- */
.bs-rw-stage.bs-rw-felt { position:relative; overflow:hidden; flex-direction:column; align-items:center;
  gap:10px; padding:18px 10px 14px; margin-bottom:12px;
  background-image:radial-gradient(circle at 50% 30%, rgba(255,255,255,.07), transparent 62%),
    radial-gradient(circle at 50% 122%, rgba(255,255,255,.05), transparent 58%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05), inset 0 -22px 44px rgba(0,0,0,.55), 0 10px 26px rgba(0,0,0,.35);
  transition:box-shadow .35s ease; }
.bs-rw-stage.bs-rw-felt.is-win { box-shadow:inset 0 1px 0 rgba(255,255,255,.06),
  inset 0 -22px 44px rgba(0,0,0,.55), 0 0 0 1px var(--bs-gold), 0 0 34px -10px var(--bs-gold); }
.bs-rw-vign { position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(ellipse at 50% 30%, rgba(0,0,0,0) 40%, rgba(0,0,0,.55) 100%); }

/* ---- Wheel: frets, recessed ball track, turret hub ----------------------- */
.bs-rw-stage .bs-rw-wheel-wrap { position:relative; z-index:2; flex:none; width:196px; height:196px; }
.bs-rw-stage .bs-rw-pointer { top:-9px; z-index:6; font-size:22px; line-height:1; color:var(--bs-gold-ink);
  filter:drop-shadow(0 2px 5px rgba(0,0,0,.75)); }
.bs-rw-stage .bs-rw-num { width:16px; margin-left:-8px; font-size:9px; line-height:11px; }
.bs-rw-wheel-wrap .bs-rw-btrack { position:absolute; inset:5px; z-index:1; border-radius:50%; pointer-events:none;
  box-shadow:inset 0 0 0 12px rgba(var(--bs-well-rgb), .86), inset 0 0 12px 12px rgba(0,0,0,.45); }
.bs-rw-wheel-wrap .bs-rw-btrack::after { content:''; position:absolute; inset:12px; border-radius:50%;
  box-shadow:0 0 0 1px rgba(255,255,255,.13), inset 0 0 12px rgba(0,0,0,.55); }
.bs-rw-wheel-wrap .bs-rw-rim { z-index:2;
  box-shadow:inset 0 0 0 4px var(--bs-elev2), inset 0 0 0 6px rgba(0,0,0,.6), inset 0 0 22px rgba(0,0,0,.5),
    0 0 0 1px rgba(255,255,255,.08), 0 16px 34px rgba(0,0,0,.6); }
.bs-rw-wheel-wrap .bs-rw-cone { z-index:2; width:92px; height:92px; margin:-46px 0 0 -46px;
  background:radial-gradient(circle at 50% 26%, var(--bs-elev2), var(--bs-panel) 68%, var(--bs-bg) 100%);
  box-shadow:0 0 0 2px rgba(0,0,0,.5), inset 0 8px 16px rgba(0,0,0,.5), inset 0 -6px 12px rgba(255,255,255,.05); }

.bs-rw-orbit { position:absolute; inset:0; z-index:3; pointer-events:none;
  transition:transform 2.2s cubic-bezier(.15,.85,.25,1); }
.bs-rw-orbit.bs-rw-launch { transition:transform 2.4s cubic-bezier(.32,.05,.62,.42); }
.bs-rw-wheel.bs-rw-nofx, .bs-rw-orbit.bs-rw-nofx { transition:none !important; }
.bs-rw-orbit .bs-rw-ball { top:8px; width:10px; height:10px; margin-left:-5px;
  background:radial-gradient(circle at 34% 28%, #ffffff, #cfd3da 52%, #8e949e 100%);
  box-shadow:0 3px 7px rgba(0,0,0,.75), inset 0 -2px 3px rgba(0,0,0,.25);
  transition:transform .55s cubic-bezier(.25,1.5,.5,1); }
.bs-rw-orbit .bs-rw-ball.is-in { transform:translateY(11px) scale(.94); }

.bs-rw-stage .bs-rw-hub { z-index:5; width:46px; height:46px; border:0;
  background:radial-gradient(circle at 50% 26%, var(--bs-elev2), var(--bs-panel) 70%);
  box-shadow:0 0 0 2px var(--bs-gold), 0 0 0 5px rgba(0,0,0,.55), 0 6px 14px rgba(0,0,0,.6),
    inset 0 2px 6px rgba(255,255,255,.10); }
.bs-rw-hub-n { font-size:16px; font-weight:900; letter-spacing:-.02em; color:var(--bs-text);
  font-variant-numeric:tabular-nums; }
.bs-rw-stage .bs-rw-hub.is-win { animation:bs-rw-hub-pulse 1.6s ease-in-out infinite; }
.bs-rw-hub.is-win .bs-rw-hub-n { color:var(--bs-gold-ink); }
@keyframes bs-rw-hub-pulse {
  0%,100% { box-shadow:0 0 0 2px var(--bs-gold), 0 0 0 5px rgba(0,0,0,.55), 0 6px 14px rgba(0,0,0,.6); }
  50%     { box-shadow:0 0 0 2px var(--bs-gold), 0 0 0 5px rgba(0,0,0,.55), 0 0 26px 2px var(--bs-gold); }
}

/* ---- Caption slot: taking bets → no more bets → winning number ----------- */
.bs-rw-caption { position:relative; z-index:2; display:flex; align-items:center; justify-content:center;
  min-height:28px; padding:6px 16px; border-radius:999px; border:1px solid var(--bs-line);
  background:rgba(0,0,0,.34); color:var(--bs-faint);
  font-size:10px; font-weight:900; letter-spacing:.2em; text-transform:uppercase; }
.bs-rw-caption-live { color:var(--bs-orange); border-color:var(--bs-orange); background:rgba(0,0,0,.5); }
.bs-rw-plaque { position:relative; z-index:2; display:flex; flex-wrap:wrap; align-items:center;
  justify-content:center; gap:10px 12px; width:100%; padding:9px 12px; border-radius:12px;
  border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.07), rgba(255,255,255,.015));
  animation:bs-rw-plaque-in .4s cubic-bezier(.2,.9,.3,1.4); }
@keyframes bs-rw-plaque-in { from { transform:translateY(6px); opacity:0; } to { transform:none; opacity:1; } }
.bs-rw-plaque.is-win { border-color:var(--bs-gold);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.06), 0 0 26px -8px var(--bs-gold); }
.bs-rw-plaque-txt { display:flex; flex-direction:column; gap:2px; min-width:0; text-align:left; }
.bs-rw-plaque-txt b { font-size:9px; font-weight:900; letter-spacing:.14em; text-transform:uppercase; color:var(--bs-faint); }
.bs-rw-plaque-txt i { font-style:normal; font-size:15px; font-weight:800; color:var(--bs-text); }
.bs-rw-plaque .bs-rw-payout { flex:1 0 100%; text-align:center; }

/* ---- Results board ------------------------------------------------------- */
.bs-rw-histbar { position:relative; z-index:2; display:flex; align-items:center; gap:8px; width:100%;
  padding:6px 9px; border-radius:10px; border:1px solid var(--bs-line); background:rgba(0,0,0,.34);
  overflow:hidden; }
.bs-rw-histlbl { flex:none; font-size:9px; font-weight:900; letter-spacing:.13em; text-transform:uppercase;
  color:var(--bs-faint); }
.bs-rw-histbar .bs-rw-history { flex:1; min-width:0; margin-bottom:0; gap:3px; flex-wrap:nowrap;
  justify-content:flex-start; overflow:hidden; }
.bs-rw-histbar .bs-rw-hist { flex:none; width:19px; height:19px; font-size:9px; }
.bs-rw-histbar .bs-rw-hist:first-child { width:21px; height:21px; font-size:10px; }

/* ---- The felt betting layout -------------------------------------------- */
.bs-rw-table { position:relative; padding:8px 7px; margin-bottom:10px; border-radius:12px;
  border:1px solid var(--bs-line);
  background:radial-gradient(130% 110% at 50% -30%, var(--bs-elev2), var(--bs-elev) 50%, var(--bs-panel) 100%);
  box-shadow:inset 0 0 46px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.05), 0 8px 22px rgba(0,0,0,.35); }
.bs-rw-table::before { content:''; position:absolute; inset:3px; border-radius:9px;
  border:1px solid var(--bs-line); opacity:.45; pointer-events:none; }
.bs-rw-layout { position:relative; display:grid; gap:2px;
  grid-template-columns:1.22fr repeat(12, 1fr) 1.06fr;
  grid-template-rows:repeat(3, clamp(21px, 6.2vw, 30px)) clamp(20px, 5.6vw, 26px) clamp(20px, 5.6vw, 26px); }

.bs-rw-cell { position:relative; display:flex; align-items:center; justify-content:center;
  min-width:0; margin:0; padding:0; overflow:visible; cursor:pointer; line-height:1; color:#fff;
  font-family:inherit; -webkit-appearance:none; appearance:none;
  border:1px solid rgba(255,255,255,.15); border-radius:4px;
  background:linear-gradient(180deg, rgba(255,255,255,.08), rgba(255,255,255,.02));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16), 0 1px 2px rgba(0,0,0,.5);
  transition:transform .12s ease, box-shadow .16s ease, filter .2s ease; }
.bs-rw-cell:hover:not(:disabled) { z-index:4; transform:translateY(-1px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28), 0 0 0 1px var(--bs-gold), 0 5px 12px rgba(0,0,0,.55); }
.bs-rw-cell:active:not(:disabled) { transform:translateY(0); }
.bs-rw-cell:disabled { cursor:default; }
.bs-rw-cell-n { font-size:clamp(8px, 2.5vw, 13px); font-weight:800; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; text-shadow:0 1px 2px rgba(0,0,0,.8); }
.bs-rw-cell-lbl { max-width:100%; padding:0 2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-size:clamp(6.5px, 2vw, 10px); font-weight:800; letter-spacing:.02em; text-transform:uppercase;
  color:var(--bs-text); }
.bs-rw-diamond { font-size:clamp(9px, 2.8vw, 14px); color:#fff; text-shadow:0 1px 2px rgba(0,0,0,.8); }
.bs-rw-cell.has-chip .bs-rw-cell-n, .bs-rw-cell.has-chip .bs-rw-cell-lbl { opacity:.78; }
.bs-rw-cell.is-drawn { z-index:3; animation:bs-rw-drawn 1.5s ease-in-out infinite; }
@keyframes bs-rw-drawn {
  0%,100% { box-shadow:inset 0 0 0 2px var(--bs-gold), 0 0 10px -3px var(--bs-gold); }
  50%     { box-shadow:inset 0 0 0 2px var(--bs-gold), 0 0 22px 0 var(--bs-gold); }
}
.bs-rw-layout.is-locked .bs-rw-cell:not(.is-drawn) { filter:saturate(.5) brightness(.66); }
/* Outside boxes read as printed felt, not as buttons, until hovered. */
.bs-rw-cell-out { background:linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.025)); }
.bs-rw-cell-col { background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.015)); }
.bs-rw-cell-doz { background:linear-gradient(180deg, rgba(255,255,255,.13), rgba(255,255,255,.03)); }
.bs-rw-cell-even { box-shadow:inset 0 1px 0 rgba(255,255,255,.22), 0 1px 2px rgba(0,0,0,.55); }
.bs-rw-cell-col .bs-rw-cell-lbl { font-size:clamp(7px, 2.1vw, 11px); letter-spacing:0; color:var(--bs-gold-ink); }

/* ---- Chips stacked on the felt ------------------------------------------ */
.bs-rw-chipstack { position:absolute; right:1px; bottom:1px; z-index:2; width:16px; height:16px; pointer-events:none; }
.bs-rw-chip-u, .bs-rw-chip-t { position:absolute; inset:0; border-radius:50%; font-style:normal; }
.bs-rw-chip-u { background:radial-gradient(circle at 38% 30%, var(--bs-gold), var(--bs-orange-dp) 82%);
  box-shadow:0 1px 2px rgba(0,0,0,.7), inset 0 0 0 1px rgba(255,255,255,.35); }
.bs-rw-chip-u1 { transform:translateY(-2.5px); }
.bs-rw-chip-u2 { transform:translateY(-5px); }
.bs-rw-chip-t { display:flex; align-items:center; justify-content:center;
  font-size:8px; font-weight:900; letter-spacing:-.03em; font-variant-numeric:tabular-nums;
  color:var(--bs-on-orange);
  background:radial-gradient(circle at 36% 26%, var(--bs-orange-br), var(--bs-orange) 55%, var(--bs-orange-dp) 100%);
  box-shadow:0 2px 5px rgba(0,0,0,.75), inset 0 0 0 1.4px rgba(255,255,255,.6), inset 0 0 0 3px var(--bs-orange-dp);
  animation:bs-rw-chip-in .28s cubic-bezier(.2,.9,.3,1.5); }
@keyframes bs-rw-chip-in { from { transform:translateY(-7px) scale(.6); opacity:0; } to { transform:none; opacity:1; } }
.bs-rw-chipstack.is-won .bs-rw-chip-t { color:var(--bs-bg);
  background:radial-gradient(circle at 36% 26%, rgba(255,255,255,.85), var(--bs-pos) 62%);
  box-shadow:0 2px 6px rgba(0,0,0,.75), 0 0 12px -1px var(--bs-pos), inset 0 0 0 1.4px rgba(255,255,255,.6); }
.bs-rw-chipstack.is-lost { opacity:.32; filter:grayscale(.75); }

/* ---- Chip rack ----------------------------------------------------------- */
.bs-rw-rack { display:flex; align-items:center; justify-content:center; flex-wrap:wrap; gap:9px; margin:0 0 10px; }
.bs-rw-rack-lbl { font-size:10px; font-weight:900; letter-spacing:.14em; text-transform:uppercase; color:var(--bs-faint); }
.bs-rw-rchip { position:relative; display:flex; align-items:center; justify-content:center;
  width:38px; height:38px; padding:0; border:0; border-radius:50%; cursor:pointer; font-family:inherit;
  background:radial-gradient(circle at 36% 24%, var(--bs-orange-br), var(--bs-orange) 52%, var(--bs-orange-dp) 100%);
  box-shadow:0 5px 12px rgba(0,0,0,.5), inset 0 0 0 2px rgba(255,255,255,.5),
    inset 0 0 0 5px var(--bs-orange-dp), inset 0 -4px 8px rgba(0,0,0,.3);
  transition:transform .14s ease, box-shadow .18s ease; }
.bs-rw-rchip-v { position:relative; z-index:2; font-size:12px; font-weight:900; color:var(--bs-on-orange);
  font-variant-numeric:tabular-nums; text-shadow:0 1px 1px rgba(0,0,0,.25); }
.bs-rw-rchip:hover:not(:disabled) { transform:translateY(-2px); }
.bs-rw-rchip.is-active { transform:translateY(-2px);
  box-shadow:0 7px 16px rgba(0,0,0,.55), 0 0 0 2px var(--bs-gold), inset 0 0 0 2px rgba(255,255,255,.6),
    inset 0 0 0 5px var(--bs-orange-dp); }
.bs-rw-rchip:disabled { opacity:.38; cursor:default; }
@supports (mask: radial-gradient(#000, #000)) {
  .bs-rw-rchip::before { content:''; position:absolute; inset:2px; z-index:1; border-radius:50%; pointer-events:none;
    opacity:.5; background:repeating-conic-gradient(rgba(255,255,255,.9) 0deg 13deg, rgba(255,255,255,0) 13deg 45deg);
    -webkit-mask:radial-gradient(circle, transparent 0 63%, #000 63% 100%);
    mask:radial-gradient(circle, transparent 0 63%, #000 63% 100%); }
}

/* ---- Slip trimmings ------------------------------------------------------ */
.bs-rail.bs-rw-div { margin:0 0 10px; }
.bs-rw-empty { text-align:center; }
.bs-rw-slip-dot { flex:none; width:9px; height:9px; border-radius:50%; background:var(--bs-soft);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.25); }
.bs-rw-slip-totalv { font-weight:900; color:var(--bs-text); font-variant-numeric:tabular-nums; }
.bs-rw-slip-acts { display:flex; justify-content:flex-end; margin-top:3px; }

/* ---- Physical table paint (fixed across skins, like die ivory) ----------- */
.bs-rw-cell-red { background:linear-gradient(180deg, #d2373d, #a51e24); border-color:rgba(255,255,255,.2); }
.bs-rw-cell-black { background:linear-gradient(180deg, #2c2c2c, #101010); border-color:rgba(255,255,255,.2); }
.bs-rw-cell-green { background:linear-gradient(180deg, #16a35c, #0a6b3a); border-color:rgba(255,255,255,.2); }

@media (max-width: 420px) {
  /* Reclaim some of the modal's own padding so 14 table columns stay legible. */
  .bs-rw-table { margin-left:-14px; margin-right:-14px; padding:7px 5px; }
  .bs-rw-layout { gap:1.5px; }
  .bs-rw-chipstack { width:14px; height:14px; }
  .bs-rw-chip-t { font-size:7px; }
  .bs-rw-rack { gap:7px; }
  .bs-rw-rchip { width:34px; height:34px; }
  .bs-rw-rchip-v { font-size:11px; }
  .bs-rw-plaque-txt i { font-size:13px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-rw-orbit, .bs-rw-orbit.bs-rw-launch, .bs-rw-orbit .bs-rw-ball, .bs-rw-cell,
  .bs-rw-rchip, .bs-rw-stage.bs-rw-felt { transition:none !important; }
  .bs-rw-cell.is-drawn, .bs-rw-stage .bs-rw-hub.is-win, .bs-rw-chip-t, .bs-rw-plaque { animation:none !important; }
  .bs-rw-cell.is-drawn { box-shadow:inset 0 0 0 2px var(--bs-gold) !important; }
}
/* ============================================================================
   CRASH v2 — the flagship. A drawn flight curve, escalating heat as the
   multiplier climbs, an urgent cash-out, and a bust that is impossible to miss.
   Every brand colour resolves through --bs-* tokens; the only fixed colours are
   physical materials (hull metal, the near-black sky, white-hot exhaust core).
   ========================================================================= */

/* ---- the stage: a real place, not a flat panel -------------------------- */
.bs-crash-stage {
  height: 248px; margin-bottom: 10px;
  --bs-crash-curve: var(--bs-pos);
  background:
    radial-gradient(120% 70% at 50% 122%, rgba(255,255,255,.055), transparent 62%),
    linear-gradient(180deg, #04070f 0%, #071229 38%, #0a1830 64%, var(--bs-well) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.06),
    inset 0 -34px 64px rgba(0,0,0,.5),
    0 14px 30px rgba(0,0,0,.42);
}
/* escalating intensity — the whole stage warms as the multiplier climbs */
.bs-crash-stage.bs-crash-h1 { --bs-crash-curve: var(--bs-gold); }
.bs-crash-stage.bs-crash-h2 { --bs-crash-curve: var(--bs-orange); }
.bs-crash-stage.bs-crash-h3 { --bs-crash-curve: var(--bs-orange-br); }
.bs-crash-stage.bs-crash-busted { --bs-crash-curve: var(--bs-neg); }

.bs-crash-rail { margin: 9px 0 10px; }

/* scrolling grid + speed lines sell the velocity */
.bs-crash-stage.bs-crash-flying .bs-ascend-grid { animation: bs-crash-grid 2.6s linear infinite; }
@keyframes bs-crash-grid { from { background-position: 0 0; } to { background-position: -24px 24px; } }

.bs-crash-speed {
  position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: 0;
  transition: opacity .35s ease;
  background-image: repeating-linear-gradient(101deg, rgba(255,255,255,.34) 0 1px, transparent 1px 9px);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 45%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 45%, transparent);
}
.bs-crash-stage.bs-crash-flying .bs-crash-speed { opacity: .13; animation: bs-crash-streak .55s linear infinite; }
.bs-crash-stage.bs-crash-flying.bs-crash-h1 .bs-crash-speed { opacity: .22; animation-duration: .38s; }
.bs-crash-stage.bs-crash-flying.bs-crash-h2 .bs-crash-speed { opacity: .34; animation-duration: .26s; }
.bs-crash-stage.bs-crash-flying.bs-crash-h3 .bs-crash-speed { opacity: .46; animation-duration: .17s; }
@keyframes bs-crash-streak { from { background-position: 0 0; } to { background-position: -72px 0; } }

.bs-crash-vignette {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: radial-gradient(118% 96% at 50% 44%, transparent 44%, rgba(0,0,0,.58) 100%);
}
.bs-crash-stage.bs-crash-hot .bs-crash-horizon { opacity: .58; }
.bs-crash-stage.bs-crash-h3 .bs-crash-horizon { opacity: .74; }

/* launch pad */
.bs-crash-pad { width: 46px; height: 13px; opacity: .55; }
.bs-crash-padbase {
  position: absolute; z-index: 1; width: 36px; height: 3px; border-radius: 2px;
  transform: translate(-50%, 50%); pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--bs-soft), transparent);
}

/* ---- the drawn flight curve --------------------------------------------- */
.bs-crash-plot {
  position: absolute; inset: 0; width: 100%; height: 100%; z-index: 3;
  pointer-events: none; overflow: visible;
  color: var(--bs-crash-curve, var(--bs-pos));
  filter: drop-shadow(0 0 5px currentColor);
  transition: filter .3s ease;
}
.bs-crash-stage.bs-crash-h2 .bs-crash-plot { filter: drop-shadow(0 0 9px currentColor); }
.bs-crash-stage.bs-crash-h3 .bs-crash-plot { filter: drop-shadow(0 0 14px currentColor); }
.bs-crash-curve { fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.bs-crash-curve-fill { stroke: none; }
.bs-crash-ghostline { fill: none; stroke: var(--bs-muted); stroke-width: 2; stroke-dasharray: 4 5; opacity: .4; }
.bs-crash-plot .bs-crash-g0 { stop-color: var(--bs-crash-curve, var(--bs-pos)); stop-opacity: .32; }
.bs-crash-plot .bs-crash-g1 { stop-color: var(--bs-crash-curve, var(--bs-pos)); stop-opacity: 0; }

/* ---- the ship ------------------------------------------------------------ */
.bs-crash-stage .bs-ascend-craft { z-index: 4; font-size: 0; }
.bs-crash-ship { position: relative; display: inline-block; line-height: 0; transform: rotate(32deg); }
.bs-crash-stage.bs-crash-flying .bs-crash-ship { animation: bs-crash-fly 1.15s ease-in-out infinite; }
@keyframes bs-crash-fly {
  0%, 100% { transform: rotate(32deg) translateY(0); }
  50%      { transform: rotate(29deg) translateY(-3px); }
}
.bs-crash-rocket { display: block; width: 30px; height: 39px; filter: drop-shadow(0 3px 6px rgba(0,0,0,.6)); }

/* exhaust plume — rides inside the ship so it always points aft */
.bs-crash-plume {
  position: absolute; left: 50%; bottom: -5px; width: 16px; height: 22px; margin-left: -8px;
  border-radius: 50% 50% 60% 60% / 28% 28% 100% 100%; opacity: 0; pointer-events: none;
  transform-origin: 50% 0;
  background: linear-gradient(180deg, rgba(255,255,255,.95) 0%, var(--bs-gold) 30%, var(--bs-orange) 62%, transparent 100%);
}
.bs-crash-stage.bs-crash-flying .bs-crash-plume,
.bs-crash-stage.bs-crash-igniting .bs-crash-plume { opacity: 1; animation: bs-crash-plume .22s ease-in-out infinite alternate; }
@keyframes bs-crash-plume {
  from { transform: scale(.82, .6); opacity: .7; }
  to   { transform: scale(1.05, 1.28); opacity: 1; }
}
.bs-crash-stage.bs-crash-h2 .bs-crash-plume { height: 30px; }
.bs-crash-stage.bs-crash-h3 .bs-crash-plume { height: 38px; }
.bs-crash-stage.bs-crash-busted .bs-crash-plume { opacity: 0; }

/* ==========================================================================
   ELEVEN CRAFT
   --------------------------------------------------------------------------
   Each crash variant flies its own vehicle (see craftSvg() in the engine).
   They share one class vocabulary so this block themes all of them and a new
   variant needs no new CSS.

   Placed AFTER the ship rules above on purpose. Several of these have the same
   specificity as rules above — .bs-crash-ship and
   .bs-crash-stage.bs-crash-flying .bs-crash-ship are each redeclared here to
   swap the fixed rocket angle for the per-variant --bs-vspin — and equal
   specificity is resolved by source order, so putting them earlier would
   silently lose every fight.
   ========================================================================== */

/* Resting angle is per-variant: a rocket points along its climb, a balloon and
   a lift cage do not, and rotating those like a rocket reads as falling over. */
.bs-crash-ship { transform: rotate(var(--bs-vspin, 32deg)); }
.bs-crash-stage.bs-crash-flying .bs-crash-ship { animation: bs-crash-fly-v 1.15s ease-in-out infinite; }
@keyframes bs-crash-fly-v {
  0%, 100% { transform: rotate(var(--bs-vspin, 32deg)) translateY(0); }
  50%      { transform: rotate(calc(var(--bs-vspin, 32deg) - 3deg)) translateY(-3px); }
}

/* Hull is a physical material; accents carry the variant's own hue, so every
   craft is recognisably part of the same family without being the same shape. */
.bs-cr-hull    { fill: #e8edf6; }
.bs-cr-shade   { fill: #b2bdd1; }
.bs-cr-dark    { fill: #7f8ca3; stroke: #7f8ca3; }
.bs-cr-port    { fill: #0a1526; stroke: #94a2ba; stroke-width: 1.4; }
.bs-cr-glint   { fill: rgba(255,255,255,.55); }
.bs-cr-accent  { fill: hsl(var(--bs-vh, 32) 92% 58%); }
.bs-cr-accent2 { fill: hsl(var(--bs-vh, 32) 78% 42%); }
/* The dart's reticle and the diver's rigging are strokes, not fills. */
.bs-craft-dart .bs-cr-dark,
.bs-craft-diver .bs-cr-dark,
.bs-craft-balloon .bs-cr-dark { fill: none; }
.bs-craft-diver .bs-cr-dark,
.bs-craft-balloon .bs-cr-dark { stroke: #93a1b8; }
.bs-craft-dart .bs-cr-dark { stroke: hsl(var(--bs-vh, 32) 92% 66%); }
.bs-craft-dart rect.bs-cr-dark { fill: #7f8ca3; stroke: none; }
.bs-craft-rackcar .bs-cr-dark,
.bs-craft-lift .bs-cr-dark,
.bs-craft-cablecar .bs-cr-dark,
.bs-craft-capsule .bs-cr-dark,
.bs-craft-airship .bs-cr-dark,
.bs-craft-dragster .bs-cr-dark { stroke: none; }

/* Only things with engines get an exhaust plume. A balloon, a cable car, a
   lift cage, a rack car and a parachutist do not — leaving the rocket flame
   under them was most of what made the eleven read as one game. */
.bs-craft-balloon  ~ .bs-crash-plume,
.bs-craft-cablecar ~ .bs-crash-plume,
.bs-craft-lift     ~ .bs-crash-plume,
.bs-craft-rackcar  ~ .bs-crash-plume,
.bs-craft-diver    ~ .bs-crash-plume { display: none; }

/* A dragster throws a flat, wide burnout rather than a tapered rocket plume. */
.bs-craft-dragster ~ .bs-crash-plume {
  width: 26px; margin-left: -13px; height: 14px; bottom: -3px;
  border-radius: 50% 50% 40% 40% / 40% 40% 100% 100%;
}
/* An airship's props are a soft wash, not a flame. */
.bs-craft-airship ~ .bs-crash-plume {
  width: 12px; margin-left: -6px; height: 12px; opacity: .5;
  background: radial-gradient(circle, rgba(255,255,255,.7), transparent 70%);
}
/* The two-stage burns hardest — it is the one that welds two curves together. */
.bs-craft-twostage ~ .bs-crash-plume { width: 19px; margin-left: -9.5px; }

/* Per-craft silhouette cues that no recolour could give you. */
.bs-craft-balloon  { filter: drop-shadow(0 3px 8px hsla(var(--bs-vh, 318) 80% 40% / .55)); }
.bs-craft-dart     { filter: drop-shadow(0 0 7px hsla(var(--bs-vh, 190) 95% 60% / .6)); }
.bs-craft-capsule  { filter: drop-shadow(0 3px 9px rgba(0,0,0,.75)); }
.bs-craft-lift     { filter: drop-shadow(0 4px 5px rgba(0,0,0,.7)); }

/* The canopy only makes sense open. On a bust it is the whole point of the
   variant — the stake is half refunded — so it stays visible while the rocket
   variants explode. */
.bs-crash-stage.bs-crash-busted .bs-craft-diver { opacity: 1; }
.bs-crash-stage.bs-crash-busted .bs-craft-diver .bs-cr-hull { fill: hsl(var(--bs-vh, 172) 70% 62%); }

.bs-crash-halo {
  position: absolute; left: 50%; top: 50%; width: 54px; height: 54px; margin: -27px 0 0 -27px;
  border-radius: 50%; pointer-events: none; opacity: 0; transition: opacity .3s ease;
  background: radial-gradient(circle, var(--bs-crash-curve, var(--bs-pos)), transparent 66%);
}
.bs-crash-stage.bs-crash-flying .bs-crash-halo { opacity: .2; }
.bs-crash-stage.bs-crash-flying.bs-crash-h2 .bs-crash-halo { opacity: .32; }
.bs-crash-stage.bs-crash-flying.bs-crash-h3 .bs-crash-halo { opacity: .46; }

/* ---- HUD ----------------------------------------------------------------- */
.bs-crash-hud {
  position: absolute; top: 9px; left: 10px; right: 10px; z-index: 6;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  pointer-events: none; font-size: 9px;
}
.bs-crash-pill {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px; border-radius: 999px;
  background: rgba(0,0,0,.45); border: 1px solid var(--bs-line); color: var(--bs-faint);
  font-weight: 800; letter-spacing: .11em; text-transform: uppercase; white-space: nowrap;
  transition: color .25s ease, border-color .25s ease;
}
.bs-crash-pill i { width: 6px; height: 6px; border-radius: 50%; background: var(--bs-soft); font-style: normal; flex: 0 0 auto; }
.bs-crash-stage.bs-crash-flying .bs-crash-pill { color: var(--bs-crash-curve, var(--bs-pos)); border-color: var(--bs-crash-curve, var(--bs-pos)); }
.bs-crash-stage.bs-crash-flying .bs-crash-pill i { background: currentColor; animation: bs-crash-blip 1s ease-in-out infinite; }
@keyframes bs-crash-blip { 0%, 100% { opacity: 1; } 50% { opacity: .28; } }
.bs-crash-stage.bs-crash-busted .bs-crash-pill { color: var(--bs-neg); border-color: var(--bs-neg); }
.bs-crash-stage.bs-crash-busted .bs-crash-pill i { background: var(--bs-neg); }
.bs-crash-stage.bs-crash-cashed .bs-crash-pill { color: var(--bs-gold-ink); border-color: var(--bs-gold); }
.bs-crash-stage.bs-crash-cashed .bs-crash-pill i { background: var(--bs-gold); }
.bs-crash-risk {
  color: var(--bs-muted); font-weight: 800; letter-spacing: .02em; white-space: nowrap;
  font-variant-numeric: tabular-nums; text-shadow: 0 1px 4px rgba(0,0,0,.8);
}

/* ---- the one number that matters ---------------------------------------- */
.bs-crash-stage .bs-crash-readout {
  top: 30px; z-index: 6; font-size: 50px; font-weight: 900; line-height: 1;
  letter-spacing: -.025em; font-variant-numeric: tabular-nums;
  text-shadow: 0 3px 16px rgba(0,0,0,.85);
  transition: color .18s ease, transform .18s ease;
}
.bs-crash-x { font-style: normal; font-size: .42em; font-weight: 800; letter-spacing: 0; opacity: .6; margin-left: .05em; vertical-align: .34em; }
.bs-crash-stage.bs-crash-h1 .bs-crash-readout.bs-ascend-live { color: var(--bs-gold-ink); text-shadow: 0 0 28px rgba(var(--bs-gold-rgb),.5); }
.bs-crash-stage.bs-crash-h2 .bs-crash-readout.bs-ascend-live { color: var(--bs-orange); text-shadow: 0 0 34px rgba(255,138,0,.55); transform: scale(1.05); }
.bs-crash-stage.bs-crash-h3 .bs-crash-readout.bs-ascend-live { color: var(--bs-orange-br); transform: scale(1.1); animation: bs-crash-throb .5s ease-in-out infinite alternate; }
@keyframes bs-crash-throb { from { text-shadow: 0 0 22px rgba(255,138,0,.45); } to { text-shadow: 0 0 46px rgba(255,196,0,.8); } }
.bs-crash-stage.bs-crash-busted .bs-crash-readout { color: var(--bs-neg); text-shadow: 0 0 26px rgba(255,90,95,.5); }
.bs-crash-stage.bs-crash-cashed .bs-crash-readout { color: var(--bs-gold-ink); text-shadow: 0 0 26px rgba(var(--bs-gold-rgb),.5); }

/* ---- the bust: flash, shockwaves, debris -------------------------------- */
.bs-crash-stage.bs-crash-busted { animation: bs-crash-quake .45s cubic-bezier(.36,.07,.19,.97); }
@keyframes bs-crash-quake {
  10% { transform: translate(-4px, 2px); } 22% { transform: translate(5px, -3px); }
  35% { transform: translate(-6px, 1px); } 48% { transform: translate(4px, 3px); }
  62% { transform: translate(-3px, -2px); } 78% { transform: translate(2px, 1px); }
  100% { transform: none; }
}
.bs-crash-flash {
  position: absolute; inset: 0; z-index: 5; pointer-events: none; font-style: normal;
  background: radial-gradient(circle at 50% 50%, var(--bs-neg), transparent 78%);
  opacity: 0; animation: bs-crash-flash .55s ease-out forwards;
}
@keyframes bs-crash-flash { 0% { opacity: .6; } 100% { opacity: 0; } }
.bs-crash-boom { z-index: 5; font-size: 38px; }
.bs-crash-shock {
  position: absolute; z-index: 5; width: 24px; height: 24px; border-radius: 50%;
  border: 3px solid var(--bs-neg); pointer-events: none; font-style: normal;
  transform: translate(-50%, 50%) scale(.2);
  animation: bs-crash-shock .78s cubic-bezier(.15,.75,.3,1) forwards;
}
.bs-crash-shock2 { animation-delay: .13s; border-color: var(--bs-orange-br); }
@keyframes bs-crash-shock {
  0%   { transform: translate(-50%, 50%) scale(.2); opacity: .95; border-width: 3px; }
  100% { transform: translate(-50%, 50%) scale(7); opacity: 0; border-width: 1px; }
}
.bs-crash-shard {
  position: absolute; z-index: 5; width: 4px; height: 4px; border-radius: 1px;
  pointer-events: none; font-style: normal;
  background: var(--bs-neg); box-shadow: 0 0 7px var(--bs-neg);
  transform: translate(-50%, 50%);
  animation: bs-crash-shard .74s cubic-bezier(.2,.7,.4,1) forwards;
}
@keyframes bs-crash-shard {
  0%   { transform: translate(-50%, 50%) translate(0, 0) scale(1); opacity: 1; }
  100% { transform: translate(-50%, 50%) translate(var(--bs-crash-sx, 0), var(--bs-crash-sy, 0)) scale(.25); opacity: 0; }
}

/* ---- settled-round banner ------------------------------------------------ */
.bs-crash-result {
  position: relative; margin: 0 0 10px; padding: 12px 14px 11px; border-radius: 14px; text-align: center;
  border: 1px solid var(--bs-line);
  background:
    radial-gradient(ellipse at 50% -20%, rgba(255,255,255,.07), transparent 62%),
    linear-gradient(180deg, var(--bs-elev), var(--bs-panel));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05), 0 10px 26px rgba(0,0,0,.35);
}
.bs-crash-result-l {
  font-size: 11px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  color: var(--bs-muted);
}
.bs-crash-result-l b { color: var(--bs-text); font-variant-numeric: tabular-nums; }
.bs-crash-result-s { font-size: 11px; font-weight: 800; letter-spacing: .06em; color: var(--bs-faint); margin-top: 2px; }
.bs-crash-result-win { border-color: var(--bs-gold); }
.bs-crash-result-win .bs-crash-result-s { color: var(--bs-gold-ink); }
.bs-crash-payout { display: block; margin: 4px 0 1px; font-size: 34px; line-height: 1.05; }
.bs-crash-result-bust { border-color: var(--bs-neg); }
.bs-crash-bustv {
  display: block; margin: 3px 0 1px; font-size: 32px; font-weight: 900; line-height: 1.05;
  color: var(--bs-neg); letter-spacing: -.015em; font-variant-numeric: tabular-nums;
  text-shadow: 0 0 20px rgba(255,90,95,.35);
}

/* ---- recent crash points (real settled rounds from this session) --------- */
.bs-crash-hist { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; min-height: 22px; }
.bs-crash-hist-l {
  flex: 0 0 auto; font-size: 9px; font-weight: 800; letter-spacing: .12em;
  text-transform: uppercase; color: var(--bs-faint);
}
.bs-crash-hist-row { display: flex; gap: 5px; flex: 1 1 auto; overflow-x: auto; scrollbar-width: none; }
.bs-crash-hist-row::-webkit-scrollbar { display: none; }
.bs-crash-hp {
  flex: 0 0 auto; font-style: normal; font-size: 10px; font-weight: 800;
  padding: 3px 7px; border-radius: 999px; border: 1px solid transparent;
  background: var(--bs-elev2); color: var(--bs-muted); font-variant-numeric: tabular-nums;
}
.bs-crash-hp0 { color: var(--bs-neg); }
.bs-crash-hp1 { color: var(--bs-pos); }
.bs-crash-hp2 { color: var(--bs-gold-ink); }
.bs-crash-hp3 { color: var(--bs-orange-br); border-color: var(--bs-orange); }
.bs-crash-hp-cash { box-shadow: inset 0 0 0 1px var(--bs-gold); }

/* ---- controls ------------------------------------------------------------ */
.bs-slot-ctrls .bs-crash-cash {
  position: relative; overflow: hidden; display: inline-flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 0; line-height: 1.12;
  min-width: 176px; padding: 7px 16px 8px; border-radius: 12px;
}
.bs-crash-cash-label { font-size: 10px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; opacity: .78; }
.bs-crash-cash-amt { font-size: 21px; font-weight: 900; letter-spacing: -.015em; font-variant-numeric: tabular-nums; }
.bs-crash-cash-profit { font-size: 10px; font-weight: 800; opacity: .72; font-variant-numeric: tabular-nums; }
.bs-crash-cash:not(:disabled) { animation: bs-crash-pulse 1.3s ease-in-out infinite; }
.bs-crash-cash.bs-crash-cash-h1:not(:disabled) { animation-duration: .95s; }
.bs-crash-cash.bs-crash-cash-h2:not(:disabled) { animation-duration: .68s; }
.bs-crash-cash.bs-crash-cash-h3:not(:disabled) { animation-duration: .46s; }
.bs-crash-cash::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.24) 50%, transparent 62%);
  transform: translateX(-100%); animation: bs-crash-sheen 2s linear infinite;
}
.bs-crash-cash:disabled::after { display: none; }
@keyframes bs-crash-sheen { to { transform: translateX(100%); } }
.bs-crash-launch {
  font-weight: 900; letter-spacing: .04em; text-transform: uppercase; font-size: 12px;
  min-width: 150px; padding: 12px 18px; border-radius: 12px;
}
.bs-crash-cash:disabled, .bs-crash-launch:disabled { opacity: .5; filter: saturate(.45); cursor: not-allowed; }

/* ---- phone --------------------------------------------------------------- */
@media (max-width: 420px) {
  .bs-crash-stage { height: 196px; }
  .bs-crash-stage .bs-crash-readout { top: 26px; font-size: 38px; }
  .bs-crash-rocket { width: 24px; height: 31px; }
  .bs-crash-halo { width: 42px; height: 42px; margin: -21px 0 0 -21px; }
  .bs-crash-plume { width: 13px; height: 18px; margin-left: -6.5px; }
  .bs-crash-boom { font-size: 30px; }
  .bs-crash-payout { font-size: 28px; }
  .bs-crash-bustv { font-size: 27px; }
  .bs-slot-ctrls .bs-crash-cash { min-width: 148px; padding: 6px 10px 7px; }
  .bs-crash-cash-amt { font-size: 19px; }
  .bs-crash-launch { min-width: 128px; padding: 11px 12px; }
  .bs-crash-hist-l { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-crash-stage.bs-crash-flying .bs-ascend-grid,
  .bs-crash-stage.bs-crash-flying .bs-crash-speed,
  .bs-crash-stage.bs-crash-flying .bs-crash-ship,
  .bs-crash-stage.bs-crash-flying .bs-crash-plume,
  .bs-crash-stage.bs-crash-igniting .bs-crash-plume,
  .bs-crash-stage.bs-crash-flying .bs-crash-pill i,
  .bs-crash-stage.bs-crash-h3 .bs-crash-readout.bs-ascend-live,
  .bs-crash-stage.bs-crash-busted,
  .bs-crash-flash, .bs-crash-shock, .bs-crash-shard,
  .bs-crash-cash:not(:disabled), .bs-crash-cash::after { animation: none !important; }
  .bs-crash-flash, .bs-crash-shock, .bs-crash-shard, .bs-crash-cash::after { display: none !important; }
  .bs-crash-plot, .bs-crash-speed, .bs-crash-halo, .bs-crash-pill,
  .bs-crash-stage .bs-crash-readout { transition: none !important; }
  .bs-crash-stage.bs-crash-flying .bs-crash-plume,
  .bs-crash-stage.bs-crash-igniting .bs-crash-plume { opacity: 1; }
}
/* ============================================================================
   COINFLIP — second pass. A lit table well, a coin with real thickness that
   tumbles end-over-end and lands with weight, and the compounding chain drawn
   as an escalating ladder the player climbs. Extends the first-pass .bs-cf-*
   rules above; every brand colour stays on a --bs-* token so all 10 operator
   skins keep working. The only fixed colours are the near-black well and the
   coin's own dark engraving — physical materials, not brand.
   ========================================================================== */

/* ---- the table well ------------------------------------------------------ */
.bs-coin-tray.bs-cf-tray {
  --bs-cf-apex: -42px;
  gap: 9px; min-height: 218px; padding: 16px 12px 20px; overflow: hidden;
  border-radius: 14px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05),
              inset 0 -30px 52px rgba(0,0,0,.62),
              0 12px 28px -18px rgba(0,0,0,.9);
}
/* warm pool of light under the coin (first-pass ::before, retinted per state) */
.bs-coin-tray.bs-cf-tray.is-win::before {
  background: radial-gradient(circle at 50% 46%, var(--bs-gold), transparent 62%);
  opacity: .38; animation: bs-cf-wellglow-x 1.15s ease-in-out 2;
}
.bs-coin-tray.bs-cf-tray.is-bust::before {
  background: radial-gradient(circle at 50% 46%, var(--bs-neg), transparent 60%);
  opacity: .26;
}
@keyframes bs-cf-wellglow-x { 0%,100% { opacity:.2 } 50% { opacity:.52 } }

/* felt weave + vignette, so the coin sits ON something instead of floating */
.bs-cf-vignette { position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.014) 0 2px, rgba(0,0,0,0) 2px 4px),
    repeating-linear-gradient(-45deg, rgba(0,0,0,.05) 0 2px, rgba(0,0,0,0) 2px 4px),
    radial-gradient(ellipse 78% 62% at 50% 40%, rgba(0,0,0,0) 42%, rgba(0,0,0,.58) 100%); }
.bs-cf-tray .bs-cf-tray-rail { position: absolute; left: 14%; right: 14%; bottom: 9px; z-index: 1; opacity: .35; }
.bs-coin-tray.bs-cf-tray.is-win .bs-cf-tray-rail { opacity: .8; }

/* ---- call / verdict pill ------------------------------------------------- */
.bs-cf-callout { position: relative; z-index: 3; display: inline-flex; align-items: center; gap: 7px;
  max-width: 100%; padding: 4px 12px 4px 4px; border-radius: 999px;
  border: 1px solid var(--bs-line); color: var(--bs-muted);
  background: linear-gradient(180deg, rgba(255,255,255,.075), rgba(255,255,255,.015));
  box-shadow: 0 4px 12px -6px rgba(0,0,0,.8), inset 0 1px 0 rgba(255,255,255,.08);
  font-size: 11px; font-weight: 900; letter-spacing: .1em; text-transform: uppercase; }
.bs-cf-callout b { font-weight: 900; }
.bs-cf-callout em { font-style: normal; font-size: 13px; line-height: 1; margin-left: 1px; }
.bs-cf-callout.is-idle { padding: 4px 12px; opacity: .55; }
.bs-cf-callout.is-live { color: var(--bs-text); border-color: var(--bs-orange);
  animation: bs-cf-pill-x 1.1s ease-in-out infinite; }
.bs-cf-callout.is-good { color: var(--bs-pos); border-color: var(--bs-pos); }
.bs-cf-callout.is-bad { color: var(--bs-neg); border-color: var(--bs-neg); }
@keyframes bs-cf-pill-x {
  0%,100% { box-shadow: 0 4px 12px -6px rgba(0,0,0,.8), inset 0 1px 0 rgba(255,255,255,.08); }
  50% { box-shadow: 0 0 16px -3px var(--bs-orange), inset 0 1px 0 rgba(255,255,255,.14); }
}

/* ---- the arena: shadow, halo, shockwave, coin ---------------------------- */
.bs-cf-arena { position: relative; z-index: 1; display: flex; align-items: flex-end;
  justify-content: center; width: 100%; height: 122px; }
.bs-cf-tray .bs-cf-lift { position: relative; z-index: 1; display: block;
  perspective: 900px; perspective-origin: 50% 44%; }
.bs-cf-arena .bs-cf-shadow { position: absolute; left: 50%; bottom: 1px; z-index: 0;
  width: 92px; height: 15px; margin-left: -46px; border-radius: 50%; filter: blur(4px);
  background: radial-gradient(ellipse at 50% 50%, rgba(0,0,0,.8), rgba(0,0,0,0) 72%); }
.bs-cf-halo { position: absolute; left: 50%; bottom: 0; z-index: 0; pointer-events: none;
  width: 120px; height: 120px; margin-left: -60px; margin-bottom: -10px; border-radius: 50%; }
.bs-cf-halo.is-good { box-shadow: 0 0 0 2px var(--bs-pos), 0 0 34px -6px var(--bs-pos); opacity: .5; }
.bs-cf-halo.is-win { box-shadow: 0 0 0 2px var(--bs-gold), 0 0 48px -4px var(--bs-gold); opacity: .85;
  animation: bs-cf-halo-x 1.3s ease-in-out infinite; }
.bs-cf-halo.is-loss { box-shadow: 0 0 0 2px var(--bs-neg), 0 0 30px -8px var(--bs-neg); opacity: .5; }
@keyframes bs-cf-halo-x { 0%,100% { transform: scale(1); opacity: .55 } 50% { transform: scale(1.07); opacity: .95 } }

.bs-cf-ring { position: absolute; left: 50%; bottom: 2px; z-index: 0; pointer-events: none;
  width: 22px; height: 9px; margin-left: -11px; border-radius: 50%;
  border: 2px solid var(--bs-orange); opacity: 0;
  animation: bs-cf-ring-x .68s .34s cubic-bezier(.2,.8,.3,1) forwards; }
.bs-cf-ring.is-good { border-color: var(--bs-gold); }
.bs-cf-ring.is-bad { border-color: var(--bs-neg); }
@keyframes bs-cf-ring-x { 0% { transform: scale(.35); opacity: .9 } 100% { transform: scale(7.5); opacity: 0 } }

/* ---- the coin ------------------------------------------------------------ */
.bs-cf-coin3d { display: block; position: relative; width: 102px; height: 102px;
  transform-style: preserve-3d; -webkit-transform-style: preserve-3d; will-change: transform; }
/* the toss: a real arc — quick off the thumb, hangs at the apex, drops fast */
.bs-coin-tray.bs-cf-tray.is-flipping .bs-cf-arena .bs-cf-lift { animation: bs-cf-toss-x 1.1s infinite; }
.bs-coin-tray.bs-cf-tray.is-flipping .bs-cf-arena .bs-cf-shadow { animation: bs-cf-shade-x 1.1s infinite; }
@keyframes bs-cf-toss-x {
  0%   { transform: translateY(4px) scale(1.06,.93); animation-timing-function: cubic-bezier(.1,.75,.35,1); }
  9%   { transform: translateY(-10px) scale(1); animation-timing-function: cubic-bezier(.12,.6,.4,1); }
  46%  { transform: translateY(var(--bs-cf-apex)) scale(1); animation-timing-function: cubic-bezier(.55,0,.85,.5); }
  91%  { transform: translateY(0) scale(1); animation-timing-function: cubic-bezier(.3,0,.5,1); }
  100% { transform: translateY(4px) scale(1.06,.93); }
}
@keyframes bs-cf-shade-x {
  0%,100% { transform: scale(1.12,1); opacity: .8 }
  46%     { transform: scale(.5,.66);  opacity: .2 }
}
.bs-cf-coin3d.bs-cf-spin { animation: bs-cf-tumble-x .62s linear infinite; }
@keyframes bs-cf-tumble-x { from { transform: rotateX(0deg) } to { transform: rotateX(1440deg) } }
/* the landing: one last tumble in, an overshoot, then a small settle bounce */
.bs-cf-coin3d.bs-cf-drop { animation: bs-cf-land-x .66s cubic-bezier(.18,.85,.32,1.2); }
@keyframes bs-cf-land-x {
  0%   { transform: translateY(var(--bs-cf-apex)) rotateX(-560deg) scale(.84); }
  54%  { transform: translateY(0) rotateX(0deg) scale(1.07); }
  71%  { transform: translateY(-10px) rotateX(0deg) scale(.98); }
  87%  { transform: translateY(0) rotateX(0deg) scale(1.03); }
  100% { transform: none; }
}
.bs-cf-tray.is-landed .bs-cf-arena .bs-cf-shadow { animation: bs-cf-shadeland-x .66s cubic-bezier(.18,.85,.32,1.2); }
@keyframes bs-cf-shadeland-x {
  0%  { transform: scale(.5,.66); opacity: .18 }
  54% { transform: scale(1.2,1.1); opacity: .9 }
  71% { transform: scale(.86,.9); opacity: .55 }
  100% { transform: scale(1); opacity: .8 }
}

/* milled thickness: a stack of discs between the two faces */
.bs-cf-edge { position: absolute; inset: 0; border-radius: 50%;
  background: linear-gradient(96deg, var(--bs-orange-dp) 0%, var(--bs-gold) 40%,
              var(--bs-orange-br) 58%, var(--bs-orange-dp) 100%);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.18); }
/* faces sit on the outside of that stack so the coin has genuine depth */
.bs-cf-coin3d .bs-cf-front { transform: translateZ(6px); }
.bs-cf-coin3d .bs-cf-back { transform: rotateX(180deg) translateZ(6px); }
.bs-cf-coin3d .bs-cf-side { box-shadow: inset 0 2px 7px rgba(255,255,255,.5),
  inset 0 -5px 11px rgba(0,0,0,.3), inset 0 0 0 5px rgba(26,18,7,.1), 0 0 0 1px rgba(0,0,0,.22); }
.bs-cf-sheen { position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: linear-gradient(126deg, rgba(255,255,255,.4) 0%, rgba(255,255,255,.12) 24%,
              rgba(255,255,255,0) 46%, rgba(0,0,0,.06) 70%, rgba(0,0,0,.2) 100%); }
.bs-cf-coin3d .bs-cf-side .bs-cf-art { position: relative;
  filter: drop-shadow(0 1px 0 rgba(255,255,255,.42)) drop-shadow(0 -1px 0 rgba(0,0,0,.28)); }
.bs-cf-coin3d .bs-cf-name { position: relative; }
.bs-cf-coin3d .bs-cf-q { position: relative; opacity: .35; }

/* ---- the climb ----------------------------------------------------------- */
.bs-cf-ladder { margin: 0 0 9px; padding: 8px 11px 9px; border: 1px solid var(--bs-line);
  border-radius: 12px; background: linear-gradient(180deg, var(--bs-elev), var(--bs-elev2));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.045); }
.bs-cf-ladder-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 7px; }
.bs-cf-ladder-lbl { font-size: 10px; font-weight: 900; letter-spacing: .13em;
  text-transform: uppercase; color: var(--bs-faint); }
.bs-cf-ladder-n { font-size: 11px; font-weight: 800; color: var(--bs-muted); font-variant-numeric: tabular-nums; }
.bs-cf-ladder-n b { font-size: 15px; color: var(--bs-text); }
.bs-cf-ladder.is-lost .bs-cf-ladder-n b { color: var(--bs-neg); }
.bs-cf-ladder.is-maxed .bs-cf-ladder-n b { color: var(--bs-gold-ink); }
.bs-cf-rungs { position: relative; display: flex; align-items: flex-end; gap: 2px; height: 34px; padding-bottom: 4px; }
.bs-cf-rungs::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--bs-soft), transparent); }
.bs-cf-rung { flex: 1 1 0; min-width: 0; box-sizing: border-box;
  height: var(--bs-cf-rh, 10px); transform-origin: bottom center;
  border-radius: 3px 3px 1px 1px; opacity: .42;
  background: linear-gradient(180deg, var(--bs-soft), var(--bs-elev2));
  transition: opacity .2s ease, background .2s ease, box-shadow .2s ease; }
.bs-cf-rung.is-climbed { opacity: 1; color: var(--bs-gold-ink);
  background: linear-gradient(180deg, var(--bs-gold), var(--bs-orange-dp));
  box-shadow: 0 0 9px -2px currentColor, inset 0 1px 0 rgba(255,255,255,.42); }
.bs-cf-rung.is-next { opacity: 1; background: transparent;
  border: 1px dashed var(--bs-orange); animation: bs-cf-next-x 1.5s ease-in-out infinite; }
.bs-cf-rung.is-live { opacity: 1; color: var(--bs-orange);
  background: linear-gradient(180deg, var(--bs-orange-br), var(--bs-orange-dp));
  box-shadow: 0 0 12px -2px currentColor; animation: bs-cf-live-x .62s ease-in-out infinite; }
.bs-cf-rung.is-lost { opacity: .9; color: var(--bs-neg);
  background: linear-gradient(180deg, var(--bs-neg), var(--bs-elev2)); filter: saturate(.75) brightness(.85); }
.bs-cf-rung.is-cap { position: relative; }
.bs-cf-rung.is-cap::before { content: ''; position: absolute; left: 50%; top: -8px;
  width: 5px; height: 5px; margin-left: -2.5px; border-radius: 50%;
  background: var(--bs-gold); box-shadow: 0 0 7px var(--bs-gold); opacity: .85; }
.bs-cf-rung.bs-cf-rung-pop { animation: bs-cf-rung-x .5s cubic-bezier(.2,.9,.3,1.5); }
@keyframes bs-cf-rung-x {
  0%   { transform: scaleY(.15) translateY(7px); opacity: .25 }
  60%  { transform: scaleY(1.38) translateY(0);  opacity: 1 }
  100% { transform: none }
}
@keyframes bs-cf-next-x { 0%,100% { opacity: .45 } 50% { opacity: 1 } }
@keyframes bs-cf-live-x { 0%,100% { box-shadow: 0 0 8px -3px currentColor } 50% { box-shadow: 0 0 18px 0 currentColor } }

/* ---- the number that dominates ------------------------------------------ */
.bs-cf-pot { position: relative; display: flex; flex-direction: column; align-items: center; gap: 1px;
  margin: 0 0 7px; padding: 9px 12px 11px; overflow: hidden;
  border: 1px solid var(--bs-line); border-radius: 12px;
  background: radial-gradient(130% 150% at 50% -25%, rgba(255,255,255,.07), transparent 62%), var(--bs-elev); }
.bs-cf-pot::before { content: ''; position: absolute; left: 16%; right: 16%; top: 0; height: 2px;
  border-radius: 0 0 2px 2px; opacity: .6;
  background: linear-gradient(90deg, transparent, var(--bs-orange), transparent); }
.bs-cf-pot-k { font-size: 10px; font-weight: 900; letter-spacing: .13em;
  text-transform: uppercase; color: var(--bs-faint); }
.bs-cf-pot .bs-cf-pot-v { font-size: 31px; line-height: 1.12; font-weight: 900;
  font-variant-numeric: tabular-nums; letter-spacing: -.015em; }
.bs-cf-pot-sub { font-size: 11px; font-weight: 800; color: var(--bs-muted);
  font-variant-numeric: tabular-nums; letter-spacing: .02em; }
.bs-cf-pot-sub b { color: var(--bs-orange); }
.bs-cf-pot.is-won { border-color: var(--bs-gold);
  box-shadow: 0 0 30px -12px var(--bs-gold), inset 0 0 30px -18px var(--bs-gold); }
.bs-cf-pot.is-won::before { opacity: 1; background: linear-gradient(90deg, transparent, var(--bs-gold), transparent); }
.bs-cf-pot.is-won .bs-cf-pot-sub b { color: var(--bs-gold-ink); }
.bs-cf-pot.is-bust { border-color: var(--bs-neg); }
.bs-cf-pot.is-bust::before { background: linear-gradient(90deg, transparent, var(--bs-neg), transparent); }
.bs-cf-pot.is-bust .bs-cf-pot-v { font-size: 25px; color: var(--bs-faint); }

/* ---- controls ------------------------------------------------------------ */
.bs-slot-ctrls.bs-cf-actions { gap: 9px; }
.bs-slot-ctrls .bs-cf-call { padding: 11px 12px; font-size: 14px; letter-spacing: .02em;
  transition: transform .12s ease, filter .12s ease, box-shadow .12s ease; }
.bs-slot-ctrls .bs-cf-call:hover:not([disabled]) { transform: translateY(-2px); }
.bs-slot-ctrls .bs-cf-call:active:not([disabled]) { transform: translateY(0) scale(.98); }
.bs-slot-ctrls .bs-cf-call[disabled],
.bs-slot-ctrls .bs-cf-cash[disabled] { opacity: .4; filter: grayscale(.55); cursor: not-allowed; transform: none; box-shadow: none; }
.bs-cf-chip.bs-cf-chip-lg { width: 27px; height: 27px; }
.bs-slot-ctrls .bs-cf-cash { display: inline-flex; flex-direction: column; align-items: center;
  gap: 1px; line-height: 1.14; padding: 8px 14px; }
.bs-cf-cash-lbl { font-size: 10px; font-weight: 900; letter-spacing: .12em; text-transform: uppercase; opacity: .78; }
.bs-cf-cash-amt { font-size: 17px; font-weight: 900; font-variant-numeric: tabular-nums; }
.bs-slot-ctrls .bs-cf-start { min-width: 130px; }

/* ---- phone --------------------------------------------------------------- */
@media (max-width: 420px) {
  .bs-coin-tray.bs-cf-tray { --bs-cf-apex: -34px; min-height: 200px; padding: 15px 10px 20px; gap: 8px; }
  .bs-cf-arena { height: 112px; }
  .bs-cf-coin3d { width: 88px; height: 88px; }
  .bs-cf-coin3d .bs-cf-side .bs-cf-art { width: 36px; height: 36px; }
  .bs-cf-coin3d .bs-cf-name { font-size: 9px; letter-spacing: .08em; }
  .bs-cf-halo { width: 104px; height: 104px; margin-left: -52px; margin-bottom: -9px; }
  .bs-cf-arena .bs-cf-shadow { width: 76px; margin-left: -38px; }
  .bs-cf-callout { font-size: 10px; letter-spacing: .07em; }
  .bs-cf-rungs { gap: 1px; height: 30px; }
  .bs-cf-pot .bs-cf-pot-v { font-size: 26px; }
  .bs-slot-ctrls.bs-cf-actions { gap: 7px; }
  .bs-slot-ctrls .bs-cf-call { padding: 10px 8px; font-size: 13px; gap: 6px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-coin-tray.bs-cf-tray.is-flipping .bs-cf-arena .bs-cf-lift,
  .bs-coin-tray.bs-cf-tray.is-flipping .bs-cf-arena .bs-cf-shadow,
  .bs-coin-tray.bs-cf-tray.is-win::before,
  .bs-cf-tray.is-landed .bs-cf-arena .bs-cf-shadow,
  .bs-cf-coin3d.bs-cf-spin, .bs-cf-coin3d.bs-cf-drop,
  .bs-cf-callout.is-live, .bs-cf-halo.is-win, .bs-cf-ring,
  .bs-cf-rung.is-next, .bs-cf-rung.is-live, .bs-cf-rung.bs-cf-rung-pop { animation: none !important; }
  .bs-cf-rung { transition: none !important; }
  .bs-cf-ring { opacity: 0 !important; }
}
/* ============================================================================
   CHINCHÓN — second pass. A real Spanish table: piles with physical thickness,
   a hand that fans in the grip and lifts under the finger, live meld grouping
   while the hand is still in play, and a deadwood gauge that turns gold the
   moment closing becomes legal. Every colour is a --bs-* token except the card
   stock itself (which lives in chinchonCardHtml), so all 10 skins hold.
   ========================================================================== */
.bs-chin-table { padding:12px 12px 11px; margin-bottom:10px; }
.bs-chin-table.bs-fx-shimmer::after, .bs-chin-intro.bs-fx-shimmer::after {
  pointer-events:none; border-radius:inherit; z-index:4; }

/* ---- Table top: stock · deadwood · discard -------------------------------- */
.bs-chin-top { position:relative; display:flex; align-items:center; justify-content:space-between; gap:10px; }
.bs-chin-pile { display:flex; flex-direction:column; align-items:center; gap:6px; flex:0 0 auto; }
.bs-chin-lbl { font-size:9px; font-weight:900; letter-spacing:.13em; text-transform:uppercase; color:var(--bs-muted); }
.bs-chin-n { font-size:10px; font-weight:900; letter-spacing:.05em; color:var(--bs-muted);
  font-variant-numeric:tabular-nums; min-height:13px; }

/* A pile is a stack, not a picture of a card: the layers behind it are the
   remaining stock made physical. */
.bs-chin-stack { position:relative; width:56px; height:80px; }
.bs-chin-stack .bs-pcard { position:absolute; inset:0; width:100%; height:100%; margin:0; animation:none; }
.bs-chin-layer { position:absolute; inset:0; border-radius:9px; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel));
  box-shadow:0 3px 8px rgba(0,0,0,.4);
  transform:translate(calc(var(--d,1) * 1.7px), calc(var(--d,1) * 1.7px)); }
.bs-chin-layer-d { transform:translate(calc(var(--d,1) * 1.3px), calc(var(--d,1) * 1.6px))
  rotate(calc(var(--d,1) * -3.2deg)); }
.bs-chin-facedown { box-shadow:0 8px 18px rgba(0,0,0,.5), inset 0 0 0 3px rgba(255,255,255,.18); }

/* A live pile is genuinely playable — the same doDraw() the buttons call. */
.bs-chin-pile-live { cursor:pointer; }
.bs-chin-pile-live .bs-chin-stack { animation:bs-chin-breathe 2.6s ease-in-out infinite; }
.bs-chin-pile-live .bs-chin-stack::after { content:''; position:absolute; inset:-5px; border-radius:13px;
  border:2px solid var(--bs-orange); opacity:0; transition:opacity .18s ease; pointer-events:none; }
.bs-chin-pile-live:hover .bs-chin-stack::after { opacity:.95; }
.bs-chin-pile-live:hover .bs-chin-lbl, .bs-chin-pile-live:hover .bs-chin-n { color:var(--bs-orange); }
@keyframes bs-chin-breathe { 0%,100% { transform:translateY(0) } 50% { transform:translateY(-3px) } }

/* ---- The deadwood gauge — the one number that matters --------------------- */
.bs-chin-dw { flex:1 1 auto; display:flex; flex-direction:column; align-items:center; gap:5px;
  min-width:100px; padding:9px 10px 10px; border-radius:12px; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(0,0,0,.26));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06), inset 0 -12px 20px rgba(0,0,0,.35);
  transition:border-color .3s ease, box-shadow .3s ease; }
.bs-chin-dwval { font-size:38px; line-height:1; font-weight:900; letter-spacing:-.03em; color:var(--bs-text);
  font-variant-numeric:tabular-nums; transition:color .3s ease; }
.bs-chin-dwtrack { display:block; width:100%; height:5px; border-radius:3px; background:var(--bs-elev2);
  overflow:hidden; box-shadow:inset 0 1px 2px rgba(0,0,0,.55); }
.bs-chin-dwtrack i { display:block; height:100%; border-radius:3px;
  background:linear-gradient(90deg, var(--bs-orange-dp), var(--bs-orange));
  transition:width .5s cubic-bezier(.2,.85,.3,1); }
.bs-chin-dwtag { font-size:9px; font-weight:900; letter-spacing:.1em; text-transform:uppercase; color:var(--bs-faint); }
.bs-chin-dw-ok { border-color:var(--bs-gold); box-shadow:inset 0 1px 0 rgba(255,255,255,.09), 0 0 26px -8px var(--bs-gold); }
.bs-chin-dw-ok .bs-chin-dwval { color:var(--bs-gold-ink); filter:drop-shadow(0 0 10px currentColor); }
.bs-chin-dw-ok .bs-chin-dwtrack i { background:linear-gradient(90deg, var(--bs-orange-br), var(--bs-gold)); }
.bs-chin-dw-ok .bs-chin-dwtag { color:var(--bs-gold-ink); animation:bs-chin-ready 1.9s ease-in-out infinite; }
@keyframes bs-chin-ready { 0%,100% { opacity:.5 } 50% { opacity:1 } }

/* ---- Dealer ticker -------------------------------------------------------- */
.bs-chin-hr { position:relative; margin:11px 2px 9px; }
.bs-chin-ticker { position:relative; display:flex; align-items:center; justify-content:center; gap:7px;
  min-height:15px; font-size:11px; line-height:1.35; color:var(--bs-muted); }
.bs-chin-ticker b { color:var(--bs-text); font-weight:900; }
.bs-chin-tick-dot { width:6px; height:6px; border-radius:50%; flex:none;
  background:var(--bs-orange); box-shadow:0 0 9px var(--bs-orange); }
.bs-chin-tick-idle { background:var(--bs-soft); box-shadow:none; }

/* ---- The hand, fanned in the grip ---------------------------------------- */
.bs-chin-handwrap { position:relative; margin-bottom:9px; padding:8px 8px 2px; border-radius:14px;
  border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.035), rgba(0,0,0,.28));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05); }
.bs-chin-fan { display:flex; align-items:flex-end; justify-content:center; padding:26px 6px 12px; min-height:114px; }
.bs-chin-slot { position:relative; display:inline-flex; flex:none; z-index:var(--z,1);
  transform-origin:50% 118%;
  transform:translateY(var(--dy,0px)) rotate(var(--rot,0deg));
  transition:transform .18s cubic-bezier(.2,.9,.3,1.35); }
.bs-chin-slot + .bs-chin-slot { margin-left:-17px; }
.bs-chin-fan .bs-pcard { animation:none;
  box-shadow:0 10px 20px rgba(0,0,0,.5), inset 0 0 0 1px rgba(0,0,0,.08); }
.bs-chin-fan:not(.bs-chin-fan-idle) .bs-chin-slot:hover {
  transform:translateY(calc(var(--dy,0px) - 15px)) rotate(var(--rot,0deg)) scale(1.05); z-index:30; }
.bs-chin-fan-idle .bs-pcard { cursor:default; }

/* Cards deal in one at a time — but only when the API has actually handed us
   new cards, never on a re-paint caused by merely selecting one. */
.bs-chin-fan.bs-chin-deal .bs-pcard {
  animation:bs-chin-dealin .44s cubic-bezier(.2,.9,.3,1.25) both;
  animation-delay:calc(var(--i,0) * 55ms); }
@keyframes bs-chin-dealin {
  from { transform:translate(-46px,-30px) rotate(-16deg); opacity:0 }
  to   { transform:none; opacity:1 } }

/* Melded cards carry their group's tint while the hand is still live. */
.bs-chin-slot.bs-chin-in-meld .bs-pcard { box-shadow:0 0 0 2px var(--g), 0 12px 22px rgba(0,0,0,.5); }
.bs-chin-tab { position:absolute; left:50%; bottom:-7px; width:22px; height:4px; border-radius:3px;
  transform:translateX(-50%); background:var(--g); box-shadow:0 0 10px var(--g); }
.bs-chin-slot.bs-chin-picked { z-index:40; }
.bs-chin-fan .bs-chin-picked .bs-pcard { outline:3px solid var(--bs-orange); outline-offset:2px;
  transform:translateY(-15px) scale(1.05); box-shadow:0 18px 32px rgba(0,0,0,.6); }

/* ---- Live meld read-out --------------------------------------------------- */
.bs-chin-rail { display:flex; flex-wrap:wrap; gap:7px; justify-content:center; margin-bottom:9px; }
.bs-chin-chip { display:inline-flex; align-items:center; gap:6px; padding:4px 11px; border-radius:999px;
  font-size:10px; font-weight:900; letter-spacing:.07em; text-transform:uppercase;
  font-variant-numeric:tabular-nums; color:var(--bs-muted);
  background:var(--bs-elev2); border:1px solid var(--bs-line); }
.bs-chin-chip i { width:7px; height:7px; border-radius:50%; flex:none; background:var(--g, var(--bs-soft)); }
.bs-chin-chip-dead { color:var(--bs-text); }
.bs-chin-chip-dead i { background:var(--bs-soft); }
.bs-chin-chip-ok { color:var(--bs-gold-ink); border-color:var(--bs-gold); }
.bs-chin-chip-ok i { background:var(--bs-gold); }
.bs-chin-chip-mute { color:var(--bs-faint); }
.bs-chin-chip-mute i { background:var(--bs-line); }

/* ---- Two-up action row ---------------------------------------------------- */
.bs-chin-ctrls { flex-wrap:wrap; gap:9px; margin-bottom:9px; }
.bs-chin-ctrls .bs-chin-act { flex:1 1 42%; min-width:0; padding:9px 10px; line-height:1.15;
  display:inline-flex; flex-direction:column; align-items:center; gap:2px; }
.bs-chin-act-t { font-size:13px; font-weight:900; }
.bs-chin-act-s { font-size:10px; font-weight:700; letter-spacing:.05em; opacity:.7;
  font-variant-numeric:tabular-nums; }
.bs-chin-ctrls .bs-btn:disabled { opacity:.34; filter:grayscale(.55); cursor:not-allowed; box-shadow:none; }
.bs-chin-close-hot { box-shadow:0 0 0 1px var(--bs-gold), 0 12px 26px -10px var(--bs-gold); }
.bs-chin-close-hot .bs-chin-act-s { opacity:1; }

/* ---- Lobby / dealing screen ----------------------------------------------- */
.bs-chin-intro { position:relative; padding:4px 12px 14px; margin-bottom:10px; }
.bs-chin-intro .bs-chin-fan { padding-top:20px; padding-bottom:6px; min-height:104px; }
.bs-chin-intro-title { position:relative; font-size:10px; font-weight:900; letter-spacing:.12em;
  text-transform:uppercase; color:var(--bs-muted); margin:2px 0 6px; }
.bs-chin-rules { position:relative; margin:0 auto; max-width:342px; }
.bs-chin-pay { padding:9px 12px 10px; margin-bottom:9px; text-align:left; }
.bs-chin-pay-h { font-size:9px; font-weight:900; letter-spacing:.14em; text-transform:uppercase;
  color:var(--bs-muted); margin-bottom:4px; }
.bs-chin-pay-row { display:flex; align-items:baseline; justify-content:space-between; gap:10px;
  padding:3px 0; font-size:11px; color:var(--bs-muted); border-top:1px solid var(--bs-line); }
.bs-chin-pay-h + .bs-chin-pay-row { border-top:0; }
.bs-chin-pay-row b { font-weight:900; color:var(--bs-text); font-variant-numeric:tabular-nums; }
.bs-chin-pay-top { color:var(--bs-text); }
.bs-chin-pay-top b { color:var(--bs-gold-ink); }

/* ---- Settlement: verdict, then both hands grouped into real melds --------- */
.bs-chin-verdict { position:relative; overflow:hidden; text-align:center; margin-bottom:10px;
  padding:13px 12px 12px; border-radius:14px; border:1px solid var(--bs-line);
  background:radial-gradient(130% 140% at 50% -20%, var(--bs-elev2), var(--bs-panel) 72%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05); }
.bs-chin-verdict-win { border-color:var(--bs-gold); }
.bs-chin-verdict-loss { border-color:var(--bs-line); }
.bs-chin-verdict-push { border-color:var(--bs-soft); }
.bs-chin-vlabel { font-size:9px; font-weight:900; letter-spacing:.16em; text-transform:uppercase; color:var(--bs-muted); }
.bs-chin-verdict .bs-fx-payout { display:block; margin:1px 0 9px; }
.bs-chin-banner { font-size:23px; font-weight:900; letter-spacing:.06em; margin-bottom:6px;
  background:linear-gradient(100deg, var(--bs-orange-br), var(--bs-gold) 45%, var(--bs-orange-br));
  background-size:220% 100%; -webkit-background-clip:text; background-clip:text;
  color:transparent; -webkit-text-fill-color:transparent; }
.bs-chin-verdict-jackpot { border-color:var(--bs-gold); box-shadow:inset 0 0 44px -14px var(--bs-gold); }
.bs-chin-verdict-jackpot .bs-chin-banner { animation:bs-chin-sheen 2.8s linear infinite; }
@keyframes bs-chin-sheen { from { background-position:0% 50% } to { background-position:220% 50% } }
.bs-chin-score { display:flex; align-items:center; justify-content:center; gap:16px; }
.bs-chin-score-side { display:inline-flex; flex-direction:column; align-items:center; gap:1px;
  font-size:9px; font-weight:900; letter-spacing:.12em; text-transform:uppercase; color:var(--bs-muted); }
.bs-chin-score-side b { font-size:22px; line-height:1; letter-spacing:0; color:var(--bs-text);
  font-variant-numeric:tabular-nums; }
.bs-chin-score-lead b { color:var(--bs-pos); }
.bs-chin-score-vs { font-size:9px; font-weight:900; letter-spacing:.14em; color:var(--bs-faint); }

.bs-chin-seat { position:relative; }
.bs-chin-seat-dw { letter-spacing:.06em; color:var(--bs-faint); }
.bs-chin-seat-dw-ok { color:var(--bs-gold-ink); }
.bs-chin-groups { display:flex; flex-wrap:wrap; gap:9px; justify-content:center; }
.bs-chin-group { position:relative; display:flex; flex-direction:column; align-items:center; gap:5px;
  padding:7px 9px 8px; border-radius:11px; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.045), rgba(0,0,0,.24));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05); }
.bs-chin-gtag { font-size:8px; font-weight:900; letter-spacing:.12em; text-transform:uppercase;
  color:var(--g, var(--bs-muted)); }
.bs-chin-gcards { display:flex; }
.bs-chin-gcards .bs-pcard { animation:none; }
.bs-chin-gcards .bs-pcard + .bs-pcard { margin-left:-15px; }
.bs-chin-group .bs-sp-melded { outline:2px solid var(--g); outline-offset:1px; }
.bs-chin-group-dead { border-style:dashed; }
.bs-chin-group-dead .bs-chin-gtag { color:var(--bs-faint); }
.bs-chin-group-hero { border-color:var(--bs-gold); box-shadow:0 0 30px -9px var(--bs-gold),
  inset 0 1px 0 rgba(255,255,255,.08); }

@media (max-width:420px) {
  .bs-chin-top { gap:6px; }
  .bs-chin-stack { width:46px; height:66px; }
  .bs-chin-dw { min-width:80px; padding:7px 7px 8px; }
  .bs-chin-dwval { font-size:30px; }
  .bs-chin-fan { padding:22px 2px 12px; min-height:98px; }
  .bs-chin-slot + .bs-chin-slot { margin-left:-15px; }
  .bs-chin-ctrls .bs-chin-act { flex:1 1 100%; }
  .bs-chin-gcards .bs-pcard + .bs-pcard { margin-left:-13px; }
  .bs-chin-groups { gap:7px; }
  .bs-chin-banner { font-size:19px; }
  .bs-chin-score { gap:12px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-chin-pile-live .bs-chin-stack, .bs-chin-dw-ok .bs-chin-dwtag,
  .bs-chin-verdict-jackpot .bs-chin-banner, .bs-chin-fan.bs-chin-deal .bs-pcard { animation:none !important; }
  .bs-chin-slot, .bs-chin-dw, .bs-chin-dwval, .bs-chin-dwtrack i,
  .bs-chin-pile-live .bs-chin-stack::after { transition:none !important; }
}

/* ============================================================================
   CHINCHÓN — RAKED PLAYER-VS-PLAYER TABLES
   Two humans, one pot, a house rake taken out of it. Everything here exists to
   make three things impossible to miss: whose turn it is, that the opponent is
   a CARD COUNT and nothing more, and where every penny of the pot goes. The
   felt, the fan, the piles and the meld tinting are the practice game's and are
   not restyled — this is the furniture around them.
   Every colour is a --bs-* token, so all 10 operator skins hold unmodified.
   ========================================================================== */

/* ---- Mode switch: Practice vs Play for a pot ------------------------------
   Two toggle buttons, not a tablist. Practice reads as the resting state and
   the raked table as the deliberate one, which is the whole point of putting
   the switch here rather than adding a second tile to the lobby. */
.bs-chin-modes { display:flex; gap:7px; margin:0 0 11px; }
.bs-chin-mode { flex:1 1 0; min-width:0; display:flex; flex-direction:column; align-items:flex-start;
  gap:2px; padding:8px 11px; border-radius:12px; cursor:pointer; text-align:left;
  border:1px solid var(--bs-line); background:var(--bs-elev2); color:var(--bs-muted);
  font:inherit; transition:border-color .16s ease, color .16s ease, background .16s ease; }
.bs-chin-mode-t { font-size:12.5px; font-weight:900; letter-spacing:.01em; }
.bs-chin-mode-s { font-size:9.5px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  opacity:.72; line-height:1.25; }
.bs-chin-mode:hover:not(:disabled) { border-color:var(--bs-soft); color:var(--bs-text); }
.bs-chin-mode-on { border-color:var(--bs-gold); color:var(--bs-text);
  background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(0,0,0,.2));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07), 0 0 22px -12px var(--bs-gold); }
.bs-chin-mode-on .bs-chin-mode-s { color:var(--bs-gold-ink); opacity:1; }
.bs-chin-mode:disabled { opacity:.4; cursor:not-allowed; }

/* ---- The purse: stake in · pot · rake out · winner receives ---------------
   Printed on the lobby row AND on the table, because a player should never have
   to work the rake out for themselves, and it must never arrive as a surprise
   deduction at settlement. */
.bs-chin-pvp-purse { display:grid; gap:6px; margin-bottom:8px;
  grid-template-columns:repeat(auto-fit, minmax(78px, 1fr)); }
.bs-chin-pvp-fig { display:flex; flex-direction:column; gap:2px; min-width:0;
  padding:7px 9px 8px; border-radius:11px; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.04), rgba(0,0,0,.2)); }
.bs-chin-pvp-figl { font-size:8.5px; font-weight:900; letter-spacing:.1em; text-transform:uppercase;
  color:var(--bs-muted); line-height:1.3; }
.bs-chin-pvp-fig b { font-size:14px; font-weight:900; color:var(--bs-text);
  font-variant-numeric:tabular-nums; letter-spacing:-.01em; }
.bs-chin-pvp-fig-rake b { color:var(--bs-muted); }
.bs-chin-pvp-fig-win { border-color:var(--bs-gold); }
.bs-chin-pvp-fig-win b { color:var(--bs-gold-ink); }
.bs-chin-pvp-fig-win .bs-chin-pvp-figl { color:var(--bs-gold-ink); }
.bs-chin-pvp-rakenote { margin:0 0 10px; text-align:left; }

/* ---- Lobby --------------------------------------------------------------- */
.bs-chin-pvp-h { font-size:9px; font-weight:900; letter-spacing:.14em; text-transform:uppercase;
  color:var(--bs-muted); }
.bs-chin-pvp-open { padding:10px 12px 4px; margin-bottom:11px; text-align:left; }
.bs-chin-pvp-open .bs-hint { margin:5px 0 8px; }
.bs-chin-pvp-lobby { text-align:left; }
.bs-chin-pvp-lobbyhead { display:flex; align-items:center; justify-content:space-between;
  gap:10px; margin-bottom:6px; }
.bs-chin-pvp-filter { display:flex; align-items:center; gap:7px; margin-bottom:9px;
  font-size:11px; color:var(--bs-muted); cursor:pointer; }
.bs-chin-pvp-filter input { width:16px; height:16px; flex:none; accent-color:var(--bs-orange); margin:0; }
.bs-chin-pvp-empty { margin:10px 0 4px; text-align:center; }
.bs-chin-pvp-row { padding:9px 10px 10px; margin-bottom:8px; border-radius:13px;
  border:1px solid var(--bs-line); background:var(--bs-elev2);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04); }
.bs-chin-pvp-rowtop { display:flex; align-items:baseline; justify-content:space-between;
  gap:8px; margin-bottom:7px; flex-wrap:wrap; }
.bs-chin-pvp-tid { font-size:9px; font-weight:900; letter-spacing:.12em; text-transform:uppercase;
  color:var(--bs-faint); }
.bs-chin-pvp-clock { font-size:10px; font-weight:700; letter-spacing:.05em; color:var(--bs-muted); }
.bs-chin-pvp-clock b { color:var(--bs-text); font-variant-numeric:tabular-nums; }
.bs-chin-pvp-rowfoot { display:flex; align-items:center; justify-content:space-between;
  gap:9px; flex-wrap:wrap; }
.bs-chin-pvp-rowfoot .bs-hint { margin:0; }
.bs-chin-pvp-join { flex:0 0 auto; }
.bs-chin-pvp-hash { margin-top:7px; font-size:9.5px; color:var(--bs-faint); overflow-wrap:anywhere; }
.bs-chin-pvp-hash code { font-size:9.5px; color:var(--bs-muted); }
.bs-chin-pvp-resume { display:flex; align-items:center; justify-content:space-between; gap:10px;
  flex-wrap:wrap; padding:8px 11px; margin-bottom:10px; border-radius:12px; text-align:left;
  font-size:11.5px; color:var(--bs-text);
  border:1px solid var(--bs-gold); background:rgba(0,0,0,.18);
  box-shadow:0 0 24px -14px var(--bs-gold); }

/* ---- Whose turn ---------------------------------------------------------- */
.bs-chin-pvp-turn { display:flex; align-items:center; gap:8px; flex-wrap:wrap; text-align:left;
  padding:8px 11px; margin-bottom:9px; border-radius:12px; font-size:11.5px; line-height:1.35;
  color:var(--bs-muted); border:1px solid var(--bs-line); background:var(--bs-elev2); }
.bs-chin-pvp-turnt { flex:1 1 auto; min-width:0; }
.bs-chin-pvp-turn b { color:var(--bs-text); font-weight:900; }
.bs-chin-pvp-turn .bs-chin-pvp-clock { flex:0 0 auto; }
.bs-chin-pvp-turn-you { border-color:var(--bs-gold); color:var(--bs-text);
  box-shadow:inset 0 0 30px -18px var(--bs-gold); }
.bs-chin-pvp-turn-you b { color:var(--bs-gold-ink); }

/* ---- The opponent: a COUNT of face-down backs, never anything more -------- */
.bs-chin-pvp-opp { position:relative; }
.bs-chin-pvp-hidden { display:flex; justify-content:center; align-items:flex-end;
  min-height:34px; padding:2px 0 1px; }
.bs-chin-pvp-back { width:24px; height:34px; flex:none; border-radius:5px;
  border:1px solid var(--bs-line);
  background:repeating-linear-gradient(135deg, var(--bs-elev2) 0 4px, var(--bs-panel) 4px 8px);
  box-shadow:0 4px 10px rgba(0,0,0,.42), inset 0 0 0 2px rgba(255,255,255,.1); }
.bs-chin-pvp-back + .bs-chin-pvp-back { margin-left:-9px; }
.bs-chin-pvp-secret { margin:5px 0 0; font-size:10px; text-align:center; }

/* ---- Settlement ledger --------------------------------------------------- */
.bs-chin-pvp-ledger { text-align:left; margin-bottom:9px; padding:8px 12px 9px;
  border-radius:13px; border:1px solid var(--bs-line); background:var(--bs-elev2); }
.bs-chin-pvp-led { display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  padding:5px 0; font-size:11.5px; color:var(--bs-muted); border-top:1px solid var(--bs-line); }
.bs-chin-pvp-led:first-child { border-top:0; }
.bs-chin-pvp-led b { font-weight:900; color:var(--bs-text); font-variant-numeric:tabular-nums; }
.bs-chin-pvp-led-zero b { color:var(--bs-pos); }
.bs-chin-pvp-led-hero { color:var(--bs-text); }
.bs-chin-pvp-led-hero b { font-size:16px; color:var(--bs-gold-ink); }
.bs-chin-pvp-norake { margin:0 0 10px; color:var(--bs-pos); text-align:center; }

@media (max-width:420px) {
  .bs-chin-modes { gap:6px; }
  .bs-chin-mode { padding:8px 9px; }
  .bs-chin-mode-t { font-size:12px; }
  .bs-chin-mode-s { font-size:9px; letter-spacing:.04em; }
  /* Two up rather than four: at 375px a four-across purse squeezes the money
     figures into two lines each and the whole strip stops being readable. */
  .bs-chin-pvp-purse { grid-template-columns:repeat(2, minmax(0, 1fr)); }
  .bs-chin-pvp-rowfoot { align-items:stretch; }
  .bs-chin-pvp-join { flex:1 1 100%; }
  .bs-chin-pvp-resume .bs-btn { flex:1 1 100%; }
  .bs-chin-pvp-back { width:21px; height:30px; }
  .bs-chin-pvp-back + .bs-chin-pvp-back { margin-left:-8px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-chin-mode { transition:none !important; }
}
/* ============================================================================
   SIC BO — second pass. An Asian-casino table: three dice under a glass shaker
   dome sitting in a lit well, a tap-to-bet layout with the odds printed on
   every area, chips that land on selections, and winning areas that light up
   on resolution. Every colour is a --bs-* token (the only fixed colours live
   inside diceFaceSvg(), which is real ivory-and-pip dice stock, not brand).
   ========================================================================== */

/* The full table is taller than a phone viewport, so THIS modal scrolls. Scoped
   to .bs-sicbo-modal (a class openSicBo adds to its own card) so the shared
   .bs-game-modal shell every other game uses is left exactly as it was. */
.bs-game-modal.bs-sicbo-modal { max-height:92vh; overflow-y:auto; overflow-x:hidden;
  overscroll-behavior:contain; scrollbar-width:thin; scrollbar-color:var(--bs-soft) transparent; }
.bs-game-modal.bs-sicbo-modal::-webkit-scrollbar { width:8px; }
.bs-game-modal.bs-sicbo-modal::-webkit-scrollbar-thumb { background:var(--bs-soft); border-radius:999px; }
.bs-game-modal.bs-sicbo-modal::-webkit-scrollbar-track { background:transparent; }

/* ---- The shaker well ------------------------------------------------------ */
.bs-sicbo-stage { position:relative; overflow:hidden; padding:12px 10px 13px; margin-bottom:12px;
  border:1px solid var(--bs-line); border-radius:14px;
  background:
    radial-gradient(ellipse at 50% -16%, rgba(255,255,255,.075), transparent 58%),
    radial-gradient(ellipse at 50% 118%, rgba(0,0,0,.6), transparent 64%),
    linear-gradient(180deg, var(--bs-elev), var(--bs-well) 88%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06), inset 0 -24px 44px rgba(0,0,0,.55), 0 10px 26px rgba(0,0,0,.34); }
.bs-sicbo-stage::before { content:''; position:absolute; inset:6px; border-radius:11px; pointer-events:none;
  border:1px solid var(--bs-line); opacity:.5; }
.bs-sicbo-stage.bs-sicbo-stage-won { border-color:var(--bs-gold);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06), inset 0 -24px 44px rgba(0,0,0,.55),
    0 0 34px -10px var(--bs-gold), 0 10px 26px rgba(0,0,0,.34); }

.bs-sicbo-arena { position:relative; display:flex; align-items:center; justify-content:center; padding:2px 0 11px; }
.bs-sicbo-dome { position:relative; display:inline-flex; align-items:center; justify-content:center;
  padding:13px 15px 15px; border-radius:999px 999px 24px 24px; border:1px solid var(--bs-soft);
  background:radial-gradient(125% 135% at 50% 6%, rgba(255,255,255,.14), rgba(255,255,255,.032) 46%, rgba(0,0,0,.34) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.2), inset 0 -16px 30px rgba(0,0,0,.5), 0 14px 28px rgba(0,0,0,.45); }
.bs-sicbo-dome-glass { position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  background:linear-gradient(158deg, rgba(255,255,255,.22) 0 15%, rgba(255,255,255,.05) 33%, transparent 54%); }
.bs-sicbo-base { position:absolute; left:50%; bottom:2px; width:64%; height:14px; transform:translateX(-50%);
  border-radius:50%; pointer-events:none;
  background:radial-gradient(ellipse at 50% 40%, rgba(0,0,0,.65), transparent 72%); }
.bs-sicbo-stage .bs-dice-tray { background:transparent; border:0; margin:0; padding:0; gap:10px; }
.bs-sicbo-stage.bs-sicbo-shaking .bs-sicbo-dome { animation:bs-sicbo-shake .42s ease-in-out infinite; }
@keyframes bs-sicbo-shake {
  0%,100% { transform:translate(0,0) rotate(0deg); }
  25% { transform:translate(-3px,1px) rotate(-1.1deg); }
  50% { transform:translate(0,-2px) rotate(0deg); }
  75% { transform:translate(3px,1px) rotate(1.1deg); }
}
.bs-sicbo-rail { display:block; width:70%; margin:0 auto 10px; }

/* ---- Total plaque --------------------------------------------------------- */
.bs-sicbo-readout { position:relative; display:flex; flex-direction:column; align-items:center; gap:4px; }
.bs-sicbo-readout-label { font-size:9px; font-weight:900; letter-spacing:.24em; text-transform:uppercase; color:var(--bs-faint); }
.bs-sicbo-total { display:block; font-size:42px; font-weight:900; line-height:.94; letter-spacing:-.03em;
  color:var(--bs-text); font-variant-numeric:tabular-nums; text-shadow:0 6px 20px rgba(0,0,0,.65); }
.bs-sicbo-total.bs-sicbo-total-idle { font-size:34px; color:var(--bs-faint); text-shadow:none; }
.bs-sicbo-total.bs-sicbo-total-win { color:var(--bs-gold-ink); text-shadow:0 0 30px rgba(0,0,0,.4);
  animation:bs-sicbo-plaque .52s cubic-bezier(.2,.9,.3,1.45); }
@keyframes bs-sicbo-plaque {
  0% { transform:scale(.55); opacity:0; }
  60% { transform:scale(1.16); opacity:1; }
  100% { transform:none; opacity:1; }
}
.bs-sicbo-tags { display:flex; gap:6px; justify-content:center; align-items:center; flex-wrap:wrap; margin-top:2px; }
.bs-sicbo-tag.bs-sicbo-tag-hit { background:var(--bs-elev2); border-color:var(--bs-soft); color:var(--bs-text); }
.bs-sicbo-tag.bs-sicbo-tag-live { color:var(--bs-orange); border-color:var(--bs-orange); background:transparent;
  animation:bs-sicbo-tagpulse 1.15s ease-in-out infinite; }
@keyframes bs-sicbo-tagpulse { 0%,100% { opacity:.55; } 50% { opacity:1; } }

/* ---- Payout hero ---------------------------------------------------------- */
.bs-sicbo-payout { display:flex; flex-direction:column; align-items:center; gap:2px;
  padding:12px 14px 13px; margin:0 0 12px; border-radius:14px; text-align:center; }
.bs-sicbo-payout-label { font-size:9px; font-weight:900; letter-spacing:.24em; text-transform:uppercase; color:var(--bs-faint); }
.bs-sicbo-payout-fig { line-height:1.02; }
.bs-sicbo-payout-sub { font-size:11px; font-weight:800; color:var(--bs-muted); font-variant-numeric:tabular-nums; }
.bs-sicbo-payout.bs-sicbo-payout-max { border-color:var(--bs-gold); box-shadow:0 0 34px -10px var(--bs-gold); }

/* ---- Bet slip ------------------------------------------------------------- */
.bs-sicbo-slip { box-shadow:0 6px 18px rgba(0,0,0,.28); }
.bs-sicbo-bet-icon { display:inline-flex; align-items:center; justify-content:center; flex:none; width:36px; }
.bs-sicbo-bet-icon.bs-sicbo-bet-sum { width:23px; height:23px; border-radius:50%; margin-right:13px;
  background:var(--bs-elev2); border:1px solid var(--bs-soft); color:var(--bs-text);
  font-size:11px; font-weight:900; font-variant-numeric:tabular-nums; }
.bs-sicbo-bet-icon.bs-sicbo-bet-dot::before { content:''; width:13px; height:13px; border-radius:50%;
  background:radial-gradient(circle at 34% 28%, var(--bs-orange-br), var(--bs-orange-dp));
  box-shadow:0 0 0 2px var(--bs-elev2), 0 1px 3px rgba(0,0,0,.5); }
.bs-sicbo-bet-label { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bs-sicbo-bet-odds { flex:none; font-size:10px; font-weight:900; letter-spacing:.02em; color:var(--bs-gold-ink);
  font-variant-numeric:tabular-nums; padding:2px 7px; border-radius:999px;
  background:var(--bs-elev); border:1px solid var(--bs-line); }
.bs-sicbo-slip-foot { display:flex; align-items:center; justify-content:space-between; gap:10px; padding:8px 10px;
  border-top:1px solid var(--bs-line); background:var(--bs-elev);
  font-size:11px; font-weight:800; color:var(--bs-muted); font-variant-numeric:tabular-nums; }
.bs-sicbo-slip-foot b { color:var(--bs-gold-ink); font-size:13px; }
.bs-sicbo-empty { text-align:center; margin:0 0 12px; padding:15px 10px; font-size:12px;
  border:1px dashed var(--bs-line); border-radius:12px; background:rgba(0,0,0,.16); }

/* ---- The betting table ---------------------------------------------------- */
.bs-sicbo-table { position:relative; }
.bs-sicbo-table.bs-felt { padding:12px 10px 11px; margin-bottom:12px; }
.bs-sicbo-table.bs-sicbo-table-busy { opacity:.5; filter:saturate(.5); transition:opacity .2s ease; }
.bs-sicbo-row { display:grid; gap:6px; margin-bottom:8px; }
.bs-sicbo-row-3 { grid-template-columns:repeat(3, minmax(0,1fr)); }
.bs-sicbo-row-2 { grid-template-columns:repeat(2, minmax(0,1fr)); }
.bs-sicbo-row-6 { grid-template-columns:repeat(6, minmax(0,1fr)); }
.bs-sicbo-row-7 { grid-template-columns:repeat(7, minmax(0,1fr)); }
.bs-sicbo-sect { position:relative; display:flex; align-items:center; justify-content:space-between; gap:8px;
  margin:13px 2px 6px; font-size:9px; font-weight:900; letter-spacing:.16em; text-transform:uppercase;
  color:var(--bs-faint); }
.bs-sicbo-sect-odds { letter-spacing:.05em; color:var(--bs-gold-ink); font-variant-numeric:tabular-nums; }

.bs-sicbo-cell { position:relative; display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:3px; min-width:0; padding:9px 4px; border-radius:10px; cursor:pointer; text-align:center;
  font-family:inherit; color:var(--bs-text); -webkit-appearance:none; appearance:none;
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-elev));
  border:1px solid var(--bs-line);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 2px 5px rgba(0,0,0,.3);
  transition:transform .12s ease, border-color .16s ease, box-shadow .16s ease, opacity .2s ease; }
.bs-sicbo-cell:hover:not(:disabled) { border-color:var(--bs-orange); transform:translateY(-1px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 7px 15px rgba(0,0,0,.42); }
.bs-sicbo-cell:active:not(:disabled) { transform:translateY(1px); box-shadow:inset 0 2px 6px rgba(0,0,0,.4); }
.bs-sicbo-cell:disabled { cursor:default; }
.bs-sicbo-cell-main { display:flex; flex-direction:column; align-items:center; gap:2px;
  font-size:12px; font-weight:900; letter-spacing:.04em; line-height:1.16; text-transform:uppercase; }
.bs-sicbo-cell-main em { font-style:normal; text-transform:none; font-size:9px; font-weight:800;
  letter-spacing:.06em; color:var(--bs-muted); font-variant-numeric:tabular-nums; }
.bs-sicbo-cell-main b { font-size:18px; font-weight:900; letter-spacing:-.02em; font-variant-numeric:tabular-nums; }
.bs-sicbo-cell-odds { font-size:9px; font-weight:900; letter-spacing:.05em; color:var(--bs-gold-ink); opacity:.82;
  font-variant-numeric:tabular-nums; }
.bs-sicbo-cell-head { padding:13px 6px; }
.bs-sicbo-cell-gold { border-color:var(--bs-soft);
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel)); }
.bs-sicbo-cell-gold .bs-sicbo-cell-main { color:var(--bs-gold-ink); }
.bs-sicbo-cell-num { padding:7px 2px; }
.bs-sicbo-cell-die { padding:8px 2px 7px; }

/* Chip on an area, then the resolution states (declared after :disabled so the
   lit / dimmed treatment still reads once the table locks). */
.bs-sicbo-cell.bs-sicbo-cell-on { z-index:1; border-color:var(--bs-orange);
  box-shadow:inset 0 0 0 1px var(--bs-orange-dp), 0 5px 14px rgba(0,0,0,.42); }
.bs-sicbo-cell.bs-sicbo-cell-cold { opacity:.36; filter:saturate(.45); }
.bs-sicbo-cell.bs-sicbo-cell-cold.bs-sicbo-cell-on { opacity:.55; }
.bs-sicbo-cell.bs-sicbo-cell-won { opacity:1; filter:none; border-color:var(--bs-pos);
  box-shadow:inset 0 0 0 1px var(--bs-pos), 0 0 22px -6px var(--bs-pos), 0 3px 10px rgba(0,0,0,.4);
  animation:bs-sicbo-light .58s cubic-bezier(.2,.9,.3,1.4); }
.bs-sicbo-cell.bs-sicbo-cell-won .bs-sicbo-cell-odds { color:var(--bs-pos); opacity:1; }
.bs-sicbo-cell.bs-sicbo-cell-won.bs-sicbo-cell-on { border-color:var(--bs-gold);
  box-shadow:inset 0 0 0 1px var(--bs-gold), 0 0 26px -6px var(--bs-gold), 0 3px 10px rgba(0,0,0,.4); }
@keyframes bs-sicbo-light {
  0% { transform:scale(1); }
  45% { transform:scale(1.07); }
  100% { transform:scale(1); }
}

/* ---- Chips ---------------------------------------------------------------- */
/* Chips are allowed to spill a couple of px into the grid gap rather than clip a
   money figure; .bs-sicbo-cell-on lifts its cell so the spill stays on top. */
.bs-sicbo-chip { position:relative; display:inline-flex; align-items:center; justify-content:center; flex:none;
  white-space:nowrap; font-weight:900; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; color:var(--bs-on-orange);
  background:radial-gradient(circle at 34% 26%, var(--bs-orange-br), var(--bs-orange) 54%, var(--bs-orange-dp) 100%);
  box-shadow:0 2px 6px rgba(0,0,0,.5), inset 0 2px 3px rgba(255,255,255,.34), inset 0 -3px 5px rgba(0,0,0,.26); }
.bs-sicbo-chip-on { height:20px; padding:0 8px; margin-top:3px; border-radius:999px; font-size:10px;
  box-shadow:0 0 0 2px var(--bs-orange-dp), 0 3px 7px rgba(0,0,0,.5),
    inset 0 2px 3px rgba(255,255,255,.34), inset 0 -3px 5px rgba(0,0,0,.26); }
.bs-sicbo-chip-drop { animation:bs-sicbo-chipdrop .44s cubic-bezier(.2,.9,.3,1.5); }
@keyframes bs-sicbo-chipdrop {
  0% { transform:translateY(-26px) scale(.45) rotate(-16deg); opacity:0; }
  62% { transform:translateY(2px) scale(1.1) rotate(3deg); opacity:1; }
  100% { transform:none; opacity:1; }
}
.bs-sicbo-chiprow { margin-bottom:6px; }
.bs-sicbo-chiprow .bs-slot-ctrls { flex-direction:row-reverse; align-items:center; gap:14px; }
.bs-sicbo-chip-hand { width:48px; height:48px; border-radius:50%; font-size:10px;
  box-shadow:0 0 0 3px var(--bs-orange-dp), 0 6px 14px rgba(0,0,0,.5),
    inset 0 2px 4px rgba(255,255,255,.34), inset 0 -4px 7px rgba(0,0,0,.28); }
.bs-sicbo-chip-hand::before { content:''; position:absolute; inset:5px; border-radius:50%;
  border:2px dashed rgba(0,0,0,.24); pointer-events:none; }

/* ---- Mini dice used on the single / double / triple areas ------------------ */
.bs-sicbo-minis { display:inline-flex; align-items:center; justify-content:center; }
.bs-sicbo-mini { display:inline-flex; filter:drop-shadow(0 2px 3px rgba(0,0,0,.55)); }
.bs-sicbo-minis-2 .bs-sicbo-mini + .bs-sicbo-mini { margin-left:-5px; }
.bs-sicbo-minis-3 .bs-sicbo-mini + .bs-sicbo-mini { margin-left:-4px; }
.bs-sicbo-minis-2 .bs-sicbo-mini:nth-child(1) { transform:rotate(-8deg); }
.bs-sicbo-minis-2 .bs-sicbo-mini:nth-child(2) { transform:rotate(8deg); }
.bs-sicbo-minis-3 .bs-sicbo-mini:nth-child(1) { transform:rotate(-11deg); }
.bs-sicbo-minis-3 .bs-sicbo-mini:nth-child(3) { transform:rotate(11deg); }

/* ---- Roll button ---------------------------------------------------------- */
.bs-sicbo-rollrow { margin-top:2px; }
.bs-sicbo-rollrow .bs-sicbo-roll { min-width:210px; padding:13px 22px; font-size:15px; letter-spacing:.02em;
  font-variant-numeric:tabular-nums;
  box-shadow:0 9px 22px rgba(0,0,0,.42), inset 0 1px 0 rgba(255,255,255,.3); }
.bs-sicbo-rollrow .bs-sicbo-roll:disabled { opacity:.4; cursor:not-allowed; filter:grayscale(.6);
  box-shadow:none; transform:none; }

@media (prefers-reduced-motion: reduce) {
  .bs-sicbo-stage.bs-sicbo-shaking .bs-sicbo-dome,
  .bs-sicbo-tag.bs-sicbo-tag-live,
  .bs-sicbo-total.bs-sicbo-total-win,
  .bs-sicbo-cell.bs-sicbo-cell-won,
  .bs-sicbo-chip-drop { animation:none !important; }
}

@media (max-width:420px) {
  .bs-sicbo-stage { padding:10px 6px 11px; }
  .bs-sicbo-dome { padding:10px 8px 12px; }
  .bs-sicbo-stage .bs-dice-tray { gap:6px; }
  .bs-sicbo-total { font-size:38px; }
  .bs-sicbo-total.bs-sicbo-total-idle { font-size:30px; }
  .bs-sicbo-table.bs-felt { padding:10px 7px 9px; }
  .bs-sicbo-row { gap:4px; }
  .bs-sicbo-cell { padding:7px 2px; border-radius:8px; gap:2px; }
  .bs-sicbo-cell-head { padding:11px 3px; }
  .bs-sicbo-cell-main { font-size:11px; letter-spacing:.02em; }
  .bs-sicbo-cell-main em { font-size:8px; letter-spacing:.02em; }
  .bs-sicbo-cell-main b { font-size:15px; }
  .bs-sicbo-cell-odds { font-size:8px; letter-spacing:.01em; }
  .bs-sicbo-chip-on { height:17px; padding:0 5px; font-size:8px; margin-top:2px; box-shadow:0 0 0 1.5px var(--bs-orange-dp), 0 2px 5px rgba(0,0,0,.5), inset 0 1px 2px rgba(255,255,255,.34); }
  .bs-sicbo-chip-hand { width:42px; height:42px; font-size:9px; }
  .bs-sicbo-bet { padding:7px 8px; gap:6px; font-size:12px; }
  .bs-sicbo-bet-icon { width:30px; }
  .bs-sicbo-bet-icon.bs-sicbo-bet-sum { width:21px; height:21px; margin-right:9px; font-size:10px; }
  .bs-sicbo-bet-odds { font-size:9px; padding:2px 5px; }
  .bs-sicbo-rollrow .bs-sicbo-roll { min-width:0; width:100%; }
}
/* ============================================================================
   Scratch card — premium pass. The ticket is real printed stock lying on the
   felt counter: perforated top/bottom edges, punched sides, gold-ink prize
   marks, a serial + barcode, and milled foil panels that shed crumbs as they
   are scratched. Settling stamps the ticket WINNER / NO WIN and pays out on a
   count-up line. Presentation only — every colour is a var(--bs-*) token bar
   the near-black panel well and neutral black/white ink shading.
   ========================================================================== */
.bs-felt.bs-scratch-felt { padding:16px 14px; }
.bs-felt.bs-scratch-felt::before { display:none; }

/* ---- ticket stock -------------------------------------------------------- */
.bs-scratch-ticket { position:relative; overflow:hidden; margin:0; padding:12px 13px 10px;
  border:1px solid var(--bs-line); border-radius:12px;
  background:
    repeating-linear-gradient(135deg, rgba(255,255,255,.022) 0 2px, transparent 2px 7px),
    radial-gradient(140% 130% at 50% -25%, var(--bs-elev2), var(--bs-panel) 72%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07), inset 0 -20px 34px rgba(0,0,0,.3),
    0 14px 28px -10px rgba(0,0,0,.6); }
.bs-scratch-ticket::before, .bs-scratch-ticket::after { content:''; position:absolute; left:0; right:0;
  height:3px; pointer-events:none;
  background:repeating-linear-gradient(90deg, var(--bs-line) 0 4px, transparent 4px 9px); }
.bs-scratch-ticket::before { top:0; }
.bs-scratch-ticket::after { bottom:0; }
.bs-scratch-ticket.bs-scratch-won { border-color:var(--bs-gold);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09), inset 0 -20px 40px rgba(0,0,0,.3),
    0 0 0 1px var(--bs-gold), 0 16px 40px -14px var(--bs-gold); }

/* punched side notches — clipped to half-circles by the ticket's overflow */
.bs-scratch-punch { position:absolute; top:50%; width:14px; height:14px; margin-top:-7px;
  border-radius:50%; pointer-events:none; background:var(--bs-bg);
  box-shadow:inset 0 2px 3px rgba(0,0,0,.8), 0 0 0 1px var(--bs-line); }
.bs-scratch-punch-l { left:-7px; }
.bs-scratch-punch-r { right:-7px; }

/* printer head sweeping down the ticket while it is being issued */
.bs-scratch-headbar { position:absolute; left:0; right:0; top:0; height:3px; z-index:8; pointer-events:none;
  background:linear-gradient(90deg, transparent, var(--bs-orange), transparent);
  box-shadow:0 0 18px 2px var(--bs-orange);
  animation:bs-scratch-printhead 1.1s ease-in-out infinite; }
@keyframes bs-scratch-printhead {
  0% { transform:translateY(0); opacity:.15 } 50% { opacity:1 } 100% { transform:translateY(170px); opacity:.15 } }

/* fill-mode is `forwards`, never `both`: there is no delay, so backwards fill
   buys nothing, and it would leave the element stuck at its opacity:0 frame in
   any context where animations are throttled or suppressed. */
.bs-scratch-dispensed { animation:bs-scratch-dispense .5s cubic-bezier(.2,.85,.3,1.04) forwards; }
@keyframes bs-scratch-dispense {
  0% { transform:translateY(-26px) scale(.97); opacity:0; filter:blur(2px) }
  100% { transform:none; opacity:1; filter:none } }

/* ---- ticket furniture ---------------------------------------------------- */
.bs-scratch-head { margin-bottom:8px; }
.bs-scratch-tag { box-shadow:0 2px 7px -1px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.35); }
.bs-scratch-serial { font-size:9px; letter-spacing:.13em; }
.bs-rail.bs-scratch-rail { margin:0 0 10px; opacity:.32; }
.bs-scratch-foot { display:flex; align-items:center; justify-content:space-between; gap:10px;
  margin-top:2px; padding:0 1px 2px; }
.bs-scratch-barcode { display:flex; align-items:stretch; gap:1px; height:16px; }
.bs-scratch-barcode i { display:block; background:var(--bs-muted); }
.bs-scratch-fine, .bs-scratch-price { font-size:8px; font-weight:800; letter-spacing:.13em;
  text-transform:uppercase; color:var(--bs-faint); white-space:nowrap; }
.bs-scratch-price b { color:var(--bs-muted); font-variant-numeric:tabular-nums; letter-spacing:.04em; }
.bs-scratch-settled .bs-scratch-fine, .bs-scratch-settled .bs-scratch-price { visibility:hidden; }

/* ---- panels -------------------------------------------------------------- */
.bs-scratch-panels { gap:9px; margin-bottom:9px; }
.bs-scratch-panel { max-width:118px; border-width:1px; border-color:var(--bs-line); border-radius:10px;
  background:radial-gradient(115% 100% at 50% 0%, var(--bs-elev2) 0%, var(--bs-well) 96%);
  box-shadow:inset 0 2px 12px rgba(0,0,0,.72), inset 0 0 0 1px rgba(255,255,255,.03),
    0 2px 0 rgba(0,0,0,.4);
  transition:border-color .25s ease, box-shadow .25s ease, transform .25s ease; }
.bs-scratch-panel.revealed { background:radial-gradient(115% 100% at 50% 0%, var(--bs-elev2), var(--bs-panel) 100%); }
.bs-scratch-idx { position:absolute; top:0; left:0; z-index:6; pointer-events:none;
  padding:2px 6px 3px 5px; border-bottom-right-radius:9px;
  font-size:8px; font-weight:900; letter-spacing:.08em; color:var(--bs-faint);
  font-variant-numeric:tabular-nums;
  background:linear-gradient(150deg, rgba(0,0,0,.6), rgba(0,0,0,.18)); }

.bs-scratch-prize { position:relative; z-index:1; gap:5px; }
.bs-scratch-glyph { color:var(--bs-gold-ink); font-size:30px; line-height:1;
  filter:drop-shadow(0 3px 7px rgba(0,0,0,.6)); transition:filter .3s ease; }
.bs-scratch-icon { display:block; width:34px; height:34px; fill:currentColor; }
.bs-scratch-emoji { display:block; font-size:30px; line-height:1; }
.bs-scratch-unknown { color:var(--bs-faint); }
.bs-scratch-name { font-size:8px; letter-spacing:.12em; color:var(--bs-faint); }

/* two of the open panels already match — the tense beat before the last one */
.bs-scratch-panel.bs-scratch-near { border-color:var(--bs-gold);
  box-shadow:inset 0 2px 12px rgba(0,0,0,.6), 0 0 0 1px var(--bs-gold), 0 0 18px -6px var(--bs-gold); }
.bs-scratch-panel.bs-scratch-near .bs-scratch-name { color:var(--bs-gold-ink); }

/* match 3 — the payoff */
.bs-scratch-panel.bs-scratch-hit { border-color:var(--bs-gold);
  background:radial-gradient(115% 100% at 50% 0%, var(--bs-elev2), var(--bs-panel) 100%);
  animation:bs-scratch-hitpulse 1.6s ease-in-out infinite; }
.bs-scratch-panel.bs-scratch-hit:nth-child(2) { animation-delay:.14s; }
.bs-scratch-panel.bs-scratch-hit:nth-child(3) { animation-delay:.28s; }
.bs-scratch-panel.bs-scratch-hit .bs-scratch-name { color:var(--bs-gold-ink); }
.bs-scratch-panel.bs-scratch-hit .bs-scratch-glyph {
  filter:drop-shadow(0 0 11px var(--bs-gold)) drop-shadow(0 2px 4px rgba(0,0,0,.55)); }
@keyframes bs-scratch-hitpulse {
  0%,100% { box-shadow:0 0 0 1px var(--bs-gold), 0 0 16px -8px var(--bs-gold), inset 0 0 20px -12px var(--bs-gold) }
  50% { box-shadow:0 0 0 1px var(--bs-gold), 0 0 34px -4px var(--bs-gold), inset 0 0 30px -6px var(--bs-gold) } }

/* the panel waiting to be scratched */
.bs-scratch-panel.bs-scratch-active { border-color:var(--bs-orange);
  box-shadow:inset 0 2px 12px rgba(0,0,0,.66), 0 0 0 1px var(--bs-orange), 0 0 22px -8px var(--bs-orange); }

/* ---- foil + crumbs ------------------------------------------------------- */
.bs-scratch-panel canvas { z-index:2; border-radius:9px;
  transition:opacity .34s ease, transform .34s ease, filter .34s ease; }
/* Stand-in foil for the frames before the canvas has painted (and the belt-and
   -braces case where 2d canvas is unavailable) — removed the moment the real
   milled foil lands, so scratching always cuts through to the prize. */
.bs-scratch-panel canvas.bs-scratch-unpainted {
  background:linear-gradient(135deg, var(--bs-line) 0%, var(--bs-soft) 26%, var(--bs-muted) 50%,
    var(--bs-soft) 74%, var(--bs-line) 100%); }
.bs-scratch-panel canvas.bs-scratch-cleared { opacity:0; transform:scale(1.07); filter:brightness(1.75); }

.bs-scratch-crumbs { position:absolute; inset:0; z-index:5; pointer-events:none;
  overflow:hidden; border-radius:9px; }
.bs-scratch-crumb { position:absolute; display:block; border-radius:1px;
  background:linear-gradient(135deg, rgba(255,255,255,.9), var(--bs-muted) 55%, rgba(0,0,0,.65));
  box-shadow:0 1px 1px rgba(0,0,0,.55);
  animation-name:bs-scratch-crumbfall; animation-timing-function:cubic-bezier(.3,.1,.6,1);
  animation-fill-mode:forwards; }
@keyframes bs-scratch-crumbfall {
  0% { opacity:.95; transform:translate(0,0) rotate(0deg) }
  100% { opacity:0; transform:translate(var(--bs-crumb-x,0), var(--bs-crumb-y,26px)) rotate(var(--bs-crumb-r,140deg)) } }
.bs-scratch-crumbs.is-flash::before { content:''; position:absolute; inset:-12%; border-radius:14px;
  background:radial-gradient(circle at 50% 50%, var(--bs-gold), transparent 62%);
  opacity:0; animation:bs-scratch-flashfade .55s ease-out forwards; }
@keyframes bs-scratch-flashfade {
  0% { opacity:0; transform:scale(.6) } 28% { opacity:.5 } 100% { opacity:0; transform:scale(1.16) } }

/* ---- reveal progress + tension ------------------------------------------ */
.bs-scratch-progress { display:flex; gap:6px; justify-content:center; margin:0 0 8px; }
.bs-scratch-dot { display:block; width:24px; height:4px; border-radius:2px; background:var(--bs-line);
  transition:background .3s ease, box-shadow .3s ease; }
.bs-scratch-dot.is-on { background:var(--bs-orange); box-shadow:0 0 10px -2px var(--bs-orange); }
.bs-slot-msg.bs-scratch-tense { color:var(--bs-gold-ink); font-weight:900; letter-spacing:.01em;
  animation:bs-scratch-tense 1.05s ease-in-out infinite; }
@keyframes bs-scratch-tense {
  0%,100% { opacity:.78; text-shadow:none } 50% { opacity:1; text-shadow:0 0 15px var(--bs-gold) } }

/* ---- settled ticket: stamp + payout line -------------------------------- */
.bs-scratch-stamp { position:absolute; right:8px; bottom:9px; z-index:7; pointer-events:none;
  padding:4px 12px 5px; border-radius:6px; transform:rotate(-11deg);
  font-size:15px; font-weight:900; letter-spacing:.17em; text-transform:uppercase;
  animation:bs-scratch-stampin .44s cubic-bezier(.2,.9,.3,1.5) forwards; }
.bs-scratch-stamp.is-win { color:var(--bs-gold-ink); border:2px solid var(--bs-gold); opacity:.94;
  text-shadow:0 0 14px var(--bs-gold);
  box-shadow:0 0 24px -6px var(--bs-gold), inset 0 0 16px -7px var(--bs-gold); }
.bs-scratch-stamp.is-back { color:var(--bs-muted); border:2px solid var(--bs-soft); opacity:.75; }
.bs-scratch-stamp.is-void { color:var(--bs-faint); border:2px solid var(--bs-line); opacity:.55; }
/* opacity is deliberately left off the 100% frame so each stamp settles back to
   its own resting opacity (.94 winner / .55 void) instead of a shared value. */
@keyframes bs-scratch-stampin {
  0% { transform:rotate(-26deg) scale(2.3); opacity:0 }
  62% { opacity:.98 }
  100% { transform:rotate(-11deg) scale(1) } }

.bs-scratch-payline { display:flex; align-items:center; justify-content:center; gap:11px; flex-wrap:wrap;
  margin:0 0 10px; padding:9px 14px; border-radius:12px;
  border:1px solid var(--bs-line);
  background:linear-gradient(180deg, var(--bs-elev2), var(--bs-panel)); }
.bs-scratch-payline.is-win { border-color:var(--bs-gold);
  box-shadow:0 0 0 1px var(--bs-gold), 0 12px 34px -18px var(--bs-gold); }
.bs-scratch-payline.is-jackpot { animation:bs-scratch-jackpot 1.5s ease-in-out infinite; }
@keyframes bs-scratch-jackpot {
  0%,100% { box-shadow:0 0 0 1px var(--bs-gold), 0 12px 30px -20px var(--bs-gold) }
  50% { box-shadow:0 0 0 1px var(--bs-gold), 0 14px 50px -14px var(--bs-gold) } }
.bs-scratch-pay-label { font-size:9px; font-weight:900; letter-spacing:.16em; text-transform:uppercase;
  color:var(--bs-muted); }
.bs-scratch-payline .bs-scratch-pay-amt { font-size:28px; line-height:1.05; }
.bs-scratch-payline:not(.is-win) .bs-scratch-pay-amt { color:var(--bs-text); text-shadow:none; }
.bs-scratch-mult { font-size:11px; font-weight:900; font-variant-numeric:tabular-nums;
  padding:3px 9px; border-radius:999px; color:var(--bs-muted);
  background:var(--bs-elev); border:1px solid var(--bs-line); }
.bs-scratch-payline.is-win .bs-scratch-mult { color:var(--bs-on-orange); border-color:transparent;
  background:linear-gradient(180deg, var(--bs-orange-br), var(--bs-orange)); }

/* ---- phone --------------------------------------------------------------- */
@media (max-width:420px) {
  .bs-felt.bs-scratch-felt { padding:12px 9px; }
  .bs-scratch-ticket { padding:10px 9px 9px; }
  .bs-scratch-panels { gap:6px; }
  .bs-scratch-panel { max-width:none; }
  .bs-scratch-icon { width:29px; height:29px; }
  .bs-scratch-emoji, .bs-scratch-glyph { font-size:26px; }
  .bs-scratch-name { font-size:7px; letter-spacing:.07em; }
  .bs-scratch-serial { font-size:8px; letter-spacing:.06em; }
  .bs-scratch-barcode { height:13px; }
  .bs-scratch-fine, .bs-scratch-price { font-size:7px; letter-spacing:.08em; }
  .bs-scratch-payline { gap:8px; padding:8px 10px; }
  .bs-scratch-payline .bs-scratch-pay-amt { font-size:24px; }
  .bs-scratch-stamp { font-size:12px; padding:3px 9px 4px; right:6px; bottom:7px; letter-spacing:.12em; }
  .bs-scratch-dot { width:20px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-scratch-crumb, .bs-scratch-crumbs.is-flash::before { display:none !important; }
  .bs-scratch-headbar, .bs-scratch-dispensed, .bs-scratch-stamp,
  .bs-scratch-panel.bs-scratch-hit, .bs-scratch-payline.is-jackpot,
  .bs-slot-msg.bs-scratch-tense { animation:none !important; }
  /* no opacity override here — `forwards` fill means each stamp already rests at
     its own opacity, so winner and void stay visually distinct without motion */
  .bs-scratch-panel.bs-scratch-hit { box-shadow:0 0 0 1px var(--bs-gold), 0 0 24px -8px var(--bs-gold); }
  .bs-scratch-panel canvas { transition:none !important; }
}

/* ==========================================================================
   Cashier — withdrawals (saved payout methods, live fee/net breakdown,
   pending requests + per-withdrawal status timeline).
   Colours come from the skin's custom properties only, so all ten operator
   skins recolour this panel for free.
   ========================================================================== */
.bs-wd { margin-top: 14px; }
.bs-wd-rail { margin: 0 0 14px; }
.bs-wd-break .bs-wd-rail { margin: 8px 0; opacity: .32; }
.bs-wd-sec { padding-top: 14px; margin-top: 14px; border-top: 1px solid var(--bs-line); }
.bs-wd-sec:first-of-type { padding-top: 0; margin-top: 0; border-top: 0; }
.bs-wd-lbl { display: block; }

/* One-shot confirmation banner — always carries the API's own message. */
.bs-wd-flash { border: 1px solid var(--bs-line); background: var(--bs-elev2); color: var(--bs-text);
  border-radius: 10px; padding: 10px 12px; font-size: 13px; margin-bottom: 12px; }
.bs-wd-flash-ok { border-color: rgba(47,208,122,.4); color: var(--bs-pos); }

/* ---- saved payout methods ------------------------------------------------ */
.bs-wd-privacy { margin-bottom: 10px; }
.bs-wd-methods { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.bs-wd-method { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  border: 1px solid var(--bs-line); border-radius: 10px; background: var(--bs-elev2); padding: 10px 12px; }
.bs-wd-method-def { border-color: var(--bs-orange); }
.bs-wd-method-i { flex: 1 1 160px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.bs-wd-method-i strong { font-size: 14px; overflow-wrap: anywhere; }
.bs-wd-method-t { font-size: 11px; color: var(--bs-muted); text-transform: uppercase; letter-spacing: .07em; }
.bs-wd-method-a { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.bs-wd-del:hover { border-color: var(--bs-neg); color: var(--bs-neg); }

.bs-wd-add { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding: 10px; }
.bs-card .bs-wd-add select { flex: 0 0 auto; width: auto; margin: 0; }
.bs-card .bs-wd-add input { flex: 1 1 180px; min-width: 0; margin: 0; }
.bs-wd-add-err { margin-top: 8px; }

/* ---- live amount / fee / net breakdown ----------------------------------- */
.bs-wd-break { padding: 12px 14px; margin: 10px 0; }
.bs-wd-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  font-size: 13px; color: var(--bs-muted); padding: 3px 0; }
.bs-wd-row strong { color: var(--bs-text); font-variant-numeric: tabular-nums; font-weight: 700; }
.bs-wd-fee { color: var(--bs-muted) !important; }
.bs-wd-row-net { font-size: 14px; }
.bs-wd-row-net strong { font-size: 19px; font-weight: 900; color: var(--bs-gold-ink); letter-spacing: -.01em; }

/* Blocking reason (below minimum, over the cap, more than the balance) — shown
   BEFORE submit so the API never has to reject the request. */
.bs-wd-msg { color: var(--bs-orange); font-size: 13px; margin: 6px 0 10px; }
.bs-wd-go { width: 100%; }
.bs-wd-go:disabled { opacity: .45; cursor: not-allowed; filter: none; }
.bs-wd-go:disabled:active { transform: none; }
.bs-wd-err { margin-bottom: 6px; }

/* ---- withdrawal history -------------------------------------------------- */
.bs-wd-list { display: flex; flex-direction: column; gap: 10px; }
.bs-wd-item { border: 1px solid var(--bs-line); border-radius: 12px; background: var(--bs-elev2); padding: 12px 14px; }
.bs-wd-item-live { border-color: rgba(255,138,0,.42); }
.bs-wd-item-h { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.bs-wd-item-amt { display: flex; flex-direction: column; gap: 2px; }
.bs-wd-item-amt strong { font-size: 17px; font-variant-numeric: tabular-nums; }
.bs-wd-item-when { font-size: 11px; color: var(--bs-faint); }
.bs-wd-item-b { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 8px; font-size: 12px; color: var(--bs-muted); }
.bs-wd-item-b strong { color: var(--bs-text); font-variant-numeric: tabular-nums; }
.bs-wd-cancel { margin-top: 10px; }
.bs-wd-cancel:hover { border-color: var(--bs-neg); color: var(--bs-neg); }

/* ---- per-withdrawal status timeline -------------------------------------- */
.bs-wd-tl { margin-top: 10px; border-top: 1px solid var(--bs-line); padding-top: 8px; }
.bs-wd-tl summary { cursor: pointer; font-size: 12px; font-weight: 700; color: var(--bs-muted); }
.bs-wd-tl summary:hover { color: var(--bs-orange); }
.bs-wd-tl[open] summary { color: var(--bs-text); }
.bs-wd-tl-n { display: inline-block; min-width: 17px; padding: 0 5px; border-radius: 999px;
  background: var(--bs-soft); color: var(--bs-muted); font-size: 10px; text-align: center; }
.bs-wd-tl-list { list-style: none; margin: 10px 0 0; padding: 0 0 0 6px; }
.bs-wd-tl-item { position: relative; display: flex; gap: 12px; padding: 0 0 12px 0; }
.bs-wd-tl-item:last-child { padding-bottom: 0; }
/* The connecting spine between events. */
.bs-wd-tl-item::before { content: ""; position: absolute; left: 4px; top: 12px; bottom: 0; width: 1px; background: var(--bs-line); }
.bs-wd-tl-item:last-child::before { display: none; }
.bs-wd-tl-dot { flex: none; width: 9px; height: 9px; margin-top: 4px; border-radius: 50%;
  background: var(--bs-soft); box-shadow: 0 0 0 3px var(--bs-elev2); }
.bs-wd-tl-requested .bs-wd-tl-dot { background: var(--bs-muted); }
.bs-wd-tl-approved .bs-wd-tl-dot, .bs-wd-tl-paid .bs-wd-tl-dot { background: var(--bs-pos); }
.bs-wd-tl-rejected .bs-wd-tl-dot { background: var(--bs-neg); }
.bs-wd-tl-cancelled .bs-wd-tl-dot { background: var(--bs-faint); }
.bs-wd-tl-body { flex: 1; min-width: 0; }
.bs-wd-tl-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.bs-wd-tl-head strong { font-size: 13px; }
.bs-wd-tl-at { font-size: 11px; color: var(--bs-faint); font-variant-numeric: tabular-nums; }
.bs-wd-tl-by { font-size: 11px; color: var(--bs-muted); margin-top: 1px; }
.bs-wd-tl-note { font-size: 12px; color: var(--bs-muted); margin-top: 4px; overflow-wrap: anywhere; }

@media (max-width:420px) {
  .bs-wd-add { flex-direction: column; align-items: stretch; }
  .bs-card .bs-wd-add select, .bs-card .bs-wd-add input, .bs-wd-add .bs-btn { width: 100%; }
  .bs-wd-method-a { width: 100%; }
  .bs-wd-item-b { gap: 8px 14px; }
}

/* ============================================================================
   PRODUCT POLISH
   A finishing layer over the SHARED chrome only — cards, headings, labels,
   tables, forms, buttons, focus. The casino games have their own dedicated
   styling above and are deliberately not touched here (game-specific selectors
   are more specific, or already set the property they care about).
   Every colour still resolves through a --bs-* custom property, so all ten
   operator skins keep working.
   ========================================================================== */
.betsystem-widget, .bs-hero, .bs-overlay {
  /* Type scale — one ratio for the whole product instead of ad-hoc sizes. */
  --bs-t-2xs: 10.5px;
  --bs-t-xs: 11.5px;
  --bs-t-sm: 13px;
  --bs-t-md: 14px;
  --bs-t-lg: 17px;
  --bs-t-xl: 21px;
  /* Vertical rhythm — a 4px base step. */
  --bs-sp-1: 4px;
  --bs-sp-2: 8px;
  --bs-sp-3: 12px;
  --bs-sp-4: 16px;
  --bs-sp-5: 20px;
  font-size: var(--bs-t-md);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ---- surfaces ------------------------------------------------------------ */
/* Layered depth: a hairline top highlight (the light catching the top edge),
   a tight contact shadow, then a wide soft ambient one. */
.bs-card {
  padding: var(--bs-sp-5) var(--bs-sp-5) calc(var(--bs-sp-5) + 2px);
  margin: var(--bs-sp-3) 0;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .055),
    0 1px 2px rgba(0, 0, 0, .3),
    0 12px 32px -14px rgba(0, 0, 0, .62);
}
.bs-card > :first-child { margin-top: 0; }
.bs-card > :last-child { margin-bottom: 0; }

/* On the light skin the dark ambient shadow reads as dirt — soften it and make
   the top highlight opaque white instead. */
.bs-skin-classic .bs-card {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .9),
    0 1px 2px rgba(16, 24, 40, .06),
    0 12px 28px -16px rgba(16, 24, 40, .28);
}

/* ---- headings & labels --------------------------------------------------- */
.bs-card h3 { font-size: var(--bs-t-lg); line-height: 1.25; margin: 0 0 var(--bs-sp-4); }
.bs-card h4 { font-size: var(--bs-t-md); line-height: 1.3; margin: 0 0 var(--bs-sp-3); letter-spacing: -.005em; }
.bs-card p { margin: 0 0 var(--bs-sp-3); line-height: 1.55; }
.bs-label { font-size: var(--bs-t-2xs); letter-spacing: .1em; line-height: 1.4; font-weight: 700; }
.bs-hint { font-size: var(--bs-t-sm); line-height: 1.5; margin: var(--bs-sp-2) 0; }
.bs-terms, .bs-hero-rg { line-height: 1.5; }
.bs-auth label, .bs-limit-form label, .bs-range label, .bs-card label {
  font-size: 12px; line-height: 1.35; margin: var(--bs-sp-3) 0 var(--bs-sp-1) 0; font-weight: 600;
}
.bs-net { margin-top: var(--bs-sp-1); line-height: 1.4; }

/* ---- tables -------------------------------------------------------------- */
.bs-table { font-size: var(--bs-t-sm); margin-top: var(--bs-sp-3); }
.bs-table th {
  font-size: var(--bs-t-2xs); text-transform: uppercase; letter-spacing: .08em;
  font-weight: 700; padding: var(--bs-sp-2) var(--bs-sp-2) 6px; white-space: nowrap;
}
.bs-table td { padding: 10px var(--bs-sp-2); line-height: 1.45; }
/* Figures line up column-to-column instead of jittering row to row. */
.bs-table td { font-variant-numeric: tabular-nums; }
.bs-table tbody tr:last-child td { border-bottom: 0; }

/* ---- buttons ------------------------------------------------------------- */
/* More physical: lifts off the surface on hover, presses in on click, and
   clearly reads as dead when disabled. */
.bs-btn {
  line-height: 1.2;
  letter-spacing: .005em;
  transition: transform .08s ease, filter .18s ease, box-shadow .18s ease,
              background-color .18s ease, border-color .18s ease, color .18s ease;
}
.bs-btn:hover { transform: translateY(-1px); }
.bs-btn:active { transform: translateY(1px) scale(.995); filter: brightness(.97); }
.bs-btn:disabled, .bs-btn[disabled], .bs-btn[aria-disabled="true"] {
  opacity: .42; filter: grayscale(.3); cursor: not-allowed; box-shadow: none;
}
.bs-btn:disabled:hover, .bs-btn[disabled]:hover, .bs-btn[aria-disabled="true"]:hover {
  transform: none; filter: grayscale(.3);
}
.bs-btn:disabled:active, .bs-btn[disabled]:active { transform: none; }
.bs-btn-ghost:hover { background: var(--bs-elev2); border-color: var(--bs-orange); color: var(--bs-orange); }
.bs-btn-ghost:active { background: var(--bs-elev); }

/* ---- focus --------------------------------------------------------------- */
/* Keyboard users get a visible, on-brand ring everywhere; pointer users don't
   (:focus-visible), so nothing changes for mouse/touch play.
   Two rings, not one: the brand outline can sit on felt, gold, an orange button
   or a red roulette pocket, so a separating halo in the surface colour goes
   underneath it. --bs-panel is near-black on the nine dark skins and white on
   `classic`, so the pair stays legible both ways without a second rule. */
.betsystem-widget :focus-visible,
.bs-hero :focus-visible,
.bs-overlay :focus-visible {
  outline: 3px solid var(--bs-orange);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--bs-panel), 0 0 0 6px rgba(0, 0, 0, .28);
}
/* The inputs kill the default outline for a border swap — give them the ring back. */
.bs-card input:focus-visible, .bs-card select:focus-visible,
.bs-card textarea:focus-visible, .bs-redeem input:focus-visible {
  outline: 3px solid var(--bs-orange); outline-offset: 1px; border-color: var(--bs-orange);
}

/* Visually hidden, still read aloud. */
.bs-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ============================================================================
   LANGUAGE SWITCHER (header) — compact trigger + listbox dropdown.
   Sized to sit in a tight header bar next to a Log in / Deposit button.
   ========================================================================== */
.betsystem-widget[data-betsystem="lang"] { display: inline-block; vertical-align: middle; }
.bs-langsw { position: relative; display: inline-block; text-align: left; }

.bs-langsw-btn {
  display: inline-flex; align-items: center; gap: 7px;
  height: 34px; padding: 0 11px; max-width: 100%;
  background: var(--bs-elev2); border: 1px solid var(--bs-line); border-radius: 999px;
  color: var(--bs-text); font: inherit; font-size: 12.5px; font-weight: 700; line-height: 1;
  cursor: pointer; white-space: nowrap;
  transition: border-color .16s ease, color .16s ease, background .16s ease;
}
.bs-langsw-btn:hover, .bs-langsw-open .bs-langsw-btn { border-color: var(--bs-orange); color: var(--bs-orange); }

/* Globe mark — drawn in currentColor so it follows every skin. */
.bs-langsw-glyph {
  position: relative; flex: none; width: 14px; height: 14px; border-radius: 50%;
  border: 1.5px solid currentColor; opacity: .85;
}
.bs-langsw-glyph::before {
  content: ""; position: absolute; top: -1.5px; bottom: -1.5px; left: 2.5px; right: 2.5px;
  border-radius: 50%; border: 1.5px solid currentColor;
}
.bs-langsw-glyph::after {
  content: ""; position: absolute; left: -1.5px; right: -1.5px; top: 50%;
  border-top: 1.5px solid currentColor;
}

.bs-langsw-code { font-weight: 800; font-size: 12px; letter-spacing: .06em; }
.bs-langsw-name { font-weight: 600; }
.bs-langsw-btn .bs-langsw-name {
  color: var(--bs-muted); max-width: 10ch; overflow: hidden; text-overflow: ellipsis;
}
.bs-langsw-btn:hover .bs-langsw-name, .bs-langsw-open .bs-langsw-btn .bs-langsw-name { color: inherit; }
.bs-langsw-caret {
  width: 0; height: 0; flex: none; margin-left: 1px;
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid currentColor; opacity: .7; transition: transform .16s ease;
}
.bs-langsw-open .bs-langsw-caret { transform: rotate(180deg); }

.bs-langsw-menu {
  position: absolute; z-index: 9999; top: calc(100% + 6px); right: 0;
  min-width: 178px; display: flex; flex-direction: column; gap: 2px; padding: 6px;
  background: var(--bs-panel); border: 1px solid var(--bs-line); border-radius: 12px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .06),
    0 18px 44px -16px rgba(0, 0, 0, .75);
}
.bs-skin-classic .bs-langsw-menu {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9), 0 16px 36px -18px rgba(16, 24, 40, .4);
}
.bs-langsw-menu[hidden] { display: none; }

.bs-langsw-opt {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 10px; border: 0; border-radius: 8px; background: transparent;
  color: var(--bs-text); font: inherit; font-size: 13px; text-align: left; cursor: pointer;
  transition: background .14s ease, color .14s ease;
}
.bs-langsw-opt .bs-langsw-name { flex: 1 1 auto; color: inherit; }
.bs-langsw-opt:hover { background: var(--bs-elev2); }
.bs-langsw-on { background: var(--bs-elev2); }
.bs-langsw-on .bs-langsw-code, .bs-langsw-tick { color: var(--bs-orange); }
.bs-langsw-tick { flex: none; width: 12px; text-align: right; font-weight: 900; }

/* In a tight header (or on a phone) the endonym drops and the code carries it. */
.bs-langsw-compact .bs-langsw-name { display: none; }
@media (max-width: 720px) {
  .bs-langsw-btn .bs-langsw-name { display: none; }
  .bs-langsw-btn { padding: 0 10px; gap: 6px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-langsw-btn, .bs-langsw-caret, .bs-langsw-opt, .bs-btn { transition: none; }
  .bs-langsw-open .bs-langsw-caret { transform: none; }
  .bs-btn:hover, .bs-btn:active { transform: none; }
}

/* ============================================================================
   MOBILE HARDENING — the phone pass (audited at 375px and 390px).
   Deliberately appended LAST and written entirely inside max-width queries:
   desktop is byte-for-byte unchanged, and every rule here wins at equal
   specificity over the per-game phone blocks above without having to edit
   twenty scattered media queries.
   Two steps only, matching the rest of the sheet: 560px (phone/small tablet)
   and 420px (the real handset case — 375/390/412 all land here).
   Every colour still resolves from a --bs-* token, so all 10 skins hold.
   ========================================================================== */

/* The ONE rule here that is not inside a media query, because the bug it fixes
   is not phone-specific: `.bs-overlay` was a fixed, centred flex box with no
   overflow, so ANY modal taller than the viewport was clipped off both ends
   with no way to scroll to the rest of it and no way to reach the × — true on
   an 800px-high laptop as well as on a handset.
   This is a behaviour change, not a restyle. `align-items:flex-start` plus
   `margin:auto` on the card is geometrically identical to `align-items:center`
   whenever the card fits (auto margins absorb the free space), and `auto`
   overflow shows no scrollbar in that case — measured identical to the pixel
   at 1280x800. It only does anything once the layout is already broken, at
   which point the overflow becomes scrollable instead of unreachable. */
.bs-overlay { align-items: flex-start; overflow-y: auto; overflow-x: hidden;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.bs-overlay > .bs-overlay-card { margin: auto; }

@media (max-width: 560px) {

  /* ---- 1. Nothing may push the page sideways ------------------------------
     `overflow-wrap` is inherited, so one declaration per root covers every
     descendant: a long team name, an un-spaced money figure or a wallet
     address now breaks instead of forcing its flex/grid track wider than the
     card. It only breaks words that would otherwise overflow, so normal copy
     is untouched. This also defuses `min-width:auto` on flex items, which was
     the underlying cause of most of the sideways drift. */
  .betsystem-widget, .bs-card, .bs-hero, .bs-overlay-card { overflow-wrap: break-word; }
  .betsystem-widget, .bs-hero { max-width: 100%; }

  /* Wide data tables (My Bets is six columns) scroll inside themselves rather
     than widening the card and, with it, the page. `display:block` turns the
     table into its own scrollport; the rows still lay out as one table inside
     it, so the columns stay aligned. */
  .bs-table { display: block; width: 100%; overflow-x: auto;
    -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
  .bs-table th { padding-left: 6px; padding-right: 6px; }
  .bs-table td { padding-left: 6px; padding-right: 6px; }

  /* ---- 2. Modals: a real gutter, and a close control that stays reachable --
     On a phone every game modal (Roulette, Craps, Keno, Blackjack, Chinchón,
     Sic Bo, Video Poker) is taller than the viewport, so the scrollport above
     does the heavy lifting; this just gives it a gutter to breathe in. */
  .bs-overlay { padding: 10px 12px 20px; }

  /* 28px of gutter each side cost 56px of a 345px modal. 16px buys most of it
     back — which is what the dense boards below are spending. The card is a
     shrinkable flex item, so its own max-width (380 / 480) still caps it while
     the overlay's padding guarantees a gutter on a 375px handset. */
  .bs-overlay-card { padding: 16px; }

  /* Sic Bo had carved out its own inner scroller. On a phone the overlay does
     the scrolling for every game, so there is one scrollbar and one sticky
     head everywhere instead of a nested pair. */
  .bs-game-modal.bs-sicbo-modal { max-height: none; overflow: visible; }

  /* The title bar pins to the top of the scrollport, so the × is one thumb
     press away however long the game gets. */
  .bs-game-modal .bs-game-modal-head {
    position: sticky; top: 0; z-index: 9;
    margin: -16px -16px 12px; padding: 11px 16px;
    border-radius: 15px 15px 0 0;
    background: var(--bs-panel);
    border-bottom: 1px solid var(--bs-line);
  }
  .bs-game-modal .bs-game-modal-head > h3,
  .bs-game-modal .bs-game-modal-head > strong {
    min-width: 0; margin: 0; font-size: 15px; line-height: 1.25;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .bs-game-modal-head .bs-x {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; margin: -7px -9px -7px 4px;
    font-size: 26px; border-radius: 12px;
  }
  .bs-game-modal-head .bs-x:active { background: var(--bs-elev2); }
  .bs-overlay-actions { flex-wrap: wrap; }
  .bs-overlay-actions .bs-btn { flex: 1 1 140px; }

  /* ---- 3. Tap targets ----------------------------------------------------
     Everything the thumb has to hit gets a comfortable box. Game-specific
     buttons that set their own padding are more specific and keep it. */
  .bs-btn { padding: 13px 18px; font-size: 15px; }
  .bs-btn-sm { padding: 12px 14px; font-size: 13px; }
  .bs-tabs button { padding: 12px 9px; }
  .bs-cat, .bs-league { padding: 10px 15px; }
  .bs-pay { padding: 12px 14px; }
  .bs-chip-amt { padding: 11px 15px; }
  .bs-lang-b { padding: 10px 13px; }
  /* A bare "×" glyph is a ~18px target. Padding grows the hit box; the equal
     negative margin puts the glyph back exactly where it was drawn. */
  .bs-slip-sel .bs-x { padding: 11px; margin: -11px -6px -11px 0; }
  .bs-fair summary, .bs-wd-tl summary { padding: 7px 0; }
  .bs-game .bs-btn { display: block; margin: 0 8px 10px; }

  /* Form fields: 16px is the iOS threshold — anything smaller makes Safari
     zoom the whole page on focus, which is itself a source of sideways drift. */
  .bs-card input, .bs-card select, .bs-card textarea, .bs-redeem input {
    font-size: 16px; min-height: 44px;
  }
  .bs-card input[type="checkbox"], .bs-card input[type="radio"] {
    min-height: 0; width: 20px; height: 20px;
  }
  /* Game-modal inputs get NO styling from `.bs-card input` — the modal is
     appended to <body>, outside any card — so on a phone they were raw native
     controls: sub-16px (zoom on focus) and barely tall enough to hit. */
  .bs-game-modal input, .bs-game-modal select {
    box-sizing: border-box; min-height: 44px; padding: 10px 12px;
    font-family: inherit; font-size: 16px;
    color: var(--bs-text); background: var(--bs-bg);
    border: 1px solid var(--bs-line); border-radius: 10px;
  }
  .bs-game-modal input:focus, .bs-game-modal select:focus { border-color: var(--bs-orange); }
  .bs-slot-ctrls input { width: 108px; }
  .bs-row-tight input { width: 112px; }

  /* ---- 4. Rows that could not wrap ---------------------------------------
     `.bs-slot-ctrls` (the stake + action row every instant game uses) was
     `nowrap`, and the buttons inside carry min-widths of 130–210px. Crash's
     stake + LAUNCH + CASH OUT needed ~436px on a 313px canvas and simply
     spilled out of the modal. */
  .bs-slot-ctrls, .bs-toggle, .bs-quick, .bs-redeem, .bs-tabs,
  .bs-hilo-actions, .bs-bj-actions, .bs-tcp-actions, .bs-cs-actions,
  .bs-rw-rack, .bs-craps-phase,
  .bs-dice-tray, .bs-actions, .bs-kyc-box, .bs-hero-cta { flex-wrap: wrap; }
  .bs-slot-ctrls > *, .bs-toggle > * { min-width: 0; }

  /* The primary action of a round takes its own full-width row — the stake
     control keeps the row above it. */
  .bs-slot-ctrls .bs-crash-cash, .bs-slot-ctrls .bs-crash-launch,
  .bs-slot-ctrls .bs-mines-cash, .bs-slot-ctrls .bs-hilo-cash,
  .bs-slot-ctrls .bs-bac-deal, .bs-slot-ctrls .bs-dice-roll,
  .bs-slot-ctrls .bs-limbo-launch, .bs-slot-ctrls .bs-cf-cash,
  .bs-slot-ctrls .bs-vp-draw, .bs-btn.bs-craps-roll,
  .bs-slot-ctrls .bs-tcp-deal, .bs-slot-ctrls .bs-cs-deal,
  .bs-sicbo-rollrow .bs-sicbo-roll, .bs-rw-spin-btn, .bs-pw-spin {
    flex: 1 1 100%; min-width: 0; max-width: none;
  }
  .bs-toggle.bs-craps-toggle .bs-btn { flex: 1 1 44%; min-width: 0; }
  .bs-actions .bs-btn, .bs-hero-cta .bs-btn { flex: 1 1 150px; }
  .bs-redeem input { flex: 1 1 150px; min-width: 0; }
  .bs-quick { gap: 8px; }
  .bs-chip-amt { flex: 1 1 auto; min-width: 66px; text-align: center; }
  .bs-pays { gap: 8px; }
  .bs-pay { flex: 1 1 auto; min-width: 82px; text-align: center; }
  .bs-wd-go { width: 100%; }

  /* ---- 5. Widgets outside the modals -------------------------------------- */
  /* Live scoreboard: 23px team names + a 40px score never fit 273px of card. */
  .bs-lt-hero { padding: 16px 14px; }
  .bs-lt-hero .claw { width: 190px; height: 190px; right: -34px; top: -14px; }
  .bs-lt-match { gap: 9px; margin-bottom: 16px; }
  .bs-lt-team { min-width: 0; }
  .bs-lt-team .nm { font-size: 17px; }
  .bs-lt-team .mt { font-size: 10.5px; }
  .bs-lt-score { gap: 8px; font-size: 28px; }
  .bs-lt-clock { font-size: 12px; }
  .bs-lt-row1 { flex-wrap: wrap; gap: 8px; }

  /* Odds buttons: three per row on a narrow card, so the label must be able to
     shrink rather than widen its grid track. */
  .bs-odds, .bs-lt-odds3 { gap: 6px; }
  .bs-odd { min-width: 0; padding: 11px 4px; }
  .bs-odd-name, .bs-odd-bookmaker, .bs-odd-price { max-width: 100%; text-align: center; }

  .bs-fixture-head, .bs-slip-sel, .bs-tour-h, .bs-bonus-h,
  .bs-note-h, .bs-vip-status, .bs-lb-tabs { min-width: 0; }
  .bs-winners li { flex-wrap: wrap; }
  .bs-win-detail { margin-left: auto; }

  /* Boost rail: one card plus a peek of the next, so the horizontal scroll is
     discoverable instead of looking like a cut-off row. */
  .bs-boosts { gap: 10px; scroll-snap-type: x proximity; }
  .bs-boost { flex: 0 0 84%; max-width: 280px; }

  .bs-jp { min-width: 118px; max-width: 100%; }
  .bs-jp-val { max-width: 100%; font-size: 20px; overflow-wrap: anywhere; }
  .bs-refcode { font-size: 20px; letter-spacing: 3px; overflow-wrap: anywhere; }
  .bs-games { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
  .bs-feats, .bs-promos, .bs-lt-promos { grid-template-columns: 1fr; }

  /* Language menu must never hang off the right edge. */
  .bs-langsw-btn { height: 40px; padding: 0 12px; }
  .bs-langsw-menu { max-width: calc(100vw - 24px); max-height: 60vh; overflow-y: auto; }
  .bs-langsw-opt { padding: 12px 10px; font-size: 14px; }
}

@media (max-width: 420px) {

  /* ---- 6. The dense boards ------------------------------------------------ */

  /* Roulette. 14 columns across ~341px (the table already borrows the modal's
     gutter). `minmax(0,1fr)` stops a cell's own content from widening its
     track — without it a two-digit number could push the layout past the
     board — and the rows go from 23px to ~28px tall so the numbers are
     actually hittable. The negative margins follow the modal's new 16px
     gutter so the felt sits flush to the modal edge. */
  .bs-rw-table { margin-left: -16px; margin-right: -16px; padding: 7px 5px; }
  .bs-rw-layout {
    gap: 1.5px;
    grid-template-columns: 1.22fr repeat(12, minmax(0, 1fr)) 1.06fr;
    grid-template-rows: repeat(3, clamp(26px, 7.2vw, 32px))
                        clamp(24px, 6.4vw, 28px) clamp(24px, 6.4vw, 28px);
  }
  .bs-rw-cell-n { font-size: clamp(9px, 2.7vw, 13px); }
  .bs-rw-rchip { width: 40px; height: 40px; }

  /* Sic Bo. The grid already uses minmax(0,1fr); the cells just needed a real
     minimum height so a 6- and 7-across row is still a thumb target. */
  .bs-sicbo-row-6 .bs-sicbo-cell, .bs-sicbo-row-7 .bs-sicbo-cell { min-height: 46px; }
  .bs-sicbo-row-2 .bs-sicbo-cell, .bs-sicbo-row-3 .bs-sicbo-cell { min-height: 52px; }
  .bs-sicbo-cell-main b { font-size: 14px; }

  /* Keno. 40 cells across the card: tightening the gutters and the ticket
     padding takes each cell from ~29px to ~33px without any scrolling. */
  .bs-keno-ticket { padding: 8px 5px 6px; }
  .bs-keno-grid { gap: 3px; }
  .bs-keno-num { font-size: 12px; }

  /* Plinko. 17 buckets on a flex row: `min-width:auto` meant a "1000x" label
     claimed ~20px each, i.e. 356px of a 279px board, so the buckets drifted
     off the percentage grid the ball's landing position is computed against.
     `min-width:0` puts every bucket back on 100/(rows+1)% exactly. */
  .bs-plink-board.bs-plink-v2 .bs-plink-bucket {
    min-width: 0; font-size: clamp(5px, 1.7vw, 8px);
  }
  .bs-plink-bucket-lbl { display: block; max-width: 100%; overflow: hidden; }

  /* Video poker paytable: the name column must be the one that gives way. */
  .bs-vp-pt-head, .bs-vp-pt-row { grid-template-columns: minmax(0, 1fr) auto auto; }

  /* Craps boxes / Mines tiles / Baccarat spots are grid- or flex-sized and
     already fit at 375px; they only needed a floor on the touch box. These are
     all flex or grid children, so a min-height still centres their content. */
  .bs-craps-box { min-height: 34px; }
  .bs-craps-line { min-height: 48px; }
  .bs-bac-spot, .bs-bac-denom { min-height: 46px; }
  .bs-plink-risk .bs-plink-risk-btn, .bs-pw-risks .bs-pw-risk { min-height: 44px; }
  /* .bs-limbo-chip is an inline-block .bs-btn-sm, so it grows by padding
     instead — a min-height would leave its label pinned to the top. */
  .bs-limbo-chip { padding: 12px 10px; }

  /* Bet-slip remove buttons were ~24px tall inside a 13px row. */
  .bs-rw-slip-x, .bs-sicbo-slip .bs-sicbo-x { padding: 9px 11px; line-height: 1.2; }
  .bs-bac-x { padding: 11px; margin: -11px -4px -11px -8px; }

  /* Slip rows: the label is the flexible part, the money is not. */
  .bs-rw-slip-row, .bs-sicbo-bet { min-width: 0; }
  .bs-rw-slip-label, .bs-sicbo-bet-label { min-width: 0; }
}

/* ============================================================================
   THREE CARD POKER — the Shuffle Master table. Gold-on-black cloth, the three
   PRINTED BETTING CIRCLES (Pair Plus / Ante / Play) stacked between the two
   hands exactly as they are silk-screened on a real layout, and a ranking
   ladder that states the thing players get wrong: on three cards a STRAIGHT
   BEATS A FLUSH.

   Deliberately nothing like Blackjack (green cloth, printed arc, chip totals)
   or Caribbean Stud (rectangular wager boxes, five-card rows) — three games,
   three tables. The card stock itself is the shared cardFaceHtml(), and the
   deal/flip animation is the shared toolkit, so only the furniture is new.
   Every colour is a --bs-* token; the only fixed values are neutral
   black/white light and shadow on physical objects.
   ========================================================================== */
.bs-felt.bs-tcp-felt { position:relative; padding:12px 12px 11px; }

/* Cloth: gold tint + table vignette on its own layer, so .bs-fx-shimmer keeps
   the felt's own pseudo-element while a deal is in flight. */
.bs-tcp-cloth { position:absolute; inset:0; border-radius:14px; overflow:hidden; pointer-events:none; }
.bs-tcp-cloth::before { content:''; position:absolute; inset:0;
  background:radial-gradient(128% 90% at 50% -8%, var(--bs-gold), transparent 64%); opacity:.09; }
.bs-tcp-cloth::after { content:''; position:absolute; inset:0;
  background:radial-gradient(104% 76% at 50% 46%, transparent 34%, rgba(0,0,0,.52) 100%); }
.bs-felt.bs-tcp-felt.is-settled { box-shadow:inset 0 1px 0 rgba(255,255,255,.05),
  inset 0 -18px 34px rgba(0,0,0,.45), 0 0 34px -16px var(--bs-gold); }

.bs-tcp-crest { position:relative; z-index:1; display:flex; align-items:center; gap:10px; margin:0 2px 8px; }
.bs-tcp-crest i { flex:1; height:1px; background:linear-gradient(90deg, transparent, var(--bs-gold)); opacity:.32; }
.bs-tcp-crest i:last-child { background:linear-gradient(90deg, var(--bs-gold), transparent); }
.bs-tcp-crest span { flex:none; font-size:9px; font-weight:900; letter-spacing:.26em;
  text-transform:uppercase; color:var(--bs-gold-ink); opacity:.8; }

/* ---- seats --------------------------------------------------------------- */
.bs-tcp-seat { position:relative; z-index:1; }
.bs-tcp-seat .bs-felt-label { min-height:26px; margin-bottom:5px; }
.bs-tcp-tag { margin-right:auto; }
.bs-tcp-row { position:relative; gap:9px; min-height:88px; }
/* A tight three-card fan — the whole hand reads at a glance, which is the
   decision this table is about. */
.bs-tcp-row .bs-bj-card:not(.bs-bj-flip) > .bs-pcard { transform-origin:50% 100%; }
.bs-tcp-row .bs-bj-card:nth-child(1):not(.bs-bj-flip) > .bs-pcard { transform:rotate(-3.2deg); }
.bs-tcp-row .bs-bj-card:nth-child(2):not(.bs-bj-flip) > .bs-pcard { transform:rotate(0deg); }
.bs-tcp-row .bs-bj-card:nth-child(3):not(.bs-bj-flip) > .bs-pcard { transform:rotate(3.2deg); }
/* The dealer's three cards are the secret on the table — a gold hairline says so. */
.bs-tcp-hole > .bs-pcard-back { box-shadow:0 6px 16px rgba(0,0,0,.45),
  inset 0 0 0 3px rgba(255,255,255,.16), 0 0 0 1px var(--bs-gold), 0 0 16px -7px var(--bs-gold); }

/* The hand's own category, named rather than left for the player to work out. */
.bs-tcp-cat { flex:none; padding:3px 10px; border-radius:999px; letter-spacing:.04em;
  font-size:10px; font-weight:900; text-transform:uppercase; color:var(--bs-muted);
  background:rgba(0,0,0,.3); box-shadow:inset 0 0 0 1px var(--bs-line); }
.bs-tcp-cat-pay { color:var(--bs-gold-ink); box-shadow:inset 0 0 0 1px var(--bs-gold); }
.bs-tcp-cat-nq { color:var(--bs-neg); box-shadow:inset 0 0 0 1px var(--bs-neg); }

/* The qualifying rule, printed on the cloth between the two hands. */
.bs-tcp-qual { position:relative; z-index:1; margin:9px 0 8px; text-align:center;
  font-size:9px; font-weight:900; letter-spacing:.15em; text-transform:uppercase;
  color:var(--bs-gold-ink); opacity:.6; }
.bs-tcp-qual.is-q { color:var(--bs-pos); opacity:1; }
.bs-tcp-qual.is-nq { color:var(--bs-neg); opacity:1; }

/* ---- the three printed betting circles ----------------------------------- */
.bs-tcp-spots { position:relative; z-index:1; display:flex; gap:10px;
  justify-content:center; align-items:center; margin:0 0 10px; }
.bs-tcp-spot { position:relative; flex:1 1 0; min-width:0; max-width:108px; aspect-ratio:1 / 1;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1px;
  border-radius:50%; text-align:center; padding:4px;
  background:radial-gradient(circle at 50% 34%, rgba(255,255,255,.05), rgba(0,0,0,.3) 74%);
  box-shadow:inset 0 0 0 1px var(--bs-line), inset 0 0 0 4px rgba(0,0,0,.18);
  transition:box-shadow .25s ease, opacity .25s ease, filter .25s ease; }
.bs-tcp-spot::before { content:''; position:absolute; inset:0; border-radius:50%;
  border:1px dashed var(--bs-line); margin:5px; pointer-events:none; }
.bs-tcp-spot-name { font-size:8px; font-weight:900; letter-spacing:.12em;
  text-transform:uppercase; color:var(--bs-faint); line-height:1.2; }
.bs-tcp-spot-amt { font-size:13px; font-weight:900; color:var(--bs-text);
  font-variant-numeric:tabular-nums; line-height:1.15; overflow-wrap:anywhere; }
.bs-tcp-spot-pay { font-size:10px; font-weight:900; color:var(--bs-pos);
  font-variant-numeric:tabular-nums; }
/* The Play circle is empty until the player commits to it. */
.bs-tcp-spot-play { box-shadow:inset 0 0 0 1px var(--bs-line); }
.bs-tcp-spot.is-pending { box-shadow:inset 0 0 0 1px var(--bs-orange), 0 0 22px -10px var(--bs-orange); }
.bs-tcp-spot.is-pending .bs-tcp-spot-amt { color:var(--bs-orange); }
.bs-tcp-spot.is-won { box-shadow:inset 0 0 0 1.5px var(--bs-pos), 0 0 26px -8px var(--bs-pos); }
.bs-tcp-spot.is-lost { opacity:.42; filter:saturate(.45); }
.bs-tcp-spot.is-idle { opacity:.35; }

/* ---- the ranking ladder — the point of this modal ------------------------ */
.bs-tcp-lad { margin:0 0 10px; border:1px solid var(--bs-line); border-radius:12px;
  overflow:hidden; background:linear-gradient(180deg, rgba(255,255,255,.03), rgba(0,0,0,.22)); }
/* The summary is the headline, not a label: it carries the one sentence a
   player can get wrong, so it reads the same whether the rows are open or
   folded away. */
.bs-tcp-lad-sum { display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  padding:8px 11px; cursor:pointer; list-style:none; user-select:none;
  background:rgba(0,0,0,.26); }
.bs-tcp-lad-sum::-webkit-details-marker { display:none; }
.bs-tcp-lad-sum::after { content:'▾'; margin-left:auto; flex:none; font-size:11px;
  color:var(--bs-faint); transition:transform .2s ease; }
.bs-tcp-lad[open] > .bs-tcp-lad-sum::after { transform:rotate(180deg); }
.bs-tcp-lad-sum-t { font-size:10px; font-weight:900; letter-spacing:.14em;
  text-transform:uppercase; color:var(--bs-text); }
.bs-tcp-lad-sum-k { font-size:10px; font-weight:900; letter-spacing:.08em;
  text-transform:uppercase; color:var(--bs-gold-ink);
  padding:2px 8px; border-radius:999px; box-shadow:inset 0 0 0 1px var(--bs-gold); }
.bs-tcp-lad-head, .bs-tcp-lad-row { display:grid; grid-template-columns:1fr 64px 64px;
  gap:6px; align-items:center; padding:5px 11px; }
.bs-tcp-lad-head { font-size:8px; font-weight:900; letter-spacing:.13em; text-transform:uppercase;
  color:var(--bs-faint); background:rgba(0,0,0,.3); border-bottom:1px solid var(--bs-line); }
.bs-tcp-lad-head span + span, .bs-tcp-lad-row span + span { text-align:right; }
.bs-tcp-lad-row { font-size:12px; font-weight:700; color:var(--bs-muted);
  border-top:1px solid rgba(255,255,255,.03); transition:background .25s, color .25s; }
.bs-tcp-lad-name { color:var(--bs-text); min-width:0; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.bs-tcp-lad-odds { font-variant-numeric:tabular-nums; letter-spacing:.02em; }
/* The two adjacent rows that invert against five-card poker get a gold rule, so
   the eye lands on the pair the player is most likely to have backwards. */
.bs-tcp-lad-row.is-straight, .bs-tcp-lad-row.is-flush { box-shadow:inset 3px 0 0 var(--bs-gold); }
.bs-tcp-lad-row.is-hit { background:linear-gradient(90deg, rgba(var(--bs-gold-rgb),.16), transparent);
  color:var(--bs-gold-ink); }
.bs-tcp-lad-row.is-hit .bs-tcp-lad-name { color:var(--bs-gold-ink); }
.bs-tcp-lad-note { margin:0; padding:7px 11px 8px; border-top:1px solid var(--bs-line);
  background:rgba(0,0,0,.24); font-size:11px; line-height:1.5; color:var(--bs-gold-ink); }

/* ---- result -------------------------------------------------------------- */
.bs-tcp-msg { letter-spacing:.04em; }
.bs-tcp-outcome { position:relative; margin:12px 0 10px; padding:12px 14px 11px; text-align:center;
  border-radius:14px; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.012));
  animation:bs-tcp-outcome-in .46s cubic-bezier(.2,.9,.3,1.35) backwards; }
@keyframes bs-tcp-outcome-in { from { opacity:0; transform:translateY(10px) scale(.97); } to { opacity:1; transform:none; } }
.bs-tcp-outcome-tag { font-size:13px; font-weight:900; letter-spacing:.16em;
  text-transform:uppercase; color:var(--bs-muted); line-height:1.3; }
.bs-tcp-payout { display:block; margin:5px 0 1px; }
.bs-tcp-outcome-sub { font-size:13px; font-weight:700; color:var(--bs-text); margin-top:3px; }
.bs-tcp-outcome-win { border-color:var(--bs-pos); box-shadow:0 0 30px -12px var(--bs-pos); }
.bs-tcp-outcome-win .bs-tcp-outcome-tag { color:var(--bs-pos); }
.bs-tcp-outcome-lose .bs-tcp-outcome-tag { color:var(--bs-neg); }
.bs-tcp-outcome-fold .bs-tcp-outcome-tag { color:var(--bs-faint); }
.bs-tcp-outcome-push .bs-tcp-payout { color:var(--bs-muted); text-shadow:none; }

/* The honest per-leg ledger: what each bet staked, and what it gave back. */
.bs-tcp-break { margin:0 0 12px; border:1px solid var(--bs-line); border-radius:12px;
  overflow:hidden; background:rgba(0,0,0,.22); }
.bs-tcp-break-head, .bs-tcp-break-row { display:grid; grid-template-columns:1fr 84px 84px;
  gap:6px; padding:5px 11px; align-items:center; }
.bs-tcp-break-head { font-size:8px; font-weight:900; letter-spacing:.13em; text-transform:uppercase;
  color:var(--bs-faint); background:rgba(0,0,0,.3); border-bottom:1px solid var(--bs-line); }
.bs-tcp-break-head span + span, .bs-tcp-break-row span + span {
  text-align:right; font-variant-numeric:tabular-nums; }
.bs-tcp-break-row { font-size:12px; font-weight:800; color:var(--bs-text);
  border-top:1px solid rgba(255,255,255,.03); }
.bs-tcp-break-row.is-up span:last-child { color:var(--bs-pos); }
.bs-tcp-break-row.is-down span:last-child { color:var(--bs-neg); }

/* ---- controls ------------------------------------------------------------ */
.bs-tcp-actions { display:flex; gap:10px; justify-content:center; margin:0 0 4px; }
.bs-tcp-act { flex:1 1 0; min-width:0; max-width:200px; display:inline-flex; flex-direction:column;
  align-items:center; justify-content:center; gap:2px; padding:11px 10px 9px; line-height:1.1; }
.bs-tcp-act b { font-size:16px; font-weight:900; letter-spacing:.04em; }
.bs-tcp-act i { font-style:normal; font-size:10px; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; opacity:.75; font-variant-numeric:tabular-nums; }
.bs-tcp-act:disabled { opacity:.34; cursor:default; box-shadow:none; }
.bs-tcp-act:disabled:hover { filter:none; transform:none; }
.bs-btn-ghost.bs-tcp-act:disabled:hover { border-color:var(--bs-soft); color:var(--bs-text); }
.bs-tcp-note, .bs-tcp-risk { text-align:center; margin:6px 0 0; font-size:12px; line-height:1.45; }
.bs-tcp-deal { min-width:120px; font-weight:900; letter-spacing:.05em; }
.bs-tcp-ctrls { flex-wrap:wrap; }

@media (max-width:480px) {
  .bs-tcp-spot { max-width:none; }
  .bs-tcp-spot-amt { font-size:12px; }
  .bs-tcp-lad-head, .bs-tcp-lad-row { grid-template-columns:1fr 54px 54px; padding-left:9px; padding-right:9px; }
  .bs-tcp-break-head, .bs-tcp-break-row { grid-template-columns:1fr 70px 70px; padding-left:9px; padding-right:9px; }
}
@media (max-width:420px) {
  .bs-pcard-row.bs-tcp-row { gap:6px; }
  .bs-tcp-spots { gap:7px; }
  .bs-tcp-spot-name { font-size:7.5px; letter-spacing:.08em; }
  .bs-tcp-act b { font-size:14px; }
  .bs-tcp-act i { font-size:9px; letter-spacing:.04em; }
  .bs-tcp-outcome-tag { font-size:12px; letter-spacing:.11em; }
  .bs-tcp-lad-row, .bs-tcp-break-row { font-size:11.5px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-tcp-outcome { animation:none !important; }
  .bs-tcp-spot, .bs-tcp-lad-row, .bs-tcp-lad-sum::after { transition:none !important; }
}

/* ============================================================================
   CARIBBEAN STUD — the same cards, a completely different table. Where Three
   Card Poker prints circles, this prints two rectangular WAGER BOXES; where
   that game fans three cards, this lays out five in a straight rank with the
   dealer's single up card under a spotlight — the one piece of information the
   whole bet/fold decision turns on. Warm orange cloth against that table's
   gold, so the two are never mistaken for each other in the lobby.

   The Bet ladder here is the STANDARD five-card ranking: a flush beats a
   straight, the exact opposite of the three-card table above. Both tables
   print their own, precisely so the inversion cannot bite.
   ========================================================================== */
.bs-felt.bs-cs-felt { position:relative; padding:12px 12px 11px; }
.bs-cs-cloth { position:absolute; inset:0; border-radius:14px; overflow:hidden; pointer-events:none; }
.bs-cs-cloth::before { content:''; position:absolute; inset:0;
  background:radial-gradient(120% 84% at 50% -6%, var(--bs-orange), transparent 62%); opacity:.11; }
.bs-cs-cloth::after { content:''; position:absolute; inset:0;
  background:radial-gradient(106% 78% at 50% 44%, transparent 32%, rgba(0,0,0,.54) 100%); }
.bs-felt.bs-cs-felt.is-settled { box-shadow:inset 0 1px 0 rgba(255,255,255,.05),
  inset 0 -18px 34px rgba(0,0,0,.45), 0 0 34px -16px var(--bs-orange); }

.bs-cs-crest { position:relative; z-index:1; display:flex; align-items:center; gap:10px; margin:0 2px 8px; }
.bs-cs-crest i { flex:1; height:1px; background:linear-gradient(90deg, transparent, var(--bs-orange)); opacity:.35; }
.bs-cs-crest i:last-child { background:linear-gradient(90deg, var(--bs-orange), transparent); }
.bs-cs-crest span { flex:none; font-size:9px; font-weight:900; letter-spacing:.26em;
  text-transform:uppercase; color:var(--bs-orange); opacity:.82; }

/* ---- seats: five cards in a straight rank, no fan ------------------------ */
.bs-cs-seat { position:relative; z-index:1; }
.bs-cs-seat .bs-felt-label { min-height:26px; margin-bottom:5px; }
.bs-cs-tag { margin-right:auto; }
.bs-cs-row { position:relative; gap:7px; min-height:88px; flex-wrap:nowrap; }
.bs-cs-row .bs-bj-card > .bs-pcard { transform:none; }
.bs-cs-row .bs-pcard, .bs-cs-row .bs-pcard-slot { width:58px; height:82px; }
.bs-cs-row .bs-pcard-suit { font-size:25px; }
/* The dealer's up card: the one fact the decision is made on, so it is lit. */
.bs-cs-up > .bs-pcard { box-shadow:0 8px 20px rgba(0,0,0,.5),
  inset 0 0 0 1px rgba(0,0,0,.07), 0 0 0 2px var(--bs-orange), 0 0 22px -5px var(--bs-orange); }
.bs-cs-hole > .bs-pcard-back { opacity:.86; box-shadow:0 5px 14px rgba(0,0,0,.45),
  inset 0 0 0 3px rgba(255,255,255,.13); }
.bs-cs-shows { flex:none; font-size:9px; font-weight:900; letter-spacing:.13em;
  text-transform:uppercase; color:var(--bs-orange); opacity:.8; }

.bs-cs-rank { flex:none; padding:3px 10px; border-radius:999px; letter-spacing:.04em;
  font-size:10px; font-weight:900; text-transform:uppercase; color:var(--bs-muted);
  background:rgba(0,0,0,.3); box-shadow:inset 0 0 0 1px var(--bs-line); }
.bs-cs-rank-pay { color:var(--bs-gold-ink); box-shadow:inset 0 0 0 1px var(--bs-gold); }
.bs-cs-rank-nq { color:var(--bs-neg); box-shadow:inset 0 0 0 1px var(--bs-neg); }

.bs-cs-qual { position:relative; z-index:1; margin:9px 0 8px; text-align:center;
  font-size:9px; font-weight:900; letter-spacing:.15em; text-transform:uppercase;
  color:var(--bs-orange); opacity:.62; }
.bs-cs-qual.is-q { color:var(--bs-pos); opacity:1; }
.bs-cs-qual.is-nq { color:var(--bs-neg); opacity:1; }

/* ---- the two printed wager boxes ----------------------------------------- */
.bs-cs-boxes { position:relative; z-index:1; display:flex; gap:10px; margin:10px 0 0; }
.bs-cs-box { flex:1 1 0; min-width:0; display:flex; flex-direction:column; align-items:center;
  gap:2px; padding:8px 8px 7px; border-radius:10px; text-align:center;
  background:linear-gradient(180deg, rgba(255,255,255,.045), rgba(0,0,0,.3));
  box-shadow:inset 0 0 0 1px var(--bs-line), inset 0 1px 0 rgba(255,255,255,.05);
  transition:box-shadow .25s ease, opacity .25s ease, filter .25s ease; }
.bs-cs-box-name { font-size:8px; font-weight:900; letter-spacing:.2em;
  text-transform:uppercase; color:var(--bs-faint); }
.bs-cs-box-amt { font-size:15px; font-weight:900; color:var(--bs-text);
  font-variant-numeric:tabular-nums; line-height:1.15; overflow-wrap:anywhere; }
.bs-cs-box-note { font-size:9px; font-weight:800; letter-spacing:.1em;
  text-transform:uppercase; color:var(--bs-muted); }
.bs-cs-box-pay { font-size:11px; font-weight:900; color:var(--bs-pos); font-variant-numeric:tabular-nums; }
.bs-cs-box.is-pending { box-shadow:inset 0 0 0 1.5px var(--bs-orange), 0 0 24px -12px var(--bs-orange); }
.bs-cs-box.is-pending .bs-cs-box-amt { color:var(--bs-orange); }
.bs-cs-box.is-won { box-shadow:inset 0 0 0 1.5px var(--bs-pos), 0 0 26px -8px var(--bs-pos); }
.bs-cs-box.is-push { box-shadow:inset 0 0 0 1.5px var(--bs-soft); }
.bs-cs-box.is-lost { opacity:.42; filter:saturate(.45); }
.bs-cs-box.is-idle { opacity:.35; }

/* ---- the Bet ladder ------------------------------------------------------ */
.bs-cs-lad { margin:0 0 10px; border:1px solid var(--bs-line); border-radius:12px;
  overflow:hidden; background:linear-gradient(180deg, rgba(255,255,255,.03), rgba(0,0,0,.22)); }
.bs-cs-lad-sum { display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  padding:8px 11px; cursor:pointer; list-style:none; user-select:none;
  background:rgba(0,0,0,.26); }
.bs-cs-lad-sum::-webkit-details-marker { display:none; }
.bs-cs-lad-sum::after { content:'▾'; margin-left:auto; flex:none; font-size:11px;
  color:var(--bs-faint); transition:transform .2s ease; }
.bs-cs-lad[open] > .bs-cs-lad-sum::after { transform:rotate(180deg); }
.bs-cs-lad-sum-t { font-size:10px; font-weight:900; letter-spacing:.14em;
  text-transform:uppercase; color:var(--bs-text); }
/* Same badge, the OTHER colour and the OTHER sentence — the two tables must not
   be mistaken for one another at a glance. */
.bs-cs-lad-sum-k { font-size:10px; font-weight:900; letter-spacing:.08em;
  text-transform:uppercase; color:var(--bs-orange-br);
  padding:2px 8px; border-radius:999px; box-shadow:inset 0 0 0 1px var(--bs-orange); }
.bs-cs-lad-head, .bs-cs-lad-row { display:grid; grid-template-columns:1fr 60px 72px;
  gap:6px; align-items:center; padding:4px 11px; }
.bs-cs-lad-head { font-size:8px; font-weight:900; letter-spacing:.13em; text-transform:uppercase;
  color:var(--bs-faint); background:rgba(0,0,0,.3); border-bottom:1px solid var(--bs-line); }
.bs-cs-lad-head span + span, .bs-cs-lad-row span + span { text-align:right; }
.bs-cs-lad-row { font-size:12px; font-weight:700; color:var(--bs-muted);
  border-top:1px solid rgba(255,255,255,.03); transition:background .25s, color .25s; }
.bs-cs-lad-name { color:var(--bs-text); min-width:0; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.bs-cs-lad-odds, .bs-cs-lad-cash { font-variant-numeric:tabular-nums; letter-spacing:.02em; }
.bs-cs-lad-cash { color:var(--bs-gold-ink); }
/* The inverted pair, marked here too — in the OTHER order, on purpose. */
.bs-cs-lad-row.is-flush, .bs-cs-lad-row.is-straight { box-shadow:inset 3px 0 0 var(--bs-orange); }
.bs-cs-lad-row.is-hit { background:linear-gradient(90deg, rgba(255,138,0,.18), transparent);
  color:var(--bs-orange-br); }
.bs-cs-lad-row.is-hit .bs-cs-lad-name { color:var(--bs-orange-br); }
.bs-cs-lad-note { margin:0; padding:7px 11px 8px; border-top:1px solid var(--bs-line);
  background:rgba(0,0,0,.24); font-size:11px; line-height:1.5; color:var(--bs-orange-br); }

/* ---- result -------------------------------------------------------------- */
.bs-cs-msg { letter-spacing:.04em; }
.bs-cs-outcome { position:relative; margin:12px 0 10px; padding:12px 14px 11px; text-align:center;
  border-radius:14px; border:1px solid var(--bs-line);
  background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.012));
  animation:bs-cs-outcome-in .46s cubic-bezier(.2,.9,.3,1.35) backwards; }
@keyframes bs-cs-outcome-in { from { opacity:0; transform:translateY(10px) scale(.97); } to { opacity:1; transform:none; } }
.bs-cs-outcome-tag { font-size:13px; font-weight:900; letter-spacing:.16em;
  text-transform:uppercase; color:var(--bs-muted); line-height:1.3; }
.bs-cs-payout { display:block; margin:5px 0 1px; }
.bs-cs-outcome-sub { font-size:13px; font-weight:700; color:var(--bs-text); margin-top:3px; }
.bs-cs-outcome-mult { margin-top:6px; font-size:10px; font-weight:900; letter-spacing:.12em;
  text-transform:uppercase; color:var(--bs-gold-ink); }
.bs-cs-outcome-win { border-color:var(--bs-pos); box-shadow:0 0 30px -12px var(--bs-pos); }
.bs-cs-outcome-win .bs-cs-outcome-tag { color:var(--bs-pos); }
.bs-cs-outcome-lose .bs-cs-outcome-tag { color:var(--bs-neg); }
.bs-cs-outcome-push .bs-cs-payout { color:var(--bs-muted); text-shadow:none; }

/* ---- controls ------------------------------------------------------------ */
.bs-cs-actions { display:flex; gap:10px; justify-content:center; margin:0 0 4px; }
.bs-cs-act { flex:1 1 0; min-width:0; max-width:200px; display:inline-flex; flex-direction:column;
  align-items:center; justify-content:center; gap:2px; padding:11px 10px 9px; line-height:1.1; }
.bs-cs-act b { font-size:16px; font-weight:900; letter-spacing:.04em; }
.bs-cs-act i { font-style:normal; font-size:10px; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; opacity:.75; font-variant-numeric:tabular-nums; }
.bs-cs-act:disabled { opacity:.34; cursor:default; box-shadow:none; }
.bs-cs-act:disabled:hover { filter:none; transform:none; }
.bs-btn-ghost.bs-cs-act:disabled:hover { border-color:var(--bs-soft); color:var(--bs-text); }
.bs-cs-note, .bs-cs-risk { text-align:center; margin:6px 0 0; font-size:12px; line-height:1.45; }
.bs-cs-deal { min-width:120px; font-weight:900; letter-spacing:.05em; }
.bs-cs-ctrls { flex-wrap:wrap; }

/* Five 58px cards + four 7px gaps need 318px of row. Below that the cards
   shrink rather than the row wrapping — a stud hand read across two lines is
   not a stud hand. */
@media (max-width:480px) {
  /* `.bs-pcard-row.bs-cs-row` rather than `.bs-cs-row`: the shared
     `.bs-felt .bs-pcard-row { gap:6px }` at 430px is a two-class selector and
     would otherwise win the tie and widen this row again. */
  .bs-pcard-row.bs-cs-row { gap:5px; }
  .bs-cs-row .bs-pcard, .bs-cs-row .bs-pcard-slot { width:52px; height:74px; }
  .bs-cs-row .bs-pcard-suit { font-size:22px; }
  .bs-cs-row .bs-pcard-corner { font-size:10px; }
  .bs-cs-lad-head, .bs-cs-lad-row { grid-template-columns:1fr 52px 64px; padding-left:9px; padding-right:9px; }
}
@media (max-width:420px) {
  .bs-pcard-row.bs-cs-row { gap:4px; }
  .bs-cs-row .bs-pcard, .bs-cs-row .bs-pcard-slot { width:47px; height:67px; }
  .bs-cs-row .bs-pcard-suit { font-size:19px; }
  .bs-cs-row .bs-pcard-tl { top:4px; left:4px; }
  .bs-cs-row .bs-pcard-br { bottom:4px; right:4px; }
  .bs-cs-act b { font-size:14px; }
  .bs-cs-act i { font-size:9px; letter-spacing:.04em; }
  .bs-cs-outcome-tag { font-size:12px; letter-spacing:.11em; }
  .bs-cs-lad-row { font-size:11.5px; }
  .bs-cs-box-amt { font-size:14px; }
}
/* iPhone SE / 320px. Five cards at 47px land on EXACTLY the 251px of row a
   320px handset leaves — zero slack, which one font substitution or one step
   of text zoom would turn into an overflow. Buy 20px of margin instead. */
@media (max-width:360px) {
  .bs-cs-row .bs-pcard, .bs-cs-row .bs-pcard-slot { width:43px; height:61px; }
  .bs-cs-row .bs-pcard-suit { font-size:17px; }
  .bs-cs-row .bs-pcard-corner { font-size:9px; }
  .bs-cs-row { min-height:61px; }
}

@media (prefers-reduced-motion: reduce) {
  .bs-cs-outcome { animation:none !important; }
  .bs-cs-box, .bs-cs-lad-row, .bs-cs-lad-sum::after { transition:none !important; }
}

/* ============================================================================
   ACCESSIBILITY — keyboard operability and focus visibility.

   Additive only: no colour, size or layout of any existing element changes.
   Everything here either makes an existing control reachable/visible to a
   keyboard user, or keeps a purely decorative layer out of their way.
   ========================================================================== */

/* The polite live region that announces each settled round (bsAnnounce).
   .bs-sr-only already hides it; this just pins it out of any stacking context
   so it can never be caught by an ancestor's overflow or transform. */
.bs-live-region { position: fixed !important; top: 0; left: 0; }

/* ---- focus inside clipped containers ------------------------------------
   The felt grids, the ticket and the reel window all clip their children
   (overflow:hidden / border-radius), which would slice an outside-drawn ring in
   half. Draw it INSIDE the control instead — same ring, still unmistakable. */
.bs-rw-cell:focus-visible,
.bs-sicbo-cell:focus-visible,
.bs-keno-num:focus-visible,
.bs-mines-tile:focus-visible,
.bs-scratch-panel:focus-visible,
.bs-rw-rchip:focus-visible,
.bs-bac-denom:focus-visible,
.bs-bac-spot:focus-visible,
.bs-craps-line:focus-visible {
  outline-offset: -3px;
  box-shadow: inset 0 0 0 2px var(--bs-panel);
}

/* ---- cards as controls ---------------------------------------------------
   A playing card is a <div>, so it cannot be a <button> without wrecking the
   3D flip and fan geometry. Where JS gives one role="button" + tabindex it is a
   real control, and must look and behave like one. */
.bs-pcard[role="button"],
.bs-chin-pile[role="button"],
.bs-note[role="button"] {
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
/* The fan overlaps its cards, so the focused one has to come to the front or
   its ring is buried under the next card along. The :has() rule lifts the whole
   slot where supported; the plain one is the fallback and is harmless either
   way (both only ever apply while a card actually has keyboard focus). */
.bs-chin-fan .bs-pcard:focus-visible { z-index: 60; }
.bs-chin-slot:has(.bs-pcard:focus-visible) { z-index: 60; }

/* The Dice target handle is a slider the player can now drive with the arrow
   keys; it sits on top of the coloured track, so it gets the inset treatment. */
.bs-dice-handle:focus-visible { outline-offset: 1px; z-index: 8; }

/* ---- the scratch foil ---------------------------------------------------
   The canvas is aria-hidden decoration painted over its own button. Enter or
   Space on the panel underneath is the keyboard equivalent of dragging the foil
   off; once the panel is spent, the foil must stop swallowing pointer events. */
.bs-scratch-panel:disabled canvas { pointer-events: none; }

/* ---- modal dialogs -------------------------------------------------------
   bsWireDialog() moves focus onto the dialog box itself so its name and role
   are announced. That is a programmatic focus, so :focus-visible does not
   match it and no ring is drawn — but Safari still paints a default outline on
   a tabindex="-1" target, so suppress exactly that case. */
.bs-overlay-card:focus:not(:focus-visible) { outline: none; }

/* ---- Windows High Contrast / forced colours -----------------------------
   In forced-colours mode the brand palette is discarded, so the ring has to be
   asked for by name or a keyboard user loses it entirely. */
@media (forced-colors: active) {
  .betsystem-widget :focus-visible,
  .bs-hero :focus-visible,
  .bs-overlay :focus-visible {
    outline: 3px solid Highlight;
    box-shadow: none;
  }
}

/* ---- SHARED CRASH ---------------------------------------------------------
   The auto-rolling table. Everything here is chrome AROUND the stage: the
   stage, curve, rocket and explosion are the existing .bs-crash-* rules, reused
   unchanged so all ten Elementor skin presets keep working with no new tokens.

   Three things this table has that the private crash cannot:
     - a variant strip, because eleven titles share this screen and their terms
       genuinely differ (a guaranteed floor, a scaled payout, a hard minimum);
     - a roster, because other people are on this round;
     - a "would now be" line, because the curve keeps climbing after you are out.
   -------------------------------------------------------------------------- */

.bs-scrash-stage { margin-bottom: var(--bs-sp-2); }

/* ---- variant terms ------------------------------------------------------- */
.bs-scrash-variant { margin: 0 0 var(--bs-sp-2); }
.bs-scrash-blurb {
  margin: 0 0 6px; font-size: var(--bs-t-sm); line-height: 1.45; color: var(--bs-muted);
}
.bs-scrash-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.bs-scrash-chip {
  display: inline-flex; align-items: center; padding: 3px 8px; border-radius: 999px;
  border: 1px solid var(--bs-line); background: var(--bs-elev);
  font-size: var(--bs-t-2xs); font-weight: 700; font-style: normal; color: var(--bs-muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* A term in the player's favour (a floor, a refund) reads differently from one
   against them (a scaled payout, a hard minimum). Colour carries that, and the
   words say it too -- colour alone would be invisible to a third of players. */
.bs-scrash-chip.is-good { border-color: var(--bs-pos); color: var(--bs-pos); }
.bs-scrash-chip.is-warn { border-color: var(--bs-gold); color: var(--bs-gold-ink); }

.bs-scrash-round {
  margin-left: auto; font-size: var(--bs-t-2xs); font-weight: 800; letter-spacing: .08em;
  color: var(--bs-faint); font-variant-numeric: tabular-nums;
}

/* ---- controls ------------------------------------------------------------ */
.bs-scrash-ctrls { margin: 0 0 var(--bs-sp-2); }
.bs-scrash-form { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-items: end; }
.bs-scrash-form .bs-btn { grid-column: 1 / -1; }
.bs-scrash-f {
  display: flex; flex-direction: column; gap: 4px;
  font-size: var(--bs-t-2xs); font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--bs-faint);
}
.bs-scrash-f input {
  width: 100%; padding: 9px 10px; border-radius: 10px;
  border: 1px solid var(--bs-line); background: var(--bs-bg); color: var(--bs-text);
  font: inherit; font-size: var(--bs-t-md); font-variant-numeric: tabular-nums;
}
.bs-scrash-f input:focus-visible { outline: 2px solid var(--bs-orange); outline-offset: 1px; }

.bs-scrash-wait {
  grid-column: 1 / -1; text-align: center; font-size: var(--bs-t-2xs);
  font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--bs-faint);
}
.bs-scrash-wait b { color: var(--bs-text); font-variant-numeric: tabular-nums; }

.bs-scrash-mine, .bs-scrash-banked, .bs-scrash-locked, .bs-scrash-watch {
  padding: 11px 14px; border-radius: 12px; text-align: center;
  border: 1px solid var(--bs-line); background: var(--bs-elev);
}
.bs-scrash-banked { border-color: var(--bs-gold); }
.bs-scrash-mine-l {
  font-size: var(--bs-t-2xs); font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: var(--bs-faint);
}
.bs-scrash-mine-v {
  font-size: var(--bs-t-lg); font-weight: 900; color: var(--bs-text);
  font-variant-numeric: tabular-nums; line-height: 1.2;
}
.bs-scrash-banked .bs-scrash-mine-v { color: var(--bs-gold-ink); }
.bs-scrash-locked, .bs-scrash-watch {
  font-size: var(--bs-t-sm); color: var(--bs-muted); line-height: 1.4;
}

/* The Cash Out button on a variant that refuses cash-outs below a floor.
   Disabled AND legible: it still shows what the round is worth, so the player
   can see the gate open rather than wonder why the button is dead. */
.bs-crash-cash.is-gated {
  opacity: 1; background: var(--bs-elev); color: var(--bs-faint);
  border: 1px dashed var(--bs-line); box-shadow: none; cursor: not-allowed;
}
.bs-crash-cash.is-gated .bs-crash-cash-amt { color: var(--bs-muted); }

/* The penalty bank button sits on its own rather than inside .bs-slot-ctrls,
   so it needs the stacked label/amount/profit layout stating explicitly. */
.bs-pen-bank {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  width: 100%; line-height: 1.15; padding: 9px 14px 10px;
}
.bs-pen-hint { text-align: center; }

/* ---- the roster ---------------------------------------------------------- */
.bs-scrash-roster {
  margin: 0 0 var(--bs-sp-2); border: 1px solid var(--bs-line); border-radius: 12px;
  background: var(--bs-panel); overflow: hidden;
}
.bs-scrash-roster-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 7px 11px; border-bottom: 1px solid var(--bs-line); background: var(--bs-elev);
  font-size: var(--bs-t-2xs); font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
}
.bs-scrash-roster-head b { color: var(--bs-text); }
.bs-scrash-roster-head span { color: var(--bs-faint); font-variant-numeric: tabular-nums; }

/* Capped and scrollable: a busy round can carry fifty names and the stage must
   not be pushed off the screen by them. */
.bs-scrash-rows { max-height: 168px; overflow-y: auto; }
.bs-scrash-empty {
  padding: 14px 11px; text-align: center; font-size: var(--bs-t-sm); color: var(--bs-faint);
}
.bs-scrash-row {
  display: flex; align-items: center; gap: 8px; padding: 6px 11px;
  border-bottom: 1px solid var(--bs-line); font-size: var(--bs-t-sm);
}
.bs-scrash-row:last-child { border-bottom: 0; }
.bs-scrash-who {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--bs-muted);
}
.bs-scrash-right { display: flex; align-items: baseline; gap: 7px; flex: 0 0 auto; }
.bs-scrash-mult { font-weight: 900; font-variant-numeric: tabular-nums; color: var(--bs-text); }
.bs-scrash-win { font-size: var(--bs-t-2xs); color: var(--bs-faint); font-variant-numeric: tabular-nums; }

.bs-scrash-row.is-out .bs-scrash-mult { color: var(--bs-pos); }
.bs-scrash-row.is-out .bs-scrash-win { color: var(--bs-pos); }
.bs-scrash-row.is-lost { opacity: .58; }
.bs-scrash-row.is-lost .bs-scrash-mult { color: var(--bs-neg); }

/* Somebody still holding on. This pulses only while a round is in flight --
   once it is over nothing on screen should still look live. */
.bs-scrash-holding {
  font-size: var(--bs-t-2xs); font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--bs-gold-ink);
}
.bs-crash-flying .bs-scrash-holding { animation: bs-scrash-hold 1.15s ease-in-out infinite; }
@keyframes bs-scrash-hold { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

.bs-scrash-auto {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  min-width: 15px; height: 15px; padding: 0 4px; border-radius: 4px;
  background: var(--bs-elev2); color: var(--bs-faint);
  font-size: 9px; font-weight: 900; font-style: normal; letter-spacing: .04em;
}

@media (prefers-reduced-motion: reduce) {
  .bs-crash-flying .bs-scrash-holding { animation: none; }
}

@media (max-width: 420px) {
  .bs-scrash-form { grid-template-columns: 1fr; }
  .bs-scrash-rows { max-height: 132px; }
}

/* ---- BLACKJACK: the rest of the ruleset ----------------------------------
   Double, split, surrender and the insurance offer. The server has always
   allowed them; these are the controls that were missing, plus the split
   strip that shows the hands you are not currently playing.
   ------------------------------------------------------------------------ */

/* The secondary action row sits under Hit/Stand: smaller, quieter, and only
   rendered for the actions the SERVER says are legal on this hand. */
.bs-bj-actions-2 { margin-top: 6px; }
.bs-bj-act-sm { padding: 7px 10px; }
.bs-bj-act-sm b { font-size: var(--bs-t-sm); }
.bs-bj-act-sm i { font-size: 10px; }

/* The insurance offer. Decline is the LEFT and visually primary control
   because declining is what optimal play does, and the note says so -- a
   casino UI that nudges toward the losing side bet is one a regulator reads
   as a dark pattern. */
.bs-bj-ins { grid-template-columns: 1fr 1fr; }
.bs-bj-ins [data-noins] { border-color: var(--bs-pos); }

/* The split strip: every hand at once, with the live one lit. */
.bs-bj-hands {
  display: flex; flex-direction: column; gap: 4px; margin: 0 0 8px;
}
.bs-bj-hand {
  display: flex; align-items: center; gap: 8px; padding: 6px 10px;
  border: 1px solid var(--bs-line); border-radius: 10px; background: var(--bs-elev);
  font-size: var(--bs-t-sm);
}
.bs-bj-hand.is-active { border-color: var(--bs-orange); background: var(--bs-elev2); }
.bs-bj-hand.is-bust { opacity: .55; border-color: var(--bs-neg); }
.bs-bj-hand.is-done { opacity: .55; }
.bs-bj-hand-n {
  flex: 0 0 auto; font-size: var(--bs-t-2xs); font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--bs-faint);
}
.bs-bj-hand.is-active .bs-bj-hand-n { color: var(--bs-orange); }
.bs-bj-hand-cards { flex: 1 1 auto; display: flex; gap: 3px; min-width: 0; flex-wrap: wrap; }
.bs-bj-hand-total { flex: 0 0 auto; font-weight: 900; font-variant-numeric: tabular-nums; }
.bs-bj-hand-stake {
  flex: 0 0 auto; font-size: var(--bs-t-2xs); color: var(--bs-faint);
  font-variant-numeric: tabular-nums;
}

/* A miniature card face for the strip. Real card colour, so a red suit reads
   as red on every skin including the light one. */
.bs-bj-glyph {
  display: inline-flex; align-items: center; padding: 1px 5px; border-radius: 4px;
  background: #f6f7fa; color: #14181f; font-style: normal;
  font-size: var(--bs-t-2xs); font-weight: 800; line-height: 1.5;
}
.bs-bj-glyph.is-red { color: #c62129; }

@media (max-width: 420px) {
  .bs-bj-actions-2 { grid-template-columns: 1fr 1fr; }
  .bs-bj-act-sm i { display: none; }
}

/* ---- PENALTY SHOOTOUT -----------------------------------------------------
   A goalmouth, a keeper who moves to where he dived, and six corners priced by
   the server. The corner buttons carry a "read" bar showing how heavily the
   keeper is favouring them — the mechanic that makes this game different is
   visible rather than hidden, which is the point.
   -------------------------------------------------------------------------- */

.bs-pen-pitch {
  position: relative; aspect-ratio: 16 / 11; margin: 0 0 var(--bs-sp-2);
  border-radius: 14px; overflow: hidden; border: 1px solid var(--bs-line);
  background:
    radial-gradient(ellipse at 50% 120%, rgba(255,255,255,.10), transparent 55%),
    linear-gradient(180deg, #0d2a17 0%, #123a20 45%, #0c2a17 100%);
  background-color: #103218;
}
/* The turf: mown stripes, kept subtle so the goal reads first. */
.bs-pen-pitch::after {
  content: ''; position: absolute; inset: 55% 0 0; pointer-events: none;
  background: repeating-linear-gradient(90deg, rgba(255,255,255,.045) 0 12%, transparent 12% 24%);
}
.bs-pen-crowd {
  position: absolute; inset: 0 0 62% 0;
  background:
    repeating-linear-gradient(90deg, rgba(255,255,255,.07) 0 3px, transparent 3px 7px),
    linear-gradient(180deg, #0b1220, #14202f);
  opacity: .8;
}

.bs-pen-goal { position: absolute; inset: 14% 8% 8% 8%; }
.bs-pen-net {
  position: absolute; inset: 0; border-radius: 2px;
  background:
    repeating-linear-gradient(90deg, rgba(255,255,255,.16) 0 1px, transparent 1px 9px),
    repeating-linear-gradient(0deg, rgba(255,255,255,.16) 0 1px, transparent 1px 9px),
    rgba(0,0,0,.30);
}
.bs-pen-post, .bs-pen-bar { position: absolute; background: #f2f5f8; border-radius: 3px; }
.bs-pen-post { top: 0; bottom: 0; width: 5px; }
.bs-pen-post-l { left: -5px; }
.bs-pen-post-r { right: -5px; }
.bs-pen-bar { left: -5px; right: -5px; top: -5px; height: 5px; }

.bs-pen-keeper {
  position: absolute; transform: translate(-50%, -50%);
  transition: left .42s cubic-bezier(.22,1.2,.36,1), top .42s cubic-bezier(.22,1.2,.36,1);
  color: var(--bs-orange);
}
.bs-pen-k-head, .bs-pen-k-body, .bs-pen-k-leg { fill: #1d2733; }
.bs-pen-k-body { fill: var(--bs-orange); }
.bs-pen-k-arm { fill: var(--bs-orange-dp); }
.bs-pen-k-glove { fill: #f2f5f8; }

.bs-pen-ball {
  position: absolute; width: 13px; height: 13px; margin: -6px 0 0 -6px; border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, #ffffff, #c8ced6);
  box-shadow: 0 2px 7px rgba(0,0,0,.55);
  transition: left .30s cubic-bezier(.4,0,.2,1), top .30s cubic-bezier(.4,0,.2,1);
}
.bs-pen-ball-spot { opacity: .75; }

.bs-pen-shout {
  position: absolute; left: 50%; top: 40%; transform: translate(-50%, -50%);
  font-size: clamp(20px, 7vw, 34px); font-weight: 900; letter-spacing: .04em;
  color: var(--bs-pos); text-shadow: 0 3px 14px rgba(0,0,0,.6);
  animation: bs-pen-shout .5s cubic-bezier(.2,1.4,.3,1) both;
}
.bs-pen-shout.is-bad { color: var(--bs-neg); }
@keyframes bs-pen-shout { from { opacity: 0; transform: translate(-50%,-50%) scale(.6); } }

.bs-pen-hud { position: absolute; left: 10px; right: 10px; top: 8px; display: flex; justify-content: space-between; gap: 8px; }
.bs-pen-mult { position: absolute; left: 50%; bottom: 6px; transform: translateX(-50%); }

/* ---- the six corners ---- */
.bs-pen-board {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: 0 0 var(--bs-sp-2);
}
.bs-pen-zone {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 9px 6px 12px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--bs-line); background: var(--bs-elev); color: var(--bs-text);
  font: inherit; transition: border-color .15s ease, background .15s ease, transform .06s ease;
}
.bs-pen-zone:hover:not(:disabled) { border-color: var(--bs-orange); background: var(--bs-elev2); }
.bs-pen-zone:active:not(:disabled) { transform: translateY(1px); }
.bs-pen-zone:focus-visible { outline: 2px solid var(--bs-orange); outline-offset: 2px; }
.bs-pen-zone:disabled { opacity: .55; cursor: default; }
/* The keeper is favouring this corner: warn, but never disable — it is still a
   legal shot and it pays more precisely because it is worse. */
.bs-pen-zone.is-read { border-color: var(--bs-gold); }

.bs-pen-zone-x { font-size: var(--bs-t-md); font-weight: 900; font-variant-numeric: tabular-nums; }
.bs-pen-zone-p { font-size: var(--bs-t-2xs); color: var(--bs-faint); font-variant-numeric: tabular-nums; }
/* The read bar, straight off the server's keeper_read. */
.bs-pen-zone-read {
  position: absolute; left: 8px; right: 8px; bottom: 5px; height: 3px; border-radius: 2px;
  background: var(--bs-line); overflow: hidden;
}
.bs-pen-zone-read::after {
  content: ''; position: absolute; inset: 0 auto 0 0; border-radius: 2px;
  width: calc(var(--bs-pen-lean, 0) * 100%);
  background: var(--bs-gold); transition: width .3s ease;
}
.bs-pen-zone-n {
  position: absolute; top: 4px; right: 5px; min-width: 14px; height: 14px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 4px; background: var(--bs-elev2); color: var(--bs-faint);
  font-size: 9px; font-weight: 900; text-decoration: none;
}
.bs-pen-hint { text-align: center; }

@media (prefers-reduced-motion: reduce) {
  .bs-pen-keeper, .bs-pen-ball { transition: none; }
  .bs-pen-shout { animation: none; }
}

/* The "Step up" button. Inherits .bs-btn; this only gives it the width and the
   weight the moment deserves. */
.bs-pen-start { width: 100%; font-size: var(--bs-t-md); font-weight: 800; letter-spacing: .02em; }

/* ---- FIVE-REEL, TWENTY-LINE SLOT ------------------------------------------
   A 5x3 grid. The winning cells light up, and because a spin can win on several
   of twenty lines at once, the wins list below is tappable — each row lights
   only its own line, so a player can see exactly what they were paid for.
   -------------------------------------------------------------------------- */

.bs-fr-grid {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 4px;
  padding: 8px; margin: 0 0 var(--bs-sp-2); border-radius: 14px;
  border: 1px solid var(--bs-line);
  background: linear-gradient(180deg, var(--bs-elev), var(--bs-panel));
  box-shadow: inset 0 2px 10px rgba(0,0,0,.35);
}
/* Free spins: the whole cabinet changes colour, so there is never a doubt about
   whether the spin costs anything. */
.bs-fr-grid.is-free { border-color: var(--bs-gold); box-shadow: inset 0 2px 10px rgba(0,0,0,.35), 0 0 0 1px var(--bs-gold); }

.bs-fr-reel { display: flex; flex-direction: column; gap: 4px; }
.bs-fr-reel.is-spinning .bs-fr-cell { animation: bs-fr-spin .28s linear infinite; animation-delay: var(--bs-fr-d, 0ms); }
@keyframes bs-fr-spin { 0% { transform: translateY(-6%); opacity: .55; } 100% { transform: translateY(6%); opacity: 1; } }

.bs-fr-cell {
  aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
  border-radius: 8px; border: 1px solid var(--bs-line); background: var(--bs-bg);
  transition: border-color .2s ease, background .2s ease, transform .2s ease;
}
.bs-fr-sym { font-size: clamp(16px, 5.2vw, 27px); line-height: 1; }
.bs-fr-cell.is-lit {
  border-color: var(--bs-orange); background: var(--bs-elev2);
  transform: scale(1.05); box-shadow: 0 0 12px rgba(255,138,0,.35);
}
.bs-fr-cell.is-wild { border-color: var(--bs-gold); }
.bs-fr-cell.is-scatter { border-color: var(--bs-pos); }

.bs-fr-banner {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 9px 12px; margin: 0 0 var(--bs-sp-2); border-radius: 12px; text-align: center;
  border: 1px solid var(--bs-gold); background: var(--bs-elev);
}
.bs-fr-banner b { color: var(--bs-gold-ink); font-size: var(--bs-t-md); }
.bs-fr-banner span { font-size: var(--bs-t-2xs); color: var(--bs-faint); }

.bs-fr-wins { display: flex; flex-direction: column; gap: 3px; margin: 0 0 var(--bs-sp-2); }
.bs-fr-win {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 5px 10px;
  border-radius: 8px; border: 1px solid var(--bs-line); background: var(--bs-elev);
  color: var(--bs-text); font: inherit; font-size: var(--bs-t-sm); cursor: pointer;
  text-align: left;
}
.bs-fr-win:hover { border-color: var(--bs-orange); }
.bs-fr-win.is-on { border-color: var(--bs-orange); background: var(--bs-elev2); }
.bs-fr-win:focus-visible { outline: 2px solid var(--bs-orange); outline-offset: 1px; }
.bs-fr-win-n { flex: 0 0 auto; font-size: var(--bs-t-2xs); color: var(--bs-faint); text-transform: uppercase; letter-spacing: .06em; font-weight: 800; }
.bs-fr-win-s { flex: 1 1 auto; }
.bs-fr-win-p { flex: 0 0 auto; font-weight: 900; color: var(--bs-pos); font-variant-numeric: tabular-nums; }
.bs-fr-more { text-align: center; font-size: var(--bs-t-2xs); color: var(--bs-faint); }

.bs-fr-ctrls { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-items: end; }
.bs-fr-stake { display: flex; flex-direction: column; gap: 4px; font-size: var(--bs-t-2xs); font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--bs-faint); }
.bs-fr-stake input { width: 100%; padding: 9px 10px; border-radius: 10px; border: 1px solid var(--bs-line); background: var(--bs-bg); color: var(--bs-text); font: inherit; font-size: var(--bs-t-md); font-variant-numeric: tabular-nums; }
.bs-fr-stake input:focus-visible { outline: 2px solid var(--bs-orange); outline-offset: 1px; }
.bs-fr-spin { width: 100%; font-weight: 800; }
.bs-fr-perline { grid-column: 1 / -1; text-align: center; }

.bs-fr-pay { margin-top: var(--bs-sp-2); }
.bs-fr-pay summary { cursor: pointer; font-size: var(--bs-t-sm); color: var(--bs-muted); }
.bs-fr-table { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: var(--bs-t-sm); }
.bs-fr-table th, .bs-fr-table td { padding: 3px 6px; text-align: right; font-variant-numeric: tabular-nums; }
.bs-fr-table th { color: var(--bs-faint); font-size: var(--bs-t-2xs); }
.bs-fr-table td:first-child, .bs-fr-table th:first-child { text-align: left; font-size: var(--bs-t-md); }
.bs-fr-table tbody tr:nth-child(odd) { background: rgba(255,255,255,.03); }

@media (prefers-reduced-motion: reduce) {
  .bs-fr-reel.is-spinning .bs-fr-cell { animation: none; }
  .bs-fr-cell { transition: none; }
}

/* ---- BREAK BUILDER (snooker) ----------------------------------------------
   The break score sits in the middle of the baize, because it IS the
   multiplier — a^break. Everything else on this screen is in service of that
   one number being legible.
   -------------------------------------------------------------------------- */

.bs-snk-table {
  position: relative; aspect-ratio: 16 / 10; margin: 0 0 var(--bs-sp-2);
  border-radius: 14px; overflow: hidden;
  border: 6px solid #4a2f18;          /* the cushion rail, a real material */
  box-shadow: inset 0 0 40px rgba(0,0,0,.55), 0 10px 26px rgba(0,0,0,.35);
}
.bs-snk-baize {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse at 50% 40%, rgba(255,255,255,.10), transparent 62%),
    linear-gradient(180deg, #14663a, #0e4a2a);
}
/* The pockets. Six of them, which is the whole point of the shape. */
.bs-snk-baize::before, .bs-snk-baize::after {
  content: ''; position: absolute; width: 20px; height: 20px; border-radius: 50%;
  background: #06120b; box-shadow: 0 0 0 2px rgba(0,0,0,.5);
}
.bs-snk-baize::before { top: -6px; left: -6px; box-shadow: 0 0 0 2px rgba(0,0,0,.5), 0 0 0 0 transparent; }
.bs-snk-baize::after { bottom: -6px; right: -6px; }

.bs-snk-hud { position: absolute; left: 10px; right: 10px; top: 8px; display: flex; justify-content: space-between; gap: 8px; z-index: 2; }

.bs-snk-break {
  position: absolute; left: 50%; top: 46%; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; line-height: 1; z-index: 1;
}
.bs-snk-break-n {
  font-size: clamp(44px, 15vw, 82px); font-weight: 900; color: #ffffff;
  font-variant-numeric: tabular-nums; text-shadow: 0 4px 20px rgba(0,0,0,.6);
}
.bs-snk-break-l {
  font-size: var(--bs-t-2xs); font-weight: 800; letter-spacing: .22em;
  color: rgba(255,255,255,.55); margin-top: 2px;
}
/* Fifty and a century are the two numbers a snooker crowd reacts to. */
.bs-snk-table.is-fifty .bs-snk-break-n { color: var(--bs-gold-ink); }
.bs-snk-table.is-century .bs-snk-break-n { color: var(--bs-gold-ink); text-shadow: 0 0 26px var(--bs-gold); }

.bs-snk-mult {
  position: absolute; left: 50%; bottom: 30%; transform: translateX(-50%);
  font-size: var(--bs-t-lg); font-weight: 800; color: rgba(255,255,255,.82);
  font-variant-numeric: tabular-nums; z-index: 1;
}

.bs-snk-shout {
  position: absolute; left: 50%; top: 18%; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 6px;
  font-size: clamp(15px, 4.6vw, 22px); font-weight: 900; letter-spacing: .06em;
  color: var(--bs-pos); text-shadow: 0 2px 12px rgba(0,0,0,.6); z-index: 2;
  animation: bs-snk-shout .42s cubic-bezier(.2,1.4,.3,1) both;
}
.bs-snk-shout.is-bad { color: var(--bs-neg); }
@keyframes bs-snk-shout { from { opacity: 0; transform: translateX(-50%) scale(.7); } }

.bs-snk-potted {
  position: absolute; left: 8px; right: 8px; bottom: 7px; z-index: 2;
  display: flex; flex-wrap: wrap; gap: 3px; justify-content: center; align-items: center;
}
.bs-snk-more { font-size: 9px; font-weight: 800; color: rgba(255,255,255,.6); font-style: normal; }

/* ---- the shots on offer ---- */
.bs-snk-shots { display: grid; grid-template-columns: repeat(6, 1fr); gap: 5px; margin: 0 0 6px; }
/* A forced shot is ONE button, full width — the screen must never look like a
   menu where snooker gives no choice. */
.bs-snk-shots.is-forced { grid-template-columns: 1fr; }
.bs-snk-shot {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 8px 4px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--bs-line); background: var(--bs-elev); color: var(--bs-text);
  font: inherit; transition: border-color .15s ease, background .15s ease, transform .06s ease;
}
.bs-snk-shots.is-forced .bs-snk-shot { flex-direction: row; justify-content: center; gap: 10px; padding: 11px; }
.bs-snk-shot:hover:not(:disabled) { border-color: var(--bs-orange); background: var(--bs-elev2); }
.bs-snk-shot:active:not(:disabled) { transform: translateY(1px); }
.bs-snk-shot:focus-visible { outline: 2px solid var(--bs-orange); outline-offset: 2px; }
.bs-snk-shot:disabled { opacity: .55; cursor: default; }
.bs-snk-ball { display: block; }
.bs-snk-shot-v { font-size: var(--bs-t-sm); font-weight: 900; font-variant-numeric: tabular-nums; }
.bs-snk-shot-p { font-size: 9px; color: var(--bs-faint); font-variant-numeric: tabular-nums; }
.bs-snk-shot-x { font-size: var(--bs-t-2xs); font-weight: 800; color: var(--bs-gold-ink); font-variant-numeric: tabular-nums; }
.bs-snk-hint { text-align: center; margin-bottom: var(--bs-sp-2); }
.bs-snk-start { width: 100%; font-weight: 800; }

@media (prefers-reduced-motion: reduce) {
  .bs-snk-shout { animation: none; }
}
@media (max-width: 380px) {
  .bs-snk-shots { grid-template-columns: repeat(3, 1fr); }
  .bs-snk-shot-p { display: none; }
}

/* ---- THE DECLARATION (cricket) --------------------------------------------
   Two acts on one screen. Act one is your innings; act two adds a second
   scoreboard and the chase plays out ball by ball while you watch.
   -------------------------------------------------------------------------- */

.bs-ckt-board {
  position: relative; display: flex; gap: 8px; align-items: stretch;
  padding: 12px 12px 34px; margin: 0 0 var(--bs-sp-2);
  border-radius: 14px; overflow: hidden; border: 1px solid var(--bs-line);
  background: linear-gradient(180deg, #1d5c2c, #14431f);
  box-shadow: inset 0 0 34px rgba(0,0,0,.45);
}
/* The strip of cut grass down the middle. */
.bs-ckt-pitch {
  position: absolute; left: 50%; top: 0; bottom: 0; width: 26%;
  transform: translateX(-50%);
  background: linear-gradient(180deg, #cbb98a, #b9a375);
  opacity: .30;
}
.bs-ckt-board.is-chasing .bs-ckt-pitch { opacity: .18; }

.bs-ckt-side {
  position: relative; z-index: 1; flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  padding: 6px 4px; border-radius: 10px; background: rgba(0,0,0,.30);
}
.bs-ckt-side-l {
  font-size: var(--bs-t-2xs); font-weight: 800; letter-spacing: .16em;
  color: rgba(255,255,255,.6);
}
.bs-ckt-side-n {
  font-size: clamp(28px, 9vw, 46px); font-weight: 900; color: #ffffff; line-height: 1;
  font-variant-numeric: tabular-nums; text-shadow: 0 3px 14px rgba(0,0,0,.55);
}
.bs-ckt-side-n i { font-size: .5em; font-style: normal; opacity: .7; }
.bs-ckt-side-s { font-size: var(--bs-t-2xs); color: rgba(255,255,255,.62); font-variant-numeric: tabular-nums; }
/* The chase gets the warning colour: this is the half you cannot influence. */
.bs-ckt-side.is-chase { background: rgba(120,20,20,.42); }
.bs-ckt-side.is-chase .bs-ckt-side-n { color: var(--bs-neg); }

.bs-ckt-shout {
  position: absolute; left: 50%; top: 10px; transform: translateX(-50%); z-index: 2;
  font-size: clamp(14px, 4.4vw, 20px); font-weight: 900; letter-spacing: .06em;
  color: #ffffff; text-shadow: 0 2px 12px rgba(0,0,0,.6);
  animation: bs-ckt-shout .4s cubic-bezier(.2,1.4,.3,1) both;
}
.bs-ckt-shout.is-wicket { color: var(--bs-neg); }
.bs-ckt-shout.is-six, .bs-ckt-shout.is-four { color: var(--bs-gold-ink); }
.bs-ckt-shout.is-dot { color: rgba(255,255,255,.55); font-weight: 700; }
@keyframes bs-ckt-shout { from { opacity: 0; transform: translateX(-50%) scale(.7); } }

/* Every ball so far. This is a cricket scorecard, so it reads left to right. */
.bs-ckt-timeline {
  position: absolute; left: 8px; right: 8px; bottom: 8px; z-index: 2;
  display: flex; flex-wrap: wrap; gap: 3px; justify-content: center;
}
.bs-ckt-ball {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 17px; height: 17px; padding: 0 3px; border-radius: 50%;
  background: rgba(255,255,255,.16); color: #ffffff;
  font-size: 10px; font-weight: 800; font-style: normal; font-variant-numeric: tabular-nums;
}
.bs-ckt-ball.is-wicket { background: var(--bs-neg); }
.bs-ckt-ball.is-six { background: var(--bs-gold); color: #14181f; }
.bs-ckt-ball.is-four { background: rgba(var(--bs-gold-rgb),.55); }
.bs-ckt-ball.is-dot { background: rgba(255,255,255,.09); color: rgba(255,255,255,.5); }

/* ---- how you are going to bat ---- */
.bs-ckt-tiers { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin: 0 0 var(--bs-sp-2); }
.bs-ckt-tier {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 9px 6px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--bs-line); background: var(--bs-elev); color: var(--bs-text);
  font: inherit; transition: border-color .15s ease, background .15s ease;
}
.bs-ckt-tier:hover { border-color: var(--bs-orange); }
.bs-ckt-tier.is-on { border-color: var(--bs-orange); background: var(--bs-elev2); }
.bs-ckt-tier:focus-visible { outline: 2px solid var(--bs-orange); outline-offset: 2px; }
.bs-ckt-tier b { font-size: var(--bs-t-md); font-weight: 800; }
.bs-ckt-tier span { font-size: var(--bs-t-2xs); color: var(--bs-faint); }
/* The bust rate, in the warning colour, because it is the number that decides
   whether this tier is for you. */
.bs-ckt-tier i { font-size: 9px; font-style: normal; font-weight: 800; color: var(--bs-gold-ink); }

.bs-ckt-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 6px; }
.bs-ckt-actions .bs-btn { display: flex; flex-direction: column; gap: 1px; padding: 10px 8px; }
.bs-ckt-actions .bs-btn b { font-size: var(--bs-t-md); font-weight: 800; }
.bs-ckt-actions .bs-btn i { font-size: 10px; font-style: normal; opacity: .78; font-variant-numeric: tabular-nums; }
.bs-ckt-hint { text-align: center; margin-bottom: var(--bs-sp-2); }
.bs-ckt-start { width: 100%; font-weight: 800; }

@media (prefers-reduced-motion: reduce) {
  .bs-ckt-shout { animation: none; }
}

/* Declare is the decision the game is named after, so it carries the win
   colour even while disabled-looking under the minimum. */
.bs-ckt-declare:disabled { opacity: .5; }
.bs-ckt-ball b { letter-spacing: 0; }

/* ---- CRASH VARIANT IDENTITY -----------------------------------------------
   Eleven titles, one renderer, and every mark below is DERIVED from the
   variant's descriptor rather than painted on. A recolour alone would have been
   the exact reskin config/crash_variants.php exists to refuse, so colour is
   only the carrier — the ceiling line, the dead zone, the floor band, the knee,
   the rungs and the net are the differences a player can actually measure.

   --bs-vh is the variant's hue, set inline from the JS. Everything here derives
   from it, so an operator adding a twelfth variant gets a coherent stage from
   one number.
   -------------------------------------------------------------------------- */

.bs-vskin {
  --bs-vc: hsl(var(--bs-vh) 92% 58%);
  --bs-vc-dim: hsl(var(--bs-vh) 70% 42%);
  --bs-vc-deep: hsl(var(--bs-vh) 78% 12%);
  --bs-vc-soft: hsla(var(--bs-vh) 92% 58% / .22);
}

/* The horizon, the trail and the halo take the variant's colour, so the stage
   reads as THIS game rather than as crash with a coloured line on it. */
.bs-vskin .bs-crash-horizon { background: linear-gradient(180deg, transparent, var(--bs-vc-soft)); }
.bs-vskin .bs-crash-curve { stroke: var(--bs-vc); }
.bs-vskin .bs-crash-g0 { stop-color: var(--bs-vc); stop-opacity: .40; }
.bs-vskin .bs-crash-g1 { stop-color: var(--bs-vc); stop-opacity: 0; }
.bs-vskin .bs-crash-halo { background: radial-gradient(circle, var(--bs-vc-soft), transparent 70%); }

/* ---- the ceiling: where the climb actually stops ---- */
.bs-vskin-ceiling {
  position: absolute; left: 0; right: 0; height: 0; z-index: 3;
  border-top: 2px dashed var(--bs-vc); opacity: .85; font-style: normal;
  display: flex; align-items: center; justify-content: flex-end; gap: 5px;
  padding-right: 6px; pointer-events: none;
}
.bs-vskin-ceiling b {
  font-size: var(--bs-t-2xs); font-weight: 900; color: var(--bs-vc);
  transform: translateY(-50%); font-variant-numeric: tabular-nums;
}
.bs-vskin-ceiling span {
  font-size: 8px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  color: var(--bs-faint); transform: translateY(-50%);
}
/* Off the plotted range (Moonshot's 1001x). Stated rather than clamped to the
   top edge, which would draw it as if it were reachable. */
.bs-vskin-ceiling.is-offscale { top: 6px; border: 0; justify-content: center; padding: 0; }
.bs-vskin-ceiling.is-offscale span {
  transform: none; color: var(--bs-vc); font-size: var(--bs-t-2xs);
  letter-spacing: .06em; text-transform: none;
}

/* ---- the dead zone: Moonshot pays nothing under 3.00x ---- */
.bs-vskin-dead {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1;
  background: repeating-linear-gradient(135deg,
    rgba(0,0,0,.42) 0 7px, rgba(0,0,0,.24) 7px 14px);
  border-top: 1px solid var(--bs-neg);
  display: flex; align-items: flex-end; justify-content: center; padding-bottom: 4px;
  font-style: normal; pointer-events: none;
}
.bs-vskin-dead b {
  font-size: 9px; font-weight: 800; letter-spacing: .04em;
  color: var(--bs-neg); text-shadow: 0 1px 4px rgba(0,0,0,.8);
}

/* ---- the floor: Sure Thing's solid ground ---- */
.bs-vskin-floor {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1;
  background: linear-gradient(180deg, hsla(var(--bs-vh) 60% 30% / .55), hsla(var(--bs-vh) 60% 18% / .8));
  border-top: 2px solid var(--bs-vc);
  display: flex; align-items: flex-end; justify-content: center; padding-bottom: 4px;
  font-style: normal; pointer-events: none;
}
.bs-vskin-floor b {
  font-size: 9px; font-weight: 800; color: var(--bs-vc); text-shadow: 0 1px 4px rgba(0,0,0,.8);
}

/* ---- the knee: where Afterburner's second stage lights ---- */
.bs-vskin-knee {
  position: absolute; left: 0; right: 0; height: 0; z-index: 2;
  border-top: 1px solid var(--bs-vc); opacity: .6; font-style: normal;
  display: flex; align-items: center; gap: 5px; padding-left: 6px; pointer-events: none;
}
.bs-vskin-knee b, .bs-vskin-knee span { transform: translateY(-50%); }
.bs-vskin-knee b { font-size: 9px; font-weight: 900; color: var(--bs-vc); font-variant-numeric: tabular-nums; }
.bs-vskin-knee span { font-size: 8px; letter-spacing: .1em; text-transform: uppercase; color: var(--bs-faint); }

/* ---- the rungs: Ladder has no curve at all ---- */
.bs-vskin-rung {
  position: absolute; left: 8%; right: 8%; height: 0; z-index: 2;
  border-top: 2px solid var(--bs-vc); opacity: .38; font-style: normal;
  display: flex; align-items: center; justify-content: flex-end; padding-right: 4px;
  pointer-events: none;
}
.bs-vskin-rung b {
  font-size: 8px; font-weight: 800; color: var(--bs-vc); transform: translateY(-50%);
  font-variant-numeric: tabular-nums;
}
/* Discrete, so the smooth trail is hidden: drawing a curve through rungs would
   show a climb this game does not have. */
.bs-vskin-ladder .bs-crash-curve, .bs-vskin-ladder .bs-crash-curve-fill { display: none; }

/* ---- the locked target: Target Lock has no live cash-out ---- */
.bs-vskin-target {
  position: absolute; left: 0; right: 0; height: 0; z-index: 3;
  border-top: 2px solid var(--bs-gold); font-style: normal;
  display: flex; align-items: center; gap: 5px; padding-left: 6px; pointer-events: none;
}
.bs-vskin-target b, .bs-vskin-target span { transform: translateY(-50%); }
.bs-vskin-target b {
  font-size: var(--bs-t-2xs); font-weight: 900; color: var(--bs-gold-ink);
  font-variant-numeric: tabular-nums;
}
.bs-vskin-target span {
  font-size: 8px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--bs-gold-ink); opacity: .8;
}

/* ---- the net: Safety Net's bust is cushioned ---- */
.bs-vskin-net {
  position: absolute; left: 0; right: 0; bottom: 0; height: 9%; z-index: 1;
  background:
    repeating-linear-gradient(45deg, var(--bs-vc-soft) 0 1px, transparent 1px 8px),
    repeating-linear-gradient(-45deg, var(--bs-vc-soft) 0 1px, transparent 1px 8px);
  border-top: 1px solid var(--bs-vc); pointer-events: none;
}
.bs-vskin-net-l {
  position: absolute; left: 0; right: 0; bottom: 3px; z-index: 2; text-align: center;
  font-size: 9px; font-weight: 800; color: var(--bs-vc); pointer-events: none;
  text-shadow: 0 1px 4px rgba(0,0,0,.8);
}

/* ---- tone: the SHAPE of the game, not a label on it ---- */
/* Fast: the streaks run hard. Slow: they barely move. */
.bs-vtone-fast .bs-crash-speed { opacity: .9; animation-duration: .35s; }
.bs-vtone-slow .bs-crash-speed { opacity: .28; animation-duration: 2.4s; }
/* Deep: Moonshot is a night sky, so the stage floor goes black. */
.bs-vtone-deep { background-color: var(--bs-vc-deep); }
.bs-vtone-deep .bs-crash-horizon { opacity: .5; }
/* Capped: Grinder's whole game happens in the bottom third, so the grid above
   its ceiling is dimmed rather than pretending to be in play. */
.bs-vtone-capped .bs-ascend-grid { opacity: .35; }
/* Jackpot: a slow shimmer, because a slice of every stake is leaving the round
   for the shared pot. */
.bs-vtone-jackpot .bs-crash-horizon { animation: bs-vskin-pot 3.2s ease-in-out infinite; }
@keyframes bs-vskin-pot { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .bs-vtone-jackpot .bs-crash-horizon { animation: none; }
}

/* ============================================================================
   BETSYSTEM — OVERRIDES: THE RULES THE OTHER THREE FILES NEED
   ============================================================================

   WHERE THIS GOES
   ---------------
   APPEND to assets/betsystem.css after the last line (currently 6953). Nothing
   before it is touched.

   Appending after 6953 means appending after the MOBILE HARDENING block
   (5488-5745), which declares itself "deliberately appended LAST" and has since
   had 1,208 lines put after it. So everything here was checked against that
   block's ten-point trip list before it was written; the audit is §6.

   DECLARATION COUNT, stated correctly this time. The previous draft claimed
   "eighteen custom properties" twice and "four properties in total" once, and
   the rule declared nineteen. This file now contains:

       §1    19 custom properties + `color`                    = 20 declarations
       §1b    1 custom property  (`--bs-well`)                 =  1
       §2     1 `font-family`                                  =  1
       §3     1 custom property  (`--bs-line`)                 =  1
       §4.1   2 `border-color` rules + 1 `box-shadow`          =  3
       §4.2   1 `background`                                   =  1
       §4.3   1 custom property  (`--bs-gold-ink`)             =  1
       §4.4   1 `opacity`                                      =  1
       §5     9 + 1, inside @media (min-width: 561px)          = 10
                                                        TOTAL  = 39

   Counted by parsing this file, not by eye. §1 is nineteen because the previous
   draft's nineteen lost two (`--bs-field`, `--bs-live` — see the note in §1) and
   gained two (`--bs-glass`, `--bs-gold-rgb`).

   WHAT IT IS FOR
   --------------
   `skin_propagation.md` lets `bs-skin-classic` onto `.bs-overlay` for the first
   time. `substitutions.md` turns 33 hardcoded stage floors into `--bs-well`,
   which on `classic` is a deliberate DARK slate (`#161d29`) inside a white
   modal. Together those two make the light skin's game modals render — and then
   immediately break them, because a dark stage inside a light skin is a second
   lighting environment and `classic`'s ink ramp runs the wrong way for it:

       classic --bs-text   #141a24 on --bs-well #161d29  =  1.03:1
       classic --bs-muted  #4f5a6a                       =  2.42:1
       classic --bs-orange #0a58ca                       =  2.63:1
       classic --bs-pos    #0c7a45                       =  3.13:1
       classic --bs-neg    #c62129                       =  2.94:1

   Section 1 is the rule that fixes that, and it is not optional. Without it
   this package makes `classic` worse than the bug it removes.

   Sections 3 and 4 are the other half of the same problem, and they are the
   half the previous draft did not price: the chrome that is NOT inside a stage
   — every settlement banner, HUD, control row, message strip, plate and slip in
   all 21 games — lands on the white modal card, where the shipped light skin
   has `--bs-panel: #ffffff` AND `--bs-elev: #ffffff` (identical), a
   `--bs-line` at 1.31:1, a `--bs-gold` at 3.90:1 as text, and a `.bs-glass`
   made entirely of white alpha. Sections 3–5 close those.
   ========================================================================== */


/* ----------------------------------------------------------------------------
   1. THE PIT — the light skin's second lighting environment.

   One rule. Seventeen custom-property declarations and one `color`.

   THE MECHANISM, because it is the whole trick: custom properties INHERIT, and
   the nearest ancestor declaration wins for a subtree regardless of the
   specificity of the rule that reads it further down. So re-declaring the ramp
   on the stage CONTAINER re-lights every descendant automatically — every
   gradient stop, every chip fill, every border, every label — without
   enumerating a single one of them and without outranking any per-game rule.
   `.bs-dice-digit`'s `linear-gradient(var(--bs-elev2), var(--bs-panel), …)`
   resolves dark inside `.bs-dice-stage` and light everywhere else, and no rule
   for `.bs-dice-digit` had to be written or beaten.

   That is also why `substitutions.md`'s TEN `var(--bs-elev|elev2|panel) →
   var(--bs-well)` gradients do not run white-to-charcoal on the light skin.
   Inside the pit `--bs-elev` is `#222b3a`, so `.bs-felt` measures
   `#222b3a → #161d29`.

   WHY ONLY `classic`. The nine dark skins already have a ramp tuned for dark
   surfaces; a dark stage inherits a correct ramp from them by definition, so
   the correction they need is a no-op. This rule is written for all ten skins
   in the only sense that matters: it applies wherever an inversion exists, and
   there is exactly one skin with an inversion.

   WHY `:where()`. It pins the whole selector at (0,1,0) — the `.bs-skin-classic`
   class and nothing else. Skin-scoped rules must never outrank the bespoke game
   stages this overhaul exists to preserve; the moment a `.bs-skin-classic
   .bs-felt { … }` rule lands at (0,2,0) it starts winning declarations off
   per-game rules unpredictably, game by game. At (0,1,0) it wins `color` only
   on source order, and the token flip does the real work through inheritance,
   where specificity does not apply at all.

   EVERY CLASS BELOW IS EMITTED BY THE JS. Grepped one at a time against
   assets/js/betsystem-app.js (13,011 lines) — hit counts in the comment beside
   each. Four near-miss candidates were REMOVED after grepping because the JS
   never emits them: `.bs-plinko-path`, `.bs-sp-table`, `.bs-mine-board` and
   `.bs-craps-stage` are all v1 leftovers superseded by `.bs-plink-board`, the
   `.bs-chin-*` table, `.bs-mines-well` and `.bs-craps-pit`. The previous
   proposal's `.bs-well` and `.bs-stage` are emitted 0 times in either file and
   are not here either.

   TWO DECLARATIONS WERE DELETED FROM THIS RULE and the reason is the rule
   foundation.css §4 states — "a token with no consumer is a comment that lints
   as code":
     `--bs-field: #10161f`  — all five post-substitution consumers are widget
        chrome (betsystem.css:60 `.bs-card input…`, :165 `.bs-refcode`,
        :175 `.bs-prog`, :371 `.bs-2fa-key`, :375 `.bs-2fa-codes code`, emitted
        at betsystem-app.js:1585, 1623/1654, 12840/12850 and inside 53
        `bs-card` writes that are all widget `root.innerHTML`). None can be a
        descendant of any of the nineteen stage containers. The rule's own
        comment used to concede that its two candidates, `.bs-scrash-f input`
        (css:6244) and `.bs-fr-stake input` (css:6590), are siblings of the
        stage — it documented the unreachability of the declaration it was
        making. Those two inputs are now handled properly, on desktop, by §5.
     `--bs-live: #ff6b70`  — `grep -n "var(--bs-live)"` returns exactly three
        hits: :97 `.bs-pill-lost`, :204 `.bs-lt-live`, :365 `.bs-move-dn`,
        emitted at js:660/958/1488 (KYC and fixture pills), js:12435 (live
        ticker) and js:1237 (leaderboard). All widget chrome; none is a
        descendant of any pit class.

   ONE DECLARATION WAS ADDED: `--bs-glass`. Inside a stage the card is dark
   again, so the frosted plate goes back to being a white wash. Without this the
   classic dark-ink wash from foundation §3 would paint a dark plate on a dark
   stage — the same inversion this whole rule exists to prevent, one layer down.

   ----------------------------------------------------------------------------
   CONTRAST — the pit, computed. Surfaces in order:
     --bs-well #161d29 · --bs-bg #10161f · --bs-panel #1c2431
     --bs-elev #222b3a · --bs-elev2 #293445 · --bs-soft #46536b

     ink                 well  /  bg   / panel /  elev  / elev2 /  soft
     print   #f2f5fa    15.47  16.62   14.28   13.03   11.50    7.09
     muted   #aab4c4     8.08   8.68    7.45    6.80    6.00    3.70
     faint   #98a3b3     6.62   7.11    6.11    5.58    4.92    3.03
     orange  #63a4ff     6.67   7.16    6.15    5.62    4.96    3.06
     br      #8fbeff     8.84   9.49    8.16    7.44    6.57    4.05
     gold    #e0b562     8.82   9.47    8.14    7.43    6.55    4.04
     pos     #2fd07a     8.39   9.01    7.74    7.07    6.24    3.85
     neg     #ff6b70     6.11   6.56    5.64    5.15    4.54    2.80
   PASS 8 inks × 5 surfaces = 40 of 40 at AA on well/bg/panel/elev/elev2.
   WORST there 4.54:1 (neg on elev2).

   `--bs-soft` IS THE SIXTH SURFACE AND THE PREVIOUS DRAFT DID NOT MEASURE IT.
   It is declared here and it has 29 `background:` sites in the sheet. Seven of
   its eight inks are under 4.5 on it. What that actually costs, checked site by
   site, is smaller than the column looks, and it is stated rather than hidden:
     * 24 of the 29 sites are tiny GRAPHICAL objects with no text on them —
       `.bs-plink-peg` (:506, :1579), `.bs-plink-pips i` (:1725),
       `.bs-slot-bulb` (:2160), `.bs-pw-seg-bar > i` (:2656),
       `.bs-crash-pill i` (:3995), `.bs-rw-slip-dot` (:3836), the dividers at
       :1694/:2794/:3063/:3072/:3257/:3920, the conic wheel fill at :2551, etc.
       For those the number that matters is soft-vs-well, not ink-on-soft:
       pit 2.18:1, against TIGER's own 1.58:1 (#2a3340 on #05070c). The pit is
       direction-correct and BETTER than the product's own baseline, and still
       under WCAG 1.4.11's 3:1 for a graphical object. That 3:1 gap is
       product-wide and pre-existing; this package does not claim to close it.
       Raising `--bs-soft` to clear 3:1 (#586887) would take orange-on-soft from
       3.06 to 2.21 and muted-on-soft from 3.70 to 2.68 — trading a graphical
       miss for three text misses. Not done, and here are the numbers.
     * The text cases inside a stage are `.bs-craps-total-meta i` (:2026, 9px/900
       `var(--bs-orange)` on `var(--bs-soft)`): pit 3.06:1, FAIL. Tiger's own is
       5.40:1. This is the one place the pit is worse than tiger, it is one
       9-pixel uppercase tag inside the craps felt, and it is recorded here
       rather than fixed with a token that costs three other pairings.
     * `.bs-pill` / `.bs-pill-void` (:95/:99, muted on soft) is widget chrome and
       never renders inside a stage.

   The same surfaces with the ramp NOT flipped — i.e. what ships if §1 is
   dropped:
     text    #141a24     1.03   1.04    1.12    1.23    1.39   FAIL x5
     muted   #4f5a6a     2.42   2.60    2.23    2.04    1.80   FAIL x5
     faint   #67717f     3.42   3.67    3.15    2.88    2.54   FAIL x5
     orange  #0a58ca     2.63   2.82    2.42    2.21    1.95   FAIL x5
     gold    #a9781a     4.34   4.66    4.00    3.65    3.22   FAIL x4
     pos     #0c7a45     3.13   3.36    2.89    2.63    2.32   FAIL x5
     neg     #c62129     2.94   3.16    2.71    2.48    2.18   FAIL x5

   Inks on their own accents, inside the pit:
     --bs-on-orange #05101f on orange 7.53 · on -br 9.98 · on -dp 5.10
     --bs-on-gold   #1a1207 on pit gold 9.66 · on pit -dp #3a83ea 4.95
       (that last number is why substitutions.md §6.2 is now closed rather than
        deferred: `.bs-coin` (:466), `.bs-keno-ball` (:730) and `.bs-cf-side`
        (:851) all sit on a `var(--bs-gold) → var(--bs-orange-dp)` radial, and
        all three are INSIDE a pit container — `.bs-coin-tray` for the first and
        third (js:7548 wraps js:7514), `.bs-keno-board` for the second
        (js:6565 wraps the rail that js:6454 fills). classic's raw 2.19:1 on
        `--bs-orange-dp` #0847a8 therefore never renders. neon 4.09 and midnight
        4.27 do render and are genuinely pre-existing and untouched.)
   The hardcoded night skies, which stay literal (substitutions.md §4.3):
     #04070f / #050b1a / #071229 / #0a1830
     print 18.43 / 17.97 / 17.04 / 16.20 · orange 7.95 / 7.75 / 7.35 / 6.98
     gold 10.51 / 10.25 / 9.72 / 9.24   · pos 10.00 / 9.75 / 9.24 / 8.79
   `.bs-felt` inside the pit, sampled along the ramp #222b3a → #161d29:
     print 13.03 → 15.47 · muted 6.80 → 8.08 · gold 7.43 → 8.82
   The same gradient WITHOUT the pit would be #ffffff → #161d29 and --bs-print
   would measure 1.09:1 at the top stop — white on white, on the nine games that
   wrap their stage in `.bs-felt`. That is the specific bug this rule closes.

   `--bs-line` #38445a is 1.28–1.85:1 against the pit surfaces. That is
   deliberate parity, not an oversight: tiger's own `--bs-line` #222b39 on
   `--bs-elev2` measures 1.09:1, so the pit's hairline is a touch STRONGER than
   the sheet's own. Inside a stage it is a decorative divider between physical
   parts, not a component boundary; the components that DO need 3:1 are on the
   card, and §3 gives them 3.57:1 there.

   WHAT THIS RULE COSTS THE OPERATOR, stated plainly because the propagation
   patch exists to carry the operator's brand into the games: seventeen custom
   properties are re-declared ON the stage element, and a descendant declaration
   beats an ancestor's INLINE style. `class-base-widget.php:112-155` lets an
   operator set `--bs-orange`, `--bs-orange-br`, `--bs-orange-dp`, `--bs-accent`,
   `--bs-panel`, `--bs-elev`, `--bs-elev2`, `--bs-bg`, `--bs-text`, `--bs-line`,
   `--bs-soft`, `--bs-pos`, `--bs-live`, `--bs-radius`, `--bs-font`. Twelve of
   those names are re-declared here. SO: ON `classic`, INSIDE A GAME STAGE, THE
   ACCENT / SURFACE / INK RAMP IS THE PIT'S, NOT THE OPERATOR'S. That is the
   deliberate trade — an operator's brand blue at 2.63:1 on a dark stage is not
   branding, it is an invisible chip — but it is a trade, and it is not
   discoverable from the CSS. It applies to `classic` only; on the nine dark
   skins the operator's inline values pass straight through to every stage.
   A `--bs-accent-pit` channel that let the operator tune the in-stage ramp
   would need a new Elementor control in class-base-widget.php, which is a PHP
   change and is not in this package.
   -------------------------------------------------------------------------- */
.bs-skin-classic :where(
  .bs-felt,           /* js x30 — Wheel, HiLo, Scratch, Blackjack, Baccarat,
                         Video Poker, Craps, Sic Bo, Chinchón all wrap in it */
  .bs-demo-reel,      /* js x1  — the licensed-RGS demo modal */
  .bs-wheel-strip,    /* js x2  */
  .bs-dice-tray,      /* js x1  — shared by Dice, Craps, Sic Bo */
  .bs-coin-tray,      /* js x1  */
  .bs-ascend-stage,   /* js x3  */
  .bs-crash-stage,    /* js x2  — also the shared/multiplayer crash stage */
  .bs-limbo-stage,    /* js x1  */
  .bs-dice-stage,     /* js x1  */
  .bs-rw-stage,       /* js x1  */
  .bs-pw-stage,       /* js x1  */
  .bs-plink-board,    /* js x1  */
  .bs-keno-board,     /* js x1  */
  .bs-slot-window,    /* js x2  — covers .bs-slot-reel, which is inside it */
  .bs-mines-well,     /* js x1  */
  .bs-scratch-panel,  /* js x2  */
  .bs-craps-pit,      /* js x3  */
  .bs-sicbo-stage,    /* js x3  */
  .bs-hilo-stage      /* js x1  */
) {
  /* Surfaces: the same four-step ladder the dark skins have, dropped into the
     white card. --bs-well itself is NOT re-declared — #161d29 is inherited from
     .bs-skin-classic and is already the floor of this ladder. */
  --bs-bg:     #10161f;
  --bs-panel:  #1c2431;
  --bs-elev:   #222b3a;
  --bs-elev2:  #293445;
  --bs-line:   #38445a;
  --bs-soft:   #46536b;

  /* Ink. --bs-text points at --bs-print rather than repeating the literal, so
     there is one place to change the colour of everything printed on a stage.
     No cycle: --bs-print is a literal at the root and is never derived. */
  --bs-text:  var(--bs-print);
  --bs-muted: #aab4c4;
  --bs-faint: #98a3b3;

  /* Accent. classic darkened --bs-orange to #0a58ca specifically to carry white
     ink on a white card; on a dark stage that same blue is 1.95–2.63:1 and the
     picked Keno number, the lit Craps box, the Limbo target tag and the Dice
     scale midpoint all disappear. Same blue, lifted for a dark room. */
  --bs-orange:    #63a4ff;
  --bs-orange-br: #8fbeff;
  --bs-orange-dp: #3a83ea;
  --bs-on-orange: #05101f;   /* the accent is light in here, so its ink flips
                                back to dark: 7.53 / 9.98 / 5.10 */

  /* The win channel. --bs-gold is the most-consumed token in the sheet (349)
     and it is the payout colour in thirteen games. classic's #a9781a is 3.22 on
     the pit's lightest surface; #e0b562 is 6.55–9.47. --bs-gold-ink and
     --bs-gold-rgb follow it because inside the pit, surface-gold IS text-safe —
     the split only exists for white cards. */
  --bs-gold:     #e0b562;
  --bs-gold-ink: var(--bs-gold);
  --bs-gold-rgb: 224,181,98;

  /* Win/loss. classic's #0c7a45 and #c62129 are tuned for white and measure
     2.18–3.36 here. These two values are tiger's, which is not a coincidence:
     they are the values this product already tuned for dark surfaces. */
  --bs-pos:  #2fd07a;
  --bs-neg:  #ff6b70;

  /* The frosted plate goes back to a white wash: inside a stage the surface
     under it is dark again. Byte-identical to betsystem.css:557 as shipped. */
  --bs-glass: linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.015));

  /* Anything on a stage that has no colour rule of its own — a bare text node,
     an emoji reel, a felt caption — inherits from here rather than from the
     card. (0,1,0) and late in the sheet, so it wins over the per-game
     `color: var(--bs-text)` rules at the same specificity on source order; the
     ones at (0,2,0) are already handled by the --bs-text flip above, which
     inheritance settles without any specificity contest at all.) */
  color: var(--bs-print);
}


/* ----------------------------------------------------------------------------
   1b. THE FOUR SKY STAGES KEEP THEIR HORIZON ON `classic`.

   substitutions.md §1 swaps the BOTTOM stop of four hardcoded night-sky
   gradients to `var(--bs-well)`. On the nine dark skins that is a near-black
   for a near-black. On `classic` `--bs-well` is the slate `#161d29`, and the
   previous draft's justification — "sits just above #0a1830 in lightness, so
   the ramps stay monotone and do not band" — was wrong twice:

     :912  `.bs-crash-stage`  #050b1a 0.00577 → #0a1830 0.00884 → #05070c 0.00243
     :2880 `.bs-limbo-stage`  same shape
     :3877 `.bs-crash-stage`  #04070f 0.00212 → #071229 0.00638 → #0a1830 0.00931
                              → #05070c 0.00211
     :472  `.bs-ascend-stage` #0a1830 0.00931 → #05070c 0.00211

   Three of the four are NOT monotone today — they rise to a horizon glow and
   fall back to near-black at the bottom. Substituting classic's `#161d29`
   (0.01209) makes the bottom edge the BRIGHTEST band in the scene: the horizon
   is inverted, not preserved. There is no AA consequence — the skies are dark
   at every stop on every skin and `--bs-print` measures 16.20–18.43:1 on them —
   but "PRESERVE the bespoke stages, do not flatten them" is BRIEF rule 1's
   whole point, and four of the eleven bespoke stages are these.

   One rule, (0,1,0), declared on the same three elements the §1 pit already
   matches, later in the file so it wins for this one property. It restores
   exactly today's floor for the sky and nothing else: everything else in those
   stages still takes the pit's ramp, and no other `var(--bs-well)` consumer is
   a descendant of a sky stage (checked: the 33 well sites are stage containers,
   and stages do not nest).
   -------------------------------------------------------------------------- */
.bs-skin-classic :where(.bs-ascend-stage, .bs-crash-stage, .bs-limbo-stage) {
  --bs-well: #05070c;
}


/* ----------------------------------------------------------------------------
   2. OPERATOR FONTS REACH THE GAMES.

   :276 is `.betsystem-widget[style*="--bs-font"]` — an attribute selector on the
   widget class. `skin_propagation.md` copies the widget's inline `--bs-*`
   custom properties onto the overlay, so `--bs-font` is now PRESENT on the
   overlay and read by nothing: the game modal keeps `'Inter', system-ui…` from
   :7 while the lobby two divs away uses the operator's face.

   One line, mirroring :276 exactly rather than inventing a new stack. (0,2,0)
   and after :7 and :5294, so it wins `font-family`; it cannot collide with the
   mobile block, whose only font rule is `font-family: inherit` on
   `.bs-game-modal input` at :5602 — a different element, and one that now
   inherits the right thing.
   -------------------------------------------------------------------------- */
.bs-overlay[style*="--bs-font"] {
  font-family: var(--bs-font), 'Inter', system-ui, sans-serif;
}


/* ----------------------------------------------------------------------------
   3. THE CLASSIC GAME-MODAL RAMP — the half of the light skin that is NOT on a
   stage.

   THE DEFECT, verified. `.bs-skin-classic` declares
   `--bs-panel:#ffffff; --bs-elev:#ffffff; --bs-elev2:#f4f6fb; --bs-line:#dbe1ec`
   (betsystem.css:268). The sheet expresses depth as a gradient between panel
   and elev/elev2, and counted in the sheet there are 11 declarations pairing
   `var(--bs-elev)` with `var(--bs-panel)`, 41 pairing `var(--bs-elev2)` with
   `var(--bs-panel)` and 4 pairing elev with elev2 — 56 elevation gradients.
   On `classic` elev→panel computes to **1.000:1** (the same colour) and
   elev2→panel to 1.081:1. The worst instance is the banner six games share:

     :4062 `.bs-crash-result { border:1px solid var(--bs-line);
             background: radial-gradient(…rgba(255,255,255,.07)…),
                         linear-gradient(180deg, var(--bs-elev), var(--bs-panel)) }`
     used by Crash (js:3144), SharedCrash (js:3912), Cricket (js:4473),
     Snooker (js:4789), Five-reel (js:5025) and Penalty (js:5323).

   On classic that is #ffffff on #ffffff inside a #ffffff modal, separated by a
   1.31:1 hairline. The package's own T1–T9 measure ink on surfaces and never
   asked whether the surface is visible, which is how it passed its own review.

   WHAT THIS RULE DOES, AND WHAT IT DELIBERATELY DOES NOT.
   It does NOT re-tune `--bs-elev`. That was the obvious fix and it is a trap:
   `classic`'s `--bs-faint` #67717f measures only 4.95:1 on `#ffffff`, so ANY
   surface darker than relative luminance 0.905 puts faint text under AA.
   #eff3f9 — a 1.11:1 step, already too subtle to fix the finding — puts it at
   4.44:1. A real elevation ladder for the light skin therefore has to move the
   ink ramp with it, which is a re-tune of the shipped skin on 54 + 126 + 136
   consumers and belongs in its own commit with its own table.

   What it does instead is give the plate an EDGE, which is what a light UI
   actually uses. `--bs-line` is lifted inside the game modal only:

     classic --bs-line  #dbe1ec → #7f8899
       vs --bs-panel #ffffff   1.31 → 3.57   (WCAG 1.4.11 wants 3:1)
       vs --bs-elev2 #f4f6fb   1.21 → 3.30
       vs --bs-field #e8ecf4   1.11 → 3.01
       vs --bs-bg    #eef1f7   1.16 → 3.15

   PROOF THAT `--bs-line` IS NEVER AN INK, so this cannot move a text pairing:
   `grep -nE "color:\s*var\(--bs-line\)"` returns 8 lines and every one of them
   is `border-color:` or `border-top-color:` (:761, :1676, :1906, :1963, :2441,
   :3375, :4555, :5042). `grep -nE "background[^;]*var\(--bs-line\)"` returns 17
   and every one is a rule, a track, a dotted separator or a divider gradient
   (:1113, :1456, :1694, :1996, :2056, :2655, :2794, :3063, :3064, :3072, :3267,
   :4520, :4996, :5091, :5113, :5263, :6507) — none carries text. So the entire
   blast radius of this declaration is "borders and hairlines inside a game
   modal on the light skin get strong enough to see", which is the finding.

   SCOPE. `.bs-game-modal` only. The reality-check card (`.bs-overlay-card` with
   no `.bs-game-modal`, js:1429) and the widget's own `.bs-card` chrome keep the
   shipped hairline; changing 255 border sites across the whole light-skin
   product is not something this package is entitled to do on the strength of a
   game-modal finding. The lobby's `.bs-card` (:31) also renders a flat
   `#ffffff → #ffffff` gradient on classic today and still will — recorded, not
   fixed, for the same reason.

   The pit (§1) re-declares `--bs-line: #38445a` ON the stage containers, which
   are descendants of `.bs-game-modal`, so inside a stage the nearer declaration
   wins and the physical parts keep their soft hairline. No specificity contest:
   this is inheritance distance.

   SPECIFICITY: (0,1,0) — `:where()` contributes nothing, `.bs-skin-classic`
   supplies the one class. It cannot outrank any per-game rule.
   -------------------------------------------------------------------------- */
.bs-skin-classic :where(.bs-game-modal) {
  --bs-line: #7f8899;
}


/* ----------------------------------------------------------------------------
   4. LIGHT-SKIN AND LEGIBILITY CORRECTIONS — four rules, each with its number.
   -------------------------------------------------------------------------- */

/* 4.1  The five `--bs-field` controls get a BOUNDARY, not just a fill.
   substitutions.md §2 takes every card input on `classic` from a near-black box
   at 1.07:1 to a light trough at 14.74:1. That fixes the ink and leaves the
   control invisible: the new fill #e8ecf4 is 1.18:1 from the white card and the
   `1px solid var(--bs-line)` #dbe1ec border those rules already carry is
   1.31:1. WCAG 1.4.11 wants 3:1 for the visual boundary of a user-interface
   component. #7f8899 is 3.57:1 on the card and 3.01:1 on the fill.

   SPECIFICITY, worked: `.bs-card input` at :59 is (0,1,1) and
   `.bs-card input:focus` at :62 is (0,2,1). Each selector below is (0,1,1) —
   `:where()` zeroes `.bs-skin-classic`/`.bs-card` and the element supplies the
   1 — so each BEATS :59 on source order and LOSES to :62, which means the
   orange focus border still wins. `.bs-2fa-key` is (0,1,0) against :371's
   (0,1,0), later; `.bs-2fa-codes code` is (0,1,1) against :375's (0,1,1),
   later. The ≤560 rules at :5593 (font-size / min-height) and :5596
   (checkbox / radio sizing) declare no border-color and are untouched. */
.bs-skin-classic :where(.bs-card, .bs-redeem) input,
.bs-skin-classic :where(.bs-card) select,
.bs-skin-classic :where(.bs-card) textarea,
.bs-skin-classic :where(.bs-2fa-codes) code {
  border-color: #7f8899;
}
.bs-skin-classic :where(.bs-2fa-key) { border-color: #7f8899; }

/* `.bs-prog` (:175) is the odd one out: an 8px track with `overflow:hidden`, no
   border at all, and after §2 a fill of `--bs-field` at 1.18:1 from the card.
   A player cannot see how far a bonus has to go if the unfilled portion is
   indistinguishable from the card behind it. A 1px inset ring costs nothing —
   `.bs-prog` declares no `box-shadow` today, so nothing is displaced — and
   leaves 6px of visible track. (0,1,0) vs :175's (0,1,0), later. */
.bs-skin-classic :where(.bs-prog) { box-shadow: inset 0 0 0 1px #7f8899; }

/* 4.2  `.bs-jp-grand` — the gradient stop no contrast table computed.
   :137 `.bs-jp` sets the ink (`#1a1207`, becoming `var(--bs-on-gold)` at
   substitutions §3.2) and :139 `.bs-jp-grand` KEEPS that ink while replacing the
   background with `linear-gradient(135deg, var(--bs-orange), #ffcf7a)` — whose
   near stop is the SKIN'S ORANGE, not a gold. Live classes at
   betsystem-app.js:1357 `'<div class="bs-jp bs-jp-' + j.tier + '">'`.
   Sampled at 101 points, the worst point is the 0% stop:
     classic 2.88  ·  neon 5.39 · sunset 5.98 · candy 5.91 · midnight 6.03
     ice 6.52 · royal 7.66 · emerald 7.73 · tiger 7.84 · mono 12.76
   `.bs-jp-name` is 11px/700 (needs 4.5) and `.bs-jp-val` is 24px/900 (needs
   3.0) — on `classic` BOTH fail, today, in shipped widget chrome.
   `#d9a441` on the same ramp measures 8.24:1 worst and keeps the grand tier
   hotter than `.bs-jp` (#a9781a) and `.bs-jp-major` on this skin.
   (0,1,0) vs :139's (0,1,0), later. classic only; nine skins untouched. */
.bs-skin-classic :where(.bs-jp-grand) {
  background: linear-gradient(135deg, #d9a441, #ffcf7a);
}

/* 4.3  The `--bs-gold-ink` guard — the four gold-as-text sites that sit on a
   hardcoded DARK material OUTSIDE every pit container.
   substitutions.md §3c rewires all 152 `color: var(--bs-gold)` lines to
   `var(--bs-gold-ink)`. That is byte-identical on the nine dark skins and
   inside the classic pit, because `--bs-gold-ink` aliases straight through to
   `--bs-gold` in both. The only place it differs is `classic` outside a stage,
   where it becomes #7a5510 — correct on a white card and WRONG on a dark
   physical surface. Three containers hold such surfaces and are not in §1's
   nineteen:
     `.bs-rw-table`  (js:7959-7970 roulette betting layout; felt literals
                      #d2373d / #a51e24 / #2c2c2c) → `.bs-rw-cell-col
                      .bs-rw-cell-lbl` :3789
     `.bs-snk-table` (js:4724; baize #14663a / #0e4a2a / #06120b)
                      → `.bs-snk-break-n` :6649, :6650
     `.bs-ckt-board` (js:4426; pitch #1d5c2c / #14431f)
                      → `.bs-ckt-shout.is-six, .is-four` :6752
   Re-aliasing the token on the container is the same mechanism §1 uses, one
   layer out, and it costs one declaration. `.bs-ckt-tier i` (:6787, 9px gold)
   is deliberately NOT in this list — `.bs-ckt-tier` is a card-level button
   (`background: var(--bs-elev2)` when on), so it wants the text-safe gold.
   (0,1,0). */
.bs-skin-classic :where(.bs-rw-table, .bs-snk-table, .bs-ckt-board) {
  --bs-gold-ink: var(--bs-gold);
}

/* 4.4  `.bs-tier-perk`'s opacity — the composite neither T3 nor T4 took.
   :168 declares `.bs-tier-perk { font-size:12px; opacity:.92 }`. Opacity
   composites the rendered text 92% over the tier gradient, so the effective ink
   is not the token. 12px needs 4.5:1. Composited:
     `.bs-tier-2` (#c98a12 → var(--bs-gold), ink --bs-on-gold)
        classic 4.37 FAIL   (5.67 on the nine dark skins)
     `.bs-tier-3` (var(--bs-orange-dp) → var(--bs-orange-br), ink --bs-on-orange)
        midnight 4.23 FAIL · neon 4.38 FAIL · sunset 4.45 FAIL
        (ice 4.54 · candy 4.52 · classic 4.70 · emerald 4.80 · royal 5.02)
   At `opacity: 1` every one clears: tier-2 worst 4.75 (classic), tier-3 worst
   4.51 (midnight) — which are exactly the numbers T3 and T4 print.
   THIS IS A TIGER-VISIBLE CHANGE and foundation.css §4 names it as one of two:
   tiger's tier-2 perk moves 5.67 → 6.29 and tier-3 6.37 → 7.09, both upward.
   `.bs-tier-0` also improves (4.12 → 4.54, from FAIL to PASS).
   `.bs-tier-1` does NOT clear: #101319 on the hardcoded silver
   `#6b7178 → #9aa2b0` is 3.52 composited, 3.77 at opacity 1, and white is worse
   (2.57 at the light end). That plate needs a new gradient on all ten skins and
   is recorded, not fixed.
   `:where()` keeps this at (0,1,0), tying :168 and winning on source order. */
:where(.bs-tier) .bs-tier-perk { opacity: 1; }


/* ----------------------------------------------------------------------------
   5. DESKTOP GAME-MODAL INPUTS — the cheapest visible win in the sheet.

   betsystem.css:5599 says it in its own comment: *"Game-modal inputs get NO
   styling from `.bs-card input` — the modal is appended to <body>, outside any
   card."* The fix at :5602 sits inside `@media (max-width:560px)`. Above 560px
   every stake box in all 21 games is a raw native OS control on a near-black
   stage, on all ten skins. It is the most-touched control in the product: every
   game has one and every round starts with it.

   THE CORRECTION TO substitutions.md §6.5, which said this rule "must be
   written outside any media query": it must NOT. `.bs-game-modal input` at
   (0,1,1) appended here would be later than :5602 at the same specificity, and
   media queries contribute nothing to specificity — so an unguarded rule would
   BEAT the phone rule and destroy both the iOS zoom guard (`font-size: 16px`)
   and the 44px tap target. Writing it inside `@media (min-width: 561px)` means
   the two rules can never both apply, which is the sheet's own two-step idiom
   (560 / 420) read forwards. This is the first `min-width` query in the sheet;
   it adds no specificity and no new breakpoint value.

   The declarations mirror :5602 exactly, with desktop metrics, and use
   `var(--bs-bg)` for the fill — not `var(--bs-field)` — because that is what
   :5602 uses and what the two games that hand-rolled the control already use
   (`.bs-scrash-f input` :6244, `.bs-fr-stake input` :6590). Four input
   treatments become one. On `classic` `--bs-bg` is #eef1f7 with `--bs-text`
   #141a24 at 15.43:1, inside a `var(--bs-line)` border that §3 has already
   lifted to 3.15:1 against that fill.

   Because this rule is later than :6244 and :6590 at equal specificity (0,1,1),
   it normalises those two: padding 9px 10px → 9px 11px, font-size 14px → 15px,
   and adds min-height 40px. Their `width:100%` and
   `font-variant-numeric: tabular-nums` are not declared here and survive.
   `.bs-slot-ctrls input { width: 90px }` (:283) and `.bs-row-tight input`
   (:381) survive for the same reason.

   The `:focus` line mirrors :5608 and is (0,2,1), so it still loses to nothing
   that matters and wins over the base rule directly above it.
   -------------------------------------------------------------------------- */
@media (min-width: 561px) {
  .bs-game-modal input, .bs-game-modal select {
    box-sizing: border-box; min-height: 40px; padding: 9px 11px;
    font-family: inherit; font-size: 15px;
    color: var(--bs-text); background: var(--bs-bg);
    border: 1px solid var(--bs-line); border-radius: 10px;
  }
  .bs-game-modal input:focus, .bs-game-modal select:focus { border-color: var(--bs-orange); }
}


/* ============================================================================
   6. CASCADE AUDIT — the ten-point trip list for anything appended after 6953,
   answered for this file. Kept in the sheet so the next person appending here
   has the checklist and a worked example.

    1. Re-declares `align-items` on `.bs-overlay`?
       NO. :5510 is the single most fragile declaration in the sheet — it is
       (0,1,0), unscoped, and exists only to beat `align-items: center` from
       :180 on source order. It is what makes every modal scrollable at any
       viewport height, and it is what makes the sticky head at :5556 able to
       stick. This file writes no `.bs-overlay { … }` rule at all; §2 is
       `.bs-overlay[style*=…]` and sets only `font-family`.

    2. A `.bs-btn` rule at (0,1,0)?  NO. No `.bs-btn` rule of any specificity.
       (:5578's `padding: 13px 18px; font-size: 15px` phone tap-target is
       therefore untouched — it is already beaten at :6790 by
       `.bs-ckt-actions .bs-btn`, which is a live regression this file does not
       add to.)

    3. Sets `transition` or `transform` on `.bs-btn` / `.bs-btn:hover`?
       NO. Those two PRM kills at :5483 / :5485 carry no `!important` and any
       later rule at equal specificity re-enables motion for every
       reduced-motion user in the product. Nothing here declares either
       property on anything.

    4. Sets `min-width` on anything inside `.bs-slot-ctrls`?
       NO. §5 sets `min-height` on inputs, never `min-width`, and only above
       560px. (For the record, the desktop content box is 324px, not 480px:
       `.bs-overlay-card`'s `max-width: 380px` at :181 beats `.bs-game-modal`'s
       `max-width: 480px` at :130 on source order at equal specificity, and
       `:181 padding: 28px` takes the rest. §5's inputs carry no width, so they
       obey `.bs-slot-ctrls input { width: 90px }` at :283 as before.)

    5. Touches `max-width` on `.bs-game-modal`?  NO.

    6. Adds a colour token to the `.betsystem-widget, .bs-hero, .bs-overlay`
       selector list?  NO — not in this file. foundation.css does, and it sits
       AFTER the ten skin blocks, which is safe only because every name it
       declares is absent from lines 1-270. That precondition is stated at the
       top of that file and must be verified before applying it.
       §1, §1b, §3 and §4.3 here declare custom properties on STAGE, MODAL and
       CONTAINER elements, which are descendants of the declaration site, so
       they override by inheritance distance rather than by source order — and
       only under `.bs-skin-classic`.

    7. Adds an `animation`?  NO. There is no PRM backstop in this sheet — all 41
       blocks neutralise animation-names individually — so a new animation would
       need its own PRM entry. None is added. §4.4 changes an `opacity` on a
       static element; `.bs-tier-perk` has no animation and appears in no PRM
       block.

    8. Adds a `:hover`?  NO. The sheet has 64 hover rules and 0
       `@media (hover: hover)` guards, so a new one would latch on touch. None
       is added. §5's `:focus` is not a hover and mirrors the existing :5608.

    9. Changes `.bs-overlay-card`'s padding?  NO. Three other rules hardcode
       that number (the sticky head's `margin:-16px -16px 12px` at :5556,
       roulette's `margin-left/-right:-16px` at :5693, and the desktop 28px at
       :181).

   10. Targets `.bs-mines-result-win`, `.bs-keno-payout-win`, `.bs-well`,
       `.bs-stage`, or `.bs-label` inside a banner?
       NO. All five are confirmed to match nothing, and none appears in this
       package. Every class named in §1, §1b, §4.2 and §4.3 was grepped
       individually against betsystem-app.js and four candidates were dropped
       for failing that grep.

   ELEVENTH POINT, added by this pass: does it collide with a rule INSIDE
   `@media (max-width: 560px)` at equal-or-higher specificity? A media query
   contributes nothing to specificity, so a later unguarded rule beats a
   phone-only one at every viewport width. §5 is the only rule here that
   targets an element the mobile block also styles (`.bs-game-modal input`,
   :5602), and it is fenced inside `@media (min-width: 561px)` for exactly that
   reason. §4.1 targets `.bs-card input` etc., which the mobile block styles at
   :5593 — but :5593 declares only `font-size` and `min-height` and §4.1
   declares only `border-color`, so they do not intersect.

   PLUS the question this file exists to answer: WHAT NEWLY MATCHES when
   `.bs-overlay` gains a `.bs-skin-*` class?

   The sheet contains exactly two `.bs-skin-* <descendant>` rules today:
       :5329  .bs-skin-classic .bs-card        { box-shadow: … }   (0,2,0)
       :5458  .bs-skin-classic .bs-langsw-menu { … }               (0,2,0)
   Neither newly matches. All 53 `bs-card` emissions in the app JS are written
   into a widget root's innerHTML; no `.bs-card` is ever emitted inside an
   overlay (the modal is `.bs-overlay-card.bs-game-modal`, a different class).
   The language menu is header chrome and never appears in an overlay.

   :5329 is nevertheless a landmine for the NEXT change, so decide it now: the
   moment any game modal emits a `.bs-card`, :5329 fires and gives it the
   light-skin shadow on `classic` while :5316's dark shadow applies on the other
   nine. That is almost certainly what you want — but it will have happened by
   accident. If a modal is ever going to use `.bs-card`, write the rule for it
   deliberately.

   The rules THIS FILE adds that newly match once the overlay is skinned:
   §1 (nineteen stage containers), §1b (three of them), §3 (`.bs-game-modal`)
   and §4.3 (three physical-material containers). §4.1, §4.2 and §4.4 match
   widget chrome that `classic` already reached before this package existed —
   §4.2 and §4.4 are fixes to defects that ship today.

   The other eight skins have no descendant rules at all, so a `.bs-skin-neon`
   overlay gets tokens and nothing else. That is correct and intended.
   ========================================================================== */

/* ============================================================================
   FULLSCREEN GAMES  +  CHINCHÓN TABLE POLISH
   ----------------------------------------------------------------------------
   Appended last on purpose. Everything here either introduces a new class or
   deliberately outranks an earlier rule, and being last means it does so by
   specificity that is written down rather than by accident of source order.
   ========================================================================== */

/* ---- 1. The game modal gets the width it was always written for ------------
   `.bs-game-modal` asks for 480px at :130 and `.bs-overlay-card` caps every
   overlay at 380px at :181. Both are (0,1,0), so the LATER one won and every
   game has been running 100px narrower than its author specified — which on a
   seven-card fan is the difference between reading the hand and guessing at it.
   Naming both classes states the intent at (0,2,0) so neither source order nor
   a future insertion can silently flip it back. */
.bs-overlay-card.bs-game-modal { max-width: 480px; }

/* ---- 2. Header tools ------------------------------------------------------ */
.bs-game-tools { display: flex; align-items: center; gap: 2px; }
/* The glyph is 13px; the CONTROL must not be. Only the ≤560px block at :6269
   sizes `.bs-x` up to 44px, which left this a 13px target on every tablet and
   desktop — and a maximise control is exactly what gets tapped on a tablet. */
.bs-fsbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; margin: -8px -6px -8px 0; border-radius: 10px;
}
.bs-fsbtn svg { display: block; }
/* `.bs-x` is coloured `--bs-neg` because it was only ever the close button.
   Red on "make this bigger" reads as a warning; the tool is neutral chrome. */
.bs-fsbtn { color: var(--bs-muted); }
.bs-fsbtn:hover, .bs-fsbtn[aria-pressed="true"] { color: var(--bs-text); }
/* One button, two glyphs: show the one that describes what the click will do. */
.bs-fsbtn .bs-fs-out { display: none; }
.bs-fs .bs-fsbtn .bs-fs-in { display: none; }
.bs-fs .bs-fsbtn .bs-fs-out { display: block; }

@media (max-width: 560px) {
  /* :6271 gives every `.bs-x` in the head a -9px right margin to sit flush
     with the panel edge. With two tools in the row that would punch a hole
     between them, so only the one that IS at the edge keeps it. */
  .bs-game-modal-head .bs-game-tools .bs-x { margin-right: 0; margin-left: 0; }
  .bs-game-modal-head .bs-game-tools .bs-x:last-child { margin-right: -9px; }
}

/* ---- 3. Fullscreen --------------------------------------------------------
   `.bs-fs` is set on the OVERLAY, which is also the element handed to the
   native Fullscreen API — so these rules describe the layout whether the API
   granted the request or refused it. :182 makes every overlay a scrolling
   flex column with `align-items:flex-start`; a maximised card has to undo that
   and own the viewport instead. */
.bs-overlay.bs-fs {
  align-items: stretch; justify-content: stretch;
  overflow: hidden; backdrop-filter: none;
  background: var(--bs-well);
  /* The overlay carries `padding:10px 12px 20px` so a windowed modal never
     touches the screen edge. Maximised, that padding is a 24px-wide strip of
     nothing down each side of the game — the card IS the window now. */
  padding: 0;
}
.bs-overlay.bs-fs > .bs-overlay-card {
  margin: 0; width: 100%; max-width: none; height: 100%; max-height: none;
  border: 0; border-radius: 0;
  display: flex; flex-direction: column;
  overflow-y: auto; overscroll-behavior: contain;
  /* Notches and home indicators sit over a genuinely edge-to-edge surface. */
  padding:
    max(16px, env(safe-area-inset-top))
    max(16px, env(safe-area-inset-right))
    max(16px, env(safe-area-inset-bottom))
    max(16px, env(safe-area-inset-left));
}
/* The games are laid out as a single column of stages. Stretched across a
   27-inch monitor that column becomes unreadable, so cap the measure and
   centre it — the stage art still gets the extra room via §5. */
.bs-overlay.bs-fs > .bs-overlay-card > * {
  width: 100%; max-width: 560px; margin-left: auto; margin-right: auto;
  flex: 0 0 auto;
}
/* A maximised game sits in the middle of the screen rather than pinned to the
   top with a gulf beneath it — but NOT via `justify-content:center`. On a
   scroll container that centres overflowing content by pushing it equally in
   both directions, and the part above the start edge cannot be scrolled back
   to: a game taller than the screen would lose its own header with no way to
   reach it. Auto margins centre identically and collapse to zero instead of
   going negative, so the tall case degrades to a normal top-aligned scroll.

   The bottom half is a pseudo-element, NOT `> :last-child`. bsCelebrate()
   appends an absolutely-positioned `.bs-fx-burst` to the card on every win, and
   although it adds no layout it still MATCHES :last-child — so the real last
   item would lose its auto margin and the whole game would jump down the screen
   for the 2.2s the coin shower lasts, at the exact moment the payout is read
   out. ::after is always last and is never a child, so nothing the JS appends
   can take it. */
.bs-overlay.bs-fs > .bs-overlay-card > :first-child { margin-top: auto; }
.bs-overlay.bs-fs > .bs-overlay-card::after {
  content: ''; flex: 0 0 auto; height: 0; margin-top: auto;
}
/* The burst is a full-bleed effects layer, not one of the stages §3 caps. */
.bs-overlay.bs-fs > .bs-overlay-card > .bs-fx-burst { max-width: none; margin: 0; }

/* ---- 4. Chinchón: the intro fan has to read as CARDS -----------------------
   Face-down cards carry only an inset highlight, so seven of them overlapped by
   17px merge into one orange mass — the first thing anyone sees when they open
   the game. A dark outer edge per card restores the seam, and a touch of
   shadow between neighbours gives the fan depth. */
.bs-chin-fan .bs-pcard-back {
  box-shadow:
    0 0 0 1.5px rgba(0, 0, 0, .55),
    0 10px 20px rgba(0, 0, 0, .5),
    inset 0 0 0 3px rgba(255, 255, 255, .18);
}
/* The outer cards of the fan are pushed DOWN by --dy, which walked them over
   the caption underneath. Give the fan the room its own geometry needs. */
.bs-chin-intro .bs-chin-fan { padding-bottom: 20px; min-height: 118px; }
.bs-chin-intro-title { margin-top: 8px; }

/* ---- 5. Chinchón in fullscreen -------------------------------------------
   The table is the point of the game, so it is the thing that grows. Card size
   is driven through variables (§6) purely so this block can move it. */
.bs-overlay.bs-fs .bs-chin-intro,
.bs-overlay.bs-fs .bs-chin-table,
.bs-overlay.bs-fs .bs-chin-handwrap { max-width: 720px; }

@media (min-width: 720px) and (min-height: 620px) {
  .bs-overlay.bs-fs { --bs-pcw: 78px; --bs-pch: 111px; --bs-chin-lap: -20px; }
  .bs-overlay.bs-fs .bs-pcard-suit { font-size: 35px; }
  .bs-overlay.bs-fs .bs-pcard-corner { font-size: 13px; }
  .bs-overlay.bs-fs .bs-chin-fan { min-height: 142px; padding-top: 32px; }
  .bs-overlay.bs-fs .bs-chin-dwval { font-size: 46px; }
}
@media (min-width: 1024px) and (min-height: 760px) {
  .bs-overlay.bs-fs { --bs-pcw: 92px; --bs-pch: 131px; --bs-chin-lap: -22px; }
  .bs-overlay.bs-fs .bs-pcard-suit { font-size: 41px; }
  .bs-overlay.bs-fs .bs-pcard-corner { font-size: 15px; }
  .bs-overlay.bs-fs .bs-chin-fan { min-height: 168px; padding-top: 38px; }
  .bs-overlay.bs-fs .bs-chin-dwval { font-size: 54px; }
  .bs-overlay.bs-fs .bs-chin-intro,
  .bs-overlay.bs-fs .bs-chin-table,
  .bs-overlay.bs-fs .bs-chin-handwrap { max-width: 820px; }
}

/* ---- 6. Card metrics as variables ----------------------------------------
   The unset-variable fallbacks reproduce each deck's EXISTING size, so this
   changes nothing outside a fullscreen table.

   The Spanish deck needs its own three lines. A Chinchón card carries both
   classes (`bs-pcard bs-sp-card`), and `.bs-sp-card` declares 56x80 at :1289
   and 46x66 under `max-width:420px` at :1318 — all three selectors are
   (0,1,0), and this block is 7000 lines later, so a bare `.bs-pcard` rule here
   would silently win and inflate every card on a handset: 46->62px across a
   seven-card fan overflows a 375px screen and `.bs-overlay{overflow-x:hidden}`
   then clips the last card of the player's own hand with no way to scroll to
   it. Restating the Spanish sizes as the fallbacks keeps the phone layout
   exactly as it was while still letting §5 grow the table in fullscreen. */
.bs-pcard, .bs-pcard-slot { width: var(--bs-pcw, 62px); height: var(--bs-pch, 88px); }
.bs-sp-card { width: var(--bs-pcw, 56px); height: var(--bs-pch, 80px); }
.bs-chin-slot + .bs-chin-slot { margin-left: var(--bs-chin-lap, -17px); }
/* Last, not first: a media query adds no specificity, so the narrow-screen
   rules only hold if they come AFTER their full-width counterparts. */
@media (max-width: 420px) {
  .bs-sp-card { width: var(--bs-pcw, 46px); height: var(--bs-pch, 66px); }
  .bs-chin-slot + .bs-chin-slot { margin-left: var(--bs-chin-lap, -15px); }
}

/* ---- 7. The embedded / aggregator game ------------------------------------
   `.bs-game-frame` is a fixed `62vh` box, which is right in a windowed modal
   and absurd once the modal IS the screen. Maximised, the frame takes whatever
   the header leaves — the point of maximising a provider game is the game. */
.bs-overlay.bs-fs > .bs-game-embed { max-width: none; }
/* §3 caps every direct child at 560px and pins it to `flex:0 0 auto` so a
   column of stages stays readable. A game frame is the exception on both
   counts: it is the content, not a stage in a column. */
.bs-overlay.bs-fs > .bs-game-embed > .bs-game-frame {
  height: auto; max-width: none; flex: 1 1 auto; min-height: 0; border-radius: 8px;
}
.bs-overlay.bs-fs > .bs-game-embed > .bs-game-modal-head { flex: 0 0 auto; }

/* ---- 8. Your own PvP table in the lobby list ------------------------------
   The list mixes your open seat in with strangers'. Marking it is what stops a
   player clicking "Join" on their own table and being told they cannot play
   against themselves — an error for doing exactly what the row offered. */
.bs-chin-pvp-row-mine {
  border-color: var(--bs-gold);
  box-shadow: inset 0 0 0 1px rgba(var(--bs-gold-rgb), .25);
}
.bs-chin-pvp-yours {
  margin-left: 6px; padding: 1px 7px; border-radius: 999px;
  font-size: 9px; font-weight: 900; letter-spacing: .1em; text-transform: uppercase;
  color: var(--bs-on-gold); background: var(--bs-gold); vertical-align: middle;
}

/* ---- 9. Reduced motion ---------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .bs-overlay.bs-fs, .bs-overlay.bs-fs > .bs-overlay-card { transition: none !important; }
}

/* ==========================================================================
   10. PER-GAME SCENES — every title opens into its own room
   ==========================================================================
   The skin block above (section "PER-GAME SKIN") dresses the modal's CHROME
   per title: header band, edge, glow, accent. That fixed the tile-to-table
   jump, but all 24 games still shared one empty ground and one set of
   furniture — and that furniture is named `bs-slot-*`, because the slot
   game's controls were reused as the generic chrome for everything. A
   roulette table was reading its balance off a slot machine's chip.

   So this block gives each game a GROUND and its own FURNITURE MATERIAL.

   COLOUR IS NOT AUTHORED HERE, AND THAT IS THE WHOLE TRICK. There are ten
   brand skins, one of them light (classic) and one desaturating (mono).
   Hard-coding a green felt for roulette would look correct on tiger and
   wrong on every other brand, and unreadable on classic. So a scene is
   GEOMETRY and MOTION — pegs, hexes, arcs, lanes, weave — painted in the
   title's own `--bs-g-*` hue, which the skin already controls. Change the
   brand and every scene re-tints itself for free.

   Each scene sets a handful of variables and the scaffolding consumes them:

     --sc-pat     the ground pattern (background-image layers)
     --sc-size    its tile size
     --sc-op      how far it comes up out of the dark  (0.10–0.24)
     --sc-anim    ambient motion, or `none`
     --sc-rail    what the divider rail is made of
     --sc-edge    furniture roundness — felt is soft, arcade is square
     --sc-chip    the balance chip's material

   LEGIBILITY IS PRESERVED DELIBERATELY. The ground never rises above .24,
   the pattern sits BEHIND content on a negative z-index, and no scene
   touches the colour of a number a player reads. That is the same rule the
   skin block set: tinting a surface someone reads a figure off is a
   legibility bug wearing a costume.
   ========================================================================== */

/* ---- scaffolding --------------------------------------------------------- */

/* The ground. `::before` is the header's accent bar, so the scene takes
   `::after` — on a negative z-index so it paints after the modal's own
   background but before any content, never over a control.

   `isolation: isolate` IS LOAD-BEARING, and this is the whole feature.
   A negative-z child only paints above its parent's background when that
   parent forms a stacking context. `.bs-game-modal` is position:relative
   with z-index:auto, which forms none — so the scene dropped into the
   OVERLAY's context instead and painted behind the modal's opaque
   `--bs-panel` background. Every ground rendered, correctly, entirely
   invisible: the CSS reads right, the computed styles read right, and the
   feature does nothing at all. Isolating costs nothing visually and is the
   only reason any of this is on screen. */
.bs-overlay[data-bs-game] .bs-game-modal.bs-themed {
  isolation: isolate;
}
.bs-overlay[data-bs-game] .bs-game-modal.bs-themed::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background-image: var(--sc-pat, none);
  background-size: var(--sc-size, auto);
  background-position: center;
  opacity: var(--sc-op, .16);
  animation: var(--sc-anim, none);
}

/* The furniture. These four are the pieces every game shares, so they are
   the pieces that made every game feel the same. Scoped through the
   overlay's attribute, which outranks the bare `.bs-rail` base rule on
   specificity — no source-order fight, unlike the vehicle block above. */
.bs-overlay[data-bs-game] .bs-rail {
  background: var(--sc-rail, linear-gradient(90deg, transparent, var(--bs-orange), transparent));
  height: var(--sc-rail-h, 3px);
  border-radius: var(--sc-edge, 2px);
  opacity: var(--sc-rail-op, .5);
}
.bs-overlay[data-bs-game] .bs-slot-bal {
  /* Stays a BLOCK. Switching it to inline-block would drop the centring the
     base rule gets from text-align, and slide every game's balance to the
     left. fit-content + auto margins centres the chip without that. */
  width: fit-content;
  margin-left: auto; margin-right: auto;
  padding: 3px 12px;
  border-radius: var(--sc-edge, 999px);
  background: var(--sc-chip, transparent);
  border: 1px solid hsl(var(--bs-g-h) var(--bs-g-s) 40% / .28);
  letter-spacing: var(--sc-track, normal);
}
.bs-overlay[data-bs-game] .bs-slot-msg {
  font-family: var(--sc-font, inherit);
  letter-spacing: var(--sc-track, normal);
  text-transform: var(--sc-case, none);
}

/* ---- ambient motion ------------------------------------------------------ */
@keyframes bs-sc-drift  { to   { background-position: 140px center; } }
@keyframes bs-sc-rise   { to   { background-position: center -160px; } }
@keyframes bs-sc-fall   { to   { background-position: center 160px; } }
@keyframes bs-sc-sway   { 50%  { background-position: 22px center; } }
@keyframes bs-sc-breathe{ 50%  { opacity: .06; } }

/* ======================= ORIGINALS — each its own world =================== */

/* CRASH — altitude. Thin cloud strata that fall as you climb past them. */
.bs-overlay[data-bs-game="crash"] {
  --sc-pat:
    linear-gradient(hsl(var(--bs-g-h) 80% 70% / .30) 1px, transparent 1px),
    radial-gradient(60% 40% at 50% 120%, hsl(var(--bs-g-h) 90% 60% / .38), transparent 70%);
  --sc-size: 100% 74px, 100% 100%;
  --sc-op: .20;
  --sc-anim: bs-sc-fall 9s linear infinite;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 90% 62%), transparent);
  --sc-edge: 1px;
  --sc-track: .06em;
}

/* LIMBO — a shaft. Verticals converging on a vanishing point. */
.bs-overlay[data-bs-game="limbo"] {
  --sc-pat:
    repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 80% 62% / .26) 0 1px, transparent 1px 46px),
    radial-gradient(50% 34% at 50% 0%, hsl(var(--bs-g-h) 90% 58% / .40), transparent 72%);
  --sc-size: auto, 100% 100%;
  --sc-op: .18;
  --sc-anim: bs-sc-rise 7s linear infinite;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 92% 64%), transparent);
  --sc-edge: 1px;
}

/* MINES — underground. Hex seams, and nothing moves down here. */
.bs-overlay[data-bs-game="mines"] {
  --sc-pat:
    repeating-linear-gradient( 60deg, hsl(var(--bs-g-h) 70% 46% / .22) 0 1px, transparent 1px 26px),
    repeating-linear-gradient(-60deg, hsl(var(--bs-g-h) 70% 46% / .22) 0 1px, transparent 1px 26px),
    radial-gradient(70% 60% at 50% 40%, hsl(var(--bs-g-h) 80% 30% / .5), transparent 74%);
  --sc-size: auto, auto, 100% 100%;
  --sc-op: .22;
  --sc-anim: none;
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 75% 52%) 0 7px, transparent 7px 13px);
  --sc-rail-h: 2px;
  --sc-edge: 2px;
}

/* PLINKO — the pegboard itself, staggered as the real one is. */
.bs-overlay[data-bs-game="plinko"] {
  --sc-pat:
    radial-gradient(circle, hsl(var(--bs-g-h) 85% 66% / .40) 1.6px, transparent 1.8px),
    radial-gradient(circle, hsl(var(--bs-g-h) 85% 66% / .40) 1.6px, transparent 1.8px);
  --sc-size: 34px 34px, 34px 34px;
  --sc-op: .20;
  --sc-anim: none;
  --sc-rail: repeating-radial-gradient(circle at center, hsl(var(--bs-g-h) 85% 66%) 0 2px, transparent 2px 9px);
  --sc-edge: 999px;
}
.bs-overlay[data-bs-game="plinko"] .bs-game-modal.bs-themed::after { background-position: 0 0, 17px 17px; }

/* WHEEL — a fairground. Spokes radiating from the hub, turning slowly. */
.bs-overlay[data-bs-game="wheel"] {
  --sc-pat:
    repeating-conic-gradient(from 0deg at 50% 50%,
      hsl(var(--bs-g-h) 85% 60% / .26) 0deg 6deg, transparent 6deg 18deg);
  --sc-size: 100% 100%;
  --sc-op: .17;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 88% 62%), transparent);
  --sc-edge: 999px;
}
/* The spokes do NOT rotate. The scene layer is full-bleed and the modal has
   no overflow clip, so a rotating square would swing its corners outside the
   card's rounded edge on every frame. A wheel at rest still reads as a wheel. */

/* DICE — a shallow felt tray, grain running one way. */
.bs-overlay[data-bs-game="dice"] {
  --sc-pat:
    repeating-linear-gradient(45deg, hsl(var(--bs-g-h) 50% 50% / .16) 0 2px, transparent 2px 6px),
    radial-gradient(80% 70% at 50% 30%, hsl(var(--bs-g-h) 60% 34% / .40), transparent 76%);
  --sc-size: auto, 100% 100%;
  --sc-op: .18;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 60% 56%), transparent);
  --sc-edge: 6px;
}

/* HILO — a dealt column. Soft card-shaped blocks stacked up the ground. */
.bs-overlay[data-bs-game="hilo"] {
  --sc-pat:
    repeating-linear-gradient(0deg, hsl(var(--bs-g-h) 60% 56% / .18) 0 1px, transparent 1px 58px),
    radial-gradient(60% 50% at 50% 50%, hsl(var(--bs-g-h) 70% 38% / .38), transparent 74%);
  --sc-size: auto, 100% 100%;
  --sc-op: .16;
  --sc-anim: bs-sc-rise 22s linear infinite;
  /* A dealt edge, not the slot cabinet's bar — hilo is cards. */
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 70% 58%) 0 18px, transparent 18px 24px);
  --sc-edge: 8px;
}

/* KENO — a draw hall. A number grid, lit from above. */
.bs-overlay[data-bs-game="keno"] {
  --sc-pat:
    linear-gradient(hsl(var(--bs-g-h) 70% 58% / .20) 1px, transparent 1px),
    linear-gradient(90deg, hsl(var(--bs-g-h) 70% 58% / .20) 1px, transparent 1px),
    radial-gradient(50% 40% at 50% 0%, hsl(var(--bs-g-h) 80% 52% / .34), transparent 70%);
  --sc-size: 30px 30px, 30px 30px, 100% 100%;
  --sc-op: .16;
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 75% 60%) 0 3px, transparent 3px 8px);
  --sc-edge: 3px;
  --sc-track: .08em;
}

/* COINFLIP — struck metal. Concentric turning marks, no motion. */
.bs-overlay[data-bs-game="coinflip"] {
  --sc-pat:
    repeating-radial-gradient(circle at 50% 46%,
      hsl(var(--bs-g-h) 60% 62% / .20) 0 1px, transparent 1px 11px),
    radial-gradient(46% 40% at 50% 46%, hsl(var(--bs-g-h) 70% 46% / .40), transparent 72%);
  --sc-size: 100% 100%;
  --sc-op: .19;
  --sc-anim: none;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 55% 70%), hsl(var(--bs-g-h) 40% 46%), transparent);
  --sc-edge: 999px;
}

/* SCRATCH — a printed ticket. Guilloché security wash and a paper tooth. */
.bs-overlay[data-bs-game="scratch"] {
  --sc-pat:
    repeating-linear-gradient( 22deg, hsl(var(--bs-g-h) 60% 60% / .14) 0 1px, transparent 1px 7px),
    repeating-linear-gradient(-22deg, hsl(var(--bs-g-h) 60% 60% / .14) 0 1px, transparent 1px 7px);
  --sc-size: auto;
  --sc-op: .20;
  --sc-anim: none;
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 60% 64%) 0 5px, transparent 5px 10px);
  --sc-rail-h: 2px;
  --sc-edge: 2px;
  --sc-case: uppercase;
  --sc-track: .10em;
}

/* ============================ SLOTS ====================================== */

/* SLOTS — a cabinet. Warm vertical reel bands behind the glass. */
.bs-overlay[data-bs-game="slots"] {
  --sc-pat:
    repeating-linear-gradient(90deg,
      hsl(var(--bs-g-h) 60% 52% / .20) 0 1px, transparent 1px 62px),
    radial-gradient(70% 54% at 50% 34%, hsl(var(--bs-g-h) 70% 42% / .42), transparent 74%);
  --sc-size: auto, 100% 100%;
  --sc-op: .17;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 70% 58%), transparent);
  --sc-edge: 6px;
}
/* FIVE-REEL — the same cabinet, a wider machine. */
.bs-overlay[data-bs-game="five_reel_slot"] {
  --sc-pat:
    repeating-linear-gradient(90deg,
      hsl(var(--bs-g-h) 60% 52% / .20) 0 1px, transparent 1px 40px),
    radial-gradient(76% 54% at 50% 34%, hsl(var(--bs-g-h) 70% 42% / .42), transparent 74%);
  --sc-size: auto, 100% 100%;
  --sc-op: .17;
  /* Five paylines' worth of bar, so the wider machine reads wider. */
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 70% 58%) 0 34px, transparent 34px 40px);
  --sc-edge: 6px;
}

/* ==================== TABLE GAMES — one room each ========================
   The skin block deliberately gave all eight table games ONE felt identity,
   on the reasoning that a roulette wheel and a baccarat shoe belong to the
   same room. They are now separated on request. They stay recognisably
   table games — the weave is common to all of them, so the family still
   reads as a family — but each gets its own layout on that felt, so no two
   are the same table.
   ========================================================================= */

/* The shared felt weave, inherited by every table game below. */
.bs-overlay[data-bs-game="roulette"],
.bs-overlay[data-bs-game="blackjack"],
.bs-overlay[data-bs-game="baccarat"],
.bs-overlay[data-bs-game="craps"],
.bs-overlay[data-bs-game="sicbo"],
.bs-overlay[data-bs-game="three_card_poker"],
.bs-overlay[data-bs-game="caribbean_stud"],
.bs-overlay[data-bs-game="chinchon"] {
  --sc-felt: repeating-linear-gradient(45deg, hsl(var(--bs-g-h) 30% 40% / .10) 0 1px, transparent 1px 4px);
  --sc-op: .19;
  --sc-anim: none;
  --sc-edge: 10px;
  --sc-rail-h: 2px;
}

/* ROULETTE — the wheel's own geometry: a fret ring above the felt. */
.bs-overlay[data-bs-game="roulette"] {
  --sc-pat:
    repeating-conic-gradient(from 0deg at 50% 34%,
      hsl(var(--bs-g-h) 55% 56% / .30) 0deg 4.86deg, transparent 4.86deg 9.72deg),
    radial-gradient(circle at 50% 34%, transparent 52%, hsl(var(--bs-g-h) 45% 30% / .5) 53%),
    var(--sc-felt);
  --sc-size: 100% 100%, 100% 100%, auto;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 45% 62%), transparent);
}

/* BLACKJACK — the dealer's arc, and the box seats along it. */
.bs-overlay[data-bs-game="blackjack"] {
  --sc-pat:
    radial-gradient(circle at 50% -22%, transparent 61%, hsl(var(--bs-g-h) 45% 58% / .34) 62%, transparent 64%),
    radial-gradient(circle at 50% -14%, transparent 70%, hsl(var(--bs-g-h) 45% 58% / .22) 71%, transparent 73%),
    var(--sc-felt);
  --sc-size: 100% 100%, 100% 100%, auto;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 45% 60%), transparent);
}

/* BACCARAT — the big-road grid the shoe is scored on. */
.bs-overlay[data-bs-game="baccarat"] {
  --sc-pat:
    linear-gradient(hsl(var(--bs-g-h) 40% 58% / .18) 1px, transparent 1px),
    linear-gradient(90deg, hsl(var(--bs-g-h) 40% 58% / .18) 1px, transparent 1px),
    var(--sc-felt);
  --sc-size: 22px 22px, 22px 22px, auto;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 40% 64%), transparent);
  --sc-track: .06em;
}

/* CRAPS — the pit: rail bumpers down both long sides, pyramid rubber. */
.bs-overlay[data-bs-game="craps"] {
  --sc-pat:
    repeating-linear-gradient(90deg,
      hsl(var(--bs-g-h) 50% 54% / .26) 0 2px, transparent 2px 14px),
    linear-gradient(180deg, hsl(var(--bs-g-h) 45% 40% / .34) 0 8%, transparent 8% 92%, hsl(var(--bs-g-h) 45% 40% / .34) 92%),
    var(--sc-felt);
  --sc-size: 100% 9%, 100% 100%, auto;
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 50% 58%) 0 4px, transparent 4px 9px);
}

/* SIC BO — the lacquered cage: a diamond lattice, not a weave. */
.bs-overlay[data-bs-game="sicbo"] {
  --sc-pat:
    repeating-linear-gradient( 45deg, hsl(var(--bs-g-h) 55% 56% / .22) 0 1px, transparent 1px 18px),
    repeating-linear-gradient(-45deg, hsl(var(--bs-g-h) 55% 56% / .22) 0 1px, transparent 1px 18px),
    var(--sc-felt);
  --sc-size: auto, auto, auto;
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 55% 60%) 0 2px, transparent 2px 6px);
  --sc-edge: 3px;
}

/* THREE CARD POKER — three betting circles, in a row, as printed. */
.bs-overlay[data-bs-game="three_card_poker"] {
  --sc-pat:
    radial-gradient(circle at 26% 62%, transparent 8%, hsl(var(--bs-g-h) 45% 58% / .30) 8.6%, transparent 9.4%),
    radial-gradient(circle at 50% 62%, transparent 8%, hsl(var(--bs-g-h) 45% 58% / .30) 8.6%, transparent 9.4%),
    radial-gradient(circle at 74% 62%, transparent 8%, hsl(var(--bs-g-h) 45% 58% / .30) 8.6%, transparent 9.4%),
    var(--sc-felt);
  --sc-size: 100% 100%, 100% 100%, 100% 100%, auto;
  /* Three marks for three cards — the rail states the game. */
  --sc-rail: repeating-linear-gradient(90deg, transparent 0 28%, hsl(var(--bs-g-h) 45% 62%) 28% 38%, transparent 38% 100%);
}

/* CARIBBEAN STUD — the progressive drop slot and its arc of seats. */
.bs-overlay[data-bs-game="caribbean_stud"] {
  --sc-pat:
    radial-gradient(circle at 50% 118%, transparent 44%, hsl(var(--bs-g-h) 48% 60% / .30) 45%, transparent 47%),
    repeating-linear-gradient(90deg, transparent 0 46%, hsl(var(--bs-g-h) 50% 62% / .26) 46% 54%, transparent 54% 100%),
    var(--sc-felt);
  --sc-size: 100% 100%, 100% 26px, auto;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 50% 62%), transparent);
}

/* CHINCHÓN — a Spanish card table: tile floor under a smaller cloth. */
.bs-overlay[data-bs-game="chinchon"] {
  --sc-pat:
    repeating-linear-gradient( 45deg, hsl(var(--bs-g-h) 40% 56% / .16) 0 1px, transparent 1px 30px),
    repeating-linear-gradient(-45deg, hsl(var(--bs-g-h) 40% 56% / .16) 0 1px, transparent 1px 30px),
    radial-gradient(58% 48% at 50% 50%, hsl(var(--bs-g-h) 45% 34% / .42), transparent 70%);
  --sc-size: auto, auto, 100% 100%;
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 45% 60%) 0 3px, transparent 3px 11px);
  --sc-edge: 12px;
}

/* ===================== ARCADE AND SPORT ================================== */

/* VIDEO POKER — a cabinet CRT. Scanlines and a curved phosphor bloom. */
.bs-overlay[data-bs-game="video_poker"] {
  --sc-pat:
    repeating-linear-gradient(0deg, hsl(var(--bs-g-h) 70% 60% / .26) 0 1px, transparent 1px 3px),
    radial-gradient(70% 58% at 50% 46%, hsl(var(--bs-g-h) 80% 44% / .42), transparent 76%);
  --sc-size: auto, 100% 100%;
  --sc-op: .18;
  --sc-anim: bs-sc-fall 14s linear infinite;
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 80% 62%) 0 6px, transparent 6px 10px);
  --sc-edge: 0px;
  --sc-case: uppercase;
  --sc-track: .12em;
  --sc-font: ui-monospace, "JetBrains Mono", "SFMono-Regular", Menlo, monospace;
}

/* PENALTY SHOOTOUT — a mown pitch, and the net's mesh above it. */
.bs-overlay[data-bs-game="penalty_shootout"] {
  --sc-pat:
    repeating-linear-gradient( 60deg, hsl(var(--bs-g-h) 45% 62% / .14) 0 1px, transparent 1px 12px),
    repeating-linear-gradient(-60deg, hsl(var(--bs-g-h) 45% 62% / .14) 0 1px, transparent 1px 12px),
    repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 50% 44% / .22) 0 42px, transparent 42px 84px);
  --sc-size: auto, auto, auto;
  --sc-op: .18;
  --sc-anim: none;
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 50% 64%) 0 14px, transparent 14px 28px);
  --sc-edge: 2px;
}

/* SNOOKER — baize under low table lights, with the cushion line. */
.bs-overlay[data-bs-game="snooker"] {
  --sc-pat:
    radial-gradient(38% 26% at 50% 12%, hsl(var(--bs-g-h) 40% 70% / .30), transparent 70%),
    linear-gradient(180deg, transparent 0 6%, hsl(var(--bs-g-h) 45% 34% / .40) 6% 7%, transparent 7%),
    repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 35% 44% / .10) 0 1px, transparent 1px 3px);
  --sc-size: 100% 100%, 100% 100%, auto;
  --sc-op: .20;
  --sc-anim: none;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 40% 58%), transparent);
  --sc-edge: 999px;
}

/* CRICKET — the square: a cut strip, with the ring boundary beyond it. */
.bs-overlay[data-bs-game="cricket"] {
  --sc-pat:
    linear-gradient(90deg, transparent 0 40%, hsl(var(--bs-g-h) 40% 62% / .22) 40% 60%, transparent 60%),
    radial-gradient(circle at 50% 50%, transparent 63%, hsl(var(--bs-g-h) 45% 62% / .26) 64%, transparent 66%),
    repeating-linear-gradient(0deg, hsl(var(--bs-g-h) 40% 50% / .10) 0 1px, transparent 1px 9px);
  --sc-size: 100% 100%, 100% 100%, auto;
  --sc-op: .18;
  --sc-anim: none;
  /* Stumps: three uprights, evenly set. */
  --sc-rail: repeating-linear-gradient(90deg, transparent 0 46%, hsl(var(--bs-g-h) 45% 62%) 46% 48%, transparent 48% 52%, hsl(var(--bs-g-h) 45% 62%) 52% 54%, transparent 54% 100%);
  --sc-edge: 4px;
}

/* LIVE — a broadcast gallery: scanline sweep off a studio wall. */
.bs-overlay[data-bs-game="live"] {
  --sc-pat:
    repeating-linear-gradient(0deg, hsl(var(--bs-g-h) 60% 60% / .18) 0 1px, transparent 1px 5px),
    radial-gradient(66% 50% at 50% 40%, hsl(var(--bs-g-h) 70% 44% / .38), transparent 74%);
  --sc-size: auto, 100% 100%;
  --sc-op: .16;
  --sc-anim: bs-sc-breathe 6s ease-in-out infinite;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 70% 60%), transparent);
  --sc-edge: 3px;
}

/* VIRTUALS — a rendered track seen from above: lanes and a camera sweep.
   Deliberately NOT the live gallery. A simulated race and a streamed studio
   are different products and a player should not have to read the header to
   tell which one they opened. */
.bs-overlay[data-bs-game="virtuals"] {
  --sc-pat:
    repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 55% 58% / .20) 0 2px, transparent 2px 30px),
    radial-gradient(circle at 50% 50%, transparent 54%, hsl(var(--bs-g-h) 60% 56% / .24) 55%, transparent 58%),
    radial-gradient(70% 50% at 50% 30%, hsl(var(--bs-g-h) 65% 40% / .36), transparent 74%);
  --sc-size: auto, 100% 100%, 100% 100%;
  --sc-op: .17;
  --sc-anim: bs-sc-drift 11s linear infinite;
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 60% 62%) 0 10px, transparent 10px 16px);
  --sc-edge: 2px;
}

/* ---- skin guards --------------------------------------------------------- */

/* CLASSIC is the light skin, and it needs the ground DARKENED, not dimmed.

   This block first halved the opacity, on the reasoning that a ground built
   to lift out of a dark panel becomes grime on ivory. Measured, that was
   wrong in a way that is easy to miss: the scenes paint a mid-light ink, and
   a mid-light ink on white is already low contrast, so halving it took the
   three light brands — Ludgate, Lumo and Chinchón, half the estate — to a
   perceptual delta of ΔL* 0.93. That is at or below the threshold of
   perception. The feature was on, and on those brands nobody could see it.

   Worth recording HOW that hid: measured as raw luminance the light skin
   looked 16x MORE visible than the dark ones, because a dark stripe on white
   moves luminance far more than a light stripe on near-black. Luminance is
   the wrong instrument here. In perceptual lightness the dark skins sit at
   ΔL* ~2.9 and the light skin sat at 0.93.

   So the ink is darkened to 60% instead, at the scene's own opacity, which
   measures ΔL* 2.88 (max 5.01) against the dark skins' 2.9 (max 5.55) — the
   same texture, equally readable, on ivory instead of ink. Darkening keeps
   the title's hue rather than washing it out, so a brand still tints its own
   grounds. */
.bs-overlay.bs-skin-classic[data-bs-game] .bs-game-modal.bs-themed::after {
  filter: brightness(.6);
}

/* MONO carries no colour but the live dot; the scene follows that rule. */
.bs-overlay.bs-skin-mono[data-bs-game] .bs-game-modal.bs-themed::after {
  filter: saturate(0);
}

/* ---- reduced motion ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .bs-overlay[data-bs-game] .bs-game-modal.bs-themed::after { animation: none !important; }
}

/* ==========================================================================
   11. PER-GAME CELEBRATIONS — what each game throws when you win
   ==========================================================================
   bsCelebrate() is one function called from every game, and it showered gold
   coins for all of them. That is the emotional peak of a session, and it was
   the single most shared thing left: a snooker table, a crash graph and a
   penalty shootout all paid out in identical casino coins.

   The JS is untouched — it still emits N particles with random drift,
   rotation, scale and delay. Only what a particle IS changes here, through
   the variables the base `.bs-fx-coin` rule now reads:

     --fx-w / --fx-h   its size
     --fx-radius       its shape (50% coin, 2px card, 0 pixel)
     --fx-ink          what it is made of
     --fx-shadow       how it catches light
     --fx-anim         which way it travels
     --fx-ease         and how it moves

   DIRECTION IS PART OF THE IDENTITY. Coins fall because coins fall. A crash
   win is altitude, so its sparks RISE; limbo is a shaft, so its motes rise
   too. Getting that backwards is the sort of thing that reads as wrong long
   before a player can say why.

   Colour still comes from the skin wherever it can — `--bs-g-h` is the
   title's own hue — so these re-tint per brand exactly as the grounds do.
   The few that are deliberately literal (a red snooker ball, a green baize
   chip) are things a player recognises by colour, where inheriting the brand
   would destroy the reference rather than serve it.
   ========================================================================== */

@keyframes bs-fx-rise {
  0%   { transform:translate(0,0) rotate(0) scale(var(--bs-fx-scale,1)); opacity:0; }
  14%  { opacity:1; }
  100% { transform:translate(var(--bs-fx-drift,0), -420px) rotate(var(--bs-fx-rot,360deg)) scale(var(--bs-fx-scale,1)); opacity:0; }
}
/* Confetti does not fall straight — it sheds speed and swings. */
@keyframes bs-fx-flutter {
  0%   { transform:translate(0,0) rotate(0) scale(var(--bs-fx-scale,1)); opacity:0; }
  10%  { opacity:1; }
  35%  { transform:translate(calc(var(--bs-fx-drift,0) * .5), 150px) rotate(calc(var(--bs-fx-rot,360deg) * .4)) scale(var(--bs-fx-scale,1)); }
  70%  { transform:translate(calc(var(--bs-fx-drift,0) * -.3), 290px) rotate(calc(var(--bs-fx-rot,360deg) * .8)) scale(var(--bs-fx-scale,1)); }
  100% { transform:translate(var(--bs-fx-drift,0), 430px) rotate(var(--bs-fx-rot,360deg)) scale(var(--bs-fx-scale,1)); opacity:0; }
}

/* ---- originals ----------------------------------------------------------- */

/* CRASH — embers off the climb. They go UP, because the win was altitude. */
.bs-overlay[data-bs-game="crash"] {
  --fx-w: 7px; --fx-h: 7px; --fx-radius: 50%;
  --fx-ink: radial-gradient(circle at 40% 35%, #fff, hsl(var(--bs-g-h) 95% 62%) 45%, hsl(var(--bs-g-h) 90% 42%) 100%);
  --fx-shadow: 0 0 12px hsl(var(--bs-g-h) 95% 60% / .8);
  --fx-anim: bs-fx-rise; --fx-ease: cubic-bezier(.2,.6,.4,1);
}
/* LIMBO — motes drifting up the shaft. */
.bs-overlay[data-bs-game="limbo"] {
  --fx-w: 5px; --fx-h: 5px; --fx-radius: 50%;
  --fx-ink: radial-gradient(circle, #fff, hsl(var(--bs-g-h) 92% 66%) 60%, transparent 100%);
  --fx-shadow: 0 0 14px hsl(var(--bs-g-h) 92% 64% / .9);
  --fx-anim: bs-fx-rise; --fx-ease: linear;
}
/* MINES — gem shards. Angular, because nothing round comes out of a mine. */
.bs-overlay[data-bs-game="mines"] {
  --fx-w: 11px; --fx-h: 13px; --fx-radius: 2px 8px 2px 8px;
  --fx-ink: linear-gradient(140deg, #fff 4%, hsl(var(--bs-g-h) 80% 62%) 40%, hsl(var(--bs-g-h) 85% 34%) 100%);
  --fx-shadow: 0 0 9px hsl(var(--bs-g-h) 85% 55% / .6);
}
/* PLINKO — the balls themselves, still bouncing. */
.bs-overlay[data-bs-game="plinko"] {
  --fx-w: 12px; --fx-h: 12px;
  --fx-ink: radial-gradient(circle at 32% 28%, #fff, hsl(var(--bs-g-h) 88% 68%) 44%, hsl(var(--bs-g-h) 85% 44%) 100%);
  --fx-shadow: 0 0 10px hsl(var(--bs-g-h) 88% 62% / .7), inset 0 -3px 4px rgba(0,0,0,.35);
  --fx-ease: cubic-bezier(.5,-0.3,.6,1.3);
}
/* WHEEL — fairground confetti ribbons. */
.bs-overlay[data-bs-game="wheel"] {
  --fx-w: 7px; --fx-h: 16px; --fx-radius: 1px;
  --fx-ink: linear-gradient(180deg, hsl(var(--bs-g-h) 90% 68%), hsl(calc(var(--bs-g-h) + 40) 90% 56%));
  --fx-shadow: none; --fx-anim: bs-fx-flutter; --fx-ease: linear;
}
/* DICE — pips shaken out of the cup. */
.bs-overlay[data-bs-game="dice"] {
  --fx-w: 10px; --fx-h: 10px; --fx-radius: 3px;
  --fx-ink: linear-gradient(150deg, #fdfdfd, #dfe4ec 70%, #b9c0cc);
  --fx-shadow: 0 0 7px rgba(255,255,255,.35), inset 0 -2px 3px rgba(0,0,0,.28);
}
/* HILO — card corners. */
.bs-overlay[data-bs-game="hilo"] {
  --fx-w: 12px; --fx-h: 17px; --fx-radius: 2px;
  --fx-ink: linear-gradient(160deg, #fff 55%, hsl(var(--bs-g-h) 60% 74%) 100%);
  --fx-shadow: 0 1px 5px rgba(0,0,0,.4); --fx-anim: bs-fx-flutter;
}
/* KENO — drawn balls, lighter than coins and slower to settle. */
.bs-overlay[data-bs-game="keno"] {
  --fx-w: 15px; --fx-h: 15px;
  --fx-ink: radial-gradient(circle at 34% 28%, #fff 12%, hsl(var(--bs-g-h) 75% 62%) 55%, hsl(var(--bs-g-h) 78% 38%) 100%);
  --fx-shadow: inset 0 -3px 5px rgba(0,0,0,.3), 0 0 8px hsl(var(--bs-g-h) 75% 58% / .5);
  --fx-ease: cubic-bezier(.4,.05,.5,1);
}
/* COINFLIP — struck coins, edge-on and spinning. */
.bs-overlay[data-bs-game="coinflip"] {
  --fx-w: 8px; --fx-h: 16px; --fx-radius: 50%;
  --fx-ink: linear-gradient(90deg, hsl(var(--bs-g-h) 40% 42%), hsl(var(--bs-g-h) 45% 82%) 45%, hsl(var(--bs-g-h) 40% 46%));
  --fx-shadow: 0 0 9px hsl(var(--bs-g-h) 45% 70% / .6);
}
/* SCRATCH — foil flecks off the panel. */
.bs-overlay[data-bs-game="scratch"] {
  --fx-w: 9px; --fx-h: 5px; --fx-radius: 1px;
  --fx-ink: linear-gradient(70deg, #f6f8ff, hsl(var(--bs-g-h) 55% 76%) 50%, #9aa4b6);
  --fx-shadow: 0 0 6px rgba(255,255,255,.5); --fx-anim: bs-fx-flutter;
}

/* ---- slots --------------------------------------------------------------- */
/* The gold coin is the default and stays exactly as it was — this is the one
   game where a casino coin IS the right object, and every other family was
   only ever borrowing it. Five-reel throws a heavier one. */
.bs-overlay[data-bs-game="five_reel_slot"] { --fx-w: 17px; --fx-h: 17px; }

/* ---- table games --------------------------------------------------------- */
/* Chips, not coins. Flat, stacked, with the edge-spot pattern printed round
   the rim — the object a player actually gets paid in at a table. */
.bs-overlay[data-bs-game="roulette"],
.bs-overlay[data-bs-game="blackjack"],
.bs-overlay[data-bs-game="baccarat"],
.bs-overlay[data-bs-game="craps"],
.bs-overlay[data-bs-game="caribbean_stud"],
.bs-overlay[data-bs-game="three_card_poker"] {
  --fx-w: 16px; --fx-h: 16px; --fx-radius: 50%;
  --fx-ink:
    repeating-conic-gradient(from 0deg, #f4f6fa 0deg 18deg, hsl(var(--bs-g-h) 55% 46%) 18deg 36deg),
    radial-gradient(circle, hsl(var(--bs-g-h) 55% 52%) 58%, transparent 59%);
  --fx-shadow: 0 2px 6px rgba(0,0,0,.45), inset 0 0 0 3px hsl(var(--bs-g-h) 50% 40%);
  --fx-ease: cubic-bezier(.4,.05,.55,1);
}
/* CRAPS pays in dice as well as chips — square them off. */
.bs-overlay[data-bs-game="craps"] { --fx-radius: 3px; --fx-ink: linear-gradient(150deg, #fff, #e6eaf1 65%, #c2c9d4); }
/* SIC BO — the three dice from the cage. */
.bs-overlay[data-bs-game="sicbo"] {
  --fx-w: 13px; --fx-h: 13px; --fx-radius: 3px;
  --fx-ink: linear-gradient(150deg, #fffdf8, hsl(var(--bs-g-h) 65% 74%) 60%, hsl(var(--bs-g-h) 60% 48%));
  --fx-shadow: 0 2px 6px rgba(0,0,0,.5), inset 0 -3px 4px rgba(0,0,0,.25);
}
/* CHINCHÓN — Spanish cards, fluttering down. */
.bs-overlay[data-bs-game="chinchon"] {
  --fx-w: 13px; --fx-h: 19px; --fx-radius: 2px;
  --fx-ink: linear-gradient(155deg, #fffdf6 58%, hsl(var(--bs-g-h) 55% 70%) 100%);
  --fx-shadow: 0 1px 6px rgba(0,0,0,.42); --fx-anim: bs-fx-flutter; --fx-ease: linear;
}

/* ---- arcade and sport ---------------------------------------------------- */

/* VIDEO POKER — phosphor pixels off the tube. Square, no softness anywhere. */
.bs-overlay[data-bs-game="video_poker"] {
  --fx-w: 9px; --fx-h: 9px; --fx-radius: 0;
  --fx-ink: linear-gradient(180deg, hsl(var(--bs-g-h) 90% 72%), hsl(var(--bs-g-h) 90% 48%));
  --fx-shadow: 0 0 10px hsl(var(--bs-g-h) 92% 60% / .9);
  --fx-ease: steps(9, end);
}
/* PENALTY SHOOTOUT — stadium confetti. */
.bs-overlay[data-bs-game="penalty_shootout"] {
  --fx-w: 8px; --fx-h: 12px; --fx-radius: 1px;
  --fx-ink: linear-gradient(180deg, #fff, hsl(var(--bs-g-h) 70% 58%));
  --fx-shadow: none; --fx-anim: bs-fx-flutter; --fx-ease: linear;
}
/* SNOOKER — the colours off the table. Deliberately literal: a red and a
   yellow ball are the reference, and re-tinting them to the brand would
   throw the reference away rather than serve it. */
.bs-overlay[data-bs-game="snooker"] {
  --fx-w: 14px; --fx-h: 14px;
  --fx-ink: radial-gradient(circle at 32% 26%, #fff 6%, #d21f26 42%, #6d0d12 100%);
  --fx-shadow: 0 2px 7px rgba(0,0,0,.55), inset 0 -4px 6px rgba(0,0,0,.35);
}
/* CRICKET — the bails, end over end. */
.bs-overlay[data-bs-game="cricket"] {
  --fx-w: 6px; --fx-h: 15px; --fx-radius: 3px;
  --fx-ink: linear-gradient(180deg, #f3e4c6, #c49a5e 60%, #8c6633);
  --fx-shadow: 0 1px 5px rgba(0,0,0,.4); --fx-anim: bs-fx-flutter;
}
/* LIVE — studio light motes off the gallery lamps. */
.bs-overlay[data-bs-game="live"] {
  --fx-w: 6px; --fx-h: 6px;
  --fx-ink: radial-gradient(circle, #fff, hsl(var(--bs-g-h) 80% 70%) 55%, transparent 100%);
  --fx-shadow: 0 0 12px hsl(var(--bs-g-h) 80% 66% / .8);
}
/* VIRTUALS — track sparks, thrown flat rather than floated, because a
   simulated race and a streamed studio should not pay out identically. */
.bs-overlay[data-bs-game="virtuals"] {
  --fx-w: 14px; --fx-h: 4px; --fx-radius: 2px;
  --fx-ink: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 85% 72%) 40%, #fff 60%, transparent);
  --fx-shadow: 0 0 10px hsl(var(--bs-g-h) 85% 64% / .75);
  --fx-ease: cubic-bezier(.1,.7,.3,1);
}

/* ---- skin guards --------------------------------------------------------- */
/* Mono carries no colour but the live dot, and that includes what it pays in.
   The literal balls above are the ones that would otherwise break the rule. */
.bs-overlay.bs-skin-mono[data-bs-game] .bs-fx-coin { filter: saturate(0); }

/* bsCelebrate() already returns early under reduced motion, so there is
   nothing to disable here — the particles are never created at all. */

/* ==========================================================================
   12. PER-GAME ENTRANCES — how each game arrives
   ==========================================================================
   There was no entrance at all. Every one of the 24 games simply existed the
   frame after you pressed its tile, identically. That is the moment a player
   meets a game, and it happens far more often than a win does — several times
   a session against maybe one payout — so it was the most-repeated shared
   moment left in the product.

   Eight motions, assigned by what the game IS rather than spread for variety:

     drop     a cabinet lands            slots, five-reel, plinko, keno
     rise     it comes up from below     crash, limbo, virtuals
     deal     laid onto felt, off-angle  the seven table games
     power    a CRT striking on          video poker
     emerge   lit rather than moved      mines, snooker
     slide    fed out of a machine       scratch
     spin     turned into place          wheel, coinflip
     kick     a quick physical pop       dice, hilo, penalty, cricket, live

   TRANSFORM IS DELIBERATELY NOT PERSISTED. `animation-fill-mode` is left at
   its default, so the modal holds no transform once the entrance finishes —
   measured by driving the animation to its end and reading it back: `none`.
   A held transform makes an element a containing block for every
   fixed-position descendant, which costs nothing to avoid and is miserable to
   diagnose later, because the entrance looks perfect and something unrelated
   is subtly wrong for the rest of the session.

   Worth knowing while you are in here: `.bs-overlay` sets
   `backdrop-filter: blur(4px)`, and that ALREADY makes the overlay a
   containing block for fixed children. A `position:fixed` node inside a game
   modal is positioned against the overlay, not the viewport, and was before
   any of this existed. If you ever chase a fixed element landing in the wrong
   place, that is the cause and it is not the entrance.

   The entrance runs on the modal, so the scene layer beneath it travels with
   the card rather than sliding underneath it.
   ========================================================================== */

@keyframes bs-md-drop {
  from { transform: translateY(-26px) scale(.985); opacity: 0; }
  60%  { transform: translateY(3px)   scale(1);    opacity: 1; }
  to   { transform: none; opacity: 1; }
}
@keyframes bs-md-rise {
  from { transform: translateY(34px) scale(.99); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@keyframes bs-md-deal {
  from { transform: translate(-18px, 14px) rotate(-2.2deg) scale(.97); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
/* A tube striking on: the line before the picture. */
@keyframes bs-md-power {
  from { transform: scaleY(.02) scaleX(1.04); opacity: 0; filter: brightness(2.4); }
  45%  { transform: scaleY(.06) scaleX(1);    opacity: 1; filter: brightness(1.8); }
  to   { transform: none; opacity: 1; filter: none; }
}
@keyframes bs-md-emerge {
  from { transform: scale(.94); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@keyframes bs-md-slide {
  from { transform: translateX(-30px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@keyframes bs-md-spin {
  from { transform: rotate(-3.5deg) scale(.965); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@keyframes bs-md-kick {
  from { transform: scale(.9);  opacity: 0; }
  55%  { transform: scale(1.015); opacity: 1; }
  to   { transform: none; opacity: 1; }
}

/* The modal wears whichever its game names. Default is `drop`, so a category
   added later arrives deliberately rather than blinking into place. */
.bs-overlay[data-bs-game] .bs-game-modal.bs-themed {
  animation: var(--md-in, bs-md-drop .32s cubic-bezier(.2,.8,.3,1.05));
}

/* ---- assignment ---------------------------------------------------------- */

.bs-overlay[data-bs-game="slots"]            { --md-in: bs-md-drop .34s cubic-bezier(.2,.85,.3,1.1); }
.bs-overlay[data-bs-game="five_reel_slot"]   { --md-in: bs-md-drop .40s cubic-bezier(.2,.85,.3,1.08); }
.bs-overlay[data-bs-game="plinko"]           { --md-in: bs-md-drop .30s cubic-bezier(.3,1.4,.5,1); }
.bs-overlay[data-bs-game="keno"]             { --md-in: bs-md-drop .38s cubic-bezier(.25,.7,.35,1); }

.bs-overlay[data-bs-game="crash"]            { --md-in: bs-md-rise .34s cubic-bezier(.15,.75,.3,1); }
.bs-overlay[data-bs-game="limbo"]            { --md-in: bs-md-rise .30s cubic-bezier(.1,.8,.3,1); }
.bs-overlay[data-bs-game="virtuals"]         { --md-in: bs-md-rise .36s ease-out; }

.bs-overlay[data-bs-game="roulette"]         { --md-in: bs-md-deal .36s cubic-bezier(.2,.7,.3,1); }
.bs-overlay[data-bs-game="blackjack"]        { --md-in: bs-md-deal .32s cubic-bezier(.2,.7,.3,1); }
.bs-overlay[data-bs-game="baccarat"]         { --md-in: bs-md-deal .42s cubic-bezier(.25,.65,.3,1); }
.bs-overlay[data-bs-game="craps"]            { --md-in: bs-md-deal .28s cubic-bezier(.2,.9,.3,1.1); }
.bs-overlay[data-bs-game="sicbo"]            { --md-in: bs-md-deal .30s cubic-bezier(.2,.85,.3,1.05); }
.bs-overlay[data-bs-game="three_card_poker"] { --md-in: bs-md-deal .34s cubic-bezier(.2,.7,.3,1); }
.bs-overlay[data-bs-game="caribbean_stud"]   { --md-in: bs-md-deal .38s cubic-bezier(.2,.7,.3,1); }
.bs-overlay[data-bs-game="chinchon"]         { --md-in: bs-md-deal .40s cubic-bezier(.22,.68,.3,1); }

.bs-overlay[data-bs-game="video_poker"]      { --md-in: bs-md-power .40s cubic-bezier(.15,.9,.25,1); }

.bs-overlay[data-bs-game="mines"]            { --md-in: bs-md-emerge .42s ease-out; }
.bs-overlay[data-bs-game="snooker"]          { --md-in: bs-md-emerge .48s ease-out; }

.bs-overlay[data-bs-game="scratch"]          { --md-in: bs-md-slide .32s cubic-bezier(.2,.8,.3,1); }

.bs-overlay[data-bs-game="wheel"]            { --md-in: bs-md-spin .40s cubic-bezier(.2,.75,.3,1.04); }
.bs-overlay[data-bs-game="coinflip"]         { --md-in: bs-md-spin .30s cubic-bezier(.2,.85,.3,1.08); }

.bs-overlay[data-bs-game="dice"]             { --md-in: bs-md-kick .26s cubic-bezier(.3,1.3,.5,1); }
.bs-overlay[data-bs-game="hilo"]             { --md-in: bs-md-kick .30s cubic-bezier(.3,1.2,.5,1); }
.bs-overlay[data-bs-game="penalty_shootout"] { --md-in: bs-md-kick .24s cubic-bezier(.3,1.5,.5,1); }
.bs-overlay[data-bs-game="cricket"]          { --md-in: bs-md-kick .32s cubic-bezier(.3,1.15,.5,1); }
.bs-overlay[data-bs-game="live"]             { --md-in: bs-md-kick .34s ease-out; }

/* ---- the control you actually press -------------------------------------- */
/* A slot's SPIN, a crash CASH OUT and a blackjack HIT were the same pill. The
   ACCENT stays the brand's, deliberately — the button is where a brand is
   loudest, and handing its colour to the game would trade a real identity for
   a decorative one. What changes is the room's own carpentry: the corner
   radius each scene already declares, so a felt table's control is rounded
   and an arcade cabinet's is square. */
.bs-overlay[data-bs-game] .bs-btn { border-radius: var(--sc-edge, 10px); }
/* Except where the scene's radius is meant for a hairline rail rather than a
   control — a 1px button reads as a bug, and 999px would make a lozenge of
   something that should look pressable. */
.bs-overlay[data-bs-game="crash"] .bs-btn,
.bs-overlay[data-bs-game="limbo"] .bs-btn,
.bs-overlay[data-bs-game="video_poker"] .bs-btn { border-radius: 2px; }
.bs-overlay[data-bs-game="plinko"] .bs-btn,
.bs-overlay[data-bs-game="wheel"] .bs-btn,
.bs-overlay[data-bs-game="coinflip"] .bs-btn,
.bs-overlay[data-bs-game="snooker"] .bs-btn { border-radius: 999px; }

/* ---- the payout figure --------------------------------------------------- */
/* It keeps its gold and its size everywhere, because it is the one number a
   player looks for and consistency there is worth more than variety. Only the
   letterforms follow the room — video poker counts up in its own monospace,
   the scenes that set a tracking keep it. */
.bs-overlay[data-bs-game] .bs-fx-payout {
  font-family: var(--sc-font, inherit);
  letter-spacing: var(--sc-track, -.01em);
}

/* ---- reduced motion ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .bs-overlay[data-bs-game] .bs-game-modal.bs-themed { animation: none !important; }
}

/* ==========================================================================
   13. DRAGON TOWER
   ==========================================================================
   Drawn as nine rows rather than a grid, which is the whole argument for the
   game existing beside Mines: one shortening board versus nine independent
   floors. The live row is the only lit one; cleared floors dim and settle
   beneath it so the climb is legible at a glance rather than from the number.
   ========================================================================== */

.bs-dt-stage { margin: 4px 0 10px; }
.bs-dt-tower { display: flex; flex-direction: column; gap: 4px; }

.bs-dt-row { display: flex; align-items: center; gap: 8px; padding: 2px 4px;
  border-radius: 8px; transition: background .18s, opacity .18s; opacity: .5; }
.bs-dt-row.is-cleared { opacity: .85; }
.bs-dt-row.is-live { opacity: 1; background: hsl(var(--bs-g-h) var(--bs-g-s) 42% / .12);
  box-shadow: inset 0 0 0 1px hsl(var(--bs-g-h) var(--bs-g-s) 52% / .3); }

.bs-dt-rung { flex: 0 0 54px; text-align: right; font-size: 11px; font-weight: 700;
  color: var(--bs-muted); font-variant-numeric: tabular-nums; }
.bs-dt-row.is-live .bs-dt-rung { color: var(--bs-gold-ink); }

.bs-dt-cells { display: flex; gap: 4px; flex: 1; }
.bs-dt-tile { flex: 1; aspect-ratio: 5 / 3; min-height: 26px; border: 0; cursor: pointer;
  border-radius: 6px; background: var(--bs-elev2); box-shadow: inset 0 -2px 0 rgba(0,0,0,.28);
  display: flex; align-items: center; justify-content: center; padding: 0;
  transition: transform .1s, background .16s, box-shadow .16s; }
.bs-dt-tile.is-idle { background: var(--bs-elev); cursor: default; }
.bs-dt-tile.is-live:hover { background: var(--bs-soft); transform: translateY(-1px); }
.bs-dt-tile.is-live:active { transform: translateY(1px); }
.bs-dt-tile:disabled { cursor: default; }
/* REVEALED TILES ARE RINGED, NOT WASHED, and that is an accessibility fix
   rather than a style preference. These carried a dark hue wash and a 28%
   black respectively — both invented rather than taken from a token, so both
   stayed dark on the light `classic` skin that Ludgate, Lumo and Chinchón run.
   Measured there, the EGG — the win state of the game — sat at 1.82 contrast
   against its own icon, and the flame at 2.68. Half the estate was showing an
   almost invisible result.

   The ring and the icon both come from --bs-pos / --bs-neg, which every skin
   redefines, over the tile's ordinary surface. That measures 5.00 and 5.32 on
   classic and 7.73 and 5.10 on tiger: comfortably past AA everywhere, and the
   two states stay obviously different from each other. Same approach Mines
   already uses for its gem and bomb. */
.bs-dt-tile.is-egg { background: var(--bs-elev2); color: var(--bs-pos);
  box-shadow: inset 0 0 0 1.5px var(--bs-pos), inset 0 -2px 0 rgba(0,0,0,.16); }
.bs-dt-tile.is-flame { background: var(--bs-elev2); color: var(--bs-neg);
  box-shadow: inset 0 0 0 1.5px var(--bs-neg), inset 0 -2px 0 rgba(0,0,0,.16); }
/* The tile the player actually pressed: the same colour, drawn heavier, so it
   reads as emphasis rather than as a different state. */
.bs-dt-tile.is-picked { box-shadow: inset 0 0 0 3px currentColor; }
.bs-dt-tile.is-burn { animation: bs-dt-scorch .5s ease-out; }
@keyframes bs-dt-scorch {
  0%   { transform: scale(1);    filter: brightness(2.6); }
  40%  { transform: scale(1.07); filter: brightness(1.5); }
  100% { transform: scale(1);    filter: none; }
}
.bs-dt-icon { display: block; width: 62%; max-width: 22px; line-height: 0; }
.bs-dt-icon svg { width: 100%; height: auto; display: block; }

.bs-dt-pot { display: flex; align-items: baseline; justify-content: center; gap: 8px; margin-top: 10px; }
.bs-dt-pot-label { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--bs-muted); }
.bs-dt-pot-mult { font-size: 13px; font-weight: 800; color: var(--bs-muted); font-variant-numeric: tabular-nums; }

.bs-dt-diffs { display: flex; gap: 6px; flex-wrap: wrap; margin: 2px 0 8px; }
.bs-dt-diff { flex: 1; min-width: 62px; padding: 6px 4px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--bs-line); background: var(--bs-elev); color: var(--bs-muted);
  font-size: 12px; font-weight: 700; display: flex; flex-direction: column; gap: 1px; }
.bs-dt-diff b { font-size: 11px; font-weight: 800; opacity: .75; font-variant-numeric: tabular-nums; }
.bs-dt-diff.is-on { border-color: hsl(var(--bs-g-h) var(--bs-g-s) 55% / .8);
  background: hsl(var(--bs-g-h) var(--bs-g-s) 40% / .22); color: var(--bs-text); }
.bs-dt-diff:disabled { opacity: .5; cursor: default; }

@media (prefers-reduced-motion: reduce) {
  .bs-dt-tile, .bs-dt-row { transition: none !important; }
  .bs-dt-tile.is-burn { animation: none !important; }
}

/* ---- its place in the three per-game systems ----------------------------- */

/* SCENE — a stone shaft. Vertical courses of masonry with the light from
   above, so the ground reads as something you climb rather than stand on. */
.bs-overlay[data-bs-game="dragon_tower"] {
  --sc-pat:
    repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 60% 48% / .18) 0 1px, transparent 1px 54px),
    repeating-linear-gradient(0deg,  hsl(var(--bs-g-h) 60% 48% / .16) 0 1px, transparent 1px 30px),
    radial-gradient(60% 42% at 50% 0%, hsl(var(--bs-g-h) 75% 50% / .42), transparent 74%);
  --sc-size: auto, auto, 100% 100%;
  --sc-op: .19;
  --sc-anim: none;
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 70% 56%) 0 9px, transparent 9px 15px);
  --sc-edge: 6px;
}
/* CELEBRATION — hatching eggshell, not casino coins. */
.bs-overlay[data-bs-game="dragon_tower"] {
  --fx-w: 12px; --fx-h: 15px; --fx-radius: 50% 50% 46% 46%;
  --fx-ink: radial-gradient(circle at 36% 28%, #fff 8%, hsl(var(--bs-g-h) 70% 64%) 48%, hsl(var(--bs-g-h) 72% 38%) 100%);
  --fx-shadow: 0 0 9px hsl(var(--bs-g-h) 72% 58% / .6), inset 0 -3px 4px rgba(0,0,0,.28);
}
/* ENTRANCE — it rises, because the game is a climb. */
.bs-overlay[data-bs-game="dragon_tower"] { --md-in: bs-md-rise .38s cubic-bezier(.15,.8,.3,1); }

/* ==========================================================================
   14. DRAGON TIGER and ANDAR BAHAR
   ==========================================================================
   Two card tables that must not look like each other or like Baccarat.

   Dragon Tiger is a DUEL: two seats facing across a centre line, one card
   each, so the layout says "compare these" before a word is read.

   Andar Bahar is a RUN: two growing piles under the joker that started them,
   with the count as the headline, because the length of the run is the game
   rather than the value of any card in it.
   ========================================================================== */

/* ---- Dragon Tiger --------------------------------------------------------- */
.bs-dtg-table { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: 10px; margin: 6px 0 12px; }
.bs-dtg-seat { display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 6px; border-radius: 12px; transition: background .2s, box-shadow .2s; }
.bs-dtg-seat.is-won { background: hsl(var(--bs-g-h) var(--bs-g-s) 42% / .18);
  box-shadow: inset 0 0 0 1px hsl(var(--bs-g-h) var(--bs-g-s) 56% / .5); }
.bs-dtg-seat-name { font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 800; color: var(--bs-muted); }
.bs-dtg-vs { font-size: 12px; font-weight: 900; letter-spacing: .08em; color: var(--bs-muted);
  text-transform: uppercase; min-width: 54px; text-align: center; }

.bs-dtg-spots { display: flex; gap: 6px; margin-bottom: 8px; }
.bs-dtg-spot { flex: 1; padding: 8px 4px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--bs-line); background: var(--bs-elev); color: var(--bs-muted);
  display: flex; flex-direction: column; gap: 2px; font-weight: 800; font-size: 12px; }
.bs-dtg-spot-pays { font-size: 10px; font-weight: 700; opacity: .7; }
.bs-dtg-spot.is-on { border-color: hsl(var(--bs-g-h) var(--bs-g-s) 58% / .85);
  background: hsl(var(--bs-g-h) var(--bs-g-s) 40% / .24); color: var(--bs-text); }
.bs-dtg-spot.is-won { box-shadow: 0 0 0 2px var(--bs-gold-ink) inset; color: var(--bs-gold-ink); }
/* The tie spot is the long shot and is drawn as one: narrower, and set apart. */
.bs-dtg-spot.bs-dtg-tie { flex: 0 0 30%; }
.bs-dtg-win { text-align: center; margin-top: 8px; }

/* ---- Andar Bahar ---------------------------------------------------------- */
.bs-ab-joker { display: flex; align-items: center; justify-content: center; gap: 10px;
  margin: 4px 0 10px; }
.bs-ab-joker-label { font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 800; color: var(--bs-muted); }
.bs-ab-count { font-size: 12px; font-weight: 800; color: var(--bs-gold-ink);
  font-variant-numeric: tabular-nums; }

.bs-ab-piles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 10px; }
.bs-ab-pile { padding: 8px; border-radius: 10px; background: var(--bs-elev);
  border: 1px solid var(--bs-line); min-height: 74px; }
.bs-ab-pile.is-won { border-color: hsl(var(--bs-g-h) var(--bs-g-s) 58% / .8);
  background: hsl(var(--bs-g-h) var(--bs-g-s) 40% / .18); }
.bs-ab-pile-head { display: flex; align-items: center; gap: 6px; margin-bottom: 6px;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase; font-weight: 800;
  color: var(--bs-muted); }
.bs-ab-pile-head b { margin-left: auto; font-variant-numeric: tabular-nums; color: var(--bs-text); }
.bs-ab-firstmark { font-style: normal; font-size: 9px; padding: 1px 4px; border-radius: 4px;
  background: hsl(var(--bs-g-h) var(--bs-g-s) 48% / .35); color: var(--bs-text); letter-spacing: .04em; }
.bs-ab-cards { flex-wrap: wrap; gap: 3px; align-items: center; }
.bs-ab-more { font-size: 11px; font-weight: 800; color: var(--bs-muted);
  padding: 2px 5px; border-radius: 5px;
  /* --bs-elev2 rather than a black wash: the wash measured 3.51 against its
     own text on the light skin, and this measures well past AA on every one. */
  background: var(--bs-elev2); border: 1px solid var(--bs-line); }

.bs-ab-sides { display: flex; gap: 6px; margin-bottom: 8px; }
.bs-ab-side { flex: 1; padding: 8px 4px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--bs-line); background: var(--bs-elev); color: var(--bs-muted);
  display: flex; flex-direction: column; gap: 2px; font-weight: 800; font-size: 12px; }
.bs-ab-side-pays { font-size: 10px; font-weight: 700; opacity: .7; }
.bs-ab-side.is-on { border-color: hsl(var(--bs-g-h) var(--bs-g-s) 58% / .85);
  background: hsl(var(--bs-g-h) var(--bs-g-s) 40% / .24); color: var(--bs-text); }
.bs-ab-side.is-won { box-shadow: 0 0 0 2px var(--bs-gold-ink) inset; color: var(--bs-gold-ink); }
.bs-ab-win { text-align: center; margin-top: 8px; }

@media (max-width: 420px) {
  .bs-ab-piles { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .bs-dtg-seat { transition: none !important; }
}

/* ---- their place in the three per-game systems ---------------------------- */

/* DRAGON TIGER: a duel line down the centre of the felt, with a lamp over each
   seat. Not the shared weave alone, because this table seats two, facing. */
.bs-overlay[data-bs-game="dragon_tiger"] {
  --sc-pat:
    linear-gradient(90deg, transparent 0 49.4%, hsl(var(--bs-g-h) 60% 60% / .34) 49.4% 50.6%, transparent 50.6%),
    radial-gradient(30% 26% at 24% 22%, hsl(var(--bs-g-h) 70% 56% / .30), transparent 70%),
    radial-gradient(30% 26% at 76% 22%, hsl(var(--bs-g-h) 70% 56% / .30), transparent 70%),
    repeating-linear-gradient(45deg, hsl(var(--bs-g-h) 30% 40% / .10) 0 1px, transparent 1px 4px);
  --sc-size: 100% 100%, 100% 100%, 100% 100%, auto;
  --sc-op: .19;
  --sc-anim: none;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 60% 62%), transparent);
  --sc-edge: 10px;
  --sc-rail-h: 2px;
  /* Pays in chips like the other tables, but in its own colour. */
  --fx-w: 16px; --fx-h: 16px; --fx-radius: 50%;
  --fx-ink:
    repeating-conic-gradient(from 0deg, #f4f6fa 0deg 18deg, hsl(var(--bs-g-h) 55% 46%) 18deg 36deg),
    radial-gradient(circle, hsl(var(--bs-g-h) 55% 52%) 58%, transparent 59%);
  --fx-shadow: 0 2px 6px rgba(0,0,0,.45), inset 0 0 0 3px hsl(var(--bs-g-h) 50% 40%);
  --md-in: bs-md-deal .30s cubic-bezier(.2,.85,.3,1.06);
}

/* ANDAR BAHAR: two lanes running away from the joker at the top, because the
   game is a run down them rather than a hand laid on felt. */
.bs-overlay[data-bs-game="andar_bahar"] {
  --sc-pat:
    linear-gradient(90deg, transparent 0 49.6%, hsl(var(--bs-g-h) 55% 58% / .26) 49.6% 50.4%, transparent 50.4%),
    repeating-linear-gradient(0deg, hsl(var(--bs-g-h) 55% 56% / .16) 0 1px, transparent 1px 34px),
    radial-gradient(44% 30% at 50% 4%, hsl(var(--bs-g-h) 70% 54% / .40), transparent 72%);
  --sc-size: 100% 100%, auto, 100% 100%;
  --sc-op: .18;
  --sc-anim: bs-sc-fall 16s linear infinite;
  --sc-rail: repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 58% 60%) 0 22px, transparent 22px 30px);
  --sc-edge: 8px;
  --sc-rail-h: 2px;
  /* Falling cards, not chips: the game pays out of a running deal. */
  --fx-w: 13px; --fx-h: 19px; --fx-radius: 2px;
  --fx-ink: linear-gradient(155deg, #fffdf8 56%, hsl(var(--bs-g-h) 58% 70%) 100%);
  --fx-shadow: 0 1px 6px rgba(0,0,0,.45);
  --fx-anim: bs-fx-flutter; --fx-ease: linear;
  --md-in: bs-md-slide .34s cubic-bezier(.2,.8,.3,1);
}

/* ---- betslip placement receipt --------------------------------------------
   Replaces a native alert(). Sits where the slip's contents just were, so the
   confirmation appears at the point the player's eye already is, and inherits
   the brand's tokens instead of the operating system's chrome. */
.bs-slip-receipt {
  margin: 0 0 8px; padding: 10px 12px; border-radius: 10px;
  font-size: 13px; font-weight: 700; line-height: 1.35;
  color: var(--bs-text);
  background: hsl(var(--bs-g-h) var(--bs-g-s) 42% / .20);
  border: 1px solid hsl(var(--bs-g-h) var(--bs-g-s) 56% / .55);
  animation: bs-slip-receipt-in .28s cubic-bezier(.2,.85,.3,1.05) both;
}
/* Partly-failed placements are not a success and must not be dressed as one. */
.bs-slip-receipt-partial {
  background: color-mix(in srgb, var(--bs-neg) 16%, transparent);
  border-color: color-mix(in srgb, var(--bs-neg) 55%, transparent);
}
@keyframes bs-slip-receipt-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .bs-slip-receipt { animation: none; }
}

/* ---- toasts ---------------------------------------------------------------
   Replaces six native alert() calls. Above .bs-overlay (99999) on purpose: a
   game can fail to launch while a modal is already up, and a notice you cannot
   see is worse than the blocking dialog it replaced.

   pointer-events is none on the stack and auto on each toast, so the strip does
   not swallow clicks on the page beneath it while still letting the dismiss
   button be pressed. */
.bs-toasts {
  position: fixed; z-index: 100010; pointer-events: none;
  left: 50%; transform: translateX(-50%);
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  display: flex; flex-direction: column-reverse; align-items: center; gap: 8px;
  width: min(440px, calc(100vw - 24px));
}
.bs-toast {
  pointer-events: auto;
  display: flex; align-items: flex-start; gap: 10px;
  width: 100%; padding: 11px 10px 11px 14px;
  border-radius: 12px; font-size: 13.5px; font-weight: 600; line-height: 1.4;
  color: var(--bs-text); background: var(--bs-elev);
  border: 1px solid var(--bs-line);
  box-shadow: 0 10px 30px -8px rgba(0,0,0,.5);
  opacity: 1; transform: none;
  transition: opacity .22s ease, transform .22s ease;
  animation: bs-toast-in .26s cubic-bezier(.2,.85,.3,1.05) both;
}
.bs-toast.is-out { opacity: 0; transform: translateY(8px); animation: none; }
.bs-toast-msg { flex: 1; min-width: 0; }
/* An error is the brand's negative colour, not a generic red, so it still
   belongs to whichever skin is loaded. */
.bs-toast-err {
  border-color: color-mix(in srgb, var(--bs-neg) 60%, transparent);
  background: color-mix(in srgb, var(--bs-neg) 14%, var(--bs-elev));
}
.bs-toast-x {
  flex: none; width: 24px; height: 24px; margin: -2px 0 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 6px; cursor: pointer;
  background: transparent; color: var(--bs-muted);
  font-size: 17px; line-height: 1;
}
.bs-toast-x:hover { background: rgba(127,127,127,.18); color: var(--bs-text); }
.bs-toast-x:focus-visible { outline: 2px solid var(--bs-gold-ink); outline-offset: 1px; }

@keyframes bs-toast-in {
  from { opacity: 0; transform: translateY(10px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .bs-toast { animation: none; transition: opacity .01s; }
  .bs-toast.is-out { transform: none; }
}

/* ==========================================================================
   15. BINGO
   ==========================================================================
   The one game here whose subject is TIME. Everything below is arranged so a
   glance answers "how close am I, and how long is left" — the caller reads
   left to right at the top, the tickets daub underneath, and the only number
   that grows is the count of balls gone.
   ========================================================================== */

.bs-bingo-caller { display: flex; align-items: center; gap: 12px; margin: 4px 0 10px; }

/* The ball is the one round, heavy thing on the screen; the tickets are all
   flat squares, so the contrast alone says which is the live object. */
.bs-bingo-ball {
  flex: none; width: 62px; height: 62px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-weight: 900; font-size: 25px; font-variant-numeric: tabular-nums;
  color: #23200f;
  background:
    radial-gradient(circle at 34% 28%, rgba(255,255,255,.95) 0 12%, transparent 42%),
    radial-gradient(circle at 50% 55%, #fffdf4 40%, hsl(var(--bs-g-h) 42% 76%) 100%);
  box-shadow: 0 6px 16px -4px rgba(0,0,0,.55), inset 0 -5px 12px -4px rgba(0,0,0,.35);
}
.bs-bingo-ball-idle { font-size: 11px; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: #5d5844; }
.bs-bingo-ball.is-dropping { animation: bs-bingo-drop .34s cubic-bezier(.2,.9,.3,1.1); }

.bs-bingo-callinfo { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.bs-bingo-count { font-size: 12px; font-weight: 800; letter-spacing: .06em;
  color: var(--bs-muted); font-variant-numeric: tabular-nums; }
.bs-bingo-recent { display: flex; gap: 4px; flex-wrap: wrap; }
/* Already-called numbers fade back rather than disappear: the trail is what
   makes the count feel like a draw in progress instead of a counter. */
.bs-bingo-past { font-style: normal; font-size: 11px; font-weight: 700;
  padding: 2px 6px; border-radius: 20px; color: var(--bs-muted);
  background: rgba(127,127,127,.16); font-variant-numeric: tabular-nums; }
.bs-bingo-past:nth-child(n+4) { opacity: .55; }

/* ---- the prize board ---- */
.bs-bingo-prizes { display: flex; gap: 6px; margin-bottom: 10px; }
.bs-bingo-prize { flex: 1; display: flex; flex-direction: column; gap: 2px;
  padding: 7px 6px; border-radius: 9px; text-align: center;
  background: var(--bs-elev); border: 1px solid var(--bs-line); }
.bs-bingo-prize b { font-size: 10.5px; font-weight: 800; letter-spacing: .04em;
  color: var(--bs-muted); }
.bs-bingo-prize i { font-style: normal; font-size: 13px; font-weight: 900;
  color: var(--bs-text); font-variant-numeric: tabular-nums; }
.bs-bingo-prize.is-won { border-color: var(--bs-gold-ink);
  background: hsl(var(--bs-g-h) var(--bs-g-s) 42% / .22); }
.bs-bingo-prize.is-won i, .bs-bingo-prize.is-won b { color: var(--bs-gold-ink); }

/* ---- the tickets ---- */
.bs-bingo-tickets { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.bs-bingo-ticket { padding: 8px; border-radius: 10px;
  background: var(--bs-elev); border: 1px solid var(--bs-line); }
.bs-bingo-ticket-head { display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 6px; font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  font-weight: 800; color: var(--bs-muted); }
.bs-bingo-togo { font-size: 11px; font-weight: 800; letter-spacing: .02em;
  text-transform: none; color: var(--bs-muted); font-variant-numeric: tabular-nums; }
/* One away is the whole game. It gets a colour and a pulse; two away gets
   nothing, because if everything is emphasised then nothing is. */
.bs-bingo-togo.is-close { color: var(--bs-gold-ink);
  animation: bs-bingo-pulse 1s ease-in-out infinite; }
.bs-bingo-togo.is-line { color: var(--bs-text); letter-spacing: .12em;
  padding: 1px 7px; border-radius: 5px;
  background: hsl(var(--bs-g-h) var(--bs-g-s) 46% / .55); animation: none; }

/* 9 columns always, however narrow: a bingo ticket that reflows is not a
   bingo ticket. The cells shrink instead, and stay square. */
.bs-bingo-grid { display: flex; flex-direction: column; gap: 3px; }
.bs-bingo-row { display: grid; grid-template-columns: repeat(9, 1fr); gap: 3px;
  border-radius: 6px; transition: background .25s ease; }
.bs-bingo-row.is-close { background: hsl(var(--bs-g-h) var(--bs-g-s) 50% / .12); }
.bs-bingo-row.is-line { background: hsl(var(--bs-g-h) var(--bs-g-s) 46% / .30);
  animation: bs-bingo-lineflash .55s ease-out; }

.bs-bingo-cell {
  font-style: normal; aspect-ratio: 1; display: flex; align-items: center;
  justify-content: center; border-radius: 5px;
  font-size: clamp(9px, 2.6vw, 13px); font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--bs-text); background: rgba(127,127,127,.13);
  transition: transform .18s ease, background .18s ease, color .18s ease;
}
.bs-bingo-cell.is-blank { background: transparent; }
/* A daub is a mark ON the number, so the number stays readable underneath —
   the point of a daubed ticket is that you can still check it. */
.bs-bingo-cell.is-daubed {
  color: #1c1a10;
  background:
    radial-gradient(circle at 50% 50%, hsl(var(--bs-g-h) 62% 66%) 0 58%, hsl(var(--bs-g-h) 58% 52%) 59% 100%);
  box-shadow: 0 0 0 1px hsl(var(--bs-g-h) 55% 44%) inset;
  animation: bs-bingo-daub .26s cubic-bezier(.2,.9,.3,1.2);
}

/* ---- buying in ---- */
.bs-bingo-buy { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.bs-bingo-buy-lab { font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  font-weight: 800; color: var(--bs-muted); }
.bs-bingo-buy-opts { display: flex; gap: 5px; margin-left: auto; }
.bs-bingo-qty { width: 34px; height: 30px; border-radius: 8px; cursor: pointer;
  font-weight: 800; font-size: 13px; font-variant-numeric: tabular-nums;
  border: 1px solid var(--bs-line); background: var(--bs-elev); color: var(--bs-muted); }
.bs-bingo-qty.is-on { border-color: hsl(var(--bs-g-h) var(--bs-g-s) 58% / .85);
  background: hsl(var(--bs-g-h) var(--bs-g-s) 40% / .26); color: var(--bs-text); }
.bs-bingo-qty:disabled { opacity: .5; cursor: default; }
.bs-bingo-total { font-size: 12px; font-weight: 700; color: var(--bs-muted);
  margin: 2px 0 8px; font-variant-numeric: tabular-nums; }
.bs-bingo-total b { color: var(--bs-text); }
.bs-bingo-win { text-align: center; margin-top: 8px; }

@keyframes bs-bingo-drop {
  0%   { transform: translateY(-16px) scale(.86); }
  70%  { transform: translateY(2px) scale(1.03); }
  100% { transform: none; }
}
@keyframes bs-bingo-daub {
  0%   { transform: scale(.55); }
  70%  { transform: scale(1.12); }
  100% { transform: none; }
}
@keyframes bs-bingo-lineflash {
  0%   { background: hsl(var(--bs-g-h) var(--bs-g-s) 62% / .75); }
  100% { background: hsl(var(--bs-g-h) var(--bs-g-s) 46% / .30); }
}
@keyframes bs-bingo-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .5; }
}
@media (prefers-reduced-motion: reduce) {
  .bs-bingo-ball.is-dropping,
  .bs-bingo-cell.is-daubed,
  .bs-bingo-row.is-line,
  .bs-bingo-togo.is-close { animation: none !important; }
  .bs-bingo-cell, .bs-bingo-row { transition: none !important; }
}

/* ---- its place in the three per-game systems ------------------------------
   A HALL: a lit ceiling, long tables running away from the caller's stand, and
   the caller's own lamp at the top. Not the shared weave — every other scene
   in this file is a table seen from above or a machine seen head-on, and this
   is a ROOM with other people in it, which is the only thing bingo has that
   nothing else here does. */
.bs-overlay[data-bs-game="bingo"] {
  --sc-pat:
    radial-gradient(38% 22% at 50% 2%, hsl(var(--bs-g-h) 75% 62% / .48), transparent 74%),
    repeating-linear-gradient(0deg, hsl(var(--bs-g-h) 50% 58% / .13) 0 1px, transparent 1px 46px),
    repeating-linear-gradient(90deg, hsl(var(--bs-g-h) 45% 55% / .10) 0 1px, transparent 1px 62px),
    radial-gradient(58% 40% at 50% 108%, hsl(var(--bs-g-h) 40% 40% / .30), transparent 70%);
  --sc-size: 100% 100%, auto, auto, 100% 100%;
  --sc-op: .20;
  --sc-anim: none;
  --sc-rail: linear-gradient(90deg, transparent, hsl(var(--bs-g-h) 68% 64%), transparent);
  --sc-edge: 12px;
  --sc-rail-h: 2px;
  /* Pays in balls, because that is what the game is made of. */
  --fx-w: 15px; --fx-h: 15px; --fx-radius: 50%;
  --fx-ink:
    radial-gradient(circle at 34% 28%, rgba(255,255,255,.95) 0 14%, transparent 44%),
    radial-gradient(circle at 50% 55%, #fffdf4 42%, hsl(var(--bs-g-h) 45% 74%) 100%);
  --fx-shadow: 0 2px 7px rgba(0,0,0,.42);
  --md-in: bs-md-drop .32s cubic-bezier(.2,.85,.3,1.08);
}

/* ---- unfinished rounds (RTS 10) -------------------------------------------
   Deliberately hard to ignore and impossible to dismiss. Every other notice in
   this file clears itself; this one stays until the round is dealt with,
   because the player has money in it and a bar they can flick away is a bar
   that will be flicked away.

   Below the toasts (100010) and below the game overlay (99999) — opening the
   game to finish the round must not leave this floating over it. */
.bs-resume-bar {
  position: fixed; z-index: 9000;
  left: 50%; transform: translateX(-50%);
  bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  width: min(560px, calc(100vw - 20px));
  border-radius: 14px; overflow: hidden;
  background: var(--bs-elev);
  border: 1px solid color-mix(in srgb, var(--bs-gold-ink) 55%, var(--bs-line));
  box-shadow: 0 14px 40px -10px rgba(0,0,0,.6);
  animation: bs-resume-in .3s cubic-bezier(.2,.85,.3,1.05) both;
}
.bs-resume-in { padding: 11px 13px; display: flex; flex-direction: column; gap: 8px; }
.bs-resume-lead {
  font-size: 12px; font-weight: 800; letter-spacing: .02em;
  color: var(--bs-gold-ink);
}
.bs-resume-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 700; color: var(--bs-text);
}
.bs-resume-game { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bs-resume-stake { font-variant-numeric: tabular-nums; color: var(--bs-muted); }
/* The buttons never shrink: "Cash out" pushed off the edge of a narrow phone
   is the one control this bar exists to offer. */
.bs-resume-row .bs-btn { flex: none; }

@keyframes bs-resume-in {
  from { opacity: 0; transform: translateX(-50%) translateY(12px); }
  to   { opacity: 1; transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) { .bs-resume-bar { animation: none; } }
@media (max-width: 420px) {
  .bs-resume-row { flex-wrap: wrap; }
  .bs-resume-game { flex: 1 0 100%; }
}

/* The list is bounded and scrolls. A real account turned up with fifteen
   unfinished rounds, and an unbounded bar grew past the top of the phone —
   hiding the buttons it exists to offer. */
.bs-resume-head { display: flex; align-items: baseline; gap: 8px; }
.bs-resume-total { margin-left: auto; font-size: 12px; font-weight: 800;
  color: var(--bs-text); font-variant-numeric: tabular-nums; }
.bs-resume-list { display: flex; flex-direction: column; gap: 6px;
  max-height: min(38vh, 220px); overflow-y: auto; }
.bs-resume-all { align-self: flex-start; }
