:root {
  --bg-deep: #0f0824;
  --bg-mid: #1a0f3d;
  /* --bg-card removed — the translucent purple "card pill" (rgba(42,24,81,0.55))
     is no longer used anywhere; new elements default to transparent /
     coin-picker dark `rgba(15, 8, 36, 0.55)` instead. */
  --bg-card-solid: #241547;
  --bg-input: rgba(12, 6, 30, 0.5);
  --border: rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.16);
  --text: #ffffff;
  --text-muted: #ffffff;
  --text-dim: rgba(255, 255, 255, 0.6);
  --primary: #ff2e5e;
  --primary-grad: linear-gradient(180deg, #ff3d6a 0%, #e5194e 100%);
  --primary-glow: 0 6px 18px rgba(255, 46, 94, 0.2);
  --blue: #4a7fff;
  --blue-grad: linear-gradient(180deg, #5b8eff 0%, #3a6ae5 100%);
  --gold: #ffb800;
  --green: #22c55e;
  --red: #ef4444;
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-pill: 999px;
  --shadow-card: 0 8px 32px rgba(0, 0, 0, 0.35);
  --shadow-glow-pink: 0 0 30px rgba(255, 46, 94, 0.15);
  --shadow-glow-blue: 0 0 30px rgba(74, 127, 255, 0.15);
}

/* Light theme — preserves the violet/pink accent identity but inverts surface
   colors so the app is readable in bright ambient light. Toggled via the
   titlebar button; the selection is persisted in localStorage. */
body[data-theme="light"] {
  --bg-deep: #f4f2fb;
  --bg-mid: #ebe6f7;
  /* --bg-card removed (light theme parity with dark) */
  --bg-card-solid: #ffffff;
  --bg-input: rgba(0, 0, 0, 0.04);
  --border: rgba(15, 8, 36, 0.12);
  --border-strong: rgba(15, 8, 36, 0.22);
  --text: #1a0f3d;
  --text-muted: #55447a;
  --text-dim: #857aa6;
  --shadow-card: 0 6px 22px rgba(15, 8, 36, 0.08);
}
body[data-theme="light"] #titlebar { background: rgba(255, 255, 255, 0.75); }
body[data-theme="light"] #bg-fx, body[data-theme="light"] #cherry-bg { opacity: 0.1; }
body[data-theme="light"] .big-wins-ticker { background: rgba(124, 58, 237, 0.05); }
body[data-theme="light"] .big-wins-ticker::before { background: linear-gradient(90deg, var(--bg-deep) 0%, transparent 100%); }
body[data-theme="light"] .big-wins-ticker::after { background: linear-gradient(90deg, transparent 0%, var(--bg-deep) 100%); }

* { margin: 0; padding: 0; box-sizing: border-box; }
/* Kill the WebView's blue tap / focus paint app-wide. Telegram on Android
   keeps a tapped <button> focused after release and the user-agent
   stylesheet paints it bright blue; that drowned the cherry-pink active
   glow on the home cards, the games-picker tiles, and any other clickable
   surface. Nuking it once globally avoids per-component focus overrides.
   Keyboard navigation still gets a visible cherry-pink rim wherever each
   component defines :focus-visible explicitly. */
* { -webkit-tap-highlight-color: transparent; }
button:focus, a:focus, [role="button"]:focus, summary:focus,
button:focus:not(:focus-visible),
a:focus:not(:focus-visible),
[role="button"]:focus:not(:focus-visible),
summary:focus:not(:focus-visible) {
  outline: none;
}
html, body { height: 100%; }
:root {
  /* Body / UI text. Inter is the canonical typeface across the app —
     every element flowing through `var(--font-ui)` (body, labels,
     buttons, inputs, top-nav, betting ticket, balance, daily card,
     affiliate, etc.) renders in one consistent family. Open Sans stays
     as a fallback only in case Inter fails to load. Both are loaded
     from Google Fonts in index.html. */
  --font-ui: 'Inter', 'Open Sans', 'SEB Sans Serif', -apple-system, 'Segoe UI', Arial, sans-serif;
  /* Numerics, addresses, hashes, txids, codes — anywhere monospace is
     wanted. Falls back to system mono fonts only if the JetBrains Mono
     webfont is still loading. */
  --font-num: 'JetBrains Mono', ui-monospace, Menlo, Consolas, monospace;
  /* Display / hero headlines. Same family as `--font-ui` so big numbers
     match the rest of the page typographically — only weight + size differ. */
  --font-display: 'Inter', 'Open Sans', system-ui, -apple-system, sans-serif;
}
body { font-family: var(--font-ui); background: var(--bg-deep); color: var(--text); overflow: hidden; font-size: 13px; line-height: 1.5; font-weight: 600; letter-spacing: 0; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
html, input, button, select, textarea { font-family: var(--font-ui); }

#bg-fx {
  position: fixed; inset: 0; z-index: -2;
  background:
    radial-gradient(ellipse 100% 60% at 50% 50%, rgba(74, 127, 255, 0.18) 0%, transparent 70%),
    linear-gradient(180deg, #2a1858 0%, #150a32 100%);
}

/* Boot splash removed per player request — used to be a cherry-logo +
   spinner overlay shown for the cold-boot window between first paint
   and DOMContentLoaded. The half-faded rectangle it left during fade-out
   read as a "stuck" overlay so the whole element was retired. The page
   now paints the bg-fx gradient + game grid directly. */

#cherry-bg {
  position: fixed;
  right: -40px;
  bottom: -40px;
  width: 360px;
  aspect-ratio: 108 / 105;
  pointer-events: none;
  z-index: -1;
  background:
    radial-gradient(ellipse 70% 70% at 30% 25%,
      rgba(255, 140, 170, 0.22) 0%,
      rgba(255, 46, 94, 0.17) 35%,
      rgba(255, 46, 94, 0.08) 70%,
      rgba(255, 46, 94, 0) 100%);
  -webkit-mask: url('./cherry.webp') no-repeat center / contain;
          mask: url('./cherry.webp') no-repeat center / contain;
}

/* Titlebar */
#titlebar {
  height: 48px; padding: 0 0 0 18px;
  display: flex; align-items: center; justify-content: space-between;
  border-bottom: 1px solid var(--border);
  -webkit-app-region: drag;
  /* Glassy top bar — same translucent treatment as #mobile-tabbar. To get
     the actual glass shimmer the bar needs scrollable content to sit
     UNDER it, so the bar is `position: fixed` and the page below leaves
     room for it via padding-top on #content (mobile rule below). Lower
     opacity (0.45) for a stronger glass read, paired with heavy 32px blur
     so the 3D dice scene's bright reflections smear out instead of
     bleeding through as a "cave" strip. */
  background: rgba(15, 8, 36, 0.45);
  backdrop-filter: blur(32px) saturate(160%); -webkit-backdrop-filter: blur(32px) saturate(160%);
  position: fixed; top: 0; left: 0; right: 0;
  /* Above the deposit picker (z=9999) and the mobile bottom nav
     (z=10001) so the navigation chrome always stays visible on top of
     fullscreen modals / pickers / overlays. */
  z-index: 10002;
}
.tb-left { display: flex; align-items: center; gap: 10px; }
.brand-mark { width: 24px; height: 24px; object-fit: contain; filter: drop-shadow(0 0 6px rgba(255, 46, 94, 0.35)); margin-left: 10px; }
.brand-name { font-weight: 800; font-size: 14px; letter-spacing: 0.04em; }
.brand-accent { color: var(--primary); }
.mode-tag { font-size: 10px; padding: 2px 8px; margin-left: 10px; border-radius: var(--r-pill); color: transparent; }
.mode-tag.admin { background: linear-gradient(90deg, var(--gold) 0%, #ff9500 100%); color: #4a2c00; font-weight: 700; letter-spacing: 0.1em; }
.tb-right { display: flex; align-items: center; gap: 4px; -webkit-app-region: no-drag; }
.tb-btn { width: 40px; height: 48px; background: transparent; border: none; color: var(--text-muted); cursor: pointer; font-size: 12px; font-family: inherit; }
body.mobile .tb-btn { display: none; }
/* Modal close buttons re-use .tb-btn but must stay visible on mobile —
   without this override the user modal / username modal / etc had no
   way to dismiss them on phone-sized viewports. */
body.mobile .modal-header .tb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  font-size: 18px;
  color: var(--text);
}
.tb-btn:hover { background: rgba(255, 255, 255, 0.06); color: var(--text); }
.tb-close:hover { background: var(--red); color: white; }
.user-pill {
  padding: 4px 8px;
  background: linear-gradient(180deg, #3c1a7a 0%, #1e0a4b 100%);
  border: none;
  border-radius: var(--r-pill);
  font-size: 11px;
  color: #fff;
  display: flex;
  align-items: center;
  gap: 4px;
  margin-right: 6px;
  cursor: pointer;
  max-width: 320px;
  transition: transform 0.08s, box-shadow 0.12s;
}
.user-pill .pill-email { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 220px; }
.user-pill:hover {
  box-shadow:
    0 10px 26px rgba(168, 85, 247, 0.45);
}
.user-pill:active {
  transform: translateY(2px);
  box-shadow:
    0 4px 12px rgba(109, 40, 217, 0.4);
}
.user-pill.hidden { display: none; }
.user-pill .dot { width: 6px; height: 6px; background: var(--green); border-radius: 50%; box-shadow: 0 0 6px var(--green); }
.user-pill .bal { color: var(--text); font-weight: 600; display: inline-flex; gap: 10px; margin-left: 4px; }
.pill-coin { display: inline-flex; align-items: center; gap: 5px; font-variant-numeric: tabular-nums; }
.pill-coin .coin-ring { padding: 1.5px; }
.pill-coin .coin-icon { width: 14px; height: 14px; }

/* Language picker — opens from the user menu as a centered modal on
   desktop and as a bottom-sheet on mobile (inherits body.mobile rules
   from .coin-picker). Rows reuse `.coin-picker-item` so they match the
   fiat picker exactly; only the circular flag image needs sizing. */
.lang-picker {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 360px; max-width: calc(100vw - 32px);
  max-height: 70vh;
  overflow-y: auto;
}
.lang-flag {
  width: 22px; height: 22px;
  border-radius: 50%;
  flex-shrink: 0;
  object-fit: cover;
  display: block;
}

/* Coin pill + picker (titlebar currency selector) */
.coin-pill-wrap { position: relative; margin-right: 8px; -webkit-app-region: no-drag; }
.coin-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px; font: inherit; color: var(--text);
  background: transparent;
  border: none; border-radius: var(--r-pill);
  cursor: pointer; font-size: 12px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.coin-pill:hover { background: rgba(255, 255, 255, 0.12); }
.coin-pill.hidden { display: none; }
.coin-pill-icon { display: inline-flex; align-items: center; }
.coin-pill-icon .coin-ring { padding: 1.5px; }
.coin-pill-icon .coin-icon { width: 16px; height: 16px; }
.coin-pill { white-space: nowrap; }
.coin-pill-bal {
  /* Desktop coin-pill balance mirrors the .pot-value (Total Bet) hero
     typography so the top-nav account balance and the betting ticket
     numbers read as the same family. */
  display: inline-block;
  white-space: nowrap;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
               Roboto, Helvetica, Arial, sans-serif;
  font-weight: 800;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
}
.coin-pill-bal .coin-pill-fiat { margin-left: 6px; }
.coin-pill-fiat { color: var(--text-muted); font-size: 11px; font-weight: 600; letter-spacing: 0; white-space: nowrap; }
.coin-pill-chev { font-size: 10px; color: var(--text-muted); transition: transform 0.15s; margin-left: 2px; flex-shrink: 0; }
.coin-pill[aria-expanded="true"] .coin-pill-chev { transform: rotate(180deg); }

.coin-picker {
  position: absolute; top: calc(100% + 2px); right: 0; min-width: 240px;
  /* Glassy translucent surface — soft dark tint + strong backdrop-blur so
     the page underneath shows through. Border kept as a faint hairline. */
  background: rgba(15, 8, 36, 0.35);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--r-md); padding: 4px;
  /* Above incidental overlays but below #titlebar (10002) and
     #mobile-tabbar (10001) so the navigation chrome always stays on
     top of the picker. */
  z-index: 10000;
  -webkit-app-region: no-drag;
}
/* Header — "Select" title + × close button at top of the picker. */
.coin-picker-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px 6px;
}
.coin-picker-title {
  font-family: var(--font-ui);
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  color: var(--text);
}
.coin-picker-close {
  background: transparent; border: none; color: var(--text-muted);
  cursor: pointer; font-size: 16px; line-height: 1;
  padding: 4px 6px; border-radius: 6px;
  transition: color 0.12s, background 0.12s;
}
.coin-picker-close:hover { color: var(--text); background: rgba(255,255,255,0.06); }
.coin-picker-search-wrap {
  position: relative;
  display: flex; align-items: stretch; gap: 6px;
  padding: 4px 4px 6px;
}
.coin-picker-search-field { position: relative; flex: 1; min-width: 0; }
.coin-picker-search-icon,
.coin-picker-search-icon svg {
  width: 14px !important; height: 14px !important;
  flex-shrink: 0;
}
.coin-picker-search-icon {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  color: var(--text-muted); pointer-events: none;
  display: inline-flex; align-items: center; justify-content: center;
}
.coin-picker-search {
  width: 100%; padding: 8px 10px 8px 30px; font: inherit; font-size: 12px;
  background: var(--bg-input); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px;
  outline: none; transition: border-color 0.12s, padding 0.15s;
}
.coin-picker-search:focus { border-color: var(--border); }
.coin-picker-search::placeholder { color: transparent; }
/* Floating-label overlay — mirrors the `.field-placeholder` pattern but
   sized + positioned for the compact search input. Sits past the search
   icon by default, floats up to the top of the field when focused or
   when the input has content. `placeholder=" "` (single space) on the
   input drives the `:placeholder-shown` selector. */
.coin-picker-search-label {
  position: absolute;
  left: 30px; top: 50%;
  transform: translateY(-50%);
  color: var(--text); font-size: 12px;
  pointer-events: none;
  transition: top 0.15s, left 0.15s, font-size 0.15s, transform 0.15s;
  z-index: 1;
}
.coin-picker-search-field:focus-within .coin-picker-search-label,
.coin-picker-search-field input:not(:placeholder-shown) + .coin-picker-search-label {
  top: 3px;
  /* Desktop: input has border 1px + padding-left 30px, so typed text starts at x=31. */
  left: 31px;
  font-size: 9px;
  transform: none;
}
/* Mobile uses padding-left:32px, so typed text starts at x=33. Keep the
   floated label aligned with that. */
body.mobile .coin-picker-search-field:focus-within .coin-picker-search-label,
body.mobile .coin-picker-search-field input:not(:placeholder-shown) + .coin-picker-search-label {
  left: 33px;
}
.coin-picker-search-field:focus-within input,
.coin-picker-search-field input:not(:placeholder-shown) {
  padding-top: 14px;
  padding-bottom: 2px;
}
.coin-picker-deposit-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px; padding: 0 14px;
  background: rgba(15, 8, 36, 0.7);
  color: var(--text);
  border: 2px solid #d91554;
  border-radius: var(--r-pill);
  box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.45);
  font-family: var(--font-ui); font-size: 12px; font-weight: 700;
  letter-spacing: -0.01em; font-variant-numeric: tabular-nums;
  cursor: pointer; white-space: nowrap; flex-shrink: 0;
  transition: transform 0.08s, box-shadow 0.12s, background 0.12s;
}
.coin-picker-deposit-btn:hover { background: rgba(15, 8, 36, 0.85); }
.coin-picker-deposit-btn:active {
  transform: translateY(2px);
  box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.45);
}
.coin-picker-deposit-plus {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px;
  background: rgba(15, 8, 36, 0.7);
  border: none;
  border-radius: var(--r-pill);
  color: #fff;
  flex-shrink: 0;
}
.coin-picker-deposit-plus-icon,
.coin-picker-deposit-plus-icon svg {
  width: 14px !important; height: 14px !important;
  stroke: currentColor; stroke-width: 3;
}
.coin-picker-list { display: flex; flex-direction: column; gap: 2px; max-height: 320px; overflow-y: auto; }
.coin-picker-empty { padding: 12px; text-align: center; font-size: 12px; color: var(--text-muted); }
.coin-pill-wrap { z-index: 9999; }
.coin-picker-item {
  display: flex; align-items: center; width: 100%; gap: 10px;
  padding: 10px 12px;
  /* Default rows wear the same dark surface as the top-nav backdrop, so
     the picker reads as an extension of the titlebar instead of a
     brighter card popping above it. */
  background: rgba(15, 8, 36, 0.55);
  border: none; cursor: pointer;
  color: var(--text); font: inherit; font-size: 13px; font-weight: 600;
  border-radius: 8px; text-align: left;
  font-variant-numeric: tabular-nums;
}
.coin-picker-item:hover { background: rgba(255, 255, 255, 0.10); color: #fff; }
/* "Hide 0 balances" — pure CSS filter on items pre-tagged with
   data-zero="1". Toggling the switch only flips this class on the
   picker (no DOM rebuild), so the bottom nav can't shift from a
   layout pass. Same rule applies to the deposit picker (.wd-picker)
   via its own coin-picker-item children. */
.coin-picker.hide-zero .coin-picker-item[data-zero="1"],
.wd-picker.hide-zero .coin-picker-item[data-zero="1"] {
  display: none;
}
.coin-picker-item.active {
  /* Selected coin LIGHTENS off the dark default — the row visibly pops
     forward instead of receding. Mirrors the "default dark → selected
     bright" pattern from the top nav. */
  background: rgba(255, 255, 255, 0.16);
  border: none;
  border-radius: 8px;
  box-shadow: none;
  color: #fff;
}
.coin-picker-icon { display: inline-flex; justify-content: center; }
.coin-picker-icon .coin-ring { padding: 1.5px; }
.coin-picker-icon .coin-icon { width: 18px; height: 18px; }
.coin-picker-name {
  flex: 1; min-width: 0; letter-spacing: 0.05em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.coin-picker-bal {
  color: #fff; font-weight: 600; font-size: 12px;
  white-space: nowrap; flex-shrink: 0;
}

/* Coin-picker footer — "Hide 0 balances" toggle + "Display in Fiat" toggle
   with currency selector. Sits below the coin list with a hairline divider
   above separating it from the item list and another hairline between each
   pair of stacked rows so the footer reads as a settled modal band, matching
   the .wd-picker footer treatment. */
.coin-picker-footer {
  margin-top: 6px; padding: 6px 4px 4px;
  display: flex; flex-direction: column; gap: 2px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.coin-picker-footer .cp-row + .cp-row {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.cp-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px; gap: 10px;
  border-radius: 8px;
  color: var(--text); font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer; user-select: none;
}
.cp-row:hover { background: rgba(255, 255, 255, 0.07); }
.cp-row-label { flex: 1; letter-spacing: 0.02em; }
.cp-row-right { display: inline-flex; align-items: center; gap: 10px; }
.cp-switch {
  appearance: none; -webkit-appearance: none;
  width: 38px; height: 22px; flex-shrink: 0;
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 999px; position: relative;
  transition: background 0.15s, border-color 0.15s;
  cursor: pointer; margin: 0;
}
.cp-switch::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 16px; height: 16px;
  background: #fff; border-radius: 50%;
  transition: transform 0.18s;
}
.cp-switch:checked { background: #3b82f6; border-color: #3b82f6; }
.cp-switch:checked::after { transform: translateX(16px); }
.cp-fiat-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; background: var(--bg-input);
  border: 1px solid var(--border); border-radius: 999px;
  color: var(--text); font: inherit; font-size: 12px; font-weight: 700;
  letter-spacing: 0.04em; cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.cp-fiat-btn:hover { background: rgba(255, 255, 255, 0.12); }
.cp-fiat-flag { font-size: 14px; line-height: 1; }
.cp-fiat-sub {
  margin: 4px 4px 0; padding: 4px;
  background: var(--bg-input); border: 1px solid var(--border);
  border-radius: 8px; max-height: 200px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 2px;
}
.cp-fiat-sub.hidden { display: none; }
.cp-fiat-sub-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: 6px;
  background: transparent; border: none; cursor: pointer;
  color: var(--text); font: inherit; font-size: 12px; font-weight: 600;
  text-align: left;
}
.cp-fiat-sub-item:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }
.cp-fiat-sub-item.active { background: rgba(15, 8, 36, 0.55); color: #fff; }
.cp-fiat-sub-item .cp-fiat-code { flex: 0 0 auto; min-width: 38px; font-weight: 700; letter-spacing: 0.04em; }
.cp-fiat-sub-item .cp-fiat-name { color: var(--text-muted); }

/* Titlebar quick-action icon buttons (deposit, mute, bell bonus) — small
   visible chip with a subtle background + hairline border so they read as
   discrete buttons rather than floating icons. Same surface treatment used
   on the left-nav search button — keeps the top bar's button family
   visually consistent. */
.tb-icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 6px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border);
  color: var(--text);
  cursor: pointer; margin-right: 6px; padding: 0;
  -webkit-app-region: no-drag; transition: background 0.12s;
}
.tb-icon-btn:hover { background: rgba(255, 255, 255, 0.12); }
/* Language flag button — circular wrapper around the SVG flag, same hit
   area as the other tb-icon-btn buttons. Flag scales to 20px so the round
   shape sits comfortably inside the 32px tap target. Overrides the
   squared base above so the round flag isn't framed by a square chip. */
.tb-lang-btn {
  padding: 0;
  border-radius: 50%;
  background: transparent;
  border: none;
}
.tb-lang-btn:hover { background: rgba(255, 255, 255, 0.12); }
.tb-lang-btn .lang-flag { width: 20px; height: 20px; }
.tb-icon-btn.hidden { display: none; }
.user-menu.hidden,
.coin-picker.hidden,
.tb-search-results.hidden,
.tb-deposit-btn.hidden { display: none; }

/* Top-nav Deposit button — same dark surface + white border as coin-pill. */
.tb-deposit-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px; padding: 8px 14px;
  background: transparent;
  color: var(--text);
  border: none; border-radius: var(--r-pill);
  font: inherit; font-size: 12px; font-weight: 700;
  letter-spacing: -0.01em; text-transform: none;
  font-variant-numeric: tabular-nums;
  cursor: pointer; margin-right: 6px; white-space: nowrap;
  -webkit-app-region: no-drag;
  flex-shrink: 0;
}
.tb-deposit-btn > * { flex-shrink: 0; }
.tb-deposit-btn:hover,
.tb-deposit-btn:active { background: rgba(255, 255, 255, 0.12); }
.tb-deposit-icon { width: 16px; height: 16px; stroke: currentColor; flex-shrink: 0; }
/* Mobile: Deposit button collapses to an icon-only pill. The "Deposit"
   text is already exposed via the bottom tab bar, so the top-nav version
   keeps only the wallet icon so the balance + coin-pill always have room. */
body.mobile .tb-deposit-btn { padding: 8px clamp(8px, 2.5vw, 12px); margin-right: 0; }
body.mobile .tb-deposit-btn span { display: none !important; }
body.mobile .tb-deposit-icon { width: clamp(14px, 4vw, 18px); height: clamp(14px, 4vw, 18px); }
.tb-icon { width: 16px; height: 16px; stroke: currentColor; }
body.mobile .tb-icon-btn { width: clamp(30px, 8.5vw, 40px); height: clamp(30px, 8.5vw, 40px); margin-right: 0; }
body.mobile .tb-icon { width: clamp(14px, 4vw, 18px); height: clamp(14px, 4vw, 18px); }

/* Mobile bottom tab bar — only shown on mobile when logged in */
#mobile-tabbar {
  display: none; position: fixed; left: 0; right: 0; bottom: 0;
  min-height: 60px;
  background: rgba(15, 8, 36, 0.35);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--border);
  z-index: 10001; padding-bottom: env(safe-area-inset-bottom, 0);
}
/* Telegram Mini App: viewportStableHeight is shorter than window.innerHeight
   because Telegram Desktop reserves bottom space for the bot-info chrome
   (the @username strip). Pin the bottom nav to Telegram's reported viewport
   bottom so it never slides under that chrome. `--tg-vh` is set in JS by
   tryTelegramLogin and refreshed on viewportChanged. */
body.tg-mode #mobile-tabbar {
  bottom: calc(100vh - var(--tg-vh, 100vh));
}
/* When tg-mode pushes the tabbar UP by the Telegram chrome amount, EVERY
   in-game sticky bet panel has to follow — otherwise the panel keeps its
   `bottom: 60px` calibration and ends up overlapping (the tabbar slides
   over the PLACE BET button). Strict universal override 2026-05 keyed
   off `body.tg-mode.mobile`. Adds the same chrome offset Telegram
   reports via --tg-vh so the panel sits flush above the tabbar's top
   edge regardless of viewport size or which Telegram client. */
body.tg-mode.mobile .dice-controls-sticky,
body.tg-mode.mobile .cf-controls-sticky,
body.tg-mode.mobile .roul-controls-sticky,
body.tg-mode.mobile .slots-controls-sticky,
body.tg-mode.mobile .mines-controls-sticky,
body.tg-mode.mobile .plinko-controls-sticky,
body.tg-mode.mobile .bj-controls-sticky,
body.tg-mode.mobile .crash-controls {
  bottom: calc(60px + env(safe-area-inset-bottom, 0) + (100vh - var(--tg-vh, 100vh))) !important;
}
/* Make sure the page itself doesn't render past Telegram's reported
   viewport, so scrollable content stops above the bot-info chrome. */
body.tg-mode {
  max-height: var(--tg-vh, 100vh);
  overflow: hidden;
}
body.tg-mode #app-view,
body.tg-mode #auth-view {
  max-height: var(--tg-vh, 100vh);
}
body.mobile.logged-in #mobile-tabbar {
  display: grid; grid-template-columns: repeat(5, 1fr);
  gap: clamp(2px, 1vw, 8px);
  padding-left: clamp(2px, 1vw, 6px);
  padding-right: clamp(2px, 1vw, 6px);
}
.mtab {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; background: transparent; border: none; cursor: pointer;
  color: var(--text-muted);
  /* Canonical casino UI typography — matches the top-nav coin-picker
     amount stack (Open Sans 700, tabular nums, -0.01em tracking). */
  font-family: var(--font-ui);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  font-size: clamp(8px, 2.2vw, 11px);
  line-height: 1.1;
  padding: 4px 0;
}
.mtab span { white-space: nowrap; max-width: 100%; }
.mtab:hover, .mtab:active, .mtab.active { color: #fff; }
.mtab-i { width: clamp(18px, 5vw, 22px); height: clamp(18px, 5vw, 22px); stroke: currentColor; flex-shrink: 0; }

/* On mobile when logged-in, leave room below content for tab bar. */
body.mobile.logged-in #content { padding-bottom: calc(60px + env(safe-area-inset-bottom, 0) + 12px); }
body.mobile.logged-in #livechat { bottom: calc(70px + env(safe-area-inset-bottom, 0)); }

/* Hide per-game coin selectors — default coin is set in the titlebar coin-pill.
   The underlying <select> stays in the DOM so handlers reading .value keep working. */
/* Hide the per-game coin selector container entirely — the coin is selected
   globally from the titlebar coin-pill. The <select> itself stays in the DOM
   hidden so game handlers reading .value keep working. */
.dice-field:has(.coin-select),
.crash-ctrl:has(.coin-select) { display: none !important; }

/* Auto-cashout label gets a small info icon — explains how the value
   behaves (round crashes first → you lose; reaches it first → you win
   amount × multiplier). Native `title` tooltip on hover (desktop) and
   long-press (mobile WebView). */
.crash-autocashout-label {
  display: inline-flex; align-items: center; gap: 6px;
}
.autocashout-info {
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-muted); cursor: help;
  border-radius: 50%;
  width: 16px; height: 16px;
  outline: none;
}
.autocashout-info:hover,
.autocashout-info:focus-visible { color: var(--text); }
.coin-dd:has(> select.coin-select) { display: none !important; }
select.coin-select { display: none !important; }

/* Quick bet chip presets — mounted inside the fixed bottom bar, right above
   the Place Bet button, so preset amounts are always reachable.
   Rendered as a single bordered pill with flush chips separated by a thin
   vertical divider, matching the amount-input ½/2×/↻ group. */
/* Quick-chip preset row — discrete outlined button pills (one per chip)
   instead of a single flat bar with vertical separators. Each chip
   reads as its own tappable affordance, which makes the panel feel
   active rather than disabled. The row itself is transparent so the
   pills sit directly on the surrounding panel surface. */
.quick-chips-row {
  display: grid; grid-template-columns: repeat(5, 1fr);
  gap: 6px; margin: 0 0 6px;
  width: 100%;
  background: transparent;
  border: none;
  border-radius: 0;
}
.quick-chips-row > .quick-chip-btn {
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  padding: 8px 4px;
}
.quick-chips-row > .quick-chip-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}
/* Quick-bet chips + amount-group helpers (½ / 2× / .0001 / .001 / …) share
   the same dark-navy palette as the Safe / Medium / Risky risk presets
   for consistency — no red tint, just the calm neutral plate. */
.quick-chip-btn, .dice-quick, .crash-chip {
  /* Flex-centre so the chip number sits exactly in the middle of the pill
     regardless of font width or letter-spacing rounding. */
  display: inline-flex; align-items: center; justify-content: center;
  padding: 8px 10px;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text);
  font: 700 11px inherit;
  /* Letter-spacing applied only to inter-character gaps, not after the
     last char — `text-indent` of the same magnitude visually re-centres
     the trailing whitespace gap. */
  letter-spacing: 0.04em; text-indent: 0.04em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap; text-align: center;
  cursor: pointer;
  transition: 0.15s;
}
.quick-chip-btn:hover, .dice-quick:hover, .crash-chip:hover {
  border-color: var(--border);
  color: #fff;
  background: rgba(36, 21, 71, 0.75);
}
.quick-chip-btn:active, .dice-quick:active, .crash-chip:active { transform: translateY(1px); }
.quick-chip-btn.disabled, .quick-chip-btn:disabled {
  /* Hide unaffordable chips outright rather than strike them through — the
     old line-through still consumed layout space on mobile and read as
     clutter when the balance was below every preset. The "All-in" button
     next to them is enough to signal "bet the rest". */
  display: none;
}
.quick-chip-btn.disabled:hover { border-color: var(--border); color: var(--text-muted); background: rgba(15, 8, 36, 0.55); transform: none; }
/* Inside the fixed bar the potential/hint rows should stay compact. */
body.mobile .autoplay-row .potential-win-row,
body.mobile .crash-controls .potential-win-row { margin: 0 0 6px; padding: 6px 10px; font-size: 11px; }
body.mobile .autoplay-row .amount-hint,
body.mobile .crash-controls .amount-hint { margin: 0 0 4px 2px; }

/* Provably Fair inline badge — shown after every game page's title */
.fair-inline-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; margin: 0 0 12px;
  background: rgba(255, 255, 255, 0.07); color: #fff;
  border: 1px solid var(--border); border-radius: 999px;
  font: inherit; font-size: 11px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
  cursor: pointer; transition: 0.12s;
}
.fair-inline-badge:hover { background: rgba(255, 255, 255, 0.12); color: #fff; border-color: var(--border); }
.fair-rtp {
  padding: 2px 8px; background: rgba(34, 197, 94, 0.18);
  border: 1px solid rgba(34, 197, 94, 0.45); color: var(--green);
  border-radius: 999px; font-size: 10px; font-weight: 800;
  letter-spacing: 0.06em; margin-left: 6px;
}

/* Betting-ticket: two stacked rows (Total Bet + Potential Win) with the
   label on the left, crypto amount + fiat on the right. Same layout as
   the sportsbook reference. */
.potential-win-row {
  display: flex; flex-direction: column; gap: 4px;
  padding: 10px 12px; margin-top: 4px;
  background: transparent;
  border-radius: 10px;
  font-variant-numeric: tabular-nums;
}
.pot-ticket-row {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.pot-label { color: var(--text); font-size: 12px; font-weight: 500; }
.pot-label-strong {
  color: #fff; font-weight: 700; font-size: 12px;
  letter-spacing: 0.04em; text-transform: uppercase;
  /* Keep on a single line and truncate with ellipsis when the right-side
     value is wide enough to crowd the label — otherwise the second word
     ("POTENTIAL", "WIN") wraps and overlaps the value vertically. */
  min-width: 0; flex-shrink: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pot-amount {
  display: inline-flex; align-items: baseline; gap: 8px;
  margin-left: auto;
  flex-shrink: 0;
}
.pot-value { color: var(--text); font-weight: 600; font-size: 13px; white-space: nowrap; }
.pot-ticket-row-win .pot-value {
  color: #fff; font-weight: 800; font-size: 15px;
}
.pot-fiat { color: var(--text-muted); font-weight: 500; font-size: 11px; white-space: nowrap; }
.pot-ticket-row-win .pot-fiat { color: #fff; font-weight: 700; font-size: 13px; }
.pot-mult {
  margin-left: auto; color: #fff; font-weight: 800; font-size: 11px;
  padding: 3px 10px; border-radius: 999px;
  background: linear-gradient(180deg, #a855f7 0%, #7c3aed 100%);
  box-shadow: 0 0 10px rgba(168, 85, 247, 0.35);
  letter-spacing: 0.02em;
}

/* Min/Max amount hint — subtle line under the potential-win row */
.amount-hint {
  font-size: 10px; color: var(--text-dim); margin-top: 2px; margin-left: 4px;
  font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
  font-weight: 700;
}

/* Zero-balance CTA on the play button */
.zero-balance-cta {
  background: linear-gradient(180deg, #ffb800 0%, #e59a00 100%) !important;
  box-shadow: 0 3px 0 0 rgba(140, 90, 0, 0.75), 0 6px 20px rgba(255, 184, 0, 0.35) !important;
  color: #1a0f3d !important;
  font-weight: 900 !important;
  letter-spacing: 0.08em;
}

/* Desktop (Electron) — bet bar sticks to the bottom of the game column, so
   Place Bet stays in view regardless of scroll position. */
body:not(.mobile) .autoplay-row,
body:not(.mobile) .crash-controls {
  position: sticky;
  bottom: 16px;
  z-index: 5;
  background: rgba(15, 8, 36, 0.94);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px 16px;
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.4);
  margin-top: auto;
}
/* Dice risk presets (Safe / Medium / Risky) sit sticky at the top of the
   game column so they're always visible above the scene. */
body:not(.mobile) .dice-risk-row {
  position: sticky;
  top: 8px;
  z-index: 5;
  background: rgba(15, 8, 36, 0.94);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 10px 12px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
}
/* Cap the game column to the viewport so every game fits without the page
   scrolling — the sticky bet bar can then always be seen. Stage/board areas
   inside shrink to fill whatever space is left. */
body:not(.mobile) .game-layout,
body:not(.mobile) .dice-game,
body:not(.mobile) .crash-main {
  height: calc(100vh - 112px);
  max-height: calc(100vh - 112px);
  min-height: 0;
}
/* Crash stage fills whatever space is left in the capped column. */
body:not(.mobile) .crash-stage {
  flex: 1 1 0;
  min-height: 120px;
}
/* All stages fill whatever vertical space is left in the capped game column,
   matching the flex behaviour of .crash-stage. */
body:not(.mobile) .dice-canvas-wrap,
body:not(.mobile) .game-display,
body:not(.mobile) .plinko-stage,
body:not(.mobile) .mines-stage {
  flex: 1 1 0;
  min-height: 120px;
  max-height: 100%;
}
/* Safety net for the Mines board: bind the 5×5 grid to a square that fits
   whichever dimension (width or height) of its container is smaller, so no
   row gets clipped when the stage shrinks. */
body:not(.mobile) .mines-grid {
  aspect-ratio: 1;
  max-height: 100%;
  max-width: min(360px, 100%);
}

/* When the Three.js scene is mounted, its canvas sits absolutely filling
   the mines-stage and has pointer-events disabled so the HTML tile grid
   above still takes clicks. The grid sits on top via z-index. */
.game-display { position: relative; }
/* The "LANDED HEADS / TAILS" overlay (and equivalent labels in other
   3D-hosted game-displays) is disabled per user request — the coin
   visual on the 3D scene already conveys the outcome, the floating
   pill on top read as redundant chrome. */
.game-display .big-result-label {
  display: none !important;
}
.mines-stage { position: relative; }
.mines-stage .mines-3d-canvas {
  position: absolute !important; inset: 0;
  width: 100% !important; height: 100% !important;
  pointer-events: none; z-index: 0;
}
.mines-stage .mines-grid,
.mines-stage .mines-status { position: relative; z-index: 2; }
/* HTML tiles become invisible click targets — the 3D scene renders the
   covers, gems and bombs, so only the clickable hit area stays. */
.mines-stage .mines-tile {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  color: transparent !important;
  text-shadow: none !important;
}
.mines-stage .mines-tile::before,
.mines-stage .mines-tile::after { display: none !important; }

/* Fixed bottom bar — compact but organized. Stacked full-width rows so
   nothing ever feels scattered, and tight spacing keeps total height low.
   .slots-controls-sticky is intentionally NOT in this group — it shares
   the dedicated `.dice-controls-sticky` rule lower down so both panels
   render with identical compositing. */
body.mobile .autoplay-row,
body.mobile .crash-controls {
  position: fixed !important;
  left: 8px !important;
  right: 8px !important;
  bottom: calc(58px + env(safe-area-inset-bottom, 0) + 6px) !important;
  background: rgba(15, 8, 36, 0.3) !important;
  backdrop-filter: blur(18px) saturate(140%); -webkit-backdrop-filter: blur(18px) saturate(140%);
  padding: 8px 10px !important;
  margin: 0 !important;
  border: 1px solid var(--border) !important;
  border-radius: 14px !important;
  z-index: 90 !important;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.5);
  display: flex !important; flex-direction: column !important;
  gap: 5px !important;
  isolation: isolate;
}
body.mobile .autoplay-row::before,
body.mobile .crash-controls::before {
  content: "";
  position: absolute; inset: 0;
  background: rgba(15, 8, 36, 0.7);
  border-radius: inherit;
  z-index: -1;
  pointer-events: none;
}
/* The slots sticky wrapper holds the amount row + quick chips + autoplay +
   SPIN inside a single fixed panel. The inner .autoplay-row must NOT be
   fixed on its own — the wrapper is already fixed for the whole set. */
body.mobile .slots-controls-sticky .autoplay-row::before {
  display: none !important;
}
body.mobile .slots-controls-sticky .autoplay-row {
  position: static !important;
  left: auto !important; right: auto !important; bottom: auto !important;
  background: transparent !important;
  backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
  padding: 0 !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  z-index: auto !important;
  /* Stack: Auto + stop-on-win on top row, SPIN full-width beneath so the
     primary CTA is the widest tap target on screen (#1 conversion lift). */
  display: flex !important; flex-direction: column !important;
  align-items: stretch !important;
  gap: 8px !important;
}
body.mobile .slots-controls-sticky .autoplay-row > .dice-roll-btn {
  width: 100% !important;
  min-height: 52px !important;
  font-size: 16px !important;
  letter-spacing: 0.08em !important;
}
/* Subtle idle pulse — draws the eye back to SPIN every ~2.5 s without
   feeling frantic. Only when the button is actionable (not disabled). */
@keyframes slots-cta-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.02); }
}
body.mobile .dice-roll-btn:not(:disabled),
body.mobile .crash-play-btn:not(:disabled) {
  animation: slots-cta-pulse 2.5s ease-in-out infinite;
}
/* Also hide .slots-controls-sticky while the user isn't logged in, so the
   auth view doesn't have a floating slots panel behind it. */
body:not(.logged-in) .slots-controls-sticky { display: none !important; }

/* Collapse chevron — small button at the top edge of each game's fixed-
   bottom panel. Clicking hides all control rows except the primary CTA
   so the player can free up screen space during a running round. */
.collapse-toggle {
  display: flex !important; align-items: center; justify-content: center;
  width: 100%; height: 20px; flex: 0 0 20px !important;
  background: transparent; border: none; color: var(--text-muted);
  cursor: pointer; padding: 0; margin: 0 !important;
  align-self: stretch !important;
  transition: color 0.12s;
}
.collapse-toggle:hover { color: var(--text); }
/* Slots panel sits over a deep purple slot-machine canvas — the muted
   chevron tone read as nearly invisible against it (user feedback).
   Force the chevron to solid white so it matches what dice shows
   visually. */
body.mobile .slots-controls-sticky > .collapse-toggle {
  color: #fff !important;
}
/* Chevron flip — points down when expanded, up when collapsed. */
.collapse-toggle i,
.collapse-toggle svg { transition: transform 0.18s; }
.collapsed > .collapse-toggle i,
.collapsed > .collapse-toggle svg { transform: rotate(180deg); }
/* When the panel is collapsed, hide all direct children except the
   chevron, the primary CTA container (.autoplay-row / .crash-play-cell),
   and the CTA buttons themselves. Inside .autoplay-row also keep just
   the action button; drop Auto toggle and the Coin/Amount rows.
   Scoped away from .crash-bets-panel — that panel owns its own
   collapse rules (hides list/header only, keeps tabs+footer). */
.collapsed:not(.crash-bets-panel) > *:not(.collapse-toggle):not(.autoplay-row):not(.crash-play-cell):not(.bj-hint-row) {
  display: none !important;
}
.collapsed:not(.crash-bets-panel) .autoplay-row > *:not(.dice-roll-btn):not(.crash-play-btn):not(.bj-actions) {
  display: none !important;
}
.collapsed:not(.crash-bets-panel) .crash-play-cell > *:not(.crash-play-btn):not(.crash-play-again) {
  display: none !important;
}
/* Collapsed panel: less vertical padding since almost everything is hidden. */
.collapsed:not(.crash-bets-panel) {
  padding-top: 4px !important; padding-bottom: 8px !important;
  gap: 4px !important;
}
/* Flexbox-based sticky panel: lives in the normal flow at the bottom of a
   full-height flex column — no calc() maths, no position: fixed, so the
   canvas above it always fills the exact remaining space and can never
   overlap the panel. Applies the same way in every game. */
body.mobile #page-dice.active,
body.mobile #page-coinflip.active,
body.mobile #page-mines.active,
body.mobile #page-plinko.active,
body.mobile #page-crash.active {
  display: flex !important; flex-direction: column;
  /* Viewport - top nav (42) - content top padding (14) - bottom tab bar
     (60) - bottom padding (12) - safe-area = pure available height. The
     overflow: hidden guarantee means the game fits the viewport with no
     page-level scrolling regardless of phone screen size. */
  height: calc(100dvh - 128px - env(safe-area-inset-bottom, 0));
  min-height: 360px;
  overflow: hidden;
}
/* And the #content that wraps the game page mustn't scroll either —
   otherwise long bets lists push the whole page up. Only the inner
   bet-list scroll container (.crash-bets-list) should scroll. */
body.mobile.logged-in #content:has(#page-dice.active),
body.mobile.logged-in #content:has(#page-coinflip.active),
body.mobile.logged-in #content:has(#page-mines.active),
body.mobile.logged-in #content:has(#page-plinko.active),
body.mobile.logged-in #content:has(#page-crash.active) {
  overflow: hidden;
}
body.mobile #page-dice.active .live-layout,
body.mobile #page-dice.active .game-layout,
body.mobile #page-coinflip.active .live-layout,
body.mobile #page-coinflip.active .game-layout,
body.mobile #page-mines.active .game-layout,
body.mobile #page-plinko.active .game-layout {
  display: flex; flex-direction: column;
  flex: 1; min-height: 0;
}
body.mobile #page-dice.active .dice-game {
  display: flex; flex-direction: column;
  flex: 1; min-height: 0;
}
body.mobile #page-dice.active .dice-history,
body.mobile #page-coinflip.active .cf-recent-hero {
  flex-shrink: 0;
}
/* Flex-sized game area: the parent column has height 100 %, the bets
   panel caps at 60 % of it, and the game section flex-grows to take the
   remaining space. Canvas flex-grows inside the game section — no px,
   no hard clamp, purely proportional to what's left. .dice-game is
   intentionally NOT in this list — it's flex-basis-driven via the
   42dvh rule below so it matches coinflip's .game-layout size. Adding
   `height: 100%` made it fight flex-basis and rendered the canvas
   visibly shorter than coinflip's on the same viewport. */
body.mobile .live-layout,
body.mobile .crash-game {
  height: 100% !important;
  min-height: 0 !important;
}
body.mobile .live-layout > .dice-game,
body.mobile .crash-game > .crash-main {
  flex: 1 1 auto !important;
  min-height: 0 !important;
}
body.mobile #page-dice.active .dice-canvas-wrap,
body.mobile #page-coinflip.active .game-display,
body.mobile #page-mines.active .mines-stage,
body.mobile #page-plinko.active .plinko-stage {
  flex: 1 1 auto !important;
  min-height: 0 !important;
  height: auto !important;
  max-height: none !important;
}

/* Dice + slots controls panel: in-flow, pinned to the bottom of the flex
   column. Slots was previously using the shared `body.mobile
   .autoplay-row, .crash-controls, .slots-controls-sticky` rule with a
   different z-index / bottom offset, which composited differently with
   the dark slot canvas behind it and read as "disabled" — pulling slots
   into the same dedicated rule as dice gives both panels identical
   compositing behaviour. */
body.mobile .dice-controls-sticky,
body.mobile .slots-controls-sticky {
  /* Pinned to the viewport bottom (same treatment as crash / coinflip) so
     the PLACE BET row overlays the tail of the All Bets list regardless
     of flex flow / scroll position. Panel is glass (30% + blur); the
     ::before pseudo-element blankets the canvas behind the panel with a
     100% opaque plate so nothing bleeds through from underneath. */
  position: fixed !important;
  left: 8px !important; right: 8px !important;
  bottom: calc(60px + env(safe-area-inset-bottom, 0)) !important;
  flex-shrink: 0;
  display: flex !important; flex-direction: column !important; gap: 8px !important;
  background: rgba(15, 8, 36, 0.3) !important;
  backdrop-filter: blur(18px) saturate(140%) !important; -webkit-backdrop-filter: blur(18px) saturate(140%) !important;
  padding: 6px 8px !important;
  border: 1px solid var(--border) !important;
  border-radius: 14px !important;
  z-index: 50 !important;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.5);
  isolation: isolate;
}
body.mobile .dice-controls-sticky::before,
body.mobile .slots-controls-sticky::before {
  content: "";
  position: absolute; inset: 0;
  background: rgba(15, 8, 36, 0.7);
  border-radius: inherit;
  z-index: -1;
  pointer-events: none;
}
body.mobile #page-slots .game-layout {
  position: relative;
}
/* Slots-only: make the controls panel genuinely transparent (instead of
   the default 30%-bg + 70%-plate ≈ 80% opaque "frosted glass"). User
   wants the slot 3D scene + page background to show through clearly,
   like a true transparent overlay. The `::before` plate is removed and
   the panel's own background is dropped to 12% — backdrop-filter blur
   stays so content edges still soften nicely. */
/* Universal: every game's sticky controls panel uses the same low-
   opacity transparent surface (was 30% bg + 70% ::before plate ≈ 80%
   opaque "frosted glass"). User wants the canvas + page background to
   show through clearly across dice / coinflip / roulette / slots /
   mines / plinko / blackjack / crash. */
body.mobile .dice-controls-sticky,
body.mobile .cf-controls-sticky,
body.mobile .roul-controls-sticky,
body.mobile .slots-controls-sticky,
body.mobile .mines-controls-sticky,
body.mobile .plinko-controls-sticky,
body.mobile .bj-controls-sticky,
body.mobile .crash-controls,
body.mobile .autoplay-row {
  background: rgba(15, 8, 36, 0.12) !important;
}
body.mobile .dice-controls-sticky::before,
body.mobile .cf-controls-sticky::before,
body.mobile .roul-controls-sticky::before,
body.mobile .slots-controls-sticky::before,
body.mobile .mines-controls-sticky::before,
body.mobile .plinko-controls-sticky::before,
body.mobile .bj-controls-sticky::before,
body.mobile .crash-controls::before,
body.mobile .autoplay-row::before {
  background: transparent !important;
}
/* Universal: force every text element inside ANY game's sticky controls
   panel to solid white so labels (Total Bet / Stop autoplay / AUTO /
   chip values / etc.) read crisp against the panel surface in dice,
   coinflip, roulette, slots, mines, plinko, blackjack, crash. Without
   this, several elements inherited default muted/grey tones that
   looked washed-out on the translucent panel. */
body.mobile .dice-controls-sticky,
body.mobile .cf-controls-sticky,
body.mobile .roul-controls-sticky,
body.mobile .slots-controls-sticky,
body.mobile .mines-controls-sticky,
body.mobile .plinko-controls-sticky,
body.mobile .bj-controls-sticky,
body.mobile .crash-controls,
body.mobile .dice-controls-sticky *,
body.mobile .cf-controls-sticky *,
body.mobile .roul-controls-sticky *,
body.mobile .slots-controls-sticky *,
body.mobile .mines-controls-sticky *,
body.mobile .plinko-controls-sticky *,
body.mobile .bj-controls-sticky *,
body.mobile .crash-controls * {
  color: #fff !important;
}
/* Stats as three compact chips in a row — each chip stacks a short label
   (top, muted, tiny) over its value (bottom, bold). Fits three side-by-side
   without any overlap on narrow phones. */
body.mobile .dice-controls-sticky .dice-stats-row {
  display: grid !important;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  padding: 0;
  overflow: visible;
}
body.mobile .dice-controls-sticky .dice-stat {
  display: flex !important; flex-direction: column !important;
  align-items: center; justify-content: center;
  gap: 0; padding: 0 4px;
  min-width: 0; border: none !important;
  line-height: 1.1;
  text-align: center;
}
body.mobile .dice-controls-sticky .dice-stat .muted {
  font-size: 8px; letter-spacing: 0.06em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
body.mobile .dice-controls-sticky .dice-stat strong {
  font-size: 12px; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
               Roboto, Helvetica, Arial, sans-serif;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum', 'cv11';
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
body.mobile .dice-controls-sticky .dice-stat .dice-chance-input {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
               Roboto, Helvetica, Arial, sans-serif !important;
  font-variant-numeric: tabular-nums !important;
  font-feature-settings: 'tnum', 'cv11' !important;
  letter-spacing: -0.01em !important;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
body.mobile .dice-controls-sticky .dice-stat-fiat { display: none !important; }

/* Live / My Bets / Big Wins tabs + Roll Under / Roll Over segments —
   same DexScreener-style Inter typography as the coin-pill balance. */
.crash-tab,
.dice-dir-seg .seg,
.dice-dir-num {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
               Roboto, Helvetica, Arial, sans-serif !important;
  font-variant-numeric: tabular-nums !important;
  font-feature-settings: 'tnum', 'cv11' !important;
  letter-spacing: -0.01em !important;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Hide every game's fixed bottom control panel when the player isn't
   logged in (i.e. the auth view is showing). Fixed-position descendants
   normally do inherit display:none from an ancestor, but an explicit rule
   guards against any parent becoming visually detached. */
body:not(.logged-in) .dice-controls-sticky,
body:not(.logged-in) .cf-controls-sticky,
body:not(.logged-in) .mines-controls-sticky,
body:not(.logged-in) .plinko-controls-sticky,
body:not(.logged-in) .roul-controls-sticky,
body:not(.logged-in) .slots-controls-sticky,
body:not(.logged-in) .bj-controls-sticky,
body:not(.logged-in) .crash-controls,
body:not(.logged-in) .autoplay-row,
body:not(.logged-in) .big-wins-ticker { display: none !important; }
/* Hide the fixed panel when the dice page isn't active (the parent page
   already has display:none, which cascades to descendants — but this rule
   documents the intent explicitly). */
body.mobile .page:not(.active) .dice-controls-sticky { display: none; }
/* Give the dice page enough bottom padding that its own scrollable content
   (canvas, history chips) isn't permanently hidden under the fixed panel. */
body.mobile #page-dice { padding-bottom: 0; }

/* Mines: same treatment — fixed bet + bomb + next-mult + start/cashout
   panel pinned just above the bottom tab bar. */
body.mobile .mines-controls-sticky {
  position: fixed !important;
  left: 8px; right: 8px;
  bottom: calc(60px + env(safe-area-inset-bottom, 0)) !important;
  flex-shrink: 0;
  display: flex; flex-direction: column; gap: 8px;
  background: rgba(15, 8, 36, 0.3);
  backdrop-filter: blur(18px) saturate(140%); -webkit-backdrop-filter: blur(18px) saturate(140%);
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 14px;
  z-index: 50;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.5);
  isolation: isolate;
}
body.mobile .mines-controls-sticky::before {
  content: "";
  position: absolute; inset: 0;
  background: rgba(15, 8, 36, 0.7);
  border-radius: inherit;
  z-index: -1;
  pointer-events: none;
}
body.mobile .mines-controls-sticky .dice-bet-row,
body.mobile .mines-controls-sticky .mines-bomb-row,
body.mobile .mines-controls-sticky .mines-next-mult-display,
body.mobile .mines-controls-sticky .dice-session,
body.mobile .mines-controls-sticky .autoplay-row {
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
  margin: 0 !important;
  position: static !important;
  box-shadow: none !important;
}
body.mobile .page:not(.active) .mines-controls-sticky { display: none; }
body.mobile #page-mines { padding-bottom: 0; }

/* Coinflip: HEADS/TAILS toggle + bet controls + FLIP button pinned to the
   bottom like dice and mines. */
body.mobile .cf-controls-sticky {
  /* Coinflip's sticky lives inside .game-layout, not as a sibling of the
     bets panel — so relative positioning leaves it floating in the middle
     when the bets feed is long. Pin it to the viewport bottom like
     crash-controls does so it overlays the bets feed's tail cleanly. */
  position: fixed !important;
  left: 8px; right: 8px;
  bottom: calc(60px + env(safe-area-inset-bottom, 0)) !important;
  flex-shrink: 0;
  display: flex; flex-direction: column; gap: 6px;
  background: rgba(15, 8, 36, 0.3);
  backdrop-filter: blur(18px) saturate(140%); -webkit-backdrop-filter: blur(18px) saturate(140%);
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 14px;
  z-index: 50;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.5);
  isolation: isolate;
}
body.mobile .cf-controls-sticky::before {
  content: "";
  position: absolute; inset: 0;
  background: rgba(15, 8, 36, 0.7);
  border-radius: inherit;
  z-index: -1;
  pointer-events: none;
}
body.mobile .cf-controls-sticky .dice-dir-row,
body.mobile .cf-controls-sticky .dice-bet-row,
body.mobile .cf-controls-sticky .dice-session,
body.mobile .cf-controls-sticky .autoplay-row {
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
  margin: 0 !important;
  position: static !important;
  box-shadow: none !important;
}
body.mobile .page:not(.active) .cf-controls-sticky { display: none; }
body.mobile #page-coinflip { padding-bottom: 0; }

/* Blackjack sticky panel — same glass treatment as cf/dice/mines/plinko
   so amount input + Total Bet + POTENTIAL WIN + chips + DEAL/HIT/STAND/
   DOUBLE + Suggest basic strategy all live inside one fixed bottom
   panel. Earlier .bj-controls-sticky had no fixed positioning at all,
   so its inner .autoplay-row (DEAL button) inherited the global
   `body.mobile .autoplay-row { position: fixed }` and floated alone
   at the bottom, leaving amount/totals/chips orphaned higher up. */
body.mobile .bj-controls-sticky {
  position: fixed !important;
  left: 8px; right: 8px;
  bottom: calc(60px + env(safe-area-inset-bottom, 0)) !important;
  flex-shrink: 0;
  display: flex; flex-direction: column; gap: 6px;
  background: rgba(15, 8, 36, 0.3);
  backdrop-filter: blur(18px) saturate(140%); -webkit-backdrop-filter: blur(18px) saturate(140%);
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 14px;
  z-index: 50;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.5);
  isolation: isolate;
}
body.mobile .bj-controls-sticky::before {
  content: "";
  position: absolute; inset: 0;
  background: rgba(15, 8, 36, 0.7);
  border-radius: inherit;
  z-index: -1;
  pointer-events: none;
}
body.mobile .bj-controls-sticky .dice-bet-row,
body.mobile .bj-controls-sticky .autoplay-row,
body.mobile .bj-controls-sticky .bj-hint-row {
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
  margin: 0 !important;
  position: static !important;
  box-shadow: none !important;
}
/* While a hand is in progress (DEAL pressed, not yet finished) hide the
   bet-config rows — amount input, Total Bet, POTENTIAL WIN, quick
   chips. Bet is locked in for the active round; showing the editor is
   noise. They reappear automatically when the round ends because the
   .bj-hand-active class is removed in the render pass. autoplay-row
   (HIT/STAND/DOUBLE) and bj-hint-row stay visible. */
.bj-controls-sticky.bj-hand-active .dice-bet-row,
.bj-controls-sticky.bj-hand-active .potential-win-row,
.bj-controls-sticky.bj-hand-active .quick-chips-row {
  display: none !important;
}
body.mobile .page:not(.active) .bj-controls-sticky { display: none; }
body.mobile #page-blackjack { padding-bottom: 0; }

/* Plinko: bet rows + histogram + autoplay/DROP BALL pinned to the bottom. */
body.mobile .plinko-controls-sticky {
  position: fixed !important;
  left: 8px; right: 8px;
  bottom: calc(60px + env(safe-area-inset-bottom, 0)) !important;
  flex-shrink: 0;
  display: flex; flex-direction: column; gap: 8px;
  background: rgba(15, 8, 36, 0.3);
  backdrop-filter: blur(18px) saturate(140%); -webkit-backdrop-filter: blur(18px) saturate(140%);
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 14px;
  z-index: 50;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.5);
  max-height: 60vh;
  overflow-y: auto;
  isolation: isolate;
}
body.mobile .plinko-controls-sticky::before {
  content: "";
  position: absolute; inset: 0;
  background: rgba(15, 8, 36, 0.7);
  border-radius: inherit;
  z-index: -1;
  pointer-events: none;
}
body.mobile .plinko-controls-sticky .dice-bet-row,
body.mobile .plinko-controls-sticky .autoplay-row {
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
  margin: 0 !important;
  position: static !important;
  box-shadow: none !important;
}
body.mobile .page:not(.active) .plinko-controls-sticky { display: none; }
body.mobile #page-plinko { padding-bottom: 0; }
/* Keep Rows + Risk dropdowns on a single row on mobile (they sit inside a
   .dice-bet-row which would otherwise stack them column-wise). */
body.mobile .plinko-rows-risk-row { flex-direction: row !important; gap: 8px; }
body.mobile .plinko-rows-risk-row .dice-field { flex: 1 1 0; width: auto !important; }
/* Individual rows inside the sticky block shed their own borders/bg so the
   outer panel looks like a single card. */
body.mobile .dice-controls-sticky .dice-risk-row,
body.mobile .dice-controls-sticky .dice-bet-row,
body.mobile .dice-controls-sticky .dice-stats-row,
body.mobile .dice-controls-sticky .autoplay-row {
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
  margin: 0 !important;
  position: static !important;
  box-shadow: none !important;
}
/* Sticky panel stays visible during the resolving phase — only the
   button label switches to "PLACE BET (next round)" so the player knows
   betting is about to reopen. No empty-panel blink, no hide/reveal
   churn. */
/* "Potential win" row is visible on mobile — sits just above the chips
   row inside every game's fixed-bottom control panel. Pattern-3 CR lift. */

/* Amount input that was hoisted into the fixed bar */
body.mobile .autoplay-row .bar-amount-field { margin: 0; width: 100%; }
body.mobile .autoplay-row .bar-amount-field label { display: none; }
body.mobile .autoplay-row .bar-amount-field .dice-amount-group {
  display: flex !important; gap: 4px; width: 100%; flex-wrap: nowrap;
}
body.mobile .autoplay-row .bar-amount-field .dice-amount-group .input {
  flex: 1 1 0%; min-width: 0;
}
body.mobile .autoplay-row .pot-label,
body.mobile .crash-controls .pot-label { font-size: 9px; }
body.mobile .autoplay-row .pot-value,
body.mobile .crash-controls .pot-value { font-size: 12px; }
body.mobile .autoplay-row .pot-mult,
body.mobile .crash-controls .pot-mult { font-size: 10px; padding: 2px 8px; }
body.mobile .autoplay-row .amount-hint,
body.mobile .crash-controls .amount-hint { display: none !important; }
body.mobile .autoplay-row .quick-chips-row,
body.mobile .crash-controls .quick-chips-row {
  gap: 3px !important; margin: 0 !important;
  grid-template-columns: repeat(5, 1fr) !important;
}
body.mobile .autoplay-row .quick-chip-btn,
body.mobile .crash-controls .quick-chip-btn {
  padding: 7px 4px; font-size: 11px; border-radius: 8px; min-height: 34px;
  text-align: center; font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  overflow: hidden; text-overflow: ellipsis;
}
body.mobile .autoplay-row .dice-roll-btn,
body.mobile .crash-controls .crash-play-btn {
  /* Primary CTA dominates the row — heavier than the autoplay-toggle
     sibling so the Roll / Spin / Place Bet action is unambiguously the
     main move. Taller (56 vs 40), bigger font (15 vs 13), 800 weight,
     wider via flex:2 1 0 so it claims 2× the room vs the secondary
     toggle which keeps flex:0 0 auto. */
  padding: 12px 16px !important;
  font-size: 15px !important;
  font-weight: 800 !important;
  letter-spacing: 0.1em;
  min-height: 56px;
  flex: 2 1 0;
  width: auto;
}
body.mobile .autoplay-row .autoplay-toggle {
  flex: 0 0 auto;
  opacity: 0.7;
}
body.mobile .autoplay-row .autoplay-toggle:hover,
body.mobile .autoplay-row .autoplay-toggle:focus-within {
  opacity: 1;
}
body.mobile .autoplay-row .autoplay-toggle,
body.mobile .crash-controls .crash-autoplay-row {
  font-size: 10px; margin: 0; padding: 0; gap: 4px;
}
/* Blackjack actions — force a clean 2×2 grid inside the fixed bar so the
   DEAL/HIT/STAND/DOUBLE buttons never pop out or wrap weirdly. */
body.mobile .autoplay-row .bj-actions {
  display: grid !important;
  grid-template-columns: 1fr 1fr !important;
  gap: 5px !important; width: 100%;
}
body.mobile .autoplay-row .bj-actions .dice-roll-btn {
  width: 100% !important; flex: none !important;
  padding: 10px !important; font-size: 12px !important;
  min-height: 40px !important; letter-spacing: 0.06em;
}
/* When only DEAL is shown, center it horizontally within the row. */
body.mobile .autoplay-row .bj-actions #bj-deal:not([style*="display:none"]) + button[style*="display:none"] ~ #bj-deal,
body.mobile .autoplay-row .bj-actions .dice-roll-btn:only-of-type {
  grid-column: 1 / -1;
  justify-self: center;
  max-width: 260px;
}
/* Crash — simple flex-column stack. No grid. Each control its own row. */
body.mobile .crash-controls {
  display: flex !important; flex-direction: column !important;
  grid-template: none !important; grid-template-columns: none !important;
  grid-template-areas: none !important;
  gap: 6px !important;
}
body.mobile .crash-controls .potential-win-row { display: none !important; }
body.mobile .crash-controls .crash-ctrl:has(.coin-select),
body.mobile .dice-field:has(.coin-select) { display: none !important; }
body.mobile .crash-controls > * { grid-area: auto !important; width: 100% !important; }
body.mobile .crash-controls .crash-ctrl {
  display: flex !important; flex-direction: column !important;
  margin: 0 !important; min-width: 0;
}
body.mobile .crash-controls .crash-ctrl label { display: none; }
body.mobile .crash-controls .crash-ctrl label.crash-autocashout-label {
  display: inline-flex !important;
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-muted);
  margin: 2px 0 4px;
}
.crash-cashout-presets {
  display: flex; gap: 4px; margin-top: 6px; flex-wrap: nowrap;
}
.crash-cashout-chip {
  flex: 1; min-width: 0;
  padding: 6px 0; font-size: 12px; font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: var(--r-pill);
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.crash-cashout-chip:hover { background: rgba(255, 255, 255, 0.10); color: #fff; }
.crash-cashout-chip:active { transform: translateY(1px); }
.crash-cashout-chip.active {
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55);
  border-color: var(--primary); color: #fff;
}
body.mobile .crash-controls .crash-ctrl .input {
  padding: 8px 10px !important; font-size: 13px; min-height: 36px; width: 100%;
}
/* Inputs wrapped in the amount pill shed all extra padding so "0." aligns
   with the "Amount" label — the pill itself provides the inner padding. */
body.mobile .crash-controls .amount-input-wrap > .input,
body.mobile .crash-controls .amount-input-wrap > .amount-body > .input {
  padding: 0 !important; min-height: 0 !important; width: auto !important;
}
body.mobile .crash-controls .dice-amount-group {
  /* ½ / 2× / ↻ on the LEFT, amount value on the FAR RIGHT — matches the
     sportsbook-ticket reference. Single row, no wrap. */
  display: flex !important; gap: 6px; flex-wrap: nowrap; align-items: stretch;
  width: 100%;
}
body.mobile .crash-controls .dice-amount-group .amount-input-wrap,
body.mobile .crash-controls .dice-amount-group .field,
body.mobile .crash-controls .dice-amount-group > .input {
  order: 2; margin-left: auto;
}
body.mobile .crash-controls .dice-amount-group .dice-quick { order: 1; }
body.mobile .crash-controls .dice-amount-group .input {
  flex: 0 1 auto; min-width: 0;
}
/* Floating-label wrapper around #c-amount needs explicit flex sizing —
   without it the wrapper collapses to 0 width and the input + label
   become invisible. Mirrors the .withdraw-input-row .field rule. The
   .amount-input-wrap class is intentionally NOT used here: it's an
   existing component (see line ~4357) that strips background+border+
   padding and clamps the input to 4ch wide, which made the field look
   blank against the dark control bar. */
body.mobile .crash-controls .dice-amount-group .field {
  flex: 1 1 auto; min-width: 0; margin-bottom: 0;
}
body.mobile .crash-controls .dice-amount-group .dice-quick {
  flex: 0 0 auto; padding: 0 12px; font-size: 11px;
  min-width: 36px; min-height: 36px;
}
body.mobile .crash-controls .crash-play-cell {
  display: flex !important; flex-direction: column; gap: 3px;
}
body.mobile .crash-controls .crash-play-btn {
  width: 100% !important; padding: 12px !important; font-size: 14px !important;
}
body.mobile .crash-controls .crash-autoplay-row {
  font-size: 10px; gap: 4px; flex-wrap: wrap; padding: 0;
}
body.mobile .crash-controls .crash-autoplay-n { width: 38px; padding: 1px 3px; font-size: 10px; }
body.mobile .crash-controls .quick-chips-row { margin: 0 !important; }
/* Give the game stage more vertical room. */
body.mobile .crash-stage { min-height: 320px !important; }

/* Hide the fixed bottom bar on instant games during resolving/resolved. Crash
   stays visible always so the player can see Place Bet / CASHOUT / NEXT ROUND
   state at a glance. */
/* Keep the autoplay row visible while the round is resolving — the play
   button swaps to a disabled "Bet (Next round)" label so the player can
   still see it and prep for the next window. */
/* In-flight / crashed — don't collapse; instead dim the amount/cashout inputs
   with an overlay so the bar keeps its shape and the play button stays
   prominent. */
.crash-controls.flying-collapsed,
.crash-controls.bet-closed { position: relative; }
.crash-controls.flying-collapsed .crash-ctrl:has(#c-amount),
.crash-controls.flying-collapsed .crash-ctrl:has(#c-cashout),
.crash-controls.bet-closed .crash-ctrl:has(#c-amount),
.crash-controls.bet-closed .crash-ctrl:has(#c-cashout) {
  /* Keep the amount + cashout fully readable AND editable while a round
     is in progress — the player can queue up a bet for the next round.
     The primary CTA's "Bet (Next round)" label signals the state. */
  transition: opacity 0.25s, filter 0.25s;
}
/* Only the currently-active page's fixed bar is visible. */
body.mobile .page:not(.active) .autoplay-row,
body.mobile .page:not(.active) .crash-controls,
body.mobile .page:not(.active) .dice-risk-row { display: none; }
/* Reserve space at content bottom so the fixed bar doesn't cover real content.
   Only applies on game pages where the fixed bar actually exists — non-game
   pages (Daily, Wallet, Profile, …) use the default padding from line 362. */
body.mobile.logged-in #content:has(#page-dice.active),
body.mobile.logged-in #content:has(#page-coinflip.active),
body.mobile.logged-in #content:has(#page-mines.active),
body.mobile.logged-in #content:has(#page-plinko.active),
body.mobile.logged-in #content:has(#page-crash.active) { padding-bottom: calc(58px + env(safe-area-inset-bottom, 0) + 260px); }

/* Favorite heart icon on game nav buttons */
.nav-btn { position: relative; }
.nav-fav {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  color: var(--text-dim); opacity: 0.4; cursor: pointer;
  transition: 0.12s;
}
.nav-btn:hover .nav-fav { opacity: 1; color: var(--text-muted); }
.nav-fav.active { color: #ff3d6a; opacity: 1; }
.nav-fav.active i { fill: #ff3d6a; }
.nav-fav:hover { background: rgba(255, 255, 255, 0.12); }
/* No left-border shift on favorited items — the heart fill is enough indicator. */
#sidebar.collapsed .nav-fav, body.mobile #sidebar .nav-fav { display: none; }

/* Big Wins marquee ticker — above content */
.big-wins-ticker {
  /* Disabled per user request — the scrolling wins ticker behind the
     top nav was distracting. Force-hidden everywhere; the rest of the
     ticker rules below stay in place so re-enabling is a one-line
     revert (drop this `display: none`). */
  display: none !important;
  overflow: hidden;
  background: rgba(15, 8, 36, 0.96);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
  padding: 8px 0 0 0;
  z-index: 50;
  position: absolute; top: 0; left: 220px; right: 0;
}
body.mobile .big-wins-ticker { position: relative; left: 0; right: 0; }
.big-wins-ticker.hidden { display: none; }
.big-wins-ticker::before, .big-wins-ticker::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 48px;
  pointer-events: none; z-index: 1;
}
.big-wins-ticker::before { left: 0; background: linear-gradient(90deg, var(--bg-deep) 0%, transparent 100%); }
.big-wins-ticker::after { right: 0; background: linear-gradient(90deg, transparent 0%, var(--bg-deep) 100%); }
.big-wins-track {
  display: inline-flex; align-items: center; gap: 0;
  white-space: nowrap;
  animation: big-wins-scroll 60s linear infinite;
  /* Force a GPU compositor layer — without this, Android WebView (and some
     Electron builds) re-paints the marquee on every frame instead of
     compositing the translated layer, which reads as "laggy" on mobile. */
  will-change: transform;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
}
.big-wins-ticker:hover .big-wins-track { animation-play-state: paused; }
.big-wins-item {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0 14px; font-size: 12px; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.big-wins-item strong { color: #fff; font-weight: 700; }
.big-wins-user { color: #fff; font-weight: 600; }
.player-flag { margin-right: 5px; font-size: 1.05em; }
.av.av-flag {
  background: rgba(255, 255, 255, 0.06) !important;
  font-size: 16px; line-height: 1; display: inline-flex;
  align-items: center; justify-content: center;
}
/* Hide the small flag row in the top "All Bets" summary — only the sum is
   useful there, per user request. */
.crash-bets-avatars { display: none !important; }
/* Hide the whole totals block (0.0000 / N Bets / Total win) — players
   only need the tabs + list; the aggregate line felt like clutter.
   Extra-specific form overrides the `body.mobile .page.bets-shown
   .crash-bets-panel.collapsed .crash-bets-total { display: flex !important }`
   rule in the mobile-layout block. */
.crash-bets-total,
body.mobile .crash-bets-total,
body.mobile .page .crash-bets-panel .crash-bets-total,
body.mobile .page.bets-shown .crash-bets-panel.collapsed .crash-bets-total,
html body .crash-bets-total,
html body.mobile .crash-bets-total,
.crash-bets-panel > .crash-bets-total,
.crash-bets-panel.collapsed .crash-bets-total {
  display: none !important;
  visibility: hidden !important;
  height: 0 !important;
  overflow: hidden !important;
  margin: 0 !important;
  padding: 0 !important;
}

/* Collapsed bets panel — only the tabs + "Provably Fair" footer are visible.
   Click the tabs row to expand and reveal the bet list. */
.crash-bets-panel .crash-bets-tabs { cursor: pointer; user-select: none; }
.crash-bets-panel.collapsed .crash-bets-total,
.crash-bets-panel.collapsed .crash-bets-header,
.crash-bets-panel.collapsed .crash-bets-list { display: none !important; }
/* Beat the desktop .live-layout/.crash-game grid item stretch so the collapsed
   panel only takes the space it needs. */
.live-layout > .crash-bets-panel.collapsed,
.crash-game > .crash-bets-panel.collapsed,
.crash-bets-panel.collapsed {
  height: auto !important; min-height: 0 !important; max-height: none !important;
  padding: 8px !important; gap: 6px !important;
  align-self: start !important;
}
.crash-bets-panel .crash-tab::after { content: ""; }

/* Old mobile bottom-sheet drawer rules removed — they were conflicting
   with the FINAL OVERRIDE block at the bottom of this file (which keeps
   the panel inline + full-width). The single source of truth for
   .crash-bets-panel sizing now lives at the end of styles.css. */
.big-wins-game { color: #fff; font-weight: 600; display: inline-flex; align-items: center; gap: 4px; }
.big-wins-game-icon { width: 14px; height: 14px; stroke: currentColor; flex-shrink: 0; }
.big-wins-x { color: var(--green); font-weight: 700; }
.big-wins-time { color: var(--text-dim); font-size: 11px; }
.big-wins-sep { color: var(--text-dim); margin: 0 4px; }
@keyframes big-wins-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

body.mobile .big-wins-ticker { padding: 6px 0; }
body.mobile .big-wins-item { font-size: 11px; padding: 0 10px; }

/* Titlebar global game search — collapses to a 32×32 icon-button on
   desktop (matching the right-side .tb-icon-btn family) and expands to
   a 260px input on focus. Clicking the icon hits the input (which fills
   the wrap), so focus expands naturally with no JS. */
.tb-search-wrap {
  position: relative; display: flex; align-items: center;
  margin-left: 8px;
  flex: 0 0 32px;
  width: 32px;
  height: 32px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  transition: flex-basis 0.18s ease, width 0.18s ease,
              max-width 0.18s ease, background 0.12s ease;
  -webkit-app-region: no-drag;
}
.tb-search-wrap:hover { background: rgba(255, 255, 255, 0.12); }
.tb-search-wrap:focus-within {
  flex: 0 1 260px; width: 260px; max-width: 260px;
  background: rgba(255, 255, 255, 0.10);
}
.tb-search-wrap.hidden { display: none; }
.tb-search-icon {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 16px; height: 16px; color: var(--text);
  pointer-events: none;
  transition: left 0.18s ease, transform 0.18s ease;
}
.tb-search-wrap:focus-within .tb-search-icon {
  left: 10px; transform: translateY(-50%);
}
.tb-search {
  width: 100%; height: 100%;
  padding: 0 10px 0 32px;
  background: transparent; color: var(--text);
  border: none; border-radius: 6px;
  font: inherit; font-size: 12px;
  outline: none;
}
.tb-search::placeholder { color: var(--text-dim); }
.tb-search-wrap:not(:focus-within) .tb-search::placeholder { color: transparent; }
.tb-search:hover,
.tb-search:focus { background: transparent; }
.tb-search::placeholder { color: var(--text-dim); }
.tb-search-results {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0;
  background: var(--bg-card-solid); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 4px; z-index: 9999;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4); max-height: 360px; overflow-y: auto;
}
.tb-search-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 12px; background: transparent; border: none;
  color: var(--text); font: inherit; font-size: 13px; font-weight: 600;
  border-radius: 6px; text-align: left; cursor: pointer;
}
.tb-search-item:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }
.tb-search-item i { color: var(--text-muted); flex-shrink: 0; }
.tb-search-empty { padding: 14px; text-align: center; color: var(--text-muted); font-size: 12px; }

/* Mobile search — input shrinks to fit its placeholder width so the
   background capsule hugs the text instead of stretching the full titlebar.
   The results dropdown still breaks out to full viewport width. */
/* Mobile search: collapsed to just the icon until focused, then expands to
   fill available width (hiding the cherry logo). */
body.mobile .tb-search-wrap {
  margin-left: 4px; margin-right: 4px;
  flex: 0 0 clamp(30px, 8.5vw, 38px) !important;
  width: clamp(30px, 8.5vw, 38px) !important;
  min-width: 0 !important; max-width: clamp(30px, 8.5vw, 38px) !important;
  transition: flex-basis 0.2s ease, width 0.2s ease, max-width 0.2s ease;
  order: 0;
  position: relative;
}
body.mobile .tb-left:focus-within .tb-search-wrap,
body.mobile.searching .tb-search-wrap {
  flex: 0 1 auto !important; width: auto !important;
  max-width: calc(100vw - 320px) !important;
  min-width: 60px !important;
  margin-right: 8px !important;
}
body.mobile .tb-left { gap: 6px !important; }
body.mobile .brand-mark { display: block; width: clamp(20px, 5.5vw, 28px); height: clamp(20px, 5.5vw, 28px); flex-shrink: 0; order: -1; margin-left: 8px; }
body.mobile .tb-search {
  width: 100% !important; max-width: none !important;
  padding: 7px 10px 7px 30px !important;
  font-size: 11px !important; min-height: 34px !important;
}
/* Hide the placeholder when the search wrap is collapsed — keeps the
   truncated "Sea…" text from leaking out next to the icon. The input
   itself stays tappable so focus still expands the wrap. */
body.mobile .tb-search::placeholder { color: transparent !important; }
body.mobile .tb-left:focus-within .tb-search::placeholder,
body.mobile.searching .tb-search::placeholder { color: var(--text-muted) !important; }
body.mobile .tb-search-icon { left: 8px; width: 16px; height: 16px; color: var(--text-muted); }
body.mobile .tb-search-results {
  position: fixed !important; top: 46px !important; left: 8px !important;
  right: 8px !important; width: auto !important; max-height: 70vh;
}

/* Hero-balance topnav: the coin-pill scales up so the player's current
   balance is the dominant element of the titlebar — same visual weight
   as a Robinhood/Coinbase-style headline. Icon larger, amount in a big
   800-weight number, fiat dropped to a small sub-line below it. The
   wallet modal's separate hero is removed (see below) since the topnav
   already shows this info on every page. */
body.mobile .coin-pill {
  padding: 4px clamp(6px, 2vw, 12px);
  gap: clamp(8px, 2.2vw, 10px);
  min-height: 50px;
  flex-shrink: 0;
  align-items: center;
}
body.mobile .coin-pill-icon { flex-shrink: 0; }
body.mobile .coin-pill-icon .coin-ring { padding: 0; background: transparent !important; }
body.mobile .coin-pill-icon .coin-icon {
  width: clamp(26px, 7.2vw, 32px);
  height: clamp(26px, 7.2vw, 32px);
  flex-shrink: 0;
}
body.mobile .coin-pill-bal {
  /* Account balance typography — mirrors the .pot-value (Total Bet /
     Potential Win) hero-money look in the betting ticket so the top-nav
     balance and the betting numbers read as one typographic family.
     Inter Heavy + tabular-nums + tight letter-spacing. */
  display: inline-flex !important;
  flex-direction: column;
  align-items: flex-start;
  white-space: nowrap;
  flex-shrink: 0;
  font-size: 17px !important;
  font-weight: 800 !important;
  letter-spacing: -0.01em !important;
  line-height: 1.2 !important;
  color: #fff !important;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
               Roboto, Helvetica, Arial, sans-serif !important;
  font-variant-numeric: tabular-nums !important;
  font-feature-settings: 'tnum', 'cv11' !important;
  -webkit-font-smoothing: antialiased !important;
  -moz-osx-font-smoothing: grayscale !important;
}
body.mobile .coin-pill-bal .coin-pill-fiat {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
               Roboto, Helvetica, Arial, sans-serif !important;
  font-variant-numeric: tabular-nums !important;
  font-feature-settings: 'tnum' !important;
  letter-spacing: -0.005em !important;
  font-weight: 500 !important;
}
body.mobile .coin-pill-bal .coin-pill-fiat {
  margin: 1px 0 0 0 !important;
  font-size: clamp(10px, 2.8vw, 12px);
  font-weight: 600;
  letter-spacing: 0;
  color: var(--text-muted);
}
body.mobile .coin-pill-chev {
  font-size: clamp(11px, 3vw, 13px);
  flex-shrink: 0;
  align-self: center;
}
/* Make sure the two halves of the titlebar can shrink past their content
   width if needed — without min-width:0 they refuse to compress and bleed
   into each other on narrow viewports. */
/* Mirror the bottom-tabbar treatment: flatten .tb-left / .tb-right so every
   visible top-bar item becomes a direct flex child, then space them evenly
   across the full width instead of clustering at the centre. */
body.mobile #titlebar { flex-wrap: nowrap !important; gap: 0; overflow: visible; justify-content: space-evenly !important; padding: 8px 0 !important; }
body.mobile #titlebar .tb-left,
body.mobile #titlebar .tb-right { display: contents; }
/* Narrow phones: shrink pills first, keep icons at a reduced fixed size so
   + and sound always fit on the same row as coin-pill and user-pill. */
body.mobile .tb-left,
body.mobile .tb-right { min-width: 0; flex-shrink: 1; flex-wrap: nowrap; }
body.mobile .tb-right { gap: clamp(8px, 2.5vw, 14px); padding-right: clamp(4px, 1.5vw, 8px); }
/* Nudge the sound icon tighter against the user-menu chev — they are both
   utility icons, visually read better as a pair. */
body.mobile #tb-mute { margin-left: -6px; }
/* Hide the top-bar sound toggle while the Login / Sign-up modal is visible. */
body:not(.logged-in) #tb-mute { display: none !important; }
/* Hide the whole top-nav bar on mobile while the Login / Sign-up modal is
   visible. Desktop Electron keeps it because that strip also houses the
   minimize / maximize / close window controls. */
body.mobile:not(.logged-in) #titlebar { display: none !important; }
/* Icon buttons (+ and sound) — fluid size via clamp, stays transparent. */
/* Topnav action icons — uniform 40 × 40 tap target, centred 20 px
   lucide icon inside. Premium chrome look matching the Telegram
   native header buttons. */
body.mobile .tb-icon-btn {
  margin: 0 !important;
  flex: 0 0 auto;
  width: 40px !important;
  height: 40px !important;
  background: transparent !important;
  border: none !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: rgba(255, 255, 255, 0.85) !important;
  transition: color 0.15s ease, transform 0.12s ease !important;
}
body.mobile .tb-icon-btn:hover { color: #fff !important; }
body.mobile .tb-icon-btn:active { transform: scale(0.94) !important; background: transparent !important; }
body.mobile .tb-icon-btn .tb-icon,
body.mobile .tb-icon-btn i[data-lucide] {
  width: 20px !important;
  height: 20px !important;
  stroke-width: 2 !important;
}
/* Tighten right-side gap so icons read as a compact action cluster
   instead of loose floating chips. */
body.mobile .tb-right {
  gap: 4px !important;
  padding-right: 4px !important;
}
/* User-pill chev — visible so the player knows there's a dropdown
   (Change username / Change language / Change password / Sign out)
   behind the user-pill. Without it the pill renders empty on mobile
   (.pill-email is hidden) and the dropdown is undiscoverable. */
body.mobile .user-pill .pill-chev {
  display: inline-flex !important;
  align-items: center !important;
  color: rgba(255, 255, 255, 0.85) !important;
  font-size: 14px !important;
  margin-left: 2px !important;
}
/* Balance coin picker is sized to its content and never shrinks — the full
   crypto amount + icon + chevron must always be visible. Other tb-right
   siblings (deposit button, sound icon) yield space as the viewport narrows. */
body.mobile .coin-pill-wrap { margin-right: 0; flex: 0 0 auto; min-width: 0; }
body.mobile .user-menu-wrap { flex: 0 0 auto; min-width: 0; }
body.mobile .user-pill { flex-shrink: 0; overflow: visible; }

/* === Touch ergonomics on mobile — ensure all interactive elements meet
   the 44×44 minimum tap target (Apple HIG / Material guideline). === */
body.mobile .mtab { min-height: 60px; }
body.mobile .coin-picker-item { min-height: 48px; padding: 12px 14px; font-size: 14px; }
/* Drop the per-item dark plate inside both the top-nav coin-picker
   and the wallet Currency dropdown (wd-picker) so each sheet reads as
   one uninterrupted glassy surface end-to-end — the default
   rgba(15,8,36,0.55) plate compounded darker over the translucent
   picker bg, leaving items visibly denser than the empty band below
   "Hide 0 balances". */
body.mobile .coin-picker .coin-picker-item,
body.mobile .wd-picker .coin-picker-item {
  background: transparent;
}
/* Re-assert hover / active highlights at matching specificity so the
   transparent default above doesn't swallow them — without these
   overrides the selected coin row and the tap-highlight both lost
   their backgrounds, making the picker feel inert. */
body.mobile .coin-picker .coin-picker-item:hover,
body.mobile .wd-picker .coin-picker-item:hover {
  background: rgba(255, 255, 255, 0.10);
}
body.mobile .coin-picker .coin-picker-item.active,
body.mobile .wd-picker .coin-picker-item.active {
  background: rgba(255, 255, 255, 0.16);
}
/* Item stretch removed — the wd-picker is now content-sized
   (body.mobile .wd-picker has bottom: auto + max-height cap), so the
   sheet shrinks to its rendered rows. Stretching items here would
   blow them up to fill the max-height cap, making each row 100+ px
   tall on tall phones. Items stay at native compact size. */
body.mobile .coin-picker-search { padding: 12px 14px 12px 32px; font-size: 14px; min-height: 44px; }
body.mobile .coin-picker-deposit-btn { font-size: 13px; min-height: 44px; padding: 0 14px; }
body.mobile .coin-picker-deposit-plus { width: 22px; height: 22px; border-radius: 6px; }
body.mobile .coin-picker-deposit-plus-icon,
body.mobile .coin-picker-deposit-plus-icon svg { width: 16px !important; height: 16px !important; }
body.mobile .wd-pill { min-height: 52px; font-size: 15px; }

/* Deposit-pair Currency + Network pills — strip the background plate
   and border so they read as inline labels with chevron, not boxed
   buttons. The pills stay tappable (full row click target) and the
   chev still signals "tap to change". Both cells use the same
   min-height + content alignment so Currency (ETH) and Network
   (Ethereum (ERC-20)) read as the same chrome row. */
body.mobile .deposit-pair .wd-pill {
  background: transparent !important;
  border: none !important;
  padding: 10px 14px !important;
  width: 100% !important;
  min-height: 40px !important;
  justify-content: flex-start !important;
  gap: 10px !important;
}
body.mobile .deposit-pair .wd-pill-name {
  font-size: 14px !important;
  font-weight: 700 !important;
  color: #fff !important;
  flex: 1 1 auto !important;
  text-align: left !important;
}
body.mobile .deposit-pair .wd-pill-chev {
  margin-left: auto !important;
  color: rgba(255, 255, 255, 0.65) !important;
}
body.mobile .quick-chip-btn { padding: 10px 14px; font-size: 12px; min-height: 36px; }
body.mobile .fair-inline-badge { padding: 10px 16px; font-size: 12px; min-height: 38px; }
body.mobile .withdraw-max, body.mobile .withdraw-submit { min-height: 48px; font-size: 13px; }
body.mobile .deposit-copy { min-height: 40px; }
body.mobile .tb-icon-btn { width: clamp(28px, 8vw, 36px); height: clamp(28px, 8vw, 36px); }
body.mobile .tb-icon { width: clamp(14px, 4vw, 18px); height: clamp(14px, 4vw, 18px); }
body.mobile .tb-burger { width: 44px; height: 44px; }
body.mobile .tb-burger-icon { width: 24px; height: 24px; }
body.mobile .lc-toggle { width: 56px; height: 56px; }
body.mobile .nav-fav { width: 34px; height: 34px; right: 4px; }
body.mobile .nav-fav i { width: 18px; height: 18px; }
/* width/height overrides are in the dedicated mobile search block above */
body.mobile .tb-search-item { padding: 12px 14px; font-size: 14px; min-height: 48px; }
body.mobile .seg { padding: 14px 10px; font-size: 13px; min-height: 46px; }
body.mobile .btn-primary, body.mobile .btn-lg { min-height: 48px; }
body.mobile .dice-quick, body.mobile .crash-chip { min-height: 40px; padding: 10px 14px; font-size: 12px; }
body.mobile .input { min-height: 44px; font-size: 14px; padding: 12px 14px; }
body.mobile .user-pill { padding: 8px 12px; min-height: 36px; }
/* Mobile picker: pin to the viewport, not the pill. Previously it was
   centred on .coin-pill-wrap which sits in the top-right — `min-width: 200px`
   overflowed the left edge and clipped the first letter of every coin name
   and the search field. `position: fixed` + left/right gutters keep the
   panel fully on-screen regardless of where the pill sits. */
body.mobile .coin-picker {
  position: fixed;
  /* Pin the top to just below the top nav AND the bottom to just above
     the bottom nav. The bottom offset also adds (100vh - var(--tg-vh))
     so that in Telegram WebApp mode — where Telegram reports a usable
     viewport (`viewportStableHeight`) shorter than `100vh` and slides
     the bottom nav up via `body.tg-mode #mobile-tabbar`'s own offset —
     the picker's bottom edge tracks the nav's top edge instead of
     extending past it and tucking the "Display in Fiat" footer row
     behind the chrome. Outside tg-mode the term is 0 (--tg-vh falls
     back to 100vh) so the original `60px + safe-area` clearance is
     preserved. */
  top: 68px;
  bottom: calc(60px + env(safe-area-inset-bottom, 0px) + 100vh - var(--tg-vh, 100vh));
  left: 0;
  right: 0;
  transform: none;
  min-width: 0;
  max-width: none;
  width: 100%;
  height: auto;
  max-height: none;
  display: flex;
  flex-direction: column;
  /* Same glassy treatment as the desktop .coin-picker rule. The previous
     solid `--bg-card-solid` made the mobile sheet read as a heavy card. */
  background: rgba(15, 8, 36, 0.35) !important;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  /* No rounded corners — the picker now spans flush from the titlebar's
     bottom edge down to the bottom nav's top edge, so the same flat
     merge applied at the bottom should also apply at the top. The
     previous 16px top radii made the picker read as a separate card
     peeking out from under the titlebar instead of a continuous sheet
     between the two nav chromes. */
  border-radius: 0;
  border: none;
  /* Bumped 9999 → 10000 so the picker sits above any incidental overlay
     content but still below #titlebar (10002) and #mobile-tabbar (10001),
     keeping both nav chromes visible on top of the picker. */
  z-index: 10000;
}
body.mobile .coin-picker-list {
  flex: 1 1 auto; min-height: 0;
  max-height: none;
}
/* Pin the picker footer to the bottom of the picker so the empty band
   below the footer is absorbed. The list above flex-grows;
   margin-top:auto pushes the footer band down against the bottom nav
   clearance. Applies to BOTH the top-nav coin-picker and the wallet
   Currency dropdowns (wd-picker / dep-picker / wd-picker — all share
   .wd-picker class), so the picker's bottom edge merges flush with
   the bottom nav with no visible gap to the page underneath. */
body.mobile .coin-picker .coin-picker-footer,
body.mobile .wd-picker .coin-picker-footer {
  margin-top: auto;
}
.coin-picker-backdrop {
  position: fixed;
  top: 0; left: 0; right: 0;
  /* Track the bottom nav same as .coin-picker — (100vh - --tg-vh) term
     keeps the backdrop's bottom edge aligned with the nav's top edge
     when Telegram WebApp slides the nav up. */
  bottom: calc(60px + env(safe-area-inset-bottom, 0px) + 100vh - var(--tg-vh, 100vh));
  /* Light scrim — strong enough to dim the page so the glass panel pops,
     light enough to keep the page visible through the picker. The previous
     0.5 alpha turned the panel into a near-solid dark slab even with the
     glass background. */
  background: rgba(0, 0, 0, 0.2);
  /* Sits just below the picker (10000) but above page content, so the
     backdrop dims the page without occluding the picker itself. */
  z-index: 9999;
  -webkit-app-region: no-drag;
  pointer-events: none;
}

/* Views */
/* The titlebar is now `position: fixed` so views fill the full viewport;
   the bar overlays the top 48px and `#content` pads itself to clear it. */
.view { display: none; height: 100vh; }
.view.active { display: flex; }

/* Auth */
#auth-view { flex-direction: column; align-items: center; justify-content: center; padding: 24px; gap: 0; }
.auth-card {
  width: 100%; max-width: 420px;
  /* Experimental — completely strip the card chrome (background, border,
     shadow). The form sits directly on the page background. */
  background: transparent;
  backdrop-filter: none; -webkit-backdrop-filter: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  /* Less top padding so WELCOME BACK sits right under the logo, matching
     the reference layout. */
  padding: 8px 32px 32px;
}
/* Brand logo floats above the auth card with a soft round purple bloom
   directly behind it — same shape and intensity as the Cloudbet sign-in
   logo. Identical look on desktop and mobile: the wrapper draws a
   radial-gradient halo (renders consistently on every WebView, no
   filter-blur quirks) that's roughly 3× the logo's size, with a tight
   inner core and a long soft falloff so it reads as ambient bloom
   rather than a hard ring. The cherry image itself stays without
   filter so its silhouette is crisp against the bloom. */
.auth-logo-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  isolation: isolate;
  /* Reserve room around the image so the bloom isn't clipped by the
     auth-view padding. Larger reserve = softer / wider falloff (more
     diffusion at the edge). */
  padding: 90px;
  margin: -90px;
}
.auth-logo-wrap::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  /* Subtle Cloudbet-style ambient bloom — low-alpha purple with a
     long soft falloff. Roughly half the intensity of the previous
     stack so the halo reads as ambient lighting around the logo,
     not a glowing button. */
  background: radial-gradient(
    closest-side,
    rgba(168, 85, 247, 0.22) 0%,
    rgba(168, 85, 247, 0.12) 35%,
    rgba(168, 85, 247, 0.05) 60%,
    rgba(168, 85, 247, 0) 85%
  );
  z-index: -1;
  pointer-events: none;
}
.auth-logo {
  display: block;
  width: clamp(72px, 20vw, 120px);
  height: auto;
  filter: none;
}
.auth-coin-strip {
  width: 100%;
  max-width: 420px;
  overflow: hidden;
  margin: 8px auto 0;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
}
.auth-coin-track {
  display: flex;
  width: max-content;
  will-change: transform;
}
.auth-coin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  flex-grow: 0;
  opacity: 0.35;
  width: 54px;
  box-sizing: border-box;
}
.auth-coin svg { width: 32px; height: 32px; display: block; }
.auth-header { text-align: center; margin-bottom: 24px; }
.auth-title { font-size: 26px; font-weight: 800; letter-spacing: 0.04em; margin-bottom: 6px; }
.auth-sub { color: var(--text-muted); font-size: 14px; font-weight: 600; }
.auth-tabs { display: flex; gap: 6px; margin-bottom: 20px; }
.tab { flex: 1; padding: 12px 10px; background: transparent; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; color: var(--text-muted); cursor: pointer; font-family: inherit; font-size: 14px; font-weight: 600; transition: 0.15s; }
.tab:hover { color: var(--text); }
.tab.active { color: var(--text); border-bottom-color: var(--text); }
.auth-form { display: flex; flex-direction: column; gap: 12px; }
.auth-hint { font-size: 11px; color: var(--text-dim); }
.auth-server { margin-top: 16px; text-align: center; font-size: 10px; color: var(--text-dim); font-family: var(--font-num); }
.field { position: relative; }
.field-icon {
  position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
  color: var(--text-muted);
  opacity: 0.6;
}
.field input {
  width: 100%; padding: 16px 44px 16px 48px;
  /* Dark filled pill — deep-navy translucent fill, light text. 14 px radius
     and floating-label overlay kept from the light-fill revision. */
  background: rgba(15, 8, 36, 0.55);
  border: 2px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  color: var(--text);
  /* Typography matches the placeholder overlay so the field reads the same
     weight + size whether empty or filled (lifted from the reference
     screenshot — regular weight, 15 px). */
  font-family: inherit; font-size: 15px; font-weight: 400;
  letter-spacing: 0.01em;
  transition: border-color 0.12s, background 0.12s;
}
.field input:hover {
  background: rgba(15, 8, 36, 0.7);
  border-color: rgba(255, 255, 255, 0.18);
}
.field input:focus {
  outline: none;
  background: rgba(15, 8, 36, 0.7);
  /* Solid Place Bet pink on focus — same base colour as the in-game CTA
     gradient (rgb 217, 21, 84). Matches the Continue button's ready state
     so the form reads as one visual piece. */
  border-color: #d91554;
  box-shadow: none;
}
/* Floating-style label — rendered as an overlay `<span>` so the `*`
   asterisk can be styled red inline. Uses `placeholder=" "` on the input
   so `:placeholder-shown` is truthy only when the field is empty.
   On focus or when the input has content the label floats up to the top
   border of the field, shrinks, and gets a solid background that notches
   the border — same behaviour as the reference (Material-style) pattern. */
.field-placeholder {
  position: absolute;
  /* Default — label sits centered vertically where the placeholder text
     would normally be, past the left-side icon. Allowed to wrap onto a
     second line so long labels (e.g. "Referral code (optional)") aren't
     clipped at the right edge on narrow mobile widths. `nowrap` is
     re-applied below for the floated state where the label sits on top
     and a 2nd line WOULD overlap the typed text. */
  top: 50%;
  left: 48px;
  right: 14px;
  transform: translateY(-50%);
  color: var(--text-muted); font-size: 15px; font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 1.15;
  pointer-events: none;
  padding: 0;
  background: transparent;
  z-index: 2;
  white-space: normal;
  transition: top 0.15s, left 0.15s, font-size 0.15s, color 0.15s, transform 0.15s;
}
/* "(optional)" is rendered slightly smaller than the main label so the
   wrap reads as a soft hint, not a duplicate field. Hidden entirely
   when the input is focused/filled (rule below). */
.field-optional { font-weight: inherit; font-size: 0.82em; color: var(--text-muted); }
/* Hide " (optional)" once the user is actively writing or has typed
   something — keeps the floated label tight (no wrap onto a second
   line that overlaps the typed text). */
.field:focus-within .field-placeholder .field-optional,
.field input:not(:placeholder-shown) + .field-placeholder .field-optional {
  display: none;
}
.field-req { color: #ec4899; margin-left: 2px; font-weight: 700; }
/* Per-field helper text (e.g. "Minimum 8 characters" under the password
   field). Wraps the input + helper so spacing stays predictable. */
.field-wrap { display: flex; flex-direction: column; gap: 4px; }
.field-help {
  display: none;
  padding: 0 16px;
  color: #ec4899; font-size: 12px; font-weight: 500;
  letter-spacing: 0.01em;
}
.field-help.show { display: block; }
/* Red border on invalid inputs (password below 8 chars). */
.field input.invalid,
.field input.invalid:hover,
.field input.invalid:focus {
  border-color: #ec4899 !important;
  box-shadow: 0 0 0 3px rgba(236, 72, 153, 0.15) !important;
}
/* Focus / has-content: label floats UP to the top of the input (staying
   past the icon horizontally), shrinks to 12 px, and the input text area
   drops below via extra top padding. `nowrap` here keeps the floated
   label single-line — wrapping in this state would push it down into
   the typed text. */
.field:focus-within .field-placeholder,
.field input:not(:placeholder-shown) + .field-placeholder {
  top: 10px;
  /* 50 px = input border-left (2 px) + input padding-left (48 px). The
     floated label is positioned relative to .field (outer edge of the
     input), so we need the +2 px to land flush with the value text's
     first character. */
  left: 50px;
  right: auto;
  transform: none;
  font-size: 12px;
  color: var(--text);
  white-space: nowrap;
}
.field:focus-within input,
.field input:not(:placeholder-shown) {
  padding-top: 24px !important;
  padding-bottom: 8px !important;
}
.field-eye {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: none; color: var(--text-muted); cursor: pointer; padding: 0;
  border-radius: 6px; transition: 0.12s;
}
.field-eye:hover { color: var(--text); background: rgba(255, 255, 255, 0.06); }
.field-eye-icon { width: 16px; height: 16px; stroke: currentColor; }

/* Buttons */
.btn { padding: 10px 16px; background: var(--bg-card-solid); color: var(--text); border: 1px solid var(--border); border-radius: var(--r-md); font-family: inherit; font-size: 12px; font-weight: 600; cursor: pointer; transition: filter 0.12s, background 0.12s, border-color 0.12s; letter-spacing: 0.02em; }
.btn:hover { filter: brightness(1.08); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; filter: none; }
.btn-lg { padding: 14px 22px; font-size: 13px; font-weight: 700; }
.btn-sm { padding: 6px 12px; font-size: 11px; }
.btn-primary {
  color: white;
  /* Translucent glass-chip look — same palette as the auth "Log in"
     button. A red-tinted gradient at 35% alpha sits over a dark
     navy-purple plate, with backdrop-blur so the surface behind shows
     through softly. Purple accent border + no outer glow. */
  border: 1px solid var(--border);
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  box-shadow:
    0 3px 0 0 rgba(50, 3, 18, 0.55);
  /* Typeface matches the auth "WELCOME" heading — same weight + tracking
     so every primary action reads with the same strong-display feel. */
  font-weight: 800;
  letter-spacing: 0.04em;
  transition: transform 0.08s, box-shadow 0.12s, filter 0.12s;
}
.btn-primary:hover {
  filter: brightness(1.08);
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.5) 0%, rgba(122, 8, 44, 0.5) 100%),
    rgba(15, 8, 36, 0.55);
  box-shadow:
    0 3px 0 0 rgba(50, 3, 18, 0.65);
}
.btn-primary:active {
  transform: translateY(2px);
  box-shadow:
    0 1px 0 0 rgba(50, 3, 18, 0.65);
}
.btn-secondary { background: var(--blue-grad); border: none; color: white; }
.btn-ghost { background: transparent; border: 1px solid var(--border); }
.btn-danger { background: linear-gradient(180deg, #f55 0%, #c22 100%); border: none; color: white; }

/* App */
/* `.active` qualifier is required — without it the ID selector beats
   the base `.view { display: none }` cascade and the app-view stays
   visible behind the auth modal after sign-out (the "Wallet" h1 was
   leaking through). */
#app-view.active { display: flex; }
#app-view { position: relative; }
#app-view > #mobile-nav-backdrop { display: none; }
#sidebar { width: 220px; padding: 12px 12px; background: #0f0824; border-right: 1px solid var(--border); display: flex; flex-direction: column; gap: 4px; overflow-y: auto; }
.nav-set { flex-direction: column; gap: 4px; }
/* Logged-in admins see BOTH the player nav (game links) AND the admin
   nav stacked in the sidebar. Force-display the player nav past any
   inline style="display:none" left over from the markup default so the
   nav is visible without waiting on the JS startup pass. */
body.logged-in.is-admin #nav-player { display: flex !important; }

/* Admin manual-deposit-credit row — responsive grid that wraps onto
   multiple rows on narrow viewports instead of overflowing into a
   single squashed line where placeholders and dropdown arrows collide
   into each other. Each cell gets a minimum readable width. */
.admin-mcredit-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
  padding: 10px 0;
  align-items: center;
}
.admin-mcredit-row .input,
.admin-mcredit-row .select { min-width: 0; }
.nav-btn {
  display: flex; align-items: center; gap: 12px; padding: 11px 14px;
  background: rgba(15, 8, 36, 0.7);
  border: none;
  border-left: 2px solid transparent;
  border-right: 2px solid transparent;
  color: #fff;
  border-radius: 0;
  cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 700;
  text-align: left;
  transition: background 0.12s, border-color 0.12s;
  position: relative;
  box-shadow: none;
}
.nav-btn:hover {
  /* Brighter hover overlay — was rgba(15, 8, 36, 0.85) which is the same
     dark violet as the sidebar background and reads as nearly invisible.
     White-with-low-alpha gives a clear "highlighted" frame against the
     dark bg, matching the reference where the hovered row stands out as
     a noticeably lighter band. */
  background: rgba(255, 255, 255, 0.20);
  color: #fff;
  box-shadow: none;
}
.nav-btn:active {
  background: rgba(255, 255, 255, 0.26);
  transform: none;
}
.nav-btn:hover .nav-i { stroke: #fff; opacity: 1; }
.nav-btn.active {
  background: rgba(255, 255, 255, 0.20);
  color: #fff;
  border-left: 2px solid #d91554;
  border-right: 2px solid transparent;
  box-shadow: none;
}
.nav-i { width: 18px; height: 18px; flex-shrink: 0; stroke: var(--text-muted); opacity: 0.8; color: var(--text-muted); display: inline-flex; align-items: center; justify-content: center; }
.nav-i svg { width: 100%; height: 100%; display: block; }
.nav-btn:hover .nav-i, .nav-btn.active .nav-i { color: #fff; }
.nav-btn:hover .nav-i { stroke: var(--text); opacity: 1; }
.nav-btn.active .nav-i { stroke: #fff; opacity: 1; }
.nav-badge { position: absolute; right: 10px; background: var(--gold); color: #4a2c00; font-size: 10px; font-weight: 700; padding: 2px 7px; border-radius: var(--r-pill); }
.nav-badge:empty { display: none; }
.sidebar-footer { padding-top: 12px; border-top: 1px solid var(--border); }
.logout-btn { width: 100%; padding: 10px; background: transparent; border: 1px solid var(--border); border-radius: var(--r-md); color: var(--text-muted); cursor: pointer; font-family: inherit; font-size: 11px; }
.logout-btn:hover { color: var(--red); border-color: var(--red); }

#content { flex: 1; padding: 56px 32px 24px; overflow-y: auto; min-width: 0; }

/* Desktop narrowing pass removed per player request — the full-width
   layout is restored on wide viewports so the bets feed and other
   content actually fill the screen instead of sitting in a 480 px
   phone-shaped column with empty bg on the sides. */
.page { display: none; }
.page.active { display: block; animation: fadeIn 0.3s ease-out; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.page-title { font-size: 26px; font-weight: 800; margin-bottom: 18px; letter-spacing: -0.01em; }
/* Home page "GAMES" title — centered + extra top breathing room so it
   sits a tasteful distance below the topnav coin-pill instead of
   crowding directly under it. */
#page-home > .page-title {
  text-align: center;
  margin-top: 16px;
  /* Force the title to span the full content width so `text-align:
     center` actually centers it on the viewport, not on whatever
     intrinsic width the h1 would otherwise resolve to. Without this,
     the title was visually shifted to the left because the h1 was
     sizing to its text content + left page padding. */
  display: block;
  width: 100%;
  margin-left: 0;
  margin-right: 0;
}
/* The X close affordance on Wallet / Daily — only visible while those
   pages are open as a modal overlay (mirrors the Games picker close). */
.page-close {
  position: absolute; top: 12px; right: 12px;
  width: 32px; height: 32px;
  display: none; align-items: center; justify-content: center;
  background: transparent; border: 0;
  color: var(--text-muted, #9a8ecf);
  font-size: 18px; line-height: 1;
  cursor: pointer; border-radius: 50%;
  transition: background 0.12s, color 0.12s;
  z-index: 5;
}
.page-close:hover { background: rgba(255,255,255,0.06); color: var(--text); }
.page--modal-active > .page-close { display: flex; }
body.mobile .page-close { top: 10px; right: 10px; }
.page { position: relative; }
/* Translucent overlay treatment for Wallet / Daily — same glass surface
   as the Games picker. Display:block !important to win against the
   `.page` rule that sets display:none on inactive sections. */
.page--modal-active {
  display: block !important;
  position: fixed;
  top: 60px;
  left: 50%;
  transform: translateX(-50%);
  width: calc(100vw - 32px);
  max-width: 720px;
  max-height: calc(100dvh - 60px - 24px);
  overflow-y: auto;
  z-index: 9999;
  padding: 36px 20px 24px;
  background: rgba(15, 8, 36, 0.55);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--r-lg, 16px);
}
body.mobile .page--modal-active {
  top: 68px;
  left: 0; right: 0;
  width: 100%; max-width: none;
  transform: none;
  bottom: calc(60px + env(safe-area-inset-bottom, 0px));
  max-height: none;
  border-radius: 16px 16px 0 0;
  border-left: 0; border-right: 0; border-bottom: 0;
  padding: 32px 16px 16px;
  /* Glassy translucent surface to match the topnav (#titlebar) — same
     rgba(15, 8, 36, 0.35) tint + 14px backdrop-blur so the modal reads
     as part of the same chrome family as the nav above it instead of a
     separate solid card. */
  background: rgba(15, 8, 36, 0.35);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.page-title .muted { font-size: 13px; font-weight: 500; color: var(--text-muted); margin-left: 10px; }
/* Section titles + muted-text helper share the same typographic
   treatment as the left-nav menu items (.nav-btn): Open Sans
   (var(--font-ui)) inherited from body, weight 600, 13 px, no uppercase
   transform, no extra letter-spacing. Keeps every "Recent deposits",
   "No deposits yet", and similar header/empty-state line visually
   consistent with the sidebar nav. */
.section-title {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-muted);
  margin: 26px 0 12px;
}
/* Wallet-page-only treatment — section labels read as small uppercase
   tracked labels (matches the games-picker section titles), so the
   "Recent deposits" / "Your withdrawal requests" / "Recent swaps"
   headers feel like part of the polished family. Scoped to #page-wallet
   so other pages keep the calm sentence-case sub-heading look. */
#page-wallet .section-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 22px 0 10px;
}
/* Wallet tabs — clean cherry-pink underline on the active tab so the
   active state matches the primary CTA brand colour, not the same
   white the inactive labels have. Hover lifts the muted text closer
   to white so the affordance reads. */
#page-wallet .auth-tabs .tab {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.01em;
  border-bottom-width: 2px;
  padding: 14px 12px;
}
#page-wallet .auth-tabs .tab.active {
  color: #fff;
  border-bottom-color: #d91554;
}
.muted {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-muted);
}

/* ─── Skeleton loaders ─────────────────────────────────────────────────
   Soft pulsing dark-grey shapes that occupy the same vertical space as
   the real content. Beats "empty until ready" flicker for any async
   list (deposits, withdrawals, swaps history, bets feed) or any region
   that mounts after a network roundtrip (wallet-grid). Dropped in via
   the skeletonRows() / skeletonBlock() helpers in app.js right before
   awaiting the API call. The shimmer is a single moving highlight on a
   static dark plate so the cost is one transform per frame, not a
   full repaint of every shape. */
.skeleton {
  position: relative;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.04);
  border-radius: 10px;
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.06) 50%,
    rgba(255, 255, 255, 0) 100%
  );
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
}
@keyframes skeleton-shimmer {
  100% { transform: translateX(100%); }
}
.skeleton-row {
  height: 52px;
  margin-bottom: 6px;
}
.skeleton-block {
  height: 16px;
  margin-bottom: 8px;
}
.skeleton-card {
  height: 220px;
  margin-bottom: 14px;
}
/* Pause the skeleton shimmer animation when its host page isn't the
   active page. Even though inactive pages are `display: none`, several
   browsers (notably Chromium-based mobile) keep the animation timer
   running, wasting GPU cycles per frame on every off-screen skeleton.
   Same trick for any other always-running keyframe scoped to a page. */
.page:not(.active) .skeleton::after,
.page:not(.active) .skeleton-row,
.page:not(.active) .skeleton-card,
.page:not(.active) .skeleton-block {
  animation-play-state: paused;
}

/* ─── Empty states ────────────────────────────────────────────────────
   Centered icon + muted message (+ optional primary CTA) for "no data
   yet" sections. Replaces the bare one-line muted text pattern so
   empty rows read as intentional design rather than missing UI. */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 32px 16px;
  text-align: center;
}
.empty-state-icon {
  width: 32px;
  height: 32px;
  color: var(--text-muted);
  opacity: 0.55;
}
.empty-state-msg {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  max-width: 240px;
  line-height: 1.45;
}
/* Soft-lavender money-in CTA — sits inside empty-state blocks (and
   eventually any other "fund your account" spot). Distinct from the
   cherry-pink bet-action CTAs so deposit-class actions don't compete
   visually with gambling CTAs. Inverse-contrast (dark text on light
   surface) is the reference's primary-action treatment. */
.empty-state-cta,
.btn-lavender {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 22px;
  background: #a78bfa;
  color: #1a0d3e;
  border: none;
  border-radius: 999px;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: transform 0.08s, filter 0.12s, background 0.12s;
}
.empty-state-cta:hover,
.btn-lavender:hover { background: #b8a0fc; }
.empty-state-cta:active,
.btn-lavender:active { transform: translateY(1px); }
.hint, p.hint {
  font-family: var(--font-ui);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

/* Wallet (player) */
/* ─── Hero balance block at the top of the Wallet modal. Borrowed from
   the reference fintech card-app pattern: lead with the player's number,
   not the form chrome. Shows the current default coin's balance huge,
   fiat sub-row underneath, and a single primary Deposit CTA that snaps
   the user to the Deposit tab. Populated by renderWalletHero() in
   app.js — kept inline `display: none` in HTML until that function
   runs so it doesn't flash unstyled placeholder text. */
.wallet-hero {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  padding: 4px 0 18px;
}
.wallet-hero-amount-row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.wallet-hero-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.wallet-hero-icon .coin-ring { padding: 2px; }
.wallet-hero-icon .coin-icon { width: 40px; height: 40px; }
.wallet-hero-amount {
  font-family: var(--font-ui);
  font-size: clamp(36px, 9vw, 56px);
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: #fff;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wallet-hero-ticker {
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  align-self: flex-end;
  padding-bottom: 6px;
}
.wallet-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 14px; }
.wallet-card {
  background: var(--bg-card-solid) padding-box,
              linear-gradient(135deg, #ffffff 0%, #ff3d6a 50%, #ffffff 100%) border-box;
  border: 3px solid transparent;
  border-radius: var(--r-lg);
  padding: 18px;
  position: relative;
}
.wallet-card-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; flex-wrap: wrap; gap: 8px; }
.wallet-coin { font-size: 13px; font-weight: 700; letter-spacing: 0.08em; color: #fff; display: inline-flex; align-items: center; gap: 8px; }
.coin-ring { display: inline-flex; padding: 2px; border-radius: 50%; flex-shrink: 0; }
.coin-ring-btc  { background: #f7931a; }
.coin-ring-eth  { background: #627eea; }
.coin-ring-sol  { background: linear-gradient(45deg, #9945ff 0%, #14f195 100%); }
.coin-ring-ltc  { background: #345d9d; }
.coin-ring-bch  { background: #0ac18e; }
.coin-ring-doge { background: #c2a633; }
.coin-icon { width: 20px; height: 20px; display: block; border-radius: 50%; }
.wallet-balance { font-size: 24px; font-weight: 800; font-variant-numeric: tabular-nums; }
.wallet-address-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.wallet-qr { width: 84px; height: 84px; background: white; padding: 4px; border-radius: var(--r-md); flex-shrink: 0; }
.wallet-address-col { flex: 1; min-width: 0; }
.wallet-address-label { font-size: 10px; letter-spacing: 0.1em; color: var(--text-dim); text-transform: uppercase; margin-bottom: 4px; }
.wallet-address { font-size: 11px; font-family: var(--font-num); color: #fff; word-break: break-all; margin-bottom: 6px; }
.withdraw-forms { display: flex; flex-direction: column; gap: 6px; }
.withdraw-form { display: grid; grid-template-columns: 80px minmax(0, 2fr) minmax(0, 1fr) auto; gap: 8px; padding: 10px 4px; background: transparent; border: none; border-bottom: 1px solid rgba(255, 255, 255, 0.04); border-radius: 0; align-items: center; }

/* Wallet → Swap form. Two stacked rows ("You send" / "You get") with
   a flip-direction button between them; reuses .input + .coin-select +
   .dice-roll-btn looks so swap blends with deposit / withdraw panes. */
.swap-card {
  display: flex; flex-direction: column; gap: 10px;
  padding: 0; background: transparent; border: none; border-radius: 0;
  width: 100%; max-width: 520px; position: relative;
}
/* Each swap row reads as a settled card — same dark plate + soft border +
   14px corner the games-picker tile uses, so the From / To stack feels
   like part of the same visual family as the rest of the polished UI. */
.swap-row {
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px 14px;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 14px;
}
.swap-row-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 8px; flex-wrap: wrap;
  /* "You send" / "You get" labels use the same typographic treatment as
     the Deposit tab's "Currency" / "Network" labels (.withdraw-label).
     Keeps wallet sub-headings consistent across panes. */
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  text-transform: none;
  color: var(--text-muted);
}
.swap-row-head > :first-child { white-space: nowrap; flex-shrink: 0; font-weight: 700; }
.swap-row-bal {
  white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  text-align: right;
}
.swap-row-bal strong { color: #fff; font-weight: 700; font-variant-numeric: tabular-nums; }
.swap-row-body {
  display: grid; grid-template-columns: minmax(96px, max-content) 1fr auto;
  gap: 8px; align-items: center;
}
.swap-amount-field { min-width: 0; margin-bottom: 0 !important; }
.swap-amount-field input.swap-amount { background: rgba(15, 8, 36, 0.55) !important; }
/* Custom coin picker for the swap form — native <select> can't show
   the SVG glyphs the rest of the app uses for BTC/ETH/SOL, so we
   render our own pill button + popup list. */
.swap-coin-btn {
  position: relative;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 12px; min-width: 96px;
  background: rgba(15, 8, 36, 0.85);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: #fff; font: inherit; font-size: 13px; font-weight: 700;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.swap-coin-btn:hover { background: rgba(255, 255, 255, 0.10); }
.swap-coin-btn[aria-expanded="true"] { background: rgba(255, 255, 255, 0.12); }
.swap-coin-icon { display: inline-flex; align-items: center; }
.swap-coin-icon .coin-ring { padding: 1.5px; }
.swap-coin-icon .coin-icon { width: 18px; height: 18px; }
.swap-coin-name { letter-spacing: 0.02em; }
.swap-coin-chev { font-size: 10px; color: var(--text-muted); margin-left: 2px; }
.swap-row-body { position: relative; }
.swap-coin-dropdown {
  position: absolute; top: calc(100% + 4px); left: 0;
  /* Glassy surface matching the deposit / withdraw pickers — translucent
     dark plate + backdrop-filter blur so the page behind softens into
     the dropdown instead of being slammed by a solid card. */
  background: rgba(15, 8, 36, 0.35);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--r-md); padding: 4px;
  z-index: 9999; min-width: 140px;
  display: flex; flex-direction: column; gap: 2px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}
.swap-coin-option {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  /* Transparent items so the glassy dropdown surface reads as one
     uninterrupted sheet — matches the same treatment applied to the
     coin-picker / wd-picker items on mobile. Hover highlight below
     still shows on top. */
  background: transparent;
  border: none; border-radius: 8px;
  color: #fff; font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer; text-align: left;
  transition: background 0.12s;
}
.swap-coin-option:hover { background: rgba(255, 255, 255, 0.16); }
/* Rate / spread summary line below the two rows. */
.swap-rate-line {
  font-size: 11px; color: var(--text-muted); text-align: center;
  letter-spacing: 0.02em; padding: 4px 0;
}
/* History row — each persisted swap rendered under "Recent swaps".
   Two-row grid: top is "[from] → [to]" with no overflow on mobile,
   bottom row spans full width with the timestamp in muted text.
   No card pill background — flat with a faint hairline separator. */
.swap-row-history {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  grid-template-rows: auto auto;
  column-gap: 10px; row-gap: 2px;
  align-items: center;
  padding: 10px 0;
  background: transparent;
  border: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.swap-row-history:last-child { border-bottom: none; }
.swap-row-from, .swap-row-to {
  display: inline-flex; align-items: center; gap: 6px;
  min-width: 0;
}
.swap-row-to { justify-content: flex-end; }
.swap-row-amt {
  font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0;
}
.swap-row-arrow {
  color: var(--text-muted); font-weight: 700;
  padding: 0 2px;
}
.swap-row-when {
  grid-column: 1 / -1;
  font-size: 10px; color: var(--text-muted);
  letter-spacing: 0.04em;
}
.swap-row-pair {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.swap-row-arrow { color: var(--text-muted); margin: 0 2px; }
.swap-amount {
  font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums;
  text-align: left;
}
.swap-max {
  padding: 8px 14px;
  background: rgba(15, 8, 36, 0.7);
  border: 2px solid #d91554;
  border-radius: var(--r-pill);
  color: #fff;
  font-weight: 700; font-size: 12px; letter-spacing: 0;
  cursor: pointer; transition: background 0.12s;
}
.swap-max:hover { background: rgba(15, 8, 36, 0.85); }
.swap-max:active { background: rgba(15, 8, 36, 0.95); transform: none; }
.swap-flip {
  align-self: center;
  width: 36px; height: 36px; border-radius: 50%;
  background: rgba(15, 8, 36, 0.85); border: 1px solid var(--border);
  color: #fff; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  margin: -10px 0; z-index: 1;
  transition: background 0.12s;
}
.swap-flip:hover { background: rgba(255, 255, 255, 0.16); }
.swap-flip svg { width: 18px; height: 18px; }
.swap-card .dice-roll-btn { margin-top: 8px; }

/* Single withdraw form — uses the titlebar coin-pill's active coin.
   No card pill background; the inputs inside provide their own dark
   surface, keeping the form flat with the rest of the wallet pane. */
.withdraw-single {
  display: flex; flex-direction: column; gap: 14px;
  padding: 0; background: transparent; border: none; border-radius: 0;
  width: 100%;
}

/* Wallet top row — Deposit (left) + Withdraw (right) side-by-side on desktop. */
.wallet-top-row {
  display: flex; gap: 20px; align-items: stretch;
  margin-bottom: 16px;
}
.wallet-top-col { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.wallet-top-col .section-title { margin-top: 0; }
body.mobile .wallet-top-row { flex-direction: column; gap: 12px; }
.deposit-card { margin-bottom: 14px; }
/* Address row aligns flush with the Currency / Network pair above —
   no extra left/right inset, wider gap than .deposit-pair so the Copy
   button reads as pulled further right from the address pill. The
   address pill flex-grows; Copy sits at the right column position with
   its right edge matching the Network button's right edge above. */
.deposit-address-row { display: flex; gap: 16px; align-items: stretch; padding: 0; }
.deposit-address-col { flex: 1; min-width: 0; display: flex; flex-direction: row; align-items: center; gap: 6px; }
.deposit-address-text {
  flex: 1; min-width: 0;
  font-family: var(--font-num); font-size: 9px; color: #fff;
  letter-spacing: 0;
  /* Full address visible at all times — wraps onto a second line at any
     character boundary so no part of the hex string ever gets hidden. */
  white-space: normal;
  word-break: break-all;
  overflow: hidden;
  padding: 12px 14px;
  background: rgba(15, 8, 36, 0.55);
  border: 2px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--r-md);
  text-align: center;
  line-height: 1.45;
}
/* Deposit "Copy" button mirrors the .btn-primary CTA look (PLACE BET /
   "+ Add custom code") — red-pink rim over translucent navy gradient,
   same backdrop blur. */
.deposit-copy {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 16px;
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid #d91554;
  border-radius: var(--r-md);
  color: #fff;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  cursor: pointer;
  box-shadow: 0 3px 0 0 rgba(50, 3, 18, 0.55);
  transition: transform 0.08s, filter 0.12s;
}
.deposit-copy:hover  { filter: brightness(1.08); }
.deposit-copy:active { transform: translateY(2px); box-shadow: 0 1px 0 0 rgba(50, 3, 18, 0.55); }
.deposit-copy:focus-visible { outline: none; }

/* Deposit extra hints — fiat rate + min deposit. Same surface treatment
   as the mobile "Deposit coin · tap to change" pill (.wd-pill, see the
   `body.mobile .wd-pill` override that flattens the desktop gradient
   to a solid #1a0f3d) so the deposit card reads as one consistent
   visual block on every device. */
.deposit-rate-hint {
  padding: 14px 16px;
  background: #1a0f3d;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  font-size: 13px; font-weight: 700; color: #fff;
  font-variant-numeric: tabular-nums; text-align: center;
  letter-spacing: 0.02em;
}
.deposit-rate-hint strong { color: #fff; font-weight: 800; }
/* Pulsing "Watching for incoming TX…" line below the deposit address.
   Reassures the player that the system is actively listening for their
   send — a high-conversion micro-cue picked up from market-leader
   crypto-casinos. */
.deposit-watching {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; margin-top: 8px;
  font-size: 12px; color: var(--text-muted);
  font-weight: 600; letter-spacing: 0.02em;
}
.deposit-watching-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--green);
}
.fiat-picker {
  margin-left: 8px; padding: 4px 8px; background: rgba(255, 255, 255, 0.08);
  color: #fff; border: 1px solid var(--border); border-radius: 999px;
  font: inherit; font-size: 11px; font-weight: 700; letter-spacing: 0.05em;
  cursor: pointer; outline: none;
}
.fiat-picker:focus { border-color: var(--border); }
.fiat-picker option { background: var(--bg-card-solid); color: #fff; }

/* Titlebar fiat picker (compact pill + dropdown) */
.tb-fiat-wrap { position: relative; -webkit-app-region: no-drag; margin-right: 6px; }
.tb-fiat-wrap.hidden { display: none; }
/* Top-bar fiat selector — settled dark plate matching the games-picker
   tile family. Was a 2 px transparent border filled with a white→purple→white
   gradient (chrome rim), which read as the brightest element in the top bar
   and pulled the eye away from the balance + coin pill it sits next to. */
.tb-fiat-btn {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 6px 10px; font: inherit;
  font-family: var(--font-ui);
  font-size: 11px; font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: #fff; cursor: pointer;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: var(--r-pill);
  transition: border-color 0.12s, background 0.12s;
}
.tb-fiat-btn:hover { border-color: rgba(217, 21, 84, 0.4); }
.tb-fiat-btn:hover { filter: brightness(1.15); }
.tb-fiat-chev { font-size: 9px; color: var(--text-muted); }
.tb-fiat-btn[aria-expanded="true"] .tb-fiat-chev { transform: rotate(180deg); }
.tb-fiat-picker {
  position: absolute; top: calc(100% + 6px); right: 0; min-width: 220px;
  background: var(--bg-card-solid); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 4px; z-index: 9999;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  max-height: 360px; overflow-y: auto;
}
.tb-fiat-item {
  display: grid; grid-template-columns: 28px 44px 1fr; align-items: center;
  gap: 6px; width: 100%;
  padding: 10px 12px; background: transparent; border: none; cursor: pointer;
  color: var(--text); font: inherit; font-size: 13px; font-weight: 600;
  border-radius: 6px; text-align: left;
}
.tb-fiat-item:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }
.tb-fiat-item.active { background: rgba(255, 255, 255, 0.12); color: #fff; }
.tb-fiat-sym { color: #fff; font-weight: 800; font-size: 14px; }
.tb-fiat-code { color: #fff; font-weight: 800; letter-spacing: 0.06em; }
.tb-fiat-name { color: var(--text-muted); font-size: 12px; font-weight: 500; }
body.mobile .tb-fiat-btn { padding: 6px 8px; font-size: 10px; }
body.mobile .tb-fiat-picker { right: 8px; left: auto; min-width: 200px; }
.deposit-meta { display: flex; flex-direction: column; gap: 6px; padding-top: 0; margin-top: -2px; }
/* Two-column rows ("Min deposit … 0.0001 BTC", "Estimated arrival … ~10–30 min")
   align label-on-left / value-on-right inside the deposit card so the
   metadata reads like a settled key-value list rather than a wrapped sentence. */
.deposit-meta-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px;
  padding-left: 22px;
  font-family: var(--font-ui);
  font-size: 13px; font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.deposit-meta-row .deposit-meta-label { color: var(--text-muted); font-weight: 500; }
.deposit-meta-row .deposit-meta-val   { color: #fff; font-weight: 700; text-align: right; }
/* Legacy single-line variant kept for any older render path. */
.deposit-min-line {
  padding-left: 22px;
  font-family: var(--font-ui);
  font-size: 13px; font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}
.deposit-min-line strong { color: #fff; font-weight: 700; }
.deposit-send-pill {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 0;
  font-family: var(--font-ui);
  font-size: 13px; font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text-muted);
}
.deposit-send-pill i { color: #fff; flex-shrink: 0; }
.deposit-send-pill strong { color: #fff; font-weight: 700; }
.wallet-qr-btn { padding: 0; background: transparent; border: none; cursor: pointer; display: block; border-radius: var(--r-md); }
.wallet-qr-btn:hover .wallet-qr { transform: scale(1.03); }
.wallet-qr-btn .wallet-qr { transition: transform 0.12s; }
.deposit-address-text[role="button"] { cursor: pointer; transition: color 0.12s; }
.deposit-address-text[role="button"]:hover { color: #fff; }

/* Mines — bomb slider + big next-multiplier display */
.mines-bomb-row { padding: 10px 14px; background: rgba(36, 21, 71, 0.6); border: 1px solid var(--border); border-radius: 12px; }
.mines-bomb-label { display: flex; flex-direction: column; gap: 8px; font-size: 12px; color: var(--text-muted); cursor: pointer; }
.mines-bomb-label strong { color: #fff; font-size: 16px; font-variant-numeric: tabular-nums; margin-right: 2px; }
/* Bomb-count slider mirrors `.dice-target-slider` so it matches the dice
   look (rounded pill grey track + 22 px white thumb with subtle ring). */
.mines-bomb-slider {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 10px;
  /* Two-tone fill — green from 0 to the current bomb position, grey for
     the remainder. `--mines-fill` is set in JS each time the slider moves. */
  background: linear-gradient(to right,
    #22c55e 0%, #22c55e var(--mines-fill, 8%),
    rgba(255,255,255,0.12) var(--mines-fill, 8%),
    rgba(255,255,255,0.12) 100%);
  border-radius: 999px;
  outline: none;
}
.mines-bomb-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 22px; height: 22px; border-radius: 50%;
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.25);
  cursor: pointer;
}
.mines-bomb-slider::-moz-range-thumb {
  width: 22px; height: 22px; border-radius: 50%;
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.25);
  cursor: pointer;
}
.mines-next-mult-display {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 18px; background: rgba(255, 255, 255, 0.07);
  border: 1px solid var(--border); border-radius: 12px;
}
.mines-next-label { font-size: 11px; color: var(--text-muted); letter-spacing: 0.08em; text-transform: uppercase; font-weight: 700; }
#mines-next-mult-big { color: #fff; font-size: 28px; font-weight: 900; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }

/* Blackjack — larger hand total */
.bj-total { font-size: 18px !important; background: rgba(255, 184, 0, 0.15); color: #fff !important; padding: 2px 10px; border-radius: 999px; margin-left: 8px; }

/* Lucky button */
.lucky-btn {
  background: linear-gradient(180deg, rgba(34, 197, 94, 0.2), rgba(22, 163, 74, 0.25)) !important;
  border-color: rgba(34, 197, 94, 0.5) !important;
  color: #86efac !important;
}
.lucky-btn:hover { background: linear-gradient(180deg, rgba(34, 197, 94, 0.35), rgba(22, 163, 74, 0.4)) !important; color: #fff !important; }
body.mobile .deposit-address-row { flex-direction: column; align-items: stretch; }
body.mobile .deposit-address-row .wallet-qr-btn { align-self: center; }
/* Withdraw pill + dropdown (mirrors titlebar coin-pill/picker pattern) */
.wd-coin-field { margin-bottom: 4px; }
.wd-pill-wrap { position: relative; }
.deposit-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 4px;
}
.deposit-pair .withdraw-field { margin-bottom: 0; min-width: 0; }
.deposit-pair .wd-pill { padding: 12px 14px; gap: 10px; }
.deposit-pair .wd-pill-name { font-size: 13px; font-weight: 600; letter-spacing: -0.01em; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wd-pill-static { cursor: default !important; }
.wd-pill-static:hover, .wd-pill-static:active { transform: none !important; }
.wd-pill {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 14px 16px; color: white;
  /* 1 px @ 6% alpha — matches the games-picker tile border. The previous
     2 px @ 8% read as a bright outline on the dark navy plate. */
  border: 1px solid rgba(255, 255, 255, 0.06); border-radius: var(--r-md);
  background: rgba(15, 8, 36, 0.55);
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  text-transform: none;
  transition: transform 0.08s, border-color 0.12s, background 0.12s;
}
.wd-pill:active {
  transform: translateY(2px);
}
.wd-pill-icon { display: inline-flex; }
.wd-pill-icon .coin-ring { padding: 1.5px; }
.wd-pill-icon .coin-icon { width: 20px; height: 20px; }
.wd-pill-name { letter-spacing: 0; font-size: 13px; font-weight: 600; text-transform: none; }
.wd-pill-bal { margin-left: auto; color: #fff; font-weight: 800; font-size: 13px; }
.wd-pill-chev {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%;
  background: rgba(255, 255, 255, 0.18); color: #fff;
  transition: transform 0.2s, background 0.15s;
}
.wd-pill:hover .wd-pill-chev { background: rgba(255, 255, 255, 0.28); }
.wd-pill[aria-expanded="true"] .wd-pill-chev { transform: rotate(180deg); }

.wd-picker {
  position: absolute; top: calc(100% + 4px); left: 0;
  /* Expand the dropdown wider than its anchor pill so full coin tickers
     (DOGE, USDC, etc.) and balance numbers fit on a single row, and so
     the "Hide 0 balances" toggle label doesn't wrap onto two lines.
     The pill itself stays half-width inside .deposit-pair; the dropdown
     just escapes to a sensible reading width. */
  min-width: 320px;
  background: rgba(15, 8, 36, 0.35);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--r-md);
  /* Padding moved to inner sections so the footer toggle band can reach
     the picker edges flush, like a settled modal footer. */
  padding: 0;
  z-index: 9999;
  overflow: hidden;
}
/* Inside the wd-picker dropdown, let the full coin ticker render — even
   with the dropdown's new min-width, the tight .coin-picker-name letter-
   spacing was clipping "DOGE" to "DO…" on the deposit picker. Killing
   the ellipsis and reducing tracking lets short coin codes breathe. */
.wd-picker .coin-picker-name {
  letter-spacing: 0;
  overflow: visible;
  text-overflow: clip;
}
.wd-picker .cp-row-label { white-space: nowrap; }
/* Modal-feel layout for the deposit picker — bigger search field, taller
   coin rows, full-width footer band for the toggle. Matches the
   reading rhythm of a settled wallet modal rather than a tiny tucked-in
   dropdown. Scoped to .wd-picker so the top-nav coin-picker is
   unchanged. */
.wd-picker .coin-picker-head { padding: 14px 16px 8px; }
.wd-picker .coin-picker-search-wrap { padding: 4px 12px 8px; }
.wd-picker .coin-picker-search { height: 44px; padding-left: 38px; font-size: 14px; }
.wd-picker .coin-picker-search-icon { left: 14px; }
.wd-picker .coin-picker-list { padding: 0 4px; gap: 0; }
.wd-picker .coin-picker-item { padding: 12px 14px; font-size: 14px; border-radius: 8px; }
.wd-picker .coin-picker-footer {
  margin-top: 4px;
  padding: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.wd-picker .coin-picker-footer .cp-row {
  padding: 14px 16px;
  border-radius: 0;
}
/* On mobile the deposit picker is detached to document.body on open
   (see openDepositPicker in app.js) so its `position: fixed` rules
   anchor to the viewport, not a transformed ancestor. With that JS
   change in place, these CSS rules can safely escape the wallet pane
   and cover the area between the top nav and bottom nav as a settled
   fullscreen modal. */
body.mobile .wd-picker {
  position: fixed !important;
  /* Pin between the top nav (#titlebar, height ~57 px on mobile) and
     the bottom nav (#mobile-tabbar, height ~60 px). The navs stay
     interactable thanks to their higher z-index. The bottom uses the
     same safe-area-inset clearance as body.mobile .coin-picker so the
     "Hide 0 balances" footer row sits fully above the nav on devices
     with a home-indicator gutter (previously bottom: 60px tucked it
     under the nav by env(safe-area-inset-bottom)). */
  top: 68px !important;
  left: 0 !important;
  right: 0 !important;
  /* Anchor the picker's bottom edge to the bottom nav's top edge so
     the sheet visually merges with the nav chrome — no gap that would
     let the page underneath (wallet form / recent deposits / etc.)
     show through. (100vh - --tg-vh) keeps the bottom edge aligned with
     the nav in Telegram WebApp where --tg-vh < 100vh. */
  bottom: calc(60px + env(safe-area-inset-bottom, 0px) + 100vh - var(--tg-vh, 100vh)) !important;
  max-width: none;
  min-width: 0 !important;
  width: auto !important;
  max-height: none !important;
  /* Flat top edge so the picker merges flush with the titlebar — mirrors
     the same treatment now applied to body.mobile .coin-picker. */
  border-radius: 0 !important;
  border: none !important;
  padding: 0 !important;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
/* Dim backdrop covers the visible page content behind the modal so
   the player's eye lands on the picker, not the half-revealed deposit
   form. Sits inside the fixed sheet so it inherits its viewport
   coverage automatically. Matches the coin-picker scrim 1:1 — same
   alpha (0.2) and same bottom clearance so the bottom nav stays
   un-dimmed and the picker reads identically to the top-nav picker. */
body.mobile .wd-picker::before {
  content: "";
  position: fixed;
  top: 0; left: 0; right: 0;
  /* Bottom tracks the actual nav top in tg-mode via the (100vh - --tg-vh)
     term so the scrim doesn't extend under the nav chrome. */
  bottom: calc(60px + env(safe-area-inset-bottom, 0px) + 100vh - var(--tg-vh, 100vh));
  background: rgba(0, 0, 0, 0.2);
  z-index: -1;
}
body.mobile .wd-picker .coin-picker-head {
  padding: 16px 18px 10px;
}
body.mobile .wd-picker .coin-picker-title { font-size: 17px; }
body.mobile .wd-picker .coin-picker-search-wrap {
  padding: 6px 14px 10px;
}
body.mobile .wd-picker .coin-picker-search {
  height: 48px;
  font-size: 15px;
}
body.mobile .wd-picker .coin-picker-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  max-height: none !important;
  padding: 0 8px;
}
body.mobile .wd-picker .coin-picker-item {
  padding: 14px 16px;
  font-size: 15px;
}
.withdraw-coin-tab {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: 10px 12px; background: var(--bg-input); color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--r-md);
  cursor: pointer; font: inherit; text-align: left;
  transition: 0.12s; font-variant-numeric: tabular-nums;
}
.withdraw-coin-tab:hover { border-color: var(--border); color: var(--text); }
.withdraw-coin-tab.active {
  border-color: var(--border); color: #fff;
  background: rgba(255, 184, 0, 0.08);
}
.withdraw-coin-tab-icon { display: inline-flex; }
.withdraw-coin-tab-icon .coin-ring { padding: 1px; }
.withdraw-coin-tab-icon .coin-icon { width: 14px; height: 14px; }
.withdraw-coin-tab-name { font-size: 11px; font-weight: 800; letter-spacing: 0.08em; display: inline-flex; align-items: center; gap: 6px; }
.withdraw-coin-tab-name::before { content: ""; }
.withdraw-coin-tab .withdraw-coin-tab-icon + .withdraw-coin-tab-name { margin-top: -18px; padding-left: 22px; }
.withdraw-coin-tab-bal { font-size: 12px; font-weight: 700; color: #fff; }

.withdraw-field { display: flex; flex-direction: column; gap: 6px; }
.withdraw-label {
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  text-transform: none;
  color: var(--text-muted);
}
.withdraw-single .input { padding: 12px 14px; font-size: 14px; width: 100%; }
/* Unified wallet-input look: every <input> in the wallet (deposit copy
   field, withdraw forms, swap rows) wears the same dark surface as the
   coin-picker rows — `rgba(15, 8, 36, 0.55)`. Border-color is the only
   focus signal; no glow, no background switch. */
#page-wallet .input,
#page-wallet input.input,
#page-wallet .swap-amount {
  background: rgba(15, 8, 36, 0.55) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--r-md) !important;
  box-shadow: none !important;
}
#page-wallet .input:hover,
#page-wallet input.input:hover,
#page-wallet .swap-amount:hover {
  background: rgba(15, 8, 36, 0.55) !important;
  border-color: var(--border-strong) !important;
}
#page-wallet .input:focus,
#page-wallet input.input:focus,
#page-wallet .swap-amount:focus {
  background: rgba(15, 8, 36, 0.55) !important;
  border-color: var(--border-strong) !important;
  box-shadow: none !important;
  outline: none !important;
}
/* Read-only "You get" input — same surface as the editable side so
   the two rows visually match instead of one looking transparent. */
#page-wallet .swap-amount[readonly] { cursor: default; }
.withdraw-input-row { display: flex; gap: 6px; align-items: stretch; }
.withdraw-input-row .input { flex: 1; min-width: 0; }
.withdraw-input-row .field { flex: 1; min-width: 0; }
.withdraw-field-floating { margin-bottom: 4px; }
.field.field-no-icon input { padding-left: 18px !important; padding-right: 18px !important; }
.field.field-no-icon .field-placeholder { left: 18px; }
.field.field-no-icon:focus-within .field-placeholder,
.field.field-no-icon input:not(:placeholder-shown) + .field-placeholder { left: 18px; }
/* Withdraw MAX + Request Withdrawal buttons inherit the standard
   .btn-primary treatment — no custom heavy font / shadow. */
.withdraw-max {
  padding: 16px 22px;
  border-radius: 14px !important;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  align-self: stretch;
  flex-shrink: 0;
}
.withdraw-submit { width: 100%; }
/* Match the typography of the "Your withdrawal requests" .section-title
   above so both reads as the same font family / weight / case.
   Background follows the canonical primary CTA pink (#d91554) — same
   as PLACE BET / login ready — so every "submit this action" button
   in the app reads identically. */
.withdraw-submit,
body.mobile .withdraw-submit,
body.mobile #page-wallet .withdraw-submit {
  font-family: var(--font-ui) !important;
  font-size: 13px !important;
  font-weight: 700 !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid #d91554 !important;
  border-radius: var(--r-pill) !important;
  color: #fff !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  filter: none !important;
}
.withdraw-submit:hover,
body.mobile .withdraw-submit:hover,
body.mobile #page-wallet .withdraw-submit:hover {
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid #d91554 !important;
  filter: none !important;
}
.withdraw-submit:active,
body.mobile .withdraw-submit:active,
body.mobile #page-wallet .withdraw-submit:active {
  background: rgba(15, 8, 36, 0.85) !important;
  border: 2px solid #d91554 !important;
  transform: none !important;
}
.withdraw-submit:disabled,
body.mobile .withdraw-submit:disabled,
body.mobile #page-wallet .withdraw-submit:disabled {
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid rgba(217, 21, 84, 0.5) !important;
  color: rgba(255, 255, 255, 0.55) !important;
  cursor: not-allowed !important;
  opacity: 1 !important;
  filter: none !important;
}

body.mobile .withdraw-coin-tabs { grid-auto-flow: row; grid-auto-columns: auto; grid-template-columns: repeat(3, 1fr); }
@media (max-width: 720px) {
  .withdraw-form { grid-template-columns: 1fr; }
}
.wf-coin { font-weight: 700; color: #fff; letter-spacing: 0.08em; font-size: 13px; display: inline-flex; align-items: center; gap: 8px; }

/* Stats */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
/* Stat cards (affiliate "Current tier" / "Referred users" / "Total wagered")
   — settled dark plate with a soft 1 px border, matching the games-picker
   tile family. The previous border-image gradient outline (white→pink→white)
   read as decorative chrome and made every stat compete with the others. */
.stat-card {
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 14px;
  padding: 18px 18px 16px;
  position: relative;
}
.stat-card.blue::before { background: var(--blue-grad); }
.stat-card.gold::before { background: linear-gradient(90deg, #ffb800, #ff9500); }
.stat-card.green::before { background: linear-gradient(90deg, #22c55e, #16a34a); }
.stat-label {
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 8px;
}
.stat-value {
  font-family: var(--font-ui);
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: #fff;
}
.stat-sub {
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.62);
  letter-spacing: 0;
  margin-top: 6px;
}

/* Inputs */
.input, .select { width: 100%; padding: 10px 12px; background: var(--bg-input); border: 1px solid var(--border); color: var(--text); border-radius: var(--r-md); font-family: inherit; font-size: 13px; transition: 0.15s; }
/* Bet-amount fields across every game (dice, coinflip, roulette, slots,
   crash, plinko, mines, blackjack). Sportsbook-ticket look: black plate,
   thin light-grey border, white centered numerals, no spinner arrows.
   Width is auto-clipped at the parent's available room — the explicit
   60 px is just the minimum from the reference photo. */
.bet-amount {
  outline: none;
  /* Settled dark plate with a soft 1 px border, matching the games-picker
     tile + .wd-pill family. The previous pure-#000 background + light-grey
     #c2c2c2 1 px border + 3 px corner read as a generic raw <input>, not
     part of the casino's polished UI. */
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 10px;
  color: #fff;
  text-align: center;
  min-width: 60px;
  padding: 10px 12px;
  appearance: textfield;
  -moz-appearance: textfield;
  transition: border-color 0.12s, background 0.12s;
}
.bet-amount:focus {
  border-color: rgba(217, 21, 84, 0.55);
  background: rgba(15, 8, 36, 0.55);
}
.bet-amount::-webkit-outer-spin-button,
.bet-amount::-webkit-inner-spin-button {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
}
.bet-amount:focus {
  background: #000;
  border-color: #c2c2c2;
  box-shadow: none;
}
/* Centre the typed amount in every game's bet-amount field — sportsbook
   ticket look (matches .bet-amount). Uses tabular numerals so digits
   align as the user types. */
#dice-amount, #cf-amount, #c-amount, #s-amount,
#plinko-amount, #mines-amount, #bj-amount, #r-amount {
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.input:hover, .select:hover { border-color: var(--border); background: rgba(255, 255, 255, 0.06); }
.input:focus, .select:focus { outline: none; border-color: var(--border); background: var(--bg-input); box-shadow: none; }
.input-sm { padding: 6px 8px; font-size: 11px; width: 90px; }
.select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='%239c8fc6'%3E%3Cpath d='M6 8L0 0h12z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; padding-right: 32px; }

/* Filter bar */
.filter-bar { display: flex; gap: 4px; padding: 4px; background: var(--bg-input); border-radius: var(--r-md); margin-bottom: 12px; width: fit-content; }
.filter { padding: 8px 14px; background: transparent; border: none; color: var(--text-muted); cursor: pointer; font-family: inherit; font-size: 11px; font-weight: 600; border-radius: var(--r-sm); letter-spacing: 0.06em; text-transform: uppercase; }
.filter.active { background: var(--blue-grad); color: white; }

/* Tables — flat rows separated by a faint hairline. The legacy
   "card pill" treatment (var(--bg-card) + 1px border + radius on
   every row) was retired per project rule: list rows must not look
   like floating pills. Existing per-shape grid-template-columns
   variants below are unaffected. */
.table-list { display: flex; flex-direction: column; gap: 0; }
.table-row {
  display: grid; gap: 10px; padding: 10px 4px;
  background: transparent; border: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 0; font-size: 12px; align-items: center;
  font-weight: 700;
}
.table-list > .table-row:last-child { border-bottom: none; }
.table-row.withdraw { grid-template-columns: 40px 160px 80px 1fr 100px 120px 140px; }
.table-row.withdraw-mine,
.table-row.history-mine {
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
  align-items: center;
  padding: 14px 4px;
}
.table-row.withdraw-mine,
.table-row.deposit-mine,
.table-row.history-mine {
  font-family: var(--font-ui);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.table-row.withdraw-mine .status-badge,
.table-row.deposit-mine .status-badge,
.table-row.history-mine .status-badge {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-transform: none;
  font-variant-numeric: tabular-nums;
}
.table-row.withdraw-mine .muted,
.table-row.deposit-mine .muted,
.table-row.history-mine .muted {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.wd-mine-header {
  /* Compact font + tracked uppercase so all five header words ("DATE, TIME",
     "TYPE", "AMOUNT", "STATUS", "INFO") fit on a single line across the full
     phone width. Slightly wider tracking than the data rows so the header
     reads as a label band, not as a normal row that happens to be small. */
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  padding: 10px 12px;
}
/* Wallet history tables (deposits + withdrawals) reach past the page
   gutter so each column gets a few extra pixels — mirrors the bets-feed
   panel treatment. */
body.mobile #deposits-list,
body.mobile #withdrawals-list,
body.mobile .wd-mine-header {
  margin-left: -10px;
  margin-right: -10px;
}
/* Header cells may wrap at whitespace ("DATE, TIME" → "DATE," / "TIME")
   but never inside a word — `keep-all` stops "AMOUNT" from breaking into
   "AMOU NT" on narrow phone columns. Each cell is centred so columns line
   up cleanly above the data rows below. Specificity must beat the later
   `body.mobile .table-row > span` rule, so `.table-row` is included. */
body.mobile .table-row.wd-mine-header > span,
.wd-mine-header > span {
  white-space: normal;
  overflow-wrap: normal;
  word-break: keep-all;
  hyphens: none;
  line-height: 1.1;
  text-align: center;
}
/* Centre the wallet's deposit / withdraw section titles + the "No deposits
   yet" / "No requests yet" empty-state line. */
.wallet-pane .section-title { text-align: center; }
#deposits-list > .muted,
#withdrawals-list > .muted { text-align: center; }
.wd-date-time { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.wd-date-time .wd-date { font-size: 12px; font-weight: 700; color: #fff; }
.wd-date-time .wd-time { font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.wd-type { font-size: 13px; font-weight: 700; color: #fff; }
.wd-amount-cell { display: inline-flex; align-items: center; gap: 6px; min-width: 0; white-space: nowrap; }
/* History rows include a leading "-" on the bet amount which optically
   sits flush against the coin icon. A slightly wider gap restores the
   same visual spacing as the deposit / withdraw rows. */
.table-row.history-mine .wd-amount-cell { gap: 10px; }
.wd-amount-cell .coin-tag-iconed { padding: 0; }
.wd-amount-cell .coin-icon { width: 18px; height: 18px; }
.wd-amount-value { font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; font-size: 13px; white-space: nowrap; word-break: normal; overflow: hidden; text-overflow: ellipsis; }
body.mobile .wd-amount-cell .coin-icon { width: 14px; height: 14px; }
body.mobile .wd-amount-value { font-size: 11px; }
.wd-info-cell { display: inline-flex; align-items: center; min-width: 0; }
.wd-info-cell .mono {
  font-family: var(--font-ui);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
body.mobile .table-row.withdraw-mine {
  display: grid; flex-direction: row;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
  align-items: center;
  gap: 6px; padding: 12px 4px;
}
.table-row.deposit { grid-template-columns: 40px 160px 80px 1fr 80px 130px; }
.table-row.deposit-mine {
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
  align-items: center;
  padding: 14px 4px;
}
body.mobile .table-row.deposit-mine,
body.mobile .table-row.history-mine {
  display: grid; flex-direction: row;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
  align-items: center;
  gap: 6px; padding: 12px 4px;
}
/* Revealed-seeds table — same horizontal-row layout as deposit/withdraw
   history. 4 columns: Date·Time | Type | Server seed | Final nonce. */
body.mobile .table-row.revealed-row {
  display: grid; flex-direction: row;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  align-items: center;
  gap: 6px; padding: 12px 4px;
}
.table-row.user { grid-template-columns: 40px 1.2fr 80px 80px 1fr 130px; }
.table-row.history-row { grid-template-columns: 90px 60px 90px 1fr 100px 130px; }
.table-row.revealed-row {
  grid-template-columns: 1fr 1fr 1fr 1fr;
  align-items: center;
  padding: 14px 4px;
  font-family: var(--font-ui);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.table-row.revealed-row .muted {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.table-row.revealed-row .mono {
  font-family: var(--font-num);
  font-size: 11px;
  color: var(--blue);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.table-row.audit-row { grid-template-columns: 130px 1fr 1fr 1fr 100px; }
.table-row.limit-row { grid-template-columns: 80px 60px 1.2fr 1.2fr auto; }
.table-row .actions { justify-self: end; display: flex; gap: 6px; }
.coin-tag { font-weight: 700; color: #fff; letter-spacing: 0.08em; font-size: 11px; }
.coin-tag-iconed {
  display: inline-flex; align-items: center; gap: 6px;
  letter-spacing: 0;
  font-size: 12px;
  font-weight: 700;
}
.coin-tag-iconed .coin-ring { padding: 1.5px; flex-shrink: 0; }
.coin-tag-iconed .coin-icon { width: 16px; height: 16px; }
.coin-tag-iconed .coin-tag-name { font-variant-numeric: tabular-nums; }
.history-coin { color: #ffffff; }
.amount-pos { color: var(--green); font-weight: 700; font-variant-numeric: tabular-nums; }
.amount-neg { color: var(--red); font-weight: 700; font-variant-numeric: tabular-nums; }
.mono { font-family: var(--font-num); color: var(--blue); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.status-badge { font-size: 9px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; justify-self: start; }
.status-pending, .status-submitted, .status-none { color: #fff; }
.status-approved { color: var(--blue); }
.status-broadcasted, .status-confirmed, .status-credited { color: var(--green); }
.status-rejected, .status-failed { color: var(--red); }
.role-admin { background: rgba(255, 184, 0, 0.15); color: #fff; }
.role-player { background: rgba(167, 139, 250, 0.15); color: #c4b5fd; }

/* Games */
.game-layout { display: flex; flex-direction: column; gap: 18px; width: 100%; max-width: 680px; margin: 0 auto; }

/* Placebet frame removed by user request — game stages no longer carry the
   shared pink border. */

.game-display { background: var(--bg-card-solid); border-radius: 24px; padding: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 272px; flex-shrink: 0; position: relative; overflow: hidden; }
/* Decorative violet radial overlay removed — it bled through every 3D scene
   that mounts inside .game-display (coinflip, slots, roulette, …) and made
   the felt look "broken" at the corners. */
.big-result {
  font-size: clamp(96px, 14vw, 160px);
  font-weight: 900;
  letter-spacing: -0.04em;
  background: var(--primary-grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  /* 2 px white outline around the digit on every game's big-result
     (dice / coinflip / roulette). paint-order: stroke fill puts the
     stroke beneath the fill so only the outer half is visible — the
     gradient / colour stays inside, white traces the silhouette. */
  -webkit-text-stroke: 2px #fff;
  paint-order: stroke fill;
}
.big-result.win { background: linear-gradient(180deg, #22c55e 0%, #16a34a 100%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.big-result.lose { background: linear-gradient(180deg, #ef4444 0%, #b91c1c 100%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.big-result-label { font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #fff; margin-top: 12px; text-align: center; transition: color 0.2s; }
.game-controls { display: flex; flex-direction: column; gap: 10px; }
.ctrl-row { display: flex; flex-direction: column; gap: 6px; }
.ctrl-row label { font-size: 10px; font-weight: 600; letter-spacing: 0.1em; color: var(--text-muted); text-transform: uppercase; }
.ctrl-stats { flex-direction: row; gap: 16px; padding: 10px 14px; background: var(--bg-input); border-radius: var(--r-md); }
.ctrl-stats > div { display: flex; flex-direction: column; }
.ctrl-stats strong { font-size: 15px; color: #fff; }
.segmented { display: flex; gap: 6px; border-bottom: 1px solid var(--border); }
.seg { flex: 1; padding: 12px 10px; background: transparent; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; color: var(--text-muted); cursor: pointer; font-family: inherit; font-size: 12px; font-weight: 700; letter-spacing: 0.1em; transition: 0.15s; }
.seg:hover { color: var(--text); }
.seg.active { color: var(--text); border-bottom-color: var(--text); }
.slider { -webkit-appearance: none; appearance: none; width: 100%; height: 6px; background: var(--bg-input); border-radius: var(--r-pill); outline: none; }
.slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 18px; height: 18px; background: var(--primary-grad); border-radius: 50%; cursor: pointer; box-shadow: var(--primary-glow); }

/* Coin flip */
.coin { width: 200px; height: 200px; border-radius: 50%; background: radial-gradient(circle at 30% 30%, #ffd93d, #ff9500 60%, #cc7700); display: flex; align-items: center; justify-content: center; font-size: 96px; font-weight: 900; color: #4a2c00; box-shadow: 0 14px 56px rgba(255, 149, 0, 0.5), inset 0 -12px 24px rgba(0,0,0,0.2); }
.coin.spinning { animation: flip 0.6s ease-in-out; }
@keyframes flip { 0% { transform: rotateY(0); } 50% { transform: rotateY(900deg) scale(1.1); } 100% { transform: rotateY(1800deg); } }

/* Slots */
.reels { display: flex; gap: 16px; }
.reel { width: 140px; height: 180px; background: linear-gradient(180deg, #3d2570 0%, #1f1040 100%); border: 2px solid var(--gold); border-radius: var(--r-md); display: flex; align-items: center; justify-content: center; font-size: 80px; box-shadow: inset 0 0 36px rgba(255, 184, 0, 0.25); }
.reel.win { animation: winPulse 0.8s ease-in-out infinite; }
@keyframes winPulse { 0%,100% { box-shadow: inset 0 0 30px rgba(34,197,94,0.3), 0 0 20px rgba(34,197,94,0.5); } 50% { box-shadow: inset 0 0 40px rgba(34,197,94,0.6), 0 0 40px rgba(34,197,94,0.8); } }

/* Crash */
.crash-multi { font-size: 96px; font-weight: 900; color: #fff; letter-spacing: -0.04em; text-shadow: 0 0 40px rgba(255, 184, 0, 0.5); }

/* Fairness — settled dark plate matching the games-picker tile family.
   Was a 3 px transparent border with white→pink→white gradient outline,
   which read as decorative chrome rather than a settled card. */
.fair-card {
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 14px;
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 720px;
}
.fair-row { display: flex; flex-direction: column; gap: 6px; }
.fair-row .muted {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.fair-row code {
  font-family: var(--font-num);
  font-size: 12px;
  font-weight: 700;
  color: #fff;
  letter-spacing: 0;
  word-break: break-all;
}
.fair-row strong {
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #fff;
}
.inline-edit { display: flex; gap: 8px; }
.inline-edit .input { flex: 1; }

/* Audit */
.audit-key { background: var(--bg-card-solid); border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px; margin-bottom: 8px; }
.audit-key pre { font-family: var(--font-num); font-size: 10px; color: var(--text-muted); white-space: pre-wrap; word-break: break-all; margin-top: 8px; }
.verify-bar { display: flex; gap: 8px; margin-bottom: 12px; max-width: 400px; }
.verify-valid { padding: 12px 16px; background: rgba(34, 197, 94, 0.15); border-left: 3px solid var(--green); border-radius: var(--r-md); color: var(--green); font-weight: 600; }
.verify-invalid { padding: 12px 16px; background: rgba(239, 68, 68, 0.15); border-left: 3px solid var(--red); border-radius: var(--r-md); color: var(--red); font-weight: 600; }

/* Toasts — themed to match the dark purple game chrome. */
#toast-stack {
  position: fixed; top: 60px; right: 16px;
  display: flex; flex-direction: column; gap: 6px;
  z-index: 1000; pointer-events: none;
  max-width: min(340px, calc(100vw - 32px));
}
#toast-stack > .toast { pointer-events: auto; }

/* ─── Network status banner ─────────────────────────────────────────────
   Persistent fixed-position strip just below the titlebar. Appears when
   navigator.onLine flips false OR `call()` throws a network error twice
   in a row (catches captive portals / DNS failures where onLine still
   lies). Auto-clears + flashes green "Reconnected" briefly when the
   connection returns. Same place-bet surface as the rest of the app so
   it reads as a first-class system message, not a fly-by toast. */
.net-status {
  position: fixed;
  top: calc(48px + env(safe-area-inset-top, 0px) + 6px);
  left: 12px;
  right: 12px;
  z-index: 10001;
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.92);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: #fff;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: -0.01em;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 3px 0 0 rgba(50, 3, 18, 0.55);
  animation: netStatusSlideDown 0.22s ease;
  pointer-events: none;
}
.net-status.hidden { display: none; }
.net-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #ff9500;
  flex-shrink: 0;
  animation: netStatusPulse 1.2s ease-in-out infinite;
}
.net-status.reconnected {
  background:
    linear-gradient(180deg, rgba(0, 214, 143, 0.30) 0%, rgba(0, 130, 84, 0.30) 100%),
    rgba(15, 8, 36, 0.92);
}
.net-status.reconnected .net-status-dot {
  background: #00d68f;
  animation: none;
}
@keyframes netStatusSlideDown {
  from { transform: translateY(-12px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
@keyframes netStatusPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.85); }
}

/* ─── Bet input invalid state ───────────────────────────────────────────
   When the player types a negative number, too many decimals, NaN, or
   over balance — the existing JS already prevents the bet from firing,
   but the input gives no visual feedback. The `.invalid` class below
   paints a red border + inline error text in the same place-bet visual
   family (sharp 4 px corners, same font stack). Cleared on next valid
   input. */
.bet-input-wrap {
  position: relative;
}
.input.invalid,
.bet-amount.invalid,
input.invalid {
  border-color: #ef4444 !important;
  box-shadow: 0 0 0 1px rgba(239, 68, 68, 0.25) inset !important;
}
.bet-error {
  /* Dark navy plate + bright cherry-pink rim — same surface as the
     "Bet (Next round)" / Verify TOTP / Change password buttons across
     the app. Reads as a first-class system message with the same brand
     pink outline players already learned. */
  display: block;
  margin-top: 4px;
  padding: 7px 12px;
  background: rgba(15, 8, 36, 0.7);
  border: 2px solid #d91554;
  border-radius: 4px;
  color: #fff;
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  line-height: 1.3;
  pointer-events: none;
  animation: betErrorSlideIn 0.15s ease;
}
.bet-error.hidden { display: none; }
@keyframes betErrorSlideIn {
  from { transform: translateY(-4px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
.toast {
  width: max-content;
  padding: 6px 12px;
  /* Place-bet surface — translucent red gradient over dark navy with the
     same subtle white border + 4 px sharp corners as PLACE BET. Brings
     toasts into the same in-game CTA visual family as the rest of the
     trade-execute slabs across the app. */
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55);
  color: #fff;
  border: 1px solid var(--border);
  border-radius: 4px;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 3px 0 0 rgba(50, 3, 18, 0.55);
  font-size: 12px; font-weight: 700;
  animation: slideIn 0.22s ease;
  transition: opacity 0.3s;
  max-width: 100%;
  word-wrap: break-word;
}
/* Actionable toast — message on top, "Play with ETH (0.0524)" button
   below. Button mirrors the auth-submit / in-game CTA flat dark-navy
   look so every primary action across the app reads the same. The
   coin icon SVG wrapper keeps consistent sizing matching the picker. */
.toast-msg { display: block; margin-bottom: 8px; }
.toast-action {
  display: inline-flex; align-items: center; gap: 8px;
  width: 100%; justify-content: center;
  padding: 10px 14px;
  background: rgba(15, 8, 36, 0.7);
  color: #fff;
  border: 2px solid #d91554;
  border-radius: 4px;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  font: inherit; font-family: var(--font-ui);
  font-size: 12px; font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: none;
  cursor: pointer;
  box-shadow: none;
  transition: background 0.12s;
}
.toast-action:hover {
  background: rgba(15, 8, 36, 0.78);
  border: 2px solid #d91554;
  filter: none;
}
.toast-action:active {
  background: rgba(15, 8, 36, 0.85);
  border: 2px solid #d91554;
  transform: none;
}
.toast-action .coin-ring { padding: 1.5px; }
.toast-action .coin-icon { width: 16px; height: 16px; }
@keyframes slideIn { from { transform: translateX(18px); opacity: 0; } to { transform: none; opacity: 1; } }

/* Mobile: dock to bottom-centre above the tab bar so toasts don't cover the
   active game board. */
body.mobile #toast-stack {
  top: auto;
  bottom: calc(70px + env(safe-area-inset-bottom, 0));
  left: 12px; right: 12px;
  align-items: center;
  max-width: none;
}
body.mobile .toast { width: max-content; text-align: center; }

::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: var(--r-pill); }
::-webkit-scrollbar-thumb:hover { background: var(--text-dim); }

/* Affiliate + user modal */
.table-row.aff-bal { grid-template-columns: 90px 1.5fr 1.5fr auto; }
.table-row.aff-ref { grid-template-columns: 1.5fr 90px 1fr 1fr 150px; }
.table-row.aff-comm { grid-template-columns: 90px 110px 1.2fr 1.2fr 150px; }
.table-row.aff-admin { grid-template-columns: 1.5fr 120px 120px 1.2fr 140px; }
.table-row.user-addr { grid-template-columns: 40px 1fr 140px auto; }
.clickable-row { cursor: pointer; transition: 0.15s; }
.clickable-row:hover { background: rgba(255, 255, 255, 0.04); border-color: var(--border); }
.clickable { cursor: pointer; color: var(--blue); text-decoration: underline dotted; }

.modal-backdrop { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.75); display: flex; align-items: center; justify-content: center; z-index: 2000; backdrop-filter: blur(6px); }
body.mobile.logged-in .modal-backdrop { bottom: calc(60px + env(safe-area-inset-bottom, 0px)); }
.modal { background: rgba(15, 8, 36, 0.35); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); border: 1px solid rgba(255, 255, 255, 0.08); border-radius: var(--r-lg); width: 90%; max-width: 880px; max-height: 85vh; overflow-y: auto; }
.modal-header { position: sticky; top: 0; background: var(--bg-card-solid); padding: 14px 20px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; font-weight: 700; font-size: 14px; letter-spacing: 0.02em; z-index: 1; }
.modal-body { padding: 20px; }
.modal-h3 { font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); margin: 20px 0 10px; }
.user-detail-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px; margin-bottom: 14px; }
.detail-label { font-size: 10px; letter-spacing: 0.1em; color: var(--text-dim); text-transform: uppercase; margin-bottom: 4px; }
.detail-banner { padding: 10px 14px; background: rgba(74, 127, 255, 0.1); border-left: 3px solid var(--blue); border-radius: var(--r-md); font-size: 12px; margin-bottom: 14px; }

/* Narrow window: shrink sidebar to icon-only so page content keeps room. */
@media (max-width: 900px) {
  #sidebar { width: 64px; padding: 16px 6px; }
  .nav-btn { justify-content: center; padding: 11px 0; font-size: 0; gap: 0; }
  .nav-btn .nav-i { font-size: 16px; }
  .nav-btn .nav-badge { position: static; margin-left: 2px; }
  .logout-btn { font-size: 0; padding: 10px 0; }
  .logout-btn::before { content: '⎋'; font-size: 14px; }
}

.dice-canvas { width: 320px; height: 200px; display: block; margin: 0 auto 18px; }

/* Custom coin dropdown (replaces native <select> visually but keeps it for form value). */
.coin-dd { position: relative; width: 100%; }
.coin-dd > select { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.coin-dd-trigger {
  width: 100%;
  padding: 10px 12px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: 13px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  transition: 0.15s;
}
.coin-dd-trigger:hover { border-color: var(--border); }
.coin-dd.open .coin-dd-trigger { border-color: var(--border); box-shadow: 0 0 0 3px rgba(255, 46, 94, 0.15); }
.coin-dd-label { flex: 1; text-align: left; font-weight: 600; letter-spacing: 0.04em; }
.coin-dd-chev { color: var(--text-dim); font-size: 10px; transition: 0.15s; }
.coin-dd.open .coin-dd-chev { transform: rotate(180deg); }

.coin-dd-list {
  position: fixed;
  top: 0; left: 0;
  background: var(--bg-card-solid);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
  padding: 4px;
  z-index: 1000;
  display: none;
}
.coin-dd.open .coin-dd-list,
.coin-dd-list.open { display: block; }
.coin-dd-item {
  width: 100%;
  padding: 10px 12px;
  background: transparent;
  border: none;
  color: var(--text);
  border-radius: 8px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.05em;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
  text-align: left;
  font-variant-numeric: tabular-nums;
  transition: 0.1s;
}
.coin-dd-item:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }
.coin-dd-item.selected {
  background: rgba(15, 8, 36, 0.55);
  border-bottom: 1px solid var(--border);
  border-radius: 8px 8px 0 0;
  color: #fff;
}
.coin-dd-item.highlight { background: rgba(255, 255, 255, 0.12); color: #fff; }
.coin-dd-search {
  width: 100%;
  padding: 7px 10px;
  margin-bottom: 4px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text);
  font-family: inherit;
  font-size: 12px;
  outline: none;
}
.coin-dd-search:focus { border-color: var(--border); box-shadow: none; }
.coin-dd-search::placeholder { color: var(--text-dim); }
.coin-dd-empty { padding: 10px; text-align: center; color: var(--text-dim); font-size: 12px; }
.coin-dd-body { max-height: 320px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }

/* User menu dropdown under the email pill. */
.user-menu-wrap { position: relative; display: inline-block; flex-shrink: 0; -webkit-app-region: no-drag; }
.user-pill { cursor: pointer; white-space: nowrap; flex-shrink: 0; }
.user-pill > * { flex-shrink: 0; }
.user-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  left: auto;
  min-width: 180px;
  /* Identical glass treatment to .coin-picker — same translucent
     purple, same blur, same hairline border, no heavy shadow. */
  background: rgba(15, 8, 36, 0.35);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--r-md);
  padding: 4px;
  z-index: 9999;
}
.user-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 10px 12px;
  background: transparent;
  border: none;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  border-radius: var(--r-sm);
  cursor: pointer;
}
.user-menu-item:hover { background: rgba(255, 255, 255, 0.06); }
.user-menu-item-lang { display: flex; align-items: center; gap: 8px; }
.user-menu-item-lang .lang-flag { width: 18px; height: 18px; }

/* Mobile: user-menu dropdown wears the drawer skin (dark surface,
   purple-tinted border, rounded corner, strong shadow, full-width rows
   with dividers). A small scale-in keyframe "jump" plays each time it
   appears via a fresh animation rather than a transition (so it runs
   every time display flips from none → block). */
body.mobile .user-menu {
  min-width: 200px;
  padding: 4px 0;
  /* Identical glass treatment to body.mobile .coin-picker — same
     translucent purple, same blur, no heavy border. !important to
     beat any other rule layering darker backgrounds on top. */
  background: rgba(15, 8, 36, 0.35) !important;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: none;
  border-radius: 16px;
}
body.mobile .user-menu-item {
  padding: 14px 16px;
  font-size: 14px;
  min-height: 48px;
  border-radius: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  width: 100%;
}
body.mobile .user-menu-item:last-child { border-bottom: none; }

.pill-chev {
  color: #fff;
  font-size: 9px;
  line-height: 1;
  margin-left: 2px;
  padding: 2px 5px;
  background: rgba(255, 255, 255, 0.18);
  border-radius: var(--r-pill);
  transition: transform 0.15s, background 0.15s;
  font-weight: bold;
  display: inline-block;
}
.user-pill:hover .pill-chev { background: rgba(255, 255, 255, 0.28); }
.user-menu-wrap.open .pill-chev { transform: rotate(180deg); }

/* Coin label used in affiliate tables: gradient-ringed logo + white text */
.coin-label { display: inline-flex; align-items: center; gap: 8px; color: #fff; font-weight: 700; letter-spacing: 0.08em; font-size: 12px; }

.table-row.aff-roll { grid-template-columns: 90px 1fr 1.2fr 1.5fr; }
.table-row.aff-settle { grid-template-columns: 200px 90px 1fr 1fr auto; }

/* Affiliate bonus banner: dark fill + white-pink gradient outline (matches .fair-card) */
.aff-bonus-card {
  background:
    var(--bg-card-solid) padding-box,
    linear-gradient(135deg, #ffffff 0%, #ff3d6a 50%, #ffffff 100%) border-box;
  border: 3px solid transparent;
  color: var(--text);
  max-width: none;
}
.aff-bonus-card strong { color: #fff; font-weight: 800; }

.aff-bonus-card { text-align: left; gap: 6px !important; }
/* Equal vertical spacing between the three text rows: title / amount /
   subtitle. Without explicit flex-column the gaps fall back to each
   line's line-height which varies with font weight + size, producing
   uneven visual rhythm. */
.aff-bonus-card .aff-bonus-text {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* Shared base — daily-card relies on these for weight/colour/line-height
   while only overriding font-size. Affiliate card overrides further to
   build a quiet-caption / hero-amount / quiet-subtitle hierarchy. */
.aff-bonus-line1, .aff-bonus-line3, .aff-bonus-amount {
  font-size: 12px; font-weight: 700; letter-spacing: -0.01em; color: #fff;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  margin: 0;
}
/* Affiliate signup-bonus card — uses the canonical casino typography
   from the top-nav coin-picker (Open Sans, weight 700, tabular nums,
   -0.01em tracking) so the card sits in-family with the rest of the
   in-game text. Amount stays the hero via size, the caption rows
   stay quieter via slightly reduced opacity. */
.aff-bonus-card .aff-bonus-text { gap: 10px; }
.aff-bonus-card .aff-bonus-line1,
.aff-bonus-card .aff-bonus-line3,
.aff-bonus-card .aff-bonus-amount {
  font-family: var(--font-ui);
  font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: #fff;
}
.aff-bonus-card .aff-bonus-line1,
.aff-bonus-card .aff-bonus-line3 {
  font-size: 13px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.75);
}
.aff-bonus-card .aff-bonus-amount {
  font-size: 28px;
  line-height: 1.1;
}
/* Daily bonus card — centred stack mirroring the login modal layout
   (title / amount / subtitle / countdown / Claim CTA), max-width 420px
   like .auth-card, generous 16px gap between rows. */
.daily-card {
  margin: 0 auto;
  max-width: 420px;
  text-align: center !important;
  align-items: center;
  gap: 16px !important;
}
.daily-card .aff-bonus-text {
  text-align: center !important;
  align-items: center;
  width: 100%;
  gap: 8px;
}
.daily-card .aff-bonus-line1,
.daily-card .aff-bonus-line3 {
  font-size: 14px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.75);
  letter-spacing: 0;
  line-height: 1.5;
}
.daily-card .aff-bonus-amount {
  font-family: var(--font-ui);
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: #fff;
  line-height: 1.1;
}
/* Tighten the gap between the coin icon and the ticker on the daily-bonus
   amount line. Inline-flex with a small gap puts the icon snugly next to
   the word — avoids the wide whitespace gap that the surrounding letter-
   spacing was introducing between the icon span and the ticker text. */
.aff-bonus-coin {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  letter-spacing: 0;
}
.aff-bonus-coin .coin-ring { padding: 1px; }
.aff-bonus-coin .coin-icon { width: 22px; height: 22px; }
.daily-card .daily-action {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
  align-items: center;
}
.daily-card .daily-countdown {
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}
.daily-card .daily-countdown.ready { color: #fff; }
.daily-card #daily-claim-btn {
  width: 100%;
  min-height: 48px;
  font-size: 14px;
  /* "Numbers only" / "+ Add custom code" CTA family: dark navy plate with
     a 2 px cherry-pink rim, sharp 4 px corners, white bold text. No
     backdrop-filter, no press-depth shadow, no gradient fill, this is
     a secondary CTA, not the PLACE BET primary. */
  background: rgba(15, 8, 36, 0.7);
  border: 2px solid #d91554;
  border-radius: 4px;
  color: #fff;
  font-family: var(--font-ui);
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
}
.daily-card #daily-claim-btn:hover {
  background: rgba(15, 8, 36, 0.78);
  border: 2px solid #d91554;
  filter: none;
}
.daily-card #daily-claim-btn:active {
  background: rgba(15, 8, 36, 0.85);
  border: 2px solid #d91554;
  transform: none;
}
.daily-card #daily-claim-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  filter: none;
  transform: none;
}

/* ─── How-it-works 3-step explainer ────────────────────────────────────
   Sits between the referral-codes card and the stat cards on the
   affiliate page. Each step is a flat panel in the place-bet visual
   family (subtle navy fill, brand-pink accent number, white text).
   On wide viewports they sit in a 3-column grid; on phone-portrait
   they stack into a single column. */
.aff-how-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin: 14px 0;
}
@media (max-width: 720px) {
  .aff-how-grid { grid-template-columns: 1fr; }
}
.aff-how-step {
  position: relative;
  padding: 14px 14px 14px 50px;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border);
  border-radius: 4px;
  font-family: var(--font-ui);
  min-height: 88px;
}
.aff-how-num {
  position: absolute;
  top: 12px;
  left: 12px;
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(180deg, #d91554 0%, #7a082c 100%);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: #fff;
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 0;
}
.aff-how-title {
  font-weight: 800;
  font-size: 13px;
  letter-spacing: -0.01em;
  color: #fff;
  margin-bottom: 4px;
}
.aff-how-text {
  font-weight: 600;
  font-size: 12px;
  letter-spacing: -0.01em;
  color: rgba(255, 255, 255, 0.72);
  line-height: 1.4;
}
.aff-how-text strong { color: #fff; font-weight: 800; }

/* ─── Earnings calculator card ─────────────────────────────────────────
   Concrete "if X then Y" example. Uses the place-bet surface so it
   reads as an actionable CTA, not a passive disclaimer. */
.aff-calc-card {
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 14px 16px;
  margin: 0 0 14px;
  font-family: var(--font-ui);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 3px 0 0 rgba(50, 3, 18, 0.55);
}
.aff-calc-label {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.55);
  margin-bottom: 6px;
}
.aff-calc-line {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: rgba(255, 255, 255, 0.78);
  line-height: 1.4;
  margin-bottom: 6px;
}
.aff-calc-line strong { color: #fff; font-weight: 800; }
.aff-calc-amount {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: #fff;
  font-variant-numeric: tabular-nums;
  margin-bottom: 4px;
}
.aff-calc-sub {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: rgba(255, 255, 255, 0.55);
}

/* Signup-bonus card — fiat hint sits inline next to the BTC amount in
   a softer, smaller font so the raw BTC reads as the headline while
   the USD/EUR equivalent provides the concrete "$0.50" context. */
.aff-bonus-fiat {
  font-size: 0.55em;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.55);
  margin-left: 6px;
  letter-spacing: 0;
}

/* Referral code card — shown at top of affiliate page */
.aff-code-card {
  background:
    var(--bg-card-solid) padding-box,
    linear-gradient(135deg, #ffffff 0%, #ff3d6a 50%, #ffffff 100%) border-box;
  border: 3px solid transparent;
  border-radius: var(--r-lg);
  padding: 18px 20px;
  margin-bottom: 16px;
}
.aff-code-label { font-size: 11px; letter-spacing: 0.12em; color: var(--text-muted); text-transform: uppercase; margin-bottom: 10px; font-weight: 700; }
.aff-code-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.aff-code {
  font-size: 28px; font-weight: 800; color: #fff;
  font-family: var(--font-num); letter-spacing: 0.08em;
  flex: 1; min-width: 0; word-break: break-all;
}
.aff-code-copy { min-width: 120px; }
.aff-link-hidden { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
/* Legacy big-code display (`#aff-code` inside `.aff-code-card`). That one
   is usually `hidden` on the current affiliate page but we keep the size
   override scoped so it can't bleed into the list rows below. */
body.mobile .aff-code-card > .aff-code { font-size: 22px; }
/* List rows stay at the same compact mono size as desktop — the mobile rule
   above used to target `.aff-code` globally, which blew the list-row codes
   up to 22 px. */
body.mobile .aff-code-list .aff-code { font-size: 14px; }
body.mobile .aff-code-row { gap: 10px; }
body.mobile .aff-code-copy { width: 100%; }

/* Sidebar toggle (hamburger) */
.sidebar-toggle {
  display: flex; align-items: center; justify-content: center;
  width: 100%; padding: 8px 0; margin-bottom: 6px;
  background: transparent; border: none; cursor: pointer;
  border-radius: var(--r-md); transition: 0.15s;
}
.sidebar-toggle:hover { background: var(--bg-card-solid); }
.toggle-icon { width: 20px; height: 20px; stroke: var(--text-muted); }

/* Collapsed sidebar: icons only */
#sidebar.collapsed { width: 64px; padding: 16px 6px; }
#sidebar.collapsed .nav-btn { justify-content: center; padding: 11px 8px; font-size: 0; gap: 0; }
#sidebar.collapsed .nav-btn .nav-i { margin: 0; }
#sidebar.collapsed .nav-badge { position: static; font-size: 0; width: 8px; height: 8px; padding: 0; min-width: 8px; border-radius: 50%; }
#sidebar.collapsed .sidebar-toggle { margin-bottom: 8px; }

/* ======== Mobile responsive layout ======== */
/* Global overflow guard: no horizontal scroll on mobile, anywhere. */
html, body.mobile, body.mobile #app-view, body.mobile #content, body.mobile .view {
  overflow-x: hidden; max-width: 100vw; width: 100vw;
}
/* Hard-clip any stray child that tries to exceed the phone viewport —
   guarantees every page is usable on any screen width without horizontal
   scroll / left-side text clipping. */
body.mobile * {
  max-width: 100vw;
  box-sizing: border-box;
}
body.mobile table,
body.mobile pre,
body.mobile code { max-width: 100%; overflow-x: auto; }
/* Exceptions: elements that deliberately scroll horizontally (marquee
   tickers, carousels). Clamping them forces wrap and they blow up. */
body.mobile .big-wins-track,
body.mobile .big-wins-track *,
body.mobile .big-wins-ticker,
body.mobile .roul-recent-hero,
body.mobile .cf-recent-hero,
body.mobile .crash-history,
body.mobile .dice-history { max-width: none; }
body.mobile * { min-width: 0; } /* allow flex/grid children to shrink */
body.mobile img, body.mobile canvas, body.mobile video { max-width: 100%; height: auto; }
body.mobile input, body.mobile select, body.mobile textarea { max-width: 100%; }

/* Hide the sidebar collapse toggle (hamburger) on mobile — sidebar is already icon-only. */
body.mobile .sidebar-toggle { display: none !important; }

/* Titlebar burger — hidden on desktop, shown on mobile. */
.tb-burger {
  display: none; align-items: center; justify-content: center;
  background: transparent; border: none; cursor: pointer;
  width: 36px; height: 36px; border-radius: 8px;
  color: var(--text); padding: 0; margin-right: 4px;
  -webkit-app-region: no-drag;
}
.tb-burger:hover { background: rgba(255,255,255,0.08); }
.tb-burger-icon { width: 22px; height: 22px; stroke: currentColor; }
body.mobile .tb-burger { display: inline-flex; }

/* Mobile nav drawer — hidden by default, slides in on .mobile-nav-open.
   Backdrop covers the whole screen including titlebar + tabbar so the drawer
   is unambiguously the foreground. */
#mobile-nav-backdrop {
  position: fixed; inset: 0;
  /* Softer scrim — lower opacity + stronger blur so the page diffuses
     through gently instead of being slammed near-black. Reduces the
     harsh contrast against the drawer. */
  background: rgba(6, 2, 20, 0.45);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  z-index: 200; opacity: 0; pointer-events: none;
  transition: opacity 0.22s ease;
}
/* Fires on any viewport when the drawer-style menu is open — not only
   when body.mobile is set. Needs `display: block` to override the default
   `#app-view > #mobile-nav-backdrop { display: none }` rule. Tapping the
   dimmed backdrop closes the menu (handler lives in app.js). */
body.mobile-nav-open #mobile-nav-backdrop {
  display: block !important;
  opacity: 1; pointer-events: auto;
}

body.mobile #sidebar {
  position: fixed; top: 68px; left: 0;
  bottom: calc(58px + env(safe-area-inset-bottom, 0) + 6px);
  width: 240px; padding: 8px 0; gap: 0;
  transform: translateX(-100%); transition: transform 0.2s ease;
  z-index: 210;
  /* Deeper near-black drawer with a hint of purple so it reads as a proper
     overlay surface, not a tinted sidebar. */
  background: #07021a;
  border-right: 1px solid var(--border);
  border-bottom-right-radius: 16px;
  box-shadow: 8px 0 32px rgba(0, 0, 0, 0.65);
  overflow-y: auto; scrollbar-width: none; -ms-overflow-style: none;
}
body.mobile #sidebar::-webkit-scrollbar { display: none; }
body.mobile.mobile-nav-open #sidebar { transform: translateX(0); }
/* Hamburger icon at the top of the mobile drawer — hidden on desktop. */
.drawer-logo { display: none; }
body.mobile #sidebar .drawer-logo {
  display: block;
  width: 32px; height: 32px;
  stroke: #fff;
  margin: 8px auto 12px;
}
body.mobile #sidebar .drawer-logo svg { width: 100%; height: 100%; }
/* Each nav button gets a thin divider line below — so the list of clickable
   items is visually separated into rows. */
body.mobile #sidebar .nav-btn {
  justify-content: flex-start; padding: 14px 16px; font-size: 14px;
  gap: 12px; width: 100%; min-height: 48px;
  border-radius: 0;
  border-top: none;
  border-bottom: none;
  border-left: 2px solid transparent;
  border-right: 2px solid transparent;
}
body.mobile #sidebar .nav-btn .nav-i { margin: 0; width: 20px; height: 20px; }
body.mobile #sidebar .nav-badge {
  position: static; font-size: 10px; width: auto; height: auto;
  min-width: auto; padding: 2px 6px; border-radius: 999px;
  margin-left: auto;
}
/* Grid shifts because sidebar is fixed-positioned */
/* Same `.active` qualifier as desktop — see line 1673 comment. */
body.mobile #app-view.active { display: block; }
/* Bottom padding clears the fixed mobile-tabbar; top padding clears the
   fixed titlebar. The wins ticker is positioned absolutely BEHIND the
   glassy titlebar (rule below) so it doesn't steal canvas height. */
body.mobile #content { padding: 50px 14px calc(60px + env(safe-area-inset-bottom, 0px)) 14px; }
/* Ticker rides behind the glassy titlebar — same pattern as desktop —
   so the canvas doesn't lose the ~40 px the ticker would take in-flow.
   z-index 50 puts it above page content (which has no positioning) but
   below the titlebar (z 100), which lets the glass titlebar dim/blur it
   for the "scrolling behind the topnav" effect. */
body.mobile .big-wins-ticker {
  position: absolute !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  z-index: 50 !important;
}
/* Game stage spans the full viewport width on mobile — breaks out of any
   parent padding via 100vw + 50%-50vw margin trick, regardless of how
   deeply the element is nested under #content's 14px gutter. Rounded
   corners flattened so the canvas hugs the screen edges. */
body.mobile .game-display,
body.mobile .dice-canvas-wrap,
body.mobile .crash-stage,
body.mobile .plinko-stage,
body.mobile .mines-stage,
body.mobile .roul-wheel-wrap,
body.mobile .blackjack-stage,
body.mobile #page-coinflip .game-display,
body.mobile #page-slots .game-display {
  /* Inset 8px from each edge with 16px rounded corners — game canvas reads
     as a soft card instead of full-bleed edge-to-edge. */
  width: calc(100vw - 16px) !important;
  max-width: calc(100vw - 16px) !important;
  margin-left: calc(50% - 50vw + 8px) !important;
  margin-right: calc(50% - 50vw + 8px) !important;
  border-radius: 16px !important;
}
body.mobile .crash-bets-panel {
  /* Match the canvas inset + radius so the bet feed reads as a sibling card. */
  width: calc(100vw - 16px) !important;
  max-width: calc(100vw - 16px) !important;
  margin-left: calc(50% - 50vw + 8px) !important;
  margin-right: calc(50% - 50vw + 8px) !important;
  border-radius: 16px !important;
  overflow: hidden !important;
}
/* Kill the column gap between the game canvas and the bets panel so the
   canvas sits flush against the next element below. Also zero out any
   vertical padding on the .dice-game / .crash-main containers and on
   the canvas-wraps inside them — those were the source of the "lavender
   band" between canvas and bets-panel on dice / coinflip / roulette. */
body.mobile .live-layout,
body.mobile .crash-game,
body.mobile .dice-game {
  gap: 0 !important;
}
body.mobile .live-layout > .dice-game,
body.mobile .live-layout > .crash-main,
body.mobile .crash-game > .crash-main,
body.mobile .dice-canvas-wrap,
body.mobile #page-coinflip .game-display,
body.mobile #page-roulette .roul-wheel-wrap,
body.mobile #page-slots .game-display,
body.mobile .crash-stage,
body.mobile .plinko-stage,
body.mobile .mines-stage,
body.mobile .blackjack-stage {
  margin-bottom: 0 !important;
  padding-bottom: 0 !important;
}
body.mobile .live-layout > .crash-bets-panel,
body.mobile .crash-game > .crash-bets-panel {
  margin-top: 0 !important;
  padding-top: 12px !important;
  position: relative;
  z-index: 2;
}
/* Crash canvas needs a tight breathing-room strip at the bottom so
   the rocket / "Place your bet" text isn't cramped against the
   bets-panel tabs. 16 px is enough — the canvas itself already
   stretches via padding to use the freed vertical room. */
body.mobile .crash-game > .crash-main {
  padding-bottom: 16px !important;
}
/* Kill the 8 px margin-bottom AND the flex: 0 0 42dvh sizing on the
   canvas wrappers (lines 9748-9760, 9586). The flex height (42dvh)
   was smaller than the canvas inside (60dvh) — the canvas overflowed
   visually past the wrapper but the wrapper's flex slot stayed at
   42dvh, leaving an 18dvh "phantom slot" the bets-panel rendered
   below, manifesting as the lavender gap. Forcing the wrapper to
   size to its content (height: auto + flex: 0 0 auto) collapses
   the gap. Plus margin-bottom: 0 kills the 8 px chip from #9760. */
body.mobile #page-coinflip.active .live-layout > .game-layout,
body.mobile #page-dice.active .live-layout > .dice-game,
body.mobile #page-slots.active .live-layout > .game-layout,
body.mobile #page-mines.active .live-layout > .game-layout,
body.mobile #page-plinko.active .live-layout > .game-layout,
body.mobile #page-blackjack.active .live-layout > .game-layout,
body.mobile #page-roulette.active .live-layout > .game-layout {
  margin-bottom: 0 !important;
  flex: 0 0 auto !important;
  height: auto !important;
  min-height: 0 !important;
}
/* And kill the gap on the parent .live-layout itself — per-game
   rules (lines 9574, 9746) set gap: 14px !important which beat my
   earlier .live-layout { gap: 0 !important } via #page-id specificity. */
body.mobile #page-roulette.active .live-layout,
body.mobile #page-blackjack.active .live-layout {
  gap: 0 !important;
}
/* Roulette's 200 px padding-bottom on .game-layout (line 9581) was
   creating an explicit 200 px lavender gap below the wheel. Kill it. */
body.mobile #page-roulette.active .game-layout {
  padding-bottom: 0 !important;
}
/* Belt-and-braces: paint a solid dark plate behind the entire
   .live-layout AND .crash-game columns so any residual gap
   (padding, flex-rounding, scroll-pad, etc.) reads as the same
   dark chrome as the bets-panel instead of leaking the page
   background as lavender. */
body.mobile .live-layout,
body.mobile .crash-game {
  background: rgba(15, 8, 36, 0.92) !important;
}

/* Roll Under / Roll Over (dice + coinflip Heads/Tails + similar
   segmented tabs) → match the typography of the bets-feed
   Live / My Bets / Big Wins tabs: smaller font, wider letter
   spacing, identical weight/colour treatment. Players read both
   strips as the same chrome family. */
body.mobile .dice-dir-seg .seg {
  font-size: clamp(10px, 2.8vw, 12px) !important;
  letter-spacing: 0.1em !important;
  font-weight: 700 !important;
  padding: 12px 10px !important;
  font-family: var(--font-ui) !important;
}
body.mobile .dice-dir-seg .seg.active {
  font-weight: 700 !important;
  letter-spacing: 0.1em !important;
  padding-bottom: 10px !important;
}
/* Force the dice-game / crash-main parent height to match its canvas
   content exactly — any flex-grow leftover space was leaking as the
   "lavender gap" between the canvas's bottom edge and the bets-panel's
   top edge. Locking to content-height eliminates the leak. */
body.mobile .live-layout > .dice-game,
body.mobile .live-layout > .crash-main,
body.mobile .crash-game > .crash-main {
  flex: 0 0 auto !important;
  min-height: 0 !important;
}
/* And size the canvas wraps inside to their own min-height (60dvh)
   without flex-growing past it. Otherwise the wrap stretches to fill
   parent's leftover flex space and the bottom gap reappears. */
body.mobile .live-layout > .dice-game > .dice-canvas-wrap,
body.mobile .live-layout > .game-display,
body.mobile .live-layout > .roul-wheel-wrap,
body.mobile .crash-game > .crash-main > .crash-stage {
  flex: 0 0 auto !important;
  height: 60dvh !important;
}
/* Max-height game canvas — the canvas gets the lion's share of vertical
   space, bets panel takes only what it needs for ~3 visible rows. */
body.mobile .dice-canvas-wrap,
body.mobile .game-display,
body.mobile .crash-stage,
body.mobile .plinko-stage,
body.mobile .mines-stage,
body.mobile .roul-wheel-wrap,
body.mobile .blackjack-stage {
  min-height: 60dvh !important;
}
body.mobile .page-title { font-size: 22px; }
/* Align every page-title / section-title with the .stat-card label
   ("PENDING WITHDRAWALS" et al). The card has a 3 px gradient border
   plus 18 px inner padding, so its label sits 21 px in from the card
   edge — push the bare titles right by the same amount on mobile so
   "Dashboard" lines up with "PENDING WITHDRAWALS" 1:1. */
body.mobile .page > .page-title,
body.mobile .page > .dashboard-head .page-title,
body.mobile .page > .section-title {
  padding-left: 21px;
}
/* Wallet pane: section-titles ("Recent deposits:", "Your withdrawal
   requests") align with the form labels above them ("Currency",
   "Withdraw coin · tap to change") at the wallet-pane left edge — and
   carry the same font-weight as `.withdraw-label` (700) so the title
   weight matches the field label weight. */
body.mobile .page .wallet-pane > .section-title {
  padding-left: 0;
  font-weight: 700;
}

/* Titlebar — compact balance on mobile */
body.mobile #titlebar { padding: 4px 12px; height: 52px; }
/* On mobile the user-pill is basically just the sign-out chev. Strip the outer
   violet pill so only the small inner chev capsule is visible. */
body.mobile .user-pill {
  padding: 0; margin-right: 4px; gap: 0;
  background: transparent !important;
  border-color: transparent !important;
  box-shadow: none !important;
  max-width: none;
}
body.mobile .user-pill .pill-email { display: none; }
body.mobile .user-pill .pill-chev {
  margin-left: 0; padding: 8px 12px; font-size: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: none;
  flex-shrink: 0;
}
body.mobile .user-pill:hover .pill-chev,
body.mobile .user-pill:active .pill-chev { background: rgba(255, 255, 255, 0.12); }
body.mobile .brand-mark { width: 18px; height: 18px; }
body.mobile .view { height: calc(100vh - 42px); }

/* Game layouts — fit viewport, center-align, smaller visuals */
body.mobile .live-layout { grid-template-columns: 1fr; gap: 8px; }
/* Mobile: bets panel lives below the game controls (order:2) and gets its
   own scroll region so it never eats the space the bet controls and PLACE
   BET button need. 55 vh gives the inner list ~4–8 rows after the tabs,
   totals, column-header and footer take their share — 40 vh left the list
   with only one visible row on most phones. */
body.mobile .live-layout > .crash-bets-panel,
body.mobile .crash-game > .crash-bets-panel {
  /* Sits below the game canvas; the sticky PLACE BET panel (position:
     fixed) overlays the bottom of this list. Content scrolls within.
     Flex ratio rebalanced — canvas now gets 2× the bets panel (was
     reversed 1:3 in favor of the panel), so the 3D scene reads as
     the hero of the page. The list still flex-grows to show ~3-5
     rows on a typical phone and scrolls internally for the rest. */
  order: 1;
  flex: 1 1 auto;
  min-height: 0 !important;
  max-height: none !important;
  width: 100% !important; max-width: 100% !important; min-width: 0 !important;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
/* Force the bets-panel parent (live-layout / crash-game) into a single
   mobile flex column, overriding any desktop grid/2-col layout. */
body.mobile .live-layout,
body.mobile .crash-game {
  display: flex !important; flex-direction: column !important;
  grid-template-columns: none !important;
  width: 100% !important; max-width: 100% !important;
  /* Gap between the game stage and the bets-panel. The tab-bar is
     already subtracted by the outer #page-* height rule, so the bottom
     reserve here only covers the fixed sticky-controls + a small
     breathing gap — the 60 px tab-bar is NOT double-counted. */
  gap: 16px;
  padding-bottom: calc(var(--sticky-h, 320px) + env(safe-area-inset-bottom, 0) + 12px);
}
/* Give the scrollable bet list breathing room at the bottom so its last
   rows aren't permanently hidden behind the fixed sticky panel. */
body.mobile .live-layout > .crash-bets-panel .crash-bets-list,
body.mobile .crash-game > .crash-bets-panel .crash-bets-list {
  flex: 1 1 auto;
  /* No forced min-height — the panel decides height based on viewport
     via its own max-height cap (see media query below). List scrolls
     internally whenever content exceeds what the panel allots. The
     sticky-controls reserve lives on the outer flex column (.live-layout
     / .crash-game), so no double-reservation here. */
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* `contain` previously trapped touch scroll inside this list — once the
     user hit the top, swiping up did nothing because the gesture stopped
     bubbling to the outer page. `auto` lets scroll chain back to the
     page so swipes past the list edge reach the rest of the game view. */
  overscroll-behavior: auto;
  /* Force vertical pan only — kills any horizontal-pan capture so the
     gesture is unambiguously "scroll the page". */
  touch-action: pan-y;
  padding-bottom: 0;
}
body.mobile .live-layout > .dice-game,
body.mobile .crash-game > .crash-main {
  order: 0;
  display: flex; flex-direction: column;
  /* Canvas-side gets 2× the flex weight of the bets panel below so
     the 3D scene reads as the hero of the page (previously the panel
     dominated 3:1 the other way). min-height is viewport-relative —
     short phones (~360px tall WebViews) keep a 320px floor, mid-size
     phones get ~50vh, and tall phones (~915px viewports) get up to
     600px before capping so the bets panel still has breathing room. */
  flex: 2 1 auto;
  min-height: clamp(320px, 50vh, 600px);
}
/* Bets panel is always visible below the canvas — it flex-grows into
   whatever space the game window leaves. Canvas keeps its intrinsic
   size (no forced split), so scenes render at the same visual footprint
   regardless of whether the feed is long or short. */
body.mobile .page .crash-bets-panel {
  display: flex !important;
  /* Panel reserves at least 60dvh so the scroll region is always tall
     enough to surface ~20 rows — the internal list flex-grows to fill
     that reserved area and scrolls once the feed exceeds it. */
  flex: 0 0 auto !important;
  min-height: 60dvh !important;
  max-height: none !important;
}
body.mobile .crash-bets-panel .crash-bets-list {
  flex: 1 1 auto !important;
  min-height: 0 !important;
  max-height: none !important;
  overflow-y: auto !important;
}
/* Game pages need to scroll vertically so the bets panel + its
   surrounding layout can extend past the viewport fold if needed.
   Sticky controls stay pinned via position:fixed, so scrolling never
   hides the Place Bet button. Applies to every game page. */
body.mobile #page-dice.active,
body.mobile #page-coinflip.active,
body.mobile #page-mines.active,
body.mobile #page-plinko.active,
body.mobile #page-crash.active,
body.mobile #page-roulette.active,
body.mobile #page-slots.active,
body.mobile #page-blackjack.active {
  overflow-y: auto !important;
}
body.mobile #page-dice.active .live-layout,
body.mobile #page-coinflip.active .live-layout,
body.mobile #page-roulette.active .live-layout,
body.mobile #page-slots.active .live-layout,
body.mobile #page-dice.active .game-layout,
body.mobile #page-coinflip.active .game-layout,
body.mobile #page-roulette.active .game-layout,
body.mobile #page-slots.active .game-layout,
body.mobile #page-blackjack.active .game-layout,
body.mobile #page-mines.active .game-layout,
body.mobile #page-plinko.active .game-layout,
body.mobile #page-crash.active .crash-game {
  height: auto !important;
  min-height: 100% !important;
}
body.mobile .page .dice-game,
body.mobile .page .crash-main,
body.mobile .live-layout > .game-layout {
  /* Fixed share of the viewport so the canvas doesn't rubber-band every
     time the bets feed adds or removes a row. basis: 0, grow: 0 would
     collapse; pinning to a dvh share via flex-basis keeps it stable.
     Applies to dice / crash / coinflip / roulette / slots (the games
     with a bets-panel sibling in .live-layout). */
  flex: 0 0 42dvh !important;
  min-height: 0 !important;
}
/* In the expanded-bets view (chevron on) shrink the canvas to a small
   slice at the top and absolutely position the bets panel below it,
   ending just above the collapsed sticky bar. Keeps the game scene
   visible (player still wants to see it) while giving the panel the
   bulk of the column. Absolute positioning bypasses the flex/min-height
   heuristics that were leaving a gap below the Provably Fair footer. */
body.mobile .page.bets-shown {
  position: relative !important;
}
body.mobile .page.bets-shown .live-layout > .dice-game,
body.mobile .page.bets-shown .live-layout > .game-layout {
  flex: 0 0 18dvh !important;
  overflow: hidden !important;
}
/* Crash specifically — DO NOT shrink the canvas when bets are shown.
   Per user request the rocket scene must stay the same size whether
   the chevron is on or off. The bet panel slides up from below and
   overlays the bottom portion of the canvas instead of pushing it
   smaller (its background is opaque so the canvas underneath is
   covered, but the rocket scene's apparent footprint is unchanged). */
/* Drop the dice-canvas-wrap floor in bets-shown so it fits within the
   18dvh dice-game container. Crash keeps its 30dvh floor since its
   parent container stays at the larger 42dvh size. */
body.mobile .page.bets-shown .live-layout > .dice-game .dice-canvas-wrap {
  min-height: 0 !important;
}
body.mobile .page.bets-shown .crash-bets-panel,
body.mobile .page.bets-shown .crash-bets-panel.collapsed {
  position: absolute !important;
  z-index: 5 !important;
  top: 18dvh !important;
  left: 0 !important;
  right: 0 !important;
  /* Anchor the panel's BOTTOM above the top edge of the fixed sticky
     controls (PLACE BET bar). --sticky-h is the bar's *height* only;
     the bar itself is positioned `bottom: 58 + env-safe + 6` from the
     viewport bottom, so the panel must clear (sticky-h + 64 + env-safe)
     plus a small gap. Without the +64 the Provably Fair footer slid
     behind the translucent bar. */
  bottom: calc(var(--sticky-h, 100px) + 64px + env(safe-area-inset-bottom, 0) + 8px) !important;
  width: auto !important;
  height: auto !important;
  min-height: 0 !important;
  max-height: none !important;
  flex: none !important;
  margin: 0 !important;
}
/* Crash bet panel anchors below its 30dvh canvas (instead of the 18dvh
   used by dice/coinflip) — keeps the rocket scene at a readable size
   while still giving the bet feed plenty of vertical room above the
   sticky PLACE BET bar. */
body.mobile #page-crash.bets-shown .crash-bets-panel,
body.mobile #page-crash.bets-shown .crash-bets-panel.collapsed {
  top: 30dvh !important;
}
body.mobile .page.bets-shown .crash-bets-panel.collapsed .crash-bets-list,
body.mobile .page.bets-shown .crash-bets-panel.collapsed .crash-bets-header,
body.mobile .page.bets-shown .crash-bets-panel.collapsed .crash-bets-total {
  display: flex !important;
}
/* Crash stage + history behave like the dice canvas stack: history
   content-sized on top, stage fills the remaining main area. */
body.mobile .crash-game > .crash-main > .crash-history { flex-shrink: 0; }
body.mobile .crash-game > .crash-main > .crash-stage {
  flex: 1 1 auto !important;
  height: auto !important;
  min-height: 30dvh !important;
  max-height: none !important;
}

/* Crash page gets the same flex column layout so bets panel can sit
   below the game and extend behind the fixed control bar. */
body.mobile #page-crash.active {
  display: flex !important; flex-direction: column;
  height: calc(100dvh - 128px - env(safe-area-inset-bottom, 0));
  min-height: 360px;
}
body.mobile #page-crash.active .crash-game {
  display: flex !important; flex-direction: column;
  flex: 1; min-height: 0; min-width: 0;
  width: 100%; max-width: 100%;
}
body.mobile #page-crash.active .crash-main,
body.mobile #page-crash.active .crash-bets-panel,
body.mobile #page-crash.active .crash-stage,
body.mobile #page-crash.active .crash-history {
  width: 100%; max-width: 100%; min-width: 0;
}
body.mobile #page-crash.active .crash-stage canvas { max-width: 100%; }
/* While the current round is flying / crashed, keep the crash controls bar
   visible — the amount and cashout fields get dimmed by the global
   .bet-closed rule, and the play button swaps to "Bet (Next round)" so the
   player can queue a bet for the next window (mirrors dice / coinflip). */
/* Sticky panel always comes last in the flex column → flush at the very
   bottom, pinned above the tab bar. */
body.mobile .dice-controls-sticky,
body.mobile .cf-controls-sticky,
body.mobile .mines-controls-sticky,
body.mobile .plinko-controls-sticky { order: 2; }
/* Compress the chrome inside the mobile bets panel so the list gets the
   dominant share of height. */
body.mobile .crash-bets-total { padding: 6px 10px; }
body.mobile .crash-bets-total-val { font-size: 16px; }
body.mobile .crash-bets-footer { padding: 6px 8px; }
body.mobile .crash-fair-badge { padding: 5px 10px; font-size: 10px; }
body.mobile .crash-game { grid-template-columns: 1fr; height: auto; min-height: 0; }
body.mobile .game-layout { max-width: 100%; gap: 10px; padding: 0; }
/* Give 3D canvases real room on mobile — 208px was designed before the
   Three.js scenes and left them cramped. */
body.mobile .game-display { min-height: 320px; min-height: 260px; padding: 0; }
body.mobile .dice-canvas-wrap {
  /* Canvas flex-grows inside .dice-game; overflow hidden so its WebGL
     context can't paint outside the box. Floor matches the coinflip
     .game-display min-height so both games' canvases feel the same
     size — earlier this was min-height: 0, which let dice render
     visibly shorter than coinflip on the same viewport. */
  flex: 1 1 auto !important;
  height: auto !important;
  min-height: 30dvh !important;
  overflow: hidden !important;
  /* Solid dark plate matching the WebGL clear color so the decorative
     #cherry-bg watermark behind the body can never bleed through the
     canvas (even before / after the first WebGL frame). */
  background: #050a0c !important;
}
body.mobile #page-coinflip .game-display,
body.mobile #page-slots .game-display,
body.mobile .crash-stage,
body.mobile .plinko-stage,
body.mobile .mines-stage,
body.mobile .roul-wheel-wrap,
body.mobile .blackjack-stage {
  background: #050a0c !important;
}
body.mobile .coin { width: 140px; height: 140px; font-size: 64px; }
body.mobile .big-result { font-size: clamp(64px, 16vw, 96px); }
body.mobile .reels { gap: 6px; justify-content: center; }
body.mobile .reel { width: 80px; height: 108px; font-size: 46px; }
/* Crash mobile stage needs the same bump so the rocket trail has vertical
   room to climb before the grid wraps. */
body.mobile .crash-stage { min-height: 320px !important; min-height: 260px !important; }

/* Crash-specific compact on mobile */
body.mobile .crash-stage { min-height: 320px; }
body.mobile .crash-multiplier { font-size: clamp(40px, 10vw, 64px); }

/* Rows stack on mobile */
body.mobile .dice-bet-row { flex-direction: column; gap: 8px; }
body.mobile .dice-dir-row { flex-direction: column; gap: 8px; align-items: center; }
body.mobile .dice-stats-row { flex-direction: column; gap: 8px; }
body.mobile .dice-slider-row { flex-direction: column; align-items: stretch; gap: 8px; }
body.mobile .dice-slider-label { min-width: 0; white-space: normal; }
body.mobile .dice-target-btns { flex-wrap: wrap; justify-content: stretch; }
body.mobile .dice-target-btns .dice-quick { flex: 1 1 calc(50% - 4px); padding: 8px 4px; }
body.mobile .dice-amount-group { flex-wrap: wrap; align-items: center; }
body.mobile .dice-amount-group .input { flex: 0 1 auto; }
/* Centre the number on mobile to match the sportsbook ticket look — the
   bet-amount field is the same look on phones as desktop now. The earlier
   left-align override conflicted with .bet-amount's text-align: center. */
body.mobile .amount-input-wrap > .input { text-align: center !important; }
body.mobile .dice-amount-group .dice-quick { flex: 1; }

/* Mines — shrink tiles so 5x5 grid fits narrow screens */
body.mobile .mines-stage { min-height: 260px; min-height: 320px; padding: 0; gap: 8px; }
body.mobile .mines-grid { max-width: 100%; gap: 4px; }
body.mobile .mines-tile { font-size: 18px; border-width: 1px; border-radius: 6px; }

/* Plinko — shrink canvas stage */
body.mobile .plinko-stage { min-height: 260px; min-height: 320px; padding: 0; }

/* Blackjack — compact cards + wrapping hands */
body.mobile .blackjack-stage { min-height: 260px; min-height: 320px; padding: 0; gap: 12px; }
body.mobile .bj-hand { min-height: 80px; gap: 4px; }
body.mobile .bj-card { width: 48px; height: 68px; font-size: 24px; }
body.mobile .bj-card .suit { font-size: 11px; bottom: 4px; right: 5px; }
body.mobile .bj-card .rank-tl { font-size: 11px; top: 4px; left: 5px; }
body.mobile .bj-actions { flex-wrap: wrap; }
body.mobile .bj-actions .dice-roll-btn { flex: 1 1 calc(50% - 4px); padding: 12px; font-size: 13px; }

/* Tables allow horizontal scroll rather than overflow */
body.mobile .table-list { overflow-x: auto; }
body.mobile .table-row { min-width: 520px; }

/* Wallet grid stacks single-column on mobile */
body.mobile .wallet-grid { grid-template-columns: 1fr; }
body.mobile .withdraw-forms { grid-template-columns: 1fr; }

/* Affiliate / dashboard cards shrink — single column so values don't overflow */
body.mobile .stat-grid { grid-template-columns: 1fr; }
body.mobile .bankroll-box { grid-template-columns: 1fr; }
body.mobile .stat-value { font-size: 20px; word-break: break-word; }

/* Table rows stack vertically on mobile — no horizontal scroll */
body.mobile .table-row,
body.mobile .table-row.history-row,
body.mobile .table-row.aff-roll,
body.mobile .table-row.aff-settle {
  display: flex; flex-direction: column; align-items: flex-start;
  min-width: 0; gap: 4px; padding: 10px 12px;
}
body.mobile .table-row > span { white-space: normal; word-break: break-word; }
body.mobile .table-list { overflow-x: visible; }

/* Fair / forms — inputs full width */
body.mobile .fair-card, body.mobile .fair-row { flex-direction: column; align-items: stretch; }
body.mobile .inline-edit { flex-direction: column; gap: 6px; }
body.mobile .verify-bar { flex-direction: column; gap: 6px; }

/* Livechat panel shrinks to near-fullscreen on mobile. The floating bubble
   itself is hidden — users open chat via the "Support" tab in the bottom nav. */
body.mobile #livechat { right: 10px; bottom: 10px; }
body.mobile #livechat .lc-panel {
  /* Anchored explicitly to both top and bottom navs so the panel never
     slides UNDER the titlebar (~57 px) or the bottom tabbar (~60 px +
     safe-area). Previously the panel was only anchored to bottom: 68
     with a calc()-based height, which on Telegram WebApp's shorter
     viewport pushed the top edge ~5 px above the titlebar bottom and
     hid the "bet" hero logo. The (100vh - --tg-vh) term keeps the
     bottom edge tracking Telegram's actual nav top when the WebView
     viewport shrinks. */
  position: fixed;
  width: calc(100vw - 20px); max-width: 380px;
  top: 74px;
  bottom: calc(68px + env(safe-area-inset-bottom, 0px) + 100vh - var(--tg-vh, 100vh));
  right: 10px;
  height: auto;
  max-height: 520px;
}
body.mobile .lc-toggle { display: none !important; }

/* Support admin inbox stacks */
body.mobile .support-layout { grid-template-columns: 1fr; height: auto; }
body.mobile .support-threads { max-height: 220px; }

/* ===== Unified mobile game polish (Dice / Coinflip / Roulette / Slots / Crash / Plinko / Mines / Blackjack) ===== */

/* Center page title, shrink to fit */
body.mobile .game-layout > .page-title,
body.mobile .dice-game > .page-title,
body.mobile .crash-main > .page-title { text-align: center; font-size: 18px; margin: 0 0 8px; }

/* All bet rows: column stack, uniform spacing */
body.mobile .dice-bet-row,
body.mobile .dice-dir-row,
body.mobile .dice-stats-row {
  flex-direction: column; gap: 8px; width: 100%;
}
body.mobile .dice-field { width: 100%; }
body.mobile .dice-field label { font-size: 10px; opacity: 0.8; }

/* Inputs + selects: full-width, taller tap targets */
body.mobile .game-layout .input,
body.mobile .dice-game .input,
body.mobile .crash-main .input {
  width: 100%; padding: 12px; font-size: 14px;
}
body.mobile .coin-dd-trigger, body.mobile .styled-dd-trigger { padding: 12px; font-size: 14px; }

/* Dice stat cards on mobile: each stat is one horizontal row with the
   label on the left and the value on the right. Three stats stack as
   three rows — no narrow columns that wrap the words. */
body.mobile .dice-stats-row {
  display: flex; flex-direction: column;
  gap: 0;
  overflow: visible;
}
body.mobile .dice-stat {
  display: flex !important; flex-direction: row !important;
  justify-content: space-between; align-items: baseline;
  gap: 8px;
  padding: 0 6px;
  line-height: 1.2;
  min-width: 0;
  border: none !important;
}
body.mobile .dice-stat + .dice-stat { border: none !important; }
body.mobile .dice-stat .muted { font-size: 9px; white-space: nowrap; letter-spacing: 0.04em; }
body.mobile .dice-stat strong {
  font-size: 12px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  text-align: right;
  line-height: 1.2;
}
body.mobile .dice-stat-fiat {
  font-size: 9px; margin-left: 4px; white-space: nowrap;
  color: var(--text-muted);
}

/* Dice range controls: buttons 2x2 grid */
body.mobile .dice-target-btns {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px; width: 100%;
}
body.mobile .dice-target-btns .dice-quick { padding: 10px; font-size: 12px; }
body.mobile .dice-dir-row { padding: 0; }
body.mobile .dice-dir-seg .seg { flex: 1; }
.dice-dir-num { font-weight: 800; color: inherit; font-variant-numeric: tabular-nums; margin-left: 4px; }

/* Hide the "Bet amount ≈ €X.XX" line above the amount pill in every game
   — the pill itself already carries the coin icon, "Amount" label and
   value, making this label redundant. */
body.mobile .dice-field-amount > label { display: none !important; }
body.mobile .dice-fiat-hint { display: none !important; }

/* Autoplay row: Auto toggle on the left, PLACE BET fills the rest on the
   same row. Applies to every game that uses .autoplay-row (dice, coinflip,
   roulette, slots, mines, plinko, blackjack). Tap the toggle any time to
   stop an in-progress autoplay run. */
body.mobile .autoplay-row {
  /* Stack: Auto toggle (short label row) on top, primary CTA full-width
     beneath. Biggest tap target = highest CR. Same pattern adopted across
     every game that uses .autoplay-row (dice, coinflip, roulette, slots,
     plinko, mines, blackjack). */
  display: flex !important; flex-direction: column !important;
  align-items: stretch; gap: 8px; padding: 0;
}
body.mobile .autoplay-row .autoplay-toggle {
  align-self: flex-start;
}
body.mobile .autoplay-row .autoplay-toggle {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 8px;
  cursor: pointer; user-select: none;
  font-size: 11px; letter-spacing: 0.02em;
}
body.mobile .autoplay-row .autoplay-toggle > input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 38px; height: 22px;
  background: rgba(255,255,255,0.18);
  border: 1px solid rgba(255,255,255,0.25);
  border-radius: 999px;
  position: relative; flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s;
  cursor: pointer; margin: 0;
}
body.mobile .autoplay-row .autoplay-toggle > input[type="checkbox"]::after {
  content: ""; position: absolute;
  top: 2px; left: 2px;
  width: 16px; height: 16px;
  background: #fff; border-radius: 50%;
  transition: transform 0.18s;
}
body.mobile .autoplay-row .autoplay-toggle > input[type="checkbox"]:checked {
  background: #22c55e; border-color: #22c55e;
}
body.mobile .autoplay-row .autoplay-toggle > input[type="checkbox"]:checked::after {
  transform: translateX(16px);
}
body.mobile .autoplay-row .autoplay-n {
  width: 42px; padding: 2px 4px; font-size: 11px;
  background: var(--bg-input); border: 1px solid rgba(255,255,255,0.2);
  border-radius: 6px; color: var(--text); text-align: center;
}
body.mobile .autoplay-row .dice-roll-btn,
body.mobile .autoplay-row .crash-play-btn {
  width: 100% !important;
  padding: 14px 14px !important; font-size: 15px !important;
  min-height: 52px;
  letter-spacing: 0.06em;
}
/* Visual "running" hint when the toggle is on — the whole label glows
   subtly so the player knows Autoplay is active and can tap to stop. */
body.mobile .autoplay-row .autoplay-toggle:has(> input[type="checkbox"]:checked) {
  color: #22c55e;
}

/* Amount group — match Crash's inline layout: the input fills the row
   while ½ / 2× / Max tiles sit to its right as narrow fixed-width chips.
   Keeps the whole amount visible because the chips are tiny, and leaves
   the row compact enough that the rest of the controls stay above the
   fold. Applies to Dice, Coinflip, Roulette, Slots, Mines, Plinko,
   Blackjack (Crash has its own .crash-amount-group with the same shape). */
body.mobile .dice-amount-group {
  /* ½ / 2× / ↻ on the LEFT, amount value on the FAR RIGHT — matches the
     sportsbook-ticket reference. Single row, no wrap. */
  display: flex !important; gap: 6px; align-items: stretch;
  flex-wrap: nowrap !important;
  width: 100%;
}
body.mobile .dice-amount-group .amount-input-wrap {
  order: 2;
  flex: 0 1 auto !important; min-width: 0; width: auto !important; max-width: 100%;
  margin-left: auto;
}
body.mobile .dice-amount-group .dice-quick,
body.mobile .dice-amount-group .dice-repeat-btn { order: 1; }
body.mobile .dice-amount-group .input { flex: 0 1 auto !important; min-width: 0; width: auto !important; }
body.mobile .dice-amount-group .amount-input-wrap .input { flex: 0 0 auto !important; min-width: 4ch !important; width: auto !important; }
body.mobile .dice-amount-group .dice-quick {
  flex: 0 0 auto !important; padding: 0 12px; font-size: 11px;
  min-width: 36px; min-height: 36px;
}
/* ↻ repeat inside the amount group flexes + sizes the same as ½ and 2×
   on mobile (its own default 40×40 fixed box would shrink it on narrow
   phones). */
body.mobile .dice-amount-group .dice-repeat-btn {
  flex: 1 1 0 !important;
  width: auto !important; height: auto !important;
  min-height: 36px;
  font-size: 12px;
}
body.mobile .crash-amount-group .crash-chip { padding: 10px 12px; font-size: 12px; }

/* Roll / play button: sticky on mobile, always reachable */
body.mobile .dice-roll-btn,
body.mobile .crash-play-btn {
  width: 100%; padding: 16px; font-size: 14px; letter-spacing: 0.06em;
}

/* Crash mobile layout */
body.mobile .crash-game { grid-template-columns: 1fr; gap: 8px; }
body.mobile .crash-main { padding: 0; }
body.mobile .crash-stage { min-height: 320px; min-height: 260px; }
body.mobile .crash-multiplier {
  font-size: clamp(44px, 12vw, 72px); position: absolute; top: 38%; left: 50%;
  transform: translate(-50%, -50%); text-align: center; width: 100%;
  line-height: 1; z-index: 3;
  font-weight: 800;
}
body.mobile .crash-status {
  /* Floats over the 3D scene without the dark "band" backdrop — that
     backdrop, combined with the tabs sitting flush below, made the
     status look squeezed between the stage and the bets panel. Now it's
     plain centered text with a subtle shadow for readability. */
  position: absolute; bottom: 18px; left: 0; right: 0; text-align: center;
  font-size: 11px; white-space: normal; padding: 0 10px; z-index: 2;
  background: transparent;
  backdrop-filter: none; -webkit-backdrop-filter: none;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.75);
  font-weight: 600;
}
body.mobile .crash-history {
  padding: 8px 10px; gap: 6px;
  flex-wrap: nowrap; overflow: hidden; align-items: center;
}
body.mobile .crash-pill { flex-shrink: 0; }
/* Crash controls are fixed at bottom (see Fixed Place Bet rule) — we only
   tune the internal grid here so amount + cashout sit on one row, play on
   the next. Do NOT set padding/margin/position here to avoid overriding
   the fixed-bottom placement. */
body.mobile .crash-controls {
  grid-template-columns: 1fr 1fr !important;
  grid-template-areas: "amount cashout" "play play" !important;
  gap: 8px !important;
}
body.mobile .crash-ctrl { margin: 0; min-width: 0; }
body.mobile .crash-ctrl:has(#c-amount) { grid-area: amount; }
body.mobile .crash-ctrl:has(#c-cashout) { grid-area: cashout; }
body.mobile .crash-ctrl.crash-play-cell { grid-area: play; display: flex; flex-direction: column; justify-content: flex-end; gap: 4px; }
body.mobile .crash-autoplay-row { font-size: 10px; flex-wrap: wrap; gap: 4px; }

/* Coin flip: coin centered, sized to viewport */
body.mobile .coin {
  width: clamp(120px, 38vw, 180px); height: clamp(120px, 38vw, 180px);
  font-size: clamp(44px, 14vw, 72px); margin: 0 auto;
}

/* Slots reels — fit 3 reels cleanly into viewport without scroll */
body.mobile .reels { gap: 6px; justify-content: center; width: 100%; }
body.mobile .reel {
  width: clamp(70px, 26vw, 100px); height: clamp(96px, 34vw, 134px);
  font-size: clamp(36px, 12vw, 56px);
}

/* Roulette hot/cold */
body.mobile .hot-cold { flex-direction: column; gap: 6px; padding: 10px; }
body.mobile .hot-cold-row { flex-wrap: wrap; }
body.mobile .hot-cold-nums, body.mobile .hot-cold-recent {
  flex-wrap: nowrap; overflow: hidden;
}
body.mobile .big-result { font-size: clamp(56px, 18vw, 96px); }

/* Mines — aspect-ratio tiles, smaller gap */
body.mobile .mines-stage { min-height: 260px; min-height: 320px; padding: 0; }
body.mobile .mines-grid { max-width: min(340px, 78vw); gap: 4px; margin: 0 auto; }
body.mobile .mines-tile { font-size: clamp(14px, 4.5vw, 22px); border-radius: 6px; border-width: 1px; }

/* Plinko — canvas scales by viewport */
body.mobile .plinko-stage { min-height: 260px; min-height: 320px; padding: 0; }

/* Blackjack — 4-action grid, smaller cards */
body.mobile .blackjack-stage { min-height: 260px; min-height: 320px; padding: 0; gap: 10px; }
body.mobile .bj-hand { min-height: 70px; gap: 4px; flex-wrap: wrap; justify-content: center; }
body.mobile .bj-card {
  width: clamp(42px, 13vw, 60px); height: clamp(60px, 18vw, 86px);
  font-size: clamp(20px, 6vw, 30px);
}
body.mobile .bj-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; width: 100%; }
body.mobile .bj-actions .dice-roll-btn { padding: 12px; font-size: 12px; }

/* Live-feed panel (All Bets / Previous / Top) — grows to fit players, with
   an internal scroll on the bet list so the panel never blows up the layout.
   The outer panel is capped by the `.live-layout > .crash-bets-panel` rule
   above at 40 vh; here we give the inner list the actual scroll region. */
body.mobile .crash-bets-panel {
  /* No horizontal padding — the bets table reaches the screen edges so it
     reads as part of the viewport, not a card with a frame. */
  padding: 8px 0; gap: 6px;
}
body.mobile .crash-bets-list {
  flex: 1 1 auto; min-height: 0; max-height: none;
  overflow-y: auto; overflow-x: hidden; font-size: 11px;
  scrollbar-width: thin; scrollbar-color: #fff transparent;
}
body.mobile .crash-bets-list::-webkit-scrollbar { width: 3px; }
body.mobile .crash-bets-list::-webkit-scrollbar-thumb { background: rgba(124, 58, 237, 0.5); border-radius: 2px; }
body.mobile .crash-bets-header { font-size: clamp(9px, 2.4vw, 10px); gap: 6px; padding: 6px 6px; }
body.mobile .crash-bet-row { gap: 6px; padding: 7px 6px; font-size: clamp(10px, 2.8vw, 12px); }
/* Bets tabs — single-line labels sized to fit. */
body.mobile .crash-bets-tabs { gap: 2px; }
body.mobile .crash-tab {
  padding: 10px 2px;
  font-size: clamp(10px, 2.8vw, 12px);
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
/* Slightly tighter columns on phones. BET column widened so 4-decimal
   amounts + 3-letter coin ticker (e.g. "0.0144 BCH") fit without the
   ticker getting ellipsed mid-letter. */
body.mobile .crash-bet-row,
body.mobile .crash-bets-header { grid-template-columns: 1.05fr 1.15fr 0.75fr 0.6fr 1fr; }
body.mobile .crash-bets-total-val { font-size: 16px; }
body.mobile .crash-bets-footer { flex-shrink: 0; }

/* Autoplay row — compact toggle + tall button */
body.mobile .autoplay-row { gap: 6px; }
body.mobile .autoplay-toggle { font-size: 11px; flex-wrap: wrap; }
/* Inline variant: autoplay becomes an "Auto" label above an iOS-style
   toggle switch, sitting left of the ↻ rebet button on the amount row.
   The numeric count input stays in the DOM (read by JS) but is hidden
   from the inline view for a clean one-glance affordance. */
body.mobile .autoplay-toggle--inline {
  margin: 0 8px 0 2px;
  padding: 2px 6px;
  gap: 4px;
  flex-shrink: 0;
  /* Same typography as the POTENTIAL WIN label — Open Sans UI font,
     weight 700, 12px, uppercase with 0.04em tracking. 12px keeps the
     "AUTO" label from squeezing the chip group on narrow phones. */
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #fff;
  display: flex !important;
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  cursor: pointer;
}
/* Label on top, switch below (checkbox comes first in DOM — flip order). */
body.mobile .autoplay-toggle--inline .autoplay-cb { order: 2; }
body.mobile .autoplay-toggle--inline > span { order: 1; }
/* Hide the count input + "rolls/flips/spins" suffix inside the span. */
body.mobile .autoplay-toggle--inline .autoplay-n { display: none; }
body.mobile .autoplay-toggle--inline > span {
  font: inherit;
  line-height: 1;
}
/* iOS-style toggle: 28x16 pill, 12x12 knob, slides to the right when on. */
body.mobile .autoplay-toggle--inline .autoplay-cb {
  appearance: none; -webkit-appearance: none;
  width: 28px; height: 16px;
  margin: 0; padding: 0;
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid var(--border);
  border-radius: 999px;
  position: relative;
  cursor: pointer;
  transition: background 0.15s;
  flex-shrink: 0;
}
body.mobile .autoplay-toggle--inline .autoplay-cb::before {
  content: "";
  position: absolute;
  top: 1px; left: 1px;
  width: 12px; height: 12px;
  background: #fff;
  border-radius: 50%;
  transition: transform 0.15s;
}
body.mobile .autoplay-toggle--inline .autoplay-cb:checked {
  background: var(--primary, #d91554);
}
body.mobile .autoplay-toggle--inline .autoplay-cb:checked::before {
  transform: translateX(12px);
}

/* Page-level: keep games vertically scrollable but no horizontal overflow */
body.mobile .game-layout, body.mobile .dice-game, body.mobile .crash-main {
  gap: 10px; padding: 0;
}

/* ======== Live-feed layout (shared by dice / coinflip / roulette / slots) ======== */
.live-layout {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 14px;
  max-width: 1400px;
  margin: 0 auto;
  align-items: stretch;
}
.live-layout > .crash-bets-panel { height: calc(100vh - 100px); min-height: 420px; }
@media (max-width: 900px) {
  .live-layout { grid-template-columns: 1fr; }
  /* Responsive panel cap — 60 % of the parent column, so the bets list
     takes a comfortable slice of the available area without overflowing
     or overlapping the game canvas above it. Internal scroll handles
     lists longer than that. */
  .live-layout > .crash-bets-panel { max-height: 60%; order: 2; }
}

/* Autoplay toggle (instant games). Body text colour (not muted) so the
   "Auto N spins" line on the slots / dice / coinflip controls panel
   reads as enabled, not greyed-out. */
.autoplay-toggle {
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--text); cursor: pointer; user-select: none;
  margin: 4px 0;
}
.autoplay-toggle input[type="checkbox"] { width: 14px; height: 14px; accent-color: var(--primary); }
.autoplay-toggle .autoplay-n {
  width: 48px; padding: 3px 5px; background: var(--bg-input);
  border: 1px solid var(--border); color: var(--text); border-radius: 4px;
  font-size: 11px; font-family: inherit;
}
.autoplay-row { display: flex; flex-direction: column; gap: 6px; }

/* ======== Dice game (SpaceDice-style) ======== */
.dice-game { max-width: 680px; width: 100%; margin: 0 auto; display: flex; flex-direction: column; gap: 10px; }

/* Result */
.dice-result-row { text-align: center; }
.dice-result-num { font-size: 64px; font-weight: 900; letter-spacing: -0.03em; color: var(--text-muted); transition: color 0.3s; }
.dice-result-num.win { color: var(--green); }
.dice-result-num.lose { color: var(--red); }
.dice-result-label { font-size: 13px; color: var(--text-muted); margin-top: -4px; }

/* Range bar */
.dice-bar-wrap { position: relative; }
/* Win-chance input inside .dice-stat — sized and styled to match the
   surrounding <strong> stats so the edit affordance reads as a number,
   not a form field. */
.dice-chance-input {
  background: transparent; border: none; color: #fff;
  font: inherit; font-weight: 800; font-size: 16px;
  padding: 0; width: 72px;
  font-variant-numeric: tabular-nums;
  outline: none;
}
.dice-chance-input:focus { outline: 2px solid #fff; outline-offset: 2px; border-radius: 4px; }
.dice-chance-input::-webkit-inner-spin-button,
.dice-chance-input::-webkit-outer-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }
.dice-chance-input { -moz-appearance: textfield; appearance: textfield; }

.dice-bar { position: relative; height: 40px; border-radius: 10px; overflow: hidden; background: var(--bg-input); display: flex; }
.dice-bar-fill { height: 100%; transition: width 0.25s ease; }
.dice-bar-green { background: linear-gradient(90deg, #16a34a 0%, #22c55e 100%); }
.dice-bar-red { background: linear-gradient(90deg, #ef4444 0%, #dc2626 100%); flex: 1; }
.dice-target-line {
  position: absolute; top: 0; bottom: 0; width: 3px;
  background: #fff; border-radius: 2px;
  box-shadow: 0 0 8px rgba(255,255,255,0.6);
  transition: left 0.25s ease;
  z-index: 2;
}
.dice-roll-dot {
  position: absolute; top: 50%; width: 14px; height: 14px;
  background: var(--gold); border: 1px solid var(--border);
  border-radius: 50%; transform: translate(-50%, -50%);
  box-shadow: 0 0 12px var(--gold);
  z-index: 3; transition: left 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.dice-bar-ticks { display: flex; justify-content: space-between; padding: 4px 2px 0; font-size: 10px; color: var(--text-dim); }

/* Slider row */
.dice-slider-row { display: flex; align-items: center; gap: 14px; }
.dice-slider-label { font-size: 13px; color: var(--text-muted); white-space: nowrap; min-width: 130px; }
.dice-slider-label strong { color: #fff; font-size: 18px; margin-left: 6px; }
.dice-range { flex: 1; }

/* Direction toggle — sized to match the Pixi range bar (40px padded each
   side) so IN/OUT feels like part of the same control. */
.dice-dir-row { display: flex; padding: 0 40px; }
/* Roll Under / Roll Over (dice) and Heads / Tails (coinflip) toggle —
   flush rectangular segments inside a single white-bordered container,
   matching the quick-chips and amount-actions look. The active half fills
   with the brand purple, the inactive half is transparent muted text. */
.dice-dir-seg {
  /* Flat, transparent strip — matches the wallet Deposit / Withdraw / Swap
     tab row. No dark plate, no surrounding border, no rounded pill, no
     divider line between segments. The segments stand on the page
     background and signal their state purely via the cherry-pink bottom
     underline on the active one + bumped weight. */
  width: 100%; max-width: none; margin: 0;
  display: flex; gap: 0;
  background: transparent !important;
  border: none !important;
  border-radius: 0;
  overflow: visible;
  padding: 0;
}
.dice-dir-seg .seg {
  flex: 1;
  padding: 14px 12px;
  background: transparent;
  border: none !important;
  border-radius: 0;
  color: var(--text-muted);
  font-family: var(--font-ui);
  font-size: 14px; font-weight: 700; letter-spacing: 0.02em;
  text-align: center;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
/* Inter-segment divider removed — flat tab strip doesn't need a line
   between buttons; the underline alone signals which is selected. */
.dice-dir-seg .seg + .seg { border-left: none !important; }
.dice-dir-seg .seg:hover:not(.active) { color: #fff; background: transparent; }
.dice-dir-seg .seg.active {
  /* Mirrors the wallet Deposit-tab look: transparent body + cherry-pink
     2 px underline. The segmented track keeps its dark plate as the
     surrounding pill; the active segment lets that plate show through
     and signals "selected" only with the bottom border + bumped
     typography weight. Padding-bottom is reduced by the border width
     so active/inactive segments stay the same total height (no jump). */
  background: transparent !important;
  color: #fff;
  font-weight: 800;
  letter-spacing: 0.04em;
  border-bottom: 2px solid #d91554 !important;
  padding-bottom: 12px;
}
.dice-dir-seg .seg .dice-dir-num { color: inherit; font-weight: 800; margin-left: 4px; }

/* Bet controls */
.dice-bet-row { display: flex; gap: 12px; }
.dice-field { display: flex; flex-direction: column; gap: 5px; flex: 1; }
.dice-field label { font-size: 10px; font-weight: 600; letter-spacing: 0.1em; color: var(--text-muted); text-transform: uppercase; }
.dice-field-amount { flex: 2; }
.dice-amount-group { display: flex; gap: 4px; align-items: center; }
.dice-amount-group .input { flex: 0 1 auto; min-width: 0; }
.dice-amount-group .amount-input-wrap { flex: 0 1 auto; }

/* Amount input — coin icon on the left, "Amount" label stacked above the
   numeric input on the right. The raw <input> is wrapped by JS so every game
   (dice, coinflip, crash, plinko, mines, roulette, slots, blackjack) shares
   the same pill. */
.amount-input-wrap {
  /* inline-flex + fit-content width so the pill always hugs its own content
     (coin icon + amount value + chips). Works uniformly regardless of
     whether the wrap sits inside a flex amount-group (dice, coinflip,
     crash) or a plain block field (roulette, slots, mines, plinko, bj). */
  display: inline-flex; align-items: flex-end;
  width: fit-content; max-width: 100%;
  gap: 6px;
  min-width: 0;
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 8px 10px;
}

/* Session ticker ("Session: +0.000 BTC · N rolls · X% win") — hidden across
   every game on mobile and desktop; the player preferred a cleaner panel
   without the running-session strip. */
.dice-session { display: none !important; }

/* Hide the whole bordered summary card at the top of every game's All
   Bets panel (amount + avatars + "N Bets" + "Total win" label). The
   table rows below carry all the information. */
.crash-bets-total { display: none !important; }

/* Visible target slider + Roll Under/Over toggle + inline condition line. */
.dice-target-row {
  display: flex; flex-direction: column; gap: 6px;
  padding: 8px 0;
}
.dice-target-slider {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 10px;
  /* Two-tone track: green fills the winning range (under N or over N
     depending on the toggle); grey fills the losing range. The split
     point is driven by --fill-start / --fill-end set in updateDiceBar. */
  background: linear-gradient(to right,
    rgba(255,255,255,0.12) 0%,
    rgba(255,255,255,0.12) var(--fill-start, 0%),
    #22c55e var(--fill-start, 0%),
    #22c55e var(--fill-end, 50%),
    rgba(255,255,255,0.12) var(--fill-end, 50%),
    rgba(255,255,255,0.12) 100%);
  border-radius: 999px;
  outline: none;
}
.dice-target-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 22px; height: 22px; border-radius: 50%;
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.25);
  cursor: pointer;
}
.dice-target-slider::-moz-range-thumb {
  width: 22px; height: 22px; border-radius: 50%;
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.25);
  cursor: pointer;
}
.dice-target-ticks {
  display: flex; justify-content: space-between;
  font-size: 10px; color: var(--text-muted); font-variant-numeric: tabular-nums;
  padding: 0;
}
.dice-condition {
  display: flex; justify-content: center; align-items: baseline;
  gap: 8px;
  padding: 4px 12px;
  font-size: 13px; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.dice-condition strong { color: #fff; font-weight: 800; letter-spacing: 0.02em; }
.dice-condition .sep { color: var(--text-dim); }
/* The "Roll under X" portion of this line duplicates the toggle + PLACE
   BET label. Hide the whole line — the slider ticks, the toggle numbers
   and the button already convey the same info. */
.dice-condition { display: none !important; }
/* Inline condition replaces the three-card stats row on dice. */
body.mobile #page-dice .dice-stats-row { display: none !important; }
/* Dice slider header: Multiplier / Chance to win labels with their
   values stacked below. Sits just above the slider on mobile. */
body.mobile .dice-dir-seg .seg .dice-dir-num { display: none !important; }
.dice-slider-stats {
  /* Overlay chips at the BOTTOM corners of the dice canvas — moved
     here from the sticky-controls panel to give the 3D scene back
     ~70-90px of vertical real estate. The top row of the canvas is
     reserved for the recent-history pill strip, so stats live below
     to avoid horizontal collision. Each .dice-slider-stat positions
     absolutely (see .dice-slider-stat-left / .dice-slider-stat-right). */
  position: absolute; bottom: 8px; left: 0; right: 0;
  z-index: 11;
  pointer-events: none;
  font-family: var(--font-ui);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.dice-slider-stat {
  position: absolute;
  bottom: 0;
  display: flex; flex-direction: column;
  gap: 2px;
  padding: 8px 14px;
  /* Match the PLACE BET / .btn-primary surface — translucent red gradient
     over a dark navy plate with a subtle white border. The previous
     2 px solid hot-pink rim read as a cheap separate-button family;
     bringing it onto the place-bet surface unifies the in-game CTA
     language across actions (PLACE BET) and stats (MULTIPLIER, CHANCE). */
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border);
  border-radius: 4px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  pointer-events: auto;
  box-shadow: 0 3px 0 0 rgba(50, 3, 18, 0.55);
}
.dice-slider-stat-left  { left: 8px; align-items: flex-start; text-align: left; }
.dice-slider-stat-right { right: 8px; align-items: flex-end;  text-align: right; }
/* Scoped under .dice-canvas-wrap to beat the body.mobile
   .dice-slider-label rule that sets white-space: normal — the chips
   need a single line at small font for the overlay to look tidy. */
.dice-canvas-wrap .dice-slider-label {
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  line-height: 1;
  white-space: nowrap;
}
/* Hero stat values — bump to 20-22px Inter Heavy with tabular-nums and
   semantic colour: brand pink for the multiplier (signals risk/reward),
   green for the win chance (signals favourable odds). Same hero-money
   typography family as PLACE BET's Total Bet / Potential Win values
   so the whole game canvas reads consistently. */
.dice-canvas-wrap .dice-slider-stats strong {
  font-family: var(--font-ui);
  color: #fff;
  font-weight: 800;
  font-size: clamp(18px, 5vw, 22px);
  letter-spacing: -0.01em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}
.dice-canvas-wrap .dice-slider-stat-left strong  { color: #ff2e5e; }
.dice-canvas-wrap .dice-slider-stat-right strong { color: #00d68f; }
.amount-input-wrap > .amount-body {
  display: flex; flex-direction: column;
  gap: 8px;
  /* Hug content width so the ½ / 2× / ↻ stack sits flush next to the amount
     value — no big empty space between them. */
  flex: 0 1 auto; min-width: 0;
}
.amount-input-wrap .amount-prefix-label {
  color: var(--text-muted);
  font-family: var(--font-ui);
  font-size: 12px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  line-height: 1.1;
}
/* Icon + digits sit in a rounded pill with a soft translucent background
   by default. On focus the border switches to gold (see :focus-within). */
.amount-input-row {
  display: inline-flex; align-items: center;
  gap: 6px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 4px 10px;
  width: max-content;
  max-width: 100%;
  flex-shrink: 0;
  font-size: 17px;
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
}
body.mobile .amount-input-row {
  font-size: 14px;
  /* Match the chip row height so the two pills align perfectly. */
  min-height: 40px; height: 40px;
  padding: 0 14px !important;
}
/* Mobile amount-pill: chips (½ / 2× / ↻) on the LEFT, coin icon + amount
   on the FAR RIGHT — matches the sportsbook ticket reference. */
body.mobile .amount-input-row {
  width: 100% !important;
  justify-content: flex-start;
}
body.mobile .amount-input-row > .amount-actions { order: 1; margin-right: auto; }
body.mobile .amount-input-row > .amount-prefix { order: 2; }
body.mobile .amount-input-row > .input {
  order: 3;
  text-align: center !important;
}
/* Two-pill layout on mobile — chips pill on the LEFT, coin icon + amount
   pill on the RIGHT, side by side. The JS wraps them both in an
   `.amount-row2` flex container. */
/* Outer flex row wraps the AUTO toggle (left) and the unified chips +
   amount pill (right). AUTO lives outside the pill so no border is
   shared — the pill visually reads as a single segmented control. */
body.mobile .amount-row-outer {
  display: flex; align-items: stretch; gap: 0; width: 100%;
}
body.mobile .amount-row-outer > .amount-row2 { flex: 1 1 auto; min-width: 0; }
body.mobile .amount-row2 {
  /* Matches `.quick-chips-row` — one unified dark-navy pill with a
     single outer border and white vertical dividers between cells. */
  display: flex !important; align-items: stretch; gap: 0;
  width: 100%;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
body.mobile .amount-row2 > .autoplay-toggle--inline {
  /* AUTO toggle stays outside the unified pill visually — no seam with
     the chip group or amount pill. Reset any inherited backgrounds. */
  background: transparent !important;
  border: none !important;
}
body.mobile .amount-row2 > .amount-actions {
  order: 1;
  display: grid !important;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 0;
  background: transparent !important;
  border: none !important;
  border-right: 1px solid rgba(255, 255, 255, 0.35) !important;
  border-radius: 0 !important;
  overflow: visible;
}
body.mobile .amount-row2 > .amount-input-row {
  order: 2;
  margin-left: 0;
  /* Flex-grow so the amount pill takes whatever room remains after
     the chip cells — long crypto values have room to read. */
  flex: 1 1 auto;
  min-width: 0;
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
}
.amount-prefix-label { display: none !important; }
body.mobile .amount-row2 > .amount-actions > .dice-quick,
body.mobile .amount-row2 > .amount-actions > .crash-chip {
  /* Unified chip sizing across every game — same width, same height,
     same padding, same typography. Uses !important to beat per-game
     mobile overrides (crash-chip vs dice-quick used to differ). */
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  min-width: 40px !important;
  width: 40px !important;
  height: 40px !important;
  min-height: 40px !important;
  display: inline-flex !important;
  align-items: center; justify-content: center;
  font: 700 13px inherit !important;
  letter-spacing: 0.02em !important;
  color: var(--text-muted);
  flex: 0 0 auto !important;
}
body.mobile .amount-row2 > .amount-actions > .dice-quick + .dice-quick,
body.mobile .amount-row2 > .amount-actions > .crash-chip + .crash-chip,
body.mobile .amount-row2 > .amount-actions > .dice-quick + .crash-chip,
body.mobile .amount-row2 > .amount-actions > .crash-chip + .dice-quick {
  border-left: 1px solid rgba(255, 255, 255, 0.35) !important;
}
body.mobile .amount-row2 > .amount-actions > .dice-quick:hover:not(:disabled),
body.mobile .amount-row2 > .amount-actions > .crash-chip:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.12) !important;
  color: #fff;
}
.amount-input-row > .amount-prefix {
  pointer-events: none;
}
.amount-input-row > .amount-prefix .coin-icon { width: 1em; height: 1em; }
.amount-input-wrap .input,
.amount-input-wrap > .amount-body > .input,
.amount-input-wrap > .input {
  border: none !important;
  background: transparent !important;
  border-radius: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  min-height: 0 !important;
  font-size: 17px !important;
  font-weight: 700;
  color: var(--text) !important;
  box-shadow: none !important;
  outline: none !important;
  text-indent: 0 !important;
  -webkit-appearance: none; appearance: none;
  /* Auto-size the input box to the actual value length. */
  field-sizing: content;
  flex: 0 0 auto !important;
  width: auto !important;
  min-width: 4ch;
  max-width: 14ch;
}
.amount-input-wrap .amount-prefix-label,
.amount-input-wrap > .amount-body > .input {
  padding-left: 0 !important;
  margin-left: 0 !important;
}
.amount-input-wrap .input:hover,
.amount-input-wrap .input:focus,
.amount-input-wrap > .amount-body > .input:hover,
.amount-input-wrap > .input:hover,
.amount-input-wrap > .amount-body > .input:focus,
.amount-input-wrap > .input:focus {
  border: none !important;
  background: transparent !important;
  box-shadow: none !important;
  outline: none !important;
}
.amount-input-row:focus-within {
  /* Gold focus ring removed per user request — input stays visually
     flat on tap, letting the unified chips+amount pill read cleanly. */
  border-color: var(--border);
  background: transparent;
  box-shadow: none;
}
.amount-prefix {
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.amount-prefix .coin-icon { width: 26px; height: 26px; }
.amount-prefix .coin-ring { padding: 0 !important; background: transparent !important; }
body.mobile .amount-input-wrap { padding: 0; gap: 8px; }
body.mobile .amount-prefix .coin-icon { width: 24px; height: 24px; }
body.mobile .amount-input-wrap > .input { font-size: 16px !important; }

/* ½ / 2× / ↻ chip-buttons stuck flush to the right end of the amount pill.
   No individual borders or rounded corners — just a thin vertical divider
   between each button, matching the inline-attached look. */
.amount-actions {
  display: flex; flex-direction: row;
  flex-shrink: 0; align-self: stretch;
  gap: 0;
  margin: -4px -10px -4px 0;
  border-left: 1px solid rgba(255,255,255,0.35);
}
body.mobile .amount-actions { margin: -4px -10px -4px 0; }
.amount-actions > button {
  flex: 0 0 auto;
  min-width: 40px;
  padding: 0 12px !important;
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  color: var(--text) !important;
  font: 700 13px inherit !important; letter-spacing: 0.02em !important;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 0.15s, color 0.15s;
}
.amount-actions > button + button { border-left: 1px solid rgba(255,255,255,0.35) !important; }
.amount-actions > button:hover:not(:disabled) {
  color: #fff !important;
  background: rgba(255, 255, 255, 0.12) !important;
}
.amount-actions > button:active { transform: translateY(1px); }
.amount-actions > button:disabled { opacity: 0.35; cursor: not-allowed; }
.amount-actions > button:last-child { border-top-right-radius: 8px; border-bottom-right-radius: 8px; }
/* Override the dice-repeat-btn fixed 40×40 when it lives in the stack. */
.amount-actions > .dice-repeat-btn {
  width: auto !important; height: auto !important;
}
/* .dice-quick shares the chip skin above — extra sizing lives here. */
.dice-quick { padding: 8px 12px; font-size: 12px; }

/* Stats row — compact one-line bar */
.dice-stats-row {
  display: flex; gap: 6px;
  padding: 6px 10px;
  background: rgba(36, 21, 71, 0.55);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  flex-wrap: wrap;  /* Profit on win cell wraps below on narrow widths. */
}
.dice-stat {
  flex: 1 1 120px; min-width: 0;
  padding: 4px 8px; background: transparent; border: none; border-radius: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  text-align: center;
}
.dice-stat + .dice-stat { border-left: 1px solid var(--border); }
.dice-stat .muted { font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); font-weight: 700; }
.dice-stat strong {
  font-size: 13px; color: #fff; font-variant-numeric: tabular-nums; font-weight: 800;
  /* Let long profit values shrink/wrap cleanly instead of blowing the row. */
  max-width: 100%; overflow-wrap: anywhere;
}
.dice-stat-fiat {
  display: block; font-size: 10px; color: var(--text-dim); margin-left: 0;
  margin-top: 1px; white-space: nowrap;
}

/* Roll button */
.dice-roll-btn { width: 100%; padding: 18px; font-size: 16px; letter-spacing: 0.08em; }
/* Provably-Fair Save / Rotate buttons share the canonical primary CTA look
   (PLACE BET / DEAL) — a clearly red-pink rim over the translucent
   navy plate, so they read as the same class of action. Affiliate-code
   Copy + Add custom code buttons get the same treatment. */
#fair-save-client,
#fair-rotate,
#aff-code-add,
.aff-code-copy-one {
  border-color: #d91554;
}
.dice-roll-btn svg { transition: transform 0.15s; }
.dice-roll-btn.rolling { animation: dice-btn-press 0.6s ease; }
.dice-roll-btn.rolling svg { animation: dice-icon-spin 0.6s cubic-bezier(0.25, 1.4, 0.5, 1); }
@keyframes dice-btn-press {
  0%   { transform: translateY(0) scale(1); }
  20%  { transform: translateY(3px) scale(0.97); }
  55%  { transform: translateY(-2px) scale(1.02); }
  100% { transform: translateY(0) scale(1); }
}
@keyframes dice-icon-spin {
  0%   { transform: rotate(0) scale(1); }
  50%  { transform: rotate(360deg) scale(1.25); }
  100% { transform: rotate(720deg) scale(1); }
}

.dice-dir-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.dice-target-btns { display: flex; gap: 4px; }

/* Dice canvas — background matched to the 3D scene's eventual look (dark
   navy backdrop fading to dark green felt at the bottom). Without this
   match the player sees a violet→green "flash" on the first mount while
   three.js loads. After mount the canvas covers everything anyway, but
   those first ~150 ms shouldn't strobe. */
.dice-canvas-wrap {
  position: relative;
  width: 100%;
  height: 272px;
  /* Tones matched to the 3D dome backdrop (top: dome cap, bottom: felt) so
     the brief CSS-visible window before WebGL renders the first frame does
     not flash a different colour at the player. */
  background: linear-gradient(180deg, #08170e 0%, #082f17 100%);
  border: none;
  border-radius: var(--r-lg);
  overflow: hidden;
}
/* Target + Win-chance readout — pinned to the top-right corner of the canvas
   so it doesn't fight the LED digits for the centre of attention. */
.dice-canvas-wrap .dice-readout {
  position: absolute; top: 12px; right: 14px; z-index: 4;
  display: flex; gap: 18px;
  pointer-events: none;
}
.dice-readout-col { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.dice-readout-label {
  font-size: 9px; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--text-muted);
}
.dice-readout-col strong {
  font-size: 15px; font-weight: 800; color: #fff;
  font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
}
/* Redundant with the LED digits; hide the old pill under the bar. */
.dice-canvas-wrap .dice-result-label { display: none; }
.dice-canvas-wrap canvas { display: block; width: 100%; height: 100%; }
.dice-canvas-wrap .dice-result-label {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  padding: 6px 14px;
  text-align: center;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #fff;
  background: rgba(15, 8, 36, 0.7);
  border: 1px solid rgba(255, 184, 0, 0.35);
  border-radius: 999px;
  backdrop-filter: blur(4px);
  pointer-events: none;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
  white-space: nowrap;
}
.result-win { color: var(--green) !important; border-color: rgba(34, 197, 94, 0.55) !important; background: rgba(22, 74, 45, 0.55) !important; }
.result-lose { color: var(--red) !important; border-color: rgba(239, 68, 68, 0.55) !important; background: rgba(74, 22, 22, 0.55) !important; }
.result-neutral { color: var(--text-muted) !important; border-color: var(--border) !important; }

/* Slider overlaid on the Pixi range bar (55% down, padded 40px each side) */
.dice-overlay-slider {
  position: absolute;
  left: 40px;
  right: 40px;
  top: 55%;
  transform: translateY(-50%);
  -webkit-appearance: none;
  appearance: none;
  height: 32px;
  background: transparent;
  cursor: pointer;
  z-index: 10;
  margin: 0;
  padding: 0;
}
.dice-overlay-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 30px;
  height: 30px;
  background: #fff;
  border-radius: 50%;
  border: 1px solid var(--border);
  box-shadow:
    0 0 12px rgba(255,255,255,0.6),
    0 0 0 0 rgba(168, 85, 247, 0.45),
    0 2px 6px rgba(0,0,0,0.4);
  cursor: grab;
  animation: dice-thumb-pulse 1.8s ease-in-out infinite;
}
.dice-overlay-slider:active::-webkit-slider-thumb,
.dice-overlay-slider:focus::-webkit-slider-thumb { animation: none; cursor: grabbing; }
.dice-overlay-slider::-moz-range-thumb {
  width: 30px;
  height: 30px;
  background: #fff;
  border-radius: 50%;
  border: 1px solid var(--border);
  box-shadow: 0 0 12px rgba(255,255,255,0.6), 0 2px 6px rgba(0,0,0,0.4);
  cursor: grab;
  animation: dice-thumb-pulse 1.8s ease-in-out infinite;
}
@keyframes dice-thumb-pulse {
  0%, 100% {
    box-shadow:
      0 0 12px rgba(255,255,255,0.6),
      0 0 0 0 rgba(168, 85, 247, 0.55),
      0 2px 6px rgba(0,0,0,0.4);
  }
  50% {
    box-shadow:
      0 0 16px rgba(255,255,255,0.85),
      0 0 0 10px rgba(168, 85, 247, 0),
      0 2px 6px rgba(0,0,0,0.4);
  }
}
/* Dashed vertical guide from just below the slider thumb down to the
   range bar, with an arrowhead pointing at the bar. No upward segment. */
.dice-thumb-guide {
  position: absolute;
  left: var(--guide-left, 50%);
  top: calc(55% + 18px);
  bottom: 14%;
  width: 2px;
  transform: translateX(-50%);
  background: repeating-linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.9) 0 6px,
    transparent 6px 12px
  );
  pointer-events: none;
  z-index: 4;
  transition: left 0.05s linear;
}
.dice-thumb-guide::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -2px;
  transform: translateX(-50%);
  width: 0; height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 7px solid rgba(255, 255, 255, 0.9);
}

/* Swipe hint — placed just above the slider thumb so it's close to the
   interaction point but doesn't overlap the thumb or the downward guide. */
.dice-swipe-hint {
  position: absolute;
  top: calc(55% - 30px);
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 6px;
  color: rgba(255, 255, 255, 0.55);
  font-size: 16px; font-weight: 700;
  pointer-events: none;
  z-index: 11;
}
.dice-swipe-arrow {
  display: inline-block; line-height: 1;
  animation: dice-arrow-slide 1.8s ease-in-out infinite;
}
.dice-swipe-arrow-l { animation-delay: 0s; }
.dice-swipe-arrow-m { animation-delay: 0.15s; font-size: 12px; opacity: 0.7; }
.dice-swipe-arrow-r { animation-delay: 0.3s; }
@keyframes dice-arrow-slide {
  0%, 100% { transform: translateX(0); opacity: 0.35; }
  50%      { transform: translateX(0); opacity: 0.9; }
}
.dice-swipe-arrow-l { animation-name: dice-arrow-slide-l; }
.dice-swipe-arrow-r { animation-name: dice-arrow-slide-r; }
@keyframes dice-arrow-slide-l {
  0%, 100% { transform: translateX(0);   opacity: 0.35; }
  50%      { transform: translateX(-4px); opacity: 0.9; }
}
@keyframes dice-arrow-slide-r {
  0%, 100% { transform: translateX(0);   opacity: 0.35; }
  50%      { transform: translateX(4px);  opacity: 0.9; }
}
.dice-canvas-wrap.touched .dice-swipe-hint { display: none; }
/* Silence the thumb pulse after the first drag — attention-getter while
   the slider is still "fresh", then stays still. */
.dice-canvas-wrap.touched .dice-overlay-slider::-webkit-slider-thumb { animation: none; }
.dice-canvas-wrap.touched .dice-overlay-slider::-moz-range-thumb     { animation: none; }
.dice-overlay-slider::-webkit-slider-runnable-track { background: transparent; }
.dice-overlay-slider::-moz-range-track { background: transparent; }

.dice-target-label {
  position: absolute;
  top: 10px;
  right: 14px;
  font-size: 12px;
  color: var(--text-muted);
  pointer-events: none;
  z-index: 5;
}
.dice-target-label strong { color: #fff; font-size: 16px; margin-left: 4px; }

/* Dice responsive */
@media (max-width: 600px) {
  .dice-game { gap: 12px; }
  .dice-canvas-wrap { min-height: 260px; }
  .dice-bet-row { flex-direction: column; }
  .dice-stats-row { flex-direction: column; }
  .dice-dir-row { flex-direction: column; gap: 8px; }
  .dice-roll-btn { padding: 14px; font-size: 14px; }
  .dice-overlay-slider { left: 20px; right: 20px; }
  .dice-target-label strong { font-size: 14px; }
}

/* ======== Crash (Aviator-style) ======== */
.crash-game {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 14px;
  max-width: 1400px;
  margin: 0 auto;
  height: calc(100vh - 80px);
  min-height: 0;
}

.crash-bets-panel {
  display: flex; flex-direction: column;
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 10px;
  gap: 8px;
  overflow: hidden;
}
.crash-bets-tabs { display: flex; gap: 6px; background: transparent; border: none; border-radius: 0; padding: 0; }
.crash-tab {
  flex: 1; padding: 12px 10px; background: transparent;
  border: none; border-bottom: 2px solid transparent; margin-bottom: -1px;
  color: var(--text-muted); font-family: inherit; font-size: 12px; font-weight: 700;
  letter-spacing: 0.1em; cursor: pointer; transition: 0.15s;
}
.crash-tab:hover { color: var(--text); }
/* Cherry-pink underline — same family as the dice direction tabs and the
   wallet Deposit / Withdraw / Swap tab row. White underline read as
   neutral chrome; the brand colour signals "active" more clearly. */
.crash-tab.active { color: #fff; border-bottom-color: #d91554; background: transparent; }

.crash-bets-total {
  background: transparent;
  border: none;
  border-radius: 0; padding: 10px 12px; display: flex; flex-direction: column; gap: 6px;
}
.crash-bets-total-head { display: flex; justify-content: space-between; align-items: center; }
.crash-bets-avatars { display: flex; }
.crash-bets-avatars .av {
  width: 24px; height: 24px; border-radius: 50%; border: 2px solid var(--bg-card-solid);
  margin-left: -6px; display: inline-flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 700; color: #fff;
}
.crash-bets-avatars .av:first-child { margin-left: 0; }
.crash-bets-total-val { color: #fff; font-weight: 800; font-size: 16px; font-variant-numeric: tabular-nums; }
.crash-bets-stats { display: flex; justify-content: space-between; font-size: 10px; color: var(--text-muted); letter-spacing: 0.04em; }
.crash-bets-stats strong { color: #fff; font-weight: 700; }

.crash-bets-header {
  display: grid; grid-template-columns: 1.3fr 0.9fr 0.9fr 0.6fr 1fr; gap: 4px;
  padding: 6px 10px; font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-dim); border: none;
  font-weight: 700;
  text-align: center;
}
.crash-bets-list {
  flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 5px;
  scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent;
}
.crash-bets-list::-webkit-scrollbar { width: 4px; }
.crash-bets-list::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 4px; }
.crash-bet-row {
  display: grid; grid-template-columns: 1.3fr 0.9fr 0.9fr 0.85fr 1fr; gap: 4px;
  padding: 10px 10px; background: transparent;
  /* Faint hairline below each row so consecutive bets from the same player
     within the same second still read as two separate entries instead of
     visually merging. Last row's hairline is removed below. */
  border: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 0;
  font-size: 11px; align-items: center; font-variant-numeric: tabular-nums;
}
.crash-bets-list > .crash-bet-row:last-child { border-bottom: none; }
/* Prevent column content from bleeding into the next column on narrow
   mobile widths — without min-width:0 + overflow clamp, the X column ("10.00×")
   visually overlaps the WIN column ("0.06000 SOL"). */
.crash-bet-row > *,
.crash-bets-header > * {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* X column shows compact multipliers ("1.22×", "10.50×") — never truncate
   them. Drop ellipsis and let the column own enough fr-share above. */
.crash-bet-row > .x,
.crash-bets-header > .x { text-overflow: clip; }
/* Right-align the X (multiplier) and Win columns — both header labels and
   data cells — so the numbers flush to the right edge of each column
   instead of sitting centred inside their grid cell. */
.crash-bet-row > .x,
.crash-bet-row .win-v { text-align: right; }
.crash-bets-header > :nth-child(4),
.crash-bets-header > :nth-child(5) { text-align: right; }
/* BET header aligns left so the label sits over the start of the bet
   amount (icon + number), which begins at the column's left edge. */
.crash-bets-header > :nth-child(2) { text-align: left; }
.crash-bet-row.won { background: transparent; border: none; }
.crash-bet-player { display: flex; align-items: center; gap: 7px; color: var(--text); min-width: 0; }
.crash-bet-player .av { width: 20px; height: 20px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 9px; font-weight: 700; color: #fff; flex-shrink: 0; }
.crash-bet-player .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crash-bet-row .bet { color: var(--text-muted); }
.crash-bet-row .x { color: var(--text-muted); font-weight: 700; }
.crash-bet-row.won .x { color: var(--green); }
.crash-bet-row .win-v { color: var(--text-muted); }
.crash-bet-row.won .win-v { color: var(--green); font-weight: 700; }

.crash-bets-footer { padding-top: 6px; border-top: 1px solid var(--border); display: flex; justify-content: center; }
.crash-fair-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; background: rgba(15, 8, 36, 0.6); border: 1px solid var(--border);
  border-radius: 6px; color: var(--text-muted); font-weight: 600; font-size: 10px;
  font-family: inherit; cursor: pointer; transition: 0.15s;
}
.crash-fair-badge:hover { color: var(--text); border-color: var(--border); }
.crash-fair-badge svg { stroke: currentColor; }

.crash-main { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

.crash-history {
  /* Floats over the game stage — positioned absolute inside .crash-main
     (which is set position:relative below). No rectangular frame, no
     background: the coloured pills just overlay the canvas. Centered, no
     scrolling, and trailing pills that would be half-clipped are trimmed
     by renderHistory() so the strip always reads tidily. */
  position: absolute; top: 8px; left: 0; right: 0; z-index: 10;
  display: flex; gap: 6px; padding: 0 12px;
  justify-content: center;
  background: transparent; border: none; border-radius: 0;
  overflow: hidden;
  scrollbar-width: none;
  pointer-events: none;
}
.crash-main { position: relative; }
.crash-history > .crash-pill { pointer-events: auto; }
.crash-history::-webkit-scrollbar { display: none; }
/* Hidden while the rocket is in the air — keeps the cockpit clean during
   FLYING, comes back the moment the round crashes or the next betting
   window opens. Toggled by the render loop in app.js. Fades rather than
   hard-cuts so the strip swap doesn't feel jarring. */
.crash-history.hide-during-flight {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease-out;
}
.crash-pill {
  padding: 5px 12px;
  background: transparent;
  border-radius: 999px;
  font-size: 12px; font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums;
  border: none;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
}
/* Latest multiplier — visible mark: solid white border + opaque dark
   plate (so it reads against any backdrop), white text. The background
   colour can also be supplied per-multiplier via inline style on the
   element if the JS wants the tier colour to fill the pill — that
   overrides the dark fallback automatically because inline beats the
   stylesheet. */
.crash-history > .crash-pill.latest,
.crash-pill.latest,
div.crash-pill.latest {
  background-color: #ff2e5e !important;
  background-image: none !important;
  border: 2px solid #ffffff !important;
  color: #ffffff !important;
  text-shadow: none !important;
  padding: 4px 12px !important;
  font-weight: 800 !important;
}

.crash-stage {
  position: relative; flex: 1; min-height: 256px;
  /* Match the 3D scene's deep-space backdrop so the surface doesn't flash
     a bright purple gradient while three.js loads. Once the renderer has
     its first frame, the canvas covers this. */
  background:
    radial-gradient(ellipse at 25% 80%, rgba(120, 80, 180, 0.10), transparent 60%),
    linear-gradient(180deg, #03050d 0%, #0a1326 100%);
  border-radius: 24px;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.crash-stage canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
/* Multiplier overlay hidden — the 3D scene + status readout handle the
   value. The status element below grows into a big readout while flying. */
.crash-multiplier { display: none !important; }
.crash-multiplier .crash-x { font-size: 0.65em; margin-left: 4px; opacity: 0.85; }
.crash-multiplier.flying { color: #fff; }
.crash-multiplier.cashed { color: var(--green); animation: crash-pop 0.4s ease; }
.crash-multiplier.crashed { color: var(--red); animation: crash-fade 0.5s ease; }
@keyframes crash-pop { 0%,100% { transform: scale(1); } 40% { transform: scale(1.15); } }
/* Super calm crash state — opacity-only fade, no transform (so the mobile
   translate(-50%, -50%) positioning is preserved). */
@keyframes crash-fade {
  0%   { opacity: 0.3; }
  100% { opacity: 1; }
}
.crash-status {
  position: absolute; bottom: 10%; left: 0; right: 0; text-align: center;
  color: var(--text-muted); font-size: 13px; font-weight: 600; z-index: 1;
  pointer-events: none;
}
.crash-status.win { color: var(--green); }
.crash-status.lose { color: var(--red); }
/* While the round is flying, the status text takes over as the BIG readout
   — kept at its default bottom position, just much larger. The "FLYING"
   label and "@ X.XX×" multiplier are split into two spans pinned to the
   left and right edges so the rocket stays visible between them. */
.crash-stage > .crash-status.flying {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 16px;
  box-sizing: border-box;
  font-family: var(--font-ui), 'Open Sans', sans-serif;
  font-size: clamp(40px, 6.5vw, 76px);
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: #fff;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.70), 0 0 28px rgba(0, 0, 0, 0.45);
  /* Text stays anchored at the bottom — no rise-with-rocket animation
     (player didn't want the text to "descend from the sky" between
     rounds). */
}
.crash-stage > .crash-status.flying .status-l { text-align: left; }
.crash-stage > .crash-status.flying .status-r { text-align: right; }
body.mobile .crash-stage > .crash-status.flying {
  font-size: clamp(36px, 10vw, 60px);
  padding: 0 24px;
}

.crash-controls {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-areas:
    "amount autocash"
    "play play";
  gap: 10px 16px;
  align-items: end;
  padding: 14px; background: rgba(36, 21, 71, 0.7);
  border: 1px solid var(--border); border-radius: var(--r-lg);
}
.crash-ctrl:has(#c-amount) { grid-area: amount; }
.crash-ctrl:has(#c-cashout) { grid-area: autocash; }
.crash-ctrl.crash-play-cell { grid-area: play; }
.crash-amount-group { display: flex; gap: 4px; }
.crash-amount-group .input { flex: 1; min-width: 0; }
/* .crash-chip shares the chip skin — extra sizing here. */
.crash-chip { padding: 0 10px; min-width: 34px; font-size: 12px; }
.crash-chip:hover { color: var(--text); border-color: var(--border); background: rgba(36,21,71,0.9); }
.crash-play-cell { display: flex; flex-direction: column; gap: 6px; }
.crash-autoplay-row { display: flex; align-items: center; gap: 6px; font-size: 10px; color: var(--text-muted); cursor: pointer; user-select: none; }
.crash-autoplay-row input[type="checkbox"] { width: 14px; height: 14px; accent-color: var(--primary); }
.crash-autoplay-n { width: 46px; padding: 2px 4px; background: var(--bg-input); border: 1px solid var(--border); color: var(--text); border-radius: 4px; font-size: 11px; font-family: inherit; }
.crash-play-btn.pulsing { animation: crash-play-pulse 1.1s ease-in-out infinite; }
@keyframes crash-play-pulse {
  0%,100% { box-shadow: 0 3px 0 0 rgba(140,10,45,0.8), 0 0 0 0 rgba(255,46,94,0.5); }
  50%     { box-shadow: 0 3px 0 0 rgba(140,10,45,0.8), 0 0 0 10px rgba(255,46,94,0); }
}

/* Streak ribbon in the stage corner — plain text, no background. */
.crash-streak {
  position: absolute; top: 14px; left: 14px; z-index: 3;
  padding: 0; border: none; background: transparent; box-shadow: none;
  font-family: var(--font-ui);
  font-size: 12px; font-weight: 700; letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: #fff;
  animation: streak-pop 0.4s ease;
}
@keyframes streak-pop { 0% { transform: scale(0.6); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }

/* Win flash overlay (full-stage green flash) */
.crash-flash {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(34,197,94,0.4), transparent 60%);
  opacity: 0;
}
.crash-flash.play { animation: crash-flash-anim 0.9s ease-out; }
@keyframes crash-flash-anim {
  0%   { opacity: 0; }
  12%  { opacity: 1; }
  100% { opacity: 0; }
}

/* Chip-fly celebration — emoji chips arcing outward from the multiplier */
.crash-chip-fly {
  position: absolute; z-index: 4; pointer-events: none;
  font-size: 22px; font-weight: 900; color: var(--green);
  text-shadow: 0 0 14px rgba(34,197,94,0.8);
  animation: chip-fly 1.2s ease-out forwards;
}
@keyframes chip-fly {
  0%   { transform: translate(0,0) scale(0.6); opacity: 0; }
  18%  { transform: translate(var(--fx-mid, 0), calc(var(--fy-mid, 0) * 1px)) scale(1.2); opacity: 1; }
  100% { transform: translate(var(--fx-end, 0), calc(var(--fy-end, 0) * 1px)) scale(0.9); opacity: 0; }
}

/* Near-miss "could have won" strip below the status */
.crash-nearmiss {
  position: absolute; bottom: 40px; left: 0; right: 0; text-align: center;
  color: #fff; font-size: 12px; font-weight: 700; z-index: 1;
  pointer-events: none; opacity: 0; transition: opacity 0.3s;
}
.crash-nearmiss.show { opacity: 1; }
.crash-ctrl { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.crash-ctrl label { font-size: 10px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); }
.crash-ctrl .input, .crash-ctrl select { width: 100%; }
.crash-play-btn { height: 48px; font-size: 14px; letter-spacing: 0.1em; }
.crash-play-btn:disabled { cursor: not-allowed; }

@media (max-width: 900px) {
  .crash-game { grid-template-columns: 1fr; height: auto; }
  /* Responsive cap — 60 % of the parent column. */
  .crash-bets-panel { max-height: 60%; order: 2; }
  .crash-controls {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "amount autocash"
      "play play";
  }
}

/* ======== Plinko ======== */
.plinko-stage {
  height: 272px; padding: 0;
  display: flex; flex-direction: column;
  position: relative;
  /* Match the renderer's setClearColor (0x0a0d18 dark navy) so the stage
     stays the same colour as the eventually-rendered scene during the
     brief window before the WebGL canvas presents its first frame. */
  background: #0a0d18;
}
.plinko-stage canvas { flex: 1; width: 100%; display: block; min-height: 0; }
.plinko-result-label {
  position: absolute; top: 12px; left: 0; right: 0;
  text-align: center; pointer-events: none;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  font-family: var(--font-ui);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.plinko-result-mult {
  font-size: 28px; font-weight: 800; line-height: 1;
  color: var(--text-muted);
}
.plinko-result-net {
  font-size: 12px; font-weight: 700; opacity: 0.85;
  color: var(--text-muted);
}
.plinko-result-label[data-tier="win"] .plinko-result-mult,
.plinko-result-label[data-tier="win"] .plinko-result-net { color: #22c55e; }
.plinko-result-label[data-tier="big"] .plinko-result-mult,
.plinko-result-label[data-tier="big"] .plinko-result-net { color: #ffd84d; }
.plinko-result-label[data-tier="loss"] .plinko-result-mult,
.plinko-result-label[data-tier="loss"] .plinko-result-net { color: #ef4444; }
/* Multiplier strip pinned flush to the bottom of the plinko stage so the
   buckets sit exactly where the balls land. All buckets share the row
   equally with no overflow so every coefficient is visible. */
.plinko-mults-strip {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex; justify-content: center; align-items: stretch;
  gap: 2px;
  padding: 4px 4px;
  flex-wrap: nowrap;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  overflow: hidden;
}
.plinko-mult-chip {
  flex: 1 1 0; min-width: 0;
  padding: 3px 1px;
  border-radius: 5px;
  font-size: clamp(7px, 1.8vw, 11px); font-weight: 700;
  color: #fff; text-align: center;
  white-space: nowrap; overflow: hidden;
  box-sizing: border-box;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  letter-spacing: -0.02em;
  transition: transform 0.18s, box-shadow 0.18s;
}
.plinko-mult-chip.cold     { background: #1e3a8a; }
.plinko-mult-chip.neutral  { background: #3b82f6; }
.plinko-mult-chip.warm     { background: #7c3aed; }
.plinko-mult-chip.hot      { background: #ec4899; }
.plinko-mult-chip.landed   { transform: scale(1.15); box-shadow: 0 0 0 2px #fff, 0 0 12px rgba(255, 255, 255, 0.6); }

/* ======== Mines ======== */
.mines-stage {
  display: flex; flex-direction: column; gap: 12px; padding: 0; height: 272px;
  /* Match the renderer's setClearColor (0x0a0d18 dark navy) so the stage
     stays the same colour as the eventually-rendered scene during the
     brief window before the WebGL canvas presents its first frame. */
  background: #0a0d18;
}
.mines-grid {
  display: grid; grid-template-columns: repeat(5, 1fr);
  gap: 6px; flex: 1;
  max-width: 360px; width: 100%; margin: 0 auto;
}
.mines-tile {
  aspect-ratio: 1; background: rgba(36, 21, 71, 0.8);
  border: 2px solid rgba(255,255,255,0.15); border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; cursor: pointer; transition: 0.12s;
  font-weight: 900; color: #fff;
}
.mines-tile:hover:not(.revealed):not(:disabled) { background: rgba(58, 35, 110, 0.9); transform: scale(1.03); }
.mines-tile:disabled { cursor: default; }
.mines-tile.revealed.gem { background: linear-gradient(135deg, #22c55e, #15803d); border-color: #4ade80; }
.mines-tile.revealed.bomb { background: linear-gradient(135deg, #ef4444, #991b1b); border-color: #f87171; animation: tile-burst 0.4s ease; }
@keyframes tile-burst { 0% { transform: scale(1); } 40% { transform: scale(1.2); } 100% { transform: scale(1); } }
.mines-status { text-align: center; color: var(--text-muted); font-size: 12px; font-weight: 600; }
.mines-status.win { color: var(--green); }
.mines-status.lose { color: var(--red); }

/* ======== Blackjack ======== */
.blackjack-stage {
  gap: 20px; padding: 0; height: 440px; display: flex; flex-direction: column;
  /* Match the renderer's setClearColor (0x05140a dark felt) so the stage
     stays felt-coloured during the brief window before the WebGL canvas
     presents its first frame. */
  background: #05140a;
}
.bj-row { display: flex; flex-direction: column; gap: 8px; }
.bj-label { font-size: 10px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); text-align: center; }
.bj-total { color: #fff; font-weight: 800; margin-left: 6px; }
.bj-hand { display: flex; gap: 6px; justify-content: center; min-height: 100px; flex-wrap: wrap; }
.bj-card {
  width: 64px; height: 92px; border-radius: 8px;
  background: linear-gradient(180deg, #fff 0%, #eee 100%);
  color: #111; display: flex; align-items: center; justify-content: center;
  font-size: 34px; font-weight: 800; font-family: var(--font-num);
  box-shadow: 0 3px 8px rgba(0,0,0,0.3);
  position: relative;
}
.bj-card.red { color: #c22; }
.bj-card.back {
  background: repeating-linear-gradient(45deg, #ff2e5e, #ff2e5e 6px, #c22 6px, #c22 12px);
  color: transparent;
}
.bj-card .suit { position: absolute; bottom: 6px; right: 8px; font-size: 14px; }
.bj-card .rank-tl { position: absolute; top: 6px; left: 8px; font-size: 14px; font-weight: 900; }
.bj-status { text-align: center; color: var(--text-muted); font-size: 13px; font-weight: 600; }
.bj-status.win { color: var(--green); }
.bj-status.lose { color: var(--red); }
.bj-status.push { color: #fff; }
.bj-actions { display: flex; gap: 8px; }
.bj-actions .dice-roll-btn { flex: 1; }

/* Admin support inbox */
.support-layout {
  display: grid; grid-template-columns: 280px 1fr; gap: 14px;
  height: calc(100vh - 140px);
}
.support-threads {
  background: var(--bg-card-solid); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: 8px;
  overflow-y: auto; display: flex; flex-direction: column; gap: 4px;
}
.support-thread-item {
  padding: 10px 12px; border-radius: 8px; cursor: pointer;
  display: flex; flex-direction: column; gap: 3px;
  background: rgba(15, 8, 36, 0.4); border: 1px solid transparent;
  transition: 0.12s;
}
.support-thread-item:hover { background: rgba(36, 21, 71, 0.7); }
.support-thread-item.active { border-color: var(--border); background: rgba(255, 46, 94, 0.1); }
.support-thread-item .email { font-size: 12px; font-weight: 700; color: var(--text); }
.support-thread-item .preview { font-size: 11px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; }
.support-thread-item .unread {
  align-self: flex-end;
  background: var(--primary); color: #fff; font-size: 10px; font-weight: 800;
  padding: 2px 7px; border-radius: 10px;
}
.support-thread-item .unread:empty { display: none; }

.support-pane {
  display: flex; flex-direction: column;
  background: var(--bg-card-solid); border: 1px solid var(--border);
  border-radius: var(--r-lg); overflow: hidden;
}
.support-pane-header {
  padding: 14px 18px; border-bottom: 1px solid var(--border);
  font-weight: 700; color: var(--text);
}
.support-pane-messages {
  flex: 1; overflow-y: auto; padding: 14px;
  display: flex; flex-direction: column; gap: 8px;
}
.support-pane-messages .msg {
  max-width: 70%; padding: 9px 12px; border-radius: 12px;
  font-size: 13px; word-wrap: break-word;
}
.support-pane-messages .msg.player {
  align-self: flex-start; background: rgba(15, 8, 36, 0.6); color: var(--text);
}
.support-pane-messages .msg.support {
  align-self: flex-end; background: var(--primary-grad); color: #fff;
}
.support-pane-form {
  display: flex; gap: 8px; padding: 10px 12px;
  border-top: 1px solid var(--border);
}
.support-pane-form .input { flex: 1; }

/* Update prompt (mobile) */
.update-modal-backdrop {
  position: fixed; inset: 0; z-index: 2000;
  background: rgba(0, 0, 0, 0.6);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.update-modal {
  /* Mirrors the .btn-primary "PLACE BET" look — translucent red gradient
     over a dark plate, pink-red rim, no outer glow. Same backdrop blur so
     the modal feels like an extension of the primary CTA. */
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.18) 0%, rgba(122, 8, 44, 0.18) 100%),
    rgba(15, 8, 36, 0.85);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid #d91554;
  border-radius: var(--r-lg);
  padding: 20px; max-width: 360px; width: 100%;
  display: flex; flex-direction: column; gap: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
.update-modal h2 { margin: 0; font-size: 17px; font-weight: 800; color: #fff; letter-spacing: 0.01em; }
.update-modal p  { margin: 0; font-size: 13px; color: var(--text); line-height: 1.4; }
.update-modal p .muted-version { color: var(--text-muted); font-weight: 500; }
.update-modal code { background: rgba(15,8,36,0.6); padding: 2px 6px; border-radius: 4px; font-size: 11px; color: #fff; }
.update-actions { display: flex; gap: 8px; margin-top: 4px; justify-content: flex-end; }
.update-actions .btn { text-decoration: none; min-width: 96px; }
.update-actions #update-download { border-color: #d91554; }
/* Small dim "What's new →" link under the version line. Doesn't compete
   with the primary CTA; just available for the curious. */
.update-whatsnew-link {
  align-self: flex-start;
  margin: 2px 0 0;
  padding: 4px 0;
  background: none; border: none;
  color: var(--text-muted);
  font: inherit; font-size: 12px; font-weight: 600;
  cursor: pointer;
  letter-spacing: 0.01em;
  transition: color 0.12s;
}
.update-whatsnew-link:hover { color: #fff; }
/* Changelog popup — same chrome as the update modal but wider and scrollable. */
.changelog-modal { max-width: 480px; max-height: 70vh; }
.changelog-body {
  display: flex; flex-direction: column; gap: 14px;
  overflow-y: auto;
  padding-right: 4px;
  margin: 4px 0;
}
.changelog-entry { display: flex; flex-direction: column; gap: 4px; }
.changelog-version {
  color: #fff; font-weight: 800; font-size: 13px;
  letter-spacing: 0.02em;
}
.changelog-bullets {
  margin: 0; padding-left: 18px;
  color: var(--text); font-size: 12px; line-height: 1.5;
  display: flex; flex-direction: column; gap: 3px;
}

/* ======== Livechat (Intercom-style support widget) ======== */
#livechat {
  position: fixed; right: 20px; bottom: 20px; z-index: 900;
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: 0;
}
#livechat, #livechat input, #livechat button, #livechat textarea,
#livechat .lc-msg, #livechat .lc-empty, #livechat .lc-home, #livechat .lc-thread,
#livechat .lc-msg * {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: 0;
}
.lc-toggle {
  /* Floating chat bubble hidden across all viewports at the user's
     request — the chat panel can still be opened from the bottom-nav
     "Support" tab (which programmatically clicks this button via
     `.lc-toggle?.click()`, working even with display:none). The
     original styling below is kept so re-enabling is a one-line revert. */
  display: none !important;
  align-items: center; justify-content: center; gap: 6px;
  width: 52px; height: 52px; padding: 0;
  background:
    linear-gradient(180deg, #3c1a7a 0%, #1e0a4b 100%) padding-box,
    linear-gradient(135deg, #ffffff 0%, #7c3aed 50%, #ffffff 100%) border-box;
  border: 2px solid transparent; color: #fff; border-radius: 50%;
  cursor: pointer; font-family: inherit; font-size: 13px; font-weight: 700;
  box-shadow:
    0 6px 20px rgba(109, 40, 217, 0.35);
  transition: transform 0.08s, box-shadow 0.12s;
  position: relative;
}
/* Brief glowing pulse on new support reply — catches the player's eye even
   with the panel collapsed. */
@keyframes lc-toggle-pulse {
  0%, 100% { box-shadow: 0 6px 20px rgba(109, 40, 217, 0.35),
                         0 0 0 0 rgba(255, 184, 0, 0.6); }
  50%      { box-shadow: 0 6px 20px rgba(109, 40, 217, 0.55),
                         0 0 0 14px rgba(255, 184, 0, 0); }
}
.lc-toggle.lc-toggle-pulse { animation: lc-toggle-pulse 1.1s ease-out 2; }

/* Notification bubble — sits above the chat toggle when an admin replies
   while the panel is closed. Solid dark background matches the coin-picker
   balance pill in the top nav for visual consistency. */
.lc-notify {
  position: absolute;
  right: 0;
  bottom: calc(100% + 10px);
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 14px;
  background: linear-gradient(180deg, rgba(15, 8, 36, 0.95) 0%, rgba(15, 8, 36, 0.85) 100%);
  color: #fff;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-family: var(--font-display);
  font-weight: 600; font-size: 13px; letter-spacing: 0;
  box-shadow: 0 8px 26px rgba(0, 0, 0, 0.45);
  cursor: pointer; user-select: none; white-space: nowrap;
  animation: lc-notify-pop 0.3s ease-out;
}
.lc-notify.hidden { display: none; }
.lc-notify-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px; padding: 0 7px;
  background: #fff; color: #1e0a4b;
  border-radius: 999px; font-weight: 800; font-size: 12px;
}
.lc-notify:hover { filter: brightness(1.1); }
.lc-notify::after {
  /* Triangle pointer hooking the bubble to the chat toggle. */
  content: ''; position: absolute; bottom: -7px; right: 22px;
  border-left: 7px solid transparent; border-right: 7px solid transparent;
  border-top: 7px solid #fff;
}
@keyframes lc-notify-pop {
  from { transform: translateY(6px) scale(0.92); opacity: 0; }
  to   { transform: translateY(0) scale(1);      opacity: 1; }
}
.lc-toggle:active {
  transform: translateY(2px);
  box-shadow:
    0 4px 12px rgba(109, 40, 217, 0.4);
}
.lc-toggle .lc-toggle-count {
  position: absolute; top: -4px; right: -4px;
}
.lc-toggle:hover {
  box-shadow:
    0 10px 26px rgba(168, 85, 247, 0.45);
}
.lc-toggle-count {
  min-width: 18px; height: 18px; padding: 0 5px;
  background: #fff; color: var(--primary);
  font-size: 10px; font-weight: 800;
  border-radius: 10px; display: inline-flex; align-items: center; justify-content: center;
}
.lc-toggle-count:empty { display: none; }

#livechat .lc-panel {
  position: absolute; right: 0; bottom: 64px;
  /* Fully responsive — the panel never forces itself past the viewport. */
  width: min(360px, calc(100vw - 32px));
  height: min(520px, calc(100vh - 140px));
  max-height: calc(100vh - 140px);
  background: #fff; color: #0f0824;
  border-radius: 16px;
  box-shadow: 0 16px 48px rgba(0,0,0,0.5), 0 4px 12px rgba(0,0,0,0.2);
  display: flex; flex-direction: column;
  overflow: hidden;
  opacity: 0; transform: translateY(10px) scale(0.98); pointer-events: none;
  transition: opacity 0.15s, transform 0.15s;
}
#livechat:not(.lc-collapsed) .lc-panel {
  opacity: 1; transform: none; pointer-events: auto;
}

.lc-hero {
  position: relative; padding: 28px 22px 22px;
  background: linear-gradient(135deg, #ff3d6a 0%, #913ef8 60%, #34b4ff 100%);
  color: #fff;
  flex-shrink: 0;
}
.lc-close {
  position: absolute; top: 14px; right: 14px;
  width: 28px; height: 28px; border-radius: 50%;
  background: rgba(255,255,255,0.2); border: none; color: #fff;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.lc-close:hover { background: rgba(255,255,255,0.35); }
.lc-avatars { display: flex; margin-bottom: 14px; }
.lc-av {
  width: 36px; height: 36px; border-radius: 50%;
  border: 3px solid #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 800; color: #fff; font-size: 14px;
  margin-left: -8px;
}
.lc-av:first-child { margin-left: 0; }
/* Single-avatar variant — used by the livechat hero. The brand logo
   replaces the legacy three-letter (E/S/M) overlapping circles. Bigger
   round avatar, no negative margin since there's no overlap to fix. */
.lc-avatars--single .lc-av-logo {
  width: 56px; height: 56px;
  border: 3px solid #fff;
  border-radius: 50%;
  object-fit: cover;
  margin-left: 0;
  background: #0f0824;
}
.lc-hero-title {
  font-size: 24px; font-weight: 800; letter-spacing: -0.01em;
  line-height: 1.2; margin: 0 0 4px;
}
.lc-hero-subtitle {
  font-size: 22px; font-weight: 700; opacity: 0.75;
  margin: 0;
}

.lc-body {
  flex: 1; overflow-y: auto;
  padding: 14px; display: flex; flex-direction: column; gap: 10px;
  background: #f6f4fb;
}
.lc-card {
  background: #fff; border: 1px solid var(--border);
  border-radius: 12px; padding: 16px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.04);
  font-family: inherit; width: 100%; text-align: left;
  cursor: pointer; transition: transform 0.12s, box-shadow 0.12s;
}
.lc-card:hover { transform: translateY(-1px); box-shadow: 0 6px 16px rgba(0,0,0,0.08); }
.lc-send-card { display: flex; justify-content: space-between; align-items: center; }
.lc-card-head { flex: 1; }
.lc-card-title { font-size: 15px; font-weight: 700; color: #0f0824; margin: 0; }
.lc-card-heading { margin-bottom: 10px; font-size: 13px; letter-spacing: 0.02em; }
.lc-card-action { color: var(--primary); flex-shrink: 0; }
.lc-ann-list { display: flex; flex-direction: column; gap: 8px; }
.lc-ann-item {
  padding: 10px 12px; background: #f6f4fb;
  border-radius: 8px; font-size: 13px; color: #0f0824;
}
/* "Join our Telegram group" card — players reach this when asking
   "where's the group?", "is it safe?". Premium card treatment with a
   Telegram-blue paper-plane glyph, two-line text (title + handle), and
   a trailing chevron so it reads as an outbound link, not a static
   announcement. White card on the muted lavender announcement plate. */
.lc-ann-link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  text-decoration: none;
  background: #ffffff;
  border: 1px solid rgba(15, 8, 36, 0.06);
  border-radius: 10px;
  box-shadow: 0 1px 2px rgba(15, 8, 36, 0.04);
  transition: transform 0.08s, box-shadow 0.12s, border-color 0.12s;
}
.lc-ann-link:hover {
  border-color: rgba(36, 156, 247, 0.4);
  box-shadow: 0 4px 12px rgba(36, 156, 247, 0.14);
}
.lc-ann-link:active { transform: translateY(1px); }
.lc-ann-link-icon {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(180deg, #249cf7 0%, #1f7fcc 100%);
  color: #fff;
  border-radius: 50%;
  box-shadow: 0 2px 6px rgba(36, 156, 247, 0.35);
}
.lc-ann-link-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.lc-ann-link-title {
  font-family: var(--font-ui), system-ui, sans-serif;
  font-size: 13.5px;
  font-weight: 700;
  color: #0f0824;
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lc-ann-link-sub {
  font-family: var(--font-ui), system-ui, sans-serif;
  font-size: 11.5px;
  font-weight: 600;
  color: #6b6883;
  letter-spacing: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lc-ann-link-chev {
  flex-shrink: 0;
  color: #b0adc4;
  font-size: 16px;
  font-weight: 700;
  padding-right: 4px;
  transition: transform 0.12s, color 0.12s;
}
.lc-ann-link:hover .lc-ann-link-chev {
  color: #249cf7;
  transform: translateX(3px);
}

.lc-thread {
  flex: 1; display: flex; flex-direction: column;
  background: #f6f4fb; min-height: 0;
}
.lc-thread-header {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; background: #fff;
  border-bottom: 1px solid var(--border);
  font-weight: 700; font-size: 14px; color: #0f0824;
}
.lc-back {
  background: transparent; border: none; color: var(--primary);
  font-size: 18px; cursor: pointer; padding: 2px 6px;
}
.lc-history {
  margin-left: auto;
  background: transparent; border: 1px solid rgba(15, 8, 36, 0.2);
  color: #0f0824; font: inherit; font-size: 11px; font-weight: 600;
  padding: 4px 10px; border-radius: 999px; cursor: pointer;
}
.lc-history:hover { background: rgba(15, 8, 36, 0.05); }
.lc-messages {
  flex: 1; overflow-y: auto;
  padding: 14px; display: flex; flex-direction: column; gap: 8px;
  scrollbar-width: thin;
}
.lc-messages::-webkit-scrollbar { width: 4px; }
.lc-messages::-webkit-scrollbar-thumb { background: #d5ccec; border-radius: 4px; }
.lc-msg {
  max-width: 80%; padding: 10px 12px; border-radius: 14px;
  font-size: 14px; line-height: 1.4; word-wrap: break-word;
  white-space: pre-wrap;
}
/* Inline system bubble (rate-limit notice, dedupe warning, etc.) — centred,
   muted, no avatar, auto-removes after a few seconds. */
.lc-msg.system {
  align-self: center; max-width: 90%;
  background: rgba(255, 61, 106, 0.18);
  color: #ffb1c3;
  border: 1px solid rgba(255, 61, 106, 0.45);
  font-size: 12px; padding: 6px 10px;
}
/* Neutral info variant — used for "thread closed" notices so they read as
   informational rather than an error. White bubble, dark text. */
.lc-msg.system.info {
  background: #ffffff;
  color: #1e0a4b;
  border: 1px solid rgba(30, 10, 75, 0.25);
}
.lc-msg.support {
  align-self: flex-start; background: #fff; color: #0f0824;
  border-bottom-left-radius: 4px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.06);
}
.lc-msg.player {
  align-self: flex-end;
  background: linear-gradient(180deg, #ff3d6a 0%, #e5194e 100%);
  color: #fff; border-bottom-right-radius: 4px;
}
.lc-empty {
  text-align: center; color: #8a7fae; font-size: 13px;
  padding: 40px 16px;
}

.lc-form {
  display: flex; gap: 8px; padding: 10px 12px;
  background: #fff; border-top: 1px solid var(--border);
}
.lc-input {
  flex: 1; padding: 10px 14px;
  background: #f6f4fb; border: 1px solid var(--border);
  color: #0f0824; border-radius: 999px;
  font-family: inherit; font-size: 13px; outline: none;
}
.lc-input:focus { border-color: var(--border); background: #fff; }
.lc-send {
  width: 38px; height: 38px; padding: 0;
  background: var(--primary-grad); color: #fff;
  border: none; border-radius: 50%; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.lc-send:hover { filter: brightness(1.08); }

/* Bankroll dashboard */
.bankroll-box {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
  margin-bottom: 20px;
}
.bankroll-card {
  padding: 14px 16px; background: var(--bg-card-solid);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  display: flex; flex-direction: column; gap: 6px;
}
.bankroll-card .coin-label { font-size: 11px; font-weight: 700; letter-spacing: 0.12em; color: var(--text-muted); text-transform: uppercase; }
.bankroll-card .liab { font-size: 22px; font-weight: 800; color: #fff; font-variant-numeric: tabular-nums; }
.bankroll-card .liab-sub { font-size: 10px; color: var(--text-dim); }
.bankroll-card .addr {
  font-family: var(--font-num); font-size: 10px;
  color: var(--text-muted); word-break: break-all;
  padding: 6px 8px; background: var(--bg-input); border-radius: 6px;
}
.bankroll-card .history-spark {
  height: 40px; margin-top: 4px; position: relative; overflow: hidden;
}
.bankroll-card .history-spark svg { display: block; width: 100%; height: 100%; }
.bankroll-refresh { margin: 0 0 12px; font-size: 10px; color: var(--text-dim); }
.bankroll-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }

/* Dashboard inline "Adjust user balance" panel. Desktop renders the
   inputs in one row (User ID | Coin | Delta | Reason | Apply); mobile
   stacks them so each field gets full width and the button doesn't
   compress to an icon. */
.admin-balance-adjust-row {
  display: grid;
  grid-template-columns: 110px 100px 160px 1fr auto;
  gap: 6px;
  align-items: center;
  padding: 10px 0;
}
body.mobile .admin-balance-adjust-row {
  grid-template-columns: 1fr;
}

/* Dashboard header — title on the left, prominent notification
   sound toggle on the right. Wraps cleanly on narrow phones. */
.dashboard-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 14px;
}
.dashboard-head .page-title { margin-bottom: 0; }
.admin-notify-toggle {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  color: #fff; font: inherit; font-size: 12px; font-weight: 700;
  letter-spacing: 0.04em; cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.admin-notify-toggle:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: var(--border-strong);
}
.admin-notify-toggle.is-muted {
  color: var(--text-muted);
  border-color: rgba(255, 255, 255, 0.04);
}
.admin-notify-toggle .admin-notify-icon {
  width: 16px; height: 16px;
}
.dashboard-actions {
  display: inline-flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
}
.dashboard-signout {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  color: #fff; font: inherit; font-size: 12px; font-weight: 700;
  letter-spacing: 0.04em; cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.dashboard-signout:hover {
  background: rgba(217, 21, 84, 0.18);
  border-color: rgba(217, 21, 84, 0.45);
  color: #ff8aa1;
}

/* Hot pool banner — surfaces the HD-derived operator addresses the
   server signs withdrawals from. Visible at the top of the Treasury
   page so the operator never forgets to keep them funded. */
.hot-pool-banner {
  margin-bottom: 16px;
  padding: 12px 14px;
  background: rgba(15, 8, 36, 0.55);
  border-radius: var(--r-md);
  border: 1px solid rgba(255, 255, 255, 0.12);
}
.hot-pool-head {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 12px; color: var(--text); margin-bottom: 10px;
}
.hot-pool-icon { width: 18px; height: 18px; flex-shrink: 0; color: var(--gold); }
.hot-pool-grid { display: flex; flex-direction: column; gap: 6px; }
.hot-pool-row {
  display: grid;
  grid-template-columns: 50px minmax(0, 1fr) auto auto;
  gap: 8px; align-items: center;
  padding: 6px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  font-size: 11px;
}
.hot-pool-row:last-child { border-bottom: none; }
.hot-pool-row .coin-label {
  font-size: 10px; font-weight: 700; letter-spacing: 0.1em;
  color: #fff; text-transform: uppercase;
}
.hot-pool-addr {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0; font-size: 10px;
}

/* Treasury — per-coin cards. Grid auto-fits 1-3 per row depending
   on viewport width. `.is-active` lights up coins that have surplus
   waiting to be swept (white border + faint glow) so the operator
   can scan the page and see what needs action immediately. */
.treasury-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
}
.treasury-card {
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  transition: border-color 0.15s;
}
.treasury-card.is-active {
  border-color: rgba(255, 255, 255, 0.55);
}
.treasury-card-head {
  display: flex; justify-content: space-between; align-items: center;
}
.treasury-card-head .coin-label {
  font-size: 12px; font-weight: 700; letter-spacing: 0.12em;
  color: #fff; text-transform: uppercase;
}
.treasury-card-pulse {
  color: var(--green); font-size: 10px;
}
.treasury-card-stats {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px 10px;
}
.treasury-card-stats > div {
  display: flex; flex-direction: column; gap: 1px;
  min-width: 0;
}
.treasury-card-stats .t-label {
  font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-dim);
}
.treasury-card-stats .t-val {
  font-size: 13px; font-weight: 700; color: #fff;
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.treasury-card-foot {
  display: flex; align-items: center; gap: 8px;
  padding-top: 4px; border-top: 1px solid rgba(255, 255, 255, 0.04);
  flex-wrap: wrap;
}
.treasury-dest {
  flex: 1; min-width: 0; font-size: 10px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.treasury-dest .mono {
  font-size: 10px; word-break: break-all;
}
.treasury-card-foot .btn-sm {
  padding: 6px 12px; font-size: 11px;
}

/* Sweep result list — cardified rows on every viewport. Avoids the
   horizontal scroll that the legacy 4-column grid forced on phones. */
.treasury-result-list {
  display: flex; flex-direction: column; gap: 4px; margin-top: 10px;
}
.treasury-result-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
  padding: 8px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  font-size: 11px;
}
.treasury-result-row:last-child { border-bottom: none; }
.treasury-result-addr,
.treasury-result-tx {
  flex: 1 1 100%; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 10px;
}
@media (min-width: 600px) {
  .treasury-result-addr { flex: 1 1 200px; }
  .treasury-result-tx   { flex: 1 1 240px; }
}
.bankroll-ngr { margin: 16px 0 0; }
.bankroll-ngr-title { font-size: 11px; color: var(--text-muted); margin-bottom: 6px; letter-spacing: 0.08em; text-transform: uppercase; }
.bankroll-ngr-bars { display: flex; align-items: flex-end; gap: 4px; height: 50px; padding: 0 4px; border-bottom: 1px solid rgba(255,255,255,0.04); }
.ngr-bar { width: 14px; min-height: 2px; border-radius: 2px 2px 0 0; }
.ngr-bar.pos { background: var(--green); }
.ngr-bar.neg { background: var(--red); }

/* Hot/cold numbers widget (roulette) */
.hot-cold {
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px 14px;
  background: var(--bg-card-solid);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
}
.hot-cold-row { display: flex; align-items: center; gap: 10px; }
.hot-cold-label {
  font-size: 10px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-muted);
  width: 52px; flex-shrink: 0;
}
.hot-cold-nums, .hot-cold-recent { display: flex; gap: 5px; flex-wrap: wrap; flex: 1; }
.roul-pill {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 28px; height: 28px; padding: 0 6px;
  border-radius: 14px; font-size: 11px; font-weight: 800;
  color: #fff; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.15);
  font-variant-numeric: tabular-nums;
}
.roul-pill.red   { background: #dc2626; border-color: #ef4444; }
.roul-pill.black { background: #0f0824; border-color: rgba(255,255,255,0.25); }
.roul-pill.green { background: #15803d; border-color: #22c55e; }
.roul-pill .freq { font-size: 9px; opacity: 0.7; margin-left: 3px; }

/* Solid white border override for all game "rectangle" cards. */
.crash-bets-panel,
.crash-controls {
  border: 1px solid var(--border);
}

/* Desktop: shrink crash page chrome so the whole bordered area fits in the
   viewport without scrolling. The stage keeps its flex-1 so the multiplier
   fills whatever vertical space is left after the tightened history and
   controls. */
body:not(.mobile) .crash-main { gap: 6px; }
body:not(.mobile) .crash-history { padding: 5px 10px; gap: 4px; }
body:not(.mobile) .crash-pill { padding: 3px 9px; font-size: 11px; }
body:not(.mobile) .crash-stage { min-height: 140px; }
body:not(.mobile) .crash-multiplier { font-size: clamp(44px, 7vw, 88px); font-weight: 800; }
body:not(.mobile) .crash-controls { padding: 8px 12px; gap: 6px 12px; }
body:not(.mobile) .crash-controls .quick-chips-row { margin: 0; }
body:not(.mobile) .crash-controls .potential-win-row { padding: 4px 10px; font-size: 11px; }
body:not(.mobile) .crash-play-btn { height: auto; padding: 18px; font-size: 16px; letter-spacing: 0.08em; }
body:not(.mobile) .crash-autoplay-row { font-size: 10px; }

/* ======== VIP page ======== */
.vip-hero { display: flex; flex-direction: column; gap: 10px; }
.vip-hero-top { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; }
.vip-hero-tier { display: flex; flex-direction: column; gap: 6px; }
.vip-hero-xp { font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.vip-hero-rakeback { text-align: right; }
.vip-hero-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); }
.vip-hero-val { font-size: 24px; font-weight: 800; color: #fff; }
.vip-progress { height: 8px; background: rgba(15, 8, 36, 0.7); border-radius: 4px; overflow: hidden; }
.vip-progress-fill { height: 100%; background: linear-gradient(90deg, #7c3aed, #a855f7); transition: width 0.3s; }
.vip-progress-caption { font-size: 11px; color: var(--text-muted); letter-spacing: 0.04em; text-transform: uppercase; }

.vip-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 9px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
  background: transparent;
  border: none;
  color: #fff;
}
.vip-badge-lg { padding: 6px 14px; font-size: 14px; gap: 6px; }

.vip-levelups { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }
.vip-levelups .btn { flex: 1 1 220px; }

.vip-rb-list { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.vip-rb-row {
  display: grid; grid-template-columns: 60px 1fr auto; gap: 12px; align-items: center;
  padding: 10px 14px; background: rgba(15, 8, 36, 0.5); border-radius: 10px;
  border: 1px solid var(--border);
}
.vip-rb-coin { font-weight: 800; color: #fff; letter-spacing: 0.04em; }
/* Clamp the amount cell so a long "0.00000000" can't bleed into the Claim
   button's paint area on narrow phones. */
.vip-rb-amt {
  font-variant-numeric: tabular-nums; color: var(--text);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Mobile rakeback row — the claim button kept stealing enough space that
   the amount column truncated to "0.000…". Stack it as two rows: coin +
   Claim on top, full-width amount underneath. Gives the amount all the
   horizontal room it needs without shrinking the tap target. */
body.mobile .vip-rb-row {
  grid-template-columns: 1fr auto;
  grid-template-rows: auto auto;
  grid-template-areas:
    "coin claim"
    "amt  amt";
  gap: 6px 10px; padding: 10px 12px;
}
body.mobile .vip-rb-row .vip-rb-coin { grid-area: coin; }
body.mobile .vip-rb-row .vip-rb-amt {
  grid-area: amt;
  font-size: 16px; font-weight: 700; color: #fff;
  white-space: nowrap; overflow: visible; text-overflow: clip;
}
body.mobile .vip-rb-row .vip-claim-rb {
  grid-area: claim; padding: 8px 14px; font-size: 12px; min-height: 36px;
}

.vip-table { width: 100%; border-collapse: collapse; margin-top: 8px; }
.vip-table th, .vip-table td {
  text-align: left; padding: 9px 10px;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
}
.vip-table th { color: var(--text-muted); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; font-size: 10px; }
.vip-table tr.vip-tier-active { background: rgba(255, 255, 255, 0.06); }
.vip-table tr.vip-tier-active td { color: #fff; font-weight: 600; }

/* Mobile: the 4-column tier table (Tier / Wagered / Rake / Level-up) was
   wider than the viewport, clipping the last two columns. Drop the level-up
   reward column (already reachable via the Claim buttons up top) and tighten
   padding so Tier / Wagered / Rake all fit in portrait width. */
body.mobile .vip-table th, body.mobile .vip-table td {
  padding: 7px 6px; font-size: 11px;
}
body.mobile .vip-table th:nth-child(4),
body.mobile .vip-table td:nth-child(4) { display: none; }
body.mobile .vip-table th:nth-child(3),
body.mobile .vip-table td:nth-child(3) { text-align: right; white-space: nowrap; }

.vip-pill-badge:empty { display: none; }
/* VIP tier pill — tier colour as the background (Silver → silvery, Gold →
   gold, etc.) with a 2px white border to match the coin-picker style. */
.vip-pill-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 14px; margin-right: 6px;
  background: transparent;
  border: none; border-radius: var(--r-pill);
  font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

/* ======== Dice: hot-streak + session tracker + risk presets + fiat hints + repeat ======== */

/* Hot-streak banner inside the canvas, top-left corner — plain text
   only (no gradient pill, no border, no glow), per user request. */
.dice-canvas-wrap .dice-streak {
  position: absolute; top: 12px; left: 14px; z-index: 5;
  padding: 0;
  background: transparent;
  border: none;
  box-shadow: none;
  color: #fff; font-size: 11px; font-weight: 800; letter-spacing: 0.04em;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
  pointer-events: none;
}
.dice-canvas-wrap .dice-streak.pop { animation: dice-streak-pop 0.4s ease; }
@keyframes dice-streak-pop {
  0% { transform: scale(0.7); opacity: 0; }
  60% { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* Session tracker strip — thin, one-line, sits below the stats row */
.dice-session {
  display: flex; align-items: center; justify-content: center;
  gap: 6px; padding: 4px 10px;
  background: rgba(15, 8, 36, 0.45);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  font-size: 10px; color: var(--text-muted);
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
}
.dice-session strong { color: #fff; font-weight: 800; }
.dice-session .dice-session-pnl.pos { color: var(--green); }
.dice-session .dice-session-pnl.neg { color: var(--red); }
.dice-session-dot { opacity: 0.5; }

/* Risk presets — 3 compact pills in a single row */
.dice-risk-row {
  display: flex; gap: 6px;
  padding: 0 40px;
}
body.mobile .dice-risk-row { padding: 0 20px; }
.dice-risk-btn {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  padding: 8px 10px;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text);
  font: 700 11px/1 inherit;
  letter-spacing: 0.08em; text-transform: uppercase;
  cursor: pointer; transition: 0.15s;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
}
.dice-risk-btn .risk-label {
  font-size: 12px; font-weight: 800;
  letter-spacing: 0.08em;
}
.dice-risk-btn .risk-meta {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  font-size: 10px; font-weight: 600;
  letter-spacing: 0.02em; text-transform: none;
  color: rgba(255,255,255,0.85);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.dice-risk-btn .risk-pay { color: var(--green); font-weight: 700; }
.dice-risk-btn:hover { border-color: var(--border); color: #fff; background: rgba(36, 21, 71, 0.75); }
.dice-risk-btn.selected {
  color: #fff;
  border-color: var(--border);
  background: rgba(255, 255, 255, 0.10);
}

/* Fiat hint next to amount label */
.dice-fiat-hint {
  margin-left: 8px;
  font-size: 10px; font-weight: 600;
  letter-spacing: 0.04em; text-transform: none;
  color: var(--text-dim);
}
.dice-stat-fiat {
  display: block;
  font-size: 10px; font-weight: 600;
  color: var(--text-dim);
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}

/* Repeat button — sits beside Place Bet */
.dice-repeat-btn {
  width: 44px; height: 44px;
  padding: 0; flex: 0 0 auto;
  border-radius: var(--r-md);
  background: rgba(36, 21, 71, 0.75);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 18px; font-weight: 800;
  cursor: pointer; transition: 0.15s;
}
.dice-repeat-btn:hover:not(:disabled) { background: rgba(255, 255, 255, 0.14); border-color: var(--border); color: #fff; }
.dice-repeat-btn:disabled { opacity: 0.35; cursor: not-allowed; }
body.mobile .dice-repeat-btn { width: 40px; height: 40px; font-size: 16px; }

/* Dice desktop: trim redundant rows. Profit/Multiplier already live in the
   compact stats strip, and the min/max hint repeats the bet-limits error
   toast — both just eat vertical space inside the capped column. */
body:not(.mobile) #page-dice .potential-win-row,
body:not(.mobile) #page-dice .amount-hint { display: none; }
body:not(.mobile) .dice-bet-row { gap: 8px; }
body:not(.mobile) .autoplay-row { gap: 6px; }

/* Custom referral-code editor */
.aff-code-editor { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.aff-code-editor .input { flex: 1 1 200px; min-width: 0; }
.aff-code-editor .btn { flex: 0 0 auto; }
.aff-code-editor .aff-code-error {
  flex: 1 1 100%;
  font-size: 11px; color: var(--red); margin-top: 2px; min-height: 14px;
}
.aff-code-edit { margin-right: 4px; }

/* Multi-code affiliate list */
.aff-code-list { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.aff-code-list .aff-code-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px;
  background: rgba(15, 8, 36, 0.45);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.aff-code-list .aff-code {
  flex: 1; min-width: 0;
  font-family: var(--font-num);
  font-weight: 700; font-size: 13px; color: #fff; letter-spacing: 0.02em;
  display: inline-flex; align-items: center; gap: 8px;
  /* Keep the code on a single line — long codes get an ellipsis instead of
     wrapping and breaking the row layout. The Copy button still pulls the
     full string from data-code. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Telegram share-link row — sits directly below each code's main row,
   visually paired with it. The URL is presented as an inset, monospace
   "address-bar" pill (single-line, ellipsis on overflow) and the Copy /
   Share buttons match its height so the trio reads as one cohesive
   widget — closer to the share patterns big crypto casinos use. */
.aff-code-list .aff-tg-row {
  display: flex; align-items: stretch; gap: 6px;
  padding: 0 8px 8px 8px;
  margin-top: -2px;
}
.aff-code-list .aff-tg-link {
  flex: 1; min-width: 0;
  display: flex; align-items: center;
  height: 32px; padding: 0 12px;
  background: rgba(0, 0, 0, 0.28);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  font-family: var(--font-num);
  font-size: 11px; font-weight: 500;
  color: rgba(255, 255, 255, 0.62);
  letter-spacing: 0.01em;
  /* Single-line ellipsis — long bot names + long codes used to wrap onto
     two lines and break the row geometry. The full URL is still
     accessible via the `title` tooltip, the `user-select: all`
     long-press, and the Copy / Share buttons. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  user-select: all;
}
.aff-code-list .aff-tg-copy,
.aff-code-list .aff-tg-share {
  flex: 0 0 auto;
  height: 32px; padding: 0 14px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
}
.aff-code-tag {
  font-size: 9px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 2px 6px; border-radius: 999px;
  color: #ffb800;
  background: rgba(255, 184, 0, 0.12);
  border: 1px solid rgba(255, 184, 0, 0.35);
}
.aff-code-del { color: var(--red); }
.aff-code-add { margin-top: 8px; align-self: flex-start; }
/* Affiliate Copy / Share / Add custom code CTAs — mirror the PLACE BET
   surface 1:1 (same gradient, same subtle white border, same 4px sharp
   corners, same press-depth shadow). Previously these used a hot pink
   solid border (`1px solid #d91554`) which read as a separate button
   family from the in-game CTAs. */
.aff-code-copy-one,
.aff-code-add,
.aff-tg-share,
#aff-copy {
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55) !important;
  border: 1px solid var(--border) !important;
  border-radius: 4px !important;
  color: #fff !important;
  font-weight: 800;
  letter-spacing: 0.04em;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 3px 0 0 rgba(50, 3, 18, 0.55);
}
.aff-code-copy-one:hover,
.aff-code-add:hover,
.aff-tg-share:hover,
#aff-copy:hover {
  filter: brightness(1.08);
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.5) 0%, rgba(122, 8, 44, 0.5) 100%),
    rgba(15, 8, 36, 0.55) !important;
  box-shadow: 0 3px 0 0 rgba(50, 3, 18, 0.65);
}
.aff-code-copy-one:active,
.aff-code-add:active,
.aff-tg-share:active,
#aff-copy:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 0 rgba(50, 3, 18, 0.65);
}

/* On mobile the editor should be touch-friendly: input fills the row,
   Save/Cancel sit below it as easy tap targets, and the "+ Add code" button
   stretches full-width so it's harder to miss. The custom-referral creator
   itself is the same one desktop users see — no separate code path. */
/* Editor is one horizontal row on mobile: input + Save + Cancel inline,
   so the whole creator stays compact. Earlier this stacked the input
   full-width and the buttons full-width below it — turned the editor
   into a tall ~200px block. */
/* Two-row layout on mobile — input claims a full row so the entire
   "Custom code (3–32 chars)" placeholder is readable; Save / Cancel wrap
   onto the row below, side by side. */
body.mobile .aff-code-editor { flex-wrap: wrap; gap: 6px; }
body.mobile .aff-code-editor .input {
  flex: 1 1 100%; width: 100%; min-width: 0;
  min-height: 38px; height: 38px; font-size: 13px; padding: 0 12px;
}
body.mobile .aff-code-editor .btn {
  flex: 1 1 0; min-width: 0;
  min-height: 38px; padding: 0 12px; font-size: 12px;
}
body.mobile .aff-code-editor .aff-code-error { flex: 1 1 100%; }
body.mobile .aff-code-add { width: 100%; min-height: 44px; align-self: stretch; text-align: center; }
/* The "PRIMARY" badge next to a referral code gets truncated to "PR" in the
   narrow mobile row and reads as clutter. Hide it — the primary code is
   already the first row, which is clear enough. Desktop keeps the badge. */
body.mobile .aff-code-list .aff-code-tag { display: none; }

/* ================================================================
   CR-boost widgets — Coinflip/Roulette/Slots/Crash/Plinko/Mines/BJ
   ================================================================ */

/* Coinflip — streak banner reuses .dice-streak; session reuses .dice-session.
   Background matches the renderer's setClearColor (0x081a0e dark felt) so
   any window between page-activation and the WebGL canvas presenting its
   first frame stays felt-coloured. The canvas covers this once it
   paints — no visible cold-load gap. */
#page-coinflip .game-display { position: relative; background: #081a0e; }
/* ─── Unconditional hide of every game's 2D fallback. The 3D scenes
   (Dice3D / Coinflip3D / Slots3D / Crash3D / Plinko3D / Blackjack3D /
   Roulette3D) are the canonical visual surface for every game. The
   2D fallback elements (legacy Pixi canvases, the yellow CSS coin,
   the .reels divs, the CSS roulette wheel, the blackjack 2D card
   rows) are no longer rendered to the user — they stay in the DOM
   only because some JS still writes to their innerHTML / reads them
   by id, and removing the nodes would crash those callers. With
   display: none they're invisible but addressable. */
#page-coinflip .game-display .coin,
#page-blackjack .blackjack-stage .bj-hand,
#page-blackjack .blackjack-stage .bj-strength,
#page-roulette .roul-wheel-wrap > .roul-wheel,
#page-roulette .roul-wheel-wrap > .roul-wheel-slots,
#page-roulette .roul-wheel-wrap > .roul-ball-orbit,
#page-roulette .roul-wheel-wrap > .roul-wheel-arrow {
  display: none !important;
}
#cf-streak { top: 12px; right: 12px; left: auto; }

/* Roulette — hero recent strip above the wheel */
#page-roulette .game-layout { position: relative; }
.roul-recent-hero {
  /* Overlays the wheel — absolute inside .game-layout, no rectangular
     container, circular pills float on top. Centered + overflow:hidden
     so the strip mirrors the .dice-history / .cf-recent-hero /
     .crash-history pattern across every game: pills clustered in the
     middle of the row, anything that doesn't fit gets clipped at the
     edges (renderRoulHistory caps the array to keep the strip tidy). */
  position: absolute; top: 8px; left: 0; right: 0; z-index: 10;
  display: flex; gap: 5px; overflow: hidden;
  justify-content: center;
  padding: 0 10px;
  background: transparent;
  border: none;
  border-radius: 0;
  scrollbar-width: none;
  pointer-events: none;
}
.roul-recent-hero > .roul-recent-pill { pointer-events: auto; }
.roul-recent-hero::-webkit-scrollbar { display: none; }
.roul-recent-empty { color: var(--text-dim); font-size: 11px; letter-spacing: 0.06em; }
.roul-recent-pill {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 30px; height: 30px; padding: 0 8px;
  border-radius: 15px; font-size: 13px; font-weight: 800;
  color: #fff;
  border: none;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}
/* Each number wears its roulette colour as a pill background — matches
   the red / black squares on the felt below so the history reads as a
   miniature version of the same colour scheme. */
.roul-recent-pill.red   { background: #dc2626; color: #fff; }
.roul-recent-pill.black { background: #111114; color: #fff; }
.roul-recent-pill.green { background: #15803d; color: #fff; }
/* Latest number keeps its roulette-colour background and gets a solid
   white ring (no glow) so it stands out from the older pills behind it. */
.roul-recent-pill.latest {
  outline: 2px solid #fff;
  outline-offset: -2px;
}
.hot-cold-compact { padding: 6px 10px; gap: 4px; }

/* Slots — coin rain overlay */
/* Match the renderer's setClearColor (0x0a0d18 dark navy/cabinet) so the
   stage stays the same colour as the eventually-rendered scene during
   the brief window before the WebGL canvas presents its first frame. */
#page-slots .game-display { overflow: hidden; background: #0a0d18; }
.slots-rain {
  position: absolute; inset: 0; pointer-events: none; z-index: 5; overflow: hidden;
}
.slots-rain-coin {
  position: absolute; top: -12%; font-size: 22px;
  animation: slots-rain-fall 1.2s ease-in forwards;
}
@keyframes slots-rain-fall {
  0%   { transform: translateY(0) rotate(0deg); opacity: 0; }
  10%  { opacity: 1; }
  100% { transform: translateY(130%) rotate(360deg); opacity: 0; }
}
.autoplay-stop-win {
  font-size: 10px; margin-left: 10px; gap: 4px;
}
.autoplay-stop-win input[type="checkbox"] { width: 12px; height: 12px; }

/* Crash — auto-cashout preset chips + play-again CTA */
.crash-auto-presets {
  display: flex; gap: 4px; margin-top: 4px;
}
.crash-auto-chip {
  flex: 1; padding: 4px 6px; font: 700 10px/1 inherit;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border);
  color: var(--text-muted);
  border-radius: var(--r-sm);
  cursor: pointer; transition: 0.15s;
  letter-spacing: 0.04em; font-variant-numeric: tabular-nums;
}
.crash-auto-chip:hover { color: #fff; border-color: var(--border); background: rgba(255, 255, 255, 0.10); }
.crash-auto-chip.selected { color: #fff; border-color: var(--border); background: rgba(255, 255, 255, 0.12); }
.crash-play-again {
  margin-top: 6px; animation: crash-play-again-pulse 1.2s ease-in-out infinite;
}
@keyframes crash-play-again-pulse {
  0%,100% { box-shadow: 0 0 0 0 rgba(34,197,94,0.35); }
  50%     { box-shadow: 0 0 0 10px rgba(34,197,94,0);   }
}

/* Mines — pulsing Cashout once above 1.5× + suggested-cashout chip */
.mines-pulse { animation: mines-cashout-pulse 1.1s ease-in-out infinite; }
@keyframes mines-cashout-pulse {
  0%,100% { box-shadow: 0 3px 0 0 rgba(140,10,45,0.75), 0 0 0 0 rgba(34,197,94,0.55); }
  50%     { box-shadow: 0 3px 0 0 rgba(140,10,45,0.75), 0 0 0 14px rgba(34,197,94,0);   }
}
.mines-suggest-chip {
  padding: 8px 14px; font: 700 11px/1 inherit;
  background: rgba(34, 197, 94, 0.15);
  border: 1px solid rgba(34, 197, 94, 0.45);
  color: #86efac;
  border-radius: 999px; cursor: pointer; transition: 0.15s;
  letter-spacing: 0.04em; text-transform: uppercase;
}
.mines-suggest-chip:hover { background: rgba(34, 197, 94, 0.25); color: #fff; }

/* Blackjack — hint overlay dims losing options, highlights recommended */
.bj-hint-toggle { margin-right: auto; font-size: 10px; }
.bj-hint-suggested {
  outline: 2px solid rgba(34, 197, 94, 0.7);
  outline-offset: 2px;
  animation: bj-hint-glow 1.4s ease-in-out infinite;
}
@keyframes bj-hint-glow {
  0%,100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.45); }
  50%     { box-shadow: 0 0 0 10px rgba(34, 197, 94, 0);   }
}
.bj-hint-dimmed { opacity: 0.45; filter: saturate(0.6); }

/* Plinko — multi-ball slider + histogram + stop toggles. Slider styling
   mirrors `.dice-target-slider` so the look matches dice (rounded pill
   track + white thumb with subtle outer ring). */
#plinko-balls {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 10px;
  background: rgba(255,255,255,0.12);
  border-radius: 999px;
  outline: none;
}
#plinko-balls::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 22px; height: 22px; border-radius: 50%;
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.25);
  cursor: pointer;
}
#plinko-balls::-moz-range-thumb {
  width: 22px; height: 22px; border-radius: 50%;
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.25);
  cursor: pointer;
}
#plinko-balls-val { color: #fff; font-weight: 800; font-variant-numeric: tabular-nums; margin-left: 6px; }

/* Games picker — fullscreen modal mirroring coin/fiat pickers, but content
   is a tile grid of games grouped by category (Originals, Slots) instead of
   a flat list. Each tile shows the lucide icon + game name. */
.games-picker {
  /* Soft red brand-tint over the same glass plate the coin-picker uses,
     so the games overlay reads as the same family of element instead of
     a pop of red. Drop shadow removed to match the flat glass aesthetic. */
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.10) 0%, rgba(122, 8, 44, 0.10) 100%),
    rgba(15, 8, 36, 0.20) !important;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  box-shadow: none;
}
body.mobile .games-picker {
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.10) 0%, rgba(122, 8, 44, 0.10) 100%),
    rgba(15, 8, 36, 0.20) !important;
}
.games-picker-section-title {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 18px 14px 8px;
}
.games-picker-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  padding: 0 12px 12px;
}
/* Tile mirrors the home grid's colorful pseudo-3D treatment, scaled for
   a denser 3-column picker layout. Per-game gradient background, ORIGINAL
   pill at top, illustration mid, name at bottom. */
.games-picker-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: space-between;
  aspect-ratio: 1 / 1;
  padding: 10px 10px 12px;
  background: var(--tile-bg, linear-gradient(135deg, #2a3f5a, #1a2538));
  border: none;
  border-radius: 16px;
  color: #fff;
  font-family: var(--font-ui);
  cursor: pointer;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.32);
}
.games-picker-tile.tile--dice     { --tile-bg: linear-gradient(155deg, #15c2c5 0%, #0a7273 80%); }
.games-picker-tile.tile--coinflip { --tile-bg: linear-gradient(155deg, #2d8bff 0%, #1146a8 80%); }
.games-picker-tile.tile--roulette { --tile-bg: linear-gradient(155deg, #1ca06b 0%, #064d31 80%); }
.games-picker-tile.tile--crash    { --tile-bg: linear-gradient(155deg, #b25cff 0%, #ff7a18 110%); }
.games-picker-tile.tile--plinko   { --tile-bg: linear-gradient(155deg, #ff5da8 0%, #b41e7b 80%); }
.games-picker-tile.tile--mines    { --tile-bg: linear-gradient(155deg, #ff6a4d 0%, #b21f10 80%); }
.games-picker-tile.tile--blackjack{ --tile-bg: linear-gradient(155deg, #ee2e3a 0%, #7a0913 80%); }
.games-picker-tile.tile--slots    { --tile-bg: linear-gradient(155deg, #ffb13e 0%, #c5710a 80%); }
.games-picker-tile::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0 2px, transparent 2px 28px),
    radial-gradient(120% 70% at 20% 0%, rgba(255, 255, 255, 0.18), transparent 60%);
  pointer-events: none;
  border-radius: inherit;
}
.games-picker-tile:active {
  transform: translateY(-1px);
  background: var(--tile-bg);
}
@media (hover: hover) {
  .games-picker-tile:hover {
    transform: translateY(-2px);
    background: var(--tile-bg);
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.42);
  }
}
.games-picker-tile:focus {
  outline: none;
  background: var(--tile-bg);
}
.games-picker-tile:focus-visible {
  outline: none;
}
.games-picker-pill {
  position: relative;
  z-index: 2;
  align-self: center;
  display: inline-flex; align-items: center;
  padding: 2px 8px;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 999px;
  color: rgba(255, 255, 255, 0.95);
  font-family: var(--font-ui);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.games-picker-illustration {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex; align-items: center; justify-content: center;
  margin: 4px 0;
}
.games-picker-illustration svg {
  width: 70%;
  max-width: 76px;
  height: auto;
  display: block;
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.35));
}
.games-picker-name {
  position: relative;
  z-index: 2;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
  line-height: 1;
  text-align: center;
}
@media (max-width: 480px) {
  .games-picker-grid { gap: 10px; }
  .games-picker-tile { padding: 8px 8px 10px; border-radius: 14px; }
  .games-picker-name { font-size: 11px; }
  .games-picker-pill { font-size: 7px; padding: 2px 6px; letter-spacing: 0.14em; }
  .games-picker-illustration svg { max-width: 60px; }
}

/* ================================================================
   CR DESIGN FOUNDATION — mute toggle, balance count-up, edge tints
   ================================================================ */

/* Mute toggle in the top bar (uses existing .tb-icon-btn sizing) */
.tb-icon-btn.tb-muted { opacity: 0.55; }
.tb-icon-btn.tb-muted:hover { opacity: 0.9; }

/* Static red dot on the notification bell when a daily bonus is
   claimable. Per UX request — no pulse / ring animation, just a flat
   solid dot. */
.tb-icon-btn.has-claim { position: relative; }
.tb-icon-btn.has-claim::after {
  content: ""; position: absolute; top: 6px; right: 6px;
  width: 8px; height: 8px; border-radius: 50%;
  background: #ef4444;
}

/* 7-day streak grid on the Daily page. Cells show day index + the
   exact reward; the active day is highlighted, claimed days are dimmed,
   day 7 is the gold "super-bonus". */
.streak-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  margin: 10px 0 14px;
}
.streak-cell {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 10px 4px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  text-align: center;
  font-variant-numeric: tabular-nums;
  transition: 0.15s;
}
.streak-cell .streak-day {
  font-size: 10px; font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.06em; text-transform: uppercase;
  margin-bottom: 2px;
}
.streak-cell .streak-reward {
  font-family: var(--font-num);
  font-size: 12px; font-weight: 700;
  color: #fff;
}
.streak-cell .streak-coin {
  font-size: 9px; color: var(--text-dim);
  letter-spacing: 0.08em; margin-top: 1px;
}
.streak-cell.claimed {
  opacity: 0.45;
  background: rgba(34, 197, 94, 0.08);
  border-color: rgba(34, 197, 94, 0.25);
}
.streak-cell.today {
  background: rgba(217, 21, 84, 0.18);
  border-color: #d91554;
  box-shadow: 0 0 0 1px #d91554 inset;
}
.streak-cell.today .streak-day { color: #fff; }
.streak-cell.super {
  background: linear-gradient(180deg, rgba(255, 184, 0, 0.18), rgba(255, 184, 0, 0.04));
  border-color: rgba(255, 184, 0, 0.55);
}
.streak-cell.super .streak-day { color: #ffb800; }
.streak-cell.super.today {
  box-shadow:
    0 0 0 1px #ffb800 inset,
    0 0 16px rgba(255, 184, 0, 0.4);
}
body.mobile .streak-cell { padding: 8px 2px; }
body.mobile .streak-cell .streak-reward { font-size: 10px; }
body.mobile .streak-cell .streak-day { font-size: 9px; }

/* Balance pill count-up flash */
.coin-pill-bal { transition: color 0.2s; }
.coin-pill-bal.bal-up   { color: #22c55e; text-shadow: 0 0 8px rgba(34,197,94,0.22); }
.coin-pill-bal.bal-down { color: #ef4444; text-shadow: 0 0 8px rgba(239,68,68,0.22); }

/* Screen-edge outcome tints — subtle inner-shadow bleed on win/loss */
body.fx-win     { animation: fx-edge-win 0.4s ease-out; }
body.fx-big-win { animation: fx-edge-bigwin 0.6s ease-out; }
body.fx-loss    { animation: fx-edge-loss 0.4s ease-out; }
@keyframes fx-edge-win {
  0%   { box-shadow: inset 0 0 0 0 rgba(34,197,94,0); }
  30%  { box-shadow: inset 0 0 120px 0 rgba(34,197,94,0.22); }
  100% { box-shadow: inset 0 0 0 0 rgba(34,197,94,0); }
}
@keyframes fx-edge-bigwin {
  0%   { box-shadow: inset 0 0 0 0 rgba(255,184,0,0); }
  25%  { box-shadow: inset 0 0 220px 0 rgba(255,184,0,0.35); }
  65%  { box-shadow: inset 0 0 160px 0 rgba(34,197,94,0.28); }
  100% { box-shadow: inset 0 0 0 0 rgba(255,184,0,0); }
}
@keyframes fx-edge-loss {
  0%   { box-shadow: inset 0 0 0 0 rgba(239,68,68,0); }
  30%  { box-shadow: inset 0 0 120px 0 rgba(239,68,68,0.2); }
  100% { box-shadow: inset 0 0 0 0 rgba(239,68,68,0); }
}
/* The inset shadow paints on the body — make sure body has relative stacking. */
body { position: relative; }

/* ================================================================
   DICE — recent-rolls chip strip above the canvas
   ================================================================ */
.dice-game { position: relative; }
.dice-history {
  /* Overlays the dice canvas — no rectangular frame, circular pills
     float directly on top with higher z-index. Same shape as the
     other games' history strips (.crash-history, .cf-recent-hero,
     .roul-recent-hero): centered cluster + overflow:hidden so when
     too many rolls pile up the edges trim instead of scrolling. */
  position: absolute; top: 8px; left: 0; right: 0; z-index: 10;
  display: flex; gap: 6px; overflow: hidden;
  justify-content: center;
  padding: 0 4%; min-height: 28px;
  scrollbar-width: none;
  background: transparent;
  border: none;
  pointer-events: none;
}
.dice-history > .dice-history-pill { pointer-events: auto; }
.dice-history::-webkit-scrollbar { display: none; }
.dice-history-pill {
  /* Naked chips — no background, no border; identity via coloured text. */
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 30px; width: 30px; height: 30px; padding: 0;
  border-radius: 999px;
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: #fff; background: transparent;
  border: none; cursor: pointer;
  flex-shrink: 0; transition: 0.15s;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
}
.dice-history-pill.low  { color: #ef4444; }
.dice-history-pill.high { color: #22c55e; }
.dice-history-pill.mid  { color: #a855f7; }
/* Latest pill — matches the crash-history latest-pill chrome exactly:
   solid pink fill, 2px white border, white text, no text-shadow. Reads
   against any background and stays consistent with the crash game. */
.dice-history-pill.latest {
  background-color: #ff2e5e;
  background-image: none;
  border: 2px solid #ffffff;
  color: #ffffff;
  text-shadow: none;
  font-weight: 800;
  backdrop-filter: none; -webkit-backdrop-filter: none;
  box-shadow: none;
}
.dice-history-pill:hover { filter: brightness(1.12); }

/* ================================================================
   COINFLIP — streak glow on the coin visual (≥3 in a row)
   ================================================================ */
#coin-visual { transition: box-shadow 0.3s, transform 0.2s; cursor: pointer; }
#coin-visual:active { transform: scale(0.96); }
#coin-visual.coin-streak-glow {
  box-shadow:
    0 0 24px rgba(255, 184, 0, 0.75),
    0 0 48px rgba(255, 184, 0, 0.45),
    inset 0 0 18px rgba(255, 255, 255, 0.25);
  animation: coin-streak-bob 1.6s ease-in-out infinite;
}
@keyframes coin-streak-bob {
  0%,100% { transform: translateY(0); }
  50%     { transform: translateY(-4px); }
}

/* ================================================================
   ROULETTE — hero pill is tappable (cursor + hover lift)
   ================================================================ */
.roul-recent-hero .roul-recent-pill { cursor: pointer; transition: 0.15s; }
.roul-recent-hero .roul-recent-pill:hover { transform: scale(1.1); filter: brightness(1.15); }

/* ================================================================
   CRASH — speed lines overlay (intensity scales with multiplier)
   ================================================================ */
.crash-speedlines {
  position: absolute; inset: 0; pointer-events: none; z-index: 0;
  opacity: 0; transition: opacity 0.15s linear;
  background:
    repeating-linear-gradient(90deg,
      rgba(255, 255, 255, 0) 0px,
      rgba(255, 255, 255, 0) 18px,
      rgba(255, 255, 255, 0.12) 18px,
      rgba(255, 255, 255, 0.12) 19px);
  animation: crash-speedlines-slide 0.9s linear infinite;
}
@keyframes crash-speedlines-slide {
  0%   { background-position: 0 0; }
  100% { background-position: -40px 0; }
}

/* ================================================================
   MINES — auto-fit 5×5 to mobile viewport width
   ================================================================ */
body.mobile .mines-grid {
  max-width: min(92vw, 360px); width: 100%; margin: 0 auto;
}
body.mobile .mines-tile {
  font-size: clamp(16px, 5vw, 22px);
}

/* ================================================================
   WAVE 2 — Slots anticipation + BJ card anim + Roulette wheel + Plinko
   ================================================================ */

/* Slots — reel anticipation (blur while spinning, pop on land) */
.reel { transition: transform 0.25s, filter 0.15s; will-change: transform, filter; }
.reel.reel-spinning {
  filter: blur(2px);
  animation: reel-spin-shake 0.08s linear infinite;
}
@keyframes reel-spin-shake {
  0%,100% { transform: translateY(0); }
  50%     { transform: translateY(-3px); }
}
.reel.reel-land { animation: reel-land-pop 0.45s cubic-bezier(0.25, 1.4, 0.5, 1); }
@keyframes reel-land-pop {
  0%   { transform: translateY(-8px) scale(0.94); }
  50%  { transform: translateY(2px) scale(1.08); }
  100% { transform: translateY(0) scale(1); }
}
/* Win-line glow across all reels when a match lands */
.reels.slots-win-line {
  box-shadow: 0 0 0 2px rgba(255, 184, 0, 0.6), 0 0 28px rgba(255, 184, 0, 0.45);
  border-radius: 16px;
  animation: slots-win-glow 1.4s ease-in-out;
}
@keyframes slots-win-glow {
  0%   { box-shadow: 0 0 0 0 rgba(255, 184, 0, 0); }
  30%  { box-shadow: 0 0 0 3px rgba(255, 184, 0, 0.65), 0 0 32px rgba(255, 184, 0, 0.55); }
  100% { box-shadow: 0 0 0 0 rgba(255, 184, 0, 0); }
}

/* Slots jackpot meter — faux progressive pool above the reels */
/* Slots jackpot pool — restyled to match the All Bets / Previous / Top tab
   family: transparent background, bottom-bordered, bold uppercase tracked. */
.slots-jackpot {
  display: flex; align-items: baseline; justify-content: center; gap: 8px;
  padding: 12px 10px; margin-bottom: 8px;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  font-family: inherit; font-size: 12px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}
.slots-jackpot-label {
  font-size: 12px; font-weight: 700; letter-spacing: 0.1em;
  color: var(--text); text-transform: uppercase;
}
.slots-jackpot-amt {
  font-size: 12px; font-weight: 700; color: var(--text);
  letter-spacing: 0.1em; text-shadow: none;
}
.slots-jackpot-coin {
  font-size: 12px; color: var(--text); font-weight: 700; letter-spacing: 0.1em;
}

/* Blackjack — card deal-in animation + dealer hole-card flip + strength meter */
@keyframes bj-card-deal {
  0%   { transform: translate(40px, -60px) rotate(-12deg) scale(0.85); opacity: 0; }
  60%  { transform: translate(0, 2px) rotate(2deg) scale(1.02); opacity: 1; }
  100% { transform: translate(0, 0) rotate(0) scale(1); }
}
.bj-card-deal { animation: bj-card-deal 0.32s cubic-bezier(0.25, 1.3, 0.5, 1); }
@keyframes bj-card-flip {
  0%   { transform: rotateY(-90deg); }
  100% { transform: rotateY(0); }
}
.bj-card-flip { animation: bj-card-flip 0.35s ease-out; transform-style: preserve-3d; backface-visibility: hidden; }

.bj-strength {
  height: 4px; margin-top: 4px;
  background: rgba(15, 8, 36, 0.45);
  border-radius: 2px; overflow: hidden;
  border: 1px solid var(--border);
}
.bj-strength-fill {
  height: 100%; width: 0%;
  transition: width 0.3s, background 0.3s;
  background: var(--text-dim);
}
.bj-strength.strength-green  .bj-strength-fill { background: linear-gradient(90deg, #16a34a, #22c55e); }
.bj-strength.strength-yellow .bj-strength-fill { background: linear-gradient(90deg, #d97706, #ffb800); }
.bj-strength.strength-red    .bj-strength-fill { background: linear-gradient(90deg, #b91c1c, #ef4444); }

/* Roulette wrapper — used to render a decorative 2D wheel; that's been
   removed. The wrapper now exists only as the mount target for the
   Roulette3D canvas, so all the CSS perspective tilt, drop shadow, and
   the conic-gradient ::before / ::after rims have been switched off
   unconditionally. (Previously these were gated on
   data-three-hosted, but with lazy-loaded 3D scripts there's a brief
   window before that flag is set where the wrap would flash the old
   2D wheel — exactly the artefact the player was reporting.) */
.roul-wheel-wrap {
  position: relative;
  width: 100%; height: 100%;
  max-width: none; aspect-ratio: auto;
  margin: 0;
  transform: none;
  filter: none;
  /* Match the renderer's setClearColor (0x05140a dark felt) so the stage
     stays felt-coloured during the brief window before the WebGL canvas
     presents its first frame. */
  background: #05140a;
}
.roul-wheel-wrap::before,
.roul-wheel-wrap::after { display: none !important; }
/* Roulette needs more vertical room so the scene (wheel + sign + bowl ring +
   light shafts) doesn't feel cramped. */
#page-roulette .game-display { height: 380px; padding: 0; }
body.mobile #page-roulette .game-display { min-height: 260px; min-height: 320px; padding: 0; }
/* Metallic outer rim — sits outside the coloured slot ring. */
.roul-wheel-wrap::before {
  content: '';
  position: absolute; inset: -6%;
  border-radius: 50%;
  background:
    conic-gradient(from 0deg,
      #2a1a5a 0deg,  #3a2770 45deg, #6d4bc9 90deg,
      #3a2770 135deg, #2a1a5a 180deg, #6d4bc9 225deg,
      #3a2770 270deg, #2a1a5a 315deg, #2a1a5a 360deg);
  box-shadow:
    inset 0 0 0 2px rgba(0, 0, 0, 0.35),
    inset 0 8px 14px rgba(255, 255, 255, 0.12),
    inset 0 -8px 14px rgba(0, 0, 0, 0.45);
  z-index: -1;
}
/* Inner rim highlight — a thin bright edge where the slots meet the rim. */
.roul-wheel-wrap::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: 50%;
  pointer-events: none;
  box-shadow:
    inset 0 0 0 3px rgba(0, 0, 0, 0.5),
    inset 0 -6px 16px rgba(0, 0, 0, 0.5),
    inset 0 6px 14px rgba(255, 255, 255, 0.14);
}

/* 37 thin radial dividers overlay — gives the conic gradient real slot edges
   instead of just colour bands. Built with a repeating conic-gradient. */
.roul-wheel-slots {
  position: absolute; inset: 0; border-radius: 50%;
  pointer-events: none; z-index: 1;
  background:
    repeating-conic-gradient(
      transparent 0deg,
      transparent calc(360deg/37 - 0.5deg),
      rgba(255, 255, 255, 0.18) calc(360deg/37 - 0.5deg),
      rgba(255, 255, 255, 0.18) calc(360deg/37));
  -webkit-mask: radial-gradient(circle, transparent 30%, #000 30.5%, #000 95%, transparent 95.5%);
          mask: radial-gradient(circle, transparent 30%, #000 30.5%, #000 95%, transparent 95.5%);
}

/* Ball orbit — rotates independently of the wheel. The ball lives on the
   outer edge, pointing up by default, and its parent rotation positions it
   around the wheel. Opposite-spin direction vs the wheel = visual realism. */
/* Slot numbers — live inside .roul-wheel so they rotate with it. Each div
   is rotated to a slot angle; its span is counter-rotated so the digit
   reads upright no matter where on the ring it lands. */
.roul-wheel-number {
  position: absolute; inset: 0;
  pointer-events: none; z-index: 2;
}
.roul-wheel-number span {
  position: absolute;
  top: 6%; left: 50%;
  display: inline-block;
  font-size: 9px; font-weight: 800; color: #fff;
  text-align: center;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 2px rgba(0,0,0,0.85);
  letter-spacing: -0.02em;
  transform-origin: center;
}

.roul-ball-orbit {
  position: absolute; inset: 0; z-index: 3;
  pointer-events: none;
}
.roul-ball {
  position: absolute; top: 3%; left: 50%;
  width: 12px; height: 12px; border-radius: 50%;
  background: radial-gradient(circle at 30% 28%, #fff 0%, #e5e7eb 45%, #9ca3af 85%, #6b7280 100%);
  box-shadow:
    0 3px 6px rgba(0, 0, 0, 0.55),
    0 0 14px rgba(255, 255, 255, 0.45),
    inset -2px -2px 4px rgba(0, 0, 0, 0.35);
  transform: translate(-50%, 0);
}
.roul-wheel {
  position: absolute; inset: 0; border-radius: 50%;
  background:
    conic-gradient(
      #15803d 0deg, #15803d calc(360deg/37),           /* 0 (green) */
      #0f0824 calc(360deg/37),   #0f0824 calc(720deg/37),
      #dc2626 calc(720deg/37),   #dc2626 calc(1080deg/37),
      #0f0824 calc(1080deg/37),  #0f0824 calc(1440deg/37),
      #dc2626 calc(1440deg/37),  #dc2626 calc(1800deg/37),
      #0f0824 calc(1800deg/37),  #0f0824 calc(2160deg/37),
      #dc2626 calc(2160deg/37),  #dc2626 calc(2520deg/37),
      #0f0824 calc(2520deg/37),  #0f0824 calc(2880deg/37),
      #dc2626 calc(2880deg/37),  #dc2626 calc(3240deg/37),
      #0f0824 calc(3240deg/37),  #0f0824 calc(3600deg/37),
      #dc2626 calc(3600deg/37),  #dc2626 calc(3960deg/37),
      #0f0824 calc(3960deg/37),  #0f0824 calc(4320deg/37),
      #dc2626 calc(4320deg/37),  #dc2626 calc(4680deg/37),
      #0f0824 calc(4680deg/37),  #0f0824 calc(5040deg/37),
      #dc2626 calc(5040deg/37),  #dc2626 calc(5400deg/37),
      #0f0824 calc(5400deg/37),  #0f0824 calc(5760deg/37),
      #dc2626 calc(5760deg/37),  #dc2626 calc(6120deg/37),
      #0f0824 calc(6120deg/37),  #0f0824 calc(6480deg/37),
      #dc2626 calc(6480deg/37),  #dc2626 calc(6840deg/37),
      #0f0824 calc(6840deg/37),  #0f0824 calc(7200deg/37),
      #dc2626 calc(7200deg/37),  #dc2626 calc(7560deg/37),
      #0f0824 calc(7560deg/37),  #0f0824 calc(7920deg/37),
      #dc2626 calc(7920deg/37),  #dc2626 calc(8280deg/37),
      #0f0824 calc(8280deg/37),  #0f0824 calc(8640deg/37),
      #dc2626 calc(8640deg/37),  #dc2626 calc(9000deg/37),
      #0f0824 calc(9000deg/37),  #0f0824 calc(9360deg/37),
      #dc2626 calc(9360deg/37),  #dc2626 calc(9720deg/37),
      #0f0824 calc(9720deg/37),  #0f0824 calc(10080deg/37),
      #dc2626 calc(10080deg/37), #dc2626 calc(10440deg/37),
      #0f0824 calc(10440deg/37), #0f0824 calc(10800deg/37),
      #dc2626 calc(10800deg/37), #dc2626 calc(11160deg/37),
      #0f0824 calc(11160deg/37), #0f0824 calc(11520deg/37),
      #dc2626 calc(11520deg/37), #dc2626 calc(11880deg/37),
      #0f0824 calc(11880deg/37), #0f0824 calc(12240deg/37),
      #dc2626 calc(12240deg/37), #dc2626 calc(12600deg/37),
      #0f0824 calc(12600deg/37), #0f0824 calc(12960deg/37),
      #dc2626 calc(12960deg/37));
  border: 1px solid var(--border);
  box-shadow: 0 0 30px rgba(168, 85, 247, 0.25), inset 0 0 20px rgba(15, 8, 36, 0.5);
  /* Transition is set inline by spinRouletteWheel() so duration + easing can
     vary per spin without CSS recompute. */
}
.roul-wheel-center {
  position: absolute; inset: 24%;
  border-radius: 50%;
  /* Raised chrome-ish hub — radial gradient gives a dome-like highlight. */
  background:
    radial-gradient(circle at 50% 30%,
      rgba(255, 255, 255, 0.22) 0%,
      rgba(168, 85, 247, 0.18) 30%,
      rgba(36, 21, 71, 0.92) 60%,
      rgba(15, 8, 36, 1) 100%);
  border: 1px solid var(--border);
  box-shadow:
    inset 0 4px 10px rgba(255, 255, 255, 0.18),
    inset 0 -6px 14px rgba(0, 0, 0, 0.5),
    0 4px 12px rgba(0, 0, 0, 0.4);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  z-index: 4;
  /* Keep the centre label flat to screen even though the wheel is tilted. */
  transform: rotateX(-22deg);
}
.roul-wheel-arrow {
  /* The 3D roulette scene renders its own pointer above the wheel, so
     the HTML arrow was landing in a floating weird spot on mobile —
     hidden here to de-duplicate. */
  display: none !important;
}


/* Amount field + quick chips in one grid row.
   Row 1: label spans full width.
   Row 2: narrow input on the left, chip strip flexing through the remaining
          space on the right. Kills the empty real estate next to the tiny
          number stepper and collapses two stacked rows into one.
   The `flex: 0 0 auto` override is critical: .dice-field has `flex: 1` which
   would otherwise stretch this cell vertically inside the bar's column flex. */
body:not(.mobile) .autoplay-row .bar-amount-field {
  display: grid;
  grid-template-columns: minmax(110px, 180px) 1fr;
  grid-template-rows: auto auto;
  gap: 4px 8px;
  flex: 0 0 auto;
  align-items: end;
  width: 100%;
}
body:not(.mobile) .autoplay-row .bar-amount-field > label {
  grid-column: 1 / -1; grid-row: 1; margin: 0;
}
body:not(.mobile) .autoplay-row .bar-amount-field > .input,
body:not(.mobile) .autoplay-row .bar-amount-field > .dice-amount-group {
  grid-column: 1; grid-row: 2; min-width: 0;
}
body:not(.mobile) .autoplay-row .bar-amount-field > .quick-chips-row {
  grid-column: 2; grid-row: 2;
  display: flex; gap: 3px;
  grid-template-columns: none;
  margin: 0;
  overflow-x: auto;
  scrollbar-width: none;
  min-width: 0;
}
body:not(.mobile) .autoplay-row .bar-amount-field > .quick-chips-row::-webkit-scrollbar { display: none; }
body:not(.mobile) .autoplay-row .bar-amount-field > .quick-chips-row .quick-chip-btn {
  padding: 7px 6px; min-width: 46px;
  font-size: 10px; flex: 1 1 auto;
  border-radius: 7px;
  min-height: 26px;
}

/* Mobile — stack back (input full width, chips scroll below). */
body.mobile .autoplay-row .bar-amount-field { display: block; }
body.mobile .autoplay-row .bar-amount-field > .quick-chips-row { margin-top: 4px; }

/* Crash controls — same shrink-chip treatment (no grid restructure since the
   crash controls already use their own grid layout). */
body:not(.mobile) .crash-controls .quick-chips-row {
  margin: 0; gap: 3px;
}
body:not(.mobile) .crash-controls .quick-chip-btn {
  padding: 5px 4px; font-size: 10px;
  border-radius: 7px; min-height: 26px;
}

/* Roulette bet-type tile grid — replaces the native <select>. Each tile is
   a tappable chip; the Red/Black tiles carry their colour so the intent is
   obvious at a glance. */
.roul-type-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 4px;
  margin-top: 4px;
}
.roul-type-btn {
  padding: 9px 6px;
  background: rgba(15, 8, 36, 0.6);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 8px;
  font: 700 11px/1 inherit;
  letter-spacing: 0.03em;
  cursor: pointer;
  transition: 0.12s;
  text-align: center;
  min-height: 36px;
  font-variant-numeric: tabular-nums;
}
.roul-type-btn:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: var(--border);
  color: #fff;
}
.roul-type-btn.active {
  background: rgba(255, 255, 255, 0.16);
  border-color: var(--border);
  color: #fff;
  box-shadow: 0 0 0 2px rgba(168, 85, 247, 0.28), 0 0 14px rgba(168, 85, 247, 0.28);
}
.roul-type-btn.roul-red {
  background: linear-gradient(180deg, #ef4444, #b91c1c);
  border-color: #f87171; color: #fff;
}
.roul-type-btn.roul-black {
  background: linear-gradient(180deg, #111827, #0f0824);
  border-color: rgba(255,255,255,0.25); color: #fff;
}
.roul-type-btn.roul-red.active {
  box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.55), 0 0 14px rgba(239, 68, 68, 0.4);
}
.roul-type-btn.roul-black.active {
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.35), 0 0 14px rgba(255, 255, 255, 0.18);
}
body.mobile .roul-type-grid { grid-template-columns: repeat(4, 1fr); gap: 3px; }
body.mobile .roul-type-btn { padding: 10px 4px; font-size: 10px; min-height: 40px; }

/* Roulette result badge — hidden. The winning number is visible on the
   wheel itself where the ball lands; the duplicated pill was redundant. */
.roul-result-badge { display: none; }

/* Coinflip recent-flips hero strip — same shape as Roulette's but with
   heads/tails pill colours. */
.cf-recent-hero {
  /* Overlays the coin canvas — same treatment as .dice-history /
     .roul-recent-hero / .crash-history: absolute-positioned,
     transparent, centered cluster + overflow:hidden so excess pills
     trim at the edges instead of producing a horizontal scrollbar.
     .game-display is the position: relative ancestor that anchors
     this. */
  position: absolute; top: 8px; left: 0; right: 0; z-index: 10;
  display: flex; gap: 5px; overflow: hidden;
  justify-content: center;
  padding: 0 10px;
  background: transparent;
  border: none;
  border-radius: 0;
  scrollbar-width: none;
  pointer-events: none;
}
.cf-recent-hero > .cf-recent-pill { pointer-events: auto; }
.cf-recent-hero::-webkit-scrollbar { display: none; }
.cf-recent-pill {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 30px; height: 30px; padding: 0 8px;
  border-radius: 15px; font-size: 13px; font-weight: 800;
  color: #fff; border: none;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0; cursor: pointer; transition: 0.15s;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}
/* Coin-side colour drives the pill background (matches the roulette
   recent-pill pattern): heads = gold, tails = dark steel. */
.cf-recent-pill.heads { background: #d4af37; color: #fff; }
.cf-recent-pill.tails { background: #1f2937; color: #fff; }
/* Latest flip keeps its coin-side background and adds a solid white
   ring (no glow) so it stands out without overriding the colour fill. */
.cf-recent-pill.latest {
  outline: 2px solid #fff;
  outline-offset: -2px;
}
.cf-recent-pill:hover { filter: brightness(1.15); transform: scale(1.08); }

/* Nav section headers ("Originals", "Slots", "Account") — subtle dividers
   inside the sidebar. */
.nav-section {
  font-size: 9px; font-weight: 800;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--text-dim);
  padding: 12px 14px 4px;
  border-top: 1px solid var(--border);
  margin-top: 4px;
}
.nav-section:first-of-type { border-top: none; margin-top: 8px; }
body.sidebar-collapsed .nav-section { display: none; }

/* ================================================================
   MOBILE PARITY — recent features that were designed for desktop
   get mobile-friendly sizing / visibility.
   ================================================================ */

/* VIP badge in the top bar — explicit mobile sizing so it's legible. */
body.mobile .vip-pill-badge {
  padding: 3px 8px; font-size: 10px;
  margin-right: 8px;
}

/* Make the primary Place Bet / Roll / Spin / Deal buttons feel weighty on
   phones — they get extra padding and a subtle glow so they read as the
   main action. */
body.mobile .btn-primary.btn-lg,
body.mobile .dice-roll-btn,
body.mobile .crash-play-btn {
  min-height: 52px;
  font-size: 14px;
  letter-spacing: 0.1em;
  /* Shadow inherits from .btn-primary — no extra outer glow, so mobile
     doesn't read brighter than desktop. */
}

/* Ensure 3D canvases fill their mobile wrappers fully. */
body.mobile .dice-3d-canvas,
body.mobile .coinflip-3d-canvas,
body.mobile .roul-wheel-wrap canvas,
body.mobile .slots-3d-canvas,
body.mobile .crash-3d-canvas,
body.mobile .plinko-3d-canvas,
body.mobile .bj-3d-canvas {
  width: 100% !important; height: 100% !important; display: block;
}

/* When the Blackjack 3D canvas takes over the stage on mobile, the 2D card
   rows are hidden and the stage would otherwise collapse to its padding
   height. Give it a fixed-but-viewport-aware height so the canvas has room
   to render — same intent as the 440 px desktop stage, scaled for phones. */
body.mobile .blackjack-stage {
  height: clamp(300px, 48vh, 460px);
  position: relative;
}
body.mobile .blackjack-stage .bj-3d-canvas {
  position: absolute; inset: 0;
}

/* Hand totals overlay — show the running "Dealer 17" / "You Blackjack" labels
   on top of the 3D table so the player can read the total without the 2D
   card rows. Applies on both desktop and mobile when 3D is hosted. The
   underlying #bj-dealer-total / #bj-player-total spans are written to by
   Blackjack.render(); we just lift their parent .bj-row out of the flex
   flow and pin it to the top/bottom of the felt. */
.blackjack-stage {
  position: relative;
}
.blackjack-stage .bj-row {
  position: absolute; left: 0; right: 0; z-index: 3;
  pointer-events: none; text-align: center; margin: 0;
}
.blackjack-stage .bj-row:nth-of-type(1) { top: 10px; }
.blackjack-stage .bj-row:nth-of-type(2) { bottom: 36px; }
.blackjack-stage .bj-label {
  display: inline-block;
  padding: 0;
  background: transparent;
  border: 0;
  font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-muted, #9a8ecf);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}
.blackjack-stage .bj-total {
  color: #fff; font-weight: 800; font-size: 14px;
  margin-left: 6px; letter-spacing: 0.04em;
}
.blackjack-stage .bj-status {
  position: absolute; bottom: 8px; left: 0; right: 0;
  text-align: center; z-index: 3; pointer-events: none;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.85);
}

/* Recent-strip pills (Roulette, Coinflip, Dice history) get a touch more
   tap area on phones. */
body.mobile .roul-recent-hero,
body.mobile .cf-recent-hero {
  padding: 6px 8px; gap: 4px;
}
body.mobile .roul-recent-pill,
body.mobile .cf-recent-pill {
  min-width: 34px; height: 34px; font-size: 14px;
}

/* Streak banner / session strip fit cleanly in the narrower viewport. */
body.mobile .dice-streak,
body.mobile #cf-streak {
  top: 8px; right: 8px; font-size: 10px; padding: 3px 8px;
}
body.mobile .dice-session,
body.mobile #cf-session,
body.mobile #mines-session {
  font-size: 10px; padding: 4px 8px; gap: 5px;
}

/* Risk presets + dir toggle — tap-friendly heights. On phones the label
   + percentage would otherwise collide ("MEDIUM" running into "50%") when
   the three cells are squeezed — stack them vertically so both fit. */
body.mobile .dice-risk-row { padding: 0 10px; gap: 4px; }
body.mobile .dice-risk-btn {
  min-height: 44px; font-size: 10px;
  flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  padding: 6px 4px;
  letter-spacing: 0.02em;
}
body.mobile .dice-risk-btn .risk-label { font-size: 11px; letter-spacing: 0.04em; }
body.mobile .dice-risk-btn .risk-meta { font-size: 9px; letter-spacing: 0; }
body.mobile .dice-risk-btn .risk-meta span { font-size: 9px; }
body.mobile .dice-dir-seg .seg { min-height: 44px; }

/* Roulette bet-type tile grid — wider touch targets on mobile. */
body.mobile .roul-type-grid { gap: 4px; }
body.mobile .roul-type-btn { min-height: 44px; font-size: 11px; }

/* Slots jackpot meter readable on narrow screens. */
body.mobile .slots-jackpot {
  padding: 6px 10px; gap: 6px;
}
body.mobile .slots-jackpot-amt { font-size: 14px; }
body.mobile .slots-jackpot-label { font-size: 8px; }

/* Crash auto-cashout preset chips — compact but tappable. */
body.mobile .crash-auto-chip { min-height: 32px; font-size: 11px; }
body.mobile .crash-play-again { min-height: 40px; font-size: 11px; }

/* Mines suggest-cashout + pulsing button + grid auto-fit (already set). */
body.mobile .mines-suggest-chip { min-height: 40px; font-size: 11px; }

/* Blackjack strength meter + hint toggle sit cleanly on mobile. */
body.mobile .bj-strength { height: 3px; }
body.mobile .bj-hint-toggle { font-size: 9px; margin-right: 4px; }

/* Last nav button in the drawer — drop the bottom divider so the list
   ends cleanly. Section headers rendered on mobile get a full-width
   darker stripe so the groups (Originals / Slots / Account) read clearly. */
body.mobile #sidebar .nav-btn:last-child { border-bottom: none; }
body.mobile #sidebar .nav-section {
  /* Match the desktop separator treatment but bump the font size — 9 px is
     unreadable on phones. Keeps the uppercase / bold / letter-spacing that
     the base `.nav-section` rule defines, so the visual language stays
     identical. */
  padding: 14px 16px 8px;
  background: rgba(0, 0, 0, 0.25);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  margin: 0;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.55);
}
body.mobile #sidebar .nav-section:first-of-type { border-top: none; }
body.mobile #sidebar .nav-btn:hover,
body.mobile #sidebar .nav-btn:active {
  background: rgba(15, 8, 36, 0.85);
  color: #fff;
}
body.mobile #sidebar .nav-btn.active {
  background: rgba(15, 8, 36, 0.85);
  color: #fff;
  border-left: 2px solid #d91554;
  border-right: 2px solid transparent;
  border-radius: 0;
  box-shadow: none;
}

/* Mobile wallet — Copy / MAX keep the dark violet pill, but the
   primary "Request withdrawal" CTA matches the canonical primary
   action colour (#d91554, same as PLACE BET / SPIN / login ready)
   so the user reads it as the same kind of submit across the app. */
body.mobile #page-wallet .deposit-copy {
  /* Match the affiliate Copy / "+ Add custom code" button 1:1 — same red
     gradient on translucent navy, same 1 px pink-red rim, same radius. */
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55) !important;
  border: 1px solid #d91554 !important;
  border-radius: var(--r-md) !important;
  box-shadow: 0 3px 0 0 rgba(50, 3, 18, 0.55) !important;
  color: #fff !important;
  font-weight: 800;
  letter-spacing: 0.04em;
}
body.mobile #page-wallet .withdraw-max {
  border: 2px solid rgba(255, 255, 255, 0.08) !important;
  background: rgba(15, 8, 36, 0.55) !important;
  border-radius: 14px !important;
  box-shadow: none !important;
  color: #fff !important;
  font-weight: 700;
  padding: 16px 22px !important;
  min-height: 0 !important;
  align-self: stretch !important;
}
body.mobile #page-wallet .deposit-copy:hover {
  filter: brightness(1.08) !important;
}
body.mobile #page-wallet .deposit-copy:active {
  transform: translateY(2px) !important;
  box-shadow: 0 1px 0 0 rgba(50, 3, 18, 0.55) !important;
}
body.mobile #page-wallet .withdraw-max:hover {
  background: rgba(15, 8, 36, 0.55) !important;
  border: 2px solid rgba(255, 255, 255, 0.08) !important;
  box-shadow: none !important;
  filter: none !important;
}
body.mobile #page-wallet .withdraw-max:active {
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid rgba(255, 255, 255, 0.08) !important;
  transform: none;
  box-shadow: none !important;
}

/* #auth-submit: match the play CTAs across every game — solid
   `#0f0824` (body --bg-deep). On the auth view the rgba(15,8,36,0.7)
   focused-input fill blends to the same visible colour because the
   page bg is `#0f0824` solid; using the opaque hex here keeps the
   button colour identical regardless of context. */
#auth-submit,
#auth-submit.btn-primary,
#auth-submit.btn-lg,
body.mobile #auth-submit {
  background: #0f0824 !important;
  border: none !important;
  border-radius: var(--r-pill) !important;
  padding: 10px 18px !important;
  color: var(--text) !important;
  font: inherit !important;
  font-size: 13px !important;
  font-weight: 700 !important;
  letter-spacing: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  filter: none !important;
  min-height: 0 !important;
}
#auth-submit:hover,
body.mobile #auth-submit:hover {
  background: rgba(255, 255, 255, 0.12) !important;
  filter: none !important;
}
#auth-submit:active,
body.mobile #auth-submit:active {
  background: rgba(255, 255, 255, 0.18) !important;
  transform: none !important;
}

/* Wallet section — suppress the hover glow + brighten filter on all wallet
   action buttons (desktop + mobile). Withdrawal is a careful action; no
   glow helps it feel deliberate. */
#page-wallet .deposit-copy:hover,
#page-wallet .withdraw-max:hover,
#page-wallet .withdraw-submit:hover,
#page-wallet .wd-pill:hover {
  filter: none !important;
}

/* On touch devices :hover sticks until the next tap, so the Copy button
   (and the referral-code Copy chips, and every other .btn) looks glowy
   for seconds after a press. Strip hover brightness + glow on mobile —
   :active still fires for a fraction of a second as press-down feedback. */
body.mobile .btn:hover,
body.mobile .btn-primary:hover,
body.mobile .deposit-copy:hover,
body.mobile .aff-code-copy:hover,
body.mobile .aff-code-copy-one:hover {
  filter: none !important;
  transform: none !important;
}

/* Mobile-wide glow removal — user asked for NO coloured outer glow on any
   button / pill in the mobile build. We collapse the box-shadow down to
   just the 3 px dark press-depth + the inset highlight for every base,
   hover, focus and active state across buttons, pills, copy chips, the
   auth submit, the wd pills and user-pill. If a new surface picks up a
   glow in the future, extend this selector list. */
body.mobile .btn,
body.mobile .btn-primary,
body.mobile .btn-ghost,
body.mobile .deposit-copy,
body.mobile .withdraw-max,
body.mobile .withdraw-submit,
body.mobile .aff-code-copy,
body.mobile .aff-code-copy-one,
body.mobile .aff-code-add,
body.mobile .aff-code-del,
body.mobile .wd-pill,
body.mobile .user-pill,
body.mobile #auth-submit,
body.mobile .dice-quick,
body.mobile .crash-chip,
body.mobile .dice-roll-btn,
body.mobile .crash-play-btn,
body.mobile .mines-suggest-chip,
body.mobile .mines-risk-chip,
body.mobile .dice-risk-btn,
body.mobile .btn:hover,
body.mobile .btn:focus,
body.mobile .btn-primary:hover,
body.mobile .btn-primary:focus,
body.mobile .deposit-copy:hover,
body.mobile .deposit-copy:focus,
body.mobile .wd-pill:hover,
body.mobile .wd-pill:focus {
  filter: none !important;
}
/* Coin-pill: no inner highlight/shadow, only the white outer border. */
body.mobile .coin-pill,
body.mobile .coin-pill:hover,
body.mobile .coin-pill:focus,
body.mobile .coin-pill:active { box-shadow: none !important; }
body.mobile .btn:active,
body.mobile .btn-primary:active,
body.mobile .deposit-copy:active,
body.mobile .dice-quick:active,
body.mobile .crash-chip:active,
body.mobile .aff-code-copy:active,
body.mobile .aff-code-copy-one:active {
  /* Press-down cue — collapse the depth to 1 px, still no coloured glow. */
  transform: translateY(1px);
}

/* Catch-all: on mobile, any element whose class suggests it's a button,
   pill, chip or copy target gets its box-shadow collapsed to the flat
   press-depth. Runs last so it beats older rules that still paint a
   coloured outer glow. Attribute selectors pick up future additions
   without having to maintain an explicit list. The topbar pills
   (.coin-pill, .user-pill) already carry a gradient border — stacking a
   drop-shadow on top made them look double-outlined, so they get no
   shadow here at all. */
body.mobile [class*="btn"],
body.mobile [class*="pill"]:not(.coin-pill):not(.user-pill),
body.mobile [class*="chip"],
body.mobile [class*="copy"],
body.mobile [class*="play-btn"],
body.mobile [class*="roll-btn"],
body.mobile [class*="submit"],
body.mobile [class*="auth-submit"],
body.mobile [class*="add"] {
  filter: none !important;
  -webkit-filter: none !important;
}
body.mobile .coin-pill,
body.mobile .user-pill,
body.mobile .vip-pill-badge {
  box-shadow: none !important;
  filter: none !important;
}
/* Mobile VIP tier pill in the top bar — strip the tier-coloured gradient
   border-plus-box-shadow that the catch-all rule stacked on top of it
   (reading as a double outline around "Silver"). Flat 1 px border in the
   tier colour with a transparent-ish fill. */
body.mobile .vip-pill-badge {
  background: transparent !important;
  border: none !important;
  padding: 5px 12px !important;
}
/* Hide the VIP rank pill inside the top nav on mobile — the bar is tight
   and the rank is visible on the VIP page when players want to check it. */
body.mobile #titlebar .vip-pill-badge,
body.mobile .tb-right .vip-pill-badge,
body.mobile .user-pill .vip-pill-badge { display: none !important; }

body.mobile .coin-pill {
  background: transparent !important;
  border: none !important;
}
body.mobile .coin-pill:hover,
body.mobile .coin-pill:active { background: transparent !important; }

/* Mobile: every gradient-bordered pill / button gets a clean solid white
   border, matching the underline under the active HEADS/TAILS tab. Replaces
   the old magenta/purple gradient border-image + pink pill skins. Extended
   to cover every bet-control button in each game so the control panel
   reads as a single, uniform action strip (½ / 2× / Max / ↻ / risk tiers /
   auto-cashout chips / SPIN / DEAL / HIT / STAND / DOUBLE / CASHOUT …).
   Bet-TYPE tiles (red/black on roulette felt, heads/tails, mines tiles)
   keep their own colour-coded identity — they're data, not actions. */
/* Chip / pill flat fill — Place Bet (.dice-roll-btn / .crash-play-btn /
   .btn-primary / #auth-submit) intentionally NOT in this list. Those CTAs
   have their own canonical solid-red `#d91554` treatment further down;
   including them here forced a navy `#1a0f3d` flash on tap-hold (mobile
   keeps :hover after a tap) which only the source-order tiebreak with
   the red rule below kept in check — fragile by design. */
body.mobile .wd-pill,
body.mobile .dice-quick,
body.mobile .crash-chip,
body.mobile .crash-auto-chip,
body.mobile .quick-chip-btn,
body.mobile .dice-repeat-btn,
body.mobile .dice-risk-btn,
body.mobile .mines-risk-chip,
body.mobile .mines-suggest-chip {
  border: 1px solid var(--border) !important;
  background: #1a0f3d !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  color: var(--text) !important;
}
/* Wallet Currency pill — both the Deposit pane's Currency/Network pair
   and the Withdraw pane's Currency selector share the same translucent
   dark surface + border treatment as the .deposit-address-text plate
   the Deposit page shows underneath. Without this scoped override they
   inherit the brighter solid #1a0f3d that the chip-family rule above
   applies. */
body.mobile .deposit-pair .wd-pill,
body.mobile [data-wallet-pane="withdraw"] .wd-pill {
  background: rgba(15, 8, 36, 0.55) !important;
  border: 2px solid rgba(255, 255, 255, 0.08) !important;
}
body.mobile .wd-pill:hover,
body.mobile .dice-quick:hover,
body.mobile .crash-chip:hover,
body.mobile .crash-auto-chip:hover,
body.mobile .quick-chip-btn:hover,
body.mobile .dice-repeat-btn:hover,
body.mobile .dice-risk-btn:hover,
body.mobile .mines-risk-chip:hover,
body.mobile .mines-suggest-chip:hover {
  filter: none !important;
  background: #1a0f3d !important;
}
body.mobile #page-wallet .deposit-copy,
body.mobile #page-wallet .withdraw-submit {
  border: 2px solid #d91554 !important;
  background: rgba(15, 8, 36, 0.7) !important;
  border-radius: var(--r-pill) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  color: #fff !important;
}
body.mobile #page-wallet .deposit-copy:hover,
body.mobile #page-wallet .withdraw-submit:hover {
  filter: none !important;
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid #d91554 !important;
}
/* MAX button: same metrics as Swap's Max chip (`padding: 8px 14px;
   font-size: 12px`) and place-bet button surface (cherry red `#d91554`
   border + translucent dark navy fill on a full pill). */
body.mobile #page-wallet .withdraw-max {
  border: 2px solid #d91554 !important;
  background: rgba(15, 8, 36, 0.7) !important;
  border-radius: var(--r-pill) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  color: #fff !important;
  padding: 8px 14px !important;
  min-height: 0 !important;
  font-size: 12px !important;
  font-weight: 700 !important;
  letter-spacing: 0 !important;
  line-height: 1.15 !important;
  align-self: center !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
}
body.mobile #page-wallet .withdraw-max:hover {
  filter: none !important;
  background: rgba(15, 8, 36, 0.85) !important;
  border: 2px solid #d91554 !important;
}
body.mobile #page-wallet .withdraw-max:active {
  background: rgba(15, 8, 36, 0.95) !important;
  border: 2px solid #d91554 !important;
  transform: none !important;
}
/* Active / selected state gets a highlight fill (still white border) so the
   chosen risk tier / auto-cashout preset / bet-type is visible. */
body.mobile .dice-quick.active,
body.mobile .crash-chip.active,
body.mobile .crash-auto-chip.active,
body.mobile .dice-risk-btn.active,
body.mobile .dice-risk-btn.selected,
body.mobile .mines-risk-chip.active,
body.mobile .quick-chip-btn.active {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.20) 0%, rgba(255, 255, 255, 0.10) 100%) !important;
  border-color: var(--border) !important;
}
body.mobile [class*="btn"]:hover,
body.mobile [class*="pill"]:hover,
body.mobile [class*="chip"]:hover,
body.mobile [class*="copy"]:hover,
body.mobile [class*="play-btn"]:hover,
body.mobile [class*="roll-btn"]:hover,
body.mobile [class*="btn"]:focus,
body.mobile [class*="pill"]:focus,
body.mobile [class*="chip"]:focus,
body.mobile [class*="copy"]:focus {
  filter: none !important;
  transform: none !important;
}

/* ============================================================
   LIVE ROULETTE — dealer banner, countdown, active-chips strip.
   Reuses existing .roul-type-grid, .game-display, .live-layout.
   ============================================================ */
.lr-dealer-bar {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 16px; margin-bottom: 14px;
  background: linear-gradient(135deg, rgba(168, 85, 247, 0.12), rgba(255, 61, 106, 0.08));
  border: 1px solid var(--border);
  border-radius: 12px;
}
.lr-dealer-avatar {
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: linear-gradient(135deg, #ff3d6a, #a855f7);
  color: #fff; font-weight: 700; font-size: 18px;
  border: 2px solid rgba(255, 255, 255, 0.2);
  flex-shrink: 0;
}
.lr-dealer-text { flex: 1; min-width: 0; }
.lr-dealer-name { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); }
.lr-dealer-msg { font-size: 16px; font-weight: 500; margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lr-phase {
  display: flex; flex-direction: column; align-items: flex-end;
  gap: 2px; flex-shrink: 0;
}
.lr-phase-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: 1px;
  color: var(--muted);
}
.lr-countdown {
  font-family: var(--font-num);
  font-size: 22px; font-weight: 700;
  color: var(--text);
  min-width: 48px; text-align: right;
}
.lr-countdown.urgent { color: #ffb800; animation: lr-pulse 0.5s infinite alternate; }
@keyframes lr-pulse { to { opacity: 0.55; } }

.lr-your-chips {
  flex: 1; display: flex; flex-wrap: wrap; gap: 6px;
  align-items: center; min-height: 36px;
  font-size: 13px; color: var(--muted);
}
.lr-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px;
  background: rgba(168, 85, 247, 0.15);
  border: 1px solid var(--border);
  font-size: 12px; color: var(--text);
  font-family: var(--font-num);
}
.lr-chip.won { background: rgba(53, 211, 153, 0.18); border-color: rgba(53, 211, 153, 0.5); }
.lr-chip.lost { background: rgba(255, 61, 106, 0.12); border-color: rgba(255, 61, 106, 0.35); opacity: 0.7; }

/* ============================================================
   MINES — risk tier presets and label.
   ============================================================ */
.mines-risk-presets {
  display: flex; gap: 6px; margin-top: 10px; flex-wrap: wrap;
}
.mines-risk-chip {
  padding: 6px 12px; font: 700 11px/1 inherit;
  background: rgba(168, 85, 247, 0.12);
  border: 1px solid var(--border);
  color: #c4b5fd;
  border-radius: 999px; cursor: pointer; transition: 0.15s;
  letter-spacing: 0.04em; text-transform: uppercase;
}
.mines-risk-chip:hover { background: rgba(168, 85, 247, 0.22); color: #fff; }
.mines-risk-chip.active {
  background: linear-gradient(135deg, #ff3d6a, #a855f7);
  border-color: transparent; color: #fff;
}
.mines-risk-tier {
  display: inline-block; padding: 2px 8px; margin-left: 4px;
  font: 700 10px/1 inherit; letter-spacing: 0.06em; text-transform: uppercase;
  background: transparent;
  color: #fff; border: none;
}
/* Per-risk colour pills removed per user request — tier label reads as
   plain white text without a coloured background or border ring. */
.mines-risk-tier[data-risk="low"],
.mines-risk-tier[data-risk="medium"],
.mines-risk-tier[data-risk="high"],
.mines-risk-tier[data-risk="minimal"],
.mines-risk-tier[data-risk="max"] {
  color: #fff;
  background: transparent;
  border-color: transparent;
}

/* ============================================================
   ROULETTE — full felt betting table (desktop).
   Hidden on mobile; the existing .roul-type-grid handles phones.
   ============================================================ */
.roul-felt-table {
  display: grid;
  grid-template-columns: 48px 1fr;
  grid-template-rows: auto auto auto;
  grid-template-areas:
    "zero numbers"
    "gap  dozens"
    "gap  outside";
  gap: 4px;
  padding: 12px;
  background:
    radial-gradient(ellipse at top, rgba(255, 255, 255, 0.05) 0%, transparent 60%),
    linear-gradient(180deg, #0f5132 0%, #0a3a23 100%);
  border: 2px solid #caa45a;
  border-radius: 10px;
  box-shadow:
    inset 0 0 24px rgba(0, 0, 0, 0.45),
    0 2px 8px rgba(0, 0, 0, 0.3);
  font-family: var(--font-display);
  margin-bottom: 8px;
}
.roul-felt-table button {
  cursor: pointer;
  font-family: inherit;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.6);
  border: 1px solid rgba(0, 0, 0, 0.5);
  border-radius: 4px;
  transition: filter 0.12s ease, transform 0.08s ease;
  background: #141024;
}
.roul-felt-table button:hover { filter: brightness(1.25); }
.roul-felt-table button:active { transform: translateY(1px); }
.roul-felt-table .rft-zero {
  grid-area: zero;
  grid-row: span 2;
  background: #15803d;
  font-size: 20px;
  border: 1px solid rgba(0, 0, 0, 0.6);
  writing-mode: vertical-rl;
  text-orientation: mixed;
}
.roul-felt-table .rft-numbers {
  grid-area: numbers;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: repeat(3, 1fr);
  grid-auto-flow: column;
  gap: 2px;
}
.roul-felt-table .rft-numbers button {
  font-size: 13px; padding: 10px 0;
}
.roul-felt-table .rft-numbers .rft-red   { background: #b91c1c; }
.roul-felt-table .rft-numbers .rft-black { background: #141024; }
.roul-felt-table .rft-dozens {
  grid-area: dozens;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
}
.roul-felt-table .rft-dozens button { padding: 10px 0; font-size: 12px; letter-spacing: 0.04em; }
.roul-felt-table .rft-outside {
  grid-area: outside;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 2px;
}
.roul-felt-table .rft-outside button {
  padding: 10px 0; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
}
.roul-felt-table .rft-outside .rft-out-red   { background: #b91c1c; }
.roul-felt-table .rft-outside .rft-out-black { background: #141024; }
.roul-felt-table button.active {
  outline: 2px solid #ffb800;
  outline-offset: 1px;
  box-shadow: 0 0 12px rgba(255, 184, 0, 0.5);
}

/* The legacy compact button grid is no longer rendered anywhere — felt
   table covers every supported bet type on both desktop and mobile. */
body:not(.mobile) .roul-felt-mobile { display: none; }
.roul-type-grid { display: none !important; }

/* Mobile sizing tweaks for the full felt — keeps the 12-column number
   strip readable on phones by trimming padding + font + border-radius. */
body.mobile .roul-felt-table {
  padding: 6px;
  font-size: 11px;
  grid-template-columns: 32px 1fr;
  gap: 3px;
}
body.mobile .roul-felt-table .rft-zero {
  font-size: 14px;
  padding: 0;
}
body.mobile .roul-felt-table .rft-numbers { gap: 1px; }
body.mobile .roul-felt-table .rft-numbers button {
  font-size: 11px; padding: 6px 0; min-height: 28px;
}
body.mobile .roul-felt-table .rft-dozens button {
  padding: 8px 0; font-size: 11px; min-height: 32px;
}
body.mobile .roul-felt-table .rft-outside button {
  padding: 8px 0; font-size: 9px; min-height: 32px;
  letter-spacing: 0.04em;
}

/* Red/black diamond markers on the outside Red/Black cells. The cell
   bg is still the bet colour; the diamond is just a visual tell that
   matches a real felt table. */
.roul-felt-table .rft-diamond {
  display: inline-block;
  width: 0; height: 0;
  border: 7px solid transparent;
  transform: rotate(45deg);
  background: currentColor;
}
.roul-felt-table .rft-out-red   { background: #b91c1c; }
.roul-felt-table .rft-out-red .rft-diamond   { background: #fff; width: 14px; height: 14px; border: 1px solid #fff; }
.roul-felt-table .rft-out-black { background: #141024; }
.roul-felt-table .rft-out-black .rft-diamond { background: #fff; width: 14px; height: 14px; border: 1px solid #fff; }

/* ============================================================
   ROULETTE — mobile felt table.
   Stacked dozens with 44 px+ tap tiles, outside bets as 3×2.
   ============================================================ */
.roul-felt-mobile {
  display: flex; flex-direction: column; gap: 6px;
  padding: 10px;
  background:
    radial-gradient(ellipse at top, rgba(255, 255, 255, 0.05) 0%, transparent 60%),
    linear-gradient(180deg, #0f5132 0%, #0a3a23 100%);
  border: 2px solid #caa45a;
  border-radius: 10px;
  box-shadow:
    inset 0 0 24px rgba(0, 0, 0, 0.45),
    0 2px 8px rgba(0, 0, 0, 0.3);
  margin-bottom: 10px;
}
.roul-felt-mobile button {
  cursor: pointer; font-family: inherit; font-weight: 700;
  color: #fff; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.6);
  border: 1px solid rgba(0, 0, 0, 0.5); border-radius: 4px;
  background: #141024; min-height: 44px; font-size: 14px;
  transition: filter 0.12s ease;
}
.roul-felt-mobile button:active { filter: brightness(1.3); }
.roul-felt-mobile button.active {
  outline: 2px solid #ffb800; outline-offset: 1px;
  box-shadow: 0 0 12px rgba(255, 184, 0, 0.5);
}
.roul-felt-mobile .rfm-zero {
  background: #15803d; font-size: 20px; padding: 10px 0;
}
.roul-felt-mobile .rfm-dozen-group {
  display: flex; flex-direction: column; gap: 3px;
}
.roul-felt-mobile .rfm-dozen-head {
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.45));
  border: 1px solid rgba(202, 164, 90, 0.6);
  letter-spacing: 0.08em; text-transform: uppercase;
  font-size: 12px; padding: 10px 0;
}
.roul-felt-mobile .rfm-dozen-nums {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(3, 1fr);
  grid-auto-flow: column;
  gap: 3px;
}
.roul-felt-mobile .rfm-dozen-nums button { padding: 12px 0; font-size: 14px; }
.roul-felt-mobile .rfm-dozen-nums .rft-red   { background: #b91c1c; }
.roul-felt-mobile .rfm-dozen-nums .rft-black { background: #141024; }
.roul-felt-mobile .rfm-outside {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px;
  margin-top: 4px;
}
.roul-felt-mobile .rfm-outside button {
  padding: 12px 0; font-size: 11px;
  letter-spacing: 0.06em; text-transform: uppercase;
}
.roul-felt-mobile .rfm-outside .rft-out-red   { background: #b91c1c; }
.roul-felt-mobile .rfm-outside .rft-out-black { background: #141024; }

/* In-game primary action buttons (PLACE BET / SPIN / FLIP / DEAL / DROP
   BALL / START GAME / CASH OUT / PLACE CHIP) — match the login-modal
   "Continue" button (#auth-submit) so every primary CTA in the app
   wears the same flat dark-navy surface with a purple-tint hover.
   Earlier the buttons briefly went yellow/red when a default gradient
   leaked through; pinning every state with !important blocks that
   regression. */
.dice-roll-btn,
.crash-play-btn,
body.mobile .dice-roll-btn,
body.mobile .crash-play-btn,
body:not(.mobile) .dice-roll-btn,
body:not(.mobile) .crash-play-btn {
  /* Match `.field input:focus` — translucent dark navy fill with the
     cherry `#d91554` border. Reads as the same visual surface as a
     focused email/password input across the whole app. No blur, no
     pink fill — just the dark plate behind the cherry outline. The
     duplicate `body:not(.mobile)` / `body.mobile` selectors guarantee
     desktop and mobile resolve to the exact same pixels even if a
     cached / inherited rule tries to override one but not the other. */
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid #d91554 !important;
  border-radius: var(--r-pill) !important;
  color: #fff !important;
  font-weight: 700 !important;
  letter-spacing: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  filter: none !important;
}
.dice-roll-btn:hover,
.crash-play-btn:hover,
body.mobile .dice-roll-btn:hover,
body.mobile .crash-play-btn:hover,
body:not(.mobile) .dice-roll-btn:hover,
body:not(.mobile) .crash-play-btn:hover {
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid #d91554 !important;
  filter: none !important;
}
.dice-roll-btn:active,
.crash-play-btn:active,
body.mobile .dice-roll-btn:active,
body.mobile .crash-play-btn:active,
body:not(.mobile) .dice-roll-btn:active,
body:not(.mobile) .crash-play-btn:active {
  background: rgba(15, 8, 36, 0.85) !important;
  border: 2px solid #d91554 !important;
  transform: none !important;
}
.dice-roll-btn:disabled,
.crash-play-btn:disabled,
body.mobile .dice-roll-btn:disabled,
body.mobile .crash-play-btn:disabled,
body:not(.mobile) .dice-roll-btn:disabled,
body:not(.mobile) .crash-play-btn:disabled {
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid rgba(217, 21, 84, 0.5) !important;
  color: rgba(255, 255, 255, 0.55) !important;
  cursor: not-allowed !important;
  opacity: 1 !important;
  filter: none !important;
}

/* Modal-form primary CTAs (Save username, Change password, Verify TOTP,
   Save API URL) — share a dark-plate + red-pill look. Daily Claim was
   removed from this group so it now inherits the .btn-primary place-bet
   surface (red gradient over navy + subtle white border), matching the
   in-game PLACE BET button. .vip-claim-rb + .vip-claim-levelup stay here
   so the rank-page Claim buttons keep their existing treatment.
   #auth-submit keeps its own login-modal-specific rule via ID specificity. */
#totp-submit, #pwd-submit, #username-submit, #api-url-form button[type="submit"], .vip-claim-rb, .vip-claim-levelup,
#totp-submit:hover, #pwd-submit:hover, #username-submit:hover, #api-url-form button[type="submit"]:hover, .vip-claim-rb:hover, .vip-claim-levelup:hover,
#totp-submit:focus, #pwd-submit:focus, #username-submit:focus, #api-url-form button[type="submit"]:focus, .vip-claim-rb:focus, .vip-claim-levelup:focus {
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid #d91554 !important;
  border-radius: var(--r-pill) !important;
  color: #fff !important;
  font-weight: 700 !important;
  letter-spacing: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  filter: none !important;
  transform: none !important;
}
#totp-submit:active, #pwd-submit:active, #username-submit:active, #api-url-form button[type="submit"]:active, .vip-claim-rb:active, .vip-claim-levelup:active {
  background: rgba(15, 8, 36, 0.85) !important;
  border: 2px solid #d91554 !important;
  transform: none !important;
}
#totp-submit:disabled, #pwd-submit:disabled, #username-submit:disabled, #api-url-form button[type="submit"]:disabled, .vip-claim-rb:disabled, .vip-claim-levelup:disabled {
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid rgba(217, 21, 84, 0.5) !important;
  color: rgba(255, 255, 255, 0.55) !important;
  cursor: not-allowed !important;
  opacity: 1 !important;
  filter: none !important;
}

/* Auth "Login" / "Sign up" submit — no white border in any state (rest /
   hover / focus / active). Hover mirrors the coin-picker item hover
   (purple-tinted 12% alpha) instead of the default red-gradient brighten.
   Applies on both desktop and mobile. */
#auth-submit,
body.mobile #auth-submit {
  border: none !important;
  /* Shape + size lifted from the reference "Welcome back" CTA — full pill,
     56 px tall, 20 px bold text, generous horizontal padding. SOLID fill
     (no translucency, no border, no drop shadow) to match the reference. */
  width: 100% !important;
  min-height: 56px !important;
  padding: 16px 20px !important;
  border-radius: 999px !important;
  font-size: 20px !important;
  font-weight: 700 !important;
  line-height: 1.2 !important;
  letter-spacing: 0 !important;
  /* Idle (fields empty / invalid) — SOLID disabled plate, no translucent
     overlay. Single opaque dark colour, muted text, not-allowed cursor. */
  background: #2b1e4a !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  color: rgba(255, 255, 255, 0.38) !important;
  cursor: not-allowed !important;
  box-shadow: none !important;
  transition: background 0.15s, color 0.15s !important;
}
/* Match `.field input:focus` — translucent dark navy fill with the
   cherry `#d91554` border. Continue / Create when the form is valid
   reads as the same surface as the focused email/password input above
   it, so the auth panel is one cohesive pill stack. */
#auth-submit.is-ready,
body.mobile #auth-submit.is-ready,
#auth-submit.is-ready:hover,
#auth-submit.is-ready:focus,
body.mobile #auth-submit.is-ready:hover,
body.mobile #auth-submit.is-ready:focus {
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid #d91554 !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  color: #fff !important;
  box-shadow: none !important;
  filter: none !important;
  transform: none !important;
}
/* Kill the browser focus ring / any box-shadow halo on the login modal's
   interactive elements — the user explicitly asked for no "glowing border"
   around Continue/Create account or around the Login/Join tabs. */
#auth-submit:focus,
#auth-submit:focus-visible,
#auth-submit:active,
.auth-tabs .tab:focus,
.auth-tabs .tab:focus-visible,
.auth-tabs .tab:active {
  outline: none !important;
  box-shadow: none !important;
}
/* No hover overlay — user wants the idle state to look identical whether
   hovered or not. Flatten filter, transform, and keep the base bg. */
#auth-submit:hover,
#auth-submit:focus,
body.mobile #auth-submit:hover,
body.mobile #auth-submit:focus {
  background: #2b1e4a !important;
  border: none !important;
  color: rgba(255, 255, 255, 0.38) !important;
  cursor: not-allowed !important;
  filter: none !important;
  transform: none !important;
  box-shadow: none !important;
}
/* Ready state overrides the disabled cursor — pointer is back when the
   form can actually be submitted. */
#auth-submit.is-ready,
body.mobile #auth-submit.is-ready {
  cursor: pointer !important;
}

/* Ops console iframe */
.ops-iframe {
  width: 100%;
  height: calc(100dvh - 200px);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 10px;
  background: #0a0618;
}

/* Blackjack basic-strategy hint row */
.bj-hint-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  font-family: var(--font-ui);
  font-size: 12px; font-weight: 700; letter-spacing: -0.01em;
  color: rgba(255,255,255,0.7);
  cursor: pointer;
  user-select: none;
}
.bj-hint-row input[type="checkbox"] { accent-color: var(--primary); }
.bj-hint-suggested { outline: 2px solid #ffb800 !important; outline-offset: 1px; }
.bj-hint-dimmed { opacity: 0.55; }

/* Plinko segmented Rows + Risk picker — replaces the two stacked
   dropdowns with a single horizontal segmented strip per row. Tap-to-
   pick, no dropdown overlay. Saves vertical space and 2 taps per
   round, lifting CR. */
.plinko-segmented-row {
  display: flex; flex-direction: column; gap: 6px;
  padding: 0 2px;
}
.plinko-seg {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  gap: 4px;
}
.plinko-seg-btn {
  padding: 8px 4px;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--r-md);
  color: #fff;
  font-family: var(--font-ui);
  font-size: 12px; font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.plinko-seg-btn:hover { background: rgba(255, 255, 255, 0.12); }
.plinko-seg-btn.active {
  /* Same translucent glass-chip look as the DROP BALL button (.btn-primary):
     red-tinted gradient at 35% alpha over a dark navy plate, white text,
     subtle border. No solid pink fill. */
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55);
  border-color: var(--primary);
  color: #fff;
}
.plinko-hidden-select {
  position: absolute !important;
  width: 1px !important; height: 1px !important;
  opacity: 0 !important; pointer-events: none !important;
  left: -9999px !important;
}

/* Plinko multi-ball slider row */
.plinko-balls-row {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 10px;
  font-family: var(--font-ui);
  font-size: 12px; font-weight: 700;
  color: rgba(255,255,255,0.7);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
/* Plinko balls range slider — brand-styled track (dark) + cherry-pink
   thumb instead of the browser's gray default that read as "broken
   UI bar" against the dark game chrome. */
.plinko-balls-row input[type="range"] {
  flex: 1;
  -webkit-appearance: none;
  appearance: none;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.1);
  outline: none;
}
.plinko-balls-row input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #d91554;
  cursor: pointer;
  border: 2px solid #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}
.plinko-balls-row input[type="range"]::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #d91554;
  cursor: pointer;
  border: 2px solid #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}
.plinko-balls-row strong { color: #fff; }

/* Slots "stop autoplay on big win" toggle. Text colour matches the dice
   panel's bright Multiplier / Chance label so the slots controls panel
   reads as "lit up" the same way. */
.slots-stop-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  font-family: var(--font-ui);
  font-size: 12px; font-weight: 700; letter-spacing: -0.01em;
  color: var(--text);
  cursor: pointer; user-select: none;
}
.slots-stop-row input[type="checkbox"] { accent-color: var(--primary); }

/* Dice chance-top label shown next to the direction toggle */
.dice-chance-top {
  font-family: var(--font-ui);
  font-size: 12px; font-weight: 700; letter-spacing: -0.01em;
  color: rgba(255,255,255,0.7);
  font-variant-numeric: tabular-nums;
  margin-left: 10px;
  white-space: nowrap;
}

/* Simplified Roulette number grid — zero + 1-36 clickable tiles.
   The existing wireRouletteFullTable() auto-populates #roul-felt-numbers
   with .rft-red / .rft-black coloured buttons and delegates clicks on
   #roul-felt-table to r-type/r-number. */
.roul-simple-grid {
  display: grid;
  grid-template-columns: 48px 1fr;
  gap: 4px;
  padding: 10px;
  background:
    radial-gradient(ellipse at top, rgba(255, 255, 255, 0.05) 0%, transparent 60%),
    linear-gradient(180deg, #0f5132 0%, #0a3a23 100%);
  border: 2px solid #caa45a;
  border-radius: 10px;
  box-shadow: inset 0 0 24px rgba(0, 0, 0, 0.45), 0 2px 8px rgba(0, 0, 0, 0.3);
  margin-bottom: 10px;
}
.roul-num-zero {
  background: #15803d;
  color: #fff;
  font-weight: 700;
  font-size: 20px;
  border: 1px solid rgba(0, 0, 0, 0.6);
  border-radius: 4px;
  cursor: pointer;
  writing-mode: vertical-rl;
  text-orientation: mixed;
  padding: 6px 0;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.6);
  transition: filter 0.12s ease, transform 0.08s ease;
}
.roul-num-zero:hover { filter: brightness(1.25); }
.roul-num-zero:active { transform: translateY(1px); }
.roul-num-zero.active {
  outline: 2px solid #ffb800;
  outline-offset: 1px;
  box-shadow: 0 0 12px rgba(255, 184, 0, 0.5);
}
.roul-simple-nums {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: repeat(3, 1fr);
  grid-auto-flow: column;
  gap: 3px;
}
.roul-simple-nums button {
  padding: 10px 0;
  font-family: inherit;
  font-weight: 700;
  font-size: 13px;
  color: #fff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.6);
  border: 1px solid rgba(0, 0, 0, 0.5);
  border-radius: 4px;
  cursor: pointer;
  transition: filter 0.12s ease, transform 0.08s ease;
}
.roul-simple-nums button:hover { filter: brightness(1.25); }
.roul-simple-nums button:active { transform: translateY(1px); }
.roul-simple-nums .rft-red   { background: #b91c1c; }
.roul-simple-nums .rft-black { background: #141024; }
.roul-simple-nums button.active {
  outline: 2px solid #ffb800;
  outline-offset: 1px;
  box-shadow: 0 0 12px rgba(255, 184, 0, 0.5);
}
body.mobile .roul-simple-grid { padding: 8px; grid-template-columns: 38px 1fr; gap: 3px; }
body.mobile .roul-num-zero { font-size: 16px; }
body.mobile .roul-simple-nums { gap: 2px; }
body.mobile .roul-simple-nums button { padding: 8px 0; font-size: 11px; }

/* Roulette sticky controls — same pattern as cf-controls-sticky / dice-controls-sticky.
   Keeps the coin + amount + SPIN row pinned above the bottom nav on mobile,
   so the wheel + number grid can scroll above without the SPIN button ever
   getting hidden or overlapping the tab bar. */
body.mobile .roul-controls-sticky {
  position: fixed !important;
  left: 8px; right: 8px;
  bottom: calc(60px + env(safe-area-inset-bottom, 0)) !important;
  flex-shrink: 0;
  display: flex; flex-direction: column; gap: 6px;
  background: rgba(15, 8, 36, 0.3);
  backdrop-filter: blur(18px) saturate(140%); -webkit-backdrop-filter: blur(18px) saturate(140%);
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 14px;
  z-index: 50;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.5);
  isolation: isolate;
}
body.mobile .roul-controls-sticky::before {
  content: "";
  position: absolute; inset: 0;
  background: rgba(15, 8, 36, 0.7);
  border-radius: inherit;
  z-index: -1;
  pointer-events: none;
}
body.mobile .roul-controls-sticky .dice-bet-row,
body.mobile .roul-controls-sticky .autoplay-row {
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
  margin: 0 !important;
}
/* Cancel the global `body.mobile .autoplay-row { position: fixed }` rule
   when the autoplay-row sits inside the roulette sticky wrapper —
   otherwise it floats independently at the bottom of the viewport and
   visually overlaps the wrapper's potential-win + quick-chips rows
   (the chevron + SPIN button float above the rest). Slots / coinflip /
   mines / plinko / dice already have the matching static-reset; this
   adds it for roulette. */
body.mobile .roul-controls-sticky .autoplay-row {
  position: static !important;
  left: auto !important; right: auto !important; bottom: auto !important;
  backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  z-index: auto !important;
}
body.mobile .roul-controls-sticky .autoplay-row::before {
  display: none !important;
}
/* Reserve bottom padding on the scrollable game-layout so the last row
   of the number grid doesn't get covered by the fixed sticky panel. */
body.mobile #page-roulette.active .game-layout { padding-bottom: 200px; }
body:not(.logged-in) .roul-controls-sticky { display: none !important; }
body.mobile .page:not(.active) .roul-controls-sticky { display: none; }

/* ======================================================================
   Roulette mobile layout — content (wheel + felt + Red/Black grid + Hot/
   Cold) is ~700px, far taller than the 42dvh budget the shared rule
   applies to every game. The 42dvh cap caused content to paint outside
   .game-layout and overlap the bets-panel below. Override to size the
   game column to content, give the bets panel a natural top margin so
   it never touches the Hot/Cold widget, and shrink the felt + wheel
   slightly so the page still scrolls only a little.
   ====================================================================== */
body.mobile #page-roulette.active .live-layout {
  /* Stack column: game above, bets-panel below. Auto height — the
     content takes as much as it needs and the page scrolls. */
  display: flex !important;
  flex-direction: column !important;
  height: auto !important;
  min-height: 100% !important;
  gap: 14px !important;
}
body.mobile #page-roulette.active .live-layout > .game-layout {
  /* Content-sized — was `flex: 0 0 42dvh` (shared with dice/coinflip).
     Roulette has ~700px of mandatory content, which 42dvh can't hold. */
  flex: 0 0 auto !important;
  height: auto !important;
  min-height: 0 !important;
  /* Drop the 200px hack padding-bottom that used to mask the overlap;
     live-layout's --sticky-h-based padding handles the sticky CTA reserve.
     Keep a small gap so the panel below isn't flush against the felt. */
  padding-bottom: 0 !important;
  margin-bottom: 8px;
}
body.mobile #page-roulette.active .roul-wheel-wrap,
body.mobile #page-roulette.active .game-display {
  /* Wheel was 320px on mobile, forced everything else off-screen. Shrink
     to ~250px so the felt + Hot/Cold sit in viewport on a typical phone
     without making the wheel pixelated. */
  min-height: 250px !important;
  height: 250px !important;
}
/* Result number ("31") lifts out of the flex flow and overlays the
   bottom-centre of the wheel area instead of sitting in the empty band
   below it. The label still flows underneath so it appears just above
   the felt. */
#page-roulette .game-display {
  position: relative;
  /* Match the 3D scene's felt + backdrop tones so the surface doesn't flash
     a bright purple card while the WebGL canvas is still mounting / loading
     three.js. Once the renderer has its first frame, the canvas covers this,
     but those first ~100 ms used to read as a bright violet glow. */
  background: #082a18;
}
#page-roulette .big-result {
  /* Anchored to the silver pin on the wheel hub — the visual centre
     of the 3D wheel itself, not the canvas. The wheel renders below
     canvas centre (camera looks at y:0.6), so top:62% lands the
     digit's centre on the pin. */
  position: absolute;
  top: 62%;
  left: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  width: max-content;
  z-index: 5;
  pointer-events: none;
  text-align: center;
  line-height: 1;
  padding: 0;
  /* 2 px white outline around the digit. paint-order: stroke fill puts
     the stroke beneath the fill so the visible outline is the outer
     half, keeping the digit interior the roulette colour (red/black/
     green) and making the numeral read on the dark wheel hub. */
  -webkit-text-stroke: 2px #fff;
  paint-order: stroke fill;
}
/* Roulette result number wears its roulette colour: red numbers in red,
   black numbers in black (white halo so they're visible on the dark
   wheel hub), zero in green. Cancels the default gradient/clip text
   used elsewhere by .big-result and the .win/.lose outcome variants. */
#page-roulette .big-result.roul-red,
#page-roulette .big-result.roul-black,
#page-roulette .big-result.roul-green {
  background: none !important;
  -webkit-background-clip: border-box !important;
  background-clip: border-box !important;
  -webkit-text-fill-color: currentColor !important;
}
#page-roulette .big-result.roul-red   { color: #ef4444; }
#page-roulette .big-result.roul-black { color: #000; }
#page-roulette .big-result.roul-green { color: #22c55e; }
/* Result label below the wheel — rendered as a small rounded pill
   matching the recent-history cards. Roulette colour drives the
   background, white text inside, soft corners. The base
   .big-result-label rule has it spanning full width via
   left:0/right:0; constrain to inline-block so the pill hugs the
   text only. */
#page-roulette .big-result-label.roul-red,
#page-roulette .big-result-label.roul-black,
#page-roulette .big-result-label.roul-green {
  left: 50% !important;
  right: auto !important;
  transform: translateX(-50%);
  width: auto;
  display: inline-block;
  padding: 6px 14px;
  border-radius: 8px;
  color: #fff !important;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 800;
}
#page-roulette .big-result-label.roul-red   { background: #dc2626; }
#page-roulette .big-result-label.roul-black { background: #111114; }
#page-roulette .big-result-label.roul-green { background: #15803d; }
#page-roulette .big-result-label {
  position: absolute;
  left: 0; right: 0; bottom: 8px;
  margin: 0;
  z-index: 4;
  pointer-events: none;
}
body.mobile #page-roulette.active .roul-simple-grid,
body.mobile #page-roulette.active .roul-type-grid,
body.mobile #page-roulette.active .hot-cold {
  /* Tighten the three info widgets so the column doesn't overshoot. */
  flex-shrink: 0;
}
body.mobile #page-roulette.active .hot-cold {
  padding: 10px 12px;
}
body.mobile #page-roulette.active .hot-cold-row { gap: 8px; }
body.mobile #page-roulette.active .hot-cold-nums,
body.mobile #page-roulette.active .hot-cold-recent { gap: 4px; }
/* The bets panel below — let it size to content with a comfortable
   minimum, no longer competing with .game-layout for a 42dvh slot. */
body.mobile #page-roulette.active .crash-bets-panel {
  flex: 0 0 auto !important;
  min-height: 50dvh !important;
  margin-top: 0 !important;
}
/* In bets-shown mode the global rule absolute-positions the bets panel
   at top: 18dvh — but roulette's game-layout is content-sized (wheel
   + felt + hot/cold ≈ 700px), so the felt's lower rows ended up
   overlapping the absolute panel. Revert to static flow for roulette
   so the panel sits naturally below the felt and the page scrolls. */
body.mobile #page-roulette.bets-shown .crash-bets-panel,
body.mobile #page-roulette.bets-shown .crash-bets-panel.collapsed {
  position: static !important;
  top: auto !important; bottom: auto !important;
  left: auto !important; right: auto !important;
  width: auto !important; height: auto !important;
  flex: 0 0 auto !important;
  min-height: 50dvh !important;
}
body.mobile #page-roulette.bets-shown .live-layout > .game-layout {
  flex: 0 0 auto !important;
  height: auto !important;
  min-height: 0 !important;
}
/* Override the page-level overflow so the parent does the scrolling
   (live-layout itself stays auto-height). Without this, the inner
   `min-height: 100%` would create a stuck container. */
body.mobile #page-roulette.active {
  overflow-y: auto !important;
  height: auto !important;
  min-height: calc(100dvh - 128px - env(safe-area-inset-bottom, 0)) !important;
}

/* ======================================================================
   Coinflip + Dice mobile layout — scroll-stack pattern (same as roulette)
   so the bets feed sits BELOW the canvas in normal flow without
   squeezing it. Both games' canvases get the same explicit floor (42dvh
   wrapper + 38dvh canvas inside) so they render at identical visual
   size. Earlier dice rendered noticeably shorter than coinflip because
   the dice wrapper's flex-basis wasn't pinned and the canvas had no
   floor.
   ====================================================================== */
body.mobile #page-coinflip.active,
body.mobile #page-dice.active,
body.mobile #page-slots.active,
body.mobile #page-mines.active,
body.mobile #page-plinko.active,
body.mobile #page-blackjack.active {
  overflow-y: auto !important;
  height: auto !important;
  min-height: calc(100dvh - 128px - env(safe-area-inset-bottom, 0)) !important;
}
body.mobile #page-coinflip.active .live-layout,
body.mobile #page-dice.active .live-layout,
body.mobile #page-slots.active .live-layout,
body.mobile #page-mines.active .live-layout,
body.mobile #page-plinko.active .live-layout,
body.mobile #page-blackjack.active .live-layout {
  display: flex !important;
  flex-direction: column !important;
  height: auto !important;
  min-height: 100% !important;
  gap: 14px !important;
}
body.mobile #page-coinflip.active .live-layout > .game-layout,
body.mobile #page-dice.active .live-layout > .dice-game,
body.mobile #page-slots.active .live-layout > .game-layout,
body.mobile #page-mines.active .live-layout > .game-layout,
body.mobile #page-plinko.active .live-layout > .game-layout,
body.mobile #page-blackjack.active .live-layout > .game-layout {
  /* Pinned wrapper — was content-sized which let the inner canvas
     collapse below 30dvh. 42dvh keeps the canvas large and consistent
     across the games. */
  flex: 0 0 42dvh !important;
  height: auto !important;
  min-height: 42dvh !important;
  margin-bottom: 8px;
}
body.mobile #page-coinflip.active .live-layout > .crash-bets-panel,
body.mobile #page-dice.active .live-layout > .crash-bets-panel,
body.mobile #page-slots.active .live-layout > .crash-bets-panel,
body.mobile #page-mines.active .live-layout > .crash-bets-panel,
body.mobile #page-plinko.active .live-layout > .crash-bets-panel,
body.mobile #page-blackjack.active .live-layout > .crash-bets-panel {
  flex: 0 0 auto !important;
  min-height: 50dvh !important;
  margin-top: 0 !important;
}
/* Canvas inside the wrapper — fills whatever the 42dvh wrapper hands it
   after the recent-hero strip takes its share. Earlier this rule had
   `min-height: 38dvh` which made the coinflip canvas claim 38dvh while
   the cf-recent-hero (~50px in normal flow) ate another ~6dvh, totalling
   more than the 42dvh wrapper — the canvas spilled over and visually
   overlapped the bets-panel below. Dice didn't have the issue because
   .dice-history is position:absolute and takes 0 flex space. Slots
   .game-display contains .reels (flex-shrink: 0, content height); the
   wrapper takes the rest. */
body.mobile #page-dice.active .dice-canvas-wrap,
body.mobile #page-coinflip.active .game-display,
body.mobile #page-slots.active .game-display,
body.mobile #page-mines.active .mines-stage,
body.mobile #page-plinko.active .plinko-stage,
body.mobile #page-blackjack.active .blackjack-stage {
  flex: 1 1 auto !important;
  height: auto !important;
  min-height: 0 !important;
}
/* In bets-shown mode for coinflip / dice / slots / mines / plinko /
   blackjack / crash, drop the global absolute-positioning in favour of
   static flow (matches roulette) so the panel sits below the canvas
   without overlapping it. */
body.mobile #page-coinflip.bets-shown .crash-bets-panel,
body.mobile #page-coinflip.bets-shown .crash-bets-panel.collapsed,
body.mobile #page-dice.bets-shown .crash-bets-panel,
body.mobile #page-dice.bets-shown .crash-bets-panel.collapsed,
body.mobile #page-slots.bets-shown .crash-bets-panel,
body.mobile #page-slots.bets-shown .crash-bets-panel.collapsed,
body.mobile #page-mines.bets-shown .crash-bets-panel,
body.mobile #page-mines.bets-shown .crash-bets-panel.collapsed,
body.mobile #page-plinko.bets-shown .crash-bets-panel,
body.mobile #page-plinko.bets-shown .crash-bets-panel.collapsed,
body.mobile #page-blackjack.bets-shown .crash-bets-panel,
body.mobile #page-blackjack.bets-shown .crash-bets-panel.collapsed,
body.mobile #page-crash.bets-shown .crash-bets-panel,
body.mobile #page-crash.bets-shown .crash-bets-panel.collapsed {
  position: static !important;
  top: auto !important; bottom: auto !important;
  left: auto !important; right: auto !important;
  width: auto !important; height: auto !important;
  flex: 0 0 auto !important;
  min-height: 50dvh !important;
}
body.mobile #page-coinflip.bets-shown .live-layout > .game-layout,
body.mobile #page-dice.bets-shown .live-layout > .dice-game,
body.mobile #page-slots.bets-shown .live-layout > .game-layout,
body.mobile #page-mines.bets-shown .live-layout > .game-layout,
body.mobile #page-plinko.bets-shown .live-layout > .game-layout,
body.mobile #page-blackjack.bets-shown .live-layout > .game-layout {
  flex: 0 0 42dvh !important;
  height: auto !important;
  min-height: 42dvh !important;
}

/* Place Bet / play CTAs across every game share the auth-submit
   background. Solid `#0f0824` (= body --bg-deep, same RGB as the
   `.field input:focus` rgba) so the live crash canvas / sticky panel
   backdrop can't bleed through and tint the button — translucent
   rgba looked purple inside .crash-controls because that panel uses
   `backdrop-filter: saturate(140%)`. Applied in every state to
   override the per-button hover gradients and the mobile #1a0f3d fill
   set earlier. */
/* Duplicate of the canonical CTA rule above — same restoration applies:
   only assert color so the .btn-primary glass-gradient (red over navy
   plate, soft border, depth shadow, blur) shows through. */
.dice-roll-btn,
.dice-roll-btn:hover,
.dice-roll-btn:focus,
.dice-roll-btn:active,
.crash-play-btn,
.crash-play-btn:hover,
.crash-play-btn:focus,
.crash-play-btn:active,
body.mobile .dice-roll-btn,
body.mobile .dice-roll-btn:hover,
body.mobile .dice-roll-btn:focus,
body.mobile .dice-roll-btn:active,
body.mobile .crash-play-btn,
body.mobile .crash-play-btn:hover,
body.mobile .crash-play-btn:focus,
body.mobile .crash-play-btn:active {
  color: #fff !important;
}

/* ============================================================
   TOUCH-DEVICE HOVER SUPPRESSION
   ------------------------------------------------------------
   On phones / tablets with no hover capability, browsers leave
   :hover styles applied AFTER a tap — the element looks "stuck
   highlighted" until the user taps elsewhere. (`mtab`,
   `nav-btn`, every button — project-wide.) The standards-
   compliant fix is to gate hover-only effects on
   `@media (hover: hover)`, but the codebase has 140+ :hover
   rules and wrapping each one is invasive.
   This block achieves the same outcome with one universal
   override: on devices that genuinely cannot hover, neutralise
   the hover-effect properties that visually persist after tap
   (transform-lift, filter-brightness, hover background overlay,
   coloured glow shadow, hover-only text/border colour).
   Properties not touched: opacity, cursor, transition (cheap),
   so the rule has minimal side-effects.
   ============================================================ */
@media (hover: none) {
  a:hover,
  button:hover,
  [role="button"]:hover,
  input:hover,
  select:hover,
  textarea:hover,
  label:hover,
  [class]:hover {
    transform: none !important;
    filter: none !important;
  }
  /* The most disruptive sticky effect is the background-overlay shift
     used by .nav-btn / .mtab / .tab / .crash-tab / etc. — the tab keeps
     a highlighted background until the user taps elsewhere. Force these
     surfaces back to their non-hover background. */
  .nav-btn:hover,
  .mtab:hover,
  .tab:hover,
  .crash-tab:hover,
  .seg:hover,
  .filter:hover,
  .tb-icon-btn:hover,
  .tb-btn:hover,
  .nav-fav:hover,
  .auth-tabs .tab:hover,
  .coin-picker-item:hover,
  .user-menu-item:hover,
  .wd-pill:hover,
  .field-eye:hover,
  .crash-pill:hover,
  .crash-fair-badge:hover,
  .lc-toggle:hover {
    background: transparent !important;
  }
  /* Buttons that have a coloured base background — restore the base on
     hover (already done in `body.mobile` overrides above for some, this
     covers the rest). */
  .btn:hover,
  .btn-ghost:hover,
  .deposit-copy:hover,
  .withdraw-max:hover,
  .withdraw-submit:hover {
    box-shadow: none !important;
  }
}


/* ============================================================
   BetsFeed — coin-filter pills, big-win celebration overlay,
   per-tab column visibility (Live shows X-game label, Big Wins
   and Mine show X-multiplier), "YOU" row highlight.
   ============================================================ */

/* Coin filter row — sits above the column header, scrolls horizontally
   on narrow phones. Active pill fills with the same red as the
   focused-input border so it reads as the same control family. */
.bets-coin-row {
  display: flex; gap: 6px; padding: 8px 8px 4px;
  overflow-x: auto; scrollbar-width: none;
}
.bets-coin-row::-webkit-scrollbar { display: none; }
.bets-coin-pill {
  flex: 0 0 auto;
  padding: 6px 12px;
  background: #1a0f3d;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  color: var(--text-muted);
  font-family: var(--font-ui); font-size: 11px; font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: 0.12s;
}
.bets-coin-pill.active {
  background: #d91554;
  border-color: #d91554;
  color: #fff;
}

/* Live tab Win cell uses the same green as Big Wins for resolved wins —
   the dimmed-text override was removed so .crash-bet-row.won .win-v from
   the base rule wins (cherry green, weight 700). Pending rows still dim
   via the .pending rule below. */

/* Pending bet — placed but not yet resolved by the round timer. Render
   identically to a resolved row so the user's own row never looks dim
   or grayed-out (operator preference: standard text colour, no opacity
   shift). The "…" placeholders in X / Win cells are enough of an
   in-flight signal. */
.crash-bet-row.pending .x,
.crash-bet-row.pending .win-v {
  color: var(--text-dim) !important;
  font-weight: 500;
}

/* "You" row highlight — disabled per UX request. Own bets render
   identically to every other row. The `(you)` suffix in the name
   column is enough to spot yourself without changing row chrome. */

/* Big-win celebration cards (e.g. "Mehmet just won 17×") are permanently
   disabled at operator request — too large, distracting, and overlapped
   the auth modal. The JS no-op in `maybeCelebrate` should already prevent
   them from being created, but this CSS rule kills any leftover instance
   from a stale client-side cache (Telegram WebView, Capacitor OTA bundle,
   browser cache). To re-enable, remove this rule AND restore the body of
   `maybeCelebrate` in app.js. */
#big-win-host,
.big-win-card { display: none !important; }
#big-win-host {
  position: fixed;
  bottom: calc(140px + env(safe-area-inset-bottom, 0));
  left: 50%; transform: translateX(-50%);
  flex-direction: column-reverse; gap: 8px;
  z-index: 200;
  pointer-events: none;
}
.big-win-card {
  pointer-events: auto;
  min-width: 240px; max-width: 90vw;
  padding: 14px 22px;
  background: linear-gradient(135deg, #ffb800 0%, #d91554 100%);
  border-radius: 16px;
  color: #fff; text-align: center;
  font-family: var(--font-ui);
  box-shadow: 0 12px 32px rgba(217, 21, 84, 0.45);
  animation: big-win-in 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.big-win-card.leave {
  animation: big-win-out 0.5s ease forwards;
}
.big-win-mult {
  font-family: var(--font-display);
  font-size: 36px; font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1;
}
.big-win-line { font-size: 12px; font-weight: 600; margin-top: 4px; opacity: 0.92; }
.big-win-amount {
  margin-top: 6px;
  font-family: var(--font-num);
  font-size: 16px; font-weight: 700;
}
@keyframes big-win-in {
  from { transform: translate(-50%, 30px) scale(0.85); opacity: 0; }
  to   { transform: translate(-50%, 0)    scale(1);    opacity: 1; }
}
@keyframes big-win-out {
  from { transform: translate(-50%, 0) scale(1);    opacity: 1; }
  to   { transform: translate(-50%, 0) scale(0.95); opacity: 0; }
}

/* ================================================================
   LIGHTER.XYZ aesthetic pass — sharp corners, hairline borders,
   ALL-CAPS letter-spaced headers, monospace numbers, no glows.
   Purple/cherry/gold palette preserved. Game canvases unchanged.
   Reversible: delete this whole block to revert to the previous look.
   ================================================================ */

/* Headers — ALL CAPS, letter-spaced. The casino's content-section h1/h2
   already use a custom font; we just lift them into the lighter.xyz
   typographic register. */
.page-title,
h2.section-title,
.stat-label {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
}

/* Sharp button corners — replaces the rounded "pill" look with crisp
   trade-execute slabs. Avatars + icon-only round buttons keep their
   own border-radius via more specific rules earlier in the file. */
.btn, .btn-primary, .btn-ghost, .btn-secondary, .btn-sm,
button.dice-roll-btn, .crash-play-btn,
.update-modal .btn, .changelog-modal .btn {
  border-radius: 4px;
}

/* Sharp card corners + hairline borders, no shadows. Replaces the
   glow/blur "premium" treatment with finance-tool minimalism. */
.stat-card, .fair-card, .aff-code-row, .aff-bonus-card,
.coin-picker-list, .update-modal, .changelog-modal {
  border-radius: 4px;
  box-shadow: none;
}
.stat-card, .fair-card {
  border: 1px solid rgba(255, 255, 255, 0.06);
}

/* Inputs — sharp, no focus glow (already enforced by CLAUDE.md rule;
   re-stating here so the aesthetic block is self-contained). */
.input, .select, textarea {
  border-radius: 3px;
  box-shadow: none;
}
.input:focus, .select:focus, textarea:focus {
  box-shadow: none;
}

/* Tabular nums everywhere money / multipliers / counts appear. Forces
   each digit to occupy the same width so columns line up vertically —
   the trading-app feel for any list of numbers. */
.balance, .stat-value, .aff-bonus-amount,
.wd-amount-value, .coin-picker-bal, .coin-picker-fiat,
.crash-bet-row, .crash-bets-header,
.crash-bet-row > .x, .crash-bet-row > .bet, .crash-bet-row > .win-v,
.dice-history-pill, .big-wins-item, .big-wins-x,
.aff-tg-link {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* Big numerical heroes — push them toward monospace so the numbers
   themselves feel data-grade. Falls back gracefully if the user's
   system doesn't have JetBrains Mono. */
.stat-value, .aff-bonus-amount {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: -0.01em;
}

/* Tighter top-level page padding — pulls content closer to the edges
   so each pixel works harder. Mobile keeps its existing tighter pad. */
body:not(.mobile) .page { padding: 14px 18px; }

/* Top-nav coin-picker pill — slightly squarer for parity with the
   surrounding sharp-corner language. */
.coin-pill, .coin-picker-row { border-radius: 4px; }

/* Game-grid landing (Home page). Flat tiles, hairline border, no card-pill
   background, no transform on hover — only a brightness pulse + accent
   border tint. Mirrors the restrained Cloudbet game-card treatment.
   Eight in-house games arranged 4-up on desktop, 2-up on narrow screens. */
.home-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  max-width: 880px;
}
.home-card {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px;
  aspect-ratio: 1 / 1;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 14px;
  color: var(--text);
  cursor: pointer;
  font-family: var(--font-ui);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  overflow: hidden;
  /* Suppress Telegram WebView's default grey tap-highlight overlay so
     the cherry-pink :active glow underneath actually shows through —
     same fix the games-picker-tile uses. Without this, the OS-level
     highlight covered our radial gradient and the home cards looked
     like they had no tap effect at all. */
  -webkit-tap-highlight-color: transparent;
  transition: border-color 0.18s ease, transform 0.18s ease, background 0.18s ease;
}
/* Subtle glow that brightens on hover — sits behind the icon + label so
   it never obscures them. Pre-rendered as a transparent radial layer so
   the transition is just opacity, not a recompute. */
.home-card::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(120% 100% at 50% 0%, rgba(217, 21, 84, 0.18) 0%, transparent 65%);
  opacity: 0;
  transition: opacity 0.18s ease;
  pointer-events: none;
}
/* Glow + lift fires on `:active` so it actually shows on phones (where
   `:hover` is unreliable / sticky); desktop's `:hover` is wrapped in
   the (hover: hover) media query so cursor users still get it without
   it ever activating on touch. */
.home-card:active {
  border-color: rgba(217, 21, 84, 0.55);
  background: rgba(28, 16, 64, 0.65);
  transform: translateY(-1px);
}
.home-card:active::before { opacity: 1; }
@media (hover: hover) {
  .home-card:hover {
    border-color: rgba(217, 21, 84, 0.55);
    background: rgba(28, 16, 64, 0.65);
    transform: translateY(-1px);
  }
  .home-card:hover::before { opacity: 1; }
}
/* Suppress the WebView's default <button>:focus blue fill — on Android
   Chrome / Telegram, after tapping a card it keeps focus and the OS
   paints the whole tile bright blue, drowning the design. We force the
   focus background back to the default plate and only show a cherry-pink
   rim when keyboard nav is actually in use (:focus-visible).  */
.home-card:focus {
  outline: none;
  background: rgba(15, 8, 36, 0.55);
  border-color: rgba(255, 255, 255, 0.06);
}
.home-card:focus:not(:focus-visible)::before { opacity: 0; }
.home-card:focus-visible {
  outline: none;
  border-color: rgba(217, 21, 84, 0.55);
}
.home-card-i {
  width: 44px; height: 44px;
  stroke: #fff; stroke-width: 1.6;
  opacity: 0.95;
  position: relative;
}
.home-card-name {
  position: relative;
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  letter-spacing: -0.01em;
}
@media (max-width: 720px) {
  .home-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
  .home-card { gap: 12px; border-radius: 12px; }
  .home-card-i { width: 40px; height: 40px; }
}

/* Premium game-card variant (proof of concept on the Dice tile). Custom
   inline SVG line-art mark replaces the lucide stock icon, cherry-pink
   accent dots provide single-accent colour without per-tile gradients,
   game name reads as caps-spaced typography rather than the standard
   sentence-case label. Subtle hover motion: the mark scales 1.04 + lifts
   1 px. Restrained, premium, private-club feel. */
.home-card.home-card--premium {
  gap: 18px;
  background: rgba(15, 8, 36, 0.55);
}
.home-card.home-card--premium .home-card-mark {
  position: relative;
  width: 56px; height: 56px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform 0.18s ease;
}
.home-card.home-card--premium .home-card-mark svg {
  width: 100%; height: 100%;
  display: block;
  transition: filter 0.18s ease;
}
.home-card.home-card--premium .home-card-name {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.94);
}
.home-card.home-card--premium:active .home-card-mark,
.home-card.home-card--premium:focus-visible .home-card-mark {
  transform: scale(1.04);
}
@media (hover: hover) {
  .home-card.home-card--premium:hover .home-card-mark {
    transform: scale(1.04);
  }
  .home-card.home-card--premium:hover .home-card-mark svg {
    filter: drop-shadow(0 2px 6px rgba(217, 21, 84, 0.22));
  }
}
@media (max-width: 720px) {
  .home-card.home-card--premium .home-card-mark { width: 48px; height: 48px; }
  .home-card.home-card--premium .home-card-name { font-size: 12px; letter-spacing: 0.12em; }
}

/* ─── Colorful pseudo-3D variant (Thrill / BC.Game style) ─────────────── */
.home-card.home-card--colorful {
  background: var(--tile-bg, linear-gradient(135deg, #2a3f5a, #1a2538));
  padding: 14px 14px 18px;
  border: none;
  border-radius: 18px;
  gap: 0;
  justify-content: space-between;
  align-items: stretch;
  overflow: hidden;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.35);
}
.home-card.home-card--colorful.tile--dice     { --tile-bg: linear-gradient(155deg, #15c2c5 0%, #0a7273 80%); }
.home-card.home-card--colorful.tile--coinflip { --tile-bg: linear-gradient(155deg, #2d8bff 0%, #1146a8 80%); }
.home-card.home-card--colorful.tile--roulette { --tile-bg: linear-gradient(155deg, #1ca06b 0%, #064d31 80%); }
.home-card.home-card--colorful.tile--crash    { --tile-bg: linear-gradient(155deg, #b25cff 0%, #ff7a18 110%); }
.home-card.home-card--colorful.tile--plinko   { --tile-bg: linear-gradient(155deg, #ff5da8 0%, #b41e7b 80%); }
.home-card.home-card--colorful.tile--mines    { --tile-bg: linear-gradient(155deg, #ff6a4d 0%, #b21f10 80%); }
.home-card.home-card--colorful.tile--blackjack{ --tile-bg: linear-gradient(155deg, #ee2e3a 0%, #7a0913 80%); }
.home-card.home-card--colorful.tile--slots    { --tile-bg: linear-gradient(155deg, #ffb13e 0%, #c5710a 80%); }
.home-card.home-card--colorful::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0 2px, transparent 2px 28px),
    radial-gradient(120% 70% at 20% 0%, rgba(255, 255, 255, 0.18), transparent 60%);
  pointer-events: none;
  border-radius: inherit;
}
.home-card.home-card--colorful::before { display: none; }
.home-card.home-card--colorful:active,
.home-card.home-card--colorful:focus,
.home-card.home-card--colorful:focus-visible {
  border-color: transparent;
  background: var(--tile-bg);
}
@media (hover: hover) {
  .home-card.home-card--colorful:hover {
    border-color: transparent;
    background: var(--tile-bg);
    transform: translateY(-2px);
    box-shadow: 0 12px 26px rgba(0, 0, 0, 0.45);
  }
}
.home-card-pill {
  position: relative;
  z-index: 2;
  align-self: center;
  display: inline-flex; align-items: center;
  padding: 3px 10px;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 999px;
  color: rgba(255, 255, 255, 0.95);
  font-family: var(--font-ui);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.home-card-illustration {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex; align-items: center; justify-content: center;
  margin: 6px 0;
}
.home-card-illustration svg {
  width: 70%;
  max-width: 110px;
  height: auto;
  display: block;
  filter: drop-shadow(0 8px 14px rgba(0, 0, 0, 0.35));
}
.home-card.home-card--colorful .home-card-name {
  position: relative;
  z-index: 2;
  font-family: var(--font-ui);
  font-size: 18px;
  font-weight: 900;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
  line-height: 1;
  text-align: center;
}
@media (max-width: 720px) {
  .home-card.home-card--colorful { padding: 12px 12px 14px; }
  .home-card.home-card--colorful .home-card-name { font-size: 16px; }
  .home-card-pill { font-size: 8px; padding: 2px 8px; letter-spacing: 0.16em; }
}

/* LIVE pill — cherry-red variant used on tiles where there's real-time
   shared activity (other players' bets / shared rounds). Mines + Blackjack
   are pure single-player sessions, so they don't get a pill at all. */
.home-card-pill--top,
.games-picker-pill--top {
  background: #e0244e;
  border-color: rgba(255, 255, 255, 0.55);
  color: #fff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.45);
  letter-spacing: 0.22em;
  box-shadow: 0 2px 6px rgba(224, 36, 78, 0.45);
}
/* BetFury-style colorful tiles embed the wordmark in HTML beside or below
   the illustration. Dice + Coinflip use a column layout (illustration on
   top, wordmark below) via their own rules. The other 6 tiles use the
   default row layout (illustration on the left, wordmark on the right). */
.home-card.home-card--colorful .home-card-name { display: none; }
.home-card.home-card--colorful .home-card-illustration { margin: 0; }
.home-card.home-card--colorful .home-card-illustration svg { width: 96%; max-width: none; }
.games-picker-tile .games-picker-name { display: none; }
.games-picker-tile .games-picker-illustration { margin: 0; flex: 1; }
.games-picker-tile .games-picker-illustration svg { width: 96%; max-width: none; }

/* ─── Dice tile — real Three.js mount slot. The dice-tile-3d.js module
   appends a <canvas> child here and runs a small WebGL scene with a
   cube + 3-point lighting. Container reserves a square area in the
   row-layout illustration so the cube has somewhere to render. */
/* ─── Tile 3D mount slot. tile-3d.js appends a <canvas> here for each
   game and runs its WebGL scene. Square aspect, capped width so the
   scene fits cleanly in the row-layout illustration. */
.tile-3d-mount {
  flex: 1;
  min-width: 0;
  min-height: 0;
  aspect-ratio: 1;
  max-width: 110px;
  position: relative;
  align-self: center;
}
.tile-3d-mount > canvas {
  width: 100%;
  height: 100%;
  display: block;
}
.games-picker-tile .tile-3d-mount {
  max-width: 84px;
}
@media (max-width: 720px) {
  .home-card .tile-3d-mount { max-width: 90px; }
}

/* ─── Dice tile — real CSS 3D cube (perspective-projected, continuous rotation) ─── */
.dice-3d-stage {
  flex: 1;
  min-width: 0;
  min-height: 0;
  perspective: 700px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.dice-3d-cube {
  --cube-size: 92px;
  width: var(--cube-size);
  height: var(--cube-size);
  position: relative;
  transform-style: preserve-3d;
  animation: dice-3d-drop 4.2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
  filter: drop-shadow(0 12px 14px rgba(0, 0, 0, 0.45));
}
/* Drop + tumble + bounce + settle loop. Same mechanic as the in-game
   dice roll: cube falls in from above while tumbling on two axes,
   slams the floor, bounces twice (each smaller), settles flat, holds
   the result, then fades for the next throw. */
@keyframes dice-3d-drop {
  0%   { transform: translateY(-105px) rotateX(-20deg) rotateY(-45deg); opacity: 0; }
  10%  { opacity: 1; }
  35%  { transform: translateY(0px)    rotateX(540deg) rotateY(720deg); }
  40%  { transform: translateY(6px)    rotateX(560deg) rotateY(740deg) scaleY(0.92); }
  50%  { transform: translateY(-26px)  rotateX(720deg) rotateY(830deg); }
  58%  { transform: translateY(0px)    rotateX(820deg) rotateY(880deg) scaleY(0.96); }
  64%  { transform: translateY(-10px)  rotateX(870deg) rotateY(900deg); }
  72%  { transform: translateY(0px)    rotateX(900deg) rotateY(900deg); opacity: 1; }
  92%  { transform: translateY(0px)    rotateX(900deg) rotateY(900deg); opacity: 1; }
  100% { transform: translateY(0px)    rotateX(900deg) rotateY(900deg); opacity: 0; }
}
.dice-3d-face {
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, #ffffff 0%, #bce8ff 100%);
  border: 2px solid rgba(255, 255, 255, 0.55);
  border-radius: 12px;
  box-shadow: inset 0 0 14px rgba(31, 127, 184, 0.38);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  padding: 14%;
  gap: 2%;
  backface-visibility: hidden;
}
.dice-3d-face[data-face="1"] { transform: translateZ(calc(var(--cube-size) / 2)); }
.dice-3d-face[data-face="6"] { transform: rotateY(180deg) translateZ(calc(var(--cube-size) / 2)); background: linear-gradient(135deg, #8ab8d8 0%, #3a5878 100%); }
.dice-3d-face[data-face="2"] { transform: rotateY(90deg) translateZ(calc(var(--cube-size) / 2)); background: linear-gradient(135deg, #c4d8e8 0%, #6a98c8 100%); }
.dice-3d-face[data-face="5"] { transform: rotateY(-90deg) translateZ(calc(var(--cube-size) / 2)); background: linear-gradient(135deg, #c4d8e8 0%, #6a98c8 100%); }
.dice-3d-face[data-face="3"] { transform: rotateX(90deg) translateZ(calc(var(--cube-size) / 2)); background: linear-gradient(135deg, #ffffff 0%, #d8e8f8 100%); }
.dice-3d-face[data-face="4"] { transform: rotateX(-90deg) translateZ(calc(var(--cube-size) / 2)); background: linear-gradient(135deg, #5a7898 0%, #2a4868 100%); }
.dice-pip {
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, #2b3a47, #0c1620);
  align-self: center;
  justify-self: center;
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.15);
}
.dice-3d-face[data-face="1"] .dice-pip:nth-child(1) { grid-area: 2 / 2; }
.dice-3d-face[data-face="2"] .dice-pip:nth-child(1) { grid-area: 1 / 1; }
.dice-3d-face[data-face="2"] .dice-pip:nth-child(2) { grid-area: 3 / 3; }
.dice-3d-face[data-face="3"] .dice-pip:nth-child(1) { grid-area: 1 / 1; }
.dice-3d-face[data-face="3"] .dice-pip:nth-child(2) { grid-area: 2 / 2; }
.dice-3d-face[data-face="3"] .dice-pip:nth-child(3) { grid-area: 3 / 3; }
.dice-3d-face[data-face="4"] .dice-pip:nth-child(1) { grid-area: 1 / 1; }
.dice-3d-face[data-face="4"] .dice-pip:nth-child(2) { grid-area: 1 / 3; }
.dice-3d-face[data-face="4"] .dice-pip:nth-child(3) { grid-area: 3 / 1; }
.dice-3d-face[data-face="4"] .dice-pip:nth-child(4) { grid-area: 3 / 3; }
.dice-3d-face[data-face="4"] .dice-pip { background: radial-gradient(circle at 30% 30%, #f0f4fa, #c0d0e0); }
.dice-3d-face[data-face="5"] .dice-pip:nth-child(1) { grid-area: 1 / 1; }
.dice-3d-face[data-face="5"] .dice-pip:nth-child(2) { grid-area: 1 / 3; }
.dice-3d-face[data-face="5"] .dice-pip:nth-child(3) { grid-area: 2 / 2; }
.dice-3d-face[data-face="5"] .dice-pip:nth-child(4) { grid-area: 3 / 1; }
.dice-3d-face[data-face="5"] .dice-pip:nth-child(5) { grid-area: 3 / 3; }
.dice-3d-face[data-face="6"] .dice-pip:nth-child(1) { grid-area: 1 / 1; }
.dice-3d-face[data-face="6"] .dice-pip:nth-child(2) { grid-area: 1 / 3; }
.dice-3d-face[data-face="6"] .dice-pip:nth-child(3) { grid-area: 2 / 1; }
.dice-3d-face[data-face="6"] .dice-pip:nth-child(4) { grid-area: 2 / 3; }
.dice-3d-face[data-face="6"] .dice-pip:nth-child(5) { grid-area: 3 / 1; }
.dice-3d-face[data-face="6"] .dice-pip:nth-child(6) { grid-area: 3 / 3; }
.dice-3d-wordmark { width: 88%; max-width: 170px; height: auto; flex-shrink: 0; }
.games-picker-tile.tile--dice .dice-3d-cube { --cube-size: 82px; }
.games-picker-tile.tile--dice .dice-3d-wordmark { width: 80%; max-width: 110px; }
@media (max-width: 720px) {
  .home-card.tile--dice .dice-3d-cube { --cube-size: 76px; }
}
@media (prefers-reduced-motion: reduce) {
  .dice-3d-cube { animation: none; transform: rotateX(-18deg) rotateY(-25deg); }
}

/* ─── Coinflip — real CSS 3D coin flipping (continuous rotateX) ─── */
.cf-3d-stage {
  flex: 1;
  min-width: 0;
  min-height: 0;
  perspective: 700px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.cf-3d-coin {
  --coin-size: 64px;
  width: var(--coin-size);
  height: var(--coin-size);
  flex-shrink: 0;
  aspect-ratio: 1;
  position: relative;
  transform-style: preserve-3d;
  animation: cf-flip 3.6s cubic-bezier(0.45, 0, 0.55, 1) infinite;
  filter: drop-shadow(0 10px 12px rgba(0, 0, 0, 0.45));
}
@keyframes cf-flip {
  0%, 8%   { transform: rotateX(0deg); }
  42%, 50% { transform: rotateX(540deg); }
  92%, 100%{ transform: rotateX(1080deg); }
}
.cf-3d-face {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, #fff5b8 0%, #ffc94d 50%, #a35a0a 100%);
  border: 3px solid #7a4408;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: Georgia, serif;
  font-size: 44px;
  font-weight: 900;
  color: #7a4408;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.3);
  backface-visibility: hidden;
  box-shadow: inset 0 0 14px rgba(122, 68, 8, 0.35);
}
.cf-3d-face--heads { transform: translateZ(2px); }
.cf-3d-face--tails { transform: rotateX(180deg) translateZ(2px); }
.games-picker-tile.tile--coinflip .cf-3d-coin { --coin-size: 70px; }
.games-picker-tile.tile--coinflip .cf-3d-face { border-width: 2px; }
@media (max-width: 720px) {
  .home-card.tile--coinflip .cf-3d-coin { --coin-size: 56px; }
}

/* ─── Roulette — wheel stays static (rotating the perspective-tilted
   ellipse segments in 2D reads as wobble, not spin). Only the ball
   orbits, around the wheel's visual centre at viewport (100, 100).
   The ball sits at (100, 58) — 42px above centre — so a CSS rotate
   pivoting on (100, 100) carries it around a 42-radius circle that
   tracks the inner edge of the wheel felt. */
.anim-r-ball-orbit {
  transform-origin: 100px 100px;
  animation: r-ball-orbit 4s linear infinite;
}
@keyframes r-ball-orbit {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ─── Crash — rocket flies upward, trail grows ─── */
.anim-cr-rocket {
  animation: cr-rocket-fly 4s ease-out infinite;
}
@keyframes cr-rocket-fly {
  0%, 3% { transform: translate(0, 30px); opacity: 0; }
  12%    { opacity: 1; }
  55%    { transform: translate(0, -22px); opacity: 1; }
  85%    { transform: translate(0, -40px); opacity: 1; }
  100%   { transform: translate(0, -45px); opacity: 0; }
}
.anim-cr-trail {
  stroke-dasharray: 4 4;
  stroke-dashoffset: 200;
  animation: cr-trail-grow 4s ease-out infinite;
}
@keyframes cr-trail-grow {
  0%, 5% { stroke-dashoffset: 200; opacity: 0; }
  20%    { opacity: 0.55; }
  55%    { stroke-dashoffset: 0;   opacity: 0.55; }
  85%    { stroke-dashoffset: 0;   opacity: 0.45; }
  100%   { stroke-dashoffset: 0;   opacity: 0; }
}
.anim-cr-trail-tip { animation: cr-trail-tip 4s ease-out infinite; }
@keyframes cr-trail-tip {
  0%, 50%   { opacity: 0; }
  60%, 85%  { opacity: 0.6; }
  100%      { opacity: 0; }
}

/* ─── Plinko — ball drops with zigzag bounces, settles in bucket ─── */
.anim-pl-ball {
  animation: pl-ball-drop 3.6s ease-in-out infinite;
}
@keyframes pl-ball-drop {
  0%, 3% { transform: translate(-28px, -90px); opacity: 0; }
  8%     { opacity: 1; }
  20%    { transform: translate(-38px, -62px); }
  35%    { transform: translate(-18px, -42px); }
  50%    { transform: translate(-30px, -22px); }
  65%    { transform: translate(-12px, -4px); }
  80%, 92% { transform: translate(0, 0); opacity: 1; }
  100%   { transform: translate(0, 0); opacity: 0; }
}

/* ─── Mines — spark pulses on the fuse, bomb sways subtly ─── */
.anim-m-spark {
  transform-origin: 145px 12px;
  animation: m-spark-pulse 0.7s ease-in-out infinite alternate;
}
@keyframes m-spark-pulse {
  0%   { transform: scale(0.85); opacity: 0.75; }
  100% { transform: scale(1.25); opacity: 1; }
}
.anim-m-bomb {
  transform-origin: 115px 84px;
  animation: m-bomb-wobble 2.4s ease-in-out infinite;
}
@keyframes m-bomb-wobble {
  0%, 100% { transform: translateX(0) rotate(0deg); }
  25%      { transform: translateX(-1px) rotate(-1.2deg); }
  75%      { transform: translateX(1px)  rotate(1.2deg); }
}

/* ─── Blackjack — two cards dealt in sequence, slide into tilted positions ─── */
.anim-bj-card-a { animation: bj-deal-a 4s ease-out infinite; }
@keyframes bj-deal-a {
  0%, 5%    { transform: translate(-180px, -60px); opacity: 0; }
  20%, 100% { transform: translate(0, 0); opacity: 1; }
}
.anim-bj-card-b { animation: bj-deal-b 4s ease-out infinite; }
@keyframes bj-deal-b {
  0%, 30%   { transform: translate(180px, -60px); opacity: 0; }
  45%, 100% { transform: translate(0, 0); opacity: 1; }
}

/* ─── Slots — three reels spin in sequence (translate + blur), staggered stop ─── */
.anim-sl-reel-1 { animation: sl-reel-spin 2.4s cubic-bezier(0.55, 0, 0.45, 1) infinite; }
.anim-sl-reel-2 { animation: sl-reel-spin 2.4s cubic-bezier(0.55, 0, 0.45, 1) infinite; animation-delay: 0.18s; }
.anim-sl-reel-3 { animation: sl-reel-spin 2.4s cubic-bezier(0.55, 0, 0.45, 1) infinite; animation-delay: 0.36s; }
@keyframes sl-reel-spin {
  0%, 18%  { transform: translateY(0);    filter: blur(0); }
  25%      { transform: translateY(-14px); filter: blur(2.5px); }
  31%      { transform: translateY(12px);  filter: blur(2.5px); }
  37%      { transform: translateY(-14px); filter: blur(2.5px); }
  43%      { transform: translateY(12px);  filter: blur(2.5px); }
  49%      { transform: translateY(-14px); filter: blur(2.5px); }
  55%      { transform: translateY(0);    filter: blur(0); }
  100%     { transform: translateY(0);    filter: blur(0); }
}

@media (prefers-reduced-motion: reduce) {
  .cf-3d-coin, .anim-r-wheel, .anim-r-ball-orbit,
  .anim-cr-rocket, .anim-cr-trail, .anim-cr-trail-tip,
  .anim-pl-ball, .anim-m-spark, .anim-m-bomb,
  .anim-bj-card-a, .anim-bj-card-b,
  .anim-sl-reel-1, .anim-sl-reel-2, .anim-sl-reel-3 {
    animation: none;
  }
}

/* ─── Game wordmark — canonical UI font (Open Sans), light colors, soft
   text-shadow. Replaces the previous SVG-based chrome wordmarks that
   leaned on Impact + heavy dark strokes and read too dark on the
   per-tile gradient backgrounds. */
.game-wordmark {
  font-family: var(--font-ui);
  font-weight: 900;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  font-size: 26px;
  line-height: 1;
  text-align: center;
  text-transform: uppercase;
  color: #ffffff;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.45), 0 0 1px rgba(0, 0, 0, 0.5);
  flex-shrink: 0;
  padding: 4px 0 2px;
  position: relative;
  z-index: 3;
}
.tile--blackjack .game-wordmark,
.tile--roulette .game-wordmark { font-size: 22px; }
@media (max-width: 720px) {
  .home-card.home-card--colorful .game-wordmark { font-size: 22px; }
  .home-card.tile--blackjack .game-wordmark,
  .home-card.tile--roulette .game-wordmark { font-size: 18px; }
}
.games-picker-tile .game-wordmark { font-size: 14px; padding: 2px 0; }
.games-picker-tile.tile--blackjack .game-wordmark,
.games-picker-tile.tile--roulette .game-wordmark { font-size: 11px; }
@media (max-width: 480px) {
  .games-picker-tile .game-wordmark { font-size: 12px; }
  .games-picker-tile.tile--blackjack .game-wordmark,
  .games-picker-tile.tile--roulette .game-wordmark { font-size: 10px; }
}

/* Telegram WebApp — hide the email/password auth modal until either the
   Telegram auto-login succeeds (in which case we never show it) or it
   fails (in which case `tg-mode` is removed and the modal returns).
   The `html.tg-mode` variant is set synchronously in <head> the moment
   Telegram's SDK exposes initData, so the modal never even paints once
   inside Telegram (the body class arrives later, after tryTelegramLogin
   runs — too late to prevent the flash). */
html.tg-mode #auth-view,
body.tg-mode #auth-view { display: none !important; }

/* Telegram-only accounts (email IS NULL) — hide the menu items that
   don't apply: there's no password to change, and signing out would be
   immediately undone by the next auto-login. */
body.tg-user #menu-change-password,
body.tg-user #menu-signout { display: none !important; }

/* ======== Inline deposit sheet ======== */
/* Bottom-sheet that slides up when the player taps PLACE BET with
   insufficient balance. Mental model: depositing is part of playing,
   not a side-quest — the game stays loaded behind. Visual language
   mirrors the trade-execute slabs elsewhere (4 px corners, subtle
   white border, no glow). */
.deposit-sheet {
  position: fixed;
  inset: 0;
  z-index: 10300;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
.deposit-sheet.hidden { display: none; }
.deposit-sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: depositSheetFade 0.18s ease;
}
.deposit-sheet-panel {
  position: relative;
  background: rgba(15, 8, 36, 0.98);
  border-top: 1px solid var(--border);
  border-radius: 12px 12px 0 0;
  padding: 18px 18px 24px;
  max-height: 90vh;
  overflow-y: auto;
  animation: depositSheetUp 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.deposit-sheet-grip {
  width: 38px; height: 4px;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 2px;
  margin: 0 auto 12px;
}
.deposit-sheet-close {
  position: absolute;
  top: 10px; right: 12px;
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, 0.55);
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  padding: 6px 10px;
  line-height: 1;
  z-index: 2;
}
.deposit-sheet-close:hover { color: #fff; }
.deposit-sheet-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 14px;
  padding-right: 30px;
}
.deposit-sheet-label {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.deposit-sheet-balance {
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: rgba(255, 255, 255, 0.72);
  font-variant-numeric: tabular-nums;
}
.deposit-sheet-coin-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.deposit-sheet-coin {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.deposit-sheet-coin .coin-icon { width: 16px; height: 16px; }
.deposit-sheet-coin .coin-ring { padding: 1px; }
.deposit-sheet-coin:hover { background: rgba(255, 255, 255, 0.12); }
.deposit-sheet-coin.active {
  /* Match PLACE BET surface 1:1 — same gradient, same border, same
     press-depth shadow as every other in-game CTA family member. */
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55);
  border-color: var(--border);
  color: #fff;
  font-weight: 800;
  letter-spacing: 0.04em;
  box-shadow: 0 3px 0 0 rgba(50, 3, 18, 0.55);
}
.deposit-sheet-qr-row {
  display: flex;
  gap: 14px;
  align-items: center;
  margin-bottom: 14px;
}
.deposit-sheet-qr {
  flex: 0 0 auto;
  width: 132px; height: 132px;
  background: #fff;
  border: 2px solid transparent;
  border-radius: 4px;
  padding: 6px;
  cursor: pointer;
  transition: border-color 0.12s, transform 0.08s;
}
.deposit-sheet-qr:hover { border-color: rgba(217, 21, 84, 0.55); }
.deposit-sheet-qr:active { transform: scale(0.98); }
.deposit-sheet-qr img { width: 100%; height: 100%; display: block; }
.deposit-sheet-addr-col {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.deposit-sheet-addr {
  font-family: ui-monospace, 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 600;
  color: var(--text);
  word-break: break-all;
  padding: 10px 12px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  line-height: 1.4;
  transition: border-color 0.12s, background 0.12s;
}
.deposit-sheet-addr:hover {
  border-color: rgba(217, 21, 84, 0.55);
  background: rgba(255, 255, 255, 0.06);
}
.deposit-sheet-addr:active { background: rgba(255, 255, 255, 0.08); }
/* D3: small dim hint sitting under the QR + address row so the tap
   affordance is visible (the `title` attr is mobile-invisible). */
.deposit-sheet-tap-hint {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: rgba(255, 255, 255, 0.45);
  text-align: center;
  margin: -6px 0 12px;
}
.deposit-sheet-copy {
  /* Place-bet surface — same family as the affiliate Copy / Share
     buttons + PLACE BET. Players have learned this look as "primary
     action" across the app; using it here makes Copy feel as actionable
     as it actually is. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 14px;
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border);
  border-radius: 4px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #fff;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  cursor: pointer;
  box-shadow: 0 3px 0 0 rgba(50, 3, 18, 0.55);
}
.deposit-sheet-copy:hover {
  filter: brightness(1.08);
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.5) 0%, rgba(122, 8, 44, 0.5) 100%),
    rgba(15, 8, 36, 0.55);
  box-shadow: 0 3px 0 0 rgba(50, 3, 18, 0.65);
}
.deposit-sheet-copy:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 0 rgba(50, 3, 18, 0.65);
}
.deposit-sheet-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 12px;
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text-muted);
}
.deposit-sheet-meta strong {
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.deposit-sheet-status {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 4px;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
  margin-bottom: 10px;
}
.deposit-sheet-status-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: #ff9500;
  flex-shrink: 0;
  animation: depositStatusPulse 1.5s ease-in-out infinite;
}
.deposit-sheet-status.detected .deposit-sheet-status-dot {
  background: #00d68f;
  animation: none;
}
.deposit-sheet-wallet-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  min-height: 48px;
  padding: 0 16px;
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: #fff;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 3px 0 0 rgba(50, 3, 18, 0.55);
}
.deposit-sheet-wallet-btn:hover {
  filter: brightness(1.08);
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.5) 0%, rgba(122, 8, 44, 0.5) 100%),
    rgba(15, 8, 36, 0.55);
}
.deposit-sheet-wallet-btn:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 0 rgba(50, 3, 18, 0.65);
}
@keyframes depositSheetUp {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}
@keyframes depositSheetFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes depositStatusPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.85); }
}
body.mobile .deposit-sheet-panel {
  padding: 16px 14px 22px;
  max-height: 92vh;
}
body.mobile .deposit-sheet-qr { width: 116px; height: 116px; }
body.mobile .deposit-sheet-addr { font-size: 10px; }

/* ======== First-run tutorial overlay ======== */
/* Shown once per user after they reach the post-login state. Three short
   steps with a single Next CTA — fast skim-through, no spotlights/arrows.
   Z-index sits above the titlebar (10002) so the overlay covers the
   whole chrome. */
.tutorial-overlay {
  position: fixed;
  inset: 0;
  z-index: 10100;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: tutorialFadeIn 0.3s ease-out;
}
@keyframes tutorialFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.tutorial-panel {
  position: relative;
  width: 100%;
  max-width: 420px;
  background: rgba(15, 8, 36, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 4px;
  padding: 36px 28px 24px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}
.tutorial-skip {
  position: absolute;
  top: 12px;
  right: 14px;
  background:
    linear-gradient(180deg, rgba(217, 21, 84, 0.35) 0%, rgba(122, 8, 44, 0.35) 100%),
    rgba(15, 8, 36, 0.55);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-muted, rgba(255, 255, 255, 0.5));
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  padding: 6px 8px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.tutorial-skip:hover { color: var(--text, #fff); }
.tutorial-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  width: 100%;
}
.tutorial-icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #ff2e5e 0%, #d91554 100%);
}
.tutorial-icon i[data-lucide] {
  width: 30px;
  height: 30px;
  color: #fff;
}
.tutorial-title {
  font-family: var(--font-ui);
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--text, #fff);
  margin: 0;
}
.tutorial-text {
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.72);
  margin: 0;
  max-width: 320px;
}
.tutorial-dots {
  display: flex;
  gap: 8px;
  margin-top: 4px;
}
.tutorial-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
  transition: background 0.2s ease;
}
.tutorial-dot.active {
  background: var(--primary, #ff2e5e);
}
.tutorial-next {
  width: 100%;
  margin-top: 4px;
}
body.mobile .tutorial-panel {
  max-width: 340px;
  padding: 32px 22px 20px;
}
body.mobile .tutorial-title { font-size: 18px; }
body.mobile .tutorial-text { font-size: 13px; }

/* ======== 100% glassy game pages ======== */
/* Every chrome element around the 3D canvas gets uniform translucent rgba
   + backdrop-filter blur so the page bg shimmers through every panel,
   row, chip, and control consistently. The canvas itself is WebGL and
   paints opaque; everything around it is now glass. */
body.mobile .crash-bets-panel,
body.mobile .crash-bets-total,
body.mobile .crash-bets-header,
body.mobile .crash-bet-row,
body.mobile .crash-bets-tabs,
body.mobile .crash-bets-footer,
body.mobile .dice-history,
body.mobile .cf-recent-hero,
body.mobile .roul-recent-hero,
body.mobile .crash-history {
  background: rgba(15, 8, 36, 0.32) !important;
  backdrop-filter: blur(22px) !important;
  -webkit-backdrop-filter: blur(22px) !important;
}
body.mobile .crash-bets-list {
  background: transparent !important;
}
body.mobile .dice-controls-sticky,
body.mobile .cf-controls-sticky,
body.mobile .roul-controls-sticky,
body.mobile .slots-controls-sticky,
body.mobile .mines-controls-sticky,
body.mobile .plinko-controls-sticky,
body.mobile .bj-controls-sticky,
body.mobile .crash-controls,
body.mobile .autoplay-row {
  background: rgba(15, 8, 36, 0.55) !important;
  backdrop-filter: blur(22px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(22px) saturate(140%) !important;
  border-top: 1px solid rgba(255, 255, 255, 0.06) !important;
}
/* Stat chips — single centered pill at the bottom of the canvas with
   MULTIPLIER and CHANCE TO WIN sitting side-by-side, separated by a
   subtle hairline. Replaces the previous "two floating corner chips"
   layout that read as orphaned UI. The combined unit anchors the
   bottom of the canvas like a status bar, professional casino style. */
body.mobile .dice-slider-stats {
  position: absolute !important;
  bottom: 4px !important;
  left: 50% !important;
  right: auto !important;
  transform: translateX(-50%);
  display: flex !important;
  gap: 0 !important;
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  z-index: 11;
  pointer-events: auto;
  box-shadow: none !important;
}
body.mobile .dice-slider-stat {
  position: static !important;
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  padding: 7px 22px !important;
  bottom: auto !important;
  left: auto !important;
  right: auto !important;
  display: flex !important;
  flex-direction: column;
  align-items: center !important;
  gap: 2px !important;
  flex-shrink: 0 !important;
  min-width: 0 !important;
  /* Bare text overlay on the 3D canvas — needs a hard text-shadow so
     it stays readable against the dice / felt without a chip frame. */
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.75), 0 0 8px rgba(0, 0, 0, 0.5);
}
body.mobile .dice-slider-stat-left {
  border: none !important;
}
/* Label = uppercase muted, like the topnav fiat sub-line. Small,
   secondary, sets the context for the value below. */
body.mobile .dice-slider-stat .dice-slider-label {
  font-size: 11px !important;
  letter-spacing: 0.08em !important;
  color: rgba(255, 255, 255, 0.65) !important;
  text-transform: uppercase !important;
  text-align: center !important;
  font-weight: 600 !important;
  white-space: nowrap !important;
  line-height: 1.1 !important;
}
/* Value = hero money-quantity typography (matches .coin-pill-bal on
   the topnav): big, bold, tabular-nums, tight letter-spacing, pure
   white. Reads instantly as the headline number players care about. */
body.mobile .dice-slider-stat strong {
  font-size: clamp(20px, 6vw, 26px) !important;
  font-weight: 800 !important;
  letter-spacing: -0.02em !important;
  font-variant-numeric: tabular-nums !important;
  color: #fff !important;
  line-height: 1.05 !important;
  font-family: var(--font-ui) !important;
}
body.mobile .dice-slider-stat .dice-slider-label {
  font-size: 9px !important;
  letter-spacing: 0.1em !important;
  color: rgba(255, 255, 255, 0.55) !important;
  text-transform: uppercase !important;
}
body.mobile .dice-slider-stat strong {
  font-size: 13px !important;
  font-weight: 800 !important;
  letter-spacing: -0.01em !important;
  font-variant-numeric: tabular-nums !important;
}

/* Bets panel sits flush against the canvas and now has its own
   opaque dark plate so any empty space between the header and the
   first row reads as part of the panel chrome — not as a "lavender
   band" showing the page bg through a transparent container. */
body.mobile .crash-bets-panel {
  padding: 0 !important;
  margin: 0 !important;
  background: rgba(15, 8, 36, 0.92) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
body.mobile .crash-bets-tabs {
  padding: 0 !important;
  margin: 0 !important;
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
body.mobile .crash-tab {
  padding: 8px 2px !important;
}

/* ======== Topnav floats over the canvas (game pages) ======== */
/* On game pages the canvas extends all the way to viewport top so the
   glassy topnav blurs the live scene behind it instead of riding on a
   separate opaque strip. Result: every chrome element (cherry, balance,
   wallet, audio, flag, user-pill) reads as floating glass over the 3D
   render — unified, premium-feel chrome. Non-game pages keep their
   62px top padding so page-titles and forms don't disappear behind
   the titlebar. */
body.mobile.logged-in #content:has(#page-dice.active),
body.mobile.logged-in #content:has(#page-coinflip.active),
body.mobile.logged-in #content:has(#page-roulette.active),
body.mobile.logged-in #content:has(#page-mines.active),
body.mobile.logged-in #content:has(#page-plinko.active),
body.mobile.logged-in #content:has(#page-crash.active),
body.mobile.logged-in #content:has(#page-slots.active),
body.mobile.logged-in #content:has(#page-blackjack.active) {
  padding-top: 0 !important;
}
/* Recent-history chip strips on game pages are position:absolute at
   top: 8px of their game-stage. With #content's padding-top now 0,
   the game-stage starts at viewport y=0, which sits BEHIND the fixed
   68px-tall topnav. Push every game's history strip down past the
   topnav so the chips don't disappear under the chrome. */
body.mobile #page-dice .dice-history,
body.mobile #page-coinflip .cf-recent-hero,
body.mobile #page-roulette .roul-recent-hero,
body.mobile #page-crash .crash-history {
  top: 76px !important;
  z-index: 15 !important;
}
/* History strips — cap rendered pills at 8 via :nth-child so the
   strip never overflows / stretches across the canvas. Older pills
   beyond the 8th are removed from layout entirely (display:none),
   not just clipped. Keeps the recent-results affordance tight. */
body.mobile #page-dice .dice-history > :nth-child(n + 9),
body.mobile #page-coinflip .cf-recent-hero > :nth-child(n + 9),
body.mobile #page-roulette .roul-recent-hero > :nth-child(n + 9),
body.mobile #page-crash .crash-history > :nth-child(n + 9) {
  display: none !important;
}
/* Plinko "Drop the ball" / win-result pill — JS moved it INTO the
   sticky panel's .autoplay-row (as a sibling of the AUTO toggle and
   DROP BALL button). Renders inline inside the row, no position:fixed
   shenanigans. Cherry-pink outline + dark glass plate matches the
   PLACE BET chrome family. */
/* Plinko result pill — absolute positioned at the TOP-LEFT corner of
   the sticky controls panel. Bypasses all flex layout weirdness:
   stays exactly where the player expects regardless of which row the
   JS inserts it into. */
body.mobile #page-plinko .plinko-controls-sticky {
  position: relative;
}
body.mobile #page-plinko .plinko-controls-sticky .plinko-result-label {
  position: absolute !important;
  /* Sits at the TOP-RIGHT corner inside the sticky panel, on the same row as
     the drag-handle chevron. Stays clear of the bet-amount row below. */
  top: 4px !important;
  left: auto !important;
  right: 10px !important;
  bottom: auto !important;
  transform: none !important;
  width: auto !important;
  max-width: 60% !important;
  margin: 0 !important;
  height: 22px !important;
  padding: 0 9px !important;
  background: rgba(15, 8, 36, 0.85) !important;
  backdrop-filter: blur(16px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(16px) saturate(140%) !important;
  border: 1.5px solid #d91554 !important;
  border-radius: var(--r-pill, 999px) !important;
  font-size: 11px !important;
  font-weight: 700 !important;
  letter-spacing: 0.02em !important;
  font-variant-numeric: tabular-nums !important;
  text-align: center !important;
  align-items: center !important;
  justify-content: center !important;
  display: inline-flex !important;
  flex-direction: row !important;
  gap: 6px !important;
  flex: 0 0 auto !important;
  z-index: 5 !important;
  visibility: visible !important;
  opacity: 1 !important;
  color: #fff !important;
  line-height: 1 !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
  box-sizing: border-box !important;
}
body.mobile #page-plinko .plinko-controls-sticky .plinko-result-label .plinko-result-mult {
  font-size: 10px !important;
  font-weight: 800 !important;
  line-height: 1 !important;
}
body.mobile #page-plinko .plinko-controls-sticky .plinko-result-label .plinko-result-net {
  font-size: 9px !important;
  font-weight: 600 !important;
  line-height: 1 !important;
  opacity: 0.85;
}
body.mobile #page-plinko .plinko-result-label .plinko-result-mult {
  font-size: 14px !important;
  font-weight: 800 !important;
}
body.mobile #page-plinko .plinko-result-label .plinko-result-net {
  font-size: 10px !important;
}
/* Glassy titlebar — 75% fill is dense enough that the canvas behind
   doesn't bleed through as a visible "light band" at the seam, but
   transparent enough that the blur still picks up scene colour for
   that frosted-glass feel. 1px bottom inset highlight keeps the
   premium bevel from the Section A polish pass. */
body.mobile #titlebar {
  background: rgba(15, 8, 36, 0.75) !important;
  border-bottom: none !important;
  backdrop-filter: blur(22px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(22px) saturate(140%) !important;
  box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.06) !important;
}

/* ======== MAX GLASSY — every surface gets the frosted treatment ======== */
/* Uniform translucent rgba + heavy backdrop-blur across every piece of
   chrome that isn't a primary CTA. Keeps PLACE BET / Withdraw / Login
   buttons solid so they read as actionable; everything else (pickers,
   menus, modals, cards, inputs, tabbar, badges) becomes frosted glass.
   Effect: the page background and 3D scene blur consistently through
   every layer of UI — single unified premium aesthetic. */

/* Bottom mobile tabbar */
body.mobile #mobile-tabbar {
  background: rgba(15, 8, 36, 0.22) !important;
  backdrop-filter: blur(28px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(28px) saturate(140%) !important;
  border-top: 1px solid rgba(255, 255, 255, 0.05) !important;
  box-shadow: 0 -1px 0 rgba(255, 255, 255, 0.03) !important;
}

/* Coin-pill in the topnav (balance display) — naked, no plate. The
   coin icon + amount + fiat float directly on the glassy titlebar. */
body.mobile .coin-pill {
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border: none !important;
}


/* All body-level pickers — coin, fiat, games, lang, deposit, wd */
body.mobile .coin-picker,
body.mobile .fiat-picker,
body.mobile .games-picker,
body.mobile .lang-picker,
body.mobile #dep-picker,
body.mobile #wd-picker {
  background: rgba(15, 8, 36, 0.55) !important;
  backdrop-filter: blur(28px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(28px) saturate(140%) !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
}
body.mobile .coin-picker-backdrop {
  background: rgba(0, 0, 0, 0.35) !important;
  backdrop-filter: blur(10px) !important;
  -webkit-backdrop-filter: blur(10px) !important;
}

/* User menu dropdown */
body.mobile .user-menu {
  background: rgba(15, 8, 36, 0.55) !important;
  backdrop-filter: blur(28px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(28px) saturate(140%) !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
}

/* Modals (page-modal overlay + .modal dialog) */
body.mobile .page--modal-active {
  background: rgba(0, 0, 0, 0.40) !important;
  backdrop-filter: blur(20px) !important;
  -webkit-backdrop-filter: blur(20px) !important;
}
body.mobile .modal,
body.mobile .update-modal,
body.mobile .changelog-modal {
  background: rgba(15, 8, 36, 0.55) !important;
  backdrop-filter: blur(28px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(28px) saturate(140%) !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
}

/* Form fields — input/select/textarea */
body.mobile .input,
body.mobile .select,
body.mobile textarea,
body.mobile input[type="text"],
body.mobile input[type="email"],
body.mobile input[type="password"],
body.mobile input[type="number"] {
  background: rgba(15, 8, 36, 0.32) !important;
  backdrop-filter: blur(12px) !important;
  -webkit-backdrop-filter: blur(12px) !important;
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
}

/* Ghost / secondary buttons get a glass tint. Tabs (`.tab`, auth-tabs)
   stay flat / transparent — they're text-only navigation, the active
   state is communicated by the cherry-pink underline alone. Boxing
   each tab in a glass plate read as "buttons in a row" rather than
   "tabbed navigation". */
body.mobile .btn-ghost,
body.mobile .btn-secondary {
  background: rgba(15, 8, 36, 0.32) !important;
  backdrop-filter: blur(14px) !important;
  -webkit-backdrop-filter: blur(14px) !important;
}
body.mobile .tab,
body.mobile .auth-tabs .tab,
body.mobile .wallet-tabs .tab {
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border-top: none !important;
  border-left: none !important;
  border-right: none !important;
  /* Keep border-bottom — the active-tab underline rule paints it
     cherry-pink. Inactive tabs stay transparent. */
  border-bottom: 2px solid transparent !important;
}
body.mobile .tab.active,
body.mobile .auth-tabs .tab.active,
body.mobile .wallet-tabs .tab.active {
  border-bottom-color: #d91554 !important;
}

/* Auth view card (login / signup) */
body.mobile .auth-card {
  background: rgba(15, 8, 36, 0.55) !important;
  backdrop-filter: blur(28px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(28px) saturate(140%) !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
}

/* Toast stack — each toast becomes a floating glass card */
body.mobile #toast-stack .toast {
  background: rgba(15, 8, 36, 0.55) !important;
  backdrop-filter: blur(20px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(20px) saturate(140%) !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
}

/* Stat / fair / bonus cards (wallet, daily, affiliate, vip) */
body.mobile .stat-card,
body.mobile .fair-card,
body.mobile .aff-bonus-card,
body.mobile .daily-card,
body.mobile .vip-card {
  background: rgba(15, 8, 36, 0.32) !important;
  backdrop-filter: blur(22px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(22px) saturate(140%) !important;
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
}

/* Deposit grid cells — flat, no card plate. The selectors + QR + copy
   row inside provide their own visual surfaces; wrapping them in a
   tinted card just stacked a redundant rectangle behind the content. */
body.mobile .wallet-grid > * {
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border: none !important;
}

/* Live chat panel + thread */
body.mobile .lc-panel,
body.mobile .lc-thread,
body.mobile .lc-form,
body.mobile .lc-input {
  background: rgba(15, 8, 36, 0.40) !important;
  backdrop-filter: blur(22px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(22px) saturate(140%) !important;
}

/* Sidebar drawer (mobile mostly hidden but glass-treat for the moment
   when it slides in from the side) */
body.mobile #sidebar {
  background: rgba(15, 8, 36, 0.55) !important;
  backdrop-filter: blur(28px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(28px) saturate(140%) !important;
  border-right: 1px solid rgba(255, 255, 255, 0.06) !important;
}

/* Big-wins ticker (rides behind the titlebar — keep transparent so it
   doesn't double-blur the canvas underneath) */
body.mobile .big-wins-ticker { background: transparent !important; }

/* VIP / mode badges, coin labels, pills sprinkled across the app */
body.mobile .vip-badge,
body.mobile .mode-tag,
body.mobile .coin-label,
body.mobile .crash-fair-badge {
  background: rgba(15, 8, 36, 0.42) !important;
  backdrop-filter: blur(14px) !important;
  -webkit-backdrop-filter: blur(14px) !important;
}

/* ======== Professional polish — alignment, tap targets, hierarchy ======== */
/* Derived from a deep design audit. Fixes inconsistencies between glassy
   surfaces and remaining solid plates, sub-44px tap targets, focus
   states that fail the CLAUDE.md "border-color only, no glow" rule,
   and tab underline colour schizophrenia. */

/* P0 — modal-header glassy continuation of its glassy parent */
body.mobile .modal-header {
  background: rgba(15, 8, 36, 0.35) !important;
  backdrop-filter: blur(14px) !important;
  -webkit-backdrop-filter: blur(14px) !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
  padding: 12px 16px !important;
}

/* P0 — VIP rakeback rows (and any other "solid-plate row" patterns) */
body.mobile .vip-rb-row {
  background: rgba(15, 8, 36, 0.32) !important;
  backdrop-filter: blur(14px) !important;
  -webkit-backdrop-filter: blur(14px) !important;
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
}

/* P0 — quick stake chips ≥ 44px tap target (Apple HIG) */
body.mobile .quick-chip-btn {
  min-height: 40px !important;
  padding: 10px 14px !important;
}

/* P1 — picker close button proper tap target */
body.mobile .coin-picker-close {
  padding: 8px 10px !important;
  min-width: 40px !important;
  min-height: 40px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
}

/* P1 — auth fields: consistent height + padding */
body.mobile .field input,
body.mobile .field select,
body.mobile .field textarea {
  min-height: 44px !important;
  padding: 12px 14px !important;
  font-size: 14px !important;
}
/* When filled / focused, drop the value text below the floated label so
   they don't overlap. Mirrors the desktop rule which mobile's compact
   padding would otherwise override. */
body.mobile .field:focus-within input,
body.mobile .field input:not(:placeholder-shown) {
  padding-top: 22px !important;
  padding-bottom: 4px !important;
}
/* Align the value text's left edge with the floated label's left edge.
   Default `.field` (icon variant): label sits at left:50px after floating
   so the value also starts past the icon. `.field-no-icon`: label sits
   at left:18px so the value matches that. Without these overrides the
   mobile `padding: 12px 14px` rule places the value too far left and the
   label appears to "step" rightward when it floats. */
body.mobile .field input { padding-left: 48px !important; }
body.mobile .field.field-no-icon input { padding-left: 18px !important; }

/* P1 — unify ALL tab underlines to cherry-pink. Was schizophrenic:
   .crash-tab used cherry, .tab + .seg + .auth-tabs used white. The
   cherry-on-active rule is the brand colour, all other underlines
   read as "inactive UI bug" by comparison. */
body.mobile .tab.active,
body.mobile .auth-tabs .tab.active,
body.mobile .seg.active,
body.mobile .wallet-tabs .tab.active {
  border-bottom-color: #d91554 !important;
}

/* P1 — picker search input: border-color only on focus (CLAUDE.md
   forbids any focus glow / box-shadow halo / bg lift). */
body.mobile .coin-picker-search:focus,
body.mobile .coin-picker-search:focus-visible {
  border-color: #d91554 !important;
  box-shadow: none !important;
  background: var(--bg-input) !important;
}

/* P1 — VIP / Affiliate / History table rows get the same glass tint as
   bets-list rows instead of bare 1px borders on transparent. */
body.mobile .aff-comm,
body.mobile .aff-referred,
body.mobile .vip-claim-row,
body.mobile .table-list > .table-row {
  background: rgba(15, 8, 36, 0.22) !important;
  backdrop-filter: blur(12px) !important;
  -webkit-backdrop-filter: blur(12px) !important;
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
  min-height: 48px !important;
  padding: 14px 12px !important;
}
/* Header rows (column labels) stay transparent — they're labels, not
   tappable cards. */
body.mobile .table-list > .wd-mine-header,
body.mobile .table-list > .deposit-mine-header {
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  min-height: 0 !important;
  padding: 8px 12px !important;
  border: none !important;
}

/* P1 — user-pill in topnav: actual 40px tap target instead of <30px */
body.mobile .user-pill {
  padding: 8px 12px !important;
  min-height: 40px !important;
  align-items: center !important;
}

/* P2 — daily countdown / muted text on glass plates needs lift to
   stay readable. Glass blurs page-bg behind it, faint muted text
   disappears. Bump muted → 85% white inside daily card. */
body.mobile .daily-card .daily-countdown,
body.mobile .daily-card .aff-bonus-line3 {
  color: rgba(255, 255, 255, 0.85) !important;
}

/* P2 — VIP progress bar visible on tiny phones */
body.mobile .vip-progress,
body.mobile .vip-progress-bar {
  height: 12px !important;
  border-radius: 6px !important;
}

/* P2 — fair-card hairline visible against canvas blur */
body.mobile .fair-card {
  border: 1px solid rgba(255, 255, 255, 0.12) !important;
}

/* P3 — VIP inline badge gets cherry-tinted glass plate so it reads
   as a status indicator, not orphaned text. */
body.mobile .vip-badge {
  background: rgba(255, 46, 94, 0.15) !important;
  border: 1px solid rgba(255, 46, 94, 0.35) !important;
  border-radius: 8px !important;
  padding: 4px 8px !important;
}

/* Faint hairline between table rows / list items — was rgba 0.04
   (near-invisible) project-wide, bump to 0.08 for 2× visibility. */
body.mobile .crash-bet-row,
body.mobile .table-list > .table-row + .table-row {
  border-bottom-color: rgba(255, 255, 255, 0.08) !important;
}

/* ======== Money-quantity hungry hierarchy ======== */
/* Every numerical value across the app reads as hero — big, bold,
   tabular-nums, pure white. Labels stay small and muted so the
   player's eye lands on the amount, not on the chrome text around it.
   Casino-grade Stake / Roobet treatment. */
body.mobile .bet-amount,
body.mobile input.bet-amount {
  font-size: clamp(18px, 5vw, 22px) !important;
  font-weight: 800 !important;
  letter-spacing: -0.02em !important;
  font-variant-numeric: tabular-nums !important;
  color: #fff !important;
  font-family: var(--font-ui) !important;
}
body.mobile .pot-value,
body.mobile .autoplay-row .pot-value,
body.mobile .crash-controls .pot-value {
  font-size: clamp(15px, 4.5vw, 18px) !important;
  font-weight: 800 !important;
  letter-spacing: -0.01em !important;
  font-variant-numeric: tabular-nums !important;
  color: #fff !important;
  font-family: var(--font-ui) !important;
}
body.mobile .pot-ticket-row-win .pot-value {
  color: var(--green, #00d68f) !important;
}
body.mobile .pot-label,
body.mobile .autoplay-row .pot-label,
body.mobile .crash-controls .pot-label {
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.04em !important;
  text-transform: uppercase !important;
  color: rgba(255, 255, 255, 0.75) !important;
  display: inline-block !important;
  visibility: visible !important;
  opacity: 1 !important;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
               Roboto, sans-serif !important;
}
body.mobile .pot-value,
body.mobile .autoplay-row .pot-value,
body.mobile .crash-controls .pot-value {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
               Roboto, sans-serif !important;
  font-variant-numeric: tabular-nums !important;
  font-feature-settings: 'tnum' !important;
  letter-spacing: -0.005em !important;
}

/* ======== DexScreener-style numerics — global ========
   Every monetary amount, multiplier, balance, payout, and tabular
   stat across the app uses Inter Semi-Bold with tabular-nums and
   tight tracking — same look as dexscreener.com price tickers. */
body.mobile .bet-amount,
body.mobile input.bet-amount,
body.mobile .bet-amount-text,
body.mobile .wallet-hero-amount,
body.mobile .wallet-hero-ticker,
body.mobile .crash-bet-row .bet,
body.mobile .crash-bet-row .x,
body.mobile .crash-bet-row .win-v,
body.mobile .crash-bets-total-val,
body.mobile .crash-bets-stats strong,
body.mobile .dice-slider-stat strong,
body.mobile .dice-slider-label,
body.mobile .daily-card .aff-bonus-amount,
body.mobile .quick-chip-btn,
body.mobile .aff-bonus-amount,
body.mobile .vip-progress-label,
body.mobile .vip-progress-pct,
body.mobile .pot-fiat,
body.mobile .amount-pos,
body.mobile .amount-neg,
body.mobile .table-row .amount,
body.mobile .table-row .wagered,
body.mobile .table-row .won,
body.mobile .table-row .profit,
body.mobile #page-history .table-row > *,
body.mobile .crash-status,
body.mobile #c-cashout,
body.mobile .dice-fiat-hint,
body.mobile #dice-profit,
body.mobile #dice-multiplier,
body.mobile #dice-chance,
body.mobile #dice-sbar-mult,
body.mobile #dice-sbar-chance,
body.mobile #cf-multiplier,
body.mobile #plinko-balls-val,
body.mobile #mines-next-mult,
body.mobile .dice-session strong,
body.mobile .dice-history-pill,
body.mobile .cf-history-pill,
body.mobile .roul-recent-num,
body.mobile .crash-history-pill {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
               Roboto, Helvetica, Arial, sans-serif !important;
  font-variant-numeric: tabular-nums !important;
  font-feature-settings: 'tnum' !important;
  letter-spacing: -0.005em !important;
  -webkit-font-smoothing: antialiased !important;
  -moz-osx-font-smoothing: grayscale !important;
}
body.mobile .quick-chip-btn[data-amount],
body.mobile .quick-chips-row > .quick-chip-btn:not(.tool):not([data-tool]) {
  font-size: 14px !important;
  font-weight: 800 !important;
  letter-spacing: -0.02em !important;
  font-variant-numeric: tabular-nums !important;
  color: #fff !important;
  font-family: var(--font-ui) !important;
}
body.mobile .daily-card .aff-bonus-amount {
  font-size: clamp(28px, 8vw, 36px) !important;
  font-weight: 800 !important;
  letter-spacing: -0.02em !important;
  font-variant-numeric: tabular-nums !important;
  color: #fff !important;
}
body.mobile .daily-card .aff-bonus-line1,
body.mobile .daily-card .aff-bonus-line3 {
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.04em !important;
  color: rgba(255, 255, 255, 0.65) !important;
  text-transform: uppercase !important;
}
body.mobile .wallet-hero-amount {
  font-size: clamp(36px, 10vw, 56px) !important;
  font-weight: 800 !important;
  letter-spacing: -0.03em !important;
  font-variant-numeric: tabular-nums !important;
  color: #fff !important;
}
body.mobile .wallet-hero-ticker {
  font-size: clamp(11px, 3vw, 13px) !important;
  font-weight: 600 !important;
  color: rgba(255, 255, 255, 0.65) !important;
}
body.mobile .crash-bet-row .bet,
body.mobile .crash-bet-row .x,
body.mobile .crash-bet-row .win-v {
  font-variant-numeric: tabular-nums !important;
  font-weight: 700 !important;
  letter-spacing: -0.01em !important;
}
body.mobile .crash-bet-row.won .win-v,
body.mobile .crash-bet-row.won .x {
  color: var(--green, #00d68f) !important;
  font-weight: 800 !important;
}
body.mobile #page-history .table-row > * {
  font-variant-numeric: tabular-nums !important;
}
body.mobile #page-history .table-row .amount,
body.mobile #page-history .table-row .wagered,
body.mobile #page-history .table-row .won,
body.mobile #page-history .table-row .profit {
  font-size: 14px !important;
  font-weight: 800 !important;
  letter-spacing: -0.01em !important;
  color: #fff !important;
}
body.mobile #page-history .amount-pos { color: var(--green, #00d68f) !important; }
body.mobile #page-history .amount-neg { color: var(--red, #ff5360) !important; }
body.mobile .dice-roll-btn,
body.mobile .cf-roll-btn,
body.mobile .roul-spin-btn,
body.mobile .crash-bet-btn,
body.mobile .plinko-drop-btn,
body.mobile .mines-bet-btn,
body.mobile .bj-deal-btn {
  font-size: clamp(15px, 4.5vw, 18px) !important;
  font-weight: 800 !important;
  letter-spacing: 0.02em !important;
  font-variant-numeric: tabular-nums !important;
  font-family: var(--font-ui) !important;
}

/* ======== Section A — premium glass details ======== */

/* A1 — Topnav bevel highlight on the bottom edge */
body.mobile #titlebar {
  box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.06) !important;
}

/* A2 — Tutorial panel diagonal sheen */
.tutorial-panel::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%,
                                       rgba(255, 255, 255, 0) 55%);
  pointer-events: none;
  z-index: 0;
}
.tutorial-panel > * { position: relative; z-index: 1; }

/* A3 — 3D canvas vignette overlay (post-mount) */
body.mobile .dice-canvas-wrap[data-dice3d-hosted]::after,
body.mobile #page-coinflip .game-display[data-three-hosted]::after,
body.mobile #page-slots .game-display[data-three-hosted]::after,
body.mobile .crash-stage[data-three-hosted]::after,
body.mobile .plinko-stage[data-three-hosted]::after,
body.mobile .mines-stage[data-three-hosted]::after,
body.mobile .roul-wheel-wrap[data-three-hosted]::after,
body.mobile .blackjack-stage[data-three-hosted]::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center,
    rgba(0, 0, 0, 0) 35%,
    rgba(0, 0, 0, 0.35) 95%);
  pointer-events: none;
  z-index: 5;
}

/* A4 — Boot splash removed; cherry-pulse keyframe + rule retired. */

/* A5 — Hero balance text-shadow glow removed: 24 px blur read as a
   visible rectangle behind the number on dark backgrounds instead
   of a soft aura. The amount is hero-sized + bold + tabular already
   — no glow needed. */

/* A6 — VIP badge shimmer sweep every 8s */
@keyframes vipShimmer {
  0%, 92% { transform: translateX(-120%); opacity: 0; }
  94%     { opacity: 1; }
  100%    { transform: translateX(220%); opacity: 0; }
}
body.mobile .vip-pill-badge {
  position: relative;
  overflow: hidden;
}
body.mobile .vip-pill-badge::after {
  content: '';
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 30%;
  background: linear-gradient(110deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.45) 50%,
    rgba(255, 255, 255, 0) 100%);
  animation: vipShimmer 8s linear infinite;
  pointer-events: none;
}

/* Big-wins ticker disabled — the constantly-scrolling marquee
   behind the titlebar was visual noise; hidden here so the topnav
   sits on a clean canvas. Renderer code stays so it can be re-
   enabled with one line change if needed. */
body.mobile .big-wins-ticker,
body.mobile #big-wins-ticker {
  display: none !important;
}

/* Roulette HOT / COLD / RECENT panel — matches the topnav glass
   treatment: same 75% rgba fill, blur(22px) saturate(140%), and the
   1 px inset bevel highlight along the bottom edge. Reads as the
   same chrome layer as the topnav. */
body.mobile .hot-cold,
body.mobile #roul-hot-cold {
  background: rgba(15, 8, 36, 0.75) !important;
  border: none !important;
  border-radius: var(--r-lg) !important;
  backdrop-filter: blur(22px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(22px) saturate(140%) !important;
  box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.06) !important;
}

/* ======== Uniform game history strip ======== */
/* Dice / coinflip / roulette / crash all show a recent-results pill
   strip at the top of the canvas. Unify the CONTAINER spacing AND
   the PILL geometry (size, radius, font, gap) so every game's strip
   reads as the same chrome layer. Per-game colours (red/black/gold/
   green/multiplier-coloured) stay intact — only size + position get
   uniformed. */
body.mobile .dice-history,
body.mobile .cf-recent-hero,
body.mobile .roul-recent-hero,
body.mobile .crash-history {
  top: 76px !important;
  z-index: 15 !important;
  /* 8% L+R inset so the outermost pills never touch the screen edge
     in any game (was 12 px / ~3% on a 393-wide phone, which still let
     the pill rim graze the gutter). overflow:hidden on the strip
     trims any pills that don't fit inside the inset width. */
  padding: 0 8% !important;
  gap: 6px !important;
  min-height: 28px !important;
  overflow: hidden !important;
}
body.mobile .dice-history-pill,
body.mobile .cf-recent-pill,
body.mobile .roul-recent-pill,
body.mobile .crash-history-pill {
  min-width: 26px !important;
  width: 26px !important;
  height: 26px !important;
  padding: 0 !important;
  border-radius: 50% !important;
  font-size: 11px !important;
  font-weight: 800 !important;
  font-variant-numeric: tabular-nums !important;
  letter-spacing: -0.02em !important;
  flex-shrink: 0 !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
}


/* ======== Per-game loading splash ======== */
/* Pulsing cherry on a dark glass plate covers the canvas while the 3D
   module finishes loading and renders its first frame. Visible by
   default; fades out the moment the mount function stamps
   `data-three-hosted` (or `data-dice3d-hosted` for dice) on the
   container. The 400ms opacity transition gives the WebGL scene time
   to paint its first frame before the splash clears. */
body.mobile .dice-canvas-wrap,
body.mobile #page-coinflip .game-display,
body.mobile #page-slots .game-display,
body.mobile .crash-stage,
body.mobile .plinko-stage,
body.mobile .mines-stage,
body.mobile .roul-wheel-wrap,
body.mobile .blackjack-stage {
  position: relative;
}
body.mobile .dice-canvas-wrap::before,
body.mobile #page-coinflip .game-display::before,
body.mobile #page-slots .game-display::before,
body.mobile .crash-stage::before,
body.mobile .plinko-stage::before,
body.mobile .mines-stage::before,
body.mobile .roul-wheel-wrap::before,
body.mobile .blackjack-stage::before {
  content: '';
  position: absolute;
  inset: 0;
  background-color: rgba(15, 8, 36, 0.92);
  background-image: url('./cherry.webp');
  background-position: center;
  background-repeat: no-repeat;
  background-size: 56px 56px;
  z-index: 20;
  pointer-events: none;
  opacity: 1;
  transition: opacity 250ms ease-out;
}
/* Hide ONLY after the per-game mount has actually rendered its first
   WebGL frame and JS sets data-three-ready. The earlier data-three-
   hosted flag was set BEFORE mount() ran, which hid the splash too
   eagerly — players saw a flash of empty canvas. data-three-ready
   is set via double-rAF inside each mount helper. */
body.mobile .dice-canvas-wrap[data-three-ready]::before,
body.mobile #page-coinflip .game-display[data-three-ready]::before,
body.mobile #page-slots .game-display[data-three-ready]::before,
body.mobile .crash-stage[data-three-ready]::before,
body.mobile .plinko-stage[data-three-ready]::before,
body.mobile .mines-stage[data-three-ready]::before,
body.mobile .roul-wheel-wrap[data-three-ready]::before,
body.mobile .blackjack-stage[data-three-ready]::before {
  opacity: 0;
  animation: none;
}

/* ======== Deep polish — interactions, transitions, contrast ======== */
/* Final layer of premium feel: every tappable element gets an :active
   press response, every async-rendered surface fades/slides in, muted
   text on glass plates gets a contrast lift, and tap targets reach the
   44px Apple HIG floor. */

/* --- Micro-interactions: :active press response on everything tappable --- */
body.mobile .btn,
body.mobile .nav-btn,
body.mobile .mtab,
body.mobile .tab,
body.mobile .seg,
body.mobile .crash-tab,
body.mobile .quick-chip-btn,
body.mobile .crash-chip,
body.mobile .mines-tile,
body.mobile .coin-picker-item,
body.mobile .tb-icon-btn,
body.mobile .tb-deposit-btn,
body.mobile .tb-lang-btn,
body.mobile .user-pill,
body.mobile .coin-pill,
body.mobile .user-menu-item,
body.mobile .collapse-toggle,
body.mobile .crash-fair-badge,
body.mobile .crash-bet-row,
body.mobile .table-row {
  transition: transform 0.12s ease, background-color 0.15s ease,
              border-color 0.15s ease, opacity 0.15s ease !important;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}
body.mobile .btn:active,
body.mobile .nav-btn:active,
body.mobile .mtab:active,
body.mobile .tab:active,
body.mobile .seg:active,
body.mobile .crash-tab:active,
body.mobile .quick-chip-btn:active,
body.mobile .crash-chip:active,
body.mobile .mines-tile:active,
body.mobile .coin-picker-item:active,
body.mobile .tb-icon-btn:active,
body.mobile .tb-deposit-btn:active,
body.mobile .tb-lang-btn:active,
body.mobile .user-pill:active,
body.mobile .coin-pill:active,
body.mobile .user-menu-item:active,
body.mobile .collapse-toggle:active,
body.mobile .crash-fair-badge:active,
body.mobile .crash-bet-row:active,
body.mobile .table-row:active {
  transform: scale(0.97);
}

/* --- Nav drawer buttons: solid background, no per-button backdrop-filter.
   The drawer itself has #07021a solid; adding a blur layer per button
   stacks 15 separate compositor layers and on iOS Safari + Telegram
   WebApp some of them silently fail to paint when a game page below has
   its own WebGL/animation layers, leaving certain rows invisible. */
body.mobile #sidebar .nav-btn:not(.active) {
  background: rgba(255, 255, 255, 0.04) !important;
}
body.mobile .support-thread-item {
  background: rgba(15, 8, 36, 0.22) !important;
  backdrop-filter: blur(12px) !important;
  -webkit-backdrop-filter: blur(12px) !important;
}
/* Softer modal backdrop — was rgba(0,0,0,0.75) which felt heavy */
body.mobile .modal-backdrop,
body.mobile .page--modal-active {
  background: rgba(0, 0, 0, 0.50) !important;
  backdrop-filter: blur(16px) !important;
  -webkit-backdrop-filter: blur(16px) !important;
}

/* --- Focus states (CLAUDE.md: border-color only, NO halo / NO bg lift) --- */
body.mobile .input:focus,
body.mobile .select:focus,
body.mobile textarea:focus,
body.mobile .field input:focus {
  border-color: #d91554 !important;
  box-shadow: none !important;
  background: var(--bg-input) !important;
  outline: none !important;
}
/* Keyboard focus ring on tappable chrome — only when via Tab key, not on tap */
body.mobile .quick-chip-btn:focus-visible,
body.mobile .crash-chip:focus-visible,
body.mobile .coin-picker-item:focus-visible,
body.mobile .btn:focus-visible,
body.mobile .nav-btn:focus-visible {
  outline: 2px solid #d91554 !important;
  outline-offset: 2px !important;
}

/* --- Entry transitions for async-rendered surfaces --- */
@keyframes modalIn {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes toastIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fadeInQ {
  from { opacity: 0; }
  to   { opacity: 1; }
}
body.mobile .modal,
body.mobile .coin-picker,
body.mobile .fiat-picker,
body.mobile .games-picker,
body.mobile .lang-picker,
body.mobile #dep-picker,
body.mobile #wd-picker,
body.mobile .user-menu[style*="block"] {
  animation: modalIn 0.18s ease-out;
}
body.mobile #toast-stack .toast {
  animation: toastIn 0.2s ease-out;
}
body.mobile .page.active {
  animation: fadeInQ 0.25s ease-out;
}

/* --- Tap targets ≥ 44 px on critical chrome --- */
body.mobile .user-pill {
  padding: 8px 12px !important;
  min-height: 44px !important;
  display: flex !important;
  align-items: center !important;
}
body.mobile .coin-pill {
  padding: 8px 14px !important;
  min-height: 40px !important;
  display: inline-flex !important;
  align-items: center !important;
}
body.mobile .cp-switch {
  width: 44px !important;
  height: 26px !important;
}
body.mobile .cp-switch::after {
  width: 20px !important;
  height: 20px !important;
}

/* --- Text contrast on glass plates --- */
body.mobile .muted,
body.mobile .text-muted,
body.mobile .text-dim {
  color: rgba(255, 255, 255, 0.75) !important;
}
body.mobile .dice-canvas-wrap .dice-readout-label,
body.mobile .game-display .dice-readout-label {
  color: #fff !important;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6) !important;
  font-weight: 700 !important;
}

/* --- Disabled state — clearly non-actionable, not "broken". Note:
   pointer-events stays at the browser default (none for :disabled
   <button>) — overriding to `auto` re-enables clicks on disabled
   buttons, which was a bug that also confused iOS's tap pipeline. */
body.mobile .btn:disabled,
body.mobile button:disabled {
  opacity: 0.55 !important;
  cursor: not-allowed !important;
  filter: grayscale(0.45) !important;
}

/* --- Tap responsiveness — eliminate the 300 ms iOS click delay on
   text inputs and quick-tap chips. `touch-action: manipulation`
   tells the browser to skip the double-tap-to-zoom check, so taps
   register instantly. Critical for the numpad: every digit press
   in a number input goes through here. */
body.mobile .input,
body.mobile .select,
body.mobile .field input,
body.mobile textarea,
body.mobile input[type="text"],
body.mobile input[type="email"],
body.mobile input[type="password"],
body.mobile input[type="number"],
body.mobile .quick-chip-btn,
body.mobile .crash-chip,
body.mobile .btn,
body.mobile .nav-btn,
body.mobile .mtab,
body.mobile .tab,
body.mobile .crash-tab {
  touch-action: manipulation;
}

/* Inputs need their own scope free of user-select:none / transform
   transitions / etc. so the iOS keyboard pipeline isn't second-
   guessed. Explicit reset for any earlier broad rule that may have
   leaked. */
body.mobile .input,
body.mobile .select,
body.mobile .field input,
body.mobile textarea,
body.mobile input[type="text"],
body.mobile input[type="email"],
body.mobile input[type="password"],
body.mobile input[type="number"] {
  user-select: text !important;
  -webkit-user-select: text !important;
  transform: none !important;
}

/* --- Keyboard-active mode — drop expensive backdrop-filter blur AND
   bump the rgba opacity to ~85% so chrome reads as a solid panel
   instead of a "ghost from the air" once the blur is gone. iOS no
   longer has to recomposite a dozen frosted-glass layers on every
   keypress, and the player still sees clean separation between the
   sticky bet panel and the page bg. */
body.mobile.has-keyboard #titlebar,
body.mobile.has-keyboard #mobile-tabbar,
body.mobile.has-keyboard .coin-pill,
body.mobile.has-keyboard .crash-bets-panel,
body.mobile.has-keyboard .crash-bets-total,
body.mobile.has-keyboard .crash-bets-header,
body.mobile.has-keyboard .crash-bet-row,
body.mobile.has-keyboard .crash-bets-tabs,
body.mobile.has-keyboard .crash-bets-footer,
body.mobile.has-keyboard .dice-history,
body.mobile.has-keyboard .cf-recent-hero,
body.mobile.has-keyboard .roul-recent-hero,
body.mobile.has-keyboard .crash-history,
body.mobile.has-keyboard .dice-slider-stat,
body.mobile.has-keyboard .dice-slider-stats,
body.mobile.has-keyboard .modal,
body.mobile.has-keyboard .coin-picker,
body.mobile.has-keyboard .games-picker,
body.mobile.has-keyboard .fiat-picker,
body.mobile.has-keyboard .lang-picker,
body.mobile.has-keyboard .user-menu,
body.mobile.has-keyboard .table-row,
body.mobile.has-keyboard .vip-rb-row {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
/* Sticky bet controls keep the glassy treatment while the OS keyboard
   is up — backdrop-filter blur stays for the premium feel, fill bumps
   to 70% so the panel reads as solid-ish above the keyboard without
   going fully opaque. */
body.mobile.has-keyboard .dice-controls-sticky,
body.mobile.has-keyboard .cf-controls-sticky,
body.mobile.has-keyboard .roul-controls-sticky,
body.mobile.has-keyboard .slots-controls-sticky,
body.mobile.has-keyboard .mines-controls-sticky,
body.mobile.has-keyboard .plinko-controls-sticky,
body.mobile.has-keyboard .bj-controls-sticky,
body.mobile.has-keyboard .crash-controls,
body.mobile.has-keyboard .autoplay-row {
  background: rgba(15, 8, 36, 0.70) !important;
  backdrop-filter: blur(16px) saturate(130%) !important;
  -webkit-backdrop-filter: blur(16px) saturate(130%) !important;
}
/* Splash pulse pauses while the keyboard is up — saves more GPU. */
body.mobile.has-keyboard .dice-canvas-wrap::before,
body.mobile.has-keyboard .game-display::before,
body.mobile.has-keyboard .crash-stage::before,
body.mobile.has-keyboard .plinko-stage::before,
body.mobile.has-keyboard .mines-stage::before,
body.mobile.has-keyboard .roul-wheel-wrap::before,
body.mobile.has-keyboard .blackjack-stage::before {
  animation: none !important;
}

/* --- Scrollbar in brand cherry, not muted lavender --- */
body.mobile .crash-bets-list::-webkit-scrollbar-thumb,
body.mobile .table-list::-webkit-scrollbar-thumb,
body.mobile .modal::-webkit-scrollbar-thumb,
body.mobile .coin-picker::-webkit-scrollbar-thumb,
body.mobile .lang-picker::-webkit-scrollbar-thumb {
  background: rgba(255, 46, 94, 0.4) !important;
}
body.mobile .crash-bets-list::-webkit-scrollbar-thumb:hover,
body.mobile .table-list::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 46, 94, 0.6) !important;
}

/* --- Selection color — brand cherry, not browser-default blue --- */
::selection {
  background: rgba(217, 21, 84, 0.4);
  color: #fff;
}

/* --- Cursor: pointer on every clickable —catches any missed --- */
body.mobile .nav-btn,
body.mobile .mtab,
body.mobile .tab,
body.mobile .coin-picker-item,
body.mobile .crash-bet-row,
body.mobile .table-row,
body.mobile .vip-menu-chip {
  cursor: pointer;
}

/* --- Collapse toggle: chev rotates smoothly --- */
body.mobile .collapse-toggle {
  transition: transform 0.18s ease !important;
}
body.mobile .collapse-toggle:hover { transform: scale(1.08); }
body.mobile .crash-bets-panel.collapsed .collapse-toggle {
  transform: rotate(180deg);
}
/* Tighten the row gap inside the bets list so the glassy rows visually
   stack into a continuous list rather than reading as separate chips.
   Every row enforced to the same height so a row with empty X/Win
   cells doesn't shrink while a fully-resolved row stays tall. */
body.mobile .crash-bets-list {
  gap: 0 !important;
}
body.mobile .crash-bet-row {
  height: 40px !important;
  min-height: 40px !important;
  max-height: 40px !important;
  padding: 0 8px !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  align-items: center !important;
}
body.mobile .crash-bet-row:last-child {
  border-bottom: none !important;
}
/* PLAYER header text aligns with the player NAME (not the avatar) in
   each row below. The row's first cell starts with an avatar (~22 px
   wide) + 7 px gap before the name; pad the header's PLAYER cell by
   the same offset so the column reads as visually aligned. */
body.mobile .crash-bets-header > :first-child,
body.mobile .crash-bets-header span:first-child {
  text-align: left !important;
  padding-left: 29px !important;
}
/* GAME column header — same left-alignment trick as PLAYER above so
   the word "GAME" lines up with the first letter of each game name
   (Dice, Coin Flip, Crash) in the rows. */
body.mobile .crash-bets-header > :nth-child(3),
body.mobile .crash-bets-header span:nth-child(3) {
  text-align: left !important;
  padding-left: 0 !important;
}
/* Inline coin icon prepended to each bet amount cell. Mirrors the
   coin-picker pattern exactly: the ring has no explicit width and
   auto-sizes from the icon + padding, just like `.coin-picker-icon
   .coin-ring`. Without this, the box-sizing math on an explicit
   width clipped the icon against the padding and SOL (whose SVG is
   pure black inside) lost its purple/green gradient ring. */
body.mobile .crash-bet-row .bet {
  display: inline-flex !important;
  align-items: center !important;
  gap: 5px !important;
  min-width: 0 !important;
}
body.mobile .crash-bet-row .bet .coin-ring {
  width: auto !important;
  height: auto !important;
  padding: 1.5px !important;
  flex-shrink: 0 !important;
}
body.mobile .crash-bet-row .bet .coin-ring .coin-icon {
  width: 14px !important;
  height: 14px !important;
}

/* ======== VIP progress chip in user-menu ======== */
/* Surfaces the player's tier + progress to next tier so they notice the
   VIP system without having to open /vip. Tappable — opens the VIP page. */
.vip-menu-chip {
  flex-direction: column !important;
  align-items: stretch !important;
  gap: 6px !important;
  padding: 10px 12px !important;
  cursor: pointer;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
}
.vip-menu-chip-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  color: var(--tier-colour, var(--text, #fff));
  letter-spacing: 0.02em;
}
.vip-menu-chip-tier {
  flex: 0 0 auto;
  text-transform: uppercase;
}
.vip-menu-chip-pct {
  margin-left: auto;
  color: rgba(255, 255, 255, 0.65);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
}
.vip-menu-chip-bar {
  display: block;
  position: relative;
  height: 4px;
  width: 100%;
  background: rgba(255, 255, 255, 0.08);
  border-radius: 2px;
  overflow: hidden;
}
.vip-menu-chip-fill {
  display: block;
  height: 100%;
  width: var(--vip-progress, 0%);
  background: var(--tier-colour, var(--primary, #ff2e5e));
  transition: width 0.3s ease;
}

/* ======== Daily-bonus streak indicator ========
   Refined for a tighter, less-shouty read:
   - 1 px cherry hairline instead of the 2 px CTA rim
   - tabular nums + -0.01em tracking (standard casino UI typography)
   - thin vertical separator instead of a comma
   - single amber accent on the bonus segment, keeps the orange flame
*/
.daily-streak-line {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding: 5px 12px;
  background: rgba(15, 8, 36, 0.55);
  border: 1px solid rgba(217, 21, 84, 0.28);
  border-radius: var(--r-pill, 999px);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  color: rgba(255, 255, 255, 0.96);
}
.daily-streak-line strong { color: #fff; font-weight: 800; }
.daily-streak-sep {
  width: 1px;
  height: 11px;
  background: rgba(255, 255, 255, 0.18);
  margin: 0 2px;
  display: inline-block;
  flex-shrink: 0;
}
.daily-streak-bonus { color: #ff9500; }


/* Bets-panel custom overrides removed — every attempt (width: 100vw,
   fixed drawer, max-height + flex column) broke the player rows
   visibility or the PLACE BET button. The original CSS earlier in
   this file already handles collapsed/expanded states correctly; no
   final override is needed. */

/* ─── FINAL FORCE: affiliate CTAs + earnings calc = "Numbers only" ───
   Match the .bet-error / "Bet (Next round)" / Verify TOTP family —
   solid dark navy plate with a 2 px cherry-pink rim, sharp 4 px
   corners, white text. Reads as a distinct CTA class from the place-
   bet glass-red gradient, but still on-brand.
   ID selectors (`#aff-code-add`, `#aff-copy`) used where the legacy
   CSS uses ID + class for that element — needed so this rule out-
   ranks the earlier `#aff-code-add { border-color: #d91554 }` line. */
body #aff-code-add,
body .aff-code-add,
body .aff-code-copy-one,
body .aff-tg-share,
body .aff-tg-copy,
body #aff-copy,
body .aff-calc-card {
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid #d91554 !important;
  border-radius: 4px !important;
  color: #fff !important;
  font-family: var(--font-ui) !important;
  font-weight: 800 !important;
  letter-spacing: 0.04em !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  box-shadow: none !important;
  text-transform: none !important;
}
body #aff-code-add:hover,
body .aff-code-add:hover,
body .aff-code-copy-one:hover,
body .aff-tg-share:hover,
body .aff-tg-copy:hover,
body #aff-copy:hover {
  background: rgba(15, 8, 36, 0.78) !important;
  border: 2px solid #d91554 !important;
  filter: none !important;
}
body #aff-code-add:active,
body .aff-code-add:active,
body .aff-code-copy-one:active,
body .aff-tg-share:active,
body .aff-tg-copy:active,
body #aff-copy:active {
  background: rgba(15, 8, 36, 0.85) !important;
  border: 2px solid #d91554 !important;
  transform: none !important;
}

/* EARNINGS EXAMPLE card override — solid cherry-pink fill matching the
   2 px border rim. Stands out as the hero "do this" CTA on the affiliate
   page (vs the dark-plate Copy / Share / Add code buttons which are
   secondary actions). Linear gradient adds subtle vertical depth so the
   pink reads as a button surface, not a flat sticker. */
body .aff-calc-card {
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid #d91554 !important;
}
body .aff-calc-card .aff-calc-label {
  color: rgba(255, 255, 255, 0.7) !important;
}
body .aff-calc-card .aff-calc-line {
  color: rgba(255, 255, 255, 0.92) !important;
}
body .aff-calc-card .aff-calc-amount {
  color: #fff !important;
}
body .aff-calc-card .aff-calc-sub {
  color: rgba(255, 255, 255, 0.72) !important;
}

/* Affiliate stat + signup-bonus cards: match EARNINGS EXAMPLE plate.
   The `body.mobile` variant exists alongside the plain `body` one so
   this rule out-specifics the mobile-card override (`body.mobile
   .aff-bonus-card { border: 1px solid rgba(255,255,255,0.06) }`) which
   would otherwise win on Telegram / mobile viewports. */
body #aff-stats .stat-card,
body.mobile #aff-stats .stat-card,
body .aff-bonus-card,
body.mobile .aff-bonus-card {
  background: rgba(15, 8, 36, 0.7) !important;
  border: 2px solid #d91554 !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
