/* =========================================================
   SPINARMORY — additions: notifications, balance dropdown tweaks,
   Shuffle-style bottom bar, bets feed, live stats widget,
   VIP page, Rewards page, responsive fixes.
   ========================================================= */

@keyframes bj-flip {
  0%   { transform: rotateY(90deg) translateY(-6px); opacity: 0; }
  100% { transform: rotateY(0) translateY(0); opacity: 1; }
}

/* ============ DICE slider — hide native thumb; we draw our own ============ */
.gp-canvas input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
}
.gp-canvas input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 28px; height: 28px;
  background: transparent;
  border: 0;
  cursor: pointer;
}
.gp-canvas input[type="range"]::-moz-range-thumb {
  width: 28px; height: 28px;
  background: transparent;
  border: 0;
  cursor: pointer;
}
.gp-canvas input[type="range"]::-webkit-slider-runnable-track {
  background: transparent;
  border: 0;
  height: 28px;
}
.gp-canvas input[type="range"]::-moz-range-track {
  background: transparent;
  border: 0;
  height: 28px;
}
.gp-canvas input[type="range"]:focus { outline: none; }

/* ============ PLAYER MODAL — shuffle style ============ */
.pm-shuffle {
  padding: 0;
  background: var(--panel);
  color: var(--text);
  border-radius: var(--radius);
  overflow: hidden;
}
.pm-shuffle-hero {
  position: relative;
  padding: 32px 20px 24px;
  background:
    radial-gradient(60% 100% at 50% 50%, rgba(61, 126, 255,.35) 0%, transparent 70%),
    linear-gradient(180deg, #1a0d33 0%, #0f0822 100%);
  overflow: hidden;
  min-height: 220px;
}
.pm-chips-bg {
  position: absolute; inset: 0;
  pointer-events: none;
}
.pm-chips-bg svg { animation: pm-chip-float 6s ease-in-out infinite alternate; }
.pm-chips-bg svg:nth-child(2) { animation-duration: 8s; animation-delay: -2s; }
.pm-chips-bg svg:nth-child(3) { animation-duration: 7s; animation-delay: -1s; }
.pm-chips-bg svg:nth-child(4) { animation-duration: 9s; animation-delay: -3s; }
.pm-chips-bg svg:nth-child(5) { animation-duration: 10s; animation-delay: -4s; }

@keyframes pm-chip-float {
  0%   { transform: translate(0, 0) rotate(var(--r, 0deg)); }
  100% { transform: translate(0, -10px) rotate(calc(var(--r, 0deg) + 6deg)); }
}

.pm-shuffle-body {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  z-index: 2;
}
.pm-shuffle-avatar {
  width: 86px; height: 86px;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(10px);
  padding: var(--space-1);
  box-shadow: 0 0 0 1px rgba(255,255,255,.08), 0 12px 32px rgba(0,0,0,.5);
}
.pm-shuffle-avatar-img {
  width: 100%; height: 100%;
  border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-size: 30px;
  color: #fff;
  text-shadow: 0 2px 8px rgba(0,0,0,.45);
}
.pm-shuffle-avatar-default {
  background: rgba(255, 255, 255, .08);
  color: rgba(255, 255, 255, .55);
}
.pm-shuffle-name {
  font-family: var(--font-ui);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -.01em;
  margin: 0;
  color: #fff;
}
.pm-shuffle-tier {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 6px 14px;
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: var(--radius-pill);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  color: #fff;
}
.pm-shuffle-tier-emblem {
  color: var(--tier-color, #3D7EFF);
  font-size: 12px;
}

/* Action buttons row */
.pm-shuffle-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  padding: 18px 16px 14px;
}
.pm-shuffle-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: 13px 18px;
  border-radius: var(--radius-md);
  border: 0;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: .15s;
  min-height: 46px;
}
.pm-shuffle-btn:disabled { opacity: .5; cursor: not-allowed; }
.pm-shuffle-btn-primary {
  background: var(--purple);
  color: #fff;
  box-shadow: 0 8px 20px rgba(61, 126, 255, .4);
}
.pm-shuffle-btn-primary:hover:not(:disabled) { transform: translateY(-1px); filter: brightness(1.1); }
.pm-shuffle-btn-ghost {
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--line-soft);
}
.pm-shuffle-btn-ghost:hover:not(:disabled) { background: rgba(255,255,255,.05); }

/* Inline tip form */
.pm-shuffle-tip {
  padding: 18px 16px 14px;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.pm-shuffle-tip-row {
  display: grid;
  grid-template-columns: 90px 1fr;
  gap: var(--space-4);
}
.pm-shuffle-tip-row select,
.pm-shuffle-tip-row input {
  padding: 12px 14px;
  background: var(--panel-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 14px;
}
.pm-shuffle-tip-row input:focus { outline: none; border-color: var(--purple); }
.pm-shuffle-tip-quick {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.pm-shuffle-tip-quick button {
  flex: 1;
  min-width: 50px;
  padding: var(--space-3);
  background: var(--panel-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  font-size: 12px;
  cursor: pointer;
  transition: .15s;
}
.pm-shuffle-tip-quick button:hover { color: var(--purple); border-color: rgba(61, 126, 255,.3); }
.pm-shuffle-tip-actions {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: var(--space-4);
}
.pm-shuffle-tip-err {
  font-family: var(--font-display);
  font-size: 11px;
  color: var(--magenta);
  text-align: center;
}

/* 3-column stats */
.pm-shuffle-stats {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 0;
  padding: 14px 16px 20px;
  border-top: 1px solid var(--line-soft);
}
.pm-shuffle-stat {
  padding: 14px 12px;
  background: var(--panel-2);
  border: 1px solid var(--line-soft);
  text-align: left;
}
.pm-shuffle-stat:first-child { border-radius: 10px 0 0 10px; border-right: 0; }
.pm-shuffle-stat:last-child  { border-radius: 0 10px 10px 0; border-left: 0; }
.pm-shuffle-stat:nth-child(2) { border-left: 0; border-right: 0; }
.pm-shuffle-stat .k {
  font-family: var(--font-ui);
  font-size: 11px;
  color: var(--text-mute);
  margin-bottom: 6px;
}
.pm-shuffle-stat .v {
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.pm-shuffle-stat-with-coin .pm-shuffle-stat-coin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: 50%;
  font-size: 11px;
  font-weight: 800;
  flex-shrink: 0;
}

/* Recent (optional) */
.pm-shuffle-recent {
  padding: 0 16px 20px;
}
.pm-shuffle-recent-head {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .15em;
  color: var(--text-mute);
  margin-bottom: 8px;
}
.pm-shuffle-recent-row {
  display: grid;
  grid-template-columns: 1fr 60px 90px;
  gap: var(--space-3);
  padding: 8px 0;
  font-size: 12px;
  border-top: 1px solid var(--line-soft);
}
.pm-shuffle-recent-row .m { color: var(--purple); text-align: right; font-family: var(--font-display); }
.pm-shuffle-recent-row .w { text-align: right; font-weight: 600; font-family: var(--font-display); }

/* Mobile tweaks */
@media (max-width: 520px) {
  .pm-shuffle-hero { padding: 26px 16px 20px; min-height: 200px; }
  .pm-shuffle-avatar { width: 72px; height: 72px; }
  .pm-shuffle-avatar-img { font-size: 26px; }
  .pm-shuffle-name { font-size: 20px; }
  .pm-shuffle-stats { padding: 12px 14px 16px; }
  .pm-shuffle-stat { padding: 12px 10px; }
  .pm-shuffle-stat .k { font-size: 10px; }
  .pm-shuffle-stat .v { font-size: 13px; }
}

/* Card dealing animation — operator rebuild. Cards now fly from
   the upper-right corner (where the visible .bj-deck stack lives),
   not just "downward from above". The fixed origin reads as the
   dealer pulling cards off the deck and flicking them onto the
   table; the brief mid-flight rotate adds physicality. The CSS
   variable fallbacks let the BjCard component still override per-
   card if it ever wants a different origin. */
@keyframes bj-deal {
  0%   { transform: translate(var(--fromX, 220px), var(--fromY, -180px)) rotate(-15deg) scale(.7); opacity: 0; }
  50%  { opacity: 1; }
  100% { transform: translate(0, 0) rotate(0) scale(1); opacity: 1; }
}

/* ============ BLACKJACK board + cards (Degen-aligned rebuild) ============
   The felt is a 3-row grid (dealer / info pill / player hands) so the
   centred BLACKJACK 3:2 · INSURANCE 2:1 strip stays anchored even when
   only one side has cards. Deck stack absolute-pinned top-right; rules
   pill absolute-pinned top-left. Surface gradient stays grey-on-grey
   per the global palette rule. */
.bj-board {
  background:
    radial-gradient(70% 60% at 50% 30%, var(--accent-10) 0%, transparent 70%),
    radial-gradient(80% 90% at 50% 100%, rgba(0, 0, 0, .55) 0%, transparent 60%),
    linear-gradient(180deg, var(--bg-3) 0%, var(--bg-1) 100%) !important;
  border-radius: var(--radius);
  position: relative;
  display: grid !important;
  grid-template-columns: 1fr;
  /* Operator feedback — pin the dealer (row 2) and player (row 4) row
     tracks to a fixed minimum height (card 116 + total badge 24 + gap
     8). Without this the rows used to be `auto`, which means an empty
     hand wrap collapsed to 0 and the felt visibly grew as cards
     landed during the deal. Mobile got the worst of it because the
     board hugged the viewport. The flex 1fr top/bottom tracks keep
     the layout vertically centred regardless of slot occupancy. */
  grid-template-rows: 1fr 148px auto 148px 1fr;
  justify-items: center;
  align-items: center;
  gap: 8px;
  padding: 30px;
  min-height: 540px;
  overflow: hidden !important;
  box-shadow: inset 0 0 80px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(255, 255, 255, .03);
}

.bj-deck-slot {
  position: absolute;
  top: 18px;
  right: 22px;
  width: 56px;
  height: 74px;
  z-index: 1;
  pointer-events: none;
}
.bj-deck-svg { display: block; }
/* Favicon centred on the top card of the deck — small enough that it
   reads as a brand mark, not a full logo, and the diagonal pattern
   still shows through around it. */
/* Operator feedback — favicon was rendered too large and sat over the
   geometric centre of the deck-slot, but the visible TOP card of the
   stack is offset (the SVG draws three rectangles staggered down-right
   by 0/2/4/6 px). Anchoring at 39%/41% — the centre of that visible
   top rect — and shrinking to 18px keeps the mark inside the card
   border on both desktop and mobile sizes. */
.bj-deck-mark {
  position: absolute;
  left: 39%;
  top: 41%;
  transform: translate(-50%, -50%);
  width: 18px;
  height: 18px;
  object-fit: contain;
  border-radius: 4px;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .65));
  pointer-events: none;
}

/* Centred info pill row — sits in the middle grid track between the
   dealer hand (above) and player hand(s) (below). */
.bj-info {
  grid-row: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  z-index: 1;
}
.bj-info-row {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: nowrap;
  white-space: nowrap;
  position: relative;
  padding-bottom: 22px; /* room for the side-chip amount badge */
  max-width: 100%;
}
.bj-info-pill {
  height: 44px;
  display: inline-flex;
  align-items: center;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: 8px;
  padding: 0 22px;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
  color: var(--text-secondary);
  letter-spacing: .06em;
  white-space: nowrap;
  flex-shrink: 0;
  position: relative;
  z-index: 2;
}
.bj-info-row.has-pp .bj-info-pill { padding-left: 28px; border-radius: 0 8px 8px 0; }
.bj-info-row.has-tp .bj-info-pill { padding-right: 28px; border-radius: 8px 0 0 8px; }
.bj-info-row.has-pp.has-tp .bj-info-pill { border-radius: 0; }
/* Task #192 — pulse-highlight the INSURANCE 2:1 segment of the
   centre pill while the offer prompt is open so the player's eye
   tracks back to the felt rather than just the prompt button. */
.bj-info-pill .bj-pill-ins { color: var(--text-secondary); transition: color .2s ease; }
.bj-info-pill-ins-active {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-40), 0 0 16px -4px var(--accent-40);
}
.bj-info-pill-ins-active .bj-pill-ins {
  color: var(--accent);
  animation: bj-ins-pulse 1.2s ease-in-out infinite;
}
@keyframes bj-ins-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .55; }
}
.bj-info-sub {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  color: var(--text-tertiary);
  letter-spacing: .18em;
}
.bj-pill-full { display: inline; }
.bj-pill-short { display: none; }

/* Side-bet ribbon — chips chevron-clipped on the outer edge so the
   central pill flows visually through the strip. */
.bj-side-chip-wrap {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
}
.bj-side-chip-wrap-pp { margin-right: -1px; }
.bj-side-chip-wrap-tp { margin-left: -1px; }
.bj-side-chip {
  position: relative;
  height: 44px;
  display: inline-flex;
  align-items: center;
  background: var(--accent-15);
  border: 1px solid var(--accent-40);
  font-family: var(--font-display);
  font-weight: 800;
  color: var(--text-primary);
  flex-shrink: 0;
}
.bj-side-chip-pp {
  padding: 0 12px 0 22px;
  border-radius: 8px 0 0 8px;
  clip-path: polygon(12px 0, 100% 0, 100% 100%, 12px 100%, 0 50%);
}
.bj-side-chip-tp {
  padding: 0 22px 0 12px;
  border-radius: 0 8px 8px 0;
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 0 100%);
}
.bj-side-chip-text {
  display: inline-flex;
  flex-direction: column;
  line-height: 1.05;
  font-size: 11px;
  letter-spacing: .06em;
  text-align: left;
}
.bj-side-chip-text span + span { margin-top: 1px; }
.bj-side-chip-amount {
  position: absolute;
  top: calc(100% + 4px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--accent);
  color: var(--accent-contrast);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 11px;
  padding: 2px 10px;
  border-radius: 4px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .45);
  z-index: 3;
}

/* Hand wrap — column of total badge + card row. Player wraps appear
   in row 4, dealer in row 2; the total badge sits BELOW the cards on
   the dealer row (column-reverse) so it reads symmetrically. */
.bj-hand-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  z-index: 2;
  /* Reserve a card-shaped placeholder so the row pre-allocates space
     while the hand is empty. Once cards land, the wrap grows naturally
     in width but height stays bounded by the surrounding row track. */
  min-height: 116px;
}
.bj-hand-wrap.bj-hand-dealer { grid-row: 2; flex-direction: column-reverse; }
.bj-hand-wrap.bj-hand-player { grid-row: 4; }
/* Empty hand wrap — keep the card row's footprint reserved so the felt
   does not visibly grow when the first card lands during the deal. */
.bj-hand-wrap.is-empty .bj-hand { min-width: 84px; min-height: 116px; }
.bj-player-hands {
  grid-row: 4;
  display: flex;
  gap: 28px;
  align-items: flex-end;
  justify-content: center;
  flex-wrap: wrap;
  z-index: 2;
  width: 100%;
  min-height: 116px;
}
.bj-player-hands .bj-hand-wrap.bj-hand-player { grid-row: auto; }
.bj-player-hands.hands-2 .bj-hand .bj-card + .bj-card,
.bj-player-hands.hands-3 .bj-hand .bj-card + .bj-card,
.bj-player-hands.hands-4 .bj-hand .bj-card + .bj-card { margin-left: -42px; }

/* Active player hand — a soft white drop-shadow on the cards instead
   of the prior gold ring, so it reads as "you're acting on this hand"
   without competing with the gold-on-win outcome state. The yellow
   overlay the operator flagged is gone. */
.bj-hand-wrap.is-active .bj-hand {
  filter: drop-shadow(0 0 12px rgba(255, 255, 255, .18));
}
.bj-hand-wrap.is-active .bj-hand-total .bj-total-num {
  border-color: rgba(255, 255, 255, .55);
  background: rgba(255, 255, 255, .08);
  color: var(--text-primary);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .35), 0 0 10px rgba(255, 255, 255, .18);
}

/* Task #218 — split-hand emphasis. When the player has 2+ hands in
   play, the active hand brightens with a stronger glow and the
   inactive hand(s) fade back so the eye lands on the hand the
   action grid will affect. Transitions are short (140 ms) so the
   active swap feels instant after Hit / Stand / Bust on a sub-hand. */
.bj-player-hands.has-active .bj-hand-wrap {
  transition: opacity .14s ease, filter .14s ease, transform .14s ease;
}
.bj-player-hands.has-active .bj-hand-wrap.is-inactive-split {
  opacity: .42;
  filter: saturate(.7);
  transform: scale(.97);
}
.bj-player-hands.has-active .bj-hand-wrap.is-active .bj-hand {
  filter: drop-shadow(0 0 18px rgba(255, 255, 255, .35));
  transform: translateY(-2px);
}

/* Per-hand tag — small uppercase label above each split hand. The
   active tag swaps to the gold accent so the "▶ HAND N · ACTING"
   chip pops above the dimmed neighbour. Hidden in single-hand play
   (the wrapper component only renders it when hands.length > 1). */
.bj-hand-tag {
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  color: var(--text-mute);
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .55);
  border: 1px solid var(--border-default);
  white-space: nowrap;
}
.bj-hand-tag.is-active-tag {
  color: var(--accent-contrast);
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 0 12px var(--accent-40);
}

/* Hand-total compound pill — number on the left in a dark disc,
   optional WIN/LOSE/PUSH/BUST label appended on the right. Same
   component is used by both player and dealer rows. */
.bj-hand-total {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
}
.bj-hand-total .bj-total-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, .7);
  border: 1px solid var(--border-default);
  padding: 4px 14px;
  min-width: 36px;
  height: 24px;
  box-sizing: border-box;
  color: var(--text-primary);
  border-radius: 999px;
}
.bj-hand-total .bj-total-label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 12px;
  height: 24px;
  box-sizing: border-box;
  border-radius: 999px;
  letter-spacing: .1em;
}
.bj-total-win  .bj-total-num   { background: var(--accent); color: var(--accent-contrast); border-color: var(--accent); box-shadow: 0 0 14px var(--accent-40); }
.bj-total-win  .bj-total-label { background: var(--accent-deep); color: #fff; }
/* Distinct BLACKJACK label for a 2-card natural 21 — same brand gold
   palette as WIN with a slightly hotter glow + tighter letter spacing. */
.bj-total-blackjack .bj-total-num   { background: var(--accent); color: var(--accent-contrast); border-color: var(--accent); box-shadow: 0 0 18px var(--accent), 0 0 30px var(--accent-40); }
.bj-total-blackjack .bj-total-label { background: var(--accent-deep); color: #fff; letter-spacing: .14em; padding: 4px 14px; }
.bj-total-lose .bj-total-num   { background: var(--magenta); color: #fff; border-color: var(--magenta); box-shadow: 0 0 14px rgba(239, 68, 68, .45); }
.bj-total-lose .bj-total-label { background: #b91c1c; color: #fff; }
.bj-total-bust .bj-total-num   { background: var(--magenta); color: #fff; border-color: var(--magenta); box-shadow: 0 0 14px rgba(239, 68, 68, .45); }
.bj-total-bust .bj-total-label { background: #b91c1c; color: #fff; }
.bj-total-push .bj-total-num   { background: #fb923c; color: var(--accent-contrast); border-color: #fb923c; box-shadow: 0 0 14px rgba(251, 146, 60, .4); }
.bj-total-push .bj-total-label { background: #c2410c; color: #fff; }

/* Card row */
.bj-hand {
  display: flex;
  align-items: flex-end;
  gap: 0;
}
.bj-hand .bj-card + .bj-card { margin-left: -32px; }

/* Card outer = perspective container; .bj-card-flip is the rotating
   element that holds both faces. Outer keeps the drop shadow and any
   per-card outcome ring so it follows the rounded shape. */
.bj-card {
  width: 84px;
  height: 116px;
  position: relative;
  flex-shrink: 0;
  user-select: none;
  perspective: 900px;
  border-radius: 8px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
  transition: box-shadow .25s ease;
}
.bj-card-flip {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform .3s cubic-bezier(.4, 0, .2, 1);
}
.bj-card.is-face-down .bj-card-flip { transform: rotateY(180deg); }
.bj-card-face {
  position: absolute;
  inset: 0;
  border-radius: 8px;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  overflow: hidden;
}
.bj-card-face-front { background: #fff; }
.bj-card-face-front.red   { color: #dc2626; }
.bj-card-face-front.black { color: #0a0a0a; }
.bj-card-face-back {
  background: #0F0F14;
  border: 1.5px solid rgba(255, 255, 255, .55);
  transform: rotateY(180deg);
}
.bj-card-face-front .bj-card-corner {
  position: absolute;
  font-family: var(--font-display);
  font-weight: 800;
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
}
.bj-card-face-front .bj-card-corner.top-left { top: 8px; left: 9px; }
.bj-card-rank { font-size: 22px; letter-spacing: -.03em; }
.bj-card-suit { font-size: 18px; margin-top: -2px; }
.bj-card-suit-big {
  position: absolute;
  bottom: 14px;
  right: 12px;
  font-size: 32px;
  line-height: 1;
}
.bj-card-back-pattern {
  position: absolute;
  inset: 4px;
  border-radius: 5px;
  background:
    repeating-linear-gradient(45deg, #1f1f24 0 4px, #28282E 4px 8px),
    #0F0F14;
}
.bj-card-back-mark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 38px;
  height: 38px;
  object-fit: contain;
  border-radius: 6px;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .55));
}

/* Card flight — outer translates from deck position; inner flips back
   → front mid-flight so the card lands face-up. The face-down case
   (dealer hole) skips the flip. */
@keyframes bj-fly {
  0%   { opacity: 0; transform: translate(var(--fromX, 220px), var(--fromY, -180px)) rotate(15deg); }
  20%  { opacity: 1; }
  100% { opacity: 1; transform: translate(0, 0) rotate(0); }
}
.bj-card[style*="bj-fly"] .bj-card-flip {
  animation: bj-card-flip .5s cubic-bezier(.4, 0, .2, 1) backwards;
}
.bj-card.is-face-down[style*="bj-fly"] .bj-card-flip { animation: none; }
@keyframes bj-card-flip {
  0%, 55% { transform: rotateY(180deg); }
  100%    { transform: rotateY(0deg); }
}

@media (max-width: 768px) {
  /* Operator feedback — felt was rendering too small on mobile so the
     player could barely see the dealer/player rows. Bumping min-height
     to 480px gives the dealer + info pill + player hands proper room
     and keeps the deck stack from crowding the BJ 3:2 pill. Padding
     stays compact so the hands aren't pushed off-screen. The 122px
     dealer/player row tracks (card 90 + badge 24 + gap 8) keep the
     layout stable so the felt doesn't visibly grow during the deal. */
  .bj-board {
    min-height: 480px;
    padding: 18px 12px 22px;
    gap: 12px;
    grid-template-rows: 1fr 122px auto 122px 1fr;
  }
  .bj-hand-wrap { min-height: 90px; }
  .bj-hand-wrap.is-empty .bj-hand { min-width: 64px; min-height: 90px; }
  .bj-player-hands { min-height: 90px; }
  .bj-deck-slot { top: 12px; right: 12px; width: 44px; height: 58px; }
  .bj-deck-svg  { width: 44px; height: 58px; }
  .bj-deck-mark { width: 14px; height: 14px; }
  .bj-card { width: 64px; height: 90px; }
  .bj-hand .bj-card + .bj-card { margin-left: -22px; }
  .bj-card-rank { font-size: 18px; }
  .bj-card-suit { font-size: 14px; }
  .bj-card-suit-big { font-size: 24px; bottom: 10px; right: 9px; }
  .bj-card-corner.top-left { top: 6px; left: 7px; }
  .bj-card-back-mark { width: 26px; height: 26px; }
  .bj-info-pill { height: 32px; padding: 0 12px; font-size: 11px; letter-spacing: .03em; }
  .bj-pill-full  { display: none; }
  .bj-pill-short { display: inline; }
  .bj-side-chip { height: 32px; }
  .bj-side-chip-pp { padding: 0 8px 0 14px; clip-path: polygon(8px 0, 100% 0, 100% 100%, 8px 100%, 0 50%); }
  .bj-side-chip-tp { padding: 0 14px 0 8px; clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 0 100%); }
  .bj-side-chip-text { font-size: 9.5px; line-height: 1; }
  .bj-side-chip-amount { font-size: 10px; padding: 2px 7px; top: calc(100% + 3px); }
  /* Tighten the rules pill so it doesn't crowd the felt corner. */
  .bj-rules-toggle { top: 10px; left: 10px; padding: 6px 10px; font-size: 11px; }
}

/* Operator rebuild — result popup. Was a thin glow text floating
   in the felt; now sits on a soft backdrop pill so it reads
   regardless of what cards are behind it, with a stronger pop-in
   curve and a brand-tinted halo. Position unchanged. */
.bj-big {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  padding: 16px 36px;
  border-radius: var(--radius-pill);
  background: rgba(10, 10, 14, .8);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid currentColor;
  box-shadow:
    0 0 0 6px rgba(10, 10, 14, .4),
    0 0 80px currentColor,
    inset 0 1px 0 rgba(255, 255, 255, .06);
  font-family: var(--font-display);
  font-size: 38px;
  font-weight: 800;
  letter-spacing: .08em;
  text-shadow: 0 0 18px currentColor;
  z-index: 5;
  animation: bj-big-in 380ms cubic-bezier(.2, 0, 0, 1.4);
  pointer-events: none;
  white-space: nowrap;
}
/* Operator rebuild — banner colours use semantic tokens. Win/push
   share the brand gold band (push at 80% saturation so it reads
   different); lose uses semantic danger. */
.bj-big.win  { color: var(--color-success); }
.bj-big.push { color: var(--accent); }
.bj-big.lose { color: var(--color-danger); }
@keyframes bj-big-in {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.6); }
  60%  { opacity: 1; transform: translate(-50%, -50%) scale(1.1); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

/* Operator rebuild — Blackjack rules pill (top-left of felt) +
   center-of-screen overlay. */
.bj-rules-toggle {
  position: absolute;
  top: 18px;
  left: 22px;
  z-index: 3;
  appearance: none;
  border: 1px solid var(--border-default);
  background: var(--bg-2);
  color: var(--text-secondary);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: color var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard);
}
.bj-rules-toggle:hover {
  color: var(--accent);
  border-color: var(--accent-40);
  background: var(--accent-soft);
}
.bj-rules-overlay {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: grid;
  place-items: center;
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  animation: bj-rules-fade 200ms var(--ease-entrance);
}
@keyframes bj-rules-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.bj-rules-card {
  width: min(420px, calc(100% - 40px));
  max-height: calc(100% - 40px);
  overflow-y: auto;
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius);
  padding: 22px 24px 24px;
  box-shadow: var(--shadow-lg);
  animation: bj-rules-pop 280ms var(--ease-emphasized);
}
@keyframes bj-rules-pop {
  from { opacity: 0; transform: scale(.94); }
  to   { opacity: 1; transform: scale(1); }
}
.bj-rules-head {
  position: relative;
  margin-bottom: var(--space-5);
}
.bj-rules-eyebrow {
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: .15em;
  color: var(--text-tertiary);
  display: block;
  margin-bottom: 4px;
}
.bj-rules-title {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 800;
  color: var(--text-primary);
  margin: 0;
}
.bj-rules-close {
  position: absolute;
  top: -4px; right: -8px;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text-secondary);
  width: 28px; height: 28px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 22px;
  line-height: 1;
  display: grid;
  place-items: center;
  transition: color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard),
              transform var(--dur-fast) var(--ease-standard);
}
.bj-rules-close:hover {
  color: var(--accent);
  background: var(--accent-soft);
  transform: rotate(90deg);
}
.bj-rules-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.bj-rules-list li {
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-secondary);
  padding-left: 14px;
  position: relative;
}
.bj-rules-list li::before {
  content: '◆';
  position: absolute;
  left: 0;
  color: var(--accent);
  font-size: 9px;
  top: 5px;
}
.bj-rules-list li strong {
  color: var(--text-primary);
  font-weight: 700;
}
.bj-rules-list li em {
  color: var(--accent);
  font-style: normal;
  font-weight: 600;
}


/* Smaller card on phones to keep multi-hand splits visible */
@media (max-width: 520px) {
  .bj-card { width: 60px; height: 84px; padding: 6px 8px; font-size: 14px; }
  .bj-card-tl span { font-size: 11px; }
  .bj-card-br { font-size: 18px; }
  .bj-card-back { font-size: 22px; }
  .bj-cards { min-height: 84px; }
  .bj-card-slot { margin-left: -16px !important; }
  .bj-card-slot:first-child { margin-left: 0 !important; }
  .bj-big { font-size: 32px; }
  .bj-hands { gap: var(--space-5); }
  .bj-deck { width: 56px; height: 78px; top: 14px; right: 14px; }
  .bj-deck-card { width: 56px; height: 78px; }
  @keyframes bj-fly-in {
    from {
      transform: translate(120px, -90px) rotate(-12deg) scale(.7);
      opacity: 0;
    }
    60% { opacity: 1; }
    to {
      transform: translate(0, 0) rotate(0) scale(1);
      opacity: 1;
    }
  }
}

/* ============ GAME INFO popover (bottom action bar) ============ */
.gp-info-pop {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  width: 280px;
  background: var(--bg-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .7), 0 0 0 1px rgba(148,163,209,.10);
  z-index: 100;
  animation: modalIn .18s ease-out;
}
.gp-info-pop .gsp-head {
  padding: 10px 12px;
  border-bottom: 1px solid var(--line-soft);
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .12em;
  display: flex; justify-content: space-between; align-items: center;
  color: var(--accent);
}
.gp-info-pop .gsp-head button {
  background: transparent; border: 0; color: var(--text-mute); cursor: pointer;
  padding: 2px;
}
.gp-info-pop .gsp-body {
  padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-3);
}
.gp-info-row {
  display: flex; justify-content: space-between; align-items: center;
  font-family: var(--font-display);
  font-size: 11px;
  color: var(--text-dim);
  letter-spacing: .04em;
}
.gp-info-row em { color: var(--text); font-style: normal; font-weight: 700; }

/* ============ AUTO-PLAY panel + manual/auto tabs ============ */
/* Operator rebuild — pill segmented tabs (Degen/Stake reference).
   Both halves equal width, dark-grey track, slightly lighter
   pill-shaped active state with white text. No gold here — the
   gold is reserved for the Place Bet CTA below. */
.gp-mode-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  padding: 3px;
  background: var(--bg-3);
  border-radius: var(--radius-pill);
  margin-bottom: var(--space-2);
}
.gp-mode-tabs button {
  padding: 7px var(--space-4);
  background: transparent;
  border: 0;
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  border-radius: var(--radius-pill);
  transition: color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard);
}
.gp-mode-tabs button:hover:not(.on) {
  color: var(--text-primary);
}
.gp-mode-tabs button.on {
  background: var(--bg-elevated);
  color: var(--text-primary);
  box-shadow: 0 1px 0 rgba(255,255,255,.04) inset;
}
.gp-mode-tabs button:disabled {
  opacity: .4; cursor: not-allowed;
}
/* Operator rebuild — Auto panel densified so the whole flow
   (Number of bets → On Win → On Loss → Stop on profit/loss → CTA)
   fits without scrolling on a typical viewport. Tighter row gap,
   smaller pad on auto-adjust, controls drop to a single
   "Reset | Increase by N" pill row. Brand stays gold-only — the
   "on" state used to be blue (`--purple`); replaced with the dark
   elevated surface so the panel reads in a single calm palette. */
.auto-panel {
  display: flex; flex-direction: column; gap: var(--space-3);
  min-width: 0;
}
.auto-panel .gp-field {
  gap: var(--space-2);
}
.auto-panel .gp-row{ min-width: 0; gap: var(--space-3); }
/* Operator rebuild — 4-cell grid (Reset | Increase by | input | %).
   Earlier 3-col layout caused the input to overlay the "Increase by"
   button, clipping its label to "Incre…by". Each child now gets its
   own track. */
.auto-adjust {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr) auto;
  gap: var(--space-2); align-items: center;
  min-width: 0;
}
.auto-adjust button {
  padding: 8px 14px;
  background: var(--bg-elevated);
  border: 0;
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  border-radius: var(--radius-sm);
  min-width: 0;
  white-space: nowrap;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.auto-adjust button:hover { color: var(--text-primary); background: var(--bg-3); }
/* Customer feedback — match the Risk-chip "on" treatment (gold
   accent + dark contrast). Earlier this was white-on-near-black,
   which felt out-of-place next to the Risk row using the brand
   accent. Same vars `.gp-chips button.on` uses so a future palette
   tweak keeps the two surfaces in lockstep. */
.auto-adjust button.on {
  background: var(--accent);
  color: var(--accent-contrast);
}
.auto-adjust input {
  min-width: 0; width: 100%;
  padding: 8px 12px;
  background: var(--bg-3);
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: var(--font-display);
  font-size: 13px;
  text-align: right;
}
.auto-adjust input:focus { box-shadow: 0 0 0 2px var(--accent); outline: none; }
.auto-pct {
  color: var(--text-tertiary);
  font-family: var(--font-display);
  font-size: 13px;
  padding: 0 6px;
  white-space: nowrap;
}
@media (max-width: 480px) {
  /* Two rows on phones: [Reset | Increase by] over [input | %]. */
  .auto-adjust { grid-template-columns: 1fr 1fr auto; }
  .auto-adjust button:first-of-type { grid-column: 1; }
  .auto-adjust button:nth-of-type(2) { grid-column: 2 / span 2; }
  .auto-adjust input { grid-column: 1 / span 2; }
  .auto-adjust .auto-pct { grid-column: 3; }
}
.auto-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-2);
  padding: var(--space-4);
  background: rgba(0,0,0,.25);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  min-width: 0;
}
.auto-stats > div {
  display: flex; flex-direction: column; gap: 2px;
  font-family: var(--font-display);
  min-width: 0;
}
.auto-stats .v { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.auto-stats .k { font-size: 9px; letter-spacing: .1em; color: var(--text-mute); text-transform: uppercase; }
.auto-stats .v { font-size: 13px; color: var(--text); font-weight: 700; }

.gp-bet.danger {
  background: var(--magenta) !important;
  color: #fff !important;
}

/* ============ BLACKJACK bet panel (Degen-aligned rebuild) ============
   Tabs at the top (Standard / Side Bets), bet-amount input row, an
   optional side-bet input pair, then the 2x2 action grid (Hit/Stand/
   Split/Double), Mode dropdown, and the Place Bet primary CTA at
   the bottom. The yellow active-hand outline the operator flagged is
   gone — see .bj-hand-wrap.is-active above (white drop-shadow). */
.bj-bet-panel { gap: var(--space-3); }

/* Standard / Side Bets tabs — left tab "active" reads as a pressed
   button; the right tab carries a small "NEW" badge. */
.bj-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  background: var(--bg-3);
  padding: 4px;
  border-radius: 10px;
  position: relative;
}
.bj-tabs button {
  position: relative;
  height: 36px;
  border: 0;
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.bj-tabs button:hover:not(.active) { color: var(--text-primary); }
.bj-tabs button.active {
  background: var(--bg-elevated);
  color: var(--text-primary);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .04) inset;
}
.bj-new-badge {
  display: inline-block;
  background: var(--color-success);
  color: var(--accent-contrast);
  font-size: 8px;
  font-weight: 800;
  letter-spacing: .06em;
  padding: 2px 5px;
  border-radius: 3px;
  position: absolute;
  top: -8px;
  right: -8px;
}

/* 2x2 action grid — Hit / Stand / Split / Double. Uniform tile shape;
   only the icon hue differs to give each action a colour cue without
   making the row look like four different buttons. */
.bj-actions-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 4px;
}
.bj-action {
  height: 40px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: 8px;
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard),
              opacity var(--dur-base) var(--ease-standard);
}
.bj-action:hover:not(:disabled) {
  background: var(--bg-2);
  border-color: var(--accent-40);
}
.bj-action:disabled {
  color: var(--text-tertiary);
  cursor: not-allowed;
  opacity: .55;
}
.bj-action.act-hit    svg { color: var(--color-success); }
.bj-action.act-stand  svg { color: var(--magenta); }
.bj-action.act-split  svg { color: var(--cyan); }
.bj-action.act-double svg { color: var(--accent); }
.bj-action:disabled svg { opacity: .55; }

/* Task #192 — insurance side bet prompt. Renders ABOVE the action
   grid when the dealer's upcard is an Ace and auto-declines after
   10 s. Two CTA columns (Accept w/ countdown + Decline) reuse the
   .bj-action shell so spacing/typography match the action grid. */
.bj-insurance-prompt {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  margin-top: 4px;
  border: 1px solid var(--accent-40, var(--border-default));
  background: var(--bg-elevated);
  border-radius: 10px;
  box-shadow: 0 0 0 1px rgba(255, 196, 71, 0.18) inset;
}
.bj-insurance-text {
  font-family: var(--font-ui);
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--text-secondary);
}
.bj-insurance-text strong { color: var(--text-primary); }
.bj-insurance-stake {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--text-secondary);
}
.bj-insurance-stake label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.bj-insurance-stake input {
  width: 90px;
  height: 28px;
  padding: 0 8px;
  background: var(--bg-3);
  border: 1px solid var(--border-default);
  border-radius: 6px;
  color: var(--text-primary);
  font-family: var(--font-display);
  font-size: 12px;
}
.bj-insurance-stake input:focus {
  outline: none;
  border-color: var(--accent-40);
}
.bj-insurance-stake .mini {
  height: 24px;
  padding: 0 8px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: 6px;
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
}
.bj-insurance-stake .mini:hover:not(:disabled) {
  background: var(--bg-2);
  border-color: var(--accent-40);
  color: var(--text-primary);
}
.bj-insurance-stake .mini:disabled {
  opacity: .55;
  cursor: not-allowed;
}
.bj-insurance-cap {
  font-size: 11px;
  color: var(--magenta);
}
.bj-insurance-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

/* Themed mode dropdown — Classic / Switch / Double Down. */
.bj-mode-select {
  background: var(--bg-3);
  border: 1px solid var(--border-default);
  border-radius: 8px;
}

/* Primary CTA — Place Bet. Brand gold pill, full-width. */
.bj-place {
  margin-top: var(--space-2);
  font-family: var(--font-ui);
  font-weight: 700;
  letter-spacing: .02em;
}

.bj-err {
  text-align: center;
  font-family: var(--font-display);
  font-size: 12px;
  color: var(--magenta);
  margin-top: var(--space-2);
}

/* Task #167 — per-game inline bet-error line. Mirrors the previous
   inline-styled magenta caption every game panel rendered (centered,
   monospaced, 12px, magenta). The optional .gp-err-retry button slots
   underneath the message when the api-client's auto-replay couldn't
   ride out a >0.5% FX move during the ~200ms RATE_STALE / RATE_MISMATCH
   retry window — clicking it re-runs the failing bet against the
   freshly-loaded rates without a page reload. */
.gp-err-line {
  text-align: center;
  font-family: var(--font-display);
  font-size: 12px;
  color: var(--magenta);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.gp-err-line .gp-err-msg {
  display: inline-block;
}
.gp-err-retry {
  background: rgba(52, 192, 235, .12);
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
  border-radius: 999px;
  padding: 4px 12px;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .12s ease, transform .12s ease;
}
.gp-err-retry:hover {
  background: rgba(52, 192, 235, .22);
}
.gp-err-retry:active {
  transform: translateY(1px);
}
/* Re-shape `.bj-err` so the optional retry button stacks cleanly under
   the message (BJ uses its own class so it keeps the existing
   margin-top spacing inside the bet panel). */
.bj-err {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

/* Result card — replaces the felt overlay banner. Outcome chip + big
   payout + multiplier on a single compact card; tone-coloured left
   rail makes the win/lose/push state legible at a glance. Operator
   feedback — sized down so the card sits cleanly inside the bet
   panel rather than dominating it. */
.bj-result-card {
  margin-top: var(--space-2);
  padding: 6px 10px 7px;
  border-radius: 8px;
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--bg-2) 92%, #fff 8%) 0%,
      var(--bg-1) 100%);
  border: 1px solid var(--border-default);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .03) inset,
    0 6px 14px -12px rgba(0, 0, 0, .5);
  display: flex;
  flex-direction: column;
  gap: 2px;
  position: relative;
  overflow: hidden;
  animation: bj-result-pop .22s cubic-bezier(.2, 0, 0, 1.15) both;
}
.bj-result-card::before {
  content: '';
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 2px;
  background: var(--accent);
  opacity: .85;
}
.bj-result-win   { border-color: color-mix(in srgb, var(--accent) 38%, transparent); }
.bj-result-win::before  { background: var(--accent); }
.bj-result-lose  { border-color: color-mix(in srgb, var(--magenta) 38%, transparent); }
.bj-result-lose::before { background: var(--magenta); }
.bj-result-push  { border-color: color-mix(in srgb, #fb923c 38%, transparent); }
.bj-result-push::before { background: #fb923c; }

@keyframes bj-result-pop {
  from { opacity: 0; transform: translateY(4px) scale(.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.bj-result-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}
.bj-result-chip {
  display: inline-flex;
  align-items: center;
  height: 15px;
  padding: 0 6px;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .1em;
}
.bj-result-chip-win  { background: var(--green); color: var(--accent-contrast); box-shadow: 0 0 8px rgba(94,201,143,.4); }
.bj-result-chip-lose { background: var(--magenta); color: #fff; }
.bj-result-chip-push { background: #fb923c; color: var(--accent-contrast); }
.bj-result-mult {
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  color: var(--text-secondary);
  letter-spacing: .02em;
}
.bj-result-payout {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 800;
  letter-spacing: -.005em;
  line-height: 1.1;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.bj-result-win  .bj-result-payout { color: var(--accent); text-shadow: 0 0 14px var(--accent-25); }
.bj-result-lose .bj-result-payout { color: var(--magenta); }
.bj-result-side {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 2px;
}
.bj-result-side-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 10.5px;
  letter-spacing: .04em;
  background: var(--bg-3);
  border: 1px solid var(--border-default);
  color: var(--text-tertiary);
}
.bj-result-side-pill .k {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: .06em;
  color: var(--text-secondary);
}
.bj-result-side-pill.is-hit {
  background: var(--accent-15);
  border-color: var(--accent-40);
  color: var(--text-primary);
}
.bj-result-side-pill.is-hit .k { color: var(--accent); }

/* Legacy alias — old .bj-action-btn rules used to style the action
   grid via the previous markup. The new JSX uses .bj-action, but we
   keep this alias so any cached HTML still renders. */
.bj-action-btn { all: unset; }

/* Game meta strip: desktop shows full rows, mobile collapses to single info line */
.game-meta-strip {
  display: none;   /* hidden on desktop — full RTP/Min/Max rows show instead */
}

/* ---------- BALANCE DROPDOWN (v2) ---------- */
.bd-row{
  display: grid; grid-template-columns: 30px 1fr auto; align-items: center;
  gap: var(--space-4); padding: 10px 10px; border-radius: var(--radius-md);
  appearance: none; background: transparent; border: 0; cursor: pointer;
  color: var(--text); text-align: left;
}
/* Crypto name flush-LEFT (right after the icon), amount flush-RIGHT in a
   tabular column — so names and amounts line up at the two edges instead
   of floating with a ragged gap in the middle (operator request). */
.bd-meta{ display: flex; flex-direction: column; gap: 2px; min-width: 0; align-items: flex-start; justify-self: start; }
.bd-sym{ font-family: var(--font-display); font-weight: 700; font-size: 12px; letter-spacing: .04em; text-align: left; }
.bd-name{ font-size: 11px; color: var(--text-mute); text-align: left; }
.bd-usd{ font-family: var(--font-display); font-size: 13px; color: var(--text); font-weight: 700; text-align: right; justify-self: end; font-variant-numeric: tabular-nums; }
.bd-actions{
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3);
  padding: 10px 4px 2px;
  border-top: 1px solid var(--line-soft); margin-top: 6px;
}
.bd-btn{
  appearance: none; border: 0; cursor: pointer;
  background: var(--accent); color: var(--accent-ink);
  font-family: var(--font-display); font-weight: 800; font-size: 12px; letter-spacing: .06em;
  padding: 10px 12px; border-radius: var(--radius-sm);
  transition: .15s;
}
.bd-btn:hover{ transform: translateY(-1px); }
.bd-btn.ghost{ background: transparent; color: var(--text); border: 1px solid var(--line-soft); }
.bd-btn.ghost:hover{ border-color: var(--purple); color: var(--purple); }

/* ---------- NOTIFICATIONS ----------------------------------------
   Operator brief: redesign to match the customer's reference
   screenshot. Clean Inter / system-ui sans-serif throughout — NO
   mono font, NO uppercase letter-spacing, NO purple accent on the
   "Mark all as read" link. Tighter row spacing, subtle line-art
   SVG icons (no chunky filled badges), single blue dot for unread.
   ----------------------------------------------------------------- */
.notif-wrap{ position: relative; display: inline-flex; }
.notif-dropdown{
  position: absolute; top: calc(100% + 10px); right: 0;
  width: 380px;
  background: #14171c;
  border: 1px solid rgba(255,255,255,.06);
  border-radius: 14px;
  box-shadow: 0 24px 80px rgba(0,0,0,.7), 0 0 0 1px rgba(148,163,209,.06);
  padding: 0; z-index: 200;
  animation: modalIn .18s ease-out;
  overflow: hidden;
  font-family: var(--font-ui);
  /* Disable the global :root letter-spacing some skins ship — the
     reference screenshot uses tight default tracking. */
  letter-spacing: 0;
}
.nd-head{
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 20px 14px;
}
.nd-title{
  margin: 0;
  font-family: var(--font-ui);
  font-size: 17px;
  font-weight: 700;
  color: #f5f6f8;
  letter-spacing: -0.01em;
}
.nd-mark{
  appearance: none; background: transparent; border: 0; cursor: pointer;
  color: #8b929c;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0;
  padding: 0;
}
.nd-mark:hover{ color: #cfd3da; }
.nd-list{
  max-height: 480px;
  overflow-y: auto;
  padding-bottom: 6px;
}
.nd-empty{
  text-align: center;
  padding: 36px 20px;
  color: #6f7682;
  font-family: var(--font-ui);
  font-size: 13px;
  letter-spacing: 0;
}
/* Each row is a 3-column grid: icon | body (auto-fill) | (time + dot
   stacked, anchored top-right). Padding keeps rows breathable
   without the over-spaced vibe the previous mono-font version had. */
.nd-item{
  display: grid;
  grid-template-columns: 28px 1fr auto;
  align-items: start;
  gap: 14px;
  padding: 14px 20px;
  border-top: 1px solid rgba(255,255,255,.04);
  transition: background .14s ease;
  cursor: pointer;
  font-family: var(--font-ui);
  letter-spacing: 0;
}
.nd-item:first-of-type{ border-top: 1px solid rgba(255,255,255,.06); }
.nd-item:hover{ background: rgba(255,255,255,.02); }
.nd-item.is-static{ cursor: default; }
.nd-item.is-static:hover{ background: transparent; }
/* Icon: outline glyph, muted colour, no chunky pill background. */
.nd-icon{
  width: 28px; height: 28px;
  display: grid; place-items: center;
  color: #c8ccd2;
  flex-shrink: 0;
}
.nd-body{ min-width: 0; }
.nd-t{
  color: #ebedf0;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.25;
}
.nd-sub{
  color: #8b929c;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0;
  margin-top: 4px;
  word-wrap: break-word;
}
/* Right-column meta: time + unread dot, inline at the top of the
   row. Matches the reference screenshot where "9 hours ago" sits
   on the same baseline as the title with a small blue dot to its
   right edge for unread notifications. */
.nd-meta{
  display: flex;
  align-items: center;
  gap: 8px;
  align-self: start;
  margin-top: 1px; /* tiny shim so the time tracks the title baseline */
  white-space: nowrap;
}
.nd-time{
  color: #6f7682;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  flex-shrink: 0;
}
.nd-dot{
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #5b8cff;
  flex-shrink: 0;
}
/* Hide the dot on read rows but keep the time visible. */
.nd-item:not(.unread) .nd-dot{ display: none; }
/* Decline button — matches the screenshot's pill-style affordance.
   Sits below the row body so click events don't tangle with the
   parent row's clickable area. */
.nd-decline{
  appearance: none;
  margin-top: 10px;
  padding: 6px 16px;
  background: rgba(118,108,182,.18);
  color: #b6acff;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0;
  transition: background .14s ease;
}
.nd-decline:hover{ background: rgba(118,108,182,.28); }
.nd-decline:focus-visible{
  outline: 2px solid rgba(150,140,220,.55);
  outline-offset: 2px;
}

/* ---------- GAME PAGE BACK-ROW (shared) ---------- */
.gp-back-row{
  display: flex; align-items: center; gap: var(--space-6); margin-bottom: 22px;
  font-family: var(--font-display); font-size: 11px; letter-spacing: .15em;
  flex-wrap: wrap;
}
.gp-back{
  appearance: none; cursor: pointer; border: 1px solid var(--line-soft);
  background: transparent; color: var(--text);
  padding: 8px 12px; border-radius: var(--radius-sm);
  font-family: var(--font-display); font-size: 11px; letter-spacing: .1em;
  display: inline-flex; align-items: center; gap: var(--space-2);
  transition: .15s;
}
.gp-back:hover{ border-color: rgba(52,192,235,.5); color: var(--accent); }
.gp-crumb{ color: var(--text); display: inline-flex; align-items: center; gap: var(--space-1); }
.gp-quickstats{
  display: inline-flex; gap: var(--space-7);
  font-family: var(--font-display); font-size: 11px;
}
.gp-quickstats em{ font-style: normal; color: var(--text-mute); letter-spacing: .08em; }
.gp-quickstats strong{ color: var(--accent); font-weight: 700; }

/* ---------- GAME PAGE BOTTOM BAR (shuffle-style) ---------- */
.gp-bottombar{
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center;
  padding: 12px 18px;
  border-top: 1px solid var(--line-soft);
  background: linear-gradient(180deg, rgba(255,255,255,.01), rgba(255,255,255,.025));
  gap: var(--space-7);
}
.gp-bb-left, .gp-bb-right{ display: inline-flex; gap: var(--space-2); align-items: center; }
.gp-bb-icon{
  appearance: none; cursor: pointer;
  width: 36px; height: 36px; border-radius: var(--radius-sm);
  display: grid; place-items: center;
  border: 1px solid var(--line-soft);
  background: transparent;
  color: var(--text-dim);
  transition: .15s;
}
.gp-bb-icon:hover{ color: var(--text); border-color: var(--purple); background: var(--white-04); }
.gp-bb-icon.on{ color: var(--gold); border-color: rgba(255,188,74,.45); background: rgba(255,188,74,.08); }
.gp-bb-center{
  display: inline-flex; align-items: center; gap: var(--space-4);
  justify-self: center;
  font-family: var(--font-display); font-size: 10px; letter-spacing: .18em;
  color: var(--text-mute);
}
.gp-bb-brand{ color: var(--accent); font-family: var(--font-display); font-size: 14px; letter-spacing: .12em; }
.gp-bb-slug{ padding: 2px 8px; border: 1px solid var(--line-soft); border-radius: var(--radius-xs); }
.gp-bb-pf{
  appearance: none; cursor: pointer;
  display: inline-flex; gap: var(--space-3); align-items: center;
  padding: 8px 12px; border-radius: var(--radius-sm);
  background: transparent; border: 1px solid var(--line-soft);
  color: var(--text); font-family: var(--font-display); font-size: 11px; letter-spacing: .1em;
  transition: .15s;
}
.gp-bb-pf:hover{ border-color: var(--accent); color: var(--accent); }

/* ---------- GAME SETTINGS POP-OVER ---------- */
.gp-settings-pop{
  position: absolute; left: 12px; bottom: 68px;
  width: 320px;
  background: var(--bg-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  box-shadow: 0 24px 80px rgba(0,0,0,.7);
  z-index: 30;
  overflow: hidden;
  animation: modalIn .18s ease-out;
}
.gsp-head{
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line-soft);
  font-family: var(--font-display); font-size: 11px; letter-spacing: .15em;
  color: var(--text);
}
.gsp-head button{
  appearance: none; background: transparent; border: 0; cursor: pointer;
  color: var(--text-mute); display: grid; place-items: center; padding: var(--space-1);
}
.gsp-body{ padding: 4px 8px; }
.gsp-row{
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px;
  gap: var(--space-5);
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.gsp-row:hover{ background: rgba(255,255,255,.03); }
.gsp-text{ display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.gsp-label{ font-size: 13px; font-weight: 600; }
.gsp-sub{ font-size: 11px; color: var(--text-mute); line-height: 1.3; }
.gsp-sw{ position: relative; width: 36px; height: 20px; flex-shrink: 0; }
.gsp-sw input{ display: none; }
.gsp-sw > span{
  position: absolute; inset: 0;
  background: rgba(255,255,255,.08);
  border-radius: var(--radius);
  transition: .2s;
}
.gsp-sw > span::before{
  content:""; position: absolute; left: 2px; top: 2px;
  width: 16px; height: 16px;
  background: #fff; border-radius: 50%;
  transition: .2s;
}
.gsp-sw input:checked + span{ background: var(--purple); }
.gsp-sw input:checked + span::before{ transform: translateX(16px); }
.gsp-foot{
  padding: 10px 16px;
  border-top: 1px solid var(--line-soft);
}
.gsp-reset{
  appearance: none; background: transparent; border: 0; cursor: pointer;
  color: var(--text-mute); font-family: var(--font-display); font-size: 11px;
  letter-spacing: .1em;
}
.gsp-reset:hover{ color: var(--text); }

/* ---------- LIVE STATS MOVABLE WIDGET ---------- */
.lsw{
  position: fixed;
  background: var(--bg-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  box-shadow: 0 24px 60px rgba(0,0,0,.7), 0 0 0 1px rgba(148,163,209,.10);
  z-index: 150;
  overflow: hidden;
  user-select: none;
  display: flex; flex-direction: column;
  min-width: 260px; min-height: 220px;
}
.lsw-resize{ position: absolute; z-index: 2; }
.lsw-resize.n{ top:0; left:10px; right:10px; height:6px; cursor:n-resize; }
.lsw-resize.s{ bottom:0; left:10px; right:10px; height:6px; cursor:s-resize; }
.lsw-resize.e{ top:10px; bottom:10px; right:0; width:6px; cursor:e-resize; }
.lsw-resize.w{ top:10px; bottom:10px; left:0; width:6px; cursor:w-resize; }
.lsw-resize.ne{ top:0; right:0; width:14px; height:14px; cursor:ne-resize; }
.lsw-resize.nw{ top:0; left:0; width:14px; height:14px; cursor:nw-resize; }
.lsw-resize.sw{ bottom:0; left:0; width:14px; height:14px; cursor:sw-resize; }
.lsw-resize.se{
  bottom:0; right:0; width:16px; height:16px; cursor:se-resize;
  display:grid; place-items:center; color: var(--text-mute);
  opacity:.5;
}
.lsw-resize.se:hover{ opacity:1; color: var(--purple); }

.lsw-head{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3);
  padding: 14px 16px 12px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--white-02);
  cursor: move;
  position: relative;
}
/* Migration 027 follow-up: title now reads as a kicker (mono +
   uppercase + amber accent rule) so it sits cleanly inside the chrome
   instead of competing with the close button for visual weight. */
.lsw-title{
  font-family: var(--font-display);
  font-size: 11px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text);
  position: relative; padding-left: 14px;
  flex: 1; min-width: 0;
}
.lsw-title::before{
  content: ""; position: absolute; left: 0; top: 50%;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent-glow);
  transform: translateY(-50%);
}
.lsw-min, .lsw-close{
  appearance: none; background: transparent; border: 0; cursor: pointer;
  color: var(--text-mute); padding: var(--space-2); display: grid; place-items: center;
  border-radius: var(--radius-xs);
  flex-shrink: 0;
  transition: background var(--t-fast), color var(--t-fast);
}
.lsw-min:hover, .lsw-close:hover{ color: var(--text); background: var(--white-06); }

/* Filter dropdown row */
.lsw-filter-row{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); margin-bottom: 12px;
}
.lsw-filter{ position: relative; }
.lsw-filter-btn{
  appearance: none; cursor: pointer;
  padding: 6px 12px;
  background: var(--white-04);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-xs);
  color: var(--text);
  font-family: var(--font-ui); font-size: 12px; font-weight: 600;
  display: inline-flex; align-items: center; gap: var(--space-2);
}
.lsw-filter-btn:hover{ background: rgba(255,255,255,.07); }
.lsw-caret{ font-size: 9px; opacity:.7; }
.lsw-filter-menu{
  position: absolute; top: 100%; left: 0; margin-top: 4px;
  background: var(--panel); border: 1px solid var(--line-soft);
  border-radius: var(--radius-xs);
  min-width: 100px; z-index: 5;
  box-shadow: 0 8px 24px rgba(0,0,0,.4);
}
.lsw-filter-item{
  display: block; width: 100%; text-align: left;
  appearance: none; background: transparent; border: 0; cursor: pointer;
  padding: 8px 12px; color: var(--text-dim);
  font-family: var(--font-ui); font-size: 12px;
}
.lsw-filter-item:hover{ background: var(--white-04); color: var(--text); }
.lsw-filter-item.on{ color: var(--accent); }
.lsw-reset{
  appearance: none; background: var(--white-04); cursor: pointer;
  border: 1px solid var(--line-soft); border-radius: var(--radius-xs);
  padding: var(--space-2); color: var(--text-mute);
  display: grid; place-items: center;
}
.lsw-reset:hover{ color: var(--text); background: rgba(255,255,255,.08); }

/* 2x2 stat grid (Profit/Wins/Wagered/Losses) */
.lsw-statgrid{
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3);
  margin-bottom: 12px;
}
.lsw-stat{
  padding: 10px 12px;
  background: rgba(255,255,255,.025);
  border: 1px solid var(--white-04);
  border-radius: var(--radius-sm);
  display: flex; flex-direction: column; gap: var(--space-1);
  min-width: 0;
}
.lsw-stat-k{
  font-family: var(--font-ui); font-size: 11px; color: var(--text-mute);
}
.lsw-stat-v{
  font-family: var(--font-display); font-size: 16px; font-weight: 700;
  color: var(--text);
  display: inline-flex; align-items: center; gap: var(--space-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lsw-coin{ font-variant-numeric: tabular-nums; }
.lsw-coin-icon{
  display: inline-grid; place-items: center;
  width: 16px; height: 16px; border-radius: 50%;
  background: linear-gradient(135deg, #f7931a, #c97e1a);
  color: #fff; font-size: 9px;
}

/* Race accordion */
.lsw-race{
  margin-top: 12px;
  background: var(--white-02);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.lsw-race-head{
  appearance: none; cursor: pointer;
  width: 100%; padding: 10px 14px;
  background: transparent; border: 0;
  display: flex; align-items: center; justify-content: space-between;
  font-family: var(--font-display); font-size: 13px; font-weight: 700;
  color: var(--text);
}
.lsw-race-head:hover{ background: rgba(255,255,255,.03); }
.lsw-race-title{ display:inline-flex; align-items:center; gap:var(--space-2); }
.lsw-race-body{
  padding: var(--space-6);
  border-top: 1px solid var(--line-soft);
}
.lsw-race-cta{
  text-align: center;
  padding: var(--space-3);
  font-family: var(--font-ui); font-size: 12px;
  color: var(--text-mute);
}
/* Empty-state race head — slightly dimmer to signal "nothing live". */
.lsw-race.empty .lsw-race-head { color: var(--text-mute); }
/* Rank pill on the collapsed head — shows the player's position
   ("#42 · $1.2K") inline so they don't have to expand the panel. */
.lsw-race-rank-pill {
  margin-left: auto;
  margin-right: var(--space-2);
  padding: 2px var(--space-3);
  background: var(--accent-15);
  color: var(--accent);
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-size: var(--text-2xs);
  font-weight: 700;
  letter-spacing: .04em;
  white-space: nowrap;
}
/* Viewer rank tile inside the expanded body. Big number = the player's
   current position, small line = their wagered + total participant count. */
.lsw-race-viewer {
  display: flex; flex-direction: column; align-items: center;
  gap: 2px;
  padding: var(--space-5) var(--space-3);
  background: linear-gradient(180deg, var(--accent-10), transparent);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-5);
}
.lsw-race-viewer-k {
  font-family: var(--font-display); font-size: var(--text-2xs);
  letter-spacing: .14em; color: var(--text-mute);
}
.lsw-race-viewer-rank {
  font-family: var(--font-display); font-size: 28px;
  color: var(--accent); line-height: 1;
  font-variant-numeric: tabular-nums;
}
.lsw-race-viewer-meta {
  font-family: var(--font-display); font-size: var(--text-xs);
  color: var(--text-dim);
}
/* Top-3 podium preview — three compact rows, gold/silver/bronze color
   accent on rank #1/#2/#3. The "me" class adds a subtle amber halo so
   the player can spot their row when they're in the top 3. */
.lsw-race-podium-k {
  font-family: var(--font-display); font-size: var(--text-2xs);
  letter-spacing: .14em; color: var(--text-mute);
  margin: var(--space-2) 0 var(--space-2);
}
.lsw-race-podium {
  display: flex; flex-direction: column; gap: 2px;
}
.lsw-race-podium-row {
  display: grid; grid-template-columns: 36px 1fr auto; align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--white-02);
  font-family: var(--font-display); font-size: var(--text-xs);
}
.lsw-race-podium-row.top1 { background: linear-gradient(90deg, var(--accent-15), transparent); }
.lsw-race-podium-row.top2 { background: linear-gradient(90deg, rgba(205,210,220,.15), transparent); }
.lsw-race-podium-row.top3 { background: linear-gradient(90deg, rgba(168,129,30,.15), transparent); }
.lsw-race-podium-row.me   { box-shadow: 0 0 0 1px var(--accent-25); }
.lsw-race-pos { color: var(--text-mute); font-weight: 700; }
.lsw-race-user { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lsw-race-amt { color: var(--accent); font-weight: 700; }
.lsw-body{ padding: var(--space-6); overflow-y: auto; flex: 1; min-height: 0; }
.lsw-big{
  display: flex; flex-direction: column; gap: var(--space-1);
  padding: 12px 14px;
  background: var(--white-04);
  border: 1px solid rgba(61, 126, 255,.2);
  border-radius: var(--radius-md);
  margin-bottom: 12px;
}
.lsw-big .k{ font-family: var(--font-display); font-size: 10px; letter-spacing: .15em; color: var(--text-mute); }
.lsw-big .v{ font-family: var(--font-display); font-size: 24px; }
.lsw-grid{
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3);
  margin-bottom: 12px;
}
.lsw-grid > div{
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 10px;
  background: var(--white-02);
  border-radius: var(--radius-sm);
}
.lsw-grid .k{ font-family: var(--font-display); font-size: 9px; letter-spacing: .14em; color: var(--text-mute); text-transform: uppercase; }
.lsw-grid .v{ font-family: var(--font-display); font-size: 13px; font-weight: 700; color: var(--text); }
.lsw-sub{
  font-family: var(--font-display); font-size: 10px; letter-spacing: .15em;
  color: var(--text-mute); margin-bottom: 6px;
}
.lsw-hist-row{ display: flex; flex-wrap: wrap; gap: var(--space-1); max-height: 72px; overflow: hidden; }
.lsw-pill{
  font-family: var(--font-display); font-size: 10px; font-weight: 700;
  padding: 3px 6px; border-radius: var(--radius-xs);
}
.lsw-pill.big{ background: var(--accent-25); color: var(--purple); }
.lsw-pill.ok{  background: rgba(94,201,143,.12); color: var(--green); }
.lsw-pill.bad{ background: rgba(255,59,107,.12); color: var(--magenta); }
.lsw-dim{ color: var(--text-mute); font-family: var(--font-display); font-size: 11px; }

/* ---------- BETS FEED ---------- */
.bets-feed{
  margin-top: 28px;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
}
.bf-head{
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px;
  border-bottom: 1px solid var(--line-soft);
  flex-wrap: wrap; gap: var(--space-5);
}
.bf-head h3{
  margin: 0;
  font-family: var(--font-display); font-size: 12px; letter-spacing: .18em;
  color: var(--text);
}
.bf-tabs{
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--white-02);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
}
.bf-tabs button{
  appearance: none; background: transparent; border: 0; cursor: pointer;
  padding: 7px 12px;
  font-family: var(--font-ui); font-weight: 600; font-size: 12px;
  color: var(--text-dim);
  border-radius: var(--radius-sm);
  transition: .15s;
}
.bf-tabs button:hover{ color: var(--text); }
.bf-tabs button.on{ background: var(--bg-2); color: var(--text); box-shadow: 0 1px 0 var(--white-04); }

.bf-table{ padding: 4px 8px 10px; }
.bf-row{
  display: grid;
  grid-template-columns: 2fr 1.2fr 60px 100px 80px 110px;
  gap: var(--space-6); align-items: center;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  font-family: var(--font-display); font-size: 12px;
  animation: bfIn .25s ease-out;
}
@keyframes bfIn{
  from{ opacity: 0; transform: translateY(-4px); }
  to{ opacity: 1; transform: none; }
}
.bf-head-row{
  color: var(--text-mute); font-size: 10px; letter-spacing: .15em;
  padding: 8px 14px;
  animation: none;
}
.bf-body{ max-height: 460px; overflow-y: auto; }
.bf-row:not(.bf-head-row):hover{ background: rgba(255,255,255,.025); }
.bf-row .game{ display: inline-flex; align-items: center; gap: var(--space-3); color: var(--text); }
.bf-row .g-dot{ width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.bf-row .user{ color: var(--text-dim); font-family: var(--font-ui); font-weight: 600; }
.bf-row .user em{ color: var(--purple); font-style: normal; font-weight: 700; }
.bf-row .num{ text-align: right; }
.bf-row .mult.big{ color: var(--purple); font-weight: 700; }
.bf-row .mult.ok{ color: var(--text); }
.bf-row .mult.bad{ color: var(--text-mute); }
.bf-row .payout.win{ color: var(--accent); }
.bf-row .payout.lose{ color: var(--magenta); }
.bf-empty{
  padding: 40px 20px; text-align: center;
  color: var(--text-mute); font-family: var(--font-display); font-size: 12px; letter-spacing: .1em;
}

/* Responsive bets feed */
@media (max-width: 900px){
  .bf-row{ grid-template-columns: 1.6fr 1fr 50px 90px; gap: var(--space-4); font-size: 11px; }
  .bf-row .bet, .bf-row .t{ display: none; }
  .bf-head-row span:nth-child(3),
  .bf-head-row span:nth-child(4){ display: none; }
}
@media (max-width: 520px){
  .bf-row{ grid-template-columns: 1.2fr 1fr 80px; gap: var(--space-3); padding: 8px 10px; }
  .bf-row .mult{ display: none; }
  .bf-head-row span:nth-child(5){ display: none; }
}

/* ---------- VIP PAGE ---------- */
.vip-page{ padding-bottom: 60px; }
.vip-hero{
  padding: 28px 0 24px;
  border-bottom: 1px dashed var(--line-soft);
  margin-bottom: 32px;
}
.vh-eyebrow{
  display: inline-flex; align-items: center; gap: var(--space-3);
  font-family: var(--font-display); font-size: 11px; letter-spacing: .18em;
  color: var(--purple);
  margin-bottom: 14px;
}
.vh-eyebrow .pulse{
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--purple);
  box-shadow: 0 0 12px var(--purple);
  animation: pulsator 1.6s ease-in-out infinite;
}
.vh-title{
  font-family: var(--font-display); font-size: clamp(38px, 5.4vw, 68px); line-height: 1.05;
  margin: 0 0 10px;
  letter-spacing: -.01em;
  max-width: 14ch;
}
/* Phase 29.9 — was 'Caveat' / 'Patrick Hand' (the only hardcoded font
   in the system); now uses the canonical display var so the design
   system is single-sourced. The handwritten flair was customer-flagged
   as off-brand vs the rest of the type system. */
.vh-hand{
  font-family: var(--font-display);
  font-weight: 700;
  font-style: italic;
  font-size: clamp(20px, 2vw, 26px);
  color: var(--purple);
  letter-spacing: -.01em;
  transform: rotate(-1.5deg);
  display: inline-block;
  margin: 0 0 18px 6px;
}
.g-glow{ color: var(--purple); text-shadow: 0 0 24px rgba(61, 126, 255,.5); }
.vh-sub{
  max-width: 620px; color: var(--text-dim); font-size: 15px; line-height: 1.55;
  text-wrap: pretty;
}

.vip-tier-rail{
  display: grid; grid-template-columns: repeat(7, 1fr);
  gap: var(--space-4);
  margin-bottom: 36px;
  position: relative;
}
.vip-tier-rail::before{
  content:""; position: absolute; left: 0; right: 0; top: 50%;
  height: 1px;
  background: repeating-linear-gradient(90deg, var(--line-soft) 0 4px, transparent 4px 10px);
  z-index: 0;
}
.vtr-tile{
  position: relative; z-index: 1;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  padding: 18px 10px;
  display: flex; flex-direction: column; gap: var(--space-2); align-items: center;
  text-align: center;
  --c: 10px;
  clip-path: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%, 0 var(--c));
  opacity: .7;
}
.vtr-tile.you{
  opacity: 1;
  border-color: var(--tier);
  box-shadow: 0 0 24px color-mix(in oklch, var(--tier) 40%, transparent);
  background: linear-gradient(180deg, color-mix(in oklch, var(--tier) 12%, var(--panel)) 0%, var(--panel) 100%);
}
.vtr-emblem{ font-family: var(--font-display); font-size: 22px; color: var(--tier); }
.vtr-name{ font-family: var(--font-display); font-size: 13px; letter-spacing: .1em; }
.vtr-lvl{ font-family: var(--font-display); font-size: 9px; letter-spacing: .18em; color: var(--text-mute); }
.vtr-tile.you .vtr-lvl{ color: var(--tier); }

.vip-current{
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 22px;
  margin-bottom: 36px;
}
.vc-kicker{
  font-family: var(--font-display); font-size: 11px; letter-spacing: .18em;
  color: var(--purple); margin-bottom: 8px;
}
.vc-row{
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-9); align-items: center;
  margin-bottom: 18px;
}
.vc-title h2{ margin: 0 0 4px; font-family: var(--font-display); font-size: 30px; }
.vc-sub{ color: var(--text-dim); font-size: 13px; }
.vc-bar{
  height: 8px; border-radius: var(--radius-xs);
  background: rgba(255,255,255,.05); overflow: hidden;
  margin-bottom: 6px;
}
.vc-bar > span{
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--purple-2), var(--purple));
  box-shadow: 0 0 14px var(--purple-glow);
}
.vc-nums{
  display: flex; justify-content: space-between;
  font-family: var(--font-display); font-size: 12px; color: var(--text-dim);
}
.vc-pct{ color: var(--purple); font-weight: 700; }
.vc-grid{
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5);
}
.vc-card{
  padding: var(--space-7);
  background: var(--white-02);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
}
.vc-k{ font-family: var(--font-display); font-size: 10px; letter-spacing: .15em; color: var(--text-mute); margin-bottom: 8px; }
.vc-v{ font-family: var(--font-display); font-size: 22px; margin-bottom: 4px; }
.vc-d{ font-size: 12px; color: var(--text-dim); }

.vip-steps, .vip-perks-sec, .vip-compare, .vip-cta{ margin-bottom: 36px; }
.vs-head{ margin-bottom: 18px; }
.vs-head h2{ margin: 0; font-family: var(--font-display); font-size: 28px; }
.vs-head .kicker{ color: var(--accent); font-family: var(--font-display); font-size: 11px; letter-spacing: .18em; }

.vs-grid{ display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }
.vs-card{
  padding: 22px;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.vs-num{
  font-family: var(--font-display); font-size: 34px; color: var(--accent);
  margin-bottom: 6px;
}
.vs-card h3{ margin: 0 0 8px; font-family: var(--font-display); font-size: 20px; }
.vs-card p{ margin: 0; color: var(--text-dim); font-size: 13px; line-height: 1.5; }

.vps-grid{ display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5); }
.vps-card{
  display: grid; grid-template-columns: 40px 1fr; gap: var(--space-6);
  padding: 18px;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.vps-icon{
  width: 40px; height: 40px; border-radius: var(--radius-md);
  background: var(--accent-15); color: var(--purple);
  display: grid; place-items: center;
}
.vps-t{ font-family: var(--font-display); font-size: 15px; margin-bottom: 4px; }
.vps-s{ font-size: 12px; color: var(--text-dim); line-height: 1.5; }

.vct-wrap{
  overflow-x: auto;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.vct{
  width: 100%; border-collapse: collapse;
  font-family: var(--font-display); font-size: 12px;
}
.vct th, .vct td{ padding: 14px 12px; text-align: center; white-space: nowrap; }
.vct th{
  font-family: var(--font-display); font-size: 10px; letter-spacing: .15em;
  color: var(--text);
  border-bottom: 1px solid var(--line-soft);
}
.vct td{ border-bottom: 1px solid rgba(255,255,255,.03); }
.vct tr:hover td{ background: var(--white-02); }
.vct td.label{ text-align: left; color: var(--text-dim); font-weight: 600; }

.vip-cta{
  display: grid; grid-template-columns: 1fr auto; gap: var(--space-9); align-items: center;
  padding: 28px;
  background: linear-gradient(135deg, rgba(61, 126, 255,.08), var(--panel));
  border: 1px solid rgba(61, 126, 255,.3);
  border-radius: var(--radius);
}
.vip-cta h2{ margin: 6px 0 6px; font-family: var(--font-display); font-size: 28px; }
.vip-cta p{ margin: 0; color: var(--text-dim); }
.vip-cta-btns{ display: inline-flex; gap: var(--space-4); }

@media (max-width: 900px){
  .vip-tier-rail{ grid-template-columns: repeat(4, 1fr); }
  .vs-grid, .vps-grid, .vc-grid{ grid-template-columns: 1fr 1fr; }
  .vc-row{ grid-template-columns: 1fr; gap: var(--space-6); }
  .vip-cta{ grid-template-columns: 1fr; }
}
@media (max-width: 540px){
  .vip-tier-rail{ grid-template-columns: repeat(2, 1fr); }
  .vs-grid, .vps-grid, .vc-grid{ grid-template-columns: 1fr; }
}

/* ---------- REWARDS PAGE ---------- */
.rw-page{ padding-bottom: 60px; }
.rw-hero{
  padding: 28px 0 24px;
  border-bottom: 1px dashed var(--line-soft);
  margin-bottom: 28px;
}
.rw-eyebrow{
  display: inline-flex; align-items: center; gap: var(--space-3);
  font-family: var(--font-display); font-size: 11px; letter-spacing: .18em;
  color: var(--accent);
  margin-bottom: 14px;
}
.rw-eyebrow .pulse{
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 12px var(--accent);
  animation: pulsator 1.6s ease-in-out infinite;
}
.rw-title{
  font-family: var(--font-display); font-size: clamp(42px, 6vw, 64px); line-height: 1;
  margin: 0 0 12px;
}
.rw-title .g-glow{ color: var(--accent); text-shadow: 0 0 20px rgba(52,192,235,.5); }
.rw-sub{ color: var(--text-dim); font-size: 15px; max-width: 620px; }

.rw-stats{
  display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-5);
  margin-bottom: 28px;
}
.rw-stat{
  padding: var(--space-8);
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  position: relative;
}
.rw-stat.accent{
  background: linear-gradient(135deg, var(--accent-10), var(--panel));
  border-color: rgba(52,192,235,.3);
}
.rw-stat .rw-k{
  font-family: var(--font-display); font-size: 10px; letter-spacing: .15em;
  color: var(--text-mute); margin-bottom: 10px;
}
.rw-stat.accent .rw-k{ color: var(--accent); }
.rw-stat .rw-v{
  font-family: var(--font-display); font-size: 28px; line-height: 1;
  margin-bottom: 6px;
}
.rw-stat .rw-d{ font-size: 12px; color: var(--text-dim); }
.rw-claim{
  appearance: none; cursor: pointer; border: 0;
  margin-top: 12px; padding: 8px 14px;
  background: var(--accent); color: var(--accent-ink);
  font-family: var(--font-display); font-weight: 800; font-size: 11px; letter-spacing: .08em;
  border-radius: var(--radius-sm);
  transition: .15s;
}
.rw-claim:hover{ transform: translateY(-1px); box-shadow: 0 6px 18px var(--accent-40); }
.rw-claim.big{ padding: 14px 22px; font-size: 14px; }
.rw-claim.ghost{
  background: transparent; color: var(--text);
  border: 1px solid var(--line-soft);
}

.rw-tabs{
  display: flex; gap: 2px; padding: var(--space-1);
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  margin-bottom: 20px;
  overflow-x: auto;
}
.rw-tabs button{
  appearance: none; cursor: pointer; border: 0;
  background: transparent;
  padding: 10px 18px;
  font-family: var(--font-ui); font-weight: 600; font-size: 13px;
  color: var(--text-dim);
  border-radius: var(--radius-sm);
  white-space: nowrap;
  transition: .15s;
}
.rw-tabs button:hover{ color: var(--text); }
.rw-tabs button.on{ background: var(--bg-2); color: var(--text); box-shadow: 0 1px 0 var(--white-04); }

.rw-panel{
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 22px;
}
.rw-panel-head{
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 18px;
  gap: var(--space-5); flex-wrap: wrap;
}
.rw-panel-head h3{
  margin: 0;
  font-family: var(--font-display); font-size: 12px; letter-spacing: .15em;
  color: var(--text);
}
.rw-pill{
  display: inline-flex; gap: var(--space-2); align-items: center;
  padding: 5px 10px; border-radius: var(--radius-xl);
  background: var(--white-04);
  font-family: var(--font-display); font-size: 10px; letter-spacing: .1em;
  color: var(--text-dim);
}
.rw-pill.accent{ background: var(--accent-10); color: var(--accent); }

/* daily */
.rw-days{ display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--space-3); }
.rw-day{
  padding: 16px 10px;
  text-align: center;
  background: var(--white-02);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  display: flex; flex-direction: column; gap: var(--space-2);
  align-items: center;
}
.rw-day.done{ background: rgba(52,192,235,.06); border-color: rgba(52,192,235,.3); opacity: .85; }
.rw-day.today{ background: var(--accent-soft); border-color: var(--purple); box-shadow: 0 0 20px rgba(61, 126, 255,.25); }
.rw-day-n{ font-family: var(--font-display); font-size: 10px; letter-spacing: .15em; color: var(--text-mute); }
.rw-day-reward{
  font-family: var(--font-display); font-size: 22px;
  color: var(--accent);
  display: inline-flex; align-items: baseline; gap: 2px;
}
.rw-day-reward span{ font-size: 18px; }
.rw-day.today .rw-day-reward{ color: var(--purple); }
.rw-day-status{
  font-family: var(--font-display); font-size: 10px; letter-spacing: .1em;
  color: var(--text-mute);
}
.rw-day.today .rw-day-status{ color: var(--purple); font-weight: 700; }
.rw-day.done .rw-day-status{ color: var(--accent); }

/* weekly */
.rw-weekly{ display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5); }
.rw-weekly-card{
  padding: var(--space-8);
  background: var(--white-02);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.rw-weekly-card.accent{
  background: linear-gradient(135deg, rgba(52,192,235,.08), var(--white-02));
  border-color: rgba(52,192,235,.3);
}
.rw-weekly-card .rw-k{ font-family: var(--font-display); font-size: 10px; letter-spacing: .15em; color: var(--text-mute); margin-bottom: 8px; }
.rw-weekly-card .rw-v{ font-family: var(--font-display); font-size: 24px; margin-bottom: 6px; }
.rw-weekly-card .rw-d{ color: var(--text-dim); font-size: 12px; margin-bottom: 12px; }

/* rakeback */
.rw-rake-top{
  display: grid; grid-template-columns: 1fr 1.4fr; gap: 18px;
  margin-bottom: 22px;
}
.rw-rake-big{
  padding: 22px;
  background: linear-gradient(135deg, rgba(52,192,235,.08), var(--white-02));
  border: 1px solid rgba(52,192,235,.3);
  border-radius: var(--radius);
}
.rw-rake-big .rw-k{ font-family: var(--font-display); font-size: 10px; letter-spacing: .15em; color: var(--accent); margin-bottom: 8px; }
.rw-rake-big .rw-v.glow{
  font-family: var(--font-display); font-size: 42px; color: var(--accent);
  text-shadow: 0 0 20px rgba(52,192,235,.5);
  margin-bottom: 16px;
}
.rw-rake-bars{ display: flex; flex-direction: column; gap: var(--space-4); justify-content: center; padding: var(--space-8); background: var(--white-02); border: 1px solid var(--line-soft); border-radius: var(--radius); }
.rw-bar-row{
  display: grid; grid-template-columns: 110px 1fr auto; gap: var(--space-5); align-items: center;
  font-family: var(--font-display); font-size: 12px;
}
.rw-bar-row span:first-child{ color: var(--text-dim); }
.rw-bar-row .bar{ height: 6px; border-radius: var(--radius-2xs); background: var(--white-04); overflow: hidden; }
.rw-bar-row .bar > span{ display: block; height: 100%; border-radius: var(--radius-2xs); }
.rw-bar-row em{ font-style: normal; color: var(--text); font-weight: 700; }
.rw-rake-history{ padding: var(--space-7); background: var(--white-02); border-radius: var(--radius-md); }
.rw-hist-row{
  display: grid; grid-template-columns: 110px 1fr auto; gap: var(--space-5); align-items: center;
  padding: 8px 4px; border-bottom: 1px solid rgba(255,255,255,.03);
  font-family: var(--font-display); font-size: 12px;
}
.rw-hist-row:last-child{ border-bottom: 0; }
.rw-hist-row span{ color: var(--text-dim); }
.rw-hist-row em{ font-style: normal; color: var(--text); font-weight: 600; }
.rw-hist-row strong{ color: var(--accent); }
.rw-sub{ font-family: var(--font-display); font-size: 10px; letter-spacing: .15em; color: var(--text-mute); margin-bottom: 10px; }

/* race */
.rw-race-board{ display: flex; flex-direction: column; gap: var(--space-1); }
.rw-race-row{
  display: grid; grid-template-columns: 60px 1.4fr 1fr 120px; gap: var(--space-6);
  padding: 12px 16px;
  background: var(--white-02);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  font-family: var(--font-display); font-size: 13px;
  align-items: center;
  transition: .15s;
}
.rw-race-row .r{ color: var(--text-mute); font-weight: 700; }
.rw-race-row .u{ color: var(--text); font-family: var(--font-ui); font-weight: 700; }
.rw-race-row .w{ color: var(--text-dim); }
.rw-race-row .p{ text-align: right; color: var(--accent); font-weight: 700; }
.rw-race-row.podium .r{ color: var(--gold); font-size: 15px; }
.rw-race-row.podium{ border-color: rgba(255,188,74,.25); }
.rw-race-row.me{
  background: linear-gradient(90deg, rgba(61, 126, 255,.14), var(--white-02));
  border-color: rgba(61, 126, 255,.4);
  box-shadow: 0 0 18px rgba(61, 126, 255,.15);
}
.rw-race-row.me .u{ color: var(--purple); }

/* challenges */
.rw-ch-grid{ display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5); }
.rw-ch-card{
  padding: 18px;
  background: var(--white-02);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.rw-ch-head{ display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 6px; }
.rw-ch-card h4{ margin: 0; font-family: var(--font-display); font-size: 17px; }
.rw-ch-r{ color: var(--accent); font-family: var(--font-display); font-size: 13px; font-weight: 700; }
.rw-ch-card p{ margin: 0 0 12px; color: var(--text-dim); font-size: 12px; line-height: 1.5; }
.rw-ch-bar{ height: 6px; background: rgba(255,255,255,.05); border-radius: var(--radius-2xs); overflow: hidden; margin-bottom: 6px; }
.rw-ch-bar > span{
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--purple));
}
.rw-ch-prog{ font-family: var(--font-display); font-size: 11px; color: var(--text-dim); }

/* codes */
.rw-codes{ display: flex; flex-direction: column; gap: var(--space-7); }
.rw-code-input{
  display: grid; grid-template-columns: 1fr auto; gap: var(--space-4);
  padding: var(--space-7);
  background: var(--white-02);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
}
.rw-code-input input{
  appearance: none; border: 0; outline: 0;
  background: transparent;
  padding: 10px 14px;
  color: var(--text);
  font-family: var(--font-display); font-size: 13px; letter-spacing: .15em;
}
.rw-code-input input::placeholder{ color: var(--text-mute); }
.rw-code-input button{
  appearance: none; border: 0; cursor: pointer;
  padding: 10px 22px;
  background: var(--accent); color: var(--accent-ink);
  font-family: var(--font-display); font-weight: 800; font-size: 12px; letter-spacing: .08em;
  border-radius: var(--radius-sm);
  transition: .15s;
}
.rw-code-list{ padding: var(--space-7); background: var(--white-02); border-radius: var(--radius-md); }

@media (max-width: 900px){
  .rw-stats{ grid-template-columns: 1fr 1fr; }
  .rw-days{ grid-template-columns: repeat(4, 1fr); }
  .rw-weekly{ grid-template-columns: 1fr; }
  .rw-rake-top{ grid-template-columns: 1fr; }
  .rw-ch-grid{ grid-template-columns: 1fr 1fr; }
}
@media (max-width: 540px){
  .rw-stats{ grid-template-columns: 1fr; }
  .rw-days{ grid-template-columns: repeat(3, 1fr); }
  .rw-ch-grid{ grid-template-columns: 1fr; }
  .rw-race-row{ grid-template-columns: 40px 1fr 80px; font-size: 12px; padding: 10px 12px; }
  .rw-race-row .w{ display: none; }
  .rw-hist-row{ grid-template-columns: 90px 1fr 70px; font-size: 11px; }
  .rw-bar-row{ grid-template-columns: 84px 1fr auto; }
}

/* ---------- GP bottombar responsive ---------- */
@media (max-width: 700px){
  .gp-bottombar{ grid-template-columns: 1fr; gap: var(--space-4); text-align: center; }
  .gp-bb-left, .gp-bb-right{ justify-content: center; }
  .gp-bb-center{ display: none; }
}

/* ---------- Additional utility buttons ---------- */
/* Spec-exact primary CTA — amber gradient + warm ink */
.btn-primary{
  appearance: none; cursor: pointer; border: 0;
  padding: 12px 22px;
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
  color: var(--on-accent);
  font-family: var(--font-display); font-weight: 800; font-size: 13px; letter-spacing: .08em;
  border-radius: var(--radius-md);
  box-shadow: 0 8px 22px var(--accent-glow);
  transition: transform .12s, box-shadow .2s, filter .15s;
}
.btn-primary.purple{
  /* Legacy class — renders as the canonical amber CTA for consistency. */
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
  color: var(--on-accent);
}
.btn-primary:hover{ transform: translateY(-1px); box-shadow: 0 12px 30px var(--accent-glow); filter: brightness(1.04); }
.btn-ghost{
  appearance: none; cursor: pointer;
  padding: 12px 22px;
  background: transparent; color: var(--text);
  border: 1px solid var(--line-soft);
  font-family: var(--font-display); font-weight: 700; font-size: 13px; letter-spacing: .08em;
  border-radius: var(--radius-md);
  transition: .15s;
}
.btn-ghost:hover{ border-color: var(--purple); color: var(--purple); }

/* ---------- Mobile hamburger in topbar (replacing old one in sidebar drawer) ---------- */
.mobile-ham{
  appearance: none; background: transparent; border: 1px solid var(--line-soft);
  width: 38px; height: 38px; border-radius: var(--radius-md);
  display: grid; place-items: center;
  color: var(--text); cursor: pointer;
}

/* ---------- Responsive fixes for sidebar brand / logo ---------- */
@media (max-width: 1100px){
  :root{ --rail-w: 220px; }
  .brand{ padding: 0 14px; gap: var(--space-3); }
  .brand .logo{ font-size: 18px; }
  .brand .logo-mark{ width: 30px; height: 30px; font-size: 16px; }
}
@media (max-width: 980px) and (min-width: 861px){
  :root{ --rail-w: 76px; }
  .brand .logo > span{ display: none; }
  .brand .logo-mark{ margin: 0 auto; }
  .rail .n-label, .rail .n-badge, .rail .section-label{ display: none; }
  .rail .nav-item{ justify-content: center; padding: 10px 8px; }
  .rail-player-top .rp-user, .rail-player-top .rp-tier,
  .rail-player-top .rp-emblem, .rail-player-top .bar, .rail-player-top .xp{ display: none; }
  .rail-mode, .rail-search{ display: none; }
}

/* Notifications: keep visible on mobile so users can see win/promo alerts */
.notif-wrap{ display: inline-flex !important; }


/* ================== FOOTER ================== */
.site-footer {
  margin-top: 72px;
  padding: 48px 0 24px;
  border-top: 1px solid var(--line-soft);
  font-family: var(--font-sans);
  color: var(--text);
}
.ft-top { display: grid; grid-template-columns: 1.1fr 3fr; gap: 48px; align-items: start; }
.ft-brand { display: flex; align-items: center; gap: var(--space-6); }
.ft-brand .logo-mark { width: 44px; height: 44px; border-radius: var(--radius-md); display:flex; align-items:center; justify-content:center; font-family: var(--font-display); font-size: 22px; }
.ft-logo { font-family: var(--font-display); font-size: 24px; letter-spacing: .02em; }
.ft-tag { font-family: var(--font-display); font-size: 10px; color: var(--text-mute); letter-spacing: .1em; text-transform: uppercase; margin-top: 2px; }
.ft-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 28px; }
.ft-grid h5 { font-family: var(--font-display); font-size: 10px; letter-spacing: .15em; color: var(--accent); margin: 0 0 14px; text-transform: uppercase; }
.ft-grid ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.ft-grid a { color: var(--text-dim); font-size: 13px; cursor: pointer; text-decoration: none; }
.ft-grid a:hover { color: var(--text); }

.ft-sub { font-family: var(--font-display); font-size: 10px; letter-spacing: .15em; color: var(--text-mute); margin-bottom: 12px; text-transform: uppercase; }

/* P3-9: Accepted Payments section now sits in its own panel — operator
   feedback was that the section "feels really not good in the eyes"
   without a visual break (the coins flowed straight into the body
   above). The panel background + softer border gives the section a
   defined boundary while staying within the existing footer palette. */
/* Task #357 — Accepted Payments restyle. Operator feedback: the row
   read as cluttered with a visible 1px outline on every chip and a
   second border on the panel. Smoothed by:
     • dropping the visible chip border (now a soft inner surface
       only, matching the "Our Currencies" reference)
     • equal-height single-row tiles, tighter padding
     • snap-scroll with -webkit-overflow-scrolling: touch for
       momentum on iOS; scrollbar fully hidden across browsers
     • softer panel chrome (no hard outline) — uses the same surface
       tone but loses the 1px line that read as a "warning border". */
.ft-accepted {
  margin-top: 40px;
  padding: 16px 18px 14px;
  background: var(--white-02);
  border: 0;
  border-radius: var(--radius-md, 10px);
}
/* Kill the global .sec-head 30px top margin inside this panel — the panel
   already provides its own 16px padding-top, so the kicker + arrows row
   was sitting in a tall empty band. */
.ft-accepted .sec-head { margin-top: 0; margin-bottom: 8px; }
/* Operator request — when Accepted Payments is hoisted to the TOP of
   the footer it sits flush against the brand + link columns below it.
   Add breathing room between the panel and .ft-top, and trim its big
   default top margin since it's now the first footer element (the
   48px footer padding already provides the top gap). */
.ft-accepted-top { margin-top: 0; margin-bottom: 40px; }
.ft-coins {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  padding: 6px 2px 12px;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-snap-type: x mandatory;
  scroll-padding-left: 4px;
  -webkit-overflow-scrolling: touch;
}
.ft-coins::-webkit-scrollbar { display: none; width: 0; height: 0; }
.ft-coins > * { scroll-snap-align: start; }
.ft-coin {
  font-family: var(--font-display);
  font-size: 11px;
  flex: 0 0 auto;
  width: 158px;
  height: 56px;
  padding: 8px 14px;
  border: 0;
  border-radius: 10px;
  color: var(--text-dim);
  background: color-mix(in srgb, var(--bg-2, #131316) 78%, #000 22%);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  transition: background .18s ease, transform .18s ease;
}
.ft-coin:hover {
  background: color-mix(in srgb, var(--bg-2) 86%, var(--accent) 14%);
  transform: translateY(-1px);
}

/* Footer-scoped zoom for the coin glyph. The BRIX-style PNGs ship
   with built-in transparent padding around the brand mark; when
   CoinIcon clips them to a circle the padding still sits inside the
   crop and reads as a faint white halo around lighter assets (ETH,
   USDC, …) on the dark footer. Scaling the inner <img> up ~12%
   pushes that padding past the circular boundary so the brand mark
   fills the disc edge-to-edge. The clip already lives on
   .dw-coin-sym (overflow: hidden when round=true), so nothing else
   needs to change. The transform-origin is the default 50% 50%
   which keeps the glyph centred. Only applied inside the footer
   row so coin chips elsewhere (bets feed, wallet picker, deposit
   modal) keep their native framing. */
.ft-coin .dw-coin-sym > img {
  transform: scale(1.12);
  transform-origin: 50% 50%;
}

.ft-coin-priced .ft-coin-info {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  line-height: 1.1;
}
.ft-coin-priced .ft-coin-sym {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: .04em;
}
.ft-coin-priced .ft-coin-usd {
  font-family: var(--font-display);
  /* Operator request — price + 24h delta read bigger and bolder so
     the live numbers stand out against the dim coin row. Bumped from
     11px/regular dim → 13px/700/full text, and the delta from 10/600
     → 12/700. Kept just under the symbol (12px → unchanged) so the
     hierarchy still says "this row is BTC" first, "the price is X"
     second. */
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: .02em;
}
.ft-coin-priced .ft-coin-delta {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .03em;
}
.ft-coin-priced .ft-coin-delta.up   { color: #4ee6a8; }
.ft-coin-priced .ft-coin-delta.down { color: #ff6b8a; }

@media (max-width: 768px) {
  .ft-coin { width: 138px; height: 56px; padding: 8px 12px; }
  .ft-coin-priced .ft-coin-sym { font-size: 11px; }
  /* Mobile bumps proportionally — price + delta still ~+2px over the
     symbol so the number reads as the headline data point on the row. */
  .ft-coin-priced .ft-coin-usd { font-size: 12px; }
  .ft-coin-priced .ft-coin-delta { font-size: 11px; }
}

.ft-social { margin-top: 32px; display: flex; justify-content: space-between; gap: var(--space-10); flex-wrap: wrap; }
.ft-social-row { display: flex; gap: var(--space-3); }
.ft-social-btn { width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--line-soft); border-radius: var(--radius-sm); color: var(--text-dim); cursor: pointer; font-family: var(--font-display); font-size: 11px; background: var(--white-02); transition: .15s; }
.ft-social-btn:hover { color: var(--accent); border-color: var(--accent); }
.ft-lic-row { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.ft-lic { font-family: var(--font-display); font-size: 11px; padding: 8px 12px; border: 1px solid var(--line-soft); border-radius: var(--radius-xs); color: var(--text-dim); }

.ft-legal { margin-top: 32px; padding-top: 24px; border-top: 1px solid var(--line-soft); }
.ft-legal p { font-size: 12px; color: var(--text-mute); line-height: 1.6; max-width: 900px; }
.ft-legal a { color: var(--accent); text-decoration: none; }
.ft-bottom { display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--space-5); margin-top: 16px; font-family: var(--font-display); font-size: 10px; letter-spacing: .1em; color: var(--text-mute); text-transform: uppercase; }
.ft-links a { color: var(--text-mute); margin: 0 2px; cursor: pointer; }
.ft-links a:hover { color: var(--text); }

@media (max-width: 960px) {
  .ft-top { grid-template-columns: 1fr; }
  .ft-grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-8); }
}

/* ================== SLOTS PAGE ================== */
.slots-page { padding: 0 0 24px; }
.slots-hero {
  display: grid; grid-template-columns: 1.4fr 1fr; gap: var(--space-10);
  margin: 24px 0 32px;
  padding: var(--space-11);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background:
    radial-gradient(ellipse at 20% 0%, rgba(167, 99, 255, .18), transparent 50%),
    radial-gradient(ellipse at 90% 100%, rgba(52, 192, 235, .08), transparent 50%),
    linear-gradient(180deg, rgba(20, 18, 30, .6), rgba(12, 10, 18, .4));
  position: relative; overflow: hidden;
}
.sh-eyebrow { display: inline-flex; align-items: center; gap: var(--space-3); font-family: var(--font-display); font-size: 11px; letter-spacing: .1em; color: var(--text-mute); text-transform: uppercase; margin-bottom: 12px; }
.sh-eyebrow .pulse { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 8px var(--accent); animation: pulse 1.5s ease-in-out infinite; }
.slots-hero h1 { font-family: var(--font-display); font-size: 56px; line-height: 1; margin: 0 0 16px; font-weight: 400; letter-spacing: -.02em; }
.g-glow-acc { color: var(--accent); text-shadow: 0 0 20px var(--accent-40); }
.slots-hero p { font-size: 15px; line-height: 1.6; color: var(--text-dim); max-width: 52ch; margin: 0 0 24px; }
.sh-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }
.sh-stats > div { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-5); border: 1px solid var(--line-soft); border-radius: var(--radius-md); background: var(--white-02); }
.sh-stats .k { font-family: var(--font-display); font-size: 9px; letter-spacing: .15em; color: var(--text-mute); text-transform: uppercase; }
.sh-stats .v { font-family: var(--font-display); font-size: 22px; color: var(--accent); }
.sh-stats .d { font-size: 10px; color: var(--text-mute); font-family: var(--font-display); }

.sh-jackpot { display: flex; align-items: center; justify-content: center; }
.jp-ring {
  width: 100%; padding: 28px;
  border: 1px solid rgba(167, 99, 255, .35);
  border-radius: var(--radius);
  background: radial-gradient(ellipse at top, rgba(167, 99, 255, .15), rgba(12, 10, 18, .6));
  text-align: center;
  position: relative;
  box-shadow: 0 0 40px rgba(167, 99, 255, .15), inset 0 1px 0 rgba(255,255,255,.05);
}
.jp-k { font-family: var(--font-display); font-size: 10px; letter-spacing: .2em; color: var(--purple); text-transform: uppercase; margin-bottom: 6px; }
.jp-v { font-family: var(--font-display); font-size: 42px; color: var(--text); line-height: 1; letter-spacing: -.02em; text-shadow: 0 0 30px rgba(167, 99, 255, .5); }
.jp-v span { font-size: 22px; color: var(--text-mute); }
.jp-d { font-family: var(--font-display); font-size: 10px; color: var(--text-mute); letter-spacing: .1em; text-transform: uppercase; margin-top: 6px; }
.jp-eligible { font-family: var(--font-display); font-size: 9px; letter-spacing: .15em; color: var(--accent); margin-top: 10px; text-transform: uppercase; }
.jp-btn { margin-top: 14px; padding: 10px 18px; border: 0; border-radius: var(--radius-sm); background: var(--purple); color: #fff; font-family: var(--font-sans); font-weight: 600; cursor: pointer; transition: .15s; }
.jp-btn:hover { background: var(--accent); color: var(--bg); }

/* Filters */
.slots-filters {
  display: grid; grid-template-columns: 280px 1fr 180px; gap: var(--space-5);
  margin-bottom: 24px; align-items: center;
}
.sf-search { position: relative; display: flex; align-items: center; gap: var(--space-3); padding: 10px 12px; border: 1px solid var(--line-soft); border-radius: var(--radius-md); background: var(--white-02); }
.sf-search input { background: none; border: 0; outline: 0; color: var(--text); flex: 1; font-family: var(--font-sans); font-size: 13px; }
.sf-search svg { color: var(--text-mute); }
.sf-cats { display: flex; gap: var(--space-2); overflow-x: auto; scrollbar-width: none; }
.sf-cats::-webkit-scrollbar { display: none; }
.sf-cats button { padding: 8px 14px; border: 1px solid var(--line-soft); border-radius: var(--radius-sm); background: var(--white-02); color: var(--text-dim); font-family: var(--font-sans); font-size: 12px; cursor: pointer; white-space: nowrap; transition: .15s; }
.sf-cats button:hover { color: var(--text); border-color: rgba(255,255,255,.15); }
.sf-cats button.on { background: var(--accent); color: var(--bg); border-color: var(--accent); font-weight: 600; }
.sf-prov { padding: 10px 12px; border: 1px solid var(--line-soft); border-radius: var(--radius-md); background: var(--white-02); color: var(--text); font-family: var(--font-sans); font-size: 13px; cursor: pointer; }

/* Slot grid — Phase 24: fluid tile floor using cqw (container query
   width) inside the .main container. Tile minimum scales 124–164px so
   the grid auto-fills more or fewer columns smoothly between viewports
   instead of jumping at hard breakpoints. */
.slots-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(clamp(124px, 14cqw, 164px), 1fr));
  gap: clamp(8px, 1.2cqw, 14px);
}
/* Phone breakpoint floor — even at the smallest viewport, keep at least 2
   tiles per row (no single-column slot grid). */
@container main (max-width: 360px){
  .slots-grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-4); }
}
.slot-card {
  position: relative; aspect-ratio: 2 / 3; border-radius: var(--radius); overflow: hidden;
  cursor: pointer; transition: transform .18s ease, box-shadow .18s ease;
  border: 1px solid rgba(255,255,255,.08);
}
.slot-card:hover { transform: translateY(-4px); box-shadow: 0 12px 30px rgba(0,0,0,.4), 0 0 24px rgba(167, 99, 255, .25); }
.slot-card-overlay {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.1) 0%, rgba(0,0,0,.6) 60%, rgba(0,0,0,.92) 100%);
  pointer-events: none;
}
.slot-card-inner { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: space-between; padding: var(--space-5); }
.slot-card-head { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
.slot-badge { font-family: var(--font-display); font-size: 9px; padding: 3px 7px; border-radius: var(--radius-xs); letter-spacing: .1em; font-weight: 700; }
.slot-badge.hot { background: #ff6b3d; color: #fff; }
.slot-badge.new { background: var(--accent); color: var(--bg); }
.slot-prov { margin-left: auto; font-family: var(--font-display); font-size: 8px; letter-spacing: .15em; color: rgba(255,255,255,.7); text-transform: uppercase; background: rgba(0,0,0,.4); padding: 3px 6px; border-radius: var(--radius-2xs); }
.slot-card-title { font-family: var(--font-display); font-size: 18px; color: #fff; line-height: 1.1; margin-bottom: 8px; text-shadow: 0 2px 8px rgba(0,0,0,.6); }
.slot-card-stats { display: flex; gap: var(--space-4); font-family: var(--font-display); font-size: 9px; color: rgba(255,255,255,.7); letter-spacing: .1em; margin-bottom: 8px; }
.slot-card-play { position: absolute; bottom: 12px; left: 12px; right: 12px; padding: var(--space-4); border: 0; border-radius: var(--radius-sm); background: var(--accent); color: var(--bg); font-family: var(--font-sans); font-weight: 700; letter-spacing: .1em; opacity: 0; transform: translateY(4px); cursor: pointer; transition: .15s; font-size: 11px; }
.slot-card:hover .slot-card-play { opacity: 1; transform: translateY(0); }

/* ========== Slot Card v3 — provider-themed, pulp-poster typography ==========
   Matches the customer's reference (HACKSAW / WANTED DEAD OR A WILD):
   banner art fills the card, brand-coloured provider tab top-right, and a
   theatrical display-font title CENTERED at the bottom over a deep scrim.
   Per-provider theming flows through the `--prov-color` CSS variable set
   inline by SlotCard's React component — every brand-tinted element
   (hover border + glow, rule above title, accent dot, PLAY button)
   consumes that one var, so changing a provider's brand colour in
   providers-meta.jsx instantly re-themes every card. */
.slot-card.v3 {
  --prov-color: #5b6175;            /* fallback if React forgets to set it */
  position: relative;
  aspect-ratio: 2 / 3;
  border-radius: var(--radius);               /* slightly rounder for a friendlier feel */
  overflow: hidden;
  cursor: pointer;
  border: 0;                         /* No real border — borders create a 1px
                                         ring around the absolutely-positioned
                                         title panel where artwork can show
                                         through. Use inset box-shadow below
                                         instead. */
  background-color: #0a0c12;         /* Opaque base behind the banner-image so
                                         a missing/slow image never reveals a
                                         transparent gap. */
  /* Inset hairline + subtle shadow gives the card definition without a real
     border (which would re-introduce the leak). */
  box-shadow:
    inset 0 0 0 1px var(--white-04),
    0 4px 14px rgba(0,0,0,.35);
  transition: transform .2s ease, box-shadow .25s ease;
}
/* Banner image — rendered as an <img> rather than CSS background so we
   can detect 404s via onError and reveal the brand-coloured gradient
   that lives on the parent's `background` property. Fills the entire
   card behind every overlay (z-index 0 — explicitly below the hover
   dim, scrim, title panel, etc.). */
.slot-card-img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  display: block;
  z-index: 0;
  pointer-events: none;
  user-select: none;
}
/* Hover dim layer — softens the artwork so the centered PLAY pill reads
   clearly. Customer ask: lighter overlay (was .45 → .25). */
.slot-card.v3::before {
  content: '';
  position: absolute; inset: 0;
  background: rgba(0,0,0,.25);
  opacity: 0;
  transition: opacity .18s ease;
  z-index: 1;
  pointer-events: none;
}
.slot-card.v3:hover::before { opacity: 1; }
/* No separate scrim above the panel — the .slot-card-bottom panel
   itself starts transparent at its top edge and fades into a brand-
   tinted dark at the bottom. This lets the artwork softly bleed into
   the title zone in the provider's colour, instead of being capped by
   a hard black band. The panel's gradient does both jobs (transition
   AND backdrop) in one element. */
.slot-card.v3:hover {
  /* Operator rebuild — brief mandates "subtle scale 1.02–1.04" + lift.
     translateY + 1.025 scale combined feels physical without overcooking. */
  transform: translateY(-3px) scale(1.025);
  box-shadow:
    inset 0 0 0 1px var(--prov-color),
    0 16px 36px rgba(0,0,0,.55),
    0 0 32px color-mix(in srgb, var(--prov-color) 35%, transparent);
}
.slot-card.v3:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
/* Provider badge — small SQUARED rect STUCK to the top edge of the card,
   centered. Customer ask: pill flush with the card top (no margin gap),
   game name hidden below. Bottom corners stay rounded (4px) to look
   tucked-in; top corners are squared so they sit right on the card edge.*/
.slot-card-prov-tab {
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  padding: 3px 10px 4px;
  font-family: var(--font-display); font-size: 8.5px; font-weight: 800;
  letter-spacing: .1em;
  color: rgba(255,255,255,.92);
  text-transform: uppercase;
  text-shadow: 0 1px 1px rgba(0,0,0,.4);
  background: var(--prov-color);
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
  box-shadow: 0 1px 3px rgba(0,0,0,.35);
  z-index: 3;
  max-width: calc(100% - 16px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-align: center;
  pointer-events: none;
}
/* HOT / NEW badges, top-left */
.slot-card.v3 .slot-card-badges {
  position: absolute; top: 6px; left: 6px;
  display: flex; gap: var(--space-1);
  z-index: 2;
}
.slot-card.v3 .slot-badge {
  font-family: var(--font-display); font-size: 8.5px; font-weight: 700;
  letter-spacing: .1em;
  padding: 2px 6px; border-radius: var(--radius-xs);
}
/* Operator feedback — colored fade overlay reduced ~70% so the artwork
   reads through clearly, layered with a halftone-style dot pattern in
   the same brand color (20% opacity) for vibe. The dots tile uniformly
   but visually fade because the linear gradient over them dims the
   bottom band, so the pattern reads as denser at the top of the
   overlay and washed-out at the bottom — natural halftone feel without
   a separate mask. The provider name box (.slot-card-prov-tab) is
   untouched. */
.slot-card.v3::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0;
  /* Operator feedback — overlay now hugs the lower 42% of the card
     instead of 65%, so the artwork breathes through the upper half. */
  height: 42%;
  z-index: 2;
  pointer-events: none;
  /* Three offset dot layers at slightly different sizes / phase break
     the visible grid so the halftone reads organic rather than tiled.
     Color intensities knocked down a notch so the brand tint is
     present but quiet against the artwork. */
  background-image:
    radial-gradient(circle,
      color-mix(in srgb, var(--prov-color) 14%, transparent) 0.9px,
      transparent 1.5px),
    radial-gradient(circle,
      color-mix(in srgb, var(--prov-color) 10%, transparent) 0.7px,
      transparent 1.3px),
    radial-gradient(circle,
      color-mix(in srgb, var(--prov-color) 8%, transparent) 0.5px,
      transparent 1px),
    linear-gradient(180deg,
      rgba(0,0,0,0) 0%,
      color-mix(in srgb, var(--prov-color) 3%,  rgba(0,0,0,.05)) 40%,
      color-mix(in srgb, var(--prov-color) 8%,  rgba(0,0,0,.26)) 75%,
      color-mix(in srgb, var(--prov-color) 13%, rgba(0,0,0,.55)) 100%);
  /* Three different tile sizes + phase offsets break the visible grid
     so adjacent rows don't line up. The result reads as a randomised
     halftone scatter rather than a perfect repeating dot mesh. */
  background-size: 7px 7px, 5px 5px, 11px 11px, 100% 100%;
  background-position: 0 0, 3px 1px, 1px 4px, 0 0;
  background-repeat: repeat, repeat, repeat, no-repeat;
}
/* Brand-color contour ring around the card — exact 1.5px inset, full
   provider color, so each card visibly outlines in its provider's
   brand. Replaces the generic hairline. */
.slot-card.v3 {
  box-shadow:
    inset 0 0 0 1.5px var(--prov-color),
    0 4px 14px rgba(0,0,0,.35);
}

/* Bottom title strip — sits ON TOP of the brand-color fade.
   Permanent Marker font, brand-color text with white center for the
   "glow" effect (matches the reference's pink title). */
.slot-card-bottom {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 78px;
  padding: 14px 10px 12px;
  z-index: 3;
  display: flex; flex-direction: column; justify-content: flex-end;
  align-items: center; gap: 6px;
  text-align: center;
  pointer-events: none;
}
/* Game name — HIDDEN per customer ask. The provider pill at the top is
   the only label; banner artwork carries the rest of the identity. */
.slot-card-name {
  display: none;
}
.slot-card-tag {
  font-family: var(--font-display); font-size: 9px; font-weight: 700;
  letter-spacing: .15em;
  color: var(--prov-color);
  display: inline-flex; align-items: center; gap: 5px;
  text-transform: uppercase;
}
.slot-card-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--prov-color);
  box-shadow: 0 0 8px var(--prov-color);
}
.slot-card-tag {
  font-family: var(--font-display); font-size: 9px; font-weight: 700;
  letter-spacing: .15em;
  color: var(--prov-color);
  display: inline-flex; align-items: center; gap: 5px;
  text-transform: uppercase;
}
.slot-card-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--prov-color);
  box-shadow: 0 0 8px var(--prov-color);
}
/* PLAY button — clean circular icon button (no text pill). The "▶ PLAY"
   text inside the <button> is suppressed via `font-size: 0`, and a
   triangle is drawn via `clip-path` on a square ::before. Brand-coloured
   per `--prov-color`.
   --
   Vertical centring: the card has a 78px solid title strip at the
   bottom, so geometric-centre of the card lands BELOW the visual centre
   of the artwork. We position the button at `(100% - 78px) / 2` so it
   sits in the middle of the artwork zone — that's where the eye expects
   a play button to be. */
.slot-card.v3 .slot-card-play {
  position: absolute;
  top: calc((100% - 78px) / 2); left: 50%;
  transform: translate(-50%, -50%) scale(.85);
  width: 56px; height: 56px;
  padding: 0;
  border: 0; border-radius: 50%;
  background: linear-gradient(180deg,
              color-mix(in srgb, var(--prov-color) 92%, white 8%),
              var(--prov-color));
  color: #fff;
  font-size: 0;                              /* hide "▶ PLAY" text */
  cursor: pointer;
  z-index: 4;
  opacity: 0;
  transition: opacity .18s ease, transform .18s ease, filter .15s ease;
  display: flex; align-items: center; justify-content: center;
  box-shadow:
    0 10px 28px color-mix(in srgb, var(--prov-color) 65%, transparent),
    0 0 0 1px rgba(255,255,255,.14),
    inset 0 1px 0 rgba(255,255,255,.22);
}
/* Triangle drawn via clip-path on a square white box. clip-path lets us
   place the apex AT the right-centre (95% 50%) and the base at 25% from
   the left, which produces a triangle that's optically centred inside
   its 20×20 bounding box (no margin/padding fudges needed). The square
   itself is centred by the parent's flex `align-items/justify-content`. */
.slot-card.v3 .slot-card-play::before {
  content: '';
  display: block;
  width: 20px; height: 20px;
  background: #fff;
  clip-path: polygon(28% 14%, 92% 50%, 28% 86%);
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.45));
}
.slot-card.v3 .slot-card-play:hover { filter: brightness(1.08); }
.slot-card.v3:hover .slot-card-play {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}
/* Touch / coarse-pointer devices (phones, tablets): no hover exists, so
   show the play icon at all times. Slightly smaller (48px) than the
   desktop hover state since it's permanently on screen. */
@media (hover: none) and (pointer: coarse) {
  .slot-card.v3 .slot-card-play {
    opacity: 1;
    transform: translate(-50%, -50%);
    width: 48px; height: 48px;
  }
  .slot-card.v3 .slot-card-play::before {
    width: 18px; height: 18px;
  }
}
@media (max-width: 600px) {
  /* Smaller cards have a 68px title strip — adjust the play button's
     "centre in artwork zone" calc accordingly. */
  .slot-card.v3 .slot-card-play { top: calc((100% - 68px) / 2); }
}

/* Smaller cards (denser grids) — scale the panel + title down so the
   two-line clamp still fits. Triggers below ~140px tile width via the
   parent grid which is auto-fill minmax(140px, ...). */
@media (max-width: 600px) {
  .slot-card-name { font-size: 15px; }
  .slot-card-bottom { height: 68px; padding: 14px 8px 10px; }
  .slot-card-bottom::before { width: 28px; }
}

.slots-empty { grid-column: 1 / -1; padding: 48px; text-align: center; color: var(--text-mute); font-family: var(--font-display); border: 1px dashed var(--line-soft); border-radius: var(--radius); display: flex; flex-direction: column; gap: var(--space-5); align-items: center; }
.slots-empty button { padding: 8px 16px; border: 1px solid var(--accent); border-radius: var(--radius-sm); background: none; color: var(--accent); cursor: pointer; font-family: var(--font-display); font-size: 11px; }

/* Providers */
.slots-providers { margin-top: 48px; }
.slots-providers h3 { font-family: var(--font-display); font-size: 11px; letter-spacing: .15em; color: var(--accent); margin-bottom: 16px; text-transform: uppercase; }
.sp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--space-4); }
.sp-card { display: flex; align-items: center; gap: var(--space-5); padding: var(--space-5); border: 1px solid var(--line-soft); border-radius: var(--radius-md); background: var(--white-02); cursor: pointer; transition: .15s; }
.sp-card:hover { border-color: var(--accent); background: rgba(52,192,235,.04); }
.sp-logo { width: 40px; height: 40px; border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-size: 16px; color: #fff; flex-shrink: 0; }
.sp-name { font-size: 13px; color: var(--text); font-weight: 500; }
.sp-count { font-family: var(--font-display); font-size: 10px; color: var(--text-mute); letter-spacing: .1em; }

/* Info */
.slots-info { margin-top: 48px; display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-8); }
.si-card { padding: 28px; border: 1px solid var(--line-soft); border-radius: var(--radius); background: var(--white-02); }
.si-kicker { font-family: var(--font-display); font-size: 10px; letter-spacing: .2em; color: var(--purple); text-transform: uppercase; margin-bottom: 10px; }
.si-card h3 { font-family: var(--font-display); font-size: 28px; font-weight: 400; margin: 0 0 16px; line-height: 1.1; }
.si-card p { color: var(--text-dim); line-height: 1.6; margin-bottom: 16px; }
.si-card ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-4); }
.si-card li { color: var(--text-dim); line-height: 1.5; padding-left: 18px; position: relative; }
.si-card li::before { content: '◆'; position: absolute; left: 0; color: var(--accent); font-size: 10px; top: 5px; }
.si-card strong { color: var(--text); font-weight: 600; }
.si-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); margin-top: 16px; }
.si-stats > div { padding: var(--space-5); border: 1px solid var(--line-soft); border-radius: var(--radius-sm); background: rgba(0,0,0,.2); }
.si-stats .k { display: block; font-family: var(--font-display); font-size: 9px; letter-spacing: .15em; color: var(--text-mute); text-transform: uppercase; margin-bottom: 4px; }
.si-stats .v { font-family: var(--font-display); font-size: 22px; color: var(--accent); }

@media (max-width: 960px) {
  .slots-hero { grid-template-columns: 1fr; padding: var(--space-9); }
  .slots-hero h1 { font-size: 36px; }
  .sh-stats { grid-template-columns: 1fr; }
  .slots-filters { grid-template-columns: 1fr; }
  .slots-info { grid-template-columns: 1fr; }
  .slots-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}

/* ================== BET FEED CHART ================== */
.bf-scope { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.bf-scope button { padding: 5px 10px; font-family: var(--font-display); font-size: 10px; border: 1px solid var(--line-soft); border-radius: var(--radius-xs); background: var(--white-02); color: var(--text-dim); cursor: pointer; letter-spacing: .1em; }
.bf-scope button.on { background: var(--accent); color: var(--bg); border-color: var(--accent); font-weight: 700; }
.bf-scope .bf-reset { margin-left: 6px; display: inline-flex; align-items: center; gap: var(--space-1); color: var(--text-mute); }

.bf-chart {
  margin-bottom: 16px;
  padding: 14px 16px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  background: rgba(0,0,0,.2);
}
.bf-chart-head { display: flex; gap: 28px; margin-bottom: 8px; flex-wrap: wrap; }
.bf-chart-meta { display: flex; flex-direction: column; gap: 2px; }
.bf-chart-meta .k { font-family: var(--font-display); font-size: 9px; letter-spacing: .15em; color: var(--text-mute); text-transform: uppercase; }
.bf-chart-meta .v { font-family: var(--font-display); font-size: 18px; color: var(--text); }
.bf-chart-svg { width: 100%; height: 120px; display: block; }
.bf-sub-tabs { display: flex; gap: var(--space-2); margin-bottom: 10px; }
.bf-sub-tabs button { padding: 6px 12px; font-family: var(--font-display); font-size: 10px; border: 1px solid var(--line-soft); border-radius: var(--radius-xs); background: var(--white-02); color: var(--text-dim); cursor: pointer; letter-spacing: .1em; }
.bf-sub-tabs button.on { background: rgba(52,192,235,.12); color: var(--accent); border-color: var(--accent); }



/* ================== DEPOSIT / WITHDRAW MODAL ================== */
.dw-modal {
  width: min(880px, 94vw);
  max-height: 92vh;
  overflow: hidden;
  padding: 0;
  display: flex; flex-direction: column;
  background: var(--bg-2);   /* flat dark — was a vertical gradient */
  border: 1px solid var(--line);
  border-radius: var(--radius);
  position: relative;
}
.dw-modal .modal-close { position: absolute; top: 14px; right: 14px; z-index: 20; }

/* Tab strip — TRIPLE DEFENSE against close-button overlap:
   1. `margin-right: 56px` — the strip's right edge sits 56px from the
      modal's right edge.
   2. `max-width: calc(100% - 56px)` — even if margin gets overridden by
      another rule, the strip can never grow wider than 100%-56px.
   3. `border-right` (none, but available) — the strip's clip boundary.
   The close button is ~32px wide × 8px right offset = 40px from the
   right edge. 56px reservation gives a 16px clear gap. We use BOTH
   `margin-right` and `max-width` so that whichever one a downstream
   rule overrides, the other still holds. */
.dw-tabs {
  display: flex; gap: var(--space-1);
  padding: 16px 0 0 16px;
  margin-right: 56px;
  max-width: calc(100% - 56px);
  border-bottom: 1px solid var(--line-soft);
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.dw-tabs::-webkit-scrollbar { display: none; }
.dw-tabs button { flex-shrink: 0; }
.dw-tabs button {
  display: inline-flex; align-items: center; gap: var(--space-3);
  padding: 12px 18px;
  background: none; border: 0;
  color: var(--text-mute);
  font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: .15s;
}
.dw-tabs button:hover { color: var(--text); }
.dw-tabs button.on {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.dw-body {
  display: grid; grid-template-columns: 240px 1fr;
  flex: 1; min-height: 0;
  overflow: hidden;
}
.dw-coinlist {
  padding: 16px 10px 16px 16px;
  overflow-y: auto;
  border-right: 1px solid var(--line-soft);
  background: rgba(0,0,0,.2);
}
.dw-sub {
  font-family: var(--font-display); font-size: 10px;
  letter-spacing: .15em; text-transform: uppercase;
  color: var(--text-mute);
  margin-bottom: 10px;
}
.dw-coin {
  display: flex; align-items: center; gap: var(--space-4);
  width: 100%;
  padding: 8px 10px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none; color: var(--text);
  cursor: pointer; text-align: left;
  margin-bottom: 2px;
  transition: .12s;
}
/* Phase 29.3 — coin row gains canonical hover-lift to match the rest
   of the card primitives (game tiles, provider tiles, etc). */
.dw-coin:hover {
  background: var(--white-04);
  transform: translateY(-1px);
  box-shadow: 0 6px 14px rgba(0,0,0,.25);
  border-color: rgba(255,255,255,.06);
}
.dw-coin.on { background: rgba(52,192,235,.08); border-color: rgba(52,192,235,.3); }
.dw-coin-sym {
  width: 28px; height: 28px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 13px;
  flex-shrink: 0;
}
.dw-coin-meta { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.dw-coin-name { font-family: var(--font-display); font-size: 12px; font-weight: 700; letter-spacing: .05em; }
.dw-coin-full { font-size: 11px; color: var(--text-mute); }
.dw-coin-bal { font-family: var(--font-display); font-size: 11px; color: var(--text-dim); }

.dw-pane {
  padding: 24px 28px;
  overflow-y: auto;
  /* Task #210 — long currency labels (e.g. "USDC (Polygon)") were
     truncating mid-word inside the wallet drawer. Allow soft-wrap on
     long words so the inline labels never clip on narrow viewports. */
  overflow-wrap: anywhere;
  word-break: normal;
}
.dw-pane label,
.dw-pane .dw-coin-name,
.dw-pane .dw-coin-full {
  white-space: normal;
  text-overflow: clip;
  overflow-wrap: anywhere;
}
.dw-title {
  font-family: var(--font-display);
  font-size: 22px; font-weight: 400;
  margin-bottom: 18px;
  letter-spacing: -.01em;
}
.dw-field { margin-bottom: 16px; }
.dw-field label {
  display: block;
  font-family: var(--font-display); font-size: 10px;
  letter-spacing: .15em; text-transform: uppercase;
  color: var(--text-mute);
  margin-bottom: 8px;
}
.dw-chips { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.dw-chips button {
  padding: 8px 14px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: var(--white-02);
  color: var(--text-dim);
  font-family: var(--font-display); font-size: 11px;
  letter-spacing: .05em;
  cursor: pointer;
  transition: .12s;
}
.dw-chips button:hover { color: var(--text); border-color: rgba(255,255,255,.18); }
.dw-chips button.on {
  background: var(--accent); color: var(--bg);
  border-color: var(--accent); font-weight: 700;
}

/* QR */
.dw-qr-row {
  display: grid;
  grid-template-columns: 180px 1fr;
  gap: 22px;
  align-items: start;
}
.dw-qr {
  position: relative;
  width: 180px; height: 180px;
  padding: var(--space-4);
  background: #fff;
  border-radius: var(--radius-md);
}
/* Skeleton shown while the deposit address resolves. Replaces the QR so
   no stale chain's QR is ever scannable during a network change. */
.dw-qr-skeleton {
  width: 100%; height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--space-4);
  background: linear-gradient(135deg, #1a1f3a 0%, #0f1228 100%);
  color: var(--text-mute);
  font-family: var(--font-display); font-size: 10px;
  border-radius: var(--radius-xs);
  text-align: center;
}
.dw-spinner {
  width: 28px; height: 28px;
  border: 2px solid rgba(52,192,235,.18);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: dwSpin .9s linear infinite;
}
@keyframes dwSpin {
  to { transform: rotate(360deg); }
}

/* Task #183 — Per-status panel for non-loading deposit states.
   Sits in the same 180px slot as the QR but feels intentional:
   distinct iconography, tailored copy, tone-matched chrome.
   Tones are driven by `data-deposit-status` so the JSX stays
   declarative (no className gymnastics). */
.dw-qr-status {
  width: 100%; height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px;
  padding: var(--space-3);
  border-radius: var(--radius-xs);
  text-align: center;
  background: linear-gradient(155deg, #181c34 0%, #0c1024 100%);
  border: 1px dashed var(--line-soft);
  color: var(--text-dim);
  transition: border-color .2s ease, background .2s ease;
}
.dw-qr-status svg { color: inherit; }
.dw-qr-status-title {
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--text);
  line-height: 1.15;
  margin-top: 2px;
}
.dw-qr-status-sub {
  font-family: var(--font-display);
  font-size: 9.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-mute);
  line-height: 1.3;
}

/* Logged-out: warm/inviting — this is a CTA state, not a failure. */
.dw-qr-status[data-deposit-status="logged_out"] {
  background: linear-gradient(155deg, rgba(52,192,235,.10) 0%, rgba(52,192,235,.02) 100%);
  border: 1px solid var(--accent-40);
  color: var(--accent);
}
.dw-qr-status[data-deposit-status="logged_out"] .dw-qr-status-title { color: #fff3c8; }

/* Disabled: neutral muted — operational state, not user error. */
.dw-qr-status[data-deposit-status="disabled"] {
  background: linear-gradient(155deg, rgba(166,174,203,.06) 0%, rgba(166,174,203,.01) 100%);
  border: 1px solid var(--line-soft);
  color: var(--text-dim);
}

/* Unsupported: warning amber — user picked a chain that won't work. */
.dw-qr-status[data-deposit-status="unsupported"] {
  background: linear-gradient(155deg, rgba(255,188,74,.08) 0%, rgba(255,188,74,.01) 100%);
  border: 1px solid rgba(255,188,74,.35);
  color: #ffd290;
}
.dw-qr-status[data-deposit-status="unsupported"] .dw-qr-status-title { color: #ffe1b2; }

/* Error: magenta — something actually broke; surface it. */
.dw-qr-status[data-deposit-status="error"] {
  background: linear-gradient(155deg, rgba(239,68,68,.10) 0%, rgba(239,68,68,.02) 100%);
  border: 1px solid rgba(239,68,68,.45);
  color: #ffb4c0;
}
.dw-qr-status[data-deposit-status="error"] .dw-qr-status-title { color: #ffd2da; }

/* Per-status warn-line tones matched to the panel above so the
   eye reads the panel + warn line as one unit. The base `.dw-warn`
   amber stays the default for `loading`. Brighter foreground colors
   meet WCAG AA on the dark modal bg (~#0a0e22). */
.dw-warn-status[data-deposit-status="logged_out"] {
  border-color: var(--accent-40);
  background: rgba(52,192,235,.08);
  color: #ffe9a8;
}
.dw-warn-status[data-deposit-status="disabled"] {
  border-color: var(--line-soft);
  background: var(--white-02);
  color: var(--text-dim);
  border-style: dashed;
}
.dw-warn-status[data-deposit-status="unsupported"] {
  border-color: rgba(255,188,74,.35);
  background: rgba(255,188,74,.06);
  color: #ffd290;
}
.dw-warn-status[data-deposit-status="error"] {
  border-color: rgba(239,68,68,.45);
  background: rgba(239,68,68,.07);
  color: #ffb4c0;
}
.dw-warn-status strong { color: inherit; filter: brightness(1.15); }
.qr-grid {
  width: 100%; height: 100%;
  display: grid;
  grid-template-columns: repeat(15, 1fr);
  gap: 1px;
}
.qr-grid span { background: #fff; }
.qr-grid .qr-on { background: #04060E; }
.qr-logo {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.qr-logo span {
  width: 32px; height: 32px;
  background: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; border-radius: var(--radius-xs);
}
.dw-qr-info { display: flex; flex-direction: column; gap: var(--space-4); }
.dw-addr {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 10px 12px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: rgba(0,0,0,.3);
  font-family: var(--font-display); font-size: 12px;
}
.dw-addr span { flex: 1; color: var(--text); letter-spacing: .02em; word-break: break-all; }
.dw-addr button {
  padding: 6px 12px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-xs);
  background: var(--accent-10);
  color: var(--accent);
  font-family: var(--font-display); font-size: 10px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  cursor: pointer;
}
.dw-addr button:hover { background: var(--accent); color: var(--bg); }
.dw-warn {
  padding: 10px 12px;
  border: 1px dashed rgba(255, 188, 74, .35);
  border-radius: var(--radius-sm);
  background: rgba(255, 188, 74, .06);
  font-size: 12px;
  color: #ffd290;
  line-height: 1.5;
}
.dw-warn.soft {
  border-color: var(--line-soft);
  background: var(--white-02);
  color: var(--text-mute);
}
.dw-meta {
  display: grid; grid-template-columns: 1fr 1fr 1fr;
  gap: var(--space-3);
}
.dw-meta > div {
  padding: var(--space-4);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: var(--white-02);
  display: flex; flex-direction: column; gap: 3px;
}
.dw-meta span {
  font-family: var(--font-display); font-size: 9px;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-mute);
}
.dw-meta em {
  font-style: normal;
  font-family: var(--font-display); font-size: 12px;
  color: var(--text); font-weight: 600;
}

/* Withdraw / Swap / Buy */
.dw-input {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: rgba(0,0,0,.3);
  color: var(--text);
  font-family: var(--font-display); font-size: 13px;
  outline: none;
}
.dw-input:focus { border-color: var(--accent); }
.dw-amount {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 4px 10px 4px 14px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: rgba(0,0,0,.3);
}
.dw-amount input {
  flex: 1;
  padding: 10px 0;
  border: 0; background: none; outline: none;
  color: var(--text);
  font-family: var(--font-display); font-size: 18px;
}
.dw-sym {
  font-family: var(--font-display); font-size: 12px;
  color: var(--text-mute); letter-spacing: .1em;
}
.dw-amount .mini {
  padding: 5px 10px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-xs);
  background: transparent;
  color: var(--accent);
  font-family: var(--font-display); font-size: 10px; font-weight: 700;
  letter-spacing: .1em;
  cursor: pointer;
}
.dw-amount .mini:hover { background: var(--accent); color: var(--bg); }

/* Vault tab — direction-toggle chips (MAIN ↔ VAULT). Built to share
   the deposit/withdraw popup visual language: same dark inner fill
   (`rgba(0,0,0,.25)` like `.dw-summary`/`.dw-amount`), same hairline
   border, same muted uppercase mono label + bright mono value
   hierarchy as `.dw-meta`. The `.on` state mirrors `.dw-coin.on` /
   `.dw-chips button.on` — accent-tinted background + accent border.
   Replaces inline-styled chips that left value text un-coloured
   (inheriting the dim button default) and broke parity with the
   deposit/withdraw tabs. */
.dw-vault-chips {
  display: flex; flex-wrap: wrap;
  gap: var(--space-3);
}
.dw-vault-chip {
  flex: 1 1 140px;
  min-width: 140px;
  padding: 12px 14px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: rgba(0,0,0,.25);
  color: var(--text);
  text-align: left;
  cursor: pointer;
  display: flex; flex-direction: column; gap: 4px;
  transition: background .15s ease, border-color .15s ease;
}
.dw-vault-chip:hover {
  border-color: rgba(255,255,255,.18);
}
.dw-vault-chip.on {
  background: var(--accent-10, rgba(52,192,235,.08));
  border-color: rgba(52,192,235,.45);
}
.dw-vault-chip-label {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--text-mute);
}
.dw-vault-chip-value {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: .02em;
}
.dw-vault-chip.on .dw-vault-chip-value {
  color: var(--accent);
}

.dw-summary {
  margin-top: 8px;
  padding: 14px 16px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  background: rgba(0,0,0,.25);
  display: flex; flex-direction: column; gap: var(--space-3);
}
.dw-summary > div {
  display: flex; justify-content: space-between;
  font-family: var(--font-display); font-size: 12px;
}
.dw-summary span { color: var(--text-mute); letter-spacing: .05em; }
.dw-summary em {
  font-style: normal; color: var(--text); font-weight: 600;
}
.dw-summary .total {
  margin-top: 6px; padding-top: 10px;
  border-top: 1px dashed var(--line-soft);
}
.dw-summary .total em { color: var(--accent); font-size: 14px; }

.dw-submit {
  margin-top: 14px;
  width: 100%;
  padding: var(--space-6);
  border: 0; border-radius: var(--radius-md);
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
  color: var(--on-accent);
  font-family: var(--font-ui); font-weight: 700;
  font-size: 14px; letter-spacing: .05em;
  cursor: pointer;
  box-shadow: 0 8px 22px var(--accent-glow);
  transition: box-shadow .2s, filter .15s;
}
.dw-submit:hover:not(:disabled) { filter: brightness(1.04); box-shadow: 0 12px 30px var(--accent-glow); }
.dw-submit:disabled { opacity: .45; filter: grayscale(.35); cursor: not-allowed; }

/* Swap */
.dw-swap { display: flex; flex-direction: column; gap: var(--space-2); position: relative; }
.dw-swap-box {
  padding: 14px 16px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  background: rgba(0,0,0,.25);
}
.dw-swap-box label {
  display: block;
  font-family: var(--font-display); font-size: 10px;
  letter-spacing: .15em; text-transform: uppercase;
  color: var(--text-mute);
  margin-bottom: 8px;
}
.dw-swap-row { display: flex; gap: var(--space-4); align-items: center; }
.dw-swap-row input {
  flex: 1;
  border: 0; background: none; outline: none;
  color: var(--text);
  font-family: var(--font-display); font-size: 20px;
}
.dw-swap-coin {
  display: inline-flex; align-items: center; gap: var(--space-3);
  padding: 8px 12px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: var(--white-04);
  color: var(--text);
  font-family: var(--font-display); font-size: 12px; font-weight: 700;
  cursor: pointer;
}
.dw-swap-bal {
  display: block; margin-top: 6px;
  font-family: var(--font-display); font-size: 10px;
  color: var(--text-mute); letter-spacing: .05em;
}
.dw-swap-arrow {
  align-self: center;
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-soft);
  border-radius: 50%;
  background: #121A2F;
  color: var(--accent);
  font-size: 16px;
  margin: -16px 0;
  z-index: 2;
}

/* Buy */
.dw-buy-providers {
  margin-top: 14px;
  display: flex; flex-direction: column; gap: var(--space-2);
}
.dw-provider {
  display: flex; align-items: center; gap: var(--space-4);
  padding: 12px 14px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: var(--white-02);
  cursor: pointer;
}
.dw-provider input { accent-color: var(--accent); }
.dw-provider span { flex: 1; font-size: 13px; color: var(--text); }
.dw-provider em {
  font-style: normal;
  font-family: var(--font-display); font-size: 11px;
  color: var(--text-mute); letter-spacing: .05em;
}

@media (max-width: 720px) {
  /* Mobile deposit modal: stacked single-column layout so the coin
     picker doesn't fight the deposit pane for 240px of horizontal real
     estate. The coin list becomes a horizontally-scrolling chip strip
     at the top of the body — taps still pick a coin, but it costs zero
     vertical room before you can see the QR + address. */
  .dw-modal {
    width: min(560px, calc(100vw - 24px));
    max-height: calc(100dvh - 24px);
  }
  .dw-body { grid-template-columns: 1fr; }
  .dw-coinlist {
    border-right: 0;
    border-bottom: 1px solid var(--line-soft);
    /* Horizontal chip-strip layout — coin tiles sit side-by-side and
       the user swipes through them. Keeps the picker visible without
       eating ~180px of vertical space above the QR. */
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    max-height: none;
    padding: 12px 16px;
    gap: 8px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .dw-coinlist::-webkit-scrollbar { display: none; }
  .dw-coinlist .dw-sub { display: none; }
  .dw-coin {
    flex: 0 0 auto;
    width: auto;
    margin-bottom: 0;
    padding: 8px 12px;
  }
  .dw-coin .dw-coin-bal { display: none; }
  /* Pane padding shrinks so the modal doesn't feel margin-heavy at narrow widths. */
  .dw-pane { padding: 18px 18px 22px; }
  .dw-tabs { padding: 12px 60px 0 12px; }
  .dw-tabs button { padding: 10px 12px; font-size: 12px; }
  .dw-qr-row { grid-template-columns: 1fr; }
  .dw-qr { margin: 0 auto; }
  .dw-meta { grid-template-columns: 1fr; }
  .dw-modal .modal-close { top: 10px; right: 10px; }
}

/* ================== LIVE STATS CHART ================== */
.lsw-reset {
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-xs);
  background: var(--white-02);
  color: var(--text-mute);
  cursor: pointer;
  margin-right: 4px;
}
.lsw-reset:hover { color: var(--accent); border-color: var(--accent); }

.lsw-chart {
  margin: 0 0 12px;
  padding: 14px 10px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: rgba(0,0,0,.25);
  min-height: 92px;
  display: flex; align-items: center;
}
.lsw-chart-svg { width: 100%; height: 64px; display: block; }

/* Mobile: collapse 2x2 grid into single column when widget is narrow */
@media (max-width: 460px) {
  .lsw-statgrid { grid-template-columns: 1fr 1fr; }
  .lsw-stat-v  { font-size: 14px; }
  .lsw-stat-k  { font-size: 10px; }
}

/* ================== BRAND LOGO IMG — universal swap ================== */
/* When .logo-mark.logo-mark-img wraps an <img> instead of holding a letter,
   strip the colored-tile chrome (background, clip-path, font-size) so the
   SVG fills the slot edge-to-edge across every surface that uses the class. */
.logo-mark.logo-mark-img,
.brand .logo-mark.logo-mark-img,
.mobile-brand .logo-mark.logo-mark-img,
.topbar .mobile-brand .logo-mark.logo-mark-img,
.auth .a-brand .logo-mark.logo-mark-img,
.ft-brand .logo-mark.logo-mark-img {
  background: transparent !important;
  border-radius: 0 !important;
  clip-path: none !important;
  box-shadow: none !important;
  padding: 0 !important;
  font-size: 0 !important;
  color: transparent !important;
  display: inline-flex !important;
  align-items: center; justify-content: center;
  overflow: visible;
}
.logo-mark.logo-mark-img img {
  width: 100%; height: 100%;
  display: block;
  object-fit: contain;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.35));
}
.ft-brand .logo-mark.logo-mark-img img { filter: drop-shadow(0 0 14px rgba(229,154,53,.35)); }

/* ================== BRAND WORDMARK — responsive sizing (Phase 20) ==================
   logo.png is the horizontal wordmark (~4.8:1). Every surface drives by
   height; width auto-scales so proportions hold across breakpoints. */

/* Topbar wordmark */
.topbar-brand.topbar-brand-img {
  display: inline-flex; align-items: center;
  text-decoration: none; cursor: pointer;
  padding: 0 4px;
  height: 22px; /* -20% (was 28px) per operator feedback */
  flex-shrink: 0;
}

/* Mobile brand — used to be a static <div>; switched to a <button> so
   tapping the logo on mobile navigates back to the home page (was a
   silent no-op before). Strip the default button chrome so the existing
   .logo-mark visual still drives the rendering. */
.mobile-brand {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  color: inherit;
  display: inline-flex;
  align-items: center;
}
.mobile-brand:focus-visible {
  outline: 2px solid var(--accent-40);
  outline-offset: 4px;
  border-radius: 8px;
}

/* Operator feedback — the topbar's small symmetric inset (~12-22px)
   used to leave the wordmark visibly OUTSIDE the .main column's
   content gutter (.main uses `max(var(--main-pad), …)` which is wider
   on big displays). Aligning the topbar's LEFT padding to the same
   formula pulls the wordmark flush with the page content's left edge.
   Right-side padding stays compact so the wallet/balance group keeps
   its current spacing. The `--right-w` subtraction accounts for the
   topbar's grid area being wider than .main (.topbar spans the main +
   right rails). */
.topbar {
  padding-left:
    max(var(--main-pad),
        calc((100% - var(--right-w, 0px) - var(--content-max)) / 2 + var(--main-pad))) !important;
}
@media (max-width: 860px) {
  .topbar { padding-left: 14px !important; }
}
.topbar-brand.topbar-brand-img img {
  height: 100%; width: auto; display: block;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.45));
}
@media (max-width: 1280px) { .topbar-brand.topbar-brand-img { height: 19px; } }
@media (max-width: 1024px) { .topbar-brand.topbar-brand-img { height: 18px; } }
/* Below 860px the topbar switches to mobile-brand (icon mark) — hide wordmark */
@media (max-width: 860px)  { .topbar-brand.topbar-brand-img { display: none; } }

/* Footer wordmark */
.ft-logo-img {
  height: 30px; width: auto; display: block;
  margin-bottom: 4px;
  filter: drop-shadow(0 0 14px rgba(229,154,53,.18));
}
@media (max-width: 768px) { .ft-logo-img { height: 26px; } }
@media (max-width: 480px) { .ft-logo-img { height: 22px; } }

/* Auth modal wordmark */
.auth .a-brand.a-brand-img {
  display: flex; align-items: center;
  margin-bottom: 18px;
}
.auth .a-wordmark-img {
  height: 30px; width: auto; display: block;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,.5));
}
@media (max-width: 600px) { .auth .a-wordmark-img { height: 24px; } }

/* In-game bottom-bar wordmark — Task 35: noticeably larger so the
   SpinArmory brand reads at game-table distance. */
.gp-bb-brand img {
  height: 22px; width: auto; /* -20% (was 28px) per operator feedback */
  display: inline-block; vertical-align: middle;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.55));
}
@media (max-width: 768px) { .gp-bb-brand img { height: 18px; } }
@media (max-width: 480px) { .gp-bb-brand img { height: 15px; } }

/* ================== PROVIDER STRIPE (HOME) — Phase 19 ================== */
/* Operator rebuild — added scroll-snap so cards snap to position when
   the user flicks; matches Stake/Roobet rail behavior. */
.provider-stripe {
  display: flex; gap: var(--space-6);
  overflow-x: auto;
  padding: 4px 2px 16px;
  scroll-behavior: smooth;
  scrollbar-width: none;
  scroll-snap-type: x mandatory;
  scroll-padding-left: 4px;
}
.provider-stripe::-webkit-scrollbar { display: none; }
.provider-stripe > * { scroll-snap-align: start; }
/* Operator feedback — clean monochrome wordmark style (no garish
   coloured discs). Card is a plain dark rounded rectangle with the
   provider's wordmark/logo centred in white/light grey, mirroring
   the reference. Drop a licensed file at /img/providers/<slug>.svg
   (or .png) and the <img> renders in place of the text wordmark. */
.provider-card {
  appearance: none; cursor: pointer;
  flex: 0 0 auto;
  /* Operator feedback — wide-rectangle proportions (≈2.5:1) match the
     reference Providers row: 165×64 — wide enough for full wordmarks,
     short enough that the tile reads as a compact plate, not a card.
     Surface ~30 % darker than the previous --bg-2 (#131316). */
  width: 165px;
  height: 64px;
  padding: 10px 16px;
  background: color-mix(in srgb, var(--bg-2, #131316) 70%, #000 30%);
  border: 1px solid color-mix(in srgb, var(--border-default, rgba(255,255,255,.06)) 70%, transparent 30%);
  border-radius: 12px;
  color: var(--text-primary, #fff);
  display: flex; align-items: center; justify-content: center;
  gap: 0;
  transition: transform .18s ease, border-color .18s ease, background .18s ease;
  position: relative; overflow: hidden;
}
.provider-card:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--provider-accent, var(--accent)) 60%, transparent 40%);
  background: color-mix(in srgb, var(--bg-2) 88%, var(--provider-accent, var(--accent)) 12%);
}
.provider-img {
  /* Operator follow-up — Pragmatic / Backseat / others ship as
     square or tall marks and previously read tiny next to wide
     wordmarks (NoLimit, Evolution). Fix is to make every <img>
     fill the full tile content area (width + height) with
     `object-fit: contain` so the image scales up until it hits
     either dimension, while preserving aspect ratio and centering.
     Result: every logo appears as large as its tile permits,
     regardless of intrinsic shape. The 165×64 tile minus 10×16
     padding leaves ~133×44 of usable space; we set width 100%
     and height 100% so the image consumes all of it. */
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  filter: none;
  transition: filter .2s ease, transform .2s ease;
  user-select: none;
}
.provider-card:hover .provider-img {
  filter: brightness(1.08);
  transform: scale(1.03);
}
/* Genuinely-monochrome wordmarks (gray+alpha PNGs, e.g. Hacksaw,
   BGaming, PushGaming, Relax) need the white-on-dark invert trick
   so they read against the dark chip; no grayscale dim. Apply by
   adding `provider-img-invert` to the <img> in provider-stripe.jsx. */
.provider-img.provider-img-invert {
  filter: brightness(0) invert(1);
}
.provider-card:hover .provider-img.provider-img-invert {
  filter: brightness(0) invert(1);
}
/* Logo boosts — two tiers because different providers ship PNGs with
   very different built-in whitespace. LARGE (1.8×) for heavily-padded
   marks (Pragmatic, Backseat); MID (1.15×) for tightly-cropped marks
   (Relax) that only need a small uplift to match neighbour visual
   weight. Parent .provider-card has overflow:hidden so the scaled
   artwork never spills outside the tile. */
.provider-img.provider-img-large {
  transform: scale(1.8);
  transform-origin: center;
}
.provider-card:hover .provider-img.provider-img-large {
  transform: scale(1.86);
}
.provider-img.provider-img-mid {
  transform: scale(1.15);
  transform-origin: center;
}
.provider-card:hover .provider-img.provider-img-mid {
  transform: scale(1.19);
}
.provider-img-originals {
  /* The SpinArmory favicon stays at full colour — it's our own brand. */
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .55));
  max-width: 56px;
  max-height: 56px;
  min-height: 36px;
}
.provider-wordmark-text {
  font-family: var(--font-display, 'Sora', system-ui, sans-serif);
  font-weight: 800;
  /* Single-line wordmark on the wide card; ellipsis if the brand
     name overflows. */
  font-size: 14px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .82);
  text-align: center;
  line-height: 1.05;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  transition: color .2s ease;
}
.provider-card:hover .provider-wordmark-text { color: #fff; }
.provider-card-originals .provider-wordmark-text { color: var(--accent); }
/* Task #357 — was `.provider-img { max-height: 80%; }` and a 40 px
   originals cap, both of which silently shrunk the brand logos to a
   fraction of the chip. The earlier rule above now governs sizing
   (36 px target) so these overrides are dropped. */
.provider-img-originals { max-width: 44px; max-height: 44px; }

@media (max-width: 768px) {
  .provider-card { width: 138px; height: 56px; padding: 8px 12px; }
  .provider-wordmark-text { font-size: 12px; letter-spacing: .03em; }
  /* Mobile keeps the same fill-the-tile rule; tile gets smaller, so the
     image scales down with it. No explicit max-height needed. */
  .provider-img-originals { max-width: 36px; max-height: 36px; }
}

/* ============================================================
   DUAL BANNER — Casino / Sports header pair, sits between the hero
   carousel and the Originals grid on home. Auto-stacks to one
   column at narrow widths via grid-template-columns: auto-fit
   minmax(300px, 1fr) — no explicit breakpoint required. Each banner
   layers (1) the PNG artwork at z=1, (2) a diagonal black-tinted
   overlay at z=2 anchoring the headline on the left, (3) a halftone
   dot pattern at z=2/70% with a left-to-right mask so the dots fade
   over the artwork, (4) the text content at z=3.
   ============================================================ */
.dual-banner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 14px;
  margin-bottom: 28px;
  position: relative;
}
.dual-banner .banner {
  position: relative;
  /* Operator brief — was a fixed 200px (180 / 160 at narrower breakpoints)
     which left the 1600×615 artwork either letterboxed on tall cells or
     cropped on wide cells. The container now follows the image's native
     aspect ratio (~2.6:1), so the picture fills it perfectly at every
     viewport and the whole composition stays visible. Min/max height
     bounds keep the hero from collapsing on tiny screens or ballooning
     on ultra-wide ones. */
  aspect-ratio: 2.6 / 1;
  min-height: 140px;
  max-height: 280px;
  border-radius: 14px;
  overflow: hidden;
  cursor: pointer;
  isolation: isolate;
  appearance: none;
  border: 0;
  padding: 0;
  margin: 0;
  text-align: left;
  display: block;
  width: 100%;
  transition: transform .2s ease, box-shadow .2s ease;
}
/* Force the content block to honour its own text-align — the parent
   `<button>` defaults to center, which would visually drift the title
   even though the absolute positioning anchors at left:28px. */
.dual-banner .banner-content {
  text-align: left;
}
.dual-banner .banner:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 32px rgba(0, 0, 0, .5);
}
.banner-casino { background: linear-gradient(110deg, #1a1850 0%, #0f0d3a 55%, #0a0830 100%); }
.banner-sports { background: linear-gradient(110deg, #0f2554 0%, #0a1a40 55%, #060f28 100%); }

.banner-art {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
}
.banner-art,
.banner-art picture { width: 100%; height: 100%; display: block; }
.banner-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Was `center right` — pulled the artwork toward the right edge so
     the subject on the left got chopped on narrow viewports. Center
     now that the container's aspect ratio matches the image's native
     ratio; there's effectively no crop, just centering. */
  object-position: center;
  display: block;
  /* Operator follow-up — the supplied PNGs ship with a dark-blue
     contour border baked into the artwork (visible as a frame
     around the central illustration). Zooming the image ~10%
     lets the container's `overflow: hidden` crop that built-in
     border off symmetrically, so the inner illustration fills the
     hero edge-to-edge. Transform-origin stays at center so left /
     right / top / bottom all trim by the same ~5%. */
  transform: scale(1.10);
  transform-origin: center center;
}

/* `.banner-overlay-*` (diagonal black-tint) and `.banner-dots`
   (halftone pattern) were removed per operator request — the
   operator-supplied artwork now reads cleanly, with only the title
   overlay anchored on the left edge. */

.banner-content {
  position: absolute;
  left: 28px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  pointer-events: none;
}
.banner-title {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 800;
  letter-spacing: .04em;
  color: #fff;
  text-shadow: 0 2px 20px rgba(0, 0, 0, .75), 0 0 1px rgba(0, 0, 0, .6);
  line-height: 1;
}
.banner-sub {
  margin-top: 6px;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  color: rgba(255, 255, 255, .80);
  text-shadow: 0 1px 6px rgba(0, 0, 0, .6);
}

@media (max-width: 1300px) {
  /* Height now derived from aspect-ratio — no override needed. Title
     overlay was removed per the prior operator pass; the orphan
     title/sub rules below are kept as no-ops in case any other surface
     (slot detail, marketing) re-introduces .banner-content later. */
  .banner-title { font-size: 26px; }
  .banner-content { left: 22px; }
}
@media (max-width: 720px) {
  .banner-title { font-size: 22px; }
  .banner-content { left: 18px; }
  .banner-sub { font-size: 12px; }
}

/* ================== PROFILE PAGE — Phase 19 ================== */
.profile-page .page-back-row { margin-bottom: 18px; }
.profile-layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: var(--space-9);
  margin-top: 8px;
}
.profile-sidemenu {
  display: flex; flex-direction: column;
  gap: 2px;
  padding: 16px 12px;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  position: sticky; top: 80px;
  align-self: start;
}
.profile-sidemenu-section {
  font-family: var(--font-display); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-mute);
  padding: 8px 12px 4px;
}
.profile-sidemenu-divider {
  height: 1px; background: var(--line-soft);
  margin: 12px 6px;
}
.profile-sidemenu-item {
  position: relative;
  appearance: none; cursor: pointer;
  display: flex; align-items: center; gap: var(--space-4);
  width: 100%; text-align: left;
  padding: 12px 14px;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  font-family: var(--font-ui); font-size: 14px; font-weight: 600;
  color: var(--text-secondary);
  transition: color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard);
}
.profile-sidemenu-item:hover {
  background: var(--white-04);
  color: var(--text-primary);
}
/* Operator rebuild — active state matches the sidebar's nav-item
   pattern (gradient stripe + accent left bar + glow). Continuity. */
.profile-sidemenu-item.on {
  background: linear-gradient(90deg, var(--accent-15), var(--accent-05));
  color: var(--accent);
}
.profile-sidemenu-item.on::before {
  content: '';
  position: absolute; left: 0; top: 8px; bottom: 8px;
  width: 3px;
  background: var(--accent);
  border-radius: 0 var(--radius-xs) var(--radius-xs) 0;
  box-shadow: 0 0 14px var(--accent-glow);
}
.profile-sidemenu-item.on .profile-sidemenu-dot {
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
}
.profile-sidemenu-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--white-10);
  flex-shrink: 0;
}
.profile-sidemenu-logout {
  color: var(--magenta) !important;
}
.profile-sidemenu-logout:hover { background: rgba(255,59,107,.08); }

.profile-pane {
  min-width: 0;
  display: flex; flex-direction: column;
  gap: 18px;
}
/* Migration 027 / Stream 2: .profile-card body deleted — JSX migrated to
   .card (Phase 1 primitive) + .frame.chamfer for the hero card. The
   alias-bridge entry near the bottom of this file stays as a defensive
   net for any straggler markup. */
/* Migration 027 / Stream 2: .profile-section-title was unused after the
   migration to window.SectionHead — deleted. The .profile-overview
   .profile-card:first-child rule is replaced by .profile-hero-card
   below, which is a token-only shim that pairs with .frame.chamfer. */

.profile-hero-card {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--space-4);
  padding: 32px var(--space-7);
  position: relative; isolation: isolate;
}
/* Gradient halo — radial accent glow behind the avatar/name. Pure token
   reference; aligns with the "amber accent rule" treatment used by
   .hero-main on the home page. */
.profile-hero-card::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 0%, var(--accent-10), transparent 60%);
  pointer-events: none; z-index: 0;
}
.profile-hero-card > * { position: relative; z-index: 1; }

/* Small accent-tinted icon used by the Request Statistics expander. */
.profile-stat-icon {
  display: inline-grid; place-items: center;
  width: 24px; height: 24px;
  border-radius: var(--radius-xs);
  background: var(--accent-10);
  color: var(--accent);
  font-size: var(--text-sm);
}
.profile-avatar {
  width: 88px; height: 88px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-display); font-size: 32px; font-weight: 700;
  color: #fff;
  box-shadow: 0 0 0 4px var(--white-04), 0 0 24px rgba(0,0,0,.3);
}
/* Task #210 — uploader variant of the round profile picture. The
   avatar BUTTON is keyboard-focusable, shows a small camera badge in
   the bottom-right corner, and dims/zooms slightly on hover so it
   reads as an interactive surface. The "Remove picture" link sits
   under the email and only renders once a custom picture is set. */
button.profile-avatar.profile-avatar-uploader {
  position: relative;
  appearance: none; border: 0; padding: 0; cursor: pointer;
  overflow: hidden;
  transition: transform var(--t-fast), box-shadow var(--t-fast);
}
button.profile-avatar.profile-avatar-uploader:hover:not(:disabled) {
  transform: scale(1.03);
  box-shadow: 0 0 0 4px var(--accent-15), 0 0 28px rgba(52,192,235,.25);
}
button.profile-avatar.profile-avatar-uploader:disabled { opacity: .65; cursor: progress; }
button.profile-avatar.profile-avatar-uploader:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 4px;
}
.profile-avatar-initial {
  font-family: var(--font-display); font-size: 32px; font-weight: 700;
  line-height: 1;
}
.profile-avatar-cam {
  position: absolute;
  right: 2px; bottom: 2px;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--bg-1);
  border: 2px solid var(--bg-0);
  display: grid; place-items: center;
  font-size: 12px; line-height: 1;
  box-shadow: 0 2px 6px rgba(0,0,0,.4);
}
.profile-avatar-msg {
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-mute);
}
.profile-avatar-msg[data-tone="err"] { color: var(--magenta); }
.profile-avatar-remove {
  appearance: none; cursor: pointer;
  margin-top: 6px;
  background: transparent; border: 0; padding: 4px 8px;
  font-family: var(--font-display); font-size: 11px;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-mute);
}
.profile-avatar-remove:hover { color: var(--magenta); }

/* Task #211 — avatar cropper modal. Sits on top of the standard
   .modal-root / .modal-shell skeleton (so it inherits the heavy-blur
   backdrop, chamfer clip-path and entrance animation). The stage is
   a square with a circular punch-out mask so the user can preview
   exactly what will end up in the round avatar. */
.avatar-cropper-shell {
  padding: 0;
  display: flex; flex-direction: column;
}
.avatar-cropper-head {
  padding: 28px 32px 12px;
  text-align: center;
}
.avatar-cropper-head .kicker {
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: .14em;
  color: var(--accent);
  display: block;
  margin-bottom: 6px;
}
.avatar-cropper-head h3 {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-size: 22px;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.avatar-cropper-sub {
  font-size: 12px;
  color: var(--text-mute);
}
.avatar-cropper-body {
  padding: 8px 32px 20px;
  display: flex; flex-direction: column; align-items: center; gap: 18px;
}
.avatar-cropper-stage {
  position: relative;
  /* Default desktop size. The mobile breakpoint below shrinks this
     to 240px; a ResizeObserver in JSX measures the actual rendered
     width so the crop math always matches what's on screen. */
  width: 280px;
  height: 280px;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: #000;
  box-shadow: inset 0 0 0 1px var(--line);
  cursor: grab;
  touch-action: none;
  user-select: none;
}
.avatar-cropper-stage:active { cursor: grabbing; }
/* Circular mask: fully opaque outside the circle, transparent inside,
   so the underlying image is visible through the punch-out and dimmed
   everywhere else. We use a radial gradient with a hard stop so the
   edge stays crisp at any size. */
.avatar-cropper-mask {
  position: absolute; inset: 0;
  pointer-events: none;
  /* `closest-side` makes 100% map to the inscribed-circle radius
     (half the square's side), so the punch-out fills the stage edge
     to edge regardless of the chosen viewport size. */
  background:
    radial-gradient(circle closest-side at center,
      transparent 0,
      transparent calc(100% - 1px),
      var(--accent) calc(100% - 1px),
      var(--accent) 100%,
      rgba(2, 4, 12, 0.62) 100%);
}
.avatar-cropper-zoom {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  max-width: 280px;
  font-family: var(--font-display);
  color: var(--text-mute);
  font-size: 14px;
}
.avatar-cropper-zoom input[type="range"] {
  flex: 1;
  accent-color: var(--accent);
}
.avatar-cropper-actions {
  padding: 14px 32px 24px;
  display: flex; gap: 10px; justify-content: flex-end;
  border-top: 1px solid var(--line-soft);
}
.avatar-cropper-actions .btn-ghost,
.avatar-cropper-actions .btn-primary {
  min-width: 120px;
}
@media (max-width: 480px) {
  .avatar-cropper-head { padding: 22px 20px 10px; }
  .avatar-cropper-body { padding: 6px 16px 16px; }
  .avatar-cropper-actions { padding: 12px 16px 18px; }
  /* No `!important` — we want JS's ResizeObserver to see the real
     rendered width and feed it into the crop math. The cropper
     component re-clamps and re-centres on viewport changes. */
  .avatar-cropper-stage {
    width: 240px;
    height: 240px;
  }
}
.profile-aff-link {
  font-family: var(--font-display); font-size: 11px;
  letter-spacing: .06em;
  color: var(--accent);
  text-decoration: none;
}
.profile-aff-link:hover { text-decoration: underline; }
.profile-name {
  font-family: var(--font-display); font-size: 22px; font-weight: 700;
  letter-spacing: .04em; color: var(--text);
}
.profile-email {
  font-family: var(--font-display); font-size: 13px;
  color: var(--text-dim);
  display: inline-flex; align-items: center; gap: var(--space-2);
}
/* Verified-checkmark badge. Aligned with the documented design rule that
   "positive = gold" (see styles.css :root --success: var(--accent)). The
   prior green hex was a one-off token violation; gold-on-amber mirrors
   the rest of the system. */
.profile-verified {
  display: inline-grid; place-items: center;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--green-soft); color: var(--green);
  font-size: 11px; font-weight: 700;
}

/* Request Statistics expander. Wrapped in <div className="frame chamfer">
   in profile-page.jsx, so the surface (background/border/radius) is
   provided by the parent. This rule only handles the button reset +
   typography. */
.profile-row-expander {
  appearance: none; cursor: pointer;
  width: 100%;
  padding: 16px 22px;
  background: transparent;
  border: 0; border-radius: 0;
  display: flex; align-items: center; justify-content: space-between;
  font-family: var(--font-display); font-weight: 700; font-size: 15px;
  color: var(--text);
}
.profile-row-expander:hover { background: var(--white-02); }
.profile-stats-body {
  padding: 18px 22px;
  background: var(--white-02);
  border-top: 1px solid var(--line);
}

/* Winnings chart */
/* .profile-winnings { padding: 22px; } — deleted in Stream 2; the
   parent now uses .card which already supplies var(--space-7) padding. */
.profile-winnings-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 12px;
}
.profile-winnings-title {
  font-family: var(--font-display); font-size: 14px; font-weight: 700;
  letter-spacing: .14em; color: var(--text);
}
.profile-winnings-range {
  font-family: var(--font-display); font-size: 11px;
  padding: 4px 10px; border-radius: var(--radius-xs);
  background: var(--white-04);
  color: var(--text-mute);
}
/* Migration 027 follow-up: chart was stretching vertically because the
   SVG had preserveAspectRatio="none". Now the JSX uses meet-fit; the
   CSS locks the aspect ratio so the chart scales cleanly between
   ~320px and ~720px wide and never goes taller than 240px. */
.profile-winnings-svg {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 540 / 220;
  max-height: 240px;
}

/* Migration 027 / Stream 2: .profile-kv-grid + .profile-kv family
   deleted — both AccountDetails and TxInfoModal migrated to
   .data-table inside a .card[data-variant=dense] surface. */

/* KYC embed inside profile pane — strip the inner page-shell back row */
.profile-kyc-wrap .page-back-row { display: none; }
.profile-kyc-wrap .page-shell { padding: 0; }
.profile-kyc-wrap .page-body { padding: 0 !important; }

/* Mobile: collapse sidebar above the pane */
@media (max-width: 860px) {
  .profile-layout { grid-template-columns: 1fr; }
  .profile-sidemenu {
    position: static;
    flex-direction: row;
    overflow-x: auto;
    padding: 8px 10px;
    gap: var(--space-1);
  }
  .profile-sidemenu-section,
  .profile-sidemenu-divider { display: none; }
  .profile-sidemenu-item {
    flex: 0 0 auto;
    padding: 8px 14px;
  }
  .profile-sidemenu-dot { display: none; }
}

/* ================== SLOTS PAGE REDESIGN — Phase 19 ================== */

/* Featured hero banner — customer-supplied artwork at /img/slot-banner.png
   layered under a navy gradient overlay so the image renders at ≤15%
   opacity (matches the home hero treatment).

   Operator request — the previous build animated a marquee-bulb ring
   chasing around the perimeter ("looked like disco"). It's been
   rebuilt as a calm, professional STATIC treatment: a soft ambient
   accent glow behind the title and a thin gradient hairline edge,
   with no rotation or pulsing (see ::before / ::after below). */
.slots-hero-banner {
  appearance: none; cursor: pointer;
  display: block;
  width: 100%;
  text-align: left;
  padding: 32px 38px;
  margin-bottom: 24px;
  /* Operator request (May 2026): show the artwork RAW — no dark overlay
     wash. The banner is just the image, with only the hero text on top
     (the text-shadow below keeps it legible against the artwork instead
     of a full-image scrim). The 2nd layer is the fallback solid, shown
     only if the image fails to load, so an unloaded banner doesn't flash
     empty. */
  background:
    url('/img/slot-banner.webp?v=2') center/cover no-repeat,
    linear-gradient(135deg, #1a0610 0%, #2a0815 50%, #3a0a18 100%);
  border: 0;
  border-radius: var(--radius-lg);
  color: #fff;
  /* Legibility for the text now that the overlay is gone — a shadow on
     the TEXT (inherited by eyebrow/title/sub) rather than a wash over
     the picture. */
  text-shadow: 0 1px 2px rgba(0,0,0,.55), 0 2px 14px rgba(0,0,0,.55);
  position: relative;
  overflow: hidden;
  transition: transform .15s ease, box-shadow .15s ease;
  min-height: 180px;
  isolation: isolate;
}
/* Operator request (May 2026): drop the blue/gold glow + edge effects
   entirely — they fought the new SpinArmory-characters artwork. The
   only hover affordance left is a slight zoom of the whole banner. */
.slots-hero-banner:hover {
  transform: scale(1.015);
}

/* ===== Home / lobby rail scrollbars (operator request, May 2026) =====
   Hide the native horizontal scrollbar on every .scroller rail. Scroll
   is driven by the arrow buttons (scrollBy) + mouse click-drag (the
   delegated pointer handler in continue.jsx adds `.is-dragging`). The
   bar is purely visual clutter under each rail — removing it keeps the
   grab/arrow interaction as the only affordance. Touch swipe + trackpad
   still work natively. */
.scroller {
  scrollbar-width: none;        /* Firefox */
  -ms-overflow-style: none;     /* legacy Edge / IE */
  cursor: grab;
}
.scroller::-webkit-scrollbar {  /* Chrome / Safari / new Edge */
  width: 0;
  height: 0;
  display: none;
}
/* While a click-drag is in progress: show the grabbing cursor, freeze
   text selection, and disable scroll-snap so the rail tracks the pointer
   1:1 instead of snapping mid-drag. The handler removes this class on
   pointerup. */
.scroller.is-dragging {
  cursor: grabbing;
  user-select: none;
  scroll-snap-type: none;
  scroll-behavior: auto;
}
.scroller.is-dragging * { pointer-events: none; }

.slots-hero-eyebrow {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-display); font-size: 11px; font-weight: 700;
  letter-spacing: .14em;
  padding: 6px 12px;
  background: rgba(0,0,0,.28);
  border-radius: var(--radius-xl);
  margin-bottom: 16px;
}
.slots-hero-eyebrow .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
}
.slots-hero-title {
  font-family: var(--font-display);
  font-size: 48px; font-weight: 900;
  line-height: 1; letter-spacing: -.01em;
  margin-bottom: 8px;
  white-space: pre-line;
}
.slots-hero-sub {
  font-family: var(--font-display); font-size: 12px;
  letter-spacing: .12em; opacity: .85;
  text-transform: uppercase;
}
.slots-hero-art {
  position: absolute;
  right: 20px; top: 50%; transform: translateY(-50%);
  width: 240px; height: 240px;
  pointer-events: none;
}
.art-circle {
  position: absolute;
  border-radius: 50%;
  border: 8px solid rgba(255,255,255,.25);
}
.art-circle.a { right: 0; top: 30px; width: 80px; height: 80px; background: var(--accent); border-color: transparent; }
.art-circle.b { right: 60px; top: 90px; width: 100px; height: 100px; background: rgba(0,0,0,.35); }
.art-circle.c { right: 20px; bottom: 20px; width: 70px; height: 70px; background: #fff; }

@media (max-width: 768px) {
  /* Operator: the "Spin" banner artwork was cropped on phones because
     `center/cover` fills the short, wide mobile container and clips the
     wordmark. Switch to `contain` so the WHOLE image is visible; the
     gradient behind fills any letterbox. aspect-ratio lets the banner be
     tall enough that contain renders the art at a usable size, and the
     hero text drops to the bottom so it never sits over the wordmark. */
  .slots-hero-banner {
    padding: 16px 18px;
    min-height: 0;
    aspect-ratio: 16 / 8;
    background:
      url('/img/slot-banner.webp?v=2') center / contain no-repeat,
      linear-gradient(135deg, #1a0610 0%, #2a0815 50%, #3a0a18 100%);
    display: flex; flex-direction: column; justify-content: flex-end;
  }
  .slots-hero-title { font-size: 28px; }
  .slots-hero-art { width: 130px; height: 130px; }
  .art-circle.a { width: 50px; height: 50px; }
  .art-circle.b { width: 60px; height: 60px; }
  .art-circle.c { width: 40px; height: 40px; }
}

/* 12-tab category strip — compact pill style, matches the header pill aesthetic */
.slots-tabs {
  display: flex; gap: var(--space-2);
  overflow-x: auto;
  padding: 2px 2px 18px;
  scrollbar-width: none;
}
.slots-tabs::-webkit-scrollbar { display: none; }
.slots-tab {
  appearance: none; cursor: pointer;
  flex: 0 0 auto;
  padding: 9px 14px;
  background: rgba(255,255,255,.025);
  border: 1px solid var(--white-06);
  border-radius: var(--radius-md);
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-ui); font-size: 12px;
  font-weight: 600; letter-spacing: .02em;
  color: var(--text-dim);
  transition: background .15s ease, color .15s ease, border-color .15s ease;
  white-space: nowrap;
  line-height: 1;
}
.slots-tab:hover { background: rgba(255,255,255,.05); color: var(--text); border-color: var(--white-10); }
.slots-tab.on {
  background: rgba(52,192,235,.12);
  border-color: rgba(52,192,235,.45);
  color: var(--accent);
}
.slots-tab-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: rgba(255,255,255,.15);
}
.slots-tab.on .slots-tab-dot { background: var(--accent); box-shadow: 0 0 5px var(--accent); }

/* Toolbar (Search + Sort + Filter) — clean, header-pill style */
.slots-toolbar {
  display: flex; gap: var(--space-4); align-items: center;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.slots-toolbar .slots-search {
  flex: 1 1 280px; min-width: 200px;
  display: flex; align-items: center; gap: var(--space-3);
  padding: 0 12px;
  height: 38px;
  background: rgba(255,255,255,.025);
  border: 1px solid var(--white-06);
  border-radius: var(--radius-md);
}
.slots-toolbar .slots-search:focus-within {
  border-color: rgba(52,192,235,.45);
  background: var(--white-04);
}
.slots-toolbar .slots-search input {
  flex: 1; min-width: 0;
  background: transparent;
  border: 0; outline: 0;
  color: var(--text);
  font-family: var(--font-ui); font-size: 13px;
}
.slots-toolbar .slots-search input::placeholder { color: var(--text-mute); }

/* Sort + Filter dropdowns — pill buttons matching the header bal-pill */
.slots-dd { position: relative; }
.slots-dd-btn {
  appearance: none; cursor: pointer;
  height: 38px; padding: 0 14px;
  background: rgba(255,255,255,.025);
  border: 1px solid var(--white-06);
  border-radius: var(--radius-md);
  color: var(--text);
  font-family: var(--font-ui); font-size: 12px; font-weight: 600;
  letter-spacing: .02em;
  display: inline-flex; align-items: center; gap: var(--space-3);
  transition: background .15s ease, border-color .15s ease;
  white-space: nowrap;
}
.slots-dd-btn:hover {
  background: rgba(255,255,255,.05);
  border-color: rgba(52,192,235,.35);
}
.slots-dd-caret { font-size: 9px; opacity: .65; }

.slots-dd-menu {
  position: absolute; top: 100%; left: 0; margin-top: 8px;
  min-width: 220px;
  background: #0e1224;
  border: 1px solid rgba(255,255,255,.07);
  border-radius: var(--radius);
  padding: var(--space-2);
  box-shadow: 0 12px 32px rgba(0,0,0,.5);
  z-index: 20;
}
.slots-filter-menu { min-width: 280px; max-height: 460px; overflow-y: auto; }
.slots-dd-item {
  display: flex; align-items: center; gap: var(--space-3);
  appearance: none; cursor: pointer;
  width: 100%; padding: 9px 12px;
  background: transparent; border: 0;
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  font-family: var(--font-ui); font-size: 13px; font-weight: 500;
  text-align: left;
  transition: background .12s ease, color .12s ease;
}
.slots-dd-item:hover { background: var(--white-04); color: var(--text); }
.slots-dd-item.on {
  color: var(--accent);
  background: rgba(52,192,235,.06);
}
.slots-dd-divider { height: 1px; background: var(--white-06); margin: 6px 4px; }
.slots-dd-section {
  font-family: var(--font-display); font-size: 9.5px; letter-spacing: .14em;
  padding: 10px 12px 4px; color: var(--text-mute);
  text-transform: uppercase;
}
.slots-dd-checklist { padding: 2px; max-height: 200px; overflow-y: auto; }
.slots-dd-check {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 7px 10px;
  font-family: var(--font-ui); font-size: 13px;
  color: var(--text-dim);
  cursor: pointer; border-radius: var(--radius-sm);
  transition: background .12s ease, color .12s ease;
}
.slots-dd-check:hover { background: var(--white-04); color: var(--text); }
.slots-dd-check input[type="checkbox"] {
  accent-color: var(--accent);
  cursor: pointer;
}
.slots-dd-toggle { justify-content: space-between; }
.slots-dd-reset { color: var(--text-mute); font-size: 12px; }
.slots-dd-reset:hover { color: var(--magenta); }

/* ================== PROVABLY FAIR MODAL ================== */
.pf-modal {
  width: min(760px, 94vw);
  max-height: 92vh;
  padding: 0;
  background: linear-gradient(180deg, #121A2F, #04060E);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex; flex-direction: column;
}
.pf-head {
  padding: 24px 28px 18px;
  border-bottom: 1px solid var(--line-soft);
  display: flex; align-items: center; gap: var(--space-6);
  background:
    radial-gradient(ellipse at 0% 0%, rgba(167,99,255,.15), transparent 60%),
    radial-gradient(ellipse at 100% 100%, rgba(52,192,235,.08), transparent 60%);
}
.pf-badge {
  width: 44px; height: 44px;
  border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center;
  background: rgba(167,99,255,.15);
  border: 1px solid rgba(167,99,255,.35);
  color: var(--purple);
}
.pf-head h3 {
  font-family: var(--font-display); font-weight: 400;
  font-size: 22px; letter-spacing: -.01em;
  margin: 0 0 2px;
}
.pf-head p {
  margin: 0;
  font-family: var(--font-display); font-size: 11px;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-mute);
}
.pf-tabs {
  display: flex; gap: 2px;
  padding: 0 28px;
  border-bottom: 1px solid var(--line-soft);
}
.pf-tabs button {
  padding: 12px 16px;
  background: none; border: 0;
  color: var(--text-mute);
  font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: .15s;
}
.pf-tabs button:hover { color: var(--text); }
.pf-tabs button.on { color: var(--accent); border-bottom-color: var(--accent); }

.pf-body { padding: 24px 28px; overflow-y: auto; flex: 1; }

.pf-steps {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: var(--space-4); margin-bottom: 20px;
}
.pf-step {
  padding: var(--space-6);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  background: var(--white-02);
  position: relative;
}
.pf-step-num {
  font-family: var(--font-display); font-size: 28px;
  color: var(--purple); line-height: 1;
  margin-bottom: 8px;
}
.pf-step-title {
  font-size: 14px; font-weight: 600;
  color: var(--text); margin-bottom: 6px;
}
.pf-step-body {
  font-size: 12px; color: var(--text-dim); line-height: 1.5;
}

.pf-section { margin-bottom: 22px; }
.pf-section h4 {
  font-family: var(--font-display); font-size: 11px;
  letter-spacing: .15em; text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 10px;
}
.pf-code {
  padding: 12px 14px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: rgba(0,0,0,.4);
  /* STAYS mono — provably-fair seed + HMAC strings; players verify
     these byte-by-byte against a script, so character-grid alignment
     is load-bearing. */
  font-family: var(--font-mono); font-size: 11px;
  color: var(--text);
  word-break: break-all;
  line-height: 1.6;
  display: flex; align-items: center; gap: var(--space-4);
}
.pf-code-label {
  font-family: var(--font-display); font-size: 9px;
  letter-spacing: .15em; text-transform: uppercase;
  color: var(--text-mute);
  flex-shrink: 0;
  min-width: 100px;
}
.pf-code-val { flex: 1; color: var(--accent); }
.pf-code-copy {
  padding: 4px 10px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-xs);
  background: transparent;
  color: var(--text-mute);
  font-family: var(--font-display); font-size: 10px;
  cursor: pointer;
  flex-shrink: 0;
}
.pf-code-copy:hover { color: var(--accent); border-color: var(--accent); }
.pf-code-stack { display: flex; flex-direction: column; gap: var(--space-3); }

.pf-hash-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }

.pf-verify {
  padding: var(--space-7);
  border: 1px solid var(--accent-25);
  border-radius: var(--radius-md);
  background: rgba(52,192,235,.04);
}
.pf-verify-head {
  display: flex; align-items: center; gap: var(--space-3);
  font-family: var(--font-display); font-size: 11px;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 12px;
}
.pf-verify-row {
  display: grid; grid-template-columns: 1fr auto;
  gap: var(--space-4); align-items: center;
}
.pf-verify-row input {
  padding: 10px 12px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: rgba(0,0,0,.4);
  color: var(--text);
  font-family: var(--font-display); font-size: 12px;
  outline: none;
}
.pf-verify-btn {
  padding: 10px 18px;
  border: 0; border-radius: var(--radius-sm);
  background: var(--accent); color: var(--bg);
  font-family: var(--font-sans); font-weight: 700;
  font-size: 12px; letter-spacing: .05em;
  cursor: pointer;
}
.pf-verify-result {
  margin-top: 10px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  font-family: var(--font-display); font-size: 11px;
}
.pf-verify-result.ok { background: var(--accent-10); color: var(--accent); border: 1px solid var(--accent-25); }
.pf-verify-result.bad { background: rgba(255,59,107,.1); color: var(--magenta); border: 1px solid rgba(255,59,107,.25); }

.pf-history {
  display: flex; flex-direction: column; gap: var(--space-1);
  max-height: 260px; overflow-y: auto;
  padding-right: 4px;
}
.pf-history-row {
  display: grid;
  grid-template-columns: 60px 1fr 70px 60px;
  gap: var(--space-4);
  padding: 8px 10px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-xs);
  background: var(--white-02);
  font-family: var(--font-display); font-size: 11px;
  align-items: center;
}
.pf-history-row.head {
  border: 0;
  background: none;
  font-size: 9px;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--text-mute);
  padding-top: 0;
}
.pf-history-row .hash { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-history-row .mult.win { color: var(--accent); }
.pf-history-row .mult.loss { color: var(--magenta); }
.pf-history-row .link {
  color: var(--purple); cursor: pointer; text-decoration: none;
  font-size: 10px;
}
.pf-history-row .link:hover { text-decoration: underline; }

.pf-footer {
  padding: 16px 28px;
  border-top: 1px solid var(--line-soft);
  display: flex; justify-content: space-between; align-items: center;
  font-family: var(--font-display); font-size: 10px;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-mute);
  background: rgba(0,0,0,.3);
}
.pf-footer a { color: var(--accent); text-decoration: none; }
.pf-footer a:hover { text-decoration: underline; }

@media (max-width: 640px) {
  .pf-steps { grid-template-columns: 1fr; }
  .pf-hash-grid { grid-template-columns: 1fr; }
  .pf-history-row { grid-template-columns: 1fr 60px; gap: var(--space-2); font-size: 10px; }
  .pf-history-row .idx, .pf-history-row .link { display: none; }
}

/* =========================================================
   MOBILE DENSITY PASS — shuffle-style compact proportions
   applies at ≤860px (phone + small tablet)
   ========================================================= */
@media (max-width: 860px) {
  /* --- topbar: slim 56px shuffle-standard --- */
  .app, .topbar, .main { min-width: 0 !important; }
  .topbar {
    padding: 0 10px !important;
    height: 56px !important;
    gap: var(--space-3) !important;
    overflow: hidden;
  }
  .mobile-brand {
    display: flex !important;
    flex: 0 0 auto;
  }
  .mobile-brand .logo-mark {
    width: 32px !important; height: 32px !important;
    border-radius: var(--radius-sm) !important;
    font-size: 16px !important;
  }
  /* push auth/balance block to the right; allow shrink */
  .bal-group {
    margin-left: auto !important;
    min-width: 0 !important;
    flex-shrink: 1 !important;
    gap: var(--space-2) !important;
  }
  .tb-login, .tb-signup {
    display: inline-flex !important;
    padding: 7px 12px !important;
    font-size: 11px !important;
    letter-spacing: .08em !important;
  }
  .tb-login { margin-left: auto !important; }
  .bal-btn { padding: 6px 10px !important; font-size: 12px !important; flex-shrink: 0; }
  .bal-val { font-size: 13px !important; }
  /* Wallet button: icon + text on tablet, icon-only on phone */
  .wallet-btn {
    padding: 6px 10px !important;
    font-size: 11px !important;
    letter-spacing: .1em !important;
    flex-shrink: 0;
  }
  .icon-btn { width: 32px !important; height: 32px !important; flex-shrink: 0; }
  .mobile-ham { width: 36px !important; height: 36px !important; flex-shrink: 0; }
  .avatar { width: 32px !important; height: 32px !important; font-size: 13px !important; flex-shrink: 0; }

  /* --- game page shell --- */
  .gp-back-row { margin-bottom: 10px !important; font-size: 11px !important; }
  .gp-back { padding: 6px 10px !important; font-size: 11px !important; }
  .gp-crumb { font-size: 10px !important; letter-spacing: .1em !important; }
  .gp-quickstats { font-size: 10px !important; gap: var(--space-3) !important; flex-wrap: wrap; }

  /* --- game panel density (shuffle.com proportions) --- */
  .gp-shell {
    padding: 0 !important;
    border-radius: var(--radius-md) !important;
    overflow: visible !important;       /* allow sticky bet button to stay in viewport */
    margin-bottom: 8px !important;
  }
  .gp { grid-template-columns: 1fr !important; gap: 0 !important; }
  .gp-canvas {
    padding: 14px 12px !important;
    min-height: 0 !important;
    max-height: none !important;        /* grow vertically to fit game content */
    max-width: 100% !important;
    overflow: hidden !important;        /* prevent horizontal overflow */
    min-width: 0 !important;
  }
  /* Force any inner grid/canvas/svg element to respect canvas width */
  .gp-canvas canvas,
  .gp-canvas svg { max-width: 100% !important; height: auto !important; }
  .gp-canvas > div { max-width: 100% !important; min-width: 0 !important; }
  /* Grid items inside canvas (Keno buttons) must shrink below content size */
  .gp-canvas > div[style*="grid"] { width: 100% !important; }
  .gp-canvas > div[style*="grid"] > * { min-width: 0 !important; min-height: 0 !important; }
  .gp-canvas button { min-width: 0 !important; }
  .gp-panel {
    padding: var(--space-6) !important;
    gap: var(--space-4) !important;
    border-top: 1px solid var(--line-soft);
    padding-bottom: 14px !important;
  }
  /* In-flow BET button — sits naturally below the controls.
     Slightly elevated visually so it stands out as primary CTA. */
  .gp-panel .gp-bet {
    position: static !important;
    width: 100%;
    margin: 6px 0 4px !important;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .35);
  }

  /* SHUFFLE-STYLE SIMPLIFICATION on mobile game pages
     Hide redundant elements (already shown elsewhere) to reduce visual noise: */

  /* Game title + sub already shown in breadcrumb at top — hide them in panel */
  .gp-panel .g-title,
  .gp-panel .g-sub { display: none !important; }

  /* "Your P/L · Seed" mini-stats already implicit in Live Stats / PF modal */
  .gp-quickstats { display: none !important; }

  /* RTP/Min/Max info strip — hide it on mobile (info available via PF link in bottombar) */
  .game-meta-strip { display: none !important; }

  /* PROVABLY FAIR row — already accessible via the bottombar shield button */
  .game-meta-pf { display: none !important; }

  /* Redundant breadcrumb crumb on smallest viewports — keep just BACK button */
  .gp-back-row { gap: var(--space-2) !important; }
  .gp-back-row > div:not(.gp-back) { font-size: 10px !important; opacity: .65; }
  .g-title { font-size: 15px !important; }
  .g-sub { font-size: 10px !important; margin-top: 2px !important; }
  .gp-field label { font-size: 10px !important; letter-spacing: .12em !important; }
  .gp-input {
    padding: 4px 4px 4px 12px !important;
    height: 44px !important;            /* shuffle's 44px input target */
  }
  .gp-input input { font-size: 14px !important; }
  .gp-input .mini { padding: 7px 11px !important; font-size: 10px !important; min-width: 38px; }
  .gp-chips button { padding: 8px 11px !important; font-size: 11px !important; min-height: 36px; }
  .gp-stat {
    padding: 8px 10px !important;
    font-size: 11px !important;
  }
  .gp-stat .k { font-size: 9px !important; letter-spacing: .1em !important; }
  .gp-stat .v { font-size: 12px !important; }
  /* Operator request — Dice stat strip stays 3-wide on mobile so the
     Multiplier / Win Chance / Roll Over row matches the reference
     screenshot. The shared @container rule in styles.css collapses
     this to 1 column under 760px; we override it here AND shrink
     paddings / fonts so all three cells fit a phone-width row. */
  .gp-stat-strip {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    gap: 6px !important;
    padding: 8px !important;
    margin-top: 16px !important;
  }
  .gp-stat-strip .gp-stat {
    padding: 8px 6px !important;
  }
  .gp-stat-strip .gp-stat .k {
    font-size: 9px !important;
    text-transform: none;
    letter-spacing: 0 !important;
  }
  .gp-stat-strip .gp-stat .v,
  .gp-stat-strip .gp-stat-edit input {
    font-size: 13px !important;
    font-weight: 600;
  }
  .gp-stat-strip .gp-stat-suffix { font-size: 12px !important; }
  .gp-row { gap: var(--space-3) !important; }

  /* Auto-play panel: keep grid tight on phones so stop-on-loss/profit never overflows */
  .auto-adjust {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(36px, 56px) auto !important;
    gap: 3px !important;
    padding: 3px !important;
  }
  .auto-adjust button { padding: 6px 4px !important; font-size: 10px !important; }
  .auto-adjust input { padding: var(--space-2) !important; font-size: 11px !important; }
  .auto-pct { font-size: 10px !important; padding-right: 3px !important; }
  .auto-stats { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; padding: var(--space-3) !important; gap: var(--space-1) !important; }
  .auto-stats .k { font-size: 8px !important; }
  .auto-stats .v { font-size: 11px !important; }
  .gp-bet {
    padding: var(--space-6) !important;
    min-height: 48px !important;        /* shuffle standard */
    font-size: 14px !important;
    font-weight: 700 !important;
    letter-spacing: .1em !important;
    border-radius: var(--radius-md) !important;
  }

  /* Hide full RTP/Min/Max rows AND info strip on mobile — info accessible via PF link in bottombar */
  .gp-panel .game-meta-row-a,
  .gp-panel .game-meta-row-b,
  .game-meta-strip { display: none !important; }

  /* --- game bottombar: single compact row, tight density --- */
  .gp-bottombar {
    grid-template-columns: auto 1fr auto !important;
    gap: var(--space-2) !important;
    padding: 6px 8px !important;
    text-align: left !important;
    min-width: 0 !important;
  }
  .gp-bb-left, .gp-bb-right { justify-content: flex-start !important; gap: 2px !important; min-width: 0 !important; }
  .gp-bb-right { justify-content: flex-end !important; }
  .gp-bb-center {
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    font-size: 10px !important;
    color: var(--text-mute) !important;
    min-width: 0 !important;
    overflow: hidden !important;
  }
  .gp-bb-slug { display: none !important; }
  .gp-bb-brand {
    font-size: 9px !important;          /* shrunk from 12-14 */
    letter-spacing: .14em !important;
    white-space: nowrap;
    color: var(--text-dim) !important;
    opacity: .65;
  }
  /* Operator follow-up — the 22px wordmark was OVERSIZED on phones and
     visually collided with the bottom-bar controls (the cramped grid only
     leaves the center column ~100px). Shrink it and cap its width to its
     own column so it can never overlap the icons / REAL-FUN toggle. */
  .gp-bb-brand img {
    height: 14px !important;
    max-width: 100% !important;
    object-fit: contain;
  }
  .gp-bb-icon {
    width: 28px !important; height: 28px !important;
    border-radius: var(--radius-xs) !important;
    flex-shrink: 0;
  }
  .gp-bb-icon svg { width: 13px !important; height: 13px !important; }
  .gp-bb-pf {
    padding: 5px 8px !important;
    font-size: 10px !important;
    letter-spacing: .04em !important;
    flex-shrink: 0;
  }
  .gp-bb-pf span { display: none; }    /* icon + arrow only on narrow */

  /* --- bets feed (below game) --- */
  .bets-feed { margin-top: 14px !important; padding: var(--space-4) !important; border-radius: var(--radius-md) !important; }
  .bf-head { flex-direction: column !important; align-items: stretch !important; gap: var(--space-3) !important; padding-bottom: 6px !important; }
  .bf-head h3 { font-size: 11px !important; letter-spacing: .12em !important; }
  .bf-scope { gap: var(--space-1) !important; flex-wrap: wrap; }
  .bf-scope button { padding: 4px 8px !important; font-size: 10px !important; }
  .bf-chart-head { gap: var(--space-3) !important; flex-wrap: wrap !important; }
  .bf-chart-meta .k { font-size: 9px !important; }
  .bf-chart-meta .v { font-size: 12px !important; }
  .bf-chart { padding: var(--space-3) !important; }
  .bf-chart-svg { height: 60px !important; }
  .bf-sub-tabs button { padding: 6px 10px !important; font-size: 10px !important; }
  .bf-row { grid-template-columns: 1.2fr 1fr auto !important; gap: var(--space-2) !important; font-size: 11px !important; padding: 6px 4px !important; }
  .bf-row .t, .bf-row .bet { display: none !important; }  /* keep: game / player / mult / payout only */

  /* --- modals: centered, edge-padded, header-clear close button ---
     The customer requirement: every popup centered in the middle of the
     device on mobile. We KEEP the .modal-root grid + place-items center
     (no flex-start anchor — that was the bug that pinned modals to the
     top of the viewport regardless of content height). max-height clamps
     so the modal can never grow taller than the viewport, which means
     the header (tab strip / top section) is always inside the visible
     box because the box itself fits on screen. */
  .modal-root {
    padding: var(--space-3) !important;
    /* Restore default centering — explicit since `place-items: center`
       in styles.css can be unintentionally overridden by other mobile
       rules in this stylesheet. */
    align-items: center !important;
    justify-items: center !important;
    /* dvh accounts for mobile browser chrome (URL bar) — the available
       viewport height changes when the chrome hides on scroll. Without
       dvh, modals can briefly extend below the chrome on iOS Safari. */
    place-items: center !important;
  }
  .modal-shell {
    padding: 0 !important;
    max-height: calc(100dvh - 24px) !important;
    /* Fallback for browsers without dvh support — same value, just vh. */
    max-height: calc(100vh - 24px);
    border-radius: var(--radius) !important;
  }
  .modal-body { padding: 0 !important; }
  .modal-close {
    top: 8px !important;
    right: 8px !important;
    width: 32px !important;
    height: 32px !important;
    z-index: 20 !important;
    background: rgba(0, 0, 0, .55) !important;
    backdrop-filter: blur(8px);
    border: 1px solid var(--line-soft) !important;
  }
  /* Ensure tab strips and modal headers don't slide under the close
     button. Triple defense:
       1. margin-right pushes the strip's right edge 56px from modal edge.
       2. max-width caps the strip width at parent-minus-56 so the strip
          can NEVER extend under the close button regardless of how the
          margin rule is interpreted.
       3. padding-right: 0 prevents accidental double-padding from
          stacking with margin (which would just waste tab space). */
  .pf-tabs, .dw-tabs, .a-tabs {
    margin-right: 56px !important;
    max-width: calc(100% - 56px) !important;
    padding-right: 0 !important;
  }
  /* Static (non-scrolling) headers — padding-right is enough. */
  .pf-modal .pf-head { padding-right: 56px !important; }
  .vip-hero, .pm-shuffle-hero, .game-modal .g-body { padding-right: 56px !important; }
  /* Game modal: art image at top, close button overlays it — looks fine */

  /* game modal */
  .game-modal .g-art { height: 160px !important; }
  .game-modal .g-body { padding: 16px 14px !important; gap: var(--space-4) !important; }
  .game-modal h2 { font-size: 22px !important; margin: 2px 0 !important; }
  .game-modal .g-provider { font-size: 11px !important; }
  .game-modal .g-desc { font-size: 12px !important; line-height: 1.5 !important; }
  .game-modal .g-stats { padding: var(--space-4) !important; gap: var(--space-2) !important; }
  .game-modal .g-stat .k { font-size: 9px !important; }
  .game-modal .g-stat .v { font-size: 13px !important; }
  .game-modal .g-ctas button { font-size: 12px !important; padding: 11px 14px !important; }
  .game-modal .g-meta { font-size: 10px !important; gap: var(--space-4) !important; }

  /* auth modal — single clean column on phones (artwork hidden,
     form full-width with comfortable padding; NOT the old cramped
     16px). Field/button sizing stays generous so taps are easy. */
  .auth { grid-template-columns: 1fr !important; min-height: 0 !important; }
  .auth .a-side { display: none !important; }
  .auth .a-form { padding: 28px 22px !important; gap: 16px !important; min-height: 0 !important; }
  .auth .a-title { font-size: 23px !important; }
  .auth .a-sub { font-size: 13px !important; }
  .auth .field input,
  .auth .a-code-input { padding: 13px 14px !important; font-size: 15px !important; }
  .auth .a-submit { padding: 15px 18px !important; font-size: 15px !important; }
  .auth .a-social button { height: 46px !important; }

  /* vip modal */
  .vip-hero { padding: 20px 16px !important; }
  .vip-hero h1 { font-size: 28px !important; }
  .vip-hero p { font-size: 12px !important; }
  .vip-status { flex-wrap: wrap !important; gap: var(--space-4) !important; padding: var(--space-5) !important; }
  .tier-rail { grid-template-columns: repeat(2, 1fr) !important; gap: var(--space-3) !important; }
  .tier-card { padding: var(--space-4) !important; }
  .tc-name { font-size: 13px !important; }
  .tc-rake { font-size: 10px !important; }
  .tc-req { font-size: 9px !important; }
  .bonus-row { grid-template-columns: repeat(2, 1fr) !important; gap: var(--space-3) !important; }
  .bonus-card { padding: var(--space-4) !important; }
  .b-value { font-size: 18px !important; }
  .perks-grid { grid-template-columns: 1fr !important; gap: var(--space-3) !important; }
  .perk { padding: var(--space-5) !important; }
  .perk h4 { font-size: 13px !important; }
  .perk p { font-size: 11px !important; }
  .vip-section { padding: var(--space-7) !important; }
  .vip-section-head h2 { font-size: 18px !important; }
  .vip-footer { padding: 14px 16px !important; }

  /* player modal */
  .player-modal { padding: var(--space-6) !important; }
  .pm-hero { gap: var(--space-5) !important; }
  .pm-avatar { width: 56px !important; height: 56px !important; font-size: 22px !important; }
  .pm-name { font-size: 18px !important; }
  .pm-meta { font-size: 10px !important; gap: var(--space-2) !important; flex-wrap: wrap; }
  .pm-actions { flex-direction: row !important; gap: var(--space-2) !important; flex-wrap: wrap !important; }
  .pm-ghost, .pm-primary { padding: 7px 10px !important; font-size: 10px !important; }
  .pm-stats { grid-template-columns: repeat(2, 1fr) !important; gap: var(--space-3) !important; }
  .pm-stat { padding: var(--space-4) !important; }
  .pm-stat .k { font-size: 9px !important; }
  .pm-stat .v { font-size: 14px !important; }
  .pm-section { margin-top: 10px !important; }
  .pm-section h4 { font-size: 11px !important; }
  .pm-row { font-size: 11px !important; padding: 6px 0 !important; }
  .pm-tip h4 { font-size: 11px !important; }
  .pm-tip-row { gap: var(--space-2) !important; }
  .pm-tip-row input, .pm-tip-row select { padding: var(--space-3) !important; font-size: 13px !important; }
  .tip-send { padding: 9px 12px !important; font-size: 10px !important; }
  .pm-tip-quick button { padding: 6px 10px !important; font-size: 11px !important; }

  /* deposit modal — leave room at top-right for close button.
     `padding-right` intentionally NOT set here so the canonical
     `padding-right: 56px !important` rule above (covering .pf-tabs,
     .dw-tabs, .a-tabs) wins and stays the single source of truth for
     close-button safe space across modals. */
  .dw-modal { max-width: 100% !important; }
  .dw-tabs {
    flex-wrap: nowrap !important;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .dw-tabs::-webkit-scrollbar { display: none; }
  .dw-tabs button { padding: 10px 12px !important; font-size: 11px !important; white-space: nowrap; flex-shrink: 0; }
  .dw-body { grid-template-columns: 1fr !important; }
  .dw-coinlist { max-height: 180px; overflow-y: auto; padding: var(--space-4) !important; }
  .dw-coin { padding: var(--space-3) !important; }
  .dw-coin-sym { width: 28px !important; height: 28px !important; }
  .dw-coin-name { font-size: 12px !important; }
  .dw-pane { padding: var(--space-6) !important; }
  .dw-title { font-size: 15px !important; }
  .dw-qr-row { flex-direction: column !important; gap: var(--space-6) !important; }
  .dw-qr { width: 150px !important; height: 150px !important; align-self: center; }
  .dw-addr { font-size: 11px !important; }
  .dw-chips button { padding: 6px 10px !important; font-size: 11px !important; }
  .dw-submit { padding: var(--space-5) !important; font-size: 12px !important; }

  /* provably fair modal */
  .pf-modal .pf-head {
    padding: 12px 14px !important;
    gap: var(--space-4) !important;
    align-items: flex-start !important;
  }
  .pf-modal .pf-head h3 { font-size: 15px !important; line-height: 1.2 !important; }
  .pf-modal .pf-head p {
    font-size: 10px !important;
    line-height: 1.4 !important;
    margin: 4px 0 0 !important;
    letter-spacing: .08em !important;
    max-width: 100% !important;
  }
  .pf-modal .pf-badge { width: 36px !important; height: 36px !important; flex-shrink: 0 !important; }
  .pf-modal .pf-badge svg { width: 18px !important; height: 18px !important; }

  .pf-tabs {
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding: 0 !important;
  }
  .pf-tabs::-webkit-scrollbar { display: none; }
  .pf-tabs button {
    padding: 10px 14px !important;
    font-size: 11px !important;
    white-space: nowrap !important;
    flex-shrink: 0 !important;
  }

  .pf-body { padding: var(--space-5) !important; }
  .pf-section { margin-top: 12px !important; }
  .pf-section:first-child { margin-top: 0 !important; }
  .pf-section h4 { font-size: 10px !important; margin-bottom: 6px !important; }

  /* stacked pf-code: label top, value full-width with wrap, copy button below */
  .pf-code {
    display: flex !important;
    flex-direction: column !important;
    align-items: stretch !important;
    gap: var(--space-1) !important;
    padding: var(--space-4) !important;
    font-size: 10px !important;
  }
  .pf-code-label {
    font-size: 9px !important;
    letter-spacing: .14em !important;
    text-transform: uppercase;
    color: var(--text-mute);
  }
  .pf-code-val {
    font-size: 10px !important;
    word-break: break-all !important;
    overflow-wrap: anywhere !important;
    line-height: 1.4 !important;
    font-family: var(--font-display);
    color: var(--accent);
  }
  .pf-code-copy {
    align-self: flex-end !important;
    padding: 4px 10px !important;
    font-size: 10px !important;
    min-width: 52px;
  }

  .pf-code-stack { gap: var(--space-3) !important; }

  .pf-verify-row {
    display: flex !important;
    flex-direction: column !important;
    gap: var(--space-3) !important;
  }
  .pf-verify-row input {
    font-size: 12px !important;
    padding: var(--space-4) !important;
    width: 100% !important;
  }
  .pf-verify-btn {
    padding: var(--space-4) !important;
    font-size: 11px !important;
    justify-content: center !important;
  }
  .pf-verify-result { font-size: 11px !important; padding: var(--space-4) !important; line-height: 1.5 !important; }

  .pf-steps { gap: var(--space-4) !important; }
  .pf-step { padding: var(--space-5) !important; }
  .pf-step-num { font-size: 18px !important; }
  .pf-step-title { font-size: 13px !important; }
  .pf-step-body { font-size: 11px !important; line-height: 1.5 !important; }

  .pf-history { font-size: 10px !important; }
  .pf-history-row {
    display: grid !important;
    grid-template-columns: 1fr 60px !important;
    gap: var(--space-3) !important;
    padding: 8px 4px !important;
  }
  .pf-history-row .idx, .pf-history-row .link { display: none !important; }
  .pf-history-row .hash { word-break: break-all !important; font-size: 9px !important; }
  .pf-history-row .mult { font-size: 11px !important; text-align: right !important; }
  .pf-history-row.head { display: none !important; }

  .pf-footer {
    padding: 10px 12px !important;
    font-size: 10px !important;
    flex-direction: column !important;
    gap: var(--space-2) !important;
    align-items: flex-start !important;
  }

  /* notifications dropdown — fixed to viewport, on top of everything */
  .notif-dropdown {
    position: fixed !important;
    top: 62px !important;
    left: 10px !important;
    right: 10px !important;
    width: auto !important;
    max-width: none !important;
    max-height: calc(100vh - 140px) !important;
    overflow-y: auto !important;
    z-index: 9999 !important;
    box-shadow: 0 24px 80px rgba(0, 0, 0, .8), 0 0 0 1px rgba(148,163,209,.18) !important;
    -webkit-overflow-scrolling: touch;
  }
  .nd-item { padding: 8px 10px !important; gap: var(--space-3) !important; }
  .nd-t { font-size: 12px !important; }
  .nd-sub { font-size: 11px !important; }

  /* Balance dropdown — viewport-anchored at the top on mobile.
     `:not(.bd-sheet)` lets the bottom-sheet variant (applied via the
     React `isMobile` prop) keep its own bottom: 0 positioning. */
  .bal-dropdown:not(.bd-sheet) {
    position: fixed !important;
    top: 62px !important;
    left: 10px !important;
    right: 10px !important;
    width: auto !important;
    max-width: none !important;
    max-height: calc(100vh - 140px) !important;
    overflow-y: auto !important;
    z-index: 9999 !important;
    box-shadow: 0 24px 80px rgba(0, 0, 0, .8), 0 0 0 1px rgba(148,163,209,.18) !important;
    -webkit-overflow-scrolling: touch;
  }
  /* ensure the bottom-sheet variant paints above the topbar */
  .bal-dropdown.bd-sheet { z-index: 9999 !important; }
  .bd-row { padding: 8px 10px !important; gap: var(--space-3) !important; }
  .bd-coin { width: 28px !important; height: 28px !important; }
  .bd-sym { font-size: 12px !important; }
  .bd-name { font-size: 10px !important; }
  .bd-usd { font-size: 12px !important; }
  .bd-opts label { font-size: 11px !important; }
  .bd-btn { padding: 9px 12px !important; font-size: 10px !important; }

  /* live stats widget — smaller on mobile */
  .lsw { width: calc(100vw - 16px) !important; left: 8px !important; right: 8px !important; max-width: 340px; }
  .lsw-head { padding: 8px 10px !important; }
  .lsw-title { font-size: 10px !important; }
  .lsw-body { padding: var(--space-4) !important; gap: var(--space-3) !important; }
  .lsw-big .v { font-size: 22px !important; }
  .lsw-grid { grid-template-columns: repeat(2, 1fr) !important; gap: var(--space-2) !important; }
  .lsw-grid > div { padding: 6px 8px !important; }
  .lsw-grid .k { font-size: 9px !important; }
  .lsw-grid .v { font-size: 12px !important; }
  .lsw-pill { font-size: 9px !important; padding: 3px 6px !important; }

  /* rewards page tighter */
  .rw-hero { padding: 18px 14px !important; }
  .rw-title { font-size: 26px !important; }
  .rw-sub { font-size: 12px !important; }
  .rw-stats { grid-template-columns: repeat(2, 1fr) !important; gap: var(--space-3) !important; }
  .rw-stat { padding: var(--space-5) !important; }
  .rw-k { font-size: 9px !important; }
  .rw-v { font-size: 20px !important; }
  .rw-tabs { flex-wrap: nowrap !important; overflow-x: auto; padding-bottom: 2px !important; }
  .rw-tabs button { padding: 8px 12px !important; font-size: 11px !important; white-space: nowrap !important; }
  .rw-panel { padding: var(--space-6) !important; }
  .rw-panel-head h3 { font-size: 11px !important; }
  .rw-days { grid-template-columns: repeat(7, 1fr) !important; gap: var(--space-1) !important; }
  .rw-day { padding: 6px 4px !important; }
  .rw-day-n { font-size: 8px !important; }
  .rw-day-reward { font-size: 14px !important; }
  .rw-day-status { font-size: 8px !important; }

  /* vip page tighter */
  .vip-page .vip-hero { padding: 24px 14px !important; }
  .vip-page .vh-title { font-size: 28px !important; }
  .vip-page .vh-sub { font-size: 12px !important; }
  .vip-tier-rail { grid-template-columns: repeat(2, 1fr) !important; gap: var(--space-3) !important; padding: var(--space-5) !important; }
  .vtr-tile { padding: 12px 10px !important; }
  .vtr-name { font-size: 12px !important; }
  .vtr-lvl { font-size: 9px !important; }
  .vip-current, .vip-steps, .vip-perks-sec, .vip-compare, .vip-cta { padding: 18px 14px !important; }
  .vs-head h2 { font-size: 18px !important; }
  .vs-grid { grid-template-columns: 1fr !important; gap: var(--space-4) !important; }
  .vps-grid { grid-template-columns: 1fr !important; gap: var(--space-4) !important; }
  .vc-grid { grid-template-columns: 1fr !important; gap: var(--space-4) !important; }
  .vct { font-size: 10px !important; }
  .vct th, .vct td { padding: var(--space-2) !important; }

  /* slots page tighter */
  .slots-info {
    grid-template-columns: 1fr !important;
    gap: var(--space-6) !important;
    margin-top: 24px !important;
  }
  .si-card {
    padding: var(--space-7) !important;
    min-width: 0 !important;
  }
  .si-card h3 { font-size: 18px !important; margin-bottom: 10px !important; }
  .si-card p, .si-card li { font-size: 12px !important; line-height: 1.5 !important; }
  .si-stats {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    gap: var(--space-2) !important;
    margin-top: 12px !important;
  }
  .si-stats > div { padding: var(--space-3) !important; min-width: 0 !important; }
  .si-stats .k { font-size: 9px !important; }
  .si-stats .v { font-size: 14px !important; }
  .slots-hero { flex-direction: column !important; gap: var(--space-7) !important; padding: 18px 14px !important; }
  .slots-hero h1 { font-size: 24px !important; }
  .sh-stats { grid-template-columns: 1fr !important; gap: var(--space-3) !important; }
  .slots-providers { padding: 18px 14px !important; }
  .sp-grid { grid-template-columns: 1fr 1fr !important; gap: var(--space-3) !important; }
  .sp-card { padding: var(--space-3) !important; }
  .sp-name { font-size: 12px !important; }
  .sp-count { font-size: 10px !important; }
  .slots-grid { grid-template-columns: repeat(2, 1fr) !important; gap: var(--space-4) !important; }
  .slot-card { min-width: 0 !important; }
  .slot-card-title { font-size: 14px !important; }
  .slots-filters { flex-direction: column !important; align-items: stretch !important; gap: var(--space-4) !important; padding: 0 !important; }

  /* footer tighter */
  .site-footer { padding: 20px 14px !important; }
  .ft-grid { grid-template-columns: repeat(2, 1fr) !important; gap: var(--space-7) !important; }
  .ft-grid h5 { font-size: 10px !important; }
  .ft-grid li { font-size: 11px !important; }
  .ft-bottom { font-size: 10px !important; flex-direction: column !important; gap: var(--space-2) !important; align-items: flex-start !important; }

  /* Operator brief — on mobile the Crash chart was eating the entire
     viewport, pushing the Bet button + bet panel below the fold. Cap
     the chart card to ~42vh so the multiplier curve stays prominent
     but the bet controls (Bet / Cashout At / Amount / Manual-Auto)
     are visible without scrolling. The 220px floor keeps the chart
     readable on very short phones (e.g. iPhone SE landscape). The
     stage flex-1 inside still resolves cleanly because the wrapper
     now has a definite max-height. The card-wide `max-height: none
     !important` on the generic .gp-canvas rule above is overridden
     here because `.gp-canvas.crash-canvas` is more specific. */
  .gp-canvas.crash-canvas {
    max-height: 42vh !important;
    min-height: 220px !important;
  }
  /* Tighter padding inside the stage so the canvas itself fills the
     visible area rather than wasting vertical room on chrome. */
  .gp-canvas.crash-canvas.crash-v2-canvas {
    padding: 10px 12px !important;
    gap: 6px !important;
  }
  /* History pill strip stays at a single line and scrolls — it would
     otherwise wrap to two rows on narrow viewports and steal vertical
     room from the now-shorter chart card. */
  .gp-canvas.crash-canvas .crash-v2-history { flex-wrap: nowrap !important; }
}

/* Phone-only (≤480px): Wallet button collapses to icon-only */
@media (max-width: 480px) {
  .wallet-btn {
    width: 36px !important;
    padding: 0 !important;
    justify-content: center !important;
    font-size: 0 !important;
    gap: 0 !important;
  }
  .wallet-btn svg { width: 14px !important; height: 14px !important; }
}

/* ultra-narrow (≤340px): only absolute essentials */
@media (max-width: 340px) {
  .topbar { gap: var(--space-1) !important; padding: 0 6px !important; }
  .wallet-btn { display: none !important; }
  .mobile-brand { display: none !important; }
  .bal-btn { padding: 5px 8px !important; font-size: 11px !important; gap: var(--space-1) !important; }
  .bal-coin { width: 22px !important; height: 22px !important; font-size: 10px !important; }
  .bal-val { font-size: 12px !important; }
  .icon-btn { width: 30px !important; height: 30px !important; }
  .avatar { width: 30px !important; height: 30px !important; font-size: 12px !important; }
  .mobile-ham { width: 32px !important; height: 32px !important; }
  .pm-stats { grid-template-columns: 1fr 1fr !important; }
  .tier-rail { grid-template-columns: 1fr !important; }
  .rw-stats { grid-template-columns: 1fr 1fr !important; }
}

/* ======================================================
   USER MENU DROPDOWN (topbar avatar)
   ====================================================== */
.user-wrap { position: relative; display: inline-block; }
.user-wrap .avatar.on { box-shadow: 0 0 0 2px rgba(61, 126, 255,.55); }
.user-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 280px;
  max-width: calc(100vw - 20px);
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  box-shadow: 0 20px 50px rgba(0,0,0,.55);
  z-index: 300;
  overflow: hidden;
  padding: var(--space-2);
}
.um-head {
  padding: var(--space-5);
  background: linear-gradient(180deg, rgba(61, 126, 255,.12), transparent);
  border-radius: var(--radius-md);
  display: flex; flex-direction: column; gap: var(--space-3); align-items: center;
  position: relative;
}
.um-avatar {
  width: 56px; height: 56px; border-radius: 50%;
  color: #fff; display: grid; place-items: center;
  font-family: var(--font-display); font-size: 22px; font-weight: 800;
  border: 2px solid rgba(255,255,255,.18);
}
.um-name {
  font-family: var(--font-display); font-size: 16px; font-weight: 700;
  color: var(--text);
}
.um-tier {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-display); font-size: 11px; letter-spacing: .05em;
  color: var(--text-dim);
}
.um-prog { width: 100%; margin-top: 4px; }
.um-prog-bar {
  height: 6px; border-radius: var(--radius-2xs); overflow: hidden;
  background: rgba(255,255,255,.08);
}
.um-prog-fill {
  height: 100%; background: linear-gradient(90deg, var(--accent), var(--purple));
  transition: width .3s ease;
}
.um-prog-lbl {
  display: flex; justify-content: space-between;
  font-family: var(--font-display); font-size: 10px; color: var(--text-mute);
  margin-top: 4px;
}
.um-prog-lbl span { color: var(--text-dim); }
.um-divider { height: 1px; background: var(--line-soft); margin: 4px 6px; }
.um-item {
  display: flex; align-items: center; gap: var(--space-4);
  width: 100%;
  padding: 9px 12px;
  background: transparent; border: 0;
  color: var(--text);
  font-family: var(--font-ui); font-size: 13px;
  cursor: pointer;
  border-radius: var(--radius-sm);
  text-align: left;
}
.um-item:hover { background: var(--accent-soft); }
.um-item.um-logout { color: var(--magenta); }
.um-item.um-logout:hover { background: rgba(255,59,107,.10); }
.um-ico {
  width: 22px; height: 22px; display: grid; place-items: center;
  color: var(--text-dim);
}
.um-item:hover .um-ico { color: var(--accent); }
.um-item.um-logout:hover .um-ico { color: var(--magenta); }
.um-label { flex: 1; }

/* ------------------------------------------------------------------
   MOBILE TOPBAR FIXES (<=860px)
   - Topbar is sticky + isolation root so fixed dropdowns always paint
     above it.
   - All 3 dropdowns (notif / balance / user-menu) are position: fixed
     with high z-index so none hide behind the topbar or sidebar.
   - Button sizing tightened so the 5 header controls fit a 320px viewport.
   ------------------------------------------------------------------ */
@media (max-width: 860px) {
  /* topbar becomes a stable stacking-context root */
  .topbar {
    position: sticky !important;
    top: 0;
    z-index: 60;
    isolation: isolate;
  }

  /* user-menu — fixed to viewport like notif-dropdown / bal-dropdown.
     Previously only ≤540px; now matches the mobile breakpoint so
     tablets also get the viewport-anchored behaviour. */
  .user-menu {
    position: fixed !important;
    top: 62px !important;
    right: 8px !important;
    left: auto !important;
    width: calc(100vw - 16px) !important;
    max-width: 340px !important;
    z-index: 9999 !important;
    max-height: calc(100vh - 140px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* header control sizing — prevent overlap on narrow devices */
  .topbar .mobile-ham,
  .topbar .icon-btn {
    width: 32px !important;
    height: 32px !important;
    flex-shrink: 0;
  }
  .topbar .mobile-brand .logo-mark {
    width: 32px !important;
    height: 32px !important;
    font-size: 15px !important;
  }
  .topbar .bal-btn {
    padding: 7px 9px !important;
    font-size: 12px !important;
    gap: var(--space-2) !important;
  }
  .topbar .wallet-btn {
    padding: 8px 10px !important;
    min-width: 40px !important;
  }
  /* Phase 29.1 — icon variant on phones: square 36px pill, the "+"
     SVG fits centered. Override the broader .wallet-btn rule above. */
  .topbar .wallet-btn.wallet-btn-icon {
    padding: 6px 8px !important;
    min-width: 36px !important;
    width: 36px !important;
    height: 36px !important;
  }
  .topbar .avatar {
    width: 32px !important;
    height: 32px !important;
    font-size: 13px !important;
  }
  .topbar .bal-group {
    gap: var(--space-1) !important;
    flex-shrink: 1;
    min-width: 0;
  }
  .topbar {
    padding: 0 10px !important;
    gap: var(--space-2) !important;
  }
}

@media (max-width: 400px) {
  /* Phase 29.1 — keep balance VISIBLE on mobile. The wallet button
     becomes a "+" icon (handled in topbar.jsx via isMobile prop +
     .wallet-btn-icon class), freeing up room for the digits. The
     balance number stays mono + ellipsis-truncated if it's
     extremely long, never display:none. */
  .topbar .bal-btn .bal-val {
    max-width: 14ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .topbar .bal-wallet-pair {
    max-width: calc(100vw - 110px);
    flex: 1 1 auto;
    min-width: 0;
  }
  .topbar .bal-btn-pill {
    flex: 1 1 auto;
    min-width: 0;
  }
}

/* ======================================================
   GENERIC USER PAGE SHELL (settings/vault/token/etc)
   — side spacing is handled by `.main` so every page
   inherits the same horizontal gutter as the home lobby.
   ====================================================== */
.page-shell {
  max-width: 100%;
  margin: 0;
  padding: 4px 0 60px;   /* vertical breathing only; .main supplies inline gutter */
}
.page-back-row {
  display: flex; align-items: center; gap: var(--space-6); margin-bottom: 14px;
}
.page-title {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -.01em;
  margin: 0 0 4px;
}
.page-sub {
  font-family: var(--font-display);
  font-size: 12px;
  color: var(--text-mute);
  letter-spacing: .06em;
  margin-bottom: 22px;
}
.page-body { display: flex; flex-direction: column; gap: var(--space-6); }
.page-tabs {
  display: flex; gap: var(--space-1);
  border-bottom: 1px solid var(--line-soft);
  margin-bottom: 18px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.page-tabs::-webkit-scrollbar { display: none; }
.page-tab {
  appearance: none; border: 0; background: transparent;
  padding: 10px 16px;
  color: var(--text-dim);
  font-family: var(--font-ui); font-size: 13px; font-weight: 600;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.page-tab.on { color: var(--text); border-bottom-color: var(--accent); }
.page-tab:hover { color: var(--text); }

/* ======================================================
   SETTINGS CARDS
   ====================================================== */
.settings-card {
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: var(--space-8);
  display: flex; flex-direction: column; gap: var(--space-6);
}
.sc-head {
  font-family: var(--font-display);
  font-size: 16px; font-weight: 700;
  color: var(--text);
}
.sc-info {
  display: grid; grid-template-columns: 1fr 2fr; gap: var(--space-6);
  background: rgba(0,0,0,.25);
  border-radius: var(--radius-md);
  padding: var(--space-7);
  align-items: center;
}
.sc-user { display: flex; align-items: center; gap: var(--space-6); }
.sc-avatar {
  width: 48px; height: 48px; border-radius: 50%;
  color: #fff; display: grid; place-items: center;
  font-family: var(--font-display); font-size: 18px; font-weight: 800;
}
.sc-user-meta { display: flex; flex-direction: column; gap: var(--space-1); }
.sc-user-name { font-family: var(--font-display); font-size: 18px; font-weight: 700; }
.sc-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }
.sc-stat { min-width: 0; }
.sc-k {
  font-family: var(--font-display); font-size: 10px; letter-spacing: .1em;
  color: var(--text-mute); text-transform: uppercase; margin-bottom: 2px;
}
.sc-v { font-family: var(--font-display); font-size: 14px; font-weight: 700; color: var(--text); }
.sc-field { display: flex; flex-direction: column; gap: var(--space-2); }
.sc-field label {
  font-family: var(--font-display); font-size: 11px; letter-spacing: .1em;
  color: var(--text-mute); text-transform: uppercase;
}
.sc-input {
  display: flex; align-items: center; gap: var(--space-3);
  background: rgba(0,0,0,.35);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  padding: 10px 14px;
}
.sc-input input {
  flex: 1; background: transparent; border: 0; outline: 0;
  color: var(--text); font-family: var(--font-display); font-size: 14px;
  min-width: 0;
}
.sc-verified { color: var(--green); font-weight: 700; }
.sc-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 0;
  border-top: 1px solid var(--white-04);
  gap: var(--space-5);
  font-family: var(--font-ui); font-size: 14px;
}
.sc-row:first-of-type { border-top: 0; }
.sc-btn {
  appearance: none; border: 1px solid var(--line-soft);
  background: var(--white-04);
  color: var(--text);
  font-family: var(--font-ui); font-size: 12px; font-weight: 600;
  padding: 7px 14px; border-radius: var(--radius-sm);
  cursor: pointer;
}
.sc-btn:hover { background: var(--accent-10); border-color: var(--line-2); }
.sc-btn.primary {
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
  color: var(--on-accent);
  border-color: transparent;
  box-shadow: 0 6px 18px var(--accent-glow);
}
.sc-btn.primary:hover { filter: brightness(1.04); }
.sc-btn.ghost { background: transparent; }
.sc-switch { position: relative; display: inline-block; width: 42px; height: 22px; }
.sc-switch input { opacity: 0; width: 0; height: 0; }
.sc-switch span {
  position: absolute; inset: 0;
  background: #33373e; border-radius: var(--radius-xl); transition: .2s; cursor: pointer;
}
.sc-switch span:before {
  content: ''; position: absolute;
  width: 16px; height: 16px; left: 3px; top: 3px;
  background: #fff; border-radius: 50%; transition: .2s;
}
.sc-switch input:checked + span { background: var(--accent); }
.sc-switch input:checked + span:before { transform: translateX(20px); background: #04060E; }
.sc-select, .sc-num {
  appearance: none;
  background: rgba(0,0,0,.35);
  border: 1px solid var(--line-soft);
  color: var(--text);
  font-family: var(--font-display); font-size: 13px;
  padding: 7px 10px; border-radius: var(--radius-sm);
  min-width: 120px;
}
.sc-muted { color: var(--text-mute); font-size: 13px; line-height: 1.5; }
.sc-stepper {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3);
  margin-top: 10px;
}
.sc-stepper .step {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 10px 12px;
  background: rgba(0,0,0,.3);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  font-family: var(--font-ui); font-size: 12px;
  color: var(--text-dim);
}
.sc-stepper .step.done { color: var(--accent); border-color: rgba(52,192,235,.3); }
.sc-stepper .step .n {
  width: 20px; height: 20px; border-radius: 50%;
  background: rgba(255,255,255,.08);
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 700; font-size: 10px;
}
.sc-stepper .step.done .n { background: var(--accent); color: var(--on-accent); }
.sc-session {
  display: flex; align-items: center; gap: var(--space-5);
  padding: var(--space-5); border-radius: var(--radius-md);
  background: rgba(0,0,0,.3);
  border: 1px solid var(--line-soft);
}
.sc-sess-icon {
  color: var(--accent);
  font-size: 16px;
}
.sc-sess-meta { flex: 1; min-width: 0; }
.sc-sess-name { font-family: var(--font-ui); font-weight: 700; }
.sc-sess-sub {
  font-family: var(--font-display); font-size: 11px; color: var(--text-mute);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sc-sess-time { font-family: var(--font-display); font-size: 11px; color: var(--accent); }

@media (max-width: 720px) {
  .sc-info { grid-template-columns: 1fr; }
  .sc-stats { grid-template-columns: repeat(3, 1fr); gap: var(--space-3); }
  .sc-stats .sc-v { font-size: 12px; }
  .sc-stepper { grid-template-columns: 1fr 1fr; }
  .page-title { font-size: 22px; }
}

/* ======================================================
   VAULT / TOKEN / TX / AFFILIATE / WISE / SUPPORT
   ====================================================== */
.vault-summary {
  background: linear-gradient(135deg, rgba(61, 126, 255,.15), rgba(52,192,235,.08));
  border: 1px solid rgba(61, 126, 255,.3);
  border-radius: var(--radius);
  padding: 20px 24px;
  display: flex; justify-content: space-between; align-items: center;
}
.vs-k { font-family: var(--font-display); font-size: 11px; color: var(--text-mute); letter-spacing: .1em; }
.vs-v { font-family: var(--font-display); font-size: 32px; font-weight: 800; color: var(--text); }
.vault-grid { display: flex; flex-direction: column; gap: var(--space-4); }
.vault-row {
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: var(--space-6);
  display: flex; flex-direction: column; gap: var(--space-4);
}
.vr-head { display: flex; align-items: center; gap: var(--space-4); }
.vr-coin {
  width: 32px; height: 32px; border-radius: 50%;
  color: #fff; display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 800;
}
.vr-name { flex: 1; font-family: var(--font-ui); font-weight: 600; }
.vr-bal { font-family: var(--font-display); font-size: 13px; color: var(--text-dim); }
.vr-actions { display: flex; gap: var(--space-3); }
.vr-actions input {
  flex: 1; min-width: 0;
  padding: 8px 12px;
  background: rgba(0,0,0,.35);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-display); font-size: 13px;
}
.vr-locked { font-family: var(--font-display); font-size: 11px; color: var(--accent); }

.token-hero {
  display: flex; align-items: center; gap: var(--space-7);
  background: linear-gradient(135deg, rgba(61, 126, 255,.2), rgba(52,192,235,.08));
  border: 1px solid rgba(61, 126, 255,.3);
  border-radius: var(--radius);
  padding: var(--space-9);
}
.th-icon {
  width: 72px; height: 72px; border-radius: 50%;
  color: #fff; display: grid; place-items: center;
  font-family: var(--font-display); font-size: 34px; font-weight: 800;
}
.th-meta { flex: 1; }
.th-name { font-family: var(--font-display); font-size: 12px; color: var(--text-mute); letter-spacing: .1em; }
.th-price { font-family: var(--font-display); font-size: 28px; font-weight: 800; }
.th-delta { font-family: var(--font-display); font-size: 13px; color: var(--text-dim); margin-left: 8px; }
.token-stats {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4);
}
.ts-cell {
  background: var(--panel); border: 1px solid var(--line-soft);
  border-radius: var(--radius); padding: var(--space-6);
}
.ts-k { font-family: var(--font-display); font-size: 11px; color: var(--text-mute); letter-spacing: .1em; }
.ts-v { font-family: var(--font-display); font-size: 20px; font-weight: 700; margin-top: 4px; }
.ts-sub { font-family: var(--font-display); font-size: 12px; color: var(--text-dim); margin-top: 2px; }

/* ── Transactions page (rebuilt for clarity) ─────────────────────── */
/* Labelled category filter bar with live counts. */
.tx-filters {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-bottom: 16px;
}
.tx-filter {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 12px;
  background: var(--panel); color: var(--text-dim);
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  font-family: var(--font-display); font-size: 12px; font-weight: 600;
  cursor: pointer;
  transition: color var(--dur-base, .15s) ease,
              border-color var(--dur-base, .15s) ease,
              background var(--dur-base, .15s) ease;
}
.tx-filter:hover { color: var(--text); border-color: var(--border-default); }
/* Empty category — shown but dimmed so the filter stays discoverable
   without implying it has rows. Still fully clickable (renders the
   friendly empty state). The `.on` rule below still wins if the user
   selects an empty tab, so the active highlight is never lost. */
.tx-filter.is-empty { opacity: .45; }
.tx-filter.is-empty:hover { opacity: .7; }
.tx-filter.on {
  color: var(--text);
  border-color: var(--accent);
  background: var(--accent-soft, rgba(52,192,235,.12));
  opacity: 1;
}
.tx-filter-dot { font-size: 13px; line-height: 1; }
.tx-filter-cnt {
  min-width: 18px; text-align: center;
  padding: 1px 6px; border-radius: 999px;
  background: var(--white-06); color: var(--text-mute);
  font-size: 11px; font-variant-numeric: tabular-nums;
}
.tx-filter.on .tx-filter-cnt { background: var(--accent); color: var(--accent-ink, #1A1205); }

.tx-wrap { display: flex; flex-direction: column; gap: 8px; }
/* Row: [category badge] [title + sub] [amount + balance]. A 3px
   left accent bar (per category, via .tx-cat-*) makes the type
   readable at a glance without a noisy uppercase code chip. */
.tx-row {
  display: grid;
  grid-template-columns: 40px 1fr auto;
  gap: 14px;
  align-items: center;
  padding: 12px 16px;
  background: var(--panel); border: 1px solid var(--line-soft);
  border-left: 3px solid var(--tx-accent, var(--line-soft));
  border-radius: var(--radius-md);
  font-family: var(--font-display);
}
.tx-badge {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border-radius: 10px;
  background: var(--white-04);
  font-size: 17px; line-height: 1;
}
.tx-main { min-width: 0; }
.tx-title {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 14px; font-weight: 700; color: var(--text);
}
.tx-sub {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 3px;
  font-size: 11.5px; color: var(--text-mute);
}
.tx-sub-cat { color: var(--tx-accent, var(--text-dim)); font-weight: 600; }
.tx-sub-id  { font-variant-numeric: tabular-nums; }
.tx-sub-id::before,
.tx-sub-ts::before { content: '·'; margin-right: 8px; color: var(--text-mute); }
/* On-chain explorer link/chip in a transaction row's sub-line. */
.tx-sub-chain { color: var(--accent, #E5B840); font-weight: 600; text-decoration: none; white-space: nowrap; }
.tx-sub-chain::before { content: '·'; margin-right: 8px; color: var(--text-mute); }
a.tx-sub-chain:hover { text-decoration: underline; }
.tx-right { text-align: right; white-space: nowrap; }
/* Per-category accent — drives the left bar + sub-label + badge tint. */
.tx-cat-deposit   { --tx-accent: #3aa1ff; }
.tx-cat-withdraw  { --tx-accent: var(--magenta); }
.tx-cat-bet       { --tx-accent: var(--accent); }
.tx-cat-win       { --tx-accent: var(--green); }
.tx-cat-bonus     { --tx-accent: #7c5cff; }
.tx-cat-rakeback  { --tx-accent: #f0b429; }
.tx-cat-tip       { --tx-accent: #46c8c8; }
.tx-cat-affiliate { --tx-accent: var(--purple); }
.tx-cat-vault     { --tx-accent: var(--text-dim); }
.tx-cat-adjust    { --tx-accent: #9aa3b2; }
.tx-cat-other     { --tx-accent: var(--text-mute); }
.tx-empty {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 48px 16px; color: var(--text-mute);
  font-family: var(--font-display); font-size: 13px;
}
.tx-empty-glyph {
  width: 44px; height: 44px; display: grid; place-items: center;
  border-radius: 12px; background: var(--white-04);
  font-size: 20px; color: var(--text-dim);
}
/* Withdrawal lifecycle pill — sits inline next to the WITHDRAW badge so
   the player can tell pending payouts from confirmed ones at a glance. */
.tx-wstatus {
  display: inline-block; margin-left: 6px;
  font-size: 9px; font-weight: 700; letter-spacing: .08em;
  padding: 2px 6px; border-radius: 999px;
  text-transform: uppercase; white-space: nowrap;
  background: rgba(255,255,255,.08); color: var(--text-dim);
}
.tx-wstatus-pending,
.tx-wstatus-approved { background: rgba(94,201,143,.18); color: var(--green); }
.tx-wstatus-sent     { background: rgba(94,201,143,.18); color: var(--green); }
.tx-wstatus-finished { background: rgba(94,201,143,.18); color: var(--green); }
.tx-wstatus-failed,
.tx-wstatus-rejected { background: rgba(255,59,107,.18); color: var(--magenta); }
.tx-amt {
  font-size: 14px; font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}
.tx-amt.pos { color: var(--green); }
.tx-amt.neg { color: var(--magenta); }
.tx-bal {
  margin-top: 3px;
  font-size: 11px; color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}

/* ===========================================================
   Transactions tab — production redesign.
   Summary tiles · filter chips · grouped card list · skeleton.
   =========================================================== */

.tx-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}
.tx-summary-tile {
  padding: 12px 14px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md, 10px);
  background: var(--panel);
  display: flex; flex-direction: column; gap: 4px;
}
.tx-summary-label {
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-mute);
  font-family: var(--font-display);
}
.tx-summary-val {
  font-size: 18px; font-weight: 700;
  font-family: var(--font-display);
  color: var(--text);
}
.tx-summary-val.pos { color: var(--accent); }
.tx-summary-val.neg { color: var(--magenta); }

.tx-toolbar {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  justify-content: space-between;
  padding: 10px 0 4px;
}
.tx-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.tx-chip {
  appearance: none; cursor: pointer;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--line-soft);
  background: var(--panel);
  color: var(--text-dim);
  font-family: var(--font-display);
  font-size: 11px; letter-spacing: .04em;
  transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.tx-chip:hover { color: var(--text); border-color: var(--accent-30, rgba(52,192,235,.35)); }
.tx-chip.on {
  background: var(--accent-15, rgba(52,192,235,.14));
  border-color: var(--accent, #34c0eb);
  color: var(--accent, #34c0eb);
}
.tx-search {
  flex: 1; min-width: 220px; max-width: 360px;
  padding: 8px 12px;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  background: var(--panel);
  color: var(--text);
  font-family: var(--font-display); font-size: 12px;
}
.tx-search:focus {
  outline: none;
  border-color: var(--accent, #34c0eb);
}

.tx-list {
  display: flex; flex-direction: column; gap: 18px;
}
.tx-group {
  display: flex; flex-direction: column; gap: 6px;
}
.tx-group-head {
  font-family: var(--font-display); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-mute);
  padding: 4px 2px 6px;
  display: flex; align-items: center; gap: 8px;
  border-bottom: 1px dashed var(--line-soft);
}
.tx-group-count {
  font-size: 9px; padding: 1px 6px; border-radius: 999px;
  background: var(--white-06, rgba(255,255,255,.06));
  color: var(--text-dim);
  letter-spacing: .04em;
}

.tx-card {
  display: grid;
  grid-template-columns: 36px 1fr auto;
  gap: 12px;
  align-items: center;
  width: 100%;
  text-align: left;
  padding: 12px 14px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md, 10px);
  background: var(--panel);
  cursor: pointer;
  appearance: none;
  font-family: inherit;
  color: inherit;
  transition: border-color .15s ease, background .15s ease, transform .15s ease;
}
.tx-card:hover {
  border-color: var(--accent-30, rgba(52,192,235,.4));
  background: var(--white-04, rgba(255,255,255,.04));
}
.tx-card:focus-visible {
  outline: 2px solid var(--accent, #34c0eb);
  outline-offset: 1px;
}

.tx-card-icon {
  display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border-radius: 50%;
  font-size: 18px; font-weight: 700;
  background: var(--white-06, rgba(255,255,255,.06));
  color: var(--text-dim);
}
.tx-card-icon.pos { background: rgba(94,201,143,.12); color: #34c0eb; }
.tx-card-icon.neg { background: rgba(255,59,107,.12); color: var(--magenta); }

.tx-card-body { min-width: 0; }
.tx-card-row1 {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 600; color: var(--text);
}
.tx-card-kind { white-space: nowrap; }
.tx-card-row2 {
  display: flex; flex-wrap: wrap; gap: 6px 12px;
  margin-top: 2px;
  font-family: var(--font-display); font-size: 11px; color: var(--text-mute);
}
.tx-card-ref { color: var(--text-dim); }
.tx-card-ts { color: var(--text-mute); }

.tx-card-right {
  display: flex; flex-direction: column; align-items: flex-end; gap: 2px;
  white-space: nowrap;
  font-family: var(--font-display);
}
.tx-card-amt {
  font-size: 14px; font-weight: 700;
}
.tx-card-amt.pos { color: var(--accent, #34c0eb); }
.tx-card-amt.neg { color: var(--magenta); }
.tx-card-bal {
  font-size: 10px; color: var(--text-mute);
}

.tx-load-more {
  display: flex; justify-content: center; padding: 8px 0;
}

.tx-skeleton { display: flex; flex-direction: column; gap: 8px; }
.tx-skeleton-row {
  height: 64px;
  border-radius: var(--radius-md, 10px);
  background: linear-gradient(90deg,
    rgba(255,255,255,.04) 0%,
    rgba(255,255,255,.08) 50%,
    rgba(255,255,255,.04) 100%);
  background-size: 200% 100%;
  animation: tx-skeleton-shimmer 1.4s ease-in-out infinite;
}
@keyframes tx-skeleton-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@media (max-width: 640px) {
  .tx-card { grid-template-columns: 28px 1fr; row-gap: 6px; }
  .tx-card-icon { width: 28px; height: 28px; font-size: 14px; }
  .tx-card-right { grid-column: 1 / -1; align-items: flex-start; }
}
/* Clickable transaction rows — added when the row maps to a bet (opens
   BetModal) or a wallet transaction (opens TxInfoModal). The amber
   hover treatment matches the home rail / nav-item active state so the
   affordance is consistent across the site. */
.tx-row-clickable {
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease, transform .15s ease;
}
.tx-row-clickable:hover {
  border-color: var(--accent-40);
  background: rgba(52,192,235,.04);
  transform: translateY(-1px);
}
.tx-row-clickable:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (max-width: 720px) {
  .tx-row { grid-template-columns: 34px 1fr auto; gap: 10px; padding: 10px 12px; }
  .tx-badge { width: 30px; height: 30px; font-size: 15px; border-radius: 8px; }
  .tx-title { font-size: 13px; }
  .tx-amt { font-size: 13px; }
  .tx-filter { padding: 6px 10px; font-size: 11px; }
}

.aff-card, .redeem-card {
  background: var(--panel); border: 1px solid var(--line-soft);
  border-radius: var(--radius); padding: var(--space-8);
  display: flex; flex-direction: column; gap: var(--space-5);
}
.aff-link {
  display: flex; gap: var(--space-4);
  background: rgba(0,0,0,.35); border: 1px solid var(--line-soft);
  border-radius: var(--radius-md); padding: 6px 6px 6px 14px;
}
.aff-link input {
  flex: 1; background: transparent; border: 0; outline: 0;
  color: var(--text); font-family: var(--font-display); font-size: 13px; min-width: 0;
}
.aff-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.aff-cell {
  background: var(--panel); border: 1px solid var(--line-soft);
  border-radius: var(--radius); padding: var(--space-7);
}
.aff-cell .sc-k { margin-bottom: 4px; }
.aff-cell .sc-v { font-family: var(--font-display); font-size: 20px; font-weight: 700; }
@media (max-width: 540px) { .aff-grid { grid-template-columns: 1fr; } .token-stats { grid-template-columns: 1fr; } }

/* Shared data-table — replaces the inline-styled `<table style={{...}}>`
   blocks scattered across the Affiliate pages (and elsewhere). Uses
   home tokens so every table on the site renders identically. The
   parent `<div>` typically wraps with the same `.aff-card` container
   to get the rounded outer border. */
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-display);
  font-size: 13px;
}
.data-table thead tr {
  background: var(--white-02);
  color: var(--text-mute);
}
.data-table th {
  text-align: left;
  padding: 12px 18px;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-weight: 700;
}
.data-table th.right, .data-table td.right { text-align: right; }

/* Operator-reported regression — on narrow viewports the admin
   reload / tier / free-spins tables overflowed horizontally with no
   scroll affordance, so the rightmost action column ("Remove
   unclaimed", "Save", etc.) was clipped off-screen and unreachable.
   Wrapping each admin table in `<div className="data-table-scroll">`
   gives the table a horizontal scroll container that lets ops swipe
   to the action column on tablet / phone widths. The min-width
   rule keeps each cell at its content width (otherwise the table
   collapses into the container and the action button is still
   half-hidden). */
.data-table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* Mac hides scrollbars by default until the user starts scrolling, so
     admins on narrow viewports could not tell the table extended past
     the edge. Force a thin, always-visible scrollbar so the affordance
     is obvious regardless of OS / mouse settings. */
  scrollbar-width: thin;
  scrollbar-color: var(--accent-40) transparent;
}
.data-table-scroll::-webkit-scrollbar {
  height: 8px;
}
.data-table-scroll::-webkit-scrollbar-track { background: transparent; }
.data-table-scroll::-webkit-scrollbar-thumb {
  background: rgba(52,192,235,0.35);
  border-radius: 4px;
}
.data-table-scroll::-webkit-scrollbar-thumb:hover {
  background: rgba(52,192,235,0.55);
}
.data-table-scroll > .data-table {
  min-width: max-content;
}
/* Sticky-right action column — kept as a fallback for tables that still
   need it. The Reloads admin grid was rebuilt as a card-list (.reload-list)
   below because Mac scrollbar hiding made the sticky column unreliable
   on narrow viewports — admins kept missing the action. */
.data-table.data-table--sticky-action thead th:last-child,
.data-table.data-table--sticky-action tbody td:last-child {
  position: sticky;
  right: 0;
  z-index: 2;
  background: var(--panel, #14141c);
  box-shadow: -10px 0 16px -10px rgba(0,0,0,0.55);
}
.data-table.data-table--sticky-action thead th:last-child {
  background: var(--white-02, rgba(255,255,255,0.02));
}
.data-table.data-table--sticky-action tbody tr:hover td:last-child {
  background: rgba(52,192,235,.04);
}

/* Reloads admin — card-list layout.
   Each reload renders as a self-contained card. The header row carries
   the user + status pill on the left and the row's action button on the
   right; the body is a 4-column auto-fit grid that reflows to fewer
   columns as the panel narrows. The action button is part of normal
   document flow on the header row, so there's no horizontal scroll and
   no Mac scrollbar dependency — the button is always visible without
   any pointer interaction.
   `auto-fit, minmax(160px, 1fr)` keeps cells comfortably wide on
   desktop (3-4 across) and collapses to single column at ≤ 360 px. */
.reload-list {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.reload-empty {
  padding: 18px;
  text-align: center;
  color: var(--text-mute);
  font-size: 13px;
}
.reload-row {
  border-top: 1px solid var(--line-soft);
  padding: 14px 18px;
  transition: background .15s ease;
}
.reload-row:hover { background: rgba(52,192,235,.04); }
/* Unsaved-edits highlight — mirrors the prior table-row `.highlight`
   class so admins can see at a glance which tier rows have pending
   changes before they hit Save. */
.reload-row.is-dirty {
  background: rgba(52,192,235,.06);
  box-shadow: inset 3px 0 0 var(--accent);
}
.reload-row-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.reload-row-title {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.reload-row-title strong {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
}
.reload-row-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.reload-row-act {
  font-size: var(--text-xs, 11px);
  padding: 6px 12px;
  white-space: nowrap;
}
.reload-row-body {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px 18px;
}
.reload-cell { min-width: 0; }
.reload-cell-k {
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: .14em;
  color: var(--text-mute);
  text-transform: uppercase;
  margin-bottom: 3px;
}
.reload-cell-v {
  font-size: 13px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.reload-cell-reason .reload-cell-v {
  color: var(--text-dim);
  font-size: 12px;
}
@media (max-width: 540px) {
  .reload-row { padding: 12px 14px; }
  .reload-row-body { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px 14px; }
  .reload-row-act { width: 100%; }
  .reload-row-actions { flex: 1 1 100%; }
}

/* ============== Required Wager — sidebar collapsible card ==============
   Mirrors the layout of the operator's Stake reference but uses
   SpinArmory tokens (panel bg, accent gold, line-soft borders).
   Renders only when the player has an active wager_requirements row;
   the React component returns null otherwise so this card is fully
   invisible for the no-bonus default state. */
.wager-section {
  margin-top: 18px;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: 12px;
  overflow: hidden;
}
.wager-head {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 14px;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--text);
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.wager-head:hover { background: rgba(52,192,235,.04); }
.wager-head-title {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--accent);
}
.wager-chev {
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-mute);
  transition: transform .2s ease;
}
.wager-chev.is-open { transform: rotate(180deg); }
.wager-body {
  padding: 4px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-top: 1px solid var(--line-soft);
}
.wager-cap-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-top: 10px;
}
.wager-cap {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .12em;
  color: var(--text-mute);
  text-transform: uppercase;
}
.wager-info {
  width: 16px; height: 16px;
  border-radius: 50%;
  background: rgba(255,255,255,.06);
  color: var(--text-mute);
  font-family: var(--font-display);
  font-size: 10px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: help;
}
.wager-info:hover { background: rgba(52,192,235,.18); color: var(--accent); }
.wager-source {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 800;
  color: var(--text);
  letter-spacing: .01em;
}
.wager-progress-text {
  font-family: var(--font-display);
  font-size: 12px;
  color: var(--text-dim);
}
.wager-progress-done { color: var(--accent); font-weight: 700; }
.wager-progress-sep  { color: var(--text-mute); }
.wager-progress-total{ color: var(--text); font-weight: 600; }
.wager-bar {
  position: relative;
  height: 8px;
  width: 100%;
  border-radius: 999px;
  background: rgba(255,255,255,.06);
  overflow: hidden;
}
.wager-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, #5CCDEF 0%, #34c0eb 60%, #2487AD 100%);
  border-radius: 999px;
  transition: width .35s cubic-bezier(.2,.85,.35,1);
  box-shadow: 0 0 10px rgba(52,192,235,.45);
}
.wager-foot {
  display: flex; align-items: center; justify-content: space-between;
  font-family: var(--font-display);
  font-size: 11px;
  color: var(--text-mute);
  margin-top: 2px;
}
.wager-pct { color: var(--accent); font-weight: 700; }
.wager-remaining { color: var(--text-dim); }
@media (max-width: 420px) {
  .wager-head { padding: 10px 12px; }
  .wager-body { padding: 4px 12px 12px; }
  .wager-source { font-size: 14px; }
}
.data-table tbody tr {
  border-top: 1px solid var(--line-soft);
  transition: background .15s ease;
}
.data-table tbody tr.highlight { background: rgba(52,192,235,.06); }
.data-table tbody tr:hover { background: rgba(52,192,235,.04); }
.data-table td {
  padding: 12px 18px;
  color: var(--text);
}
.data-table td.dim { color: var(--text-dim); }
.data-table td.mute { color: var(--text-mute); }
.data-table td.accent { color: var(--accent); }
.data-table .empty {
  padding: 28px 18px;
  text-align: center;
  color: var(--text-mute);
}

.support-wrap {
  background: var(--panel); border: 1px solid var(--line-soft);
  border-radius: var(--radius); overflow: hidden;
  display: flex; flex-direction: column;
  height: 460px; max-height: 70vh;
}
.support-scroll { flex: 1; overflow-y: auto; padding: var(--space-7); display: flex; flex-direction: column; gap: var(--space-3); }
.sp-msg { display: flex; }
.sp-msg.me { justify-content: flex-end; }
.sp-bubble {
  max-width: 80%;
  padding: 9px 14px;
  border-radius: var(--radius);
  background: var(--white-06);
  color: var(--text);
  font-family: var(--font-ui); font-size: 14px; line-height: 1.4;
}
.sp-msg.me .sp-bubble { background: var(--purple); color: #fff; border-bottom-right-radius: var(--radius-xs); }
.sp-msg.bot .sp-bubble { border-bottom-left-radius: var(--radius-xs); }
.support-input {
  display: flex; gap: var(--space-4); padding: var(--space-5);
  border-top: 1px solid var(--line-soft);
  background: rgba(0,0,0,.3);
}
.support-input input {
  flex: 1; min-width: 0;
  padding: 9px 14px;
  background: rgba(0,0,0,.35);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  color: var(--text); font-family: var(--font-ui); font-size: 14px;
}

.redeem-card input {
  padding: 14px 18px;
  background: rgba(0,0,0,.35);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  color: var(--text);
  font-family: var(--font-display); font-size: 18px; font-weight: 700;
  letter-spacing: .1em;
  text-align: center;
}
.redeem-msg {
  text-align: center; margin-top: 10px;
  font-family: var(--font-display); font-size: 13px; font-weight: 700;
}

/* ======================================================
   RAIN BANNER  — toast, FAB, and send form
   ====================================================== */
.rain-toast-stack {
  position: fixed;
  top: 76px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 400;
  display: flex; flex-direction: column; gap: var(--space-3);
  pointer-events: none;
  width: min(560px, calc(100vw - 24px));
}
.rain-toast {
  pointer-events: auto;
  display: flex; align-items: center; gap: var(--space-5);
  padding: 12px 16px;
  background: rgba(20, 18, 40, .92);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(61, 126, 255,.35);
  border-radius: var(--radius);
  color: #fff;
  box-shadow: 0 12px 32px rgba(0,0,0,.5);
  cursor: pointer;
  animation: rain-slide-in .25s ease-out;
}
.rain-toast.mine {
  border-color: rgba(52,192,235,.55);
  box-shadow: 0 0 32px var(--accent-25);
  background: linear-gradient(135deg, rgba(52,192,235,.14), rgba(20,18,40,.92));
}
.rain-toast:hover { transform: translateY(-2px); transition: transform .15s; }
.rt-icon { font-size: 26px; flex-shrink: 0; }
.rt-body { flex: 1; min-width: 0; }
.rt-title { font-family: var(--font-ui); font-weight: 600; font-size: 14px; }
.rt-title strong { color: var(--accent); font-weight: 800; }
.rt-sub { font-family: var(--font-display); font-size: 11px; color: var(--text-dim); margin-top: 2px; }
.rt-mine { font-family: var(--font-display); font-size: 12px; color: var(--accent); margin-top: 4px; font-weight: 700; }
.rt-verify { margin-top: 6px; }
.rt-verify-btn {
  background: transparent; border: 1px solid var(--border, rgba(255,255,255,.18));
  color: var(--text-dim); border-radius: 6px; padding: 3px 8px;
  font-family: var(--font-display); font-size: 11px; cursor: pointer;
}
.rt-verify-btn:hover { color: var(--text); border-color: var(--accent); }
.rt-verify-body {
  margin-top: 6px; padding: 8px 10px; border-radius: 6px;
  background: rgba(0, 0, 0, .25); border: 1px solid rgba(255, 255, 255, .08);
  font-family: var(--font-display); font-size: 11px; color: var(--text-dim);
  word-break: break-all;
}
.rt-verify-row { padding: 2px 0; }
.rt-verify-row b { color: var(--text); margin-right: 4px; }
.rt-verify-row code { color: var(--text); }
.rt-verify-ok { color: var(--accent, #30d158); font-weight: 700; }
.rt-verify-err { color: var(--danger, #ff453a); font-weight: 700; }
.rt-verify-hint { margin-top: 6px; opacity: .7; }
@keyframes rain-slide-in {
  from { opacity: 0; transform: translate(-50%, -8px) scale(.96); }
  to   { opacity: 1; transform: translate(-50%, 0) scale(1); }
}

/* Phase 26 follow-up — rain-fab removed per customer feedback. The
   bottom-right now only carries the Live Support widget; rain
   interactions still live in the chat-panel rain banner. */
.rain-fab { display: none !important; }

.rain-form {
  position: fixed;
  bottom: 150px;
  right: 16px;
  width: min(320px, calc(100vw - 32px));
  padding: var(--space-7);
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  box-shadow: 0 16px 48px rgba(0,0,0,.5);
  z-index: 301;
  display: flex; flex-direction: column; gap: var(--space-4);
}
@media (min-width: 960px) { .rain-form { bottom: 80px; right: 24px; } }
.rf-head { font-family: var(--font-display); font-size: 16px; font-weight: 700; }
.rf-row { display: flex; flex-direction: column; gap: var(--space-1); }
.rf-row label { font-family: var(--font-display); font-size: 10px; color: var(--text-mute); letter-spacing: .1em; text-transform: uppercase; }
.rf-row input {
  padding: 9px 12px;
  background: rgba(0,0,0,.35);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-display); font-size: 14px;
}
.rf-actions { display: flex; gap: var(--space-3); justify-content: flex-end; margin-top: 4px; }
.rf-err { color: var(--magenta); font-family: var(--font-display); font-size: 11px; }

/* ======================================================
   RAIN POOL — chat-integrated card (sits at top of chat)
   ====================================================== */
.rain-pool-card {
  margin: 4px 2px 12px;
  padding: 10px 12px;
  background: linear-gradient(135deg, rgba(25,20,12,.75), rgba(16,12,6,.85));
  border: 1px solid rgba(255,188,74,.28);
  border-radius: var(--radius-md);
  display: flex; flex-direction: column; gap: var(--space-3);
  color: var(--text);
  font-family: var(--font-display);
  overflow: hidden;
}

/* ── Rain pool card v2 — two-row layout ──────────────────────────────
   Replaced the cramped 4-column `.rpc-row` grid that bunched the
   icon, title, Tip button, and pot amount into a single line. The
   v2 card splits responsibilities: the headline row carries the
   pot amount (right-aligned, large) next to the title, and the
   foot row carries the live countdown next to the Tip CTA. The
   whole card is hidden by `RainPoolHeader` when `pool_amount` is
   zero (no drop is coming, no need for the chat to advertise it).
   --------------------------------------------------------------- */
.rain-pool-card-v2 {
  margin: 4px 2px 12px;
  padding: 12px 14px;
  /* Sticky-header behaviour now lives on the parent .chat-sticky-head
     so every component above the message stream (rain card + current
     announcement + LIVE CHAT label + POST ANNOUNCEMENT button) pins
     as ONE unit. Keeping the card fully opaque so it still covers
     chat rows scrolling underneath when its parent is pinned. */
  background-color: #0e0a04;
  background-image:
    radial-gradient(120% 140% at 100% -20%, rgba(255,188,74,.10), transparent 55%),
    linear-gradient(135deg, rgba(28,22,12,1), rgba(14,10,4,1));
  border: 1px solid rgba(255,188,74,.30);
  border-radius: var(--radius-md);
  display: flex; flex-direction: column; gap: 8px;
  color: var(--text);
  font-family: var(--font-display);
}

/* Operator request — the entire chat header group (rain card +
   announcement + LIVE CHAT label + POST ANNOUNCEMENT button) pins
   to the top of the right-body scroll viewport as ONE block. The
   wrapper carries the sticky positioning + opaque background so all
   children move together; sibling sticky elements with the same
   `top: 0` would otherwise just overlap each other.

   Negative top/horizontal margins span right-body's 14×16 padding so
   the wrapper's background covers edge-to-edge under any scrolling
   content. The matching positive padding keeps the visual layout
   inside the wrapper identical to the un-wrapped version.

   z-index 5 sits above plain message rows but well below modal-root
   (--z-modal) and the topbar (z-index 1000) — strictly local to the
   right-body stacking context. `top: 0` pins at the inner edge of
   right-body's content area (i.e. just under right-body's padding-top
   once the wrapper's negative margin offset is applied) so there is
   no visual jump on scroll start. */
.chat-sticky-head {
  /* Legacy class kept for any cached bundle that still emits it; the
     new architecture lifts the chat header out of the scroll area
     entirely (see .chat-fixed-head below). Treat sticky here as a
     no-op fallback. */
  position: sticky;
  top: 0;
  z-index: 50;
  isolation: isolate;
  background: var(--bg-1);
  margin: -14px -16px 0;
  padding: 14px 16px 4px;
  box-shadow: 0 6px 14px -8px rgba(0, 0, 0, .9);
}
/* Fixed-head architecture (operator follow-up): the chat header now
   lives OUTSIDE the scrolling message stream as a flex sibling of
   `.right-body`. No sticky positioning, no z-index battles — chat
   rows physically can't leak above it because they're in a different
   box. Solid dark fill + a soft border-bottom marks the boundary,
   matching the rest of the right-panel chrome. */
.chat-fixed-head {
  flex: 0 0 auto;
  background: var(--bg-1);
  padding: 14px 16px 4px;
  border-bottom: 1px solid var(--line-soft);
}
/* CurrentAnnouncement renders `.chat-announce-banner` INSIDE
   `.chat-sticky-head`. Since the parent is already sticky+top:0,
   nesting another sticky+top:0 on the banner makes its sticky anchor
   compete with the parent — under scroll, the inner sticky can
   render OUTSIDE the parent's painted background, leaving the
   impression that chat chips are leaking above the header. Inside
   an already-sticky parent we just want plain flow positioning. */
.chat-sticky-head .chat-announce-banner {
  position: static;
  z-index: auto;
}

/* Force every chat row INSIDE the chat right-body into its own
   stacking context strictly BELOW the sticky head (z-index: 50).
   Without this, a chat-msg child that creates a stacking context
   (e.g. `.bet-chip` whose hover applies a transform, or any
   inline-style transform/filter) inherits an `auto` z-index that —
   in some browsers — paints adjacent to siblings rather than being
   contained under a higher-z-index sibling like the sticky head.
   Pinning each row at z-index: 0 with `isolation: isolate` makes
   the layering deterministic: rows always paint below the sticky
   head, regardless of any inner transforms. */
.right-body > .chat-msg {
  position: relative;
  z-index: 0;
  isolation: isolate;
}

/* Admin/mod kebab menu overlap fix. Each chat row is its own
   `isolation: isolate` stacking context pinned at z-index:0, so the
   moderation popover's internal z-index can only beat content WITHIN
   its own row — rows that come later in the DOM still paint on top of
   it, which is why the open Mute/Delete menu was being covered by the
   message bodies below it. While the popover is mounted (menu open),
   lift the WHOLE row's stacking context above its siblings (still
   under the sticky chat head at z-index:50, and the menu opens
   downward so it never reaches the head anyway). `:has()` is already
   used elsewhere in this stylesheet, so it's within the browser
   target. */
.right-body > .chat-msg:has(.chat-mod-pop) {
  z-index: 40;
}

/* Chat rank icon tooltip — small drop-up pill that shows the player's
   tier level label (e.g. "Titanium I") when the user hovers the rank
   logo. Operator follow-up — pre-revision the tip was centered on the
   icon (`left:50%; translateX(-50%)`). Because the rank icon sits at
   the left edge of the chat row, half the tip extended off the row's
   left edge and the visible right half overlapped the username and
   role badge — reading as "crossing into the name + badge". Two
   refinements:
     • Anchor the tip's LEFT edge to the icon (no centering) so it
       extends cleanly to the right within the row's bounds.
     • Drop the rotated diamond arrow — at 6 px the partial borders
       formed a thin line artifact across the tip's text. The pill
       reads cleanly on its own; modern chat tooltips (Discord/Slack
       style) skip the arrow entirely.
   Stronger shadow + outer hairline ring keeps the pill visually
   lifted off whatever sits behind it on a tight chat row. */
.chat-rank-tip-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  line-height: 0;
}
.chat-rank-tip {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  padding: 4px 8px;
  background: #1a1c24;
  border-radius: 5px;
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .94);
  white-space: nowrap;
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, .55),
    0 1px 0 rgba(255, 255, 255, .04) inset,
    0 8px 20px rgba(0, 0, 0, .55);
  opacity: 0;
  pointer-events: none;
  transform: translateY(3px);
  transition: opacity .14s ease, transform .14s ease;
  z-index: 100;
}
.chat-rank-tip-wrap:hover .chat-rank-tip,
.chat-rank-tip-wrap:focus-within .chat-rank-tip {
  opacity: 1;
  transform: translateY(0);
}

.rain-pool-card-v2 .rpc-head {
  display: flex; align-items: center; gap: 8px;
  position: relative; z-index: 1;
}
.rain-pool-card-v2 .rpc-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px;
  border-radius: 7px;
  background: rgba(255,188,74,.14);
  color: #6FD4F2;
  flex-shrink: 0;
}
.rain-pool-card-v2 .rpc-title {
  font-family: var(--font-display);
  font-size: 11px; font-weight: 800; letter-spacing: .14em;
  color: var(--text);
  flex: 1; min-width: 0;
}
.rain-pool-card-v2 .rpc-pot {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-display);
  font-size: 18px; font-weight: 800;
  color: #6FD4F2;
  line-height: 1; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.rain-pool-card-v2 .rpc-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  position: relative; z-index: 1;
}
.rain-pool-card-v2 .rpc-countdown {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  min-width: 0;
}
.rain-pool-card-v2 .rpc-countdown b {
  color: var(--text); font-weight: 700;
}
.rain-pool-card-v2 .rpc-foot-right {
  display: inline-flex; align-items: center; gap: 8px;
  flex-shrink: 0;
}
.rain-pool-card-v2 .rpc-pulse {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent, #34c0eb);
  animation: rpc-pulse 1.4s ease-in-out infinite;
  flex-shrink: 0;
}
@keyframes rpc-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(52,192,235,.55); }
  50%      { box-shadow: 0 0 0 5px rgba(52,192,235,0);   }
}
@media (prefers-reduced-motion: reduce) {
  .rain-pool-card-v2 .rpc-pulse { animation: none; }
}

/* Legacy v1 selectors — kept so any cached bundle still renders. */
.rpc-row {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  gap: var(--space-4);
  align-items: center;
  min-width: 0;
}
.rpc-icon { font-size: 18px; line-height: 1; }
.rpc-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.rpc-title {
  font-family: var(--font-display);
  font-size: 10px; font-weight: 800; letter-spacing: .14em;
  color: var(--text);
}
.rpc-countdown { font-size: 10px; color: var(--text-dim); }
.rpc-tip-btn {
  appearance: none;
  background: rgba(255,188,74,.15);
  border: 1px solid rgba(255,188,74,.4);
  color: #6FD4F2;
  padding: 5px 10px;
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: 10px; font-weight: 800; letter-spacing: .1em;
  cursor: pointer;
  white-space: nowrap;
}
.rain-pool-card-v2 .rpc-tip-btn {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 10px;
}
.rpc-tip-btn:hover:not(:disabled) { background: rgba(255,188,74,.25); }
.rpc-tip-btn:disabled { opacity: .45; cursor: not-allowed; }
.rpc-pot-wrap {
  display: flex; flex-direction: column; align-items: flex-end; gap: 1px;
  min-width: 0;
}
.rpc-last {
  font-size: 10px; color: var(--accent); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  max-width: 110px;
}
.rpc-pot {
  font-family: var(--font-display);
  font-size: 18px; font-weight: 800;
  color: #6FD4F2; line-height: 1; letter-spacing: -.01em;
}

/* Tip popover nested inside the card */
.rpc-tip-popover {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-4);
  background: rgba(0,0,0,.35);
  border: 1px solid rgba(255,188,74,.22);
  border-radius: var(--radius-sm);
}
.rpc-tip-row { display: flex; gap: var(--space-2); align-items: center; }
.rpc-tip-row input {
  flex: 1; min-width: 0;
  padding: 7px 10px;
  background: rgba(0,0,0,.45);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-display); font-size: 13px;
}
.rpc-quick { display: flex; gap: var(--space-1); flex-wrap: wrap; }
.rpc-quick button {
  flex: 1 0 auto;
  padding: 5px 8px;
  appearance: none; border: 1px solid var(--line-soft);
  background: var(--white-04);
  color: var(--text-dim);
  font-family: var(--font-display); font-size: 11px; font-weight: 700;
  border-radius: var(--radius-xs); cursor: pointer;
}
.rpc-quick button:hover { color: #6FD4F2; border-color: rgba(255,188,74,.4); }
.rpc-err { color: var(--magenta); font-family: var(--font-display); font-size: 10px; }
.rpc-hint {
  font-family: var(--font-display); font-size: 10px;
  color: var(--text-mute); line-height: 1.4;
}
.rpc-hint code {
  color: var(--accent); background: rgba(52,192,235,.08);
  padding: 1px 4px; border-radius: var(--radius-2xs); font-size: 10px;
}
.rpc-hint b { color: var(--text); }

/* Mobile: keep card compact inside the chat panel */
@media (max-width: 860px) {
  .rain-pool-card { padding: 8px 10px; margin: 4px 2px 8px; }
  .rain-pool-card-v2 { padding: 10px 12px; }
  .rain-pool-card-v2 .rpc-title { font-size: 10px; }
  .rain-pool-card-v2 .rpc-countdown { font-size: 10px; }
  .rain-pool-card-v2 .rpc-pot { font-size: 16px; }
  .rain-pool-card-v2 .rpc-tip-btn { padding: 4px 8px; font-size: 9px; }
  .rain-pool-card-v2 .rpc-icon { width: 22px; height: 22px; }
  .rpc-row { gap: var(--space-3); }
  .rpc-title { font-size: 9px; }
  .rpc-countdown { font-size: 9px; }
  .rpc-pot { font-size: 15px; }
  .rpc-tip-btn { padding: 4px 8px; font-size: 9px; }
  .rpc-last { font-size: 8px; max-width: 80px; }
}

/* ======================================================
   BET MODAL (shared bet viewer)
   ====================================================== */
.bet-modal { padding: 22px 24px 24px; display: flex; flex-direction: column; gap: var(--space-7); max-width: 520px; }
.bm-head { display: flex; gap: var(--space-5); align-items: flex-start; }
.bm-head-icon {
  width: 40px; height: 40px; border-radius: var(--radius-md);
  display: grid; place-items: center;
  font-family: var(--font-display); font-size: 18px; font-weight: 800;
  flex-shrink: 0;
}
.bm-head-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.bm-head-game { font-family: var(--font-display); font-weight: 800; font-size: 22px; letter-spacing: -.01em; }
.bm-head-id { display: flex; gap: var(--space-3); align-items: center; flex-wrap: wrap; }
.bm-head-id code {
  /* Operator-underlined this in the Rain-Drop modal screenshot: bet
     /round IDs on player-facing surfaces should read in the brand
     font, not the code font. (Hashes still stay mono — see
     .bm-fair-row, .pf-code below.) */
  font-family: var(--font-display); font-size: 11px; color: var(--text-dim);
  max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bm-mini {
  appearance: none; border: 1px solid var(--line-soft);
  background: var(--white-04); color: var(--text-dim);
  padding: 4px 9px; border-radius: var(--radius-xs);
  font-family: var(--font-display); font-size: 10px; font-weight: 700; letter-spacing: .06em;
  cursor: pointer; display: inline-flex; align-items: center; gap: var(--space-1);
  transition: background var(--dur-fast, .12s) var(--ease-standard, ease-out),
              border-color var(--dur-fast, .12s) var(--ease-standard, ease-out),
              transform var(--dur-fast, .12s) var(--ease-standard, ease-out),
              color var(--dur-fast, .12s) var(--ease-standard, ease-out);
}
.bm-mini:hover { background: var(--accent-15); border-color: rgba(61, 126, 255,.4); color: var(--text); }
/* Pressed-state feedback — darker fill + slight scale-down so taps
   feel tactile on touch devices (paired with navigator.vibrate(8)). */
.bm-mini:active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
  transform: scale(.94);
}

.bm-err { color: var(--magenta); font-family: var(--font-display); font-size: 13px; padding: var(--space-5); border-radius: var(--radius-sm); background: rgba(255,59,107,.08); border: 1px solid rgba(255,59,107,.2); }

.bm-placed-by {
  appearance: none; border: 1px solid var(--line-soft);
  background: rgba(0,0,0,.25); color: var(--text);
  padding: 10px 14px; border-radius: var(--radius-md);
  display: flex; gap: var(--space-4); align-items: center; cursor: pointer; text-align: left;
}
.bm-placed-by:hover { background: var(--accent-soft); }
.bm-placed-avatar {
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center; color: #fff;
  font-family: var(--font-display); font-weight: 800; font-size: 14px;
}
.bm-placed-meta { min-width: 0; flex: 1; }
.bm-placed-label {
  font-family: var(--font-display); font-size: 10px; color: var(--text-mute);
  letter-spacing: .12em; text-transform: uppercase;
}
.bm-placed-name {
  /* Operator brief — rank-icon + username should sit visually attached
     (was `--space-2` ~8 px which read as an unintentional separator). */
  display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap;
  font-family: var(--font-display); font-weight: 700; font-size: 14px; margin-top: 2px;
}
.bm-placed-ts { font-family: var(--font-display); font-size: 11px; color: var(--text-dim); font-weight: 400; margin-left: 6px; }

.bm-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
.bm-stat {
  background: rgba(0,0,0,.3); border: 1px solid var(--line-soft);
  border-radius: var(--radius-md); padding: var(--space-5); text-align: center;
  display: flex; flex-direction: column; gap: var(--space-2); min-width: 0;
}
.bm-stat-k { font-family: var(--font-display); font-size: 10px; font-weight: 700; color: var(--text-mute); letter-spacing: .14em; text-transform: uppercase; }
.bm-stat-v {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font-family: var(--font-display); font-size: 15px; font-weight: 800;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  width: 100%;
}

.bm-preview {
  background: rgba(0,0,0,.3);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: var(--space-6);
  min-height: 140px;
  display: flex; align-items: center; justify-content: center;
}
.bm-no-preview { color: var(--text-mute); font-family: var(--font-display); font-size: 12px; }

.bm-play-cta {
  appearance: none; border: 0; background: #6FD4F2;
  color: #0a0700; font-family: var(--font-display); font-weight: 800; font-size: 14px; letter-spacing: .08em;
  padding: var(--space-6); border-radius: var(--radius-md); cursor: pointer;
  box-shadow: 0 8px 24px rgba(255,188,74,.3);
  min-height: 48px;
  transition: transform var(--dur-fast, .12s) var(--ease-standard, ease-out),
              box-shadow var(--dur-fast, .12s) var(--ease-standard, ease-out);
}
.bm-play-cta:hover { transform: translateY(-1px); box-shadow: 0 12px 32px rgba(255,188,74,.45); }
.bm-play-cta:active {
  transform: translateY(1px) scale(.985);
  box-shadow: 0 4px 12px rgba(255,188,74,.35);
}

/* -------- provably fair expander -------- */
.bm-fair {
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.bm-fair-head {
  width: 100%;
  display: flex; align-items: center; gap: var(--space-3);
  padding: 11px 14px;
  background: rgba(0,0,0,.25);
  border: 0; color: var(--text);
  font-family: var(--font-display); font-size: 12px; letter-spacing: .1em;
  cursor: pointer;
  min-height: 44px;
  transition: background var(--dur-fast, .12s) var(--ease-standard, ease-out);
}
.bm-fair-head:hover { background: rgba(0,0,0,.4); }
.bm-fair-head:active { background: var(--accent-soft); color: var(--accent); }
.bm-fair-shield { color: var(--gold, #6FD4F2); }
.bm-fair-title { flex: 1; text-align: left; font-weight: 700; }
.bm-fair-body { padding: 12px 14px; display: flex; flex-direction: column; gap: var(--space-4); }
/* STAYS mono — provably-fair seed + HMAC display. Character-grid
   alignment is load-bearing here so a player verifying the hash byte-
   by-byte against `node verify-bet.js` doesn't trip on glyph drift. */
.bm-fair-row { display: grid; grid-template-columns: 1fr 2fr; gap: var(--space-5); font-family: var(--font-mono); font-size: 11px; }
.bm-fair-k { color: var(--text-mute); letter-spacing: .06em; }
.bm-fair-v {
  color: var(--text);
  background: rgba(0,0,0,.3);
  padding: 6px 8px; border-radius: var(--radius-xs);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0;
}
.bm-fair-v:hover { white-space: normal; word-break: break-all; }
.bm-fair-actions { display: flex; align-items: center; gap: var(--space-4); }

/* Bet modal — mobile pass. Keep nothing inside wider than its column. */
.bet-modal { width: 100%; max-width: 100%; min-width: 0; box-sizing: border-box; overflow-wrap: anywhere; }
.bm-preview { min-width: 0; overflow: hidden; }
.bm-fair { min-width: 0; }
.bm-fair-v { word-break: break-all; }
.bm-play-cta { width: 100%; }
.bm-fair-head { width: 100%; }
.bm-head-id code { flex: 1 1 auto; min-width: 0; }

/* ---- Swipe-down drag handle (touch only) ----
   Hidden by default and on devices that don't support touch / hover —
   the desktop UX is unchanged.  On mobile the handle becomes the
   single, predictable place a player can grab to dismiss the modal,
   keeping the gesture from fighting the inner scroll. */
.bm-drag-handle { display: none; }
@media (hover: none) and (pointer: coarse) {
  .bm-drag-handle {
    display: flex; align-items: center; justify-content: center;
    /* Generous 44px tap zone above the visible 5px pill. */
    height: 24px;
    margin: -10px -12px 0;
    padding: 8px 0;
    touch-action: none;
    cursor: grab;
  }
  .bm-drag-handle:active { cursor: grabbing; }
  .bm-drag-grabber {
    display: block;
    width: 44px; height: 5px; border-radius: 999px;
    background: rgba(255,255,255,.22);
    transition: background var(--dur-fast, .12s) var(--ease-standard, ease-out);
  }
  .bm-drag-handle:active .bm-drag-grabber { background: rgba(255,255,255,.45); }
}

@media (max-width: 540px) {
  .bet-modal { padding: 14px 12px; gap: var(--space-5); }
  .bm-head { gap: var(--space-3); }
  .bm-head-game { font-size: 17px; line-height: 1.15; }
  .bm-head-id { row-gap: var(--space-2); }
  .bm-head-id code { max-width: 100%; min-width: 60px; }
  /* Bigger tap targets on phones — 44×44 minimum per the brief.
     Padding is widened so each button hits the iOS Human Interface
     Guidelines threshold even when the inline label is hidden. */
  .bm-mini {
    min-width: 44px; min-height: 44px;
    padding: 10px 12px; font-size: 11px;
    justify-content: center;
  }
  .bm-mini span { display: none; }
  /* 2 + 1 stat layout: PAYOUT spans the second row. */
  .bm-stats { grid-template-columns: 1fr 1fr; gap: var(--space-2); }
  .bm-stat { padding: 10px 6px; min-width: 0; }
  .bm-stat:nth-child(3) { grid-column: 1 / -1; }
  .bm-stat-v { font-size: 13px; }
  .bm-fair-row { grid-template-columns: 1fr; gap: 4px; }
  .bm-fair-v { white-space: normal; word-break: break-all; }
  .bm-fair-actions { flex-wrap: wrap; }
  /* Sticky bottom Play CTA — keeps the call-to-action in thumb reach
     even when the player has to scroll past tall game previews or the
     provably-fair section. The CTA sticks to the bottom of the
     scrolling .modal-body viewport (its nearest scrolling ancestor).
     A ::before fade renders just above the button so scrolled-past
     content doesn't smash awkwardly into the gold pill. */
  .bm-play-cta {
    position: sticky;
    bottom: 0;
    z-index: 5;
    background: #6FD4F2;
    /* Respect iOS home-indicator safe area. */
    padding-bottom: max(var(--space-6), calc(env(safe-area-inset-bottom, 0px) + 10px));
    box-shadow: 0 -10px 24px rgba(0,0,0,.45), 0 8px 24px rgba(255,188,74,.3);
  }
  .bm-play-cta::before {
    content: ''; position: absolute; left: 0; right: 0; top: -18px; height: 18px;
    background: linear-gradient(180deg, rgba(15,8,28,0), rgba(15,8,28,.6));
    pointer-events: none;
  }
  .bp-mines-grid { max-width: 100%; }
  .bp-mines-cell { font-size: 14px; }
  .bp-keno-cell { font-size: 9px; }
  .bp-plinko-svg { max-height: 140px; }
  .bp-bj-cards { flex-wrap: wrap; justify-content: center; }
  .bp-rl-pocket { width: 48px; height: 48px; font-size: 18px; }
  .bp-rl-pocket-color { font-size: 14px; }
  .bp-slot-art { max-height: 180px; }
  .bp-slot-icon { width: 80px; height: 80px; }
  .bp-wheel-mult { font-size: 30px; }
  .bp-dice-roll { font-size: 30px; }
  .bp-limbo-roll { font-size: 38px; }
  .bp-crash-num { font-size: 38px; }
}

@media (max-width: 380px) {
  .bet-modal { padding: 12px 10px; }
  .bm-head-icon { width: 32px; height: 32px; }
  .bm-head-game { font-size: 15px; }
  .bm-stat-v { font-size: 12px; }
  .bm-keno-cell, .bp-keno-cell { font-size: 8px; }
}

/* -------- game-specific previews -------- */
.bp-dice { width: 100%; display: flex; flex-direction: column; gap: var(--space-3); }
.bp-dice-roll { font-family: var(--font-display); font-size: 38px; font-weight: 800; text-align: center; }
.bp-dice-bar { position: relative; height: 14px; border-radius: var(--radius-sm); background: var(--white-04); overflow: visible; }
.bp-dice-fill-green { position: absolute; top: 0; bottom: 0; background: rgba(52,192,235,.3); border-radius: var(--radius-sm); }
.bp-dice-fill-red   { position: absolute; top: 0; bottom: 0; background: rgba(255,59,107,.3); border-radius: var(--radius-sm); }
.bp-dice-marker     { position: absolute; top: -4px; width: 3px; height: 22px; background: var(--text); border-radius: var(--radius-2xs); transform: translateX(-50%); }
.bp-dice-target     { position: absolute; top: -2px; width: 2px; height: 18px; background: var(--purple); transform: translateX(-50%); }
.bp-dice-axis { display: flex; justify-content: space-between; font-family: var(--font-display); font-size: 10px; color: var(--text-mute); padding: 0 2px; }
.bp-dice-meta { display: flex; justify-content: space-between; font-family: var(--font-display); font-size: 12px; color: var(--text-dim); }

.bp-limbo { text-align: center; width: 100%; }
.bp-limbo-roll { font-family: var(--font-display); font-size: 52px; font-weight: 800; }
.bp-limbo-meta { display: flex; justify-content: space-around; margin-top: 10px; font-family: var(--font-display); font-size: 12px; }
.bp-limbo-meta span { display: block; color: var(--text-mute); font-size: 10px; letter-spacing: .1em; margin-bottom: 2px; }

.bp-keno { display: flex; flex-direction: column; gap: var(--space-4); width: 100%; }
.bp-keno-grid { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 3px; }
.bp-keno-cell {
  aspect-ratio: 1; display: grid; place-items: center;
  background: rgba(255,255,255,.03);
  font-family: var(--font-display); font-size: 10px; color: var(--text-mute);
  border-radius: var(--radius-xs); border: 1px solid var(--line-soft);
}
.bp-keno-cell.pick  { background: var(--accent-15); border-color: var(--purple); color: var(--purple); }
.bp-keno-cell.drawn { background: rgba(255,255,255,.08); border-color: var(--text-mute); color: var(--text-dim); }
.bp-keno-cell.hit   { background: rgba(52,192,235,.2); border-color: var(--accent); color: var(--accent); font-weight: 700; }
.bp-keno-meta { display: flex; justify-content: space-around; font-family: var(--font-display); font-size: 11px; color: var(--text-dim); }
.bp-keno-meta b { color: var(--text); margin-left: 4px; }

.bp-plinko { display: flex; flex-direction: column; gap: var(--space-3); width: 100%; }
.bp-plinko-svg { width: 100%; height: auto; max-height: 180px; }
.bp-plinko-meta { display: flex; justify-content: space-around; font-family: var(--font-display); font-size: 11px; color: var(--text-dim); }
.bp-plinko-meta b { color: var(--text); margin-left: 4px; }

.bp-wheel { display: flex; flex-direction: column; gap: var(--space-4); width: 100%; }
.bp-wheel-result { text-align: center; }
.bp-wheel-mult { font-family: var(--font-display); font-size: 38px; font-weight: 800; }
.bp-wheel-sub { font-family: var(--font-display); font-size: 11px; color: var(--text-mute); display: block; letter-spacing: .08em; }
.bp-wheel-strip { display: flex; gap: 2px; overflow-x: auto; padding-bottom: 4px; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.bp-wheel-strip::-webkit-scrollbar { display: none; }
.bp-wheel-seg {
  flex: 0 0 auto; width: 36px; padding: 6px 0; text-align: center;
  border-radius: var(--radius-xs);
  font-family: var(--font-display); font-size: 10px; font-weight: 700;
  transition: transform .15s;
}
.bp-wheel-seg.on { transform: scale(1.15); box-shadow: 0 4px 14px rgba(0,0,0,.4); }
.bp-wheel-meta { display: flex; justify-content: space-around; font-family: var(--font-display); font-size: 11px; color: var(--text-dim); }
.bp-wheel-meta b { color: var(--text); margin-left: 4px; }

.bp-mines { display: flex; flex-direction: column; gap: var(--space-4); width: 100%; }
.bp-mines-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-1); max-width: 280px; margin: 0 auto; }
.bp-mines-cell {
  aspect-ratio: 1;
  background: rgba(255,255,255,.05);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-xs);
  display: grid; place-items: center;
  font-size: 16px;
}
.bp-mines-cell.gem      { background: var(--accent-15); border-color: var(--accent-40); }
.bp-mines-cell.mine     { background: rgba(255,59,107,.12); border-color: rgba(255,59,107,.35); opacity: .7; }
.bp-mines-cell.bomb-hit { background: rgba(255,59,107,.25); border-color: var(--magenta); box-shadow: 0 0 12px rgba(255,59,107,.5); }
.bp-mines-meta { display: flex; justify-content: space-around; font-family: var(--font-display); font-size: 11px; color: var(--text-dim); }
.bp-mines-meta b { color: var(--text); margin-left: 4px; }

.bp-bj { display: flex; flex-direction: column; gap: var(--space-4); width: 100%; align-items: center; }
.bp-bj-side { display: flex; flex-direction: column; gap: var(--space-1); align-items: center; }
.bp-bj-label { font-family: var(--font-display); font-size: 10px; color: var(--text-mute); letter-spacing: .12em; }
.bp-bj-cards { display: flex; gap: var(--space-1); }
.bp-bj-result { font-family: var(--font-display); font-weight: 800; font-size: 14px; letter-spacing: .08em; margin-top: 4px; }

.bp-crash { text-align: center; width: 100%; }
.bp-crash-num { font-family: var(--font-display); font-size: 52px; font-weight: 800; }
.bp-crash-meta { display: flex; justify-content: space-around; margin-top: 8px; font-family: var(--font-display); font-size: 12px; }
.bp-crash-meta span { display: block; color: var(--text-mute); font-size: 10px; letter-spacing: .1em; margin-bottom: 2px; }

/* -------- Roulette mini-replay -------- */
.bp-roulette { display: flex; flex-direction: column; gap: var(--space-4); width: 100%; }
.bp-rl-result {
  display: flex; align-items: center; gap: var(--space-5);
  justify-content: center;
}
.bp-rl-pocket {
  width: 56px; height: 56px; border-radius: 50%;
  display: grid; place-items: center;
  color: #fff; font-family: var(--font-display); font-weight: 800; font-size: 22px;
  border: 2px solid rgba(255,255,255,.18);
  box-shadow: 0 6px 18px rgba(0,0,0,.45), inset 0 0 0 2px rgba(0,0,0,.25);
  flex-shrink: 0;
}
.bp-rl-pocket-meta { display: flex; flex-direction: column; gap: 2px; }
.bp-rl-pocket-color {
  font-family: var(--font-display); font-weight: 800; font-size: 16px;
  letter-spacing: .08em;
}
.bp-rl-pocket-sub {
  font-family: var(--font-display); font-size: 10px; color: var(--text-mute); letter-spacing: .1em;
}
.bp-rl-strip {
  display: flex; gap: 2px; overflow-x: auto; padding: 4px 2px;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.bp-rl-strip::-webkit-scrollbar { display: none; }
.bp-rl-tile {
  flex: 0 0 auto; min-width: 22px; padding: 6px 4px;
  display: grid; place-items: center;
  color: rgba(255,255,255,.85);
  font-family: var(--font-display); font-weight: 700; font-size: 10px;
  border-radius: var(--radius-xs);
  border: 1px solid rgba(255,255,255,.05);
  opacity: .5;
  transition: transform .15s, opacity .15s;
}
.bp-rl-tile.covered { opacity: .9; border-color: rgba(255,255,255,.25); }
.bp-rl-tile.hit {
  opacity: 1; transform: scale(1.25);
  border-color: var(--accent); color: #fff;
  box-shadow: 0 0 12px rgba(52,192,235,.55);
}
.bp-rl-meta {
  display: flex; justify-content: space-around;
  font-family: var(--font-display); font-size: 11px; color: var(--text-dim);
  flex-wrap: wrap; gap: var(--space-2);
}
.bp-rl-meta b { color: var(--text); margin-left: 4px; }

/* -------- Slot art / placeholder preview -------- */
.bp-slot {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--space-3); width: 100%; min-width: 0;
}
.bp-slot-art {
  display: block;
  max-width: 100%;
  max-height: 220px;
  width: auto; height: auto;
  object-fit: contain;
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 24px rgba(0,0,0,.45);
  background: rgba(0,0,0,.3);
}
.bp-slot-placeholder {
  padding: var(--space-4) var(--space-3);
}
.bp-slot-icon {
  display: grid; place-items: center;
  width: 96px; height: 96px;
  border-radius: var(--radius-md);
  background: rgba(0,0,0,.35);
  border: 1px solid var(--line-soft);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.04);
}
.bp-slot-caption { text-align: center; min-width: 0; max-width: 100%; }
.bp-slot-name {
  font-family: var(--font-display); font-weight: 800; font-size: 16px;
  letter-spacing: -.005em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.bp-slot-provider {
  font-family: var(--font-display); font-size: 10px; color: var(--text-mute);
  letter-spacing: .12em; text-transform: uppercase; margin-top: 2px;
}

/* ======================================================
   CHAT RICH CHIPS (.bet-chip)
   --------------------------------------------------------
   Shared frame used by every server-vouched chat chip:
     * <BetChip>           — shared bet pill (bet-modal.jsx)
     * <RainTipChip>       — rain pool contribution (Task #189)
     * <RainSettledChip>   — hourly rain settlement (Task #189)
     * <TipChip>           — peer-to-peer visible tip (Task #189)
     * renderRainTipAlert  — text-pattern fallback for legacy
                             "💧 /tiprain · …" / "🌧 RAIN POOL · …"
                             system bodies (rain-banner.jsx)
   Centralizing here means future tweaks to background, border,
   padding, type scale, or CoinChip sizing land on every chip
   surface at once (Task #231).
   ====================================================== */
/* Wrapper rendered around system tip/rain rows. The inner .bet-chip
   carries the visual frame (Task #230 dropped the announcement
   header for these rows); this wrapper just provides row spacing. */
.chat-msg-system-chip { margin: 4px 0; padding: 0 !important; background: none !important; border: 0 !important; }

/* Customer feedback — sticky announcement banner pinned to the top
   of the chat scroll viewport. Sits under the rain header (which
   scrolls away normally). Earlier we shipped a flat gradient
   rectangle with a "◆ ANNOUNCEMENT" kicker — the customer flagged
   it as reading "too much AI". This treatment is more deliberate:
   solid panel ground + a left-edge gold rule + a small uppercase
   "Announcement" tag (no diamond ornament), with the dismiss ×
   lined up with the kicker so the action target is obvious. The
   shadow + thin lines separate it from the chat scroll content
   without a heavy outer border. */
.chat-announce-banner {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: stretch;
  gap: 10px;
  margin: 0 -16px 12px; /* full-bleed vs .right-body's 16px side padding */
  padding: 10px 14px 10px 12px;
  background: linear-gradient(180deg, var(--panel-2, #15171c) 0%, var(--panel, #11131a) 100%);
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
  box-shadow: 0 6px 14px rgba(0, 0, 0, .25);
  font-family: var(--font-ui);
}
.chat-announce-rule {
  flex: 0 0 3px;
  align-self: stretch;
  background: var(--accent);
  border-radius: 2px;
  margin: 2px 0;
}
.chat-announce-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 1px;
}
.chat-announce-kicker {
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
}
.chat-announce-text {
  font-size: 13px;
  line-height: 1.45;
  color: var(--text);
  word-break: break-word;
}
.chat-announce-text a { color: var(--accent); }
.chat-announce-dismiss {
  flex: 0 0 auto;
  align-self: flex-start;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-mute);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  padding: 2px 8px 4px;
  border-radius: 4px;
  transition: color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard);
}
.chat-announce-dismiss:hover:not(:disabled) {
  color: var(--text-primary);
  background: rgba(255, 255, 255, .04);
  border-color: var(--line-soft);
}
.chat-announce-dismiss:disabled {
  opacity: .45;
  cursor: not-allowed;
}

.bet-chip {
  display: inline-flex; align-items: center; gap: var(--space-4);
  padding: 8px 10px 8px 8px;
  margin-top: 4px;
  background: linear-gradient(135deg, rgba(20,24,34,.96), rgba(10,14,20,.96));
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  font-family: var(--font-ui);
  font-size: 11px;
  color: var(--text);
  cursor: pointer;
  max-width: 100%;
  min-width: 0;
  box-shadow: inset 3px 0 0 var(--accent-col, var(--purple));
  transition: transform .12s ease, background .15s ease;
}
.bet-chip:hover {
  background: linear-gradient(135deg, rgba(30,34,44,.96), rgba(14,18,24,.96));
  transform: translateY(-1px);
}
/* Non-interactive variant — used by renderRainTipAlert's text-pattern
   fallback chip, which has no click target. Suppresses the hover lift
   so the chip doesn't read as clickable. */
.bet-chip.bet-chip-static { cursor: default; }
.bet-chip.bet-chip-static:hover {
  background: linear-gradient(135deg, rgba(20,24,34,.96), rgba(10,14,20,.96));
  transform: none;
}
.bet-chip.loading { opacity: .65; cursor: wait; }
.bc-ico-sq {
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  font-family: var(--font-display);
  font-size: 15px; font-weight: 800;
  background: var(--accent-25);
  color: var(--purple);
  flex-shrink: 0;
}
.bc-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; }
.bc-action {
  font-family: var(--font-display);
  /* Bumped 9 → 10 px since Sora's lowercase ascender height runs
     shorter than JetBrains Mono — keeps the kicker visually balanced
     with the .bc-meta value row at the same baseline. */
  font-size: 10px;
  letter-spacing: .14em;
  font-weight: 700;
  color: var(--text-mute);
  text-transform: uppercase;
}
.bc-tipper {
  color: var(--accent); font-weight: 700;
  /* Operator request — username on a tip / rain chip should match
     the hero stat font (Sora display) so the chat alert visually
     reads as part of the same brand system as the hero numbers. */
  font-family: var(--font-display);
}
/* Task #191 — meta row must be allowed to shrink inside .bc-body so the
   game-name segment can ellipsis-truncate. Everything except .bc-game is
   marked non-shrinking below so width pressure lands on the name only.
   Font swap (operator request, May 2026): values + game name now use
   var(--font-display) (Sora), the same family the hero stat values use,
   so chat chips read as a continuation of the brand system instead of
   monospaced "code-like" digits that clashed with the hero. The kicker
   label above (.bc-action) stays mono — that's the lowercase / uppercase
   contrast the hero relies on too (.hero-stat .k mono / .v display). */
.bc-meta {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  min-width: 0;
  max-width: 100%;
}
.bc-game {
  color: var(--text); font-weight: 700;
  min-width: 0; flex: 0 1 auto;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bc-prov { flex-shrink: 0; }
.bc-mul { font-weight: 800; flex-shrink: 0; }
.bc-pay { font-weight: 800; flex-shrink: 0; }
.bc-dot { color: var(--text-mute); font-weight: 400; opacity: .7; flex-shrink: 0; }
.bc-meta > .coin-chip { flex-shrink: 0; }
.bc-arrow {
  color: var(--text-mute); margin-left: auto; font-size: 18px; font-weight: 400;
  flex-shrink: 0; padding-left: 4px;
}


/* ======================================================
   VIP PAGE V2 (matches reference shuffle-style screenshot)
   ====================================================== */
.vip-v2 {
  max-width: 1100px;
  margin: 0 auto;
  padding: 18px 20px 60px;
  display: flex; flex-direction: column; gap: 18px;
}
.vip-v2-title {
  font-family: var(--font-display);
  font-size: 30px; font-weight: 800;
  margin: 0;
}
.vip-v2-section {
  font-family: var(--font-display);
  font-size: 18px; font-weight: 700;
  margin: 14px 0 6px;
  display: flex; align-items: center; gap: var(--space-3);
}

/* User card with progress */
.vip-user-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-6);
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 18px;
}
.vuc-left { display: flex; gap: var(--space-6); align-items: flex-start; min-width: 0; }
.vuc-avatar {
  width: 56px; height: 56px; border-radius: 50%;
  display: grid; place-items: center;
  color: #fff; font-family: var(--font-display); font-size: 22px; font-weight: 800;
  flex-shrink: 0;
}
.vuc-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.vuc-name { font-family: var(--font-display); font-size: 18px; font-weight: 700; }
.vuc-tier {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-display); font-size: 12px; color: var(--text-dim);
  padding: 2px 0;
}
.vuc-prog-row { margin-top: 6px; }
.vuc-prog-bar {
  height: 8px; border-radius: var(--radius-xs);
  background: rgba(255,255,255,.08); overflow: hidden;
}
.vuc-prog-fill { height: 100%; transition: width .4s ease; }
.vuc-prog-lbls {
  display: flex; justify-content: space-between;
  font-family: var(--font-display); font-size: 11px; margin-top: 4px;
  color: var(--text-dim);
}
.vuc-right { display: flex; align-items: center; min-width: 0; }
.vuc-blurb {
  font-size: 13px; color: var(--text-dim); line-height: 1.5;
}

/* Rewards grid — Phase 26.7e bumped gap so Daily/Weekly/Monthly
   cards breathe instead of crowding (was --space-5 ≈ 10 px). */
.vip-rewards-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 18px;
  margin-top: 14px;
}
.vrw {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: var(--space-6);
  display: flex; flex-direction: column; gap: var(--space-3);
  min-width: 0;
  overflow: hidden;
}
.vrw.ready { border-color: var(--accent-40); box-shadow: 0 0 30px rgba(52,192,235,.08); }
.vrw-status {
  font-family: var(--font-display); font-size: 11px;
  color: var(--text-mute); letter-spacing: .05em;
}
.vrw.ready .vrw-status { color: var(--accent); }
.vrw-art {
  display: grid; place-items: center;
  height: 80px;
  background: linear-gradient(180deg, rgba(61, 126, 255,.12), transparent);
  border-radius: var(--radius-md);
}
.vrw-icon {
  font-size: 38px;
  filter: drop-shadow(0 0 18px rgba(255,255,255,.2));
}
.vrw-icon-instant { color: #6FD4F2; }
.vrw-icon-daily   { color: #ffd55a; }
.vrw-icon-weekly  { color: #34c0eb; }
.vrw-icon-monthly { color: #3D7EFF; }
.vrw-title { font-family: var(--font-ui); font-weight: 700; font-size: 14px; }
.vrw-amount { font-family: var(--font-display); font-size: 14px; color: var(--accent); font-weight: 700; }
.vrw-btn {
  margin-top: auto;
  appearance: none; border: 1px solid var(--line-soft);
  background: var(--white-04);
  color: var(--text-dim);
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  font-family: var(--font-ui); font-size: 12px; font-weight: 600;
  cursor: not-allowed;
}
.vrw-btn.on {
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
  color: var(--on-accent);
  border-color: transparent; cursor: pointer;
  box-shadow: 0 6px 18px var(--accent-glow);
}
.vrw-btn.on:hover { transform: translateY(-1px); filter: brightness(1.04); }

@media (max-width: 900px) { .vip-rewards-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 540px) { .vip-rewards-grid { grid-template-columns: 1fr; } .vip-user-card { grid-template-columns: 1fr; } .vuc-blurb { font-size: 12px; } }

/* VIP rank list (collapsible) */
.vip-ranks { display: flex; flex-direction: column; gap: var(--space-2); }
.vrank {
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
}
.vrank-head {
  width: 100%;
  display: grid;
  grid-template-columns: auto 1fr auto auto auto;
  gap: var(--space-5); align-items: center;
  background: transparent; border: 0;
  color: var(--text);
  padding: 14px 18px;
  cursor: pointer;
  font-family: var(--font-ui);
  text-align: left;
}
.vrank-head:hover { background: rgba(255,255,255,.03); }
.vrank.open .vrank-head { background: var(--white-04); }
.vrank-icon { display: flex; align-items: center; }
.vrank-name { font-family: var(--font-display); font-size: 15px; font-weight: 700; }
.vrank-spacer {}
.vrank-lock { font-size: 14px; color: var(--text-mute); }
.vrank-chev { color: var(--text-mute); font-size: 16px; line-height: 1; }
.vrank-table {
  border-top: 1px solid var(--line-soft);
  padding: 10px 18px 16px;
}
.vrt-head, .vrt-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--space-5);
  padding: 10px 0;
  font-family: var(--font-display);
  font-size: 13px;
}
.vrt-head { color: var(--text-mute); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; }
.vrt-row { border-top: 1px solid var(--white-04); }
.vrt-row.current { background: var(--accent-soft); border-radius: var(--radius-sm); padding: 10px 12px; margin: 0 -12px; }
.vrt-name { display: flex; align-items: center; gap: var(--space-3); color: var(--text); }
.vrt-xp { color: var(--text); font-weight: 700; }
.vrt-status {}
.vrt-status.done { color: var(--accent); }

@media (max-width: 540px) {
  .vrank-head { padding: 12px 14px; gap: var(--space-4); grid-template-columns: auto 1fr auto auto; }
  .vrank-spacer { display: none; }
  .vrt-head, .vrt-row { grid-template-columns: 1fr 1fr 1fr; gap: var(--space-3); font-size: 11px; }
}

/* Benefits comparison */
.vbenefits-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.vbenefits {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
  font-family: var(--font-display); font-size: 12px;
  min-width: 720px;
}
.vbenefits th, .vbenefits td {
  padding: 12px 10px;
  text-align: center;
  border-bottom: 1px solid rgba(255,255,255,.05);
}
.vbenefits th {
  background: rgba(0,0,0,.25);
  color: var(--text);
  font-weight: 700;
  letter-spacing: .05em;
}
.vbh { display: inline-flex; align-items: center; gap: var(--space-1); justify-content: center; }
.vbenefits th:first-child { text-align: left; padding-left: 16px; }
.vbk { text-align: left !important; padding-left: 16px !important; color: var(--text-dim); }
.vbv.ok { color: var(--accent); font-weight: 700; }
.vbv:not(.ok) { color: var(--text-mute); }

.vip-cta-band {
  margin-top: 24px;
  padding: 20px 24px;
  border-radius: var(--radius);
  background: linear-gradient(135deg, rgba(61, 126, 255,.18), var(--accent-10));
  border: 1px solid rgba(61, 126, 255,.3);
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-7);
  flex-wrap: wrap;
}
.vcb-k { font-family: var(--font-display); font-size: 20px; font-weight: 700; }
.vcb-s { font-family: var(--font-ui); font-size: 13px; color: var(--text-dim); margin-top: 4px; }

/* =========================================================
   BALANCE DROPDOWN v2 — 9 wallet rows + 12 fiat "Bet Currency" pills
   Matches the attached reference screenshot.
   ========================================================= */

.bal-dropdown.bd-v2 {
  width: 300px;
  padding: var(--space-4);
}
.bd-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: 6px 6px 10px;
  border-bottom: 1px solid var(--line-soft);
  margin-bottom: 8px;
}
.bd-head-amt {
  appearance: none; border: 0; cursor: pointer;
  background: transparent; color: var(--text);
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 2px 4px;
  font-family: var(--font-display);
  font-size: 18px; font-weight: 700;
  letter-spacing: .02em;
}
.bd-head-amt .bd-amt { color: var(--text); }
.bd-head-amt:hover { color: var(--purple); }
.bd-wallet-cta {
  padding: 8px 18px !important;
  font-size: 12px !important;
}
.bal-dropdown.bd-v2 .bd-list {
  max-height: 300px;
  overflow-y: auto;
  padding-right: 2px;
}
.bal-dropdown.bd-v2 .bd-row {
  padding: 8px 8px;
}
.bal-dropdown.bd-v2 .bd-row.on {
  background: rgba(52,192,235,.08);
  box-shadow: inset 0 0 0 1px var(--accent-25);
}
.bal-dropdown.bd-v2 .bd-row:hover {
  background: var(--white-04);
}
.bal-dropdown.bd-v2 .bd-coin {
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border-radius: 50%;
  color: #fff; font-weight: 800; font-size: 12px;
}

/* Bet Currency (fiat display) section — customer feedback rebuild.
   Each pill is now a 2-line tile: large fiat symbol on top (€/$/¥),
   smaller ISO code below. Selected state gets a soft gold gradient +
   accent border + lift, matching the canonical card-tile language. */
.bd-bet-ccy {
  border-top: 1px solid var(--line-soft);
  margin-top: 12px;
  padding: 14px 6px 4px;
}
.bd-bet-title {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .16em;
  color: var(--text-mute);
  text-transform: uppercase;
  padding: 0 4px 10px;
}
.bd-bet-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
@media (max-width: 480px) {
  .bd-bet-grid { grid-template-columns: repeat(3, 1fr); }
}
.bd-bet-pill {
  appearance: none; cursor: pointer;
  background: linear-gradient(180deg, rgba(255,255,255,.04), rgba(255,255,255,.015));
  border: 1px solid rgba(255,255,255,.06);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 9px 4px 7px;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  transition: transform .12s ease, border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
.bd-bet-pill-sym {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  line-height: 1;
  color: var(--text);
}
/* Bitmap variant — same vertical footprint as the text glyph so the
   pill height stays uniform across the grid (icon + non-icon mix). */
.bd-bet-pill-sym-img {
  width: 22px;
  height: 22px;
  object-fit: contain;
  display: block;
}

/* Bet-input coin slot bitmap variants — every game's bet field
   (.gp-input-coin) and the live roulette field (.rl-bet-input-coin)
   render the bitmap fiat icon when in fiat-display mode. The ".-img"
   modifier drops the gold disc background and switches to an <img>
   that fills the same 22×22 footprint, keeping every input row at
   identical height regardless of icon vs glyph. */
.gp-input-coin.gp-input-coin-img,
.rl-bet-input-coin.rl-bet-input-coin-img {
  background: transparent;
  width: 22px;
  height: 22px;
  object-fit: contain;
  padding: 0;
  display: block;
  flex-shrink: 0;
}
.bd-bet-pill-code {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .12em;
  font-weight: 700;
  color: var(--text-mute);
}
.bd-bet-pill:hover {
  border-color: rgba(52,192,235,.25);
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(0,0,0,.30);
}
.bd-bet-pill:hover .bd-bet-pill-code { color: var(--text-dim); }
.bd-bet-pill.on {
  background: linear-gradient(180deg, rgba(52,192,235,.18), rgba(52,192,235,.05));
  border-color: rgba(52,192,235,.55);
  box-shadow: 0 0 0 1px rgba(52,192,235,.4), 0 6px 16px rgba(52,192,235,.18);
}
.bd-bet-pill.on .bd-bet-pill-sym { color: var(--accent); text-shadow: 0 0 12px rgba(52,192,235,.4); }
.bd-bet-pill.on .bd-bet-pill-code { color: var(--accent); }
.bd-dev {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line-soft);
}

/* Mobile bottom-sheet variant.
   Animation was removed — it kept leaving the sheet parked off-screen
   (transform: translateY(100%)) due to a re-render loop in React.
   Instead we use a subtle opacity/translate transition that plays from
   React's `panel-enter` helper when the component mounts. */
.bal-dropdown.bd-sheet {
  position: fixed !important;
  top: auto !important;
  bottom: 0 !important;
  left: 0 !important;
  right: 0 !important;
  width: auto !important;
  max-width: none !important;
  border-radius: 18px 18px 0 0 !important;
  padding: 14px 14px 22px !important;
  max-height: 85vh !important;
  overflow-y: auto !important;
  box-shadow: 0 -20px 60px rgba(0,0,0,.7) !important;
  z-index: 9999 !important;
  transform: translateY(0);
}

/* =========================================================
   SLOT PLAYER MODAL — iframe wrapper for Drakon games
   ========================================================= */

.slot-player-root {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.88);
  z-index: 10000;
  display: grid;
  place-items: center;
  animation: modalIn .18s ease-out;
}
.slot-player-shell {
  width: min(1100px, 96vw);
  height: min(92vh, calc(96vw * 0.625));
  background: #04060E;
  border-radius: var(--radius);
  box-shadow: 0 30px 100px rgba(0,0,0,.8), 0 0 0 1px rgba(148,163,209,.12);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.sp-head {
  display: flex; align-items: center; gap: var(--space-6);
  padding: 10px 14px;
  border-bottom: 1px solid var(--line-soft);
  background: linear-gradient(180deg, rgba(61, 126, 255,.08), transparent);
}
.sp-title {
  flex: 1 1 auto;
  font-family: var(--font-display);
  font-size: 14px; letter-spacing: .06em;
  color: var(--text);
}
.sp-bal {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 6px 10px;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  font-family: var(--font-display); font-size: 13px; font-weight: 700;
  color: var(--text);
}
.sp-bal-glyph {
  display: grid; place-items: center;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--white-06);
  font-size: 11px;
}
.sp-close {
  appearance: none; border: 0; cursor: pointer;
  background: transparent; color: var(--text-dim);
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  transition: .15s;
}
.sp-close:hover { color: var(--text); background: rgba(255,255,255,.08); }
.sp-iframe {
  flex: 1 1 auto;
  width: 100%; height: 100%; border: 0;
  background: #000;
}

/* PDF p.20 audit: slot fullscreen sizing.
   `.gp-shell` is the wrapper passed to requestFullscreen() in
   slot-detail.jsx::toggleFullscreen. By default the browser stretches
   the element to viewport size but preserves its inner flex layout —
   the iframe inside needs explicit 100%/100% rules so it actually
   fills the screen instead of staying at its content box size. */
.gp-shell:fullscreen,
.gp-shell:-webkit-full-screen {
  width: 100vw !important;
  height: 100vh !important;
  display: flex;
  flex-direction: column;
  background: #000;
  border-radius: 0;
}
.gp-shell:fullscreen .sp-iframe,
.gp-shell:-webkit-full-screen .sp-iframe,
.gp-shell:fullscreen iframe,
.gp-shell:-webkit-full-screen iframe {
  flex: 1 1 auto;
  width: 100%; height: 100%;
  border: 0;
  display: block;
}
/* Keep the bottom bar visible in fullscreen so the user can exit. */
.gp-shell:fullscreen .gp-bottombar,
.gp-shell:-webkit-full-screen .gp-bottombar {
  flex-shrink: 0;
}
.sp-empty {
  flex: 1 1 auto;
  display: grid; place-items: center;
  padding: var(--space-8);
  text-align: center;
  color: var(--text-dim);
  font-family: var(--font-ui);
}
.sp-empty .k {
  font-family: var(--font-display);
  font-size: 18px; color: var(--text); margin-bottom: 8px;
}

@media (max-width: 700px) {
  .slot-player-shell {
    width: 100vw; height: 100vh;
    border-radius: 0;
  }
}

/* =========================================================
   SLOTS LOBBY — search + provider select (lives in .sec-head tools)
   Category chips, grid, and hero come from the shared design system
   (.chip, .slots-grid, .page-shell, .lobby-hero).
   ========================================================= */
.slots-search {
  display: inline-flex; align-items: center; gap: var(--space-3);
  padding: 8px 12px;
  background: rgba(255,255,255,.03);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  min-width: 220px;
}
.slots-search input {
  appearance: none; border: 0; outline: 0; background: transparent;
  color: var(--text);
  font-family: var(--font-ui); font-size: 12px;
  flex: 1; min-width: 0;
}
/* .slots-prov removed — provider filter now uses <SelectMenu variant="pill">. */
.slots-more {
  margin: 24px 0;
  display: flex; justify-content: center;
}
.slots-more-btn {
  appearance: none; cursor: pointer;
  background: transparent; color: var(--text);
  border: 1px solid var(--line-soft);
  font-family: var(--font-display); font-size: 12px; letter-spacing: .08em;
  padding: 12px 24px; border-radius: var(--radius-md);
  transition: .15s;
}
.slots-more-btn:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}
.slots-more-btn:disabled { opacity: .5; cursor: wait; }

@media (max-width: 700px) {
  .slots-search { min-width: 0; flex: 1 1 100%; }
  .slots-page .sd-bp { flex: 1 1 100%; }
  .slots-page .sd-bp .sm-btn { width: 100%; justify-content: space-between; }
}

/* =========================================================
   SLOT DETAIL PAGE — matches the attached Shuffle reference layout.
   Outer container is .panel.gp-shell (shared with originals) but
   with a full-width hero banner instead of the .gp grid split.
   Below the shell: title strip, More-from rail, Providers rail, BetsFeed.
   ========================================================= */

/* The .sd-shell modifier opts OUT of the originals' .gp grid so the
   banner fills the container end-to-end; the bottom bar sits below. */
.gp-shell.sd-shell { min-height: 0; padding: 0; }
.gp-shell.sd-shell > .gp,
.gp-shell.sd-shell .gp-canvas,
.gp-shell.sd-shell > .gp > .gp-panel { display: none; }

/* Hero area — either the blurred banner + CTA or the live iframe.
   Phase 26.4 — customer reported "screen size doesn't display
   correctly when starting a game". The 16:9 aspect-ratio collapses
   the hero to ~211 px tall at 375 px viewport, which clips the iframe
   below its 560 px min-height. We now drive the height from the
   available viewport space (dvh accounts for mobile browser chrome),
   clamped to a sensible window so the iframe always has enough room
   to render the actual slot UI. */
.sd-hero {
  position: relative;
  width: 100%;
  height: clamp(420px, calc(100dvh - 220px), 760px);
  /* Fallback for browsers without dvh — same value with vh. */
  height: clamp(420px, calc(100vh - 220px), 760px);
  height: clamp(420px, calc(100dvh - 220px), 760px);
  background: #000;
  overflow: hidden;
}
/* Desktop-wide layouts: use the 16:9 ratio when there's enough
   horizontal room (>= 900 px wide hero). Below that, the dvh
   formula above provides better proportions. */
@media (min-width: 1180px) {
  .sd-hero {
    height: auto;
    aspect-ratio: 16 / 9;
    max-height: 72vh;
    min-height: 560px;
  }
}
.sd-banner {
  position: absolute; inset: 0;
  /* Blurred banner — focus stays on the CTA, mirrors the reference. */
  filter: blur(6px) brightness(.62);
  transform: scale(1.08);
}
/* Solid colour fallback that sits BEHIND the <img>. If the banner URL
   404s, `bannerOK` flips to false in slot-detail.jsx, the <img> is
   removed, and this gradient is revealed. Without it, broken banner
   URLs left the user with a black void. */
.sd-banner-fallback {
  position: absolute; inset: 0;
  filter: blur(6px) brightness(.62);
  transform: scale(1.08);
  z-index: 0;
}
/* When the banner is rendered as an <img> (so we can catch onError),
   it needs cover-fit to fill the hero like the old background-image
   did. Same blur as .sd-banner since it shares that class. */
.sd-banner.sd-banner-img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  display: block;
  z-index: 1;
}
.sd-banner-overlay {
  position: absolute; inset: 0;
  background: radial-gradient(circle at center, rgba(0,0,0,.2) 0%, rgba(0,0,0,.7) 100%);
  pointer-events: none;
}
.sd-iframe {
  width: 100%; height: 100%; min-height: 560px;
  border: 0; background: #000; display: block;
}

/* Centered CTA card floating on the banner. */
.sd-banner-cta {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  min-width: 320px;
  background: rgba(10, 14, 26, .88);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 20px 24px;
  display: flex; flex-direction: column; gap: var(--space-6);
  backdrop-filter: blur(10px);
  box-shadow: 0 20px 60px rgba(0,0,0,.55);
  z-index: 2;
}
.sd-cta-bal {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-6);
}
.sd-cta-k {
  font-family: var(--font-display); font-size: 12px; letter-spacing: .08em;
  color: var(--text-dim);
}
.sd-cta-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4);
}
.sd-cta-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: 12px 18px; width: 100%;
  font-size: 13px; letter-spacing: .06em; font-weight: 700;
}

.sd-err {
  padding: 10px 12px; border-radius: var(--radius-sm);
  background: rgba(255,59,107,.12);
  border: 1px solid rgba(255,59,107,.3);
  color: #ff8da4;
  font-family: var(--font-ui); font-size: 12px;
}

/* Task #219 — fiat-downgrade notice rendered above a slot iframe when
   the upstream studio doesn't support the player's chosen bet ccy and
   Drakon substituted a different display fiat. */
.sd-downgrade-notice {
  position: absolute; top: 12px; left: 12px; right: 12px; z-index: 4;
  padding: 10px 14px; border-radius: var(--radius-sm);
  background: rgba(255,183,43,.14);
  border: 1px solid rgba(255,183,43,.35);
  color: #ffd58a;
  font-family: var(--font-ui); font-size: 12px; line-height: 1.45;
}
.sd-downgrade-notice strong { color: #ffe7b3; font-weight: 700; }

/* Title strip below the game container (game name + provider pill + stats). */
.sd-title-strip {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-7); flex-wrap: wrap;
  margin: 20px 0 4px;
}
.sd-title-left {
  display: inline-flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
}
.sd-title {
  font-family: var(--font-display); font-size: 22px; letter-spacing: .01em;
  color: var(--text); margin: 0;
}
.sd-prov-pill {
  padding: 4px 10px; border-radius: var(--radius-xs);
  background: rgba(255,255,255,.05); border: 1px solid var(--line-soft);
  color: var(--text-dim);
  font-family: var(--font-display); font-size: 11px; letter-spacing: .04em;
  white-space: nowrap;
}
.sd-title-right {
  display: inline-flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
}
.sd-stat-pill {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 5px 10px; border-radius: var(--radius-sm);
  background: var(--white-04); border: 1px solid var(--line-soft);
  color: var(--text);
  font-family: var(--font-display); font-size: 11px; font-weight: 700;
  letter-spacing: .04em;
}
.sd-stat-pill.sd-stat-trophy {
  color: var(--accent); border-color: rgba(255,183,43,.35);
  background: rgba(255,183,43,.08);
}

/* "View all" + arrow buttons that live in .sec-head tools. */
.sd-view-all {
  appearance: none; cursor: pointer;
  background: var(--white-04); border: 1px solid var(--line-soft);
  color: var(--text-dim);
  padding: 6px 12px; border-radius: var(--radius-sm);
  font-family: var(--font-display); font-size: 11px; letter-spacing: .06em;
  font-weight: 600;
  transition: .15s;
}
.sd-view-all:hover { color: var(--text); border-color: var(--accent); }

/* Providers rail — wide logo chips, horizontal scroller. */
.scroller.sd-prov-rail { grid-auto-columns: 180px; gap: var(--space-5); }
.sd-prov-chip {
  display: flex; align-items: center; gap: var(--space-4);
  padding: 12px 14px;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: .15s;
  min-width: 0;
  scroll-snap-align: start;
}
.sd-prov-chip:hover { border-color: var(--accent); transform: translateY(-1px); }
.sd-prov-logo {
  width: 40px; height: 40px; border-radius: var(--radius-sm);
  display: grid; place-items: center;
  color: #fff; font-family: var(--font-display); font-size: 14px;
  flex-shrink: 0;
}
.sd-prov-name {
  font-family: var(--font-ui); font-size: 12px; font-weight: 600;
  color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Balance-in picker (small pill dropdown used inside the panel) */
.sd-bp { position: relative; }
.sd-bp-btn {
  appearance: none; cursor: pointer;
  background: var(--white-06);
  border: 1px solid var(--line-soft);
  color: var(--text);
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 6px 10px; border-radius: var(--radius-sm);
  font-family: var(--font-display); font-size: 12px; font-weight: 700;
}
.sd-bp-btn:hover { border-color: var(--accent); }
.sd-bp-dot {
  width: 18px; height: 18px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--accent); color: var(--accent-ink);
  font-size: 10px; font-weight: 800;
}
.sd-bp-menu {
  position: absolute; top: calc(100% + 6px); right: 0;
  background: var(--panel); border: 1px solid var(--line-soft);
  border-radius: var(--radius-md); padding: var(--space-2); z-index: 100;
  box-shadow: 0 20px 60px rgba(0,0,0,.5);
  max-height: 260px; overflow-y: auto;
  min-width: 140px;
}
.sd-bp-item {
  appearance: none; cursor: pointer;
  background: transparent; border: 0;
  color: var(--text);
  display: flex; align-items: center; gap: var(--space-3);
  padding: 8px 10px; width: 100%;
  border-radius: var(--radius-xs);
  font-family: var(--font-display); font-size: 12px; font-weight: 600;
}
.sd-bp-item:hover { background: var(--white-06); }
.sd-bp-item.on { color: var(--accent); background: var(--accent-10); }

/* SelectMenu variants — shared component that wraps the .sd-bp-* tokens. */
.sd-bp.sm-full { width: 100%; display: block; }
.sd-bp.sm-full .sm-btn {
  width: 100%;
  justify-content: space-between;
  padding: 9px 12px;
  font-size: 13px;
}
.sd-bp.sm-full .sd-bp-menu {
  left: 0; right: 0;
  min-width: 0;
  max-height: 320px;
}
.sd-bp.sm-pill .sm-btn { min-width: 0; }
.sd-bp .sm-label {
  max-width: 180px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sd-bp-menu.sm-align-l { left: 0; right: auto; }
.sd-bp.sm-disabled .sm-btn { opacity: .5; cursor: not-allowed; }

/* Slot-specific Real/Fun toggle that sits in the .gp-bottombar right slot
   instead of the "Provably Fair" button. Uses the same token palette. */
.sd-mode-toggle {
  display: inline-flex;
  background: rgba(255,255,255,.03);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  padding: 2px;
}
.sd-mode-btn {
  appearance: none; cursor: pointer;
  background: transparent; border: 0;
  color: var(--text-mute);
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 6px 12px; border-radius: var(--radius-sm);
  font-family: var(--font-ui); font-size: 12px; font-weight: 700;
  letter-spacing: .02em;
  transition: .15s;
}
.sd-mode-btn:hover { color: var(--text); }
.sd-mode-btn.on {
  color: var(--text);
  background: var(--white-06);
  box-shadow: inset 0 0 0 1px var(--line-soft);
}
.sd-mode-btn svg { color: var(--accent); }

/* Narrow viewport tweaks. */
@media (max-width: 700px) {
  /* Phase 29.2 (F-26.4 audit) — dropped `aspect-ratio: 4/5` here
     because at 375×812 it produced a 469 px tall hero + 360 px
     iframe min-height, which combined with topbar / breadcrumb /
     footer pushed the iframe past the viewport on first render
     (customer's "screen size doesn't display correctly" report).
     Reusing the same dvh-clamp formula as the default `.sd-hero`
     rule (line ~5720) keeps the iframe inside the visible viewport
     with comfortable margin top + bottom. */
  .sd-hero {
    aspect-ratio: auto;
    height: clamp(360px, calc(100dvh - 180px), 640px);
    height: clamp(360px, calc(100vh  - 180px), 640px);
    height: clamp(360px, calc(100dvh - 180px), 640px);
  }
  .sd-banner-cta { min-width: 0; left: 16px; right: 16px; transform: translateY(-50%); }
  .sd-mode-btn { padding: 6px 8px; font-size: 11px; }
  .sd-iframe { min-height: 360px; }
  .sd-title { font-size: 18px; }
  .sd-view-all { display: none; }
  .scroller.sd-prov-rail { grid-auto-columns: 150px; }
}

/* =========================================================
   RESPONSIVE BREAKPOINT FIXES (audit pass)
   Each rule closes a gap identified in the responsive audit.
   ========================================================= */

/* 1. .slots-grid — lock to 2 cols on mobile so cards don't overflow */
@media (max-width: 860px) {
  .slots-grid { grid-template-columns: repeat(2, 1fr) !important; gap: var(--space-4); }
}

/* 2. .gp-bottombar — shrink icons + hide brand on ultra-narrow */
@media (max-width: 520px) {
  .gp-bottombar { padding: 6px 8px; }
  .gp-bb-left { gap: var(--space-1); }
  .gp-bb-right { gap: var(--space-1); }
  .gp-bb-icon { width: 32px; height: 32px; }
  .gp-bb-icon svg { width: 13px; height: 13px; }
  .gp-bb-center { display: none; }
}

/* 3. .sd-hero — keep 16:9 on tablet (700-860px); 4:5 rule above covers < 700px */
@media (min-width: 701px) and (max-width: 860px) {
  .sd-hero { aspect-ratio: 16 / 9; }
}

/* 4. .bf-row (BetsFeed) — 3-col compact layout on mobile, hide user column */
@media (max-width: 860px) {
  .bf-row {
    grid-template-columns: 1fr 1fr 60px !important;
    gap: var(--space-2) !important;
    font-size: 11px !important;
  }
  .bf-row > .bf-user,
  .bf-row > *:nth-child(2) { display: none; }
}

/* 5. .rw-days (Rewards calendar) — 2 cols below 375px */
@media (max-width: 375px) {
  .rw-days { grid-template-columns: repeat(2, 1fr); gap: var(--space-1); }
}

/* 6. .gp-canvas-inner — replaces inline maxWidth:480 from game-page.jsx */
.gp-canvas-inner { width: 100%; max-width: 480px; margin: 0 auto; }
@media (max-width: 860px) { .gp-canvas-inner { max-width: 100%; } }

/* =================================================================
   Customer-feedback Keno polish
   =================================================================
   Two complaints + remediation:
     1. "Canvas is very small on big screens, more room to extend on
        big screen (mobile is fine)" — overrides the .gp-canvas-inner
        max-width:480 cap on the keno surface, letting the grid
        stretch up to ~880px on desktop. Mobile path is unchanged.
     2. "Look more professional, enhance tile textures" — class-based
        styling replaces the inline-style tiles in game-page.jsx so
        each tile gets a proper gradient face, soft inner shadow,
        glow on picked/hit, and a press-on-tap interaction. Tiles
        breathe (~84-104 px on desktop) and feel like physical chips. */
.keno-canvas-inner {
  width: 100%;
  max-width: 880px;
  margin: 0 auto;
  padding: 14px 12px;
}
@media (max-width: 860px) {
  .keno-canvas-inner { max-width: 100%; padding: 8px 4px; }
}

.keno-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 10px;
  width: 100%;
}
@media (max-width: 480px) {
  .keno-grid { gap: 6px; }
}

/* Operator rebuild (PDF page 10): always-visible multiplier strip
   below the board. Equally-distributed cells, one per possible HIT
   count (0..picks). Mult on top, hit count below. Active cell is the
   cell matching the current `hits` once the round settles. */
.keno-paytable {
  /* Customer feedback — outer container drops its bg + border so
     the row reads as a flat strip of chips (matching `.gp-chips`'s
     bare flex layout in the Risk row). The cells themselves carry
     the `.gp-chips button` palette via .keno-paycell below. */
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--space-2);
  margin-top: 14px;
}
/* Customer feedback — paycell containers must match the Risk-chip
   look 1:1: same background, font, weight, padding, radius. The
   chip itself is a flex column (mult on top, hit-count below) to
   keep the existing two-line readout, but the surface palette is
   identical to `.gp-chips button` in styles.css.
   - default state ↔ inactive Risk chip (bg-elevated, text-secondary)
   - .is-winning  ↔ active Risk chip   (accent / accent-contrast)
   - .is-active   ↔ active Risk chip + a slight z-pop so the round-
                    settled hit count stands out from peer winners
                    without breaking the binary palette. */
.keno-paycell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 7px 11px;
  background: var(--bg-elevated);
  border: 0;
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  color: var(--text-secondary);
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard),
              transform var(--dur-fast) var(--ease-standard);
}
.keno-paycell-mult {
  font-size: 12px;
  font-weight: 600;
  color: inherit;
  font-variant-numeric: tabular-nums;
}
.keno-paycell-hits {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  color: inherit;
  opacity: .75;
}
/* Cells with a non-zero multiplier carry the same gold "on" treatment
   the active Risk chip uses, so the player sees at a glance which
   tiers count as a win — same palette as Risk button.on. */
.keno-paycell.is-winning {
  background: var(--accent);
  color: var(--accent-contrast);
}
.keno-paycell.is-winning .keno-paycell-hits { opacity: .85; }
/* Active cell — round just settled; this is the user's actual hit count.
   Same gold palette as .is-winning (so it never reads "less highlighted"
   than a peer winning tier) plus a subtle z-pop + glow so the eye lands
   on the realised result first. */
.keno-paycell.is-active {
  background: var(--accent);
  color: var(--accent-contrast);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px var(--accent-glow);
}
@media (max-width: 540px) {
  .keno-paycell { padding: 6px 2px; }
  .keno-paycell-mult { font-size: 11px; }
  .keno-paycell-hits { font-size: 10px; }
}

.keno-tile {
  position: relative;
  aspect-ratio: 1 / 1;
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 12px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .04), rgba(255, 255, 255, 0)),
    radial-gradient(circle at 35% 28%, rgba(255, 255, 255, .08), rgba(255, 255, 255, 0) 60%),
    linear-gradient(180deg, #1a2030, #0d1320);
  /* Inset highlight + outset shadow give the tile dimensional weight
     without leaning on heavy borders. The faint top-edge sheen reads
     as light catching a beveled face. */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .06),
    inset 0 -1px 0 rgba(0, 0, 0, .35),
    0 2px 6px rgba(0, 0, 0, .35);
  color: var(--text-dim);
  font-family: var(--font-display);
  font-size: clamp(16px, 2.4vw, 26px);
  font-weight: 700;
  letter-spacing: -.02em;
  cursor: pointer;
  transition: transform .14s ease, box-shadow .14s ease, background .18s ease, color .18s ease, border-color .18s ease;
  overflow: hidden;
  display: grid;
  place-items: center;
}
.keno-tile:hover:not(.is-locked) {
  transform: translateY(-1px);
  border-color: rgba(255, 255, 255, .14);
  color: var(--text);
}
.keno-tile:active:not(.is-locked) { transform: translateY(0); }
.keno-tile.is-locked { cursor: default; }

/* Autobet lockout — dim the entire board so the player has a clear
   visual that input is suspended. Tile clicks are blocked at the
   handler level (toggle() checks auto.running); this is purely the
   visual affordance. */
.keno-grid.is-autobet-locked { opacity: 0.78; filter: saturate(0.85); }
.keno-grid.is-autobet-locked .keno-tile { cursor: not-allowed; }

/* Operator rebuild — mobile keno layout. The Degen-style reference keeps
   8 columns (all 40 numbers visible) on phones; tighter gap + smaller
   font + lower minimum tap target so the grid stays in 5 readable rows
   without horizontal scrolling. The paytable strip can't keep 11 cells
   readable at 360 px so we let it scroll-x with snap on small screens. */
@media (max-width: 540px) {
  .keno-grid { gap: 5px; }
  .keno-tile {
    border-radius: 9px;
    font-size: clamp(13px, 3.6vw, 16px);
  }
  .keno-paytable {
    grid-auto-flow: column;
    grid-auto-columns: minmax(54px, 1fr);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    padding: 8px;
  }
  .keno-paytable::-webkit-scrollbar { display: none; }
  .keno-paycell { scroll-snap-align: start; }
}
@media (max-width: 380px) {
  /* Phones below 380 px: tighten further so 8 columns still fit. */
  .keno-grid { gap: 4px; }
  .keno-tile {
    border-radius: 7px;
    font-size: 12px;
  }
}

/* Operator rebuild — bet panel BELOW canvas on mobile for ALL originals.
   Reference (Degen) places the game canvas first, controls underneath
   on phones. The desktop `order:-1` flip we added earlier put the panel
   on the LEFT; on mobile that flips into "first row" which forces users
   to scroll past the bet panel before they can see the game. This
   resets `.gp-canvas` to render first and `.gp-panel` second. */
@container main (max-width: 760px) {
  .gp { grid-template-columns: 1fr !important; }
  .gp-canvas { order: 0 !important; }
  .gp-panel  {
    order: 1 !important;
    margin-right: 0 !important;
    margin-top: var(--space-5) !important;
    border-right: 0 !important;
    border-top: 1px solid var(--line-soft) !important;
    border-radius: var(--radius) !important;
  }

  /* BJ bet panel — on mobile the canvas is above the panel, so the
     player has to scroll PAST the felt to reach Hit/Stand/Split/Double
     at the bottom of the panel. Hoist the action grid (and the Place
     Bet CTA when it's shown idle/done) to the top of the panel so the
     primary controls sit directly under the felt within thumb reach.
     `.gp-panel` is already display:flex; flex-direction:column so a
     plain `order:` reshuffle is enough — DOM stays untouched, desktop
     layout (>760px) is unchanged. `margin-top: 0 !important` is needed
     because `.gp-panel .gp-bet { margin: ... !important; }` exists in
     a sibling mobile rule and would otherwise leave a gap above the
     hoisted Place Bet pill. `order` doesn't need !important — no other
     rule in the cascade sets `order` on these classes. */
  .bj-bet-panel .bj-place        { order: -2; margin-top: 0 !important; }
  .bj-bet-panel .bj-actions-grid { order: -1; margin-top: 0 !important; }
}

/* PICKED state — purple chip face. Subtle gradient + border tint. */
.keno-tile.is-picked {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .10), rgba(255, 255, 255, 0)),
    linear-gradient(180deg, #6c4cff 0%, #4a2fc8 100%);
  border-color: rgba(255, 255, 255, .18);
  color: #fff;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .22),
    inset 0 -1px 0 rgba(0, 0, 0, .40),
    0 4px 14px rgba(108, 76, 255, .30);
}

/* HIT (drawn but not picked) — magenta accent ring + faint fill. */
.keno-tile.is-hit-only {
  background:
    linear-gradient(180deg, rgba(255, 107, 157, .14), rgba(255, 107, 157, 0)),
    linear-gradient(180deg, #1a2030, #0d1320);
  border-color: rgba(255, 107, 157, .55);
  color: #ff9bbd;
  box-shadow:
    inset 0 1px 0 rgba(255, 107, 157, .18),
    inset 0 0 0 1px rgba(255, 107, 157, .25),
    0 2px 8px rgba(255, 107, 157, .18);
}

/* JUST-PICKED — transient class added during the Auto-Pick cascade
   so each freshly-tagged tile pops with the same scale-up keyframe
   the draw-reveal uses (kenoTilePop, defined below). The class is
   removed after the keyframe completes so a later toggle / re-pick
   on the same tile re-fires the animation. */
.keno-tile.is-just-picked {
  animation: kenoTilePop .35s ease;
}

/* Customer feedback — Auto-Pick / Clear table sit in `.gp-chips`
   so they wear the Risk-row palette (bg-elevated → accent on .on),
   but get a "slightly bigger, more breathing room" treatment vs.
   the inline Risk filter. Only SIZE / SPACING are touched — the
   palette inheritance from `.gp-chips button` in styles.css must
   continue to win, so a future palette tweak still propagates. */
.gp-chips.gp-chips-quick {
  gap: var(--space-4);                 /* 10px between the two chips, vs 6px on Risk */
  margin-top: var(--space-2);
}
.gp-chips.gp-chips-quick button {
  flex: 1 1 0;                         /* split the row 50/50 — bigger touch target */
  padding: 11px 18px;                  /* vs Risk's 7px 11px */
  font-size: 13px;                     /* one notch up from Risk's 12px */
  letter-spacing: .02em;
}

/* WIN — picked AND drawn. Gold chip face + glow. */
.keno-tile.is-win {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .18), rgba(255, 255, 255, 0)),
    linear-gradient(180deg, #5CCDEF 0%, #34c0eb 50%, #2487AD 100%);
  border-color: rgba(255, 217, 96, .60);
  color: #2a1d00;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .55),
    inset 0 -1px 0 rgba(0, 0, 0, .25),
    0 0 24px rgba(52, 192, 235, .55),
    0 4px 12px rgba(52, 192, 235, .35);
  animation: kenoTilePop .35s ease;
}

@keyframes kenoTilePop {
  0%   { transform: scale(.92); }
  50%  { transform: scale(1.06); }
  100% { transform: scale(1); }
}

/* Faint corner sheen — a diagonal highlight in the upper-left of
   each tile so they don't read flat. Hidden on the win state where
   the gold gradient already provides plenty of depth. */
.keno-tile::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, rgba(255, 255, 255, .06) 0%, rgba(255, 255, 255, 0) 35%);
  pointer-events: none;
  border-radius: inherit;
}
.keno-tile.is-win::before { display: none; }

/* 7. .vip-tier-rail — 3 cols on tablet (not 4) */
@media (min-width: 541px) and (max-width: 900px) {
  .vip-tier-rail { grid-template-columns: repeat(3, 1fr); }
}

/* 8. .bf-chart-svg — shrink on mobile */
@media (max-width: 520px) {
  .bf-chart-svg { height: 80px; }
}

/* 9. .rw-stats — 2-col at 700-860 to avoid unbalanced 1-col jump */
@media (min-width: 701px) and (max-width: 860px) {
  .rw-stats { grid-template-columns: 1fr 1fr; }
}

/* 10. .ft-grid — intermediate 3-col at tablet */
@media (min-width: 961px) and (max-width: 1100px) {
  .ft-grid { grid-template-columns: repeat(3, 1fr); gap: var(--space-8); }
}

/* 11. .pm-shuffle-stats — 2-col below 520px */
@media (max-width: 520px) {
  .pm-shuffle-stats { grid-template-columns: 1fr 1fr; }
}

/* 12. .vip-rewards-grid — 2-col on tablet */
@media (min-width: 541px) and (max-width: 900px) {
  .vip-rewards-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* 13. Sidebar nav-item label truncation on narrow viewports */
@media (max-width: 375px) {
  .rail .n-label,
  .sb-item > span,
  .nav-item > span {
    max-width: 160px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
}

/* 14. .sd-cta-btn — shrink padding on ultra-narrow */
@media (max-width: 375px) {
  .sd-cta-btn { padding: 10px 12px; font-size: 12px; gap: var(--space-1); }
}

/* 15. Right panel drawer — leave breathing room on ultra-narrow */
@media (max-width: 480px) {
  .right {
    width: calc(100% - 32px) !important;
    max-width: calc(100vw - 32px) !important;
  }
}

/* =========================================================
   AUTH MODAL — redesign overrides. The base look lives in
   styles.css; here we square off the modal-shell chamfer into a
   clean rounded card, lock the height so Login ↔ Register doesn't
   jump, and paint the left artwork panel.
   ========================================================= */

/* Clean rounded card — the global .modal-shell uses a corner-chamfer
   clip-path; the auth modal wants a plain rounded rectangle (the
   redesign reference is a soft-cornered card, not a chamfered one). */
.modal-shell:has(.auth) {
  clip-path: none;
  border-radius: 16px;
  border: 1px solid var(--line);
}

/* Height lock — Register is the taller mode (Username + Email +
   Password + Confirm Password + 2 checkboxes + submit + divider +
   socials). Both modes are locked to the SAME height so toggling
   Login ↔ Register never reflows the shell, AND that height is
   clamped to the viewport so the modal is always fully visible
   without an inner scrollbar. `min(620px, 100dvh - 56px)` keeps it
   inside the shell's own `100vh - 48px` cap with headroom:
     • tall screens  → a comfortable fixed 620 (both modes equal)
     • short screens  → shrinks to fit the viewport; the responsive
       compaction tiers below trim the register form's vertical
       rhythm so its content still fits that smaller box with no
       scroll. Desktop-only (artwork column visible). */
@media (min-width: 861px) {
  .auth,
  .modal-shell:has(.auth) {
    min-height: min(620px, calc(100dvh - 56px));
    height: min(620px, calc(100dvh - 56px));
  }
  .auth .a-form { min-height: min(620px, calc(100dvh - 56px)); }
  /* Desktop: the form compacts to fit (tiers below) so the modal-body
     never needs its own scrollbar — operator: "user shouldn't need to
     scroll". `.a-form` keeps overflow-y:auto purely as an extreme
     last-resort safety on absurdly short desktop windows. */
  .modal-shell:has(.auth) .modal-body { overflow: hidden; }
  .auth .a-form { overflow-y: auto; }
}

/* Responsive vertical compaction — progressively tighten the form so
   the TALLER register layout fits the locked height (and short
   viewports) with zero internal scrolling. Login is shorter so it
   only ever has MORE breathing room at each tier; both modes keep
   the identical outer size from the lock above. */
@media (max-height: 820px) {
  .auth .a-form { padding: 30px 40px; gap: 14px; }
  .auth .a-title { font-size: 25px; }
  .auth .field { gap: 6px; }
  .auth .field input,
  .auth .a-code-input { padding: 11px 14px; }
  .auth .a-eye { width: 34px; height: 34px; }
  .auth .a-social button { height: 44px; }
  .auth .a-side-legal { padding: 48px 30px 22px; }
}
@media (max-height: 700px) {
  .auth .a-form { padding: 22px 36px; gap: 11px; }
  .auth .a-head { gap: 4px; }
  .auth .a-title { font-size: 22px; }
  .auth .a-sub { font-size: 12.5px; }
  .auth .field { gap: 5px; }
  .auth .field label { font-size: 12px; }
  .auth .field input,
  .auth .a-code-input { padding: 10px 12px; font-size: 13.5px; }
  .auth .field .hint { display: none; }            /* non-essential */
  .auth .a-checks { gap: 9px; }
  .auth .a-submit { padding: 13px 18px; }
  .auth .a-divider { margin: 0; }
  .auth .a-social button { height: 40px; }
  .auth .a-side-legal { padding: 40px 26px 18px; font-size: 11px; }
}
@media (max-height: 580px) {
  .auth .a-form { padding: 16px 28px; gap: 9px; }
  .auth .a-title { font-size: 20px; }
  .auth .field input,
  .auth .a-code-input { padding: 9px 12px; }
  .auth .a-divider { display: none; }              /* drop the OR rule */
  .auth .a-social { gap: 8px; }
  .auth .a-social button { height: 38px; }
}

/* Left artwork panel. Background stack, top → bottom:
     1. The user's brand artwork (/img/auth-side.png), `cover`.
     2. Gold radial glow — picks up the artwork's brand tones.
     3. Dark token floor — guarantees zero transparency and matches
        the rest of the app's dark theme if the PNG is missing.
   The bottom legal scrim is its own element (.a-side-legal, styled
   in styles.css) so it stays crisp over any artwork tone. */
.auth .a-side.a-side-image {
  padding: 0;
  background-color: var(--bg-3, #1F1F24);
  background-position: center, center, center;
  background-size: cover, 100% 100%, 100% 100%;
  background-repeat: no-repeat;
  /* PNG declaration first as the universal fallback; the image-set
     declaration below overrides it in browsers that support WebP (all
     current ones), cutting this always-loaded panel from ~1.9MB to
     ~100KB. Non-supporting browsers ignore the second rule and keep the
     PNG, so nothing breaks. */
  background-image:
    url('/img/auth-side.png'),
    radial-gradient(70% 60% at 35% 30%, rgba(52, 192, 235, .22), transparent 70%),
    linear-gradient(180deg, var(--bg-2, #16161C) 0%, var(--bg-0, #0A0A0E) 100%);
  background-image:
    image-set(url('/img/auth-side.webp') type('image/webp'), url('/img/auth-side.png') type('image/png')),
    radial-gradient(70% 60% at 35% 30%, rgba(52, 192, 235, .22), transparent 70%),
    linear-gradient(180deg, var(--bg-2, #16161C) 0%, var(--bg-0, #0A0A0E) 100%);
  border-right: 1px solid var(--line);
  overflow: hidden;
  display: block;
}
.auth .a-side.a-side-image::after { display: none; }

/* =========================================================
   PHASE 2: HOMEPAGE LAYOUT — Casino/Sports in .brand, logo in .topbar
   Customer spec: move the Casino/Sports toggle to the very top-left
   where the logo used to sit; move the SPINARMORY wordmark into the
   topbar header.
   ========================================================= */

/* Brand corner now shows the Casino/Sports pill instead of the logo.
   Shrink the pill to fit the rail-w column and keep the rail-toggle
   on the right. */
.brand .brand-pill-toggle {
  flex: 1;
  display: flex;
  min-width: 0;
  padding: 3px;
  height: 34px;
}
.brand .brand-pill-toggle button {
  flex: 1;
  padding: 4px 8px;
  font-size: 11px;
  letter-spacing: .06em;
  min-width: 0;
  white-space: nowrap;
}
.rail-collapsed .brand .brand-pill-toggle { display: none; }

/* Topbar brand — the SPINARMORY wordmark now lives here. */
.topbar .topbar-brand {
  display: inline-flex;
  align-items: center;
  margin-right: 20px;
  font-family: var(--font-display);
  font-size: 20px;
  letter-spacing: .04em;
  color: var(--text);
  user-select: none;
}
.topbar .topbar-brand .logo-bracket { color: var(--accent); }
.topbar .topbar-brand .logo-glyph {
  color: var(--accent);
  margin: 0 1px;
  font-size: .9em;
}
@media (max-width: 1180px) {
  .topbar .topbar-brand { font-size: 17px; margin-right: 12px; }
}
@media (max-width: 860px) {
  .topbar .topbar-brand { display: none; }
}

/* =========================================================
   PHASE 1: INPUT SOFTENING
   Customer feedback: white borders on input fields are too stark.
   Swap them for a subtle fill + near-invisible border (chips.gg style).
   ========================================================= */
/* NOTE: .gp-input and .gp-input input are intentionally EXCLUDED from this
   block — game pages get their own (cleaner, less glowy) treatment in
   styles.css under the /* GAME PAGE */ section. The double-rectangle
   artifact users were seeing was caused by these !important rules
   overriding the gp-input styling, so they're scoped out here. */
.auth-modal input[type="text"],
.auth-modal input[type="email"],
.auth-modal input[type="password"],
.sc-field input,
.sc-input input,
.dw-input,
.slots-search input,
.redeem-box input,
.chat-input input,
.search input,
.settings-card input[type="text"],
.settings-card input[type="email"],
.settings-card input[type="password"],
.settings-card input[type="number"],
.field input {
  background: var(--white-04) !important;
  border: 1px solid var(--white-06) !important;
  transition: border-color .15s, background .15s !important;
}
.auth-modal input:focus,
.sc-field input:focus,
.sc-input input:focus,
.dw-input:focus,
.chat-input input:focus,
.settings-card input:focus,
.field input:focus {
  outline: none !important;
  border-color: var(--accent-40) !important;
  background: var(--white-06) !important;
}
.slots-search input:focus,
.search input:focus {
  outline: none !important;
  border-color: var(--white-06) !important;
  background: var(--white-04) !important;
}
/* Input wrappers (that have the border instead of the input).
   .gp-input is excluded — see note above. */
.search,
.slots-search,
.chat-input,
.sc-input {
  border-color: var(--white-06) !important;
  background: rgba(255,255,255,.03) !important;
}
.chat-input:focus-within,
.sc-input:focus-within {
  border-color: var(--accent-40) !important;
}
.search:focus-within,
.slots-search:focus-within {
  border-color: var(--white-06) !important;
}


/* ==========================================================================
   VIP RANKING SYSTEM (v3) — uses home-page design tokens (.frame, .chamfer,
   .sec-head, .scroller) so the look is identical to the rest of the site.
   No custom blue/purple banners, no custom scrollbar — everything inherits.
   ========================================================================== */
/* PDF audit: page-level max-width container so the VIP page doesn't
   sprawl on 2K+ monitors. The inline padding clamps from 16px on phones
   to 32px on wide desktops. Other player-facing pages can adopt the
   same `.page-shell-wide` token if/when we promote this pattern. */
.vip-v3 {
  display: flex; flex-direction: column;
  max-width: 1280px;
  margin-inline: auto;
  width: 100%;
  padding-inline: clamp(16px, 4vw, 32px);
}

/* ---- Hero banner — modeled after .hero-main / .hero-card ---- */
/* P4-2: softer, modernised hero gradient. Operator brief was the hero
   "is not good for the eyes" with the old icons + saturated radials.
   This version: subtler dark→panel base, refined amber-to-violet
   diagonal sweep instead of two competing corner radials, and a
   slimmer top hairline so the card reads as a single object. */
.vip-hero-banner {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 22px; align-items: center;
  padding: 26px 28px;
  background:
    linear-gradient(135deg,
      rgba(52, 192, 235, .10) 0%,
      rgba(52, 192, 235, .03) 35%,
      rgba(124, 92, 255, .04) 70%,
      rgba(61, 126, 255, .08) 100%),
    linear-gradient(180deg, var(--bg-2) 0%, var(--bg-3, var(--bg-2)) 100%);
  border: 1px solid rgba(52, 192, 235, .15);
  margin: 6px 0 4px;
  --c: 18px;
  clip-path: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)),
                     calc(100% - var(--c)) 100%, 0 100%, 0 var(--c));
  overflow: hidden;
}
.vip-hero-banner::before {
  /* Soft light streak across the top — replaces the harsh radial
     glows that made the old hero feel busy. */
  content: ""; position: absolute;
  top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(52, 192, 235, .35), transparent);
  pointer-events: none;
}
.vip-hero-banner::after{
  /* Subtle ambient glow concentrated bottom-right, well behind the
     content so it doesn't compete with the trophy/stars art. */
  content:""; position:absolute; inset:0; pointer-events:none;
  background: radial-gradient(50% 70% at 100% 100%, rgba(124, 92, 255, .08), transparent 70%);
}
.vhb-art-l, .vhb-art-r { position: relative; z-index: 1; display: grid; place-items: center; flex-shrink: 0; }
.vhb-text { position: relative; z-index: 2; min-width: 0; }
.vhb-kicker {
  display: block;
  font-family: var(--font-display); font-size: 11px;
  letter-spacing: .2em; color: var(--accent);
  margin-bottom: 6px;
}
.vhb-title {
  font-family: var(--font-display); font-size: clamp(22px, 3vw, 32px);
  color: var(--text); margin: 0 0 8px; text-transform: uppercase;
  letter-spacing: -.01em; line-height: 1;
}
.vhb-title em { color: var(--accent); font-style: normal; }
.vhb-sub {
  margin: 0 0 14px;
  color: var(--text-dim); font-size: 13.5px; line-height: 1.5;
  max-width: 56ch;
}
.vhb-stats { display: flex; flex-wrap: wrap; gap: 18px; margin-bottom: 12px; }
.vhb-stat .k {
  font-family: var(--font-display); font-size: 10px;
  letter-spacing: .15em; color: var(--text-mute); text-transform: uppercase;
}
.vhb-stat .v {
  font-family: var(--font-display); font-size: 16px;
  color: var(--text); margin-top: 4px;
  display: inline-flex; align-items: center; gap: var(--space-2);
}
.vhb-stat .v em { color: var(--accent); font-style: normal; }
.vhb-bar {
  position: relative;
  height: 8px; border-radius: var(--radius-xs);
  background: rgba(255,255,255,.05);
  overflow: hidden;
  max-width: 420px;
  margin-top: 6px;
}
.vhb-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-bright));
  transition: width .35s ease;
  box-shadow: 0 0 12px var(--accent-glow);
}
.vhb-bar-pct {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  font-family: var(--font-display); font-size: 10px;
  color: var(--on-accent); font-weight: 700;
}

@media (max-width: 720px) {
  .vip-hero-banner { grid-template-columns: 1fr; padding: 18px 18px; }
  .vhb-art-r { display: none; }
  .vhb-stats { gap: var(--space-6); }
}

/* ---- Reward row — uses .frame.chamfer just like home hero-cards ---- */
.vrewards-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  margin-top: 18px;
}
/* PDF p.12 audit: row dropped to 3 cards. The 4-card class is kept as
   a no-op alias so any legacy callsite renders 3-up gracefully. */
.vrewards-row.vrewards-row-3,
.vrewards-row.vrewards-row-4 { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
@media (max-width: 1100px) {
  .vrewards-row,
  .vrewards-row.vrewards-row-3,
  .vrewards-row.vrewards-row-4 { grid-template-columns: repeat(2, 1fr); gap: 14px; }
}
@media (max-width: 720px) {
  .vrewards-row,
  .vrewards-row.vrewards-row-3,
  .vrewards-row.vrewards-row-4 { grid-template-columns: 1fr; gap: 12px; }
}

/* ============================================================
   PDF p.11/12 audit redesign — image-led reward card (.vrw-v2).
   Each card is a vertical stack: full-bleed gradient art band +
   content footer. The legacy `.vrw` rules below this block are
   kept for any non-VIP callsite, but the VIP page now uses .vrw-v2.
   ============================================================ */
.vrw {
  position: relative;
  background: var(--bg-2);
  --c: 14px;
  display: flex; flex-direction: column; align-items: stretch;
  overflow: hidden;
  transition: transform .15s ease, box-shadow .15s ease;
  padding: 0;
}
.vrw-v2 {
  /* Override the legacy padded-on-all-sides layout — art band is
     edge-to-edge, body owns its own padding. */
  padding: 0;
}
.vrw.ready:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 28px rgba(0,0,0,.35);
}

/* ── Art band ── */
.vrw-v2 .vrw-art-band {
  position: relative;
  height: 132px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.vrw-v2 .vrw-art-grad {
  position: absolute; inset: 0;
  background: linear-gradient(135deg,
    var(--vrw-grad-from, #1f4e3d) 0%,
    var(--vrw-grad-to, #0d2e26) 100%);
  opacity: .95;
}
.vrw-v2[data-tone="instant"] {
  --vrw-grad-from: #1f8459;
  --vrw-grad-to:   #0c4a32;
}
.vrw-v2[data-tone="weekly"] {
  --vrw-grad-from: #1d8b9e;
  --vrw-grad-to:   #0c4d59;
}
.vrw-v2[data-tone="monthly"] {
  --vrw-grad-from: #d18a36;
  --vrw-grad-to:   #7c4810;
}
.vrw-v2 .vrw-art-band::after {
  /* Subtle inner highlight to give the gradient depth. */
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(120% 120% at 50% -20%, rgba(255,255,255,.18), transparent 65%);
  pointer-events: none;
}
.vrw-v2 .vrw-art-icon {
  position: relative;
  z-index: 1;
  filter: drop-shadow(0 6px 14px rgba(0,0,0,.45));
  transition: transform .25s ease;
}
.vrw-v2.ready:hover .vrw-art-icon { transform: scale(1.04); }

/* ── Status pill (overlaid on art band, top-left) ── */
.vrw-v2 .vrw-status {
  position: absolute;
  top: 12px; left: 12px;
  z-index: 2;
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-display); font-size: 10px; letter-spacing: .08em;
  color: rgba(255,255,255,.92);
  padding: 4px 9px; border-radius: 999px;
  background: rgba(0,0,0,.45);
  border: 1px solid rgba(255,255,255,.18);
  text-transform: uppercase;
  backdrop-filter: blur(2px);
}
.vrw-v2.ready .vrw-status {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}
.vrw-v2 .vrw-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 8px currentColor;
  opacity: .9;
}

/* ── Body ── */
.vrw-v2 .vrw-body {
  padding: 16px 18px 18px;
  display: flex; flex-direction: column;
  gap: 8px;
}
.vrw-v2 .vrw-title {
  font-family: var(--font-display); font-size: 16px;
  color: var(--text); letter-spacing: .02em;
  text-transform: uppercase;
  margin: 0;
}
.vrw-v2 .vrw-sub {
  font-size: 12px; color: var(--text-mute); line-height: 1.45;
  margin-bottom: 4px;
  min-height: 34px;          /* reserve space so cards align even when
                                one subtitle wraps to 2 lines */
}
.vrw-v2 .vrw-btn { margin-top: 4px; }

/* ── Buttons (shared with legacy .vrw) ── */
.vrw-btn {
  appearance: none; cursor: pointer; border: 0;
  width: 100%;
  padding: 11px 12px;
  font-family: var(--font-display); font-weight: 700; font-size: 12px; letter-spacing: .1em;
  border-radius: var(--radius-sm);
  background: var(--white-04);
  color: var(--text-mute);
  transition: filter .15s;
  text-transform: uppercase;
}
.vrw-btn.on {
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
  color: var(--on-accent);
  box-shadow: 0 6px 18px var(--accent-glow);
}
.vrw-btn.on:hover { filter: brightness(1.05); }
.vrw-btn:disabled { cursor: not-allowed; }

@media (max-width: 720px) {
  .vrw-v2 .vrw-art-band { height: 104px; }
  .vrw-v2 .vrw-body { padding: 14px 14px 16px; }
}

@media (max-width: 720px) {
  .vrewards-row { grid-template-columns: 1fr; }
}

/* ---- Tier scroller (uses home `.scroller` class — inherits site
        scrollbar + scroll-snap behaviour from styles.css) ----
        PDF audit polish: bumped tier-card width 156→172 so the
        level-up CTA on `has-claim` cards has breathing room from
        the rank label, and added scroll-padding for snap stops. */
.scroller.vtier-scroller {
  grid-auto-columns: 172px;
  gap: var(--space-5);
  scroll-padding-inline: 12px;
  scroll-snap-type: x mandatory;
}
.vtier {
  position: relative;
  padding: 20px 14px 16px;
  background: var(--bg-2);
  --c: 12px;
  display: flex; flex-direction: column; align-items: center; gap: var(--space-3);
  transition: transform .15s;
  overflow: hidden;
  scroll-snap-align: start;
  height: 100%;
  min-height: 210px;
}
/* Phase 26.7e — when a tier card carries a pending Claim button, the
   button is absolute-positioned at the bottom. Reserve enough bottom
   padding so the .vtier-lvl pill + .vtier-progress bar above don't
   slide under it. ~50px = button height + gap. */
.vtier.has-claim { padding-bottom: 50px; }
.vtier.locked .vtier-badge,
.vtier.locked .vtier-name { opacity: .55; }
.vtier.locked { background: rgba(255,255,255,.015); }
.vtier.reached { background: var(--bg-2); }
.vtier.current {
  background: rgba(52,192,235,.06);
  transform: translateY(-2px);
}
.vtier.current::before {
  /* override the .frame top hairline to be solid amber, not the gradient one */
  background: rgba(52,192,235,.55) !important;
}
.vtier-current-pill {
  position: absolute; top: 6px; right: 6px;
  padding: 3px 7px;
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
  color: var(--on-accent);
  font-family: var(--font-display); font-size: 8.5px; font-weight: 800;
  letter-spacing: .14em;
  border-radius: var(--radius-xs);
  z-index: 2;
}
.vtier-badge {
  width: 64px; height: 64px;
  display: grid; place-items: center;
  margin: 4px 0 4px;
}
.vtier-name {
  font-family: var(--font-display); font-size: 14px;
  letter-spacing: .03em; text-transform: uppercase;
  color: var(--text); text-align: center; line-height: 1.1;
}
.vtier-xp {
  font-family: var(--font-display); font-size: 11px;
  color: var(--accent); letter-spacing: .06em;
  margin-top: -2px;
}
.vtier-lvl {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 10px;
  background: rgba(255,255,255,.03);
  border-radius: var(--radius-xs);
  font-family: var(--font-display); font-size: 10px;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-dim);
  margin-top: 4px;
}
.vtier.reached .vtier-lvl { color: var(--accent); background: rgba(52,192,235,.08); }
/* Phase 27 polish — `.vtier-lock` rule removed; the 🔒 emoji is no
   longer rendered (see vip-page.jsx). The reached-state checkmark
   below stays. */
.vtier-check { font-size: 11px; color: var(--accent); }

/* Phase 26.7e — per-tier progress indicator. Customer asked (per PDF)
   to add a bar on each NEXT-rank tier showing how close the user is
   to unlocking it. Reached tiers show 100% (gold solid); the next
   un-reached tier shows live progress; further locked tiers show 0%. */
.vtier-progress {
  width: 100%;
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.vtier-progress-bar {
  width: 100%;
  height: 6px;
  background: rgba(255, 255, 255, .05);
  border-radius: 999px;
  overflow: hidden;
  position: relative;
}
.vtier-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #4ee6a8, var(--accent));
  border-radius: 999px;
  transition: width .35s ease;
}
.vtier.reached .vtier-progress-fill {
  background: linear-gradient(90deg, var(--accent), #6FD4F2);
}
.vtier-progress-pct {
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: .12em;
  color: var(--text-mute);
  font-weight: 700;
}
.vtier.reached .vtier-progress-pct,
.vtier.current .vtier-progress-pct {
  color: var(--accent);
}

/* ---- Benefits grid — each row is a frame.chamfer-sm card ---- */
.vbenefits-grid-v3 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
}
@media (max-width: 720px) { .vbenefits-grid-v3 { grid-template-columns: 1fr; } }
.vbenefit-row {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: var(--space-6); align-items: flex-start;
  padding: 16px 18px;
  background: var(--bg-2);
  --c: 10px;
  transition: transform .15s, background .15s;
}
.vbenefit-row:hover { background: rgba(52,192,235,.04); transform: translateY(-1px); }
.vbenefit-hex {
  position: relative;
  width: 64px; height: 64px;
  display: grid; place-items: center;
  flex-shrink: 0;
}
.vbenefit-text { min-width: 0; padding-top: 2px; }
.vbenefit-title {
  font-family: var(--font-display); font-size: 15px;
  color: var(--text); margin-bottom: 4px;
  letter-spacing: .015em; text-transform: uppercase;
}
.vbenefit-desc {
  font-family: var(--font-ui); font-size: 12.5px;
  color: var(--text-dim); line-height: 1.55;
}

/* ---- FAQ list ---- */
.vip-faq-list {
  display: flex; flex-direction: column; gap: var(--space-3);
}
.vfaq-row {
  background: var(--bg-2);
  --c: 10px;
  overflow: hidden;
}
.vfaq-row.open { background: rgba(52,192,235,.03); }
.vfaq-head {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px;
  background: transparent; border: 0; cursor: pointer;
  font-family: var(--font-ui); font-size: 14px; font-weight: 600;
  color: var(--text); text-align: left;
  transition: color .15s;
}
.vfaq-row:hover .vfaq-head { color: var(--accent); }
.vfaq-chev {
  font-family: var(--font-display); font-size: 16px;
  color: var(--accent); flex-shrink: 0;
  margin-left: 16px;
  /* PDF audit polish: chevron rotates smoothly when the row opens,
     matching the .15s hover transitions used elsewhere on the page. */
  transition: transform .15s ease;
}
.vfaq-row.open .vfaq-chev { transform: rotate(180deg); }
.vfaq-body {
  padding: 0 18px 16px;
  color: var(--text-dim);
  font-size: 13.5px; line-height: 1.65;
}

/* ---- CTA band when logged out — uses frame.chamfer like home cards ---- */
.vip-v3 .vip-cta-band {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-7);
  padding: 22px 26px;
  background: var(--bg-2);
  --c: 14px;
}
.vip-v3 .vip-cta-band::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background: radial-gradient(40% 80% at 100% 50%, rgba(52,192,235,.12), transparent 60%);
}
.vip-v3 .vcb-k {
  font-family: var(--font-display); font-size: 16px;
  color: var(--text); letter-spacing: .01em;
  text-transform: uppercase;
}
.vip-v3 .vcb-s {
  font-size: 12.5px; color: var(--text-dim); margin-top: 4px;
}
@media (max-width: 720px) {
  .vip-v3 .vip-cta-band { flex-direction: column; align-items: stretch; }
}

/* ============================================================
   VIP page — V3 motion rework
   ------------------------------------------------------------
   Layered animations + scroll reveals + interactive hover/tilt.
   All autoplay loops are gated behind
       @media (prefers-reduced-motion: no-preference)
   so the OS-level toggle silences every continuous animation.
   Per-interaction effects (hover lift / tilt / chevron rotate)
   stay live on every surface — they only run on user input.

   Companion JSX: src/vip-page.jsx (V3 helpers + components).
   ============================================================ */

/* ---- Particle field (used by hero + CTA band) ---------------------- */
.vip-pf {
  position: absolute; inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 1;
}
.vip-pf-dot {
  position: absolute;
  bottom: -10px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--accent-bright, #6FD4F2) 0%, transparent 70%);
  opacity: 0;
  will-change: transform, opacity;
}
.vip-pf[data-tone="royal"] .vip-pf-dot {
  background: radial-gradient(circle, #c6e2ff 0%, transparent 70%);
}
@media (prefers-reduced-motion: no-preference) {
  .vip-pf-dot {
    animation: vipParticleRise infinite ease-in-out;
  }
  @keyframes vipParticleRise {
    0%   { transform: translate3d(0, 0, 0) scale(.6); opacity: 0; }
    15%  { opacity: .8; }
    85%  { opacity: .35; }
    100% { transform: translate3d(var(--vip-drift, 0px), -120%, 0) scale(1); opacity: 0; }
  }
}

/* ---- Confetti burst (used by reward card + tier claim) ------------- */
.vip-burst {
  position: absolute;
  left: 50%; top: 50%;
  width: 0; height: 0;
  pointer-events: none;
  z-index: 4;
}
.vip-burst-p {
  position: absolute;
  left: 0; top: 0;
  width: 6px; height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--accent-bright, #6FD4F2) 30%, var(--accent, #34c0eb) 100%);
  box-shadow: 0 0 6px var(--accent-glow, rgba(52,192,235,.6));
  opacity: 0;
  will-change: transform, opacity;
}
.vip-burst[data-tone="royal"] .vip-burst-p {
  background: radial-gradient(circle, #c6e2ff 30%, #7c5cff 100%);
  box-shadow: 0 0 6px rgba(124,92,255,.6);
}
.vip-burst[data-tone="weekly"] .vip-burst-p {
  background: radial-gradient(circle, #A6E4F6 30%, #34c0eb 100%);
}
.vip-burst[data-tone="monthly"] .vip-burst-p {
  background: radial-gradient(circle, #c6e2ff 30%, #7c5cff 100%);
}
@media (prefers-reduced-motion: no-preference) {
  .vip-burst-p {
    animation: vipBurstParticle cubic-bezier(.18, .8, .3, 1) forwards;
  }
  @keyframes vipBurstParticle {
    0%   { transform: translate(0, 0) scale(.4); opacity: 0; }
    18%  { opacity: 1; }
    100% {
      transform: rotate(var(--ang, 0deg)) translate(var(--dist, 60px), 0) scale(1.05);
      opacity: 0;
    }
  }
}

/* ---- Progress ring (used by hero) ---------------------------------- */
.vip-ring {
  position: relative;
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
.vip-ring svg {
  display: block;
  filter: drop-shadow(0 6px 22px var(--accent-glow, rgba(52,192,235,.35)));
}
.vip-ring-num {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  text-align: center;
  font-family: var(--font-display);
  color: var(--text);
  pointer-events: none;
}
.vip-ring-num strong {
  display: block;
  font-size: clamp(40px, 5vw, 56px);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1;
  background: linear-gradient(180deg, var(--accent-bright, #6FD4F2), var(--accent, #34c0eb));
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.vip-ring-num span {
  display: block;
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .18em;
  color: var(--text-mute);
  text-transform: uppercase;
}

/* ---- Hero V3 ------------------------------------------------------- */
.vip-hero-v3 {
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-8, 24px);
  padding: clamp(20px, 3vw, 36px) clamp(20px, 3vw, 40px);
  isolation: isolate;
}
.vip-hero-v3 .vhb-text {
  position: relative;
  z-index: 2;
  min-width: 0;
}
.vip-hero-v3 .vhb-stage {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
  width: clamp(180px, 26vw, 232px);
  height: clamp(180px, 26vw, 232px);
}
.vip-hero-v3 .vhb-badge {
  position: absolute;
  inset: 22%;
  display: grid;
  place-items: center;
}
.vip-hero-v3 .vhb-badge-ring {
  position: absolute;
  inset: -10%;
  width: 120%;
  height: 120%;
  pointer-events: none;
  filter: drop-shadow(0 0 6px var(--accent-glow, rgba(52,192,235,.4)));
}
.vip-hero-v3 .vhb-badge-icon {
  position: relative;
  display: grid;
  place-items: center;
  z-index: 1;
}
.vip-hero-v3 .vhb-badge-fallback {
  font-family: var(--font-display);
  font-size: 64px;
  color: var(--accent, #34c0eb);
}
@media (prefers-reduced-motion: no-preference) {
  .vip-hero-v3 .vhb-badge-ring {
    animation: vipBadgeRingSpin 14s linear infinite;
  }
  .vip-hero-v3 .vhb-badge-icon {
    animation: vipBadgeBreath 4s ease-in-out infinite;
    transform-origin: center;
  }
  @keyframes vipBadgeRingSpin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
  }
  @keyframes vipBadgeBreath {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.025); }
  }
}
.vip-hero-v3 .vip-hero-orb {
  position: absolute;
  left: 50%; top: 50%;
  width: 60%; height: 100%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgba(52,192,235,.22) 0%, transparent 60%);
  pointer-events: none;
  z-index: 0;
}
.vip-hero-v3 .vip-hero-grid {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(120deg, transparent 49.5%, rgba(52,192,235,.06) 50%, transparent 50.5%) 0 0 / 28px 28px,
    linear-gradient(60deg,  transparent 49.5%, rgba(148,163,209,.04) 50%, transparent 50.5%) 0 0 / 28px 28px;
  pointer-events: none;
  z-index: 0;
  opacity: .6;
  mask-image: radial-gradient(ellipse at center, #000 30%, transparent 80%);
}
@media (prefers-reduced-motion: no-preference) {
  .vip-hero-v3 .vip-hero-orb {
    animation: vipHeroOrbPulse 12s ease-in-out infinite;
  }
  @keyframes vipHeroOrbPulse {
    0%, 100% { opacity: .55; transform: translate(-50%, -50%) scale(.92); }
    50%      { opacity: 1;   transform: translate(-50%, -50%) scale(1.05); }
  }
}
/* Hero text intro stagger — kicker, h1, sub each carry a
   --vhb-stagger inline delay. */
.vhb-anim {
  opacity: 0;
  transform: translateY(8px);
  animation: vipHeroIntroSlideUp .65s cubic-bezier(.4,.8,.3,1.1) forwards;
  animation-delay: var(--vhb-stagger, 0ms);
}
@media (prefers-reduced-motion: reduce) {
  .vhb-anim { opacity: 1; transform: none; animation: none; }
}
@keyframes vipHeroIntroSlideUp {
  to { opacity: 1; transform: translateY(0); }
}

/* Stat tile hover — subtle accent border */
.vip-hero-v3 .vhb-stat {
  transition: border-color var(--t-base, .15s) ease, background var(--t-base, .15s) ease;
}
.vip-hero-v3 .vhb-stat:hover {
  border-color: rgba(52,192,235,.38);
  background: rgba(52,192,235,.04);
}

/* Hero responsive — stack on tablet, smaller ring on mobile */
@media (max-width: 860px) {
  .vip-hero-v3 {
    grid-template-columns: 1fr;
    text-align: left;
  }
  .vip-hero-v3 .vhb-stage {
    width: clamp(160px, 50vw, 220px);
    height: clamp(160px, 50vw, 220px);
    margin: 0 auto;
  }
}
@media (max-width: 540px) {
  .vip-hero-v3 .vip-pf .vip-pf-dot:nth-child(2n) { display: none; }
  .vip-hero-v3 { padding: 18px 16px; }
}

/* ---- Reward card V3 ----------------------------------------------- */
.vrw-v3 {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transform: perspective(800px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)) translateZ(0);
  transform-style: preserve-3d;
  transition: transform var(--t-base, .15s) ease, box-shadow var(--t-base, .15s) ease;
}
.vrw-v3:hover {
  transform: perspective(800px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)) translateY(-4px);
  box-shadow: var(--shadow-accent, 0 14px 32px rgba(52,192,235,.18));
}
.vrw-v3 .vrw-orb {
  position: absolute;
  left: -10%; top: -20%;
  width: 220px; height: 220px;
  border-radius: 50%;
  background: conic-gradient(from 0deg, var(--accent-glow, rgba(52,192,235,.3)) 0deg, transparent 140deg, var(--accent-glow, rgba(52,192,235,.3)) 360deg);
  filter: blur(20px);
  opacity: .5;
  pointer-events: none;
  z-index: 0;
  will-change: transform;
}
.vrw-v3[data-tone="instant"] .vrw-orb {
  background: conic-gradient(from 0deg, rgba(94,201,143,.45) 0deg, transparent 140deg, rgba(124,92,255,.35) 360deg);
}
.vrw-v3[data-tone="weekly"] .vrw-orb {
  background: conic-gradient(from 0deg, rgba(246,213,117,.55) 0deg, transparent 140deg, rgba(52,192,235,.45) 360deg);
}
.vrw-v3[data-tone="monthly"] .vrw-orb {
  background: conic-gradient(from 0deg, rgba(124,92,255,.55) 0deg, transparent 140deg, rgba(61,126,255,.45) 360deg);
}
@media (prefers-reduced-motion: no-preference) {
  .vrw-v3 .vrw-orb { animation: vipRewardOrbSpin 18s linear infinite; }
  @keyframes vipRewardOrbSpin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
  }
}
.vrw-v3 .vrw-spark {
  position: absolute;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, var(--accent-bright, #6FD4F2) 35%, transparent 70%);
  box-shadow: 0 0 8px var(--accent-bright, #6FD4F2);
  pointer-events: none;
  z-index: 2;
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .vrw-v3 .vrw-spark {
    animation: vipRewardSparkle 2.4s ease-in-out infinite;
  }
  @keyframes vipRewardSparkle {
    0%, 100% { transform: scale(.4); opacity: 0; }
    50%      { transform: scale(1.2); opacity: .9; }
  }
}
/* Ensure the orb + sparkles sit BEHIND the art band */
.vrw-v3 .vrw-art-band, .vrw-v3 .vrw-body { position: relative; z-index: 2; }
/* Claim button — ready-state pulse */
.vrw-v3 .vrw-btn-wrap {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: 100%;
}
.vrw-v3 .vrw-btn.on {
  position: relative;
  z-index: 1;
}
@media (prefers-reduced-motion: no-preference) {
  .vrw-v3 .vrw-btn.on {
    animation: vipReadyPulse 2s ease-in-out infinite;
  }
  @keyframes vipReadyPulse {
    0%, 100% { box-shadow: 0 4px 14px rgba(52,192,235,.25); }
    50%      { box-shadow: 0 8px 30px rgba(52,192,235,.55); }
  }
}
/* Subtitle scroll-reveal */
.vrw-v3 .vrw-sub {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .5s ease, transform .5s ease;
}
.vrw-v3.in-view .vrw-sub {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .vrw-v3 .vrw-sub { opacity: 1; transform: none; }
}

/* ---- Tier card V3 ------------------------------------------------- */
.vtier-v3 {
  position: relative;
  overflow: visible;
  opacity: 0;
  transform: translateY(12px);
  animation: vipTierStaggerIn .55s cubic-bezier(.4,.8,.3,1.1) forwards;
  animation-delay: var(--vtier-stagger, 0ms);
  transition: transform var(--t-base, .15s) ease, box-shadow var(--t-base, .15s) ease, border-color var(--t-base, .15s) ease;
}
@keyframes vipTierStaggerIn {
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .vtier-v3 { opacity: 1; transform: none; animation: none; }
}
.vtier-v3:hover {
  transform: translateY(-3px) scale(1.015);
  box-shadow: var(--shadow-accent, 0 14px 32px rgba(52,192,235,.18));
}
.vtier-v3.locked:hover {
  /* Locked tiers don't lift — they're not earned yet */
  transform: translateY(0);
  box-shadow: none;
}
/* Locked tier — subtle gradient sweep ("if only…") */
.vtier-v3.locked::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg,
    transparent 30%,
    rgba(255,255,255,.045) 50%,
    transparent 70%);
  background-size: 200% 100%;
  background-position: -100% 0;
  pointer-events: none;
  z-index: 1;
  border-radius: inherit;
}
@media (prefers-reduced-motion: no-preference) {
  .vtier-v3.locked::after {
    animation: vipTierShimmer 6s ease-in-out infinite;
    animation-delay: 2s;
  }
  @keyframes vipTierShimmer {
    0%, 60%, 100% { background-position: -100% 0; }
    80%           { background-position: 200% 0; }
  }
}
/* Current tier — rotating dashed gold halo around the badge */
.vtier-v3 .vtier-halo {
  position: absolute;
  left: 50%;
  top: 18px;
  width: 76px;
  height: 76px;
  margin-left: -38px;
  pointer-events: none;
  z-index: 0;
  filter: drop-shadow(0 0 6px var(--accent-glow, rgba(52,192,235,.5)));
}
@media (prefers-reduced-motion: no-preference) {
  .vtier-v3 .vtier-halo {
    animation: vipCurrentHalo 9s linear infinite;
  }
  @keyframes vipCurrentHalo {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
  }
}
.vtier-v3 .vtier-badge { position: relative; z-index: 1; }
/* "▼ YOU" chip floating above the current tier */
.vtier-v3 .vtier-you {
  position: absolute;
  top: -14px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--accent, #34c0eb);
  color: var(--on-accent, #1A1205);
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .14em;
  padding: 3px 8px;
  border-radius: 4px;
  z-index: 3;
  box-shadow: 0 6px 14px var(--accent-glow, rgba(52,192,235,.45));
}
.vtier-v3 .vtier-you span {
  display: inline-block;
  margin-right: 3px;
  font-family: var(--font-display);
}
@media (prefers-reduced-motion: no-preference) {
  .vtier-v3 .vtier-you {
    animation: vipChipFloat 2.4s ease-in-out infinite;
  }
  @keyframes vipChipFloat {
    0%, 100% { transform: translateX(-50%) translateY(0); }
    50%      { transform: translateX(-50%) translateY(-2px); }
  }
}
/* Animated progress fill — width transitions on XP change */
.vtier-v3 .vtier-progress-fill {
  transition: width .7s cubic-bezier(.4,.8,.3,1.1);
  position: relative;
}
.vtier-v3 .vtier-progress-fill::after {
  content: "";
  position: absolute;
  right: -2px; top: -1px; bottom: -1px;
  width: 4px;
  background: var(--accent-bright, #6FD4F2);
  border-radius: 2px;
  box-shadow: 0 0 8px var(--accent-glow, rgba(52,192,235,.6));
  opacity: .8;
}
/* Has-claim — rim glow + floating $X chip */
.vtier-v3.has-claim {
  border-color: var(--accent, #34c0eb);
}
@media (prefers-reduced-motion: no-preference) {
  .vtier-v3.has-claim {
    animation: vipReadyPulse 2s ease-in-out infinite;
    animation-delay: var(--vtier-stagger, 0ms);
  }
}
.vtier-v3 .vtier-claim-wrap { position: relative; }
.vtier-v3 .vtier-claim-chip {
  position: absolute;
  top: -36px; right: 0;
  background: var(--accent, #34c0eb);
  color: var(--on-accent, #1A1205);
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .04em;
  padding: 4px 9px;
  border-radius: 6px;
  box-shadow: 0 6px 14px var(--accent-glow, rgba(52,192,235,.5));
  pointer-events: none;
  z-index: 2;
}
@media (prefers-reduced-motion: no-preference) {
  .vtier-v3 .vtier-claim-chip {
    animation: vipChipFloat 2.4s ease-in-out infinite;
  }
}

/* ---- Benefits grid V3 --------------------------------------------- */
.vbenefits-v3 .vbenefit-row-v3 {
  position: relative;
  opacity: 0;
  transform: translateY(8px);
  transition: transform var(--t-base, .15s) ease, box-shadow var(--t-base, .15s) ease, background var(--t-base, .15s) ease;
}
.vbenefits-v3.in-view .vbenefit-row-v3 {
  animation: vipBenefitStaggerIn .55s cubic-bezier(.4,.8,.3,1.1) forwards;
  animation-delay: var(--vbenefit-stagger, 0ms);
}
@keyframes vipBenefitStaggerIn {
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .vbenefits-v3 .vbenefit-row-v3 { opacity: 1; transform: none; animation: none; }
}
.vbenefit-row-v3:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-accent, 0 12px 28px rgba(52,192,235,.18));
}
/* Hex — base + spinning gradient overlay */
.vbenefit-hex .vbenefit-hex-base,
.vbenefit-hex .vbenefit-hex-spin {
  position: absolute; inset: 0; width: 100%; height: 100%;
}
.vbenefit-hex .vbenefit-hex-icon {
  position: relative;
  display: grid;
  place-items: center;
  transition: transform var(--t-base, .15s) ease;
}
.vbenefit-row-v3:hover .vbenefit-hex-icon {
  animation: kenoTilePop .35s ease;
}
@media (prefers-reduced-motion: no-preference) {
  .vbenefit-hex .vbenefit-hex-spin {
    animation: vipBenefitHexSpin 14s linear infinite;
    transform-origin: center;
  }
  @keyframes vipBenefitHexSpin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
  }
}
@media (prefers-reduced-motion: reduce) {
  .vbenefit-row-v3:hover .vbenefit-hex-icon { animation: none; transform: scale(1.06); }
}

/* ---- FAQ V3 ------------------------------------------------------- */
.vip-faq-v3 .vfaq-row-v3 {
  position: relative;
  opacity: 0;
  transform: translateY(6px);
  transition: background var(--t-base, .15s) ease;
}
.vip-faq-v3.in-view .vfaq-row-v3 {
  animation: vipBenefitStaggerIn .5s cubic-bezier(.4,.8,.3,1.1) forwards;
  animation-delay: var(--vfaq-stagger, 0ms);
}
@media (prefers-reduced-motion: reduce) {
  .vip-faq-v3 .vfaq-row-v3 { opacity: 1; transform: none; animation: none; }
}
.vfaq-row-v3 .vfaq-head:hover {
  background: rgba(52,192,235,.05);
}
.vfaq-row-v3 .vfaq-chev {
  display: inline-grid;
  place-items: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 800;
  color: var(--accent, #34c0eb);
  background: rgba(52,192,235,.08);
  transition: transform var(--t-base, .15s) cubic-bezier(.4,.8,.3,1.1), background var(--t-base, .15s) ease;
}
.vfaq-row-v3.open .vfaq-chev {
  transform: rotate(45deg);
  background: rgba(52,192,235,.18);
}
/* Smooth height — modern grid trick (no max-height hack) */
.vfaq-row-v3 .vfaq-body-clip {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .35s cubic-bezier(.4,.8,.3,1.1);
}
.vfaq-row-v3.open .vfaq-body-clip {
  grid-template-rows: 1fr;
}
.vfaq-row-v3 .vfaq-body {
  overflow: hidden;
  /* Padding lives here so the clip transition is purely height */
  padding: 0 18px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-dim);
}
.vfaq-row-v3.open .vfaq-body { padding: 4px 18px 16px; }

/* ---- CTA band V3 -------------------------------------------------- */
.vip-cta-v3 {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.vip-cta-v3 .vcb-conic {
  position: absolute; inset: -50%;
  background: conic-gradient(from 0deg, transparent 0deg, rgba(52,192,235,.10) 30deg, transparent 90deg, rgba(124,92,255,.08) 220deg, transparent 280deg);
  pointer-events: none;
  z-index: 0;
  opacity: .7;
}
@media (prefers-reduced-motion: no-preference) {
  .vip-cta-v3 .vcb-conic {
    animation: vipCtaConicSpin 28s linear infinite;
  }
  @keyframes vipCtaConicSpin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
  }
}
.vip-cta-v3 .vcb-text { position: relative; z-index: 2; min-width: 0; }
.vip-cta-v3 .vcb-cta {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  overflow: hidden;
}
.vip-cta-v3 .vcb-cta-arrow {
  display: inline-flex;
  transition: transform var(--t-base, .15s) cubic-bezier(.4,.8,.3,1.1);
}
.vip-cta-v3 .vcb-cta:hover .vcb-cta-arrow {
  transform: translateX(4px);
}

/* ============================================================
   End of VIP V3 motion rework
   ============================================================ */

/* ============================================================
   Audit GE-C1 / GE-H3 — Toast stack + Confirm/Prompt dialog
   Uses the home design tokens (--accent, --red, --bg-2, --line)
   so error UI matches every other surface in the app.
   ============================================================ */
.sa-toast-stack{
  position: fixed;
  z-index: var(--z-toast);
  bottom: 24px;
  right: 24px;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  pointer-events: none;
  max-width: min(420px, calc(100vw - 32px));
}
/* Operator rebuild — toast got a thicker semantic left bar (3 → 4px),
   tinted soft-color background, draining hairline progress at the
   bottom matching the auto-dismiss TTL. */
.sa-toast{
  position: relative;
  pointer-events: auto;
  display: flex; align-items: flex-start; gap: var(--space-4);
  padding: 14px 16px;
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.45;
  overflow: hidden;
  animation: saToastIn var(--dur-slow) var(--ease-entrance);
}
@keyframes saToastIn { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
/* Draining progress hairline — visualizes the 4500ms TTL. */
.sa-toast::after{
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  height: 2px;
  width: 100%;
  background: currentColor;
  opacity: .35;
  animation: saToastDrain 4500ms linear forwards;
  transform-origin: left center;
}
@keyframes saToastDrain { from { transform: scaleX(1); } to { transform: scaleX(0); } }

.sa-toast--error,
.sa-toast--danger{
  border-left-color: var(--color-danger);
  color: var(--color-danger);
}
.sa-toast--success{
  border-left-color: var(--color-success);
  color: var(--color-success);
}
.sa-toast--warn{
  border-left-color: var(--color-warning);
  color: var(--color-warning);
}
.sa-toast--info{
  border-left-color: var(--color-info);
  color: var(--color-info);
}
/* Reset .sa-toast text (above is `color` for the drain bar). The msg
   text uses --text again. */
.sa-toast-msg{
  flex: 1 1 auto;
  word-break: break-word;
  color: var(--text-primary);
}
.sa-toast-glyph{
  /* Glyph picks up the toast's `color` (set by the kind-specific rule
     above), which is the same hue as the left bar — clean. */
  font-family: var(--font-display);
  flex-shrink: 0;
  line-height: 1.2;
  margin-top: 1px;
  font-weight: 700;
}
.sa-toast-close{
  appearance: none; border: 0; background: transparent;
  color: var(--text-mute); font-size: 18px; line-height: 1;
  cursor: pointer; padding: 0 2px; flex-shrink: 0;
  transition: color .15s;
}
.sa-toast-close:hover{ color: var(--text); }

/* Confirm + prompt dialogs — shrink the standard modal-shell into a tight
   alert-style box. Uses the existing .modal-root / .modal-shell skeleton. */
.sa-confirm-shell{ max-width: 460px; }
.sa-confirm-body{ padding: 24px 26px 22px; }
.sa-confirm-title{
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: 18px;
  letter-spacing: .01em;
  color: var(--text);
}
.sa-confirm-text{
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--text-dim);
  line-height: 1.5;
  margin-bottom: 18px;
}
.sa-prompt-input{
  width: 100%;
  margin-bottom: 18px;
  padding: 10px 12px;
  background: var(--bg-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 13px;
  outline: none;
  transition: border-color .15s;
}
.sa-prompt-input:focus{ border-color: var(--accent); }
.sa-confirm-actions{
  display: flex; gap: var(--space-4); justify-content: flex-end;
}
.sa-btn{
  appearance: none; border: 1px solid transparent;
  padding: 9px 18px; border-radius: var(--radius-sm);
  font-family: var(--font-display); font-weight: 700;
  font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
  cursor: pointer; transition: filter .15s, background .15s, border-color .15s;
}
.sa-btn--ghost{
  background: transparent; border-color: var(--line);
  color: var(--text-dim);
}
.sa-btn--ghost:hover{ color: var(--text); border-color: var(--line-2); }
.sa-btn--primary{
  background: linear-gradient(180deg, var(--accent-bright, var(--accent)), var(--accent));
  color: var(--on-accent, #1A1205);
  box-shadow: 0 6px 18px var(--accent-glow);
}
.sa-btn--primary:hover{ filter: brightness(1.05); }
.sa-btn--danger{
  background: var(--red);
  color: #fff;
}
.sa-btn--danger:hover{ filter: brightness(1.08); }

/* Inline error banner — replaces the 13+ scattered `<span style={{color:'var(--danger)'}}>◆ msg</span>`
   patterns. Use class instead of inline style so future restyling is one line. */
.sa-error-banner{
  display: flex; align-items: center; gap: var(--space-3);
  padding: 10px 12px;
  background: rgba(242, 77, 92, .08);
  border: 1px solid rgba(242, 77, 92, .35);
  border-radius: var(--radius-sm);
  color: var(--red);
  font-family: var(--font-ui);
  font-size: 13px;
  margin: 8px 0;
}
.sa-error-banner::before{
  content: "◆";
  font-family: var(--font-display);
  flex-shrink: 0;
}

/* ============================================================
   Phase 23 — Filter dropdown rebuild + provider link + checkbox
   ============================================================ */

/* ---- Provider pill on slot detail becomes a clickable link ---- */
.sd-prov-pill.sd-prov-pill-link {
  appearance: none; cursor: pointer;
  font: inherit;
  /* Inherit existing .sd-prov-pill look. We just add interactivity. */
  transition: background .15s ease, border-color .15s ease, color .15s ease, transform .12s ease;
}
.sd-prov-pill.sd-prov-pill-link:hover {
  background: var(--accent-10);
  border-color: rgba(52,192,235,.55);
  color: var(--accent);
  transform: translateY(-1px);
}
.sd-prov-pill.sd-prov-pill-link:active { transform: translateY(0); }

/* ---- Custom checkbox (replaces native HTML check) ---- */
/* Used by the slots filter dropdown; reusable anywhere on the site
   where we want the "wallet-style" check instead of the native one. */
.sa-check-input {
  /* Keep in DOM for a11y, hide visually. */
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}
.sa-check-box {
  flex-shrink: 0;
  width: 16px; height: 16px;
  border-radius: var(--radius-xs);
  background: var(--white-04);
  border: 1px solid rgba(255,255,255,.14);
  display: inline-grid; place-items: center;
  color: transparent;          /* checkmark hidden by default */
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.sa-check-box svg {
  width: 10px; height: 8px;
  display: block;
}
/* Checked state — gold fill, ink-dark check stroke */
.sa-check-input:checked + .sa-check-box {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink, #1a1305);
}
/* Hover affordance on the row */
.slots-filter-check:hover .sa-check-box {
  border-color: rgba(52,192,235,.55);
}
/* Keyboard focus ring for accessibility */
.sa-check-input:focus-visible + .sa-check-box {
  outline: 2px solid rgba(52,192,235,.55);
  outline-offset: 2px;
}

/* ---- Filter dropdown panel (replaces .slots-dd-menu / .slots-filter-menu look) ---- */
/* Overrides the older .slots-dd-menu style for filter use only. Sort dropdown
   keeps the original .slots-dd-menu appearance — different content, different
   shape (short list of options). */
.slots-filter-menu {
  position: absolute; top: 100%; right: 0; margin-top: 8px;
  /* Right-anchored so the panel never overflows the right edge of the
     viewport. Width clamps to the smaller of 360px or available space. */
  width: min(360px, calc(100vw - 32px));
  max-height: min(70vh, 540px);
  overflow-y: auto;
  /* Match the wallet dropdown (.bal-dropdown) chrome */
  background: var(--panel, #0e1224);
  border: 1px solid var(--line-soft, rgba(255,255,255,.07));
  border-radius: var(--radius);
  box-shadow: 0 18px 40px rgba(0,0,0,.5);
  padding: 8px 0;
  z-index: 30;
  /* Kill the global .slots-dd-menu min-width / padding leftovers */
  min-width: 0;
}

.slots-filter-section { padding: 6px 14px; }
.slots-filter-section-head {
  font-family: var(--font-display);
  font-size: 10px; letter-spacing: .18em;
  color: var(--text-mute);
  text-transform: uppercase;
  padding: 6px 0 8px;
}
.slots-filter-divider {
  height: 1px;
  background: rgba(255,255,255,.05);
  margin: 4px 14px;
}

.slots-filter-search {
  display: flex; align-items: center; gap: var(--space-2);
  background: rgba(255,255,255,.03);
  border: 1px solid var(--white-06);
  border-radius: var(--radius-sm);
  padding: 6px 9px;
  color: var(--text-mute);
  margin-bottom: 6px;
  transition: border-color .15s ease, background .15s ease;
}
.slots-filter-search:focus-within {
  border-color: rgba(52,192,235,.45);
  background: rgba(255,255,255,.05);
}
.slots-filter-search input {
  flex: 1; min-width: 0;
  background: transparent; border: 0; outline: 0;
  color: var(--text);
  font-family: var(--font-ui); font-size: 12.5px;
}
.slots-filter-search input::placeholder { color: var(--text-mute); }

.slots-filter-checklist {
  /* Allow a long provider list to scroll inside the dropdown without
     blowing out the panel height. */
  max-height: 240px;
  overflow-y: auto;
  padding: 2px 0;
  /* Custom scrollbar to match the wallet dropdown */
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,.18) transparent;
}
.slots-filter-checklist::-webkit-scrollbar { width: 6px; }
.slots-filter-checklist::-webkit-scrollbar-track { background: transparent; }
.slots-filter-checklist::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,.14);
  border-radius: var(--radius-2xs);
}

.slots-filter-check {
  display: flex; align-items: center; gap: var(--space-4);
  padding: 7px 8px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text-dim);
  font-family: var(--font-ui); font-size: 13px;
  transition: background .12s ease, color .12s ease;
  user-select: none;
}
.slots-filter-check:hover {
  background: var(--white-04);
  color: var(--text);
}
.slots-filter-check-label { flex: 1; min-width: 0; }
.slots-filter-empty {
  padding: 10px 8px;
  color: var(--text-mute);
  font-family: var(--font-display); font-size: 12px;
  font-style: italic;
}

.slots-filter-reset {
  appearance: none; cursor: pointer;
  display: block;
  width: calc(100% - 28px);
  margin: 4px 14px 6px;
  padding: 9px 12px;
  background: transparent;
  border: 1px solid rgba(255,255,255,.08);
  border-radius: var(--radius-sm);
  color: var(--text-mute);
  font-family: var(--font-ui); font-size: 12.5px; font-weight: 600;
  letter-spacing: .02em;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.slots-filter-reset:hover {
  border-color: var(--magenta, #e84a8a);
  color: var(--magenta, #e84a8a);
  background: rgba(232,74,138,.05);
}

/* Mobile: slide the filter panel up as a bottom-sheet — same pattern the
   wallet dropdown uses (.bal-dropdown.bd-sheet) on mobile. The panel
   anchored to a trigger button via `right: 0` overflows the viewport on
   narrow screens because the trigger doesn't sit at the right edge of
   the viewport. A bottom-sheet sidesteps that by anchoring to the
   viewport instead of the trigger.

   Tap-outside dismissal is already handled by the `onMouseLeave` on the
   panel; on mobile users can additionally tap the FILTER button again
   (it's a toggle) to close. */
@media (max-width: 640px) {
  .slots-filter-menu {
    position: fixed !important;
    top: auto !important;
    bottom: 0 !important;
    left: 0 !important;
    right: 0 !important;
    width: auto !important;
    max-width: none !important;
    margin-top: 0 !important;
    border-radius: 18px 18px 0 0 !important;
    padding: 14px 4px 22px !important;
    max-height: 80vh !important;
    box-shadow: 0 -20px 60px rgba(0,0,0,.7) !important;
    z-index: 9999 !important;
  }
  .slots-filter-checklist { max-height: min(280px, 36vh); }
  /* A small drag handle hint above the first section */
  .slots-filter-menu::before {
    content: '';
    display: block;
    width: 38px; height: 4px;
    border-radius: var(--radius-2xs);
    background: rgba(255,255,255,.18);
    margin: -6px auto 10px;
  }
}


/* =============================================================
   DESIGN SYSTEM PRIMITIVES (Phase 1)
   -------------------------------------------------------------
   Single canonical class per UI function. Every existing variant
   class (.gp-mode-tabs, .profile-card, .aff-card, .dw-input,
   .bal-dropdown, .slot-badge, etc.) is aliased to the canonical
   below via shared selector lists. JSX migrations in Phase 2.4
   then swap the JSX className to the canonical, after which the
   alias entry can be removed (or kept as a defensive fallback
   for one release cycle).

   Tokens consumed are the ones added in Phase 0 (see :root in
   styles.css): --space-*, --text-*, --radius-*, --shadow-*,
   --accent-*, --white-*, --t-*, --ease.
   ============================================================= */

/* ---- 1. .tab-strip ------------------------------------------
   Segment toggle (Manual/Auto, Real/Fun, All/Unread, etc.).
   Replaces .gp-mode-tabs / .sd-mode-toggle / .nd-tabs / .bd-bet-pill. */
.tab-strip {
  display: inline-flex; gap: 2px;
  padding: 3px;
  background: var(--bg-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}
.tab-strip > button {
  appearance: none; cursor: pointer;
  font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  padding: var(--space-3) var(--space-5);
  background: transparent; color: var(--text-dim);
  border: 0; border-radius: var(--radius-sm);
  transition: background var(--t-base), color var(--t-base);
}
.tab-strip > button:hover { color: var(--text); }
.tab-strip > button.on,
.tab-strip > button[aria-selected="true"] {
  background: var(--accent-15);
  color: var(--accent);
}
.tab-strip > button:disabled {
  opacity: .55; cursor: not-allowed;
}
.tab-strip[data-size="sm"] { padding: 2px; }
.tab-strip[data-size="sm"] > button {
  padding: 4px var(--space-3); font-size: var(--text-2xs);
}

/* ---- 2. .card -----------------------------------------------
   Surface container. Replaces 13+ scattered card classes.
   data-variant="frame" — gradient-border premium variant
   data-variant="dense" — denser padding for inner sub-cards
   data-variant="hero"  — large hero pull-out */
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-7);
  display: flex; flex-direction: column;
  gap: var(--space-5);
  box-shadow: var(--shadow-sm);
}

/* ==================================================================
   ADMIN LIGHT THEME — scoped token override (rebuild).
   The whole app reads dark tokens from :root. The admin panel is the
   ONLY surface that should be light. We override the *base* tokens on
   the .admin-panel.admin-light root; CSS custom properties inherit
   down the DOM tree and var() resolves at use time, so every admin
   descendant (and aliases like --panel/--line-soft/--magenta) flips
   to light automatically. :root is never touched → player pages stay
   dark. Overlay roots (modal/drawer) opened from admin also get
   .admin-light so they inherit even when fixed-positioned.
   ================================================================== */
.admin-panel.admin-light,
.admin-modal-root.admin-light,
.modal-shell.admin-light,
.admin-light {
  /* surfaces */
  --bg-0: #eef1f7;            /* page background */
  --bg-1: #ffffff;            /* sidebar / topbar */
  --bg-2: #ffffff;            /* card / panel / input */
  --bg-3: #f1f4fa;            /* raised / hovered row / active nav */
  /* hairlines */
  --line:   rgba(27, 35, 48, 0.10);
  --line-2: rgba(27, 35, 48, 0.18);
  --line-3: rgba(91, 91, 230, 0.40);
  /* text */
  --text:      #1b2330;
  --text-dim:  #56607a;
  --text-mute: #8a93a8;
  /* brand accent — indigo to match the dashboard reference */
  --accent:        #5b5be6;
  --accent-rgb:    91, 91, 230;
  --accent-bright: #7b7bf0;
  --accent-2:      #4848c4;
  --accent-deep:   #e8e8fb;
  --accent-glow:   rgba(91, 91, 230, 0.28);
  --accent-ink:    #ffffff;
  --on-accent:     #ffffff;
  /* semantic */
  --red:     #e0466b;
  --blue:    #3d7bf4;
  --green:   #1faa6b;
  --magenta: #e0466b;
  --purple:  #3d7bf4;
  /* accent alpha ramp (recomputed for light) */
  --accent-05: rgba(91, 91, 230, 0.05);
  --accent-10: rgba(91, 91, 230, 0.10);
  --accent-15: rgba(91, 91, 230, 0.14);
  --accent-25: rgba(91, 91, 230, 0.22);
  --accent-40: rgba(91, 91, 230, 0.38);
  --accent-60: rgba(91, 91, 230, 0.55);
  /* "white overlay" hover tints are invisible on white — flip to ink */
  --white-02: rgba(27, 35, 48, 0.02);
  --white-04: rgba(27, 35, 48, 0.04);
  --white-06: rgba(27, 35, 48, 0.06);
  --white-10: rgba(27, 35, 48, 0.10);
  /* soft elevation for a SaaS-dashboard feel */
  --shadow-1:      0 0 0 1px var(--line);
  --shadow-sm:     0 1px 2px rgba(20, 28, 46, .06), 0 1px 1px rgba(20, 28, 46, .04);
  --shadow-md:     0 4px 16px rgba(20, 28, 46, .08);
  --shadow-lg:     0 12px 32px rgba(20, 28, 46, .12);
  --shadow-xl:     0 24px 64px rgba(20, 28, 46, .16), 0 0 0 1px var(--line);
  --shadow-accent: 0 10px 28px var(--accent-glow);
  --shadow-danger: 0 10px 24px rgba(224, 70, 107, .28);
  /* intent aliases — components express meaning, not raw hex */
  --surface:   var(--bg-2);
  --surface-2: var(--bg-3);
  --border:    var(--line);
  --positive:  var(--green);
  --negative:  var(--red);
  --brand:     var(--accent);
  --shadow-card: var(--shadow-sm);
  color-scheme: light;
}
/* Make the admin page background actually paint light (the global
   .page-shell inherits the dark body bg otherwise). */
.admin-panel.admin-light { background: var(--bg-0); color: var(--text); }

/* ==================================================================
   ADMIN CHROME REBUILD — light SaaS dashboard shell.
   Topbar + sidebar + content. Desktop: sticky 260px rail. Phone/
   tablet (≤1024px): sidebar becomes an off-canvas drawer behind a
   hamburger. NO ancestor sets overflow:hidden → the table scroll
   container actually works and action columns are never clipped.
   ================================================================== */

/* Reset the global page gutter for the admin — the topbar is full
   bleed and the shell supplies its own padding. */
.admin-panel.admin-light { padding: 0 !important; min-height: 100vh; }
.admin-panel.admin-light .page-body {
  display: block;
  padding: 0;
  gap: 0;
}

/* ── Topbar ───────────────────────────────────────────────────── */
.admin-topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: var(--space-5);
  height: 58px;
  padding: 0 var(--space-8);
  background: var(--bg-1);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}
.admin-topbar-back {
  font-family: var(--font-ui); font-size: var(--text-sm);
  color: var(--text-dim); background: transparent; border: 0;
  cursor: pointer; padding: 6px 10px; border-radius: var(--radius-md);
}
.admin-topbar-back:hover { background: var(--white-06); color: var(--text); }
.admin-topbar-title {
  display: flex; align-items: baseline; gap: 8px;
  min-width: 0; overflow: hidden;
}
.admin-topbar-app {
  font-family: var(--font-display); font-weight: 800;
  font-size: var(--text-lg); color: var(--text);
}
.admin-topbar-sep { color: var(--text-mute); }
.admin-topbar-section {
  font-family: var(--font-ui); font-size: var(--text-md);
  color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.admin-topbar-user {
  font-family: var(--font-display); font-size: var(--text-xs);
  color: var(--accent);
  white-space: nowrap;
}
/* Hamburger — hidden on desktop, shown ≤1024px. */
.admin-burger {
  display: none;
  flex-direction: column; justify-content: center; gap: 4px;
  width: 38px; height: 38px; padding: 9px;
  background: transparent; border: 1px solid var(--line);
  border-radius: var(--radius-md); cursor: pointer; flex-shrink: 0;
}
.admin-burger span {
  display: block; height: 2px; width: 100%;
  background: var(--text); border-radius: 2px;
}

/* ── Shell grid ───────────────────────────────────────────────── */
.admin-shell {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: var(--space-8);
  align-items: flex-start;
  padding: var(--space-8);
  max-width: 1680px;
  margin: 0 auto;
}
.admin-side {
  position: sticky; top: calc(58px + var(--space-8));
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--space-5);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  max-height: calc(100vh - 58px - var(--space-9));
  overflow-y: auto;
}
.admin-side-group { display: flex; flex-direction: column; gap: 2px; }
.admin-side-group + .admin-side-group {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}
.admin-side-section {
  font-family: var(--font-display); font-size: 10px;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-mute);
  padding: var(--space-2) var(--space-3);
}
.admin-side-item {
  appearance: none; cursor: pointer;
  display: flex; align-items: center; gap: var(--space-3);
  width: 100%;
  padding: var(--space-4) var(--space-4);
  background: transparent; border: 0;
  border-radius: var(--radius-md);
  font-family: var(--font-ui); font-size: var(--text-md);
  text-align: left;
  color: var(--text-dim);
  transition: background var(--t-fast), color var(--t-fast);
}
.admin-side-item:hover { background: var(--white-06); color: var(--text); }
.admin-side-item.on {
  background: var(--accent-10);
  color: var(--accent);
  font-weight: 600;
}
.admin-side-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--white-10);
  flex-shrink: 0;
}
.admin-side-item.on .admin-side-dot {
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent-glow);
}

/* ── Content column + standard tab frame ──────────────────────── */
.admin-pane { min-width: 0; }
/* The ONE robust scroll context. Crucially NOT overflow:hidden, so a
   nested .data-table-scroll can scroll and action columns are never
   clipped (the original bug). */
.admin-page-frame {
  min-width: 0;
  width: 100%;
  display: flex; flex-direction: column;
  gap: var(--space-7);
}
/* Any direct card/table wrapper that historically set overflow:hidden
   inline is neutralised so the inner horizontal scroll survives. */
.admin-page-frame .card > .data-table-scroll,
.admin-page-frame .admin-card > .data-table-scroll { overflow-x: auto; }

/* Sticky sub-tab strips inside a pane (e.g. Users/Bets) — realign
   under the new 58px topbar. */
.admin-pane > .tabs,
.admin-pane > .admin-tabs,
.admin-pane > .frame > .tabs,
.admin-pane > .card > .tabs {
  position: sticky;
  top: 58px;
  z-index: 5;
  background: var(--bg-0);
  padding-top: 4px;
  border-bottom: 1px solid var(--line);
}

/* ── ResponsiveTable card-stack (≤768px, via AdminUI.DataTable) ── */
.admin-cardlist { display: flex; flex-direction: column; gap: var(--space-5); }
.admin-rowcard {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.admin-rowcard-head {
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--line);
  font-weight: 600;
}
.admin-rowcard-body { padding: var(--space-4) var(--space-6); }
.admin-rowcard-field {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-3) 0;
}
.admin-rowcard-field + .admin-rowcard-field { border-top: 1px solid var(--line); }
.admin-rowcard-label {
  font-family: var(--font-display); font-size: 10px;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-mute); flex-shrink: 0;
}
.admin-rowcard-value {
  font-size: var(--text-md); color: var(--text);
  text-align: right; min-width: 0;
  display: flex; align-items: center; justify-content: flex-end;
  flex-wrap: wrap; gap: 6px;
}

/* Raw-table tabs (the ~20 not on DataTable): clipping already fixed
   by switching wrappers to overflow:auto. Add a clear scroll
   affordance + comfortable density so they read well on narrow
   screens without a confusing label-less card stack. */
.admin-page-frame .data-table-scroll {
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.admin-page-frame .data-table-scroll::-webkit-scrollbar { height: 9px; }
.admin-page-frame .data-table-scroll::-webkit-scrollbar-thumb {
  background: var(--line-2); border-radius: 999px;
}
@media (max-width: 768px) {
  .admin-page-frame .data-table { font-size: var(--text-sm); }
  .admin-page-frame .data-table th,
  .admin-page-frame .data-table td { padding: 10px 12px; }
}

/* ── Light aesthetic polish — SCOPED to .admin-light only so it
   never touches the dark player-facing site. Reference look:
   white cards, soft shadow, generous radius, calm tables, pill
   buttons, clear focus rings. ──────────────────────────────────── */
.admin-light .admin-card,
.admin-light .card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.admin-light .admin-card { padding: var(--space-8); }
.admin-light .admin-statcard {
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.admin-light .admin-statcard.is-clickable:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--accent);
}
/* Tables — light, airy, row hover. */
.admin-light .data-table { font-size: var(--text-md); }
.admin-light .data-table thead tr {
  background: var(--bg-3);
  color: var(--text-mute);
}
.admin-light .data-table th { border-bottom: 1px solid var(--line); }
.admin-light .data-table td { border-top: 1px solid var(--line); }
.admin-light .data-table tbody tr:hover { background: var(--accent-05); }
.admin-light .data-table tbody tr:hover td { color: var(--text); }
/* Buttons — pill, solid brand / soft ghost (reference style). */
.admin-light .btn-primary,
.admin-light .btn-secondary {
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
  border-radius: var(--radius-pill); box-shadow: var(--shadow-sm);
  font-weight: 600;
}
.admin-light .btn-primary:hover,
.admin-light .btn-secondary:hover { background: var(--accent-2); border-color: var(--accent-2); }
.admin-light .btn-ghost {
  background: var(--bg-3); color: var(--text-dim);
  border: 1px solid var(--line); border-radius: var(--radius-pill);
}
.admin-light .btn-ghost:hover { background: var(--white-06); color: var(--text); }
.admin-light .btn-danger {
  background: var(--red); color: #fff; border: 1px solid var(--red);
  border-radius: var(--radius-pill); font-weight: 600;
}
.admin-light .btn-danger:hover { filter: brightness(.94); }
/* Inputs / selects — light field, brand focus ring. */
.admin-light .input,
.admin-light .dw-input,
.admin-light input[type="text"],
.admin-light input[type="search"],
.admin-light input[type="number"],
.admin-light select,
.admin-light textarea {
  background: var(--bg-2); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius-md);
}
.admin-light .input:focus,
.admin-light .dw-input:focus,
.admin-light input:focus,
.admin-light select:focus,
.admin-light textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-15);
}
.admin-light .input::placeholder,
.admin-light .dw-input::placeholder { color: var(--text-mute); }
/* Badges — soft tinted pills. */
.admin-light .badge {
  border-radius: var(--radius-pill);
  background: var(--bg-3); color: var(--text-dim);
  border: 1px solid var(--line);
}
.admin-light .badge[data-tone="accent"] {
  background: var(--accent-10); color: var(--accent); border-color: transparent;
}
.admin-light .badge[data-tone="hot"],
.admin-light .badge[data-tone="danger"] {
  background: rgba(224,70,107,.12); color: var(--red); border-color: transparent;
}
.admin-light .badge[data-tone="success"] {
  background: rgba(31,170,107,.14); color: var(--green); border-color: transparent;
}
/* Section headers + page header on light. */
.admin-light .admin-page-head { border-bottom: 1px solid var(--line); }
.admin-light .empty,
.admin-light .empty-state {
  background: var(--bg-2); border: 1px dashed var(--line);
  border-radius: var(--radius); color: var(--text-mute);
}
/* Scrollbars in the light pane. */
.admin-light ::-webkit-scrollbar { width: 10px; height: 10px; }
.admin-light ::-webkit-scrollbar-thumb {
  background: var(--line-2); border-radius: 999px;
  border: 2px solid var(--bg-0);
}

/* Off-canvas scrim (only mounted while the drawer is open ≤1024px). */
.admin-nav-scrim {
  position: fixed; inset: 0; z-index: 44;
  background: rgba(20, 28, 46, .42);
  animation: admin-modal-fade .14s ease-out;
}

/* ── Responsive: ≤1024px — sidebar becomes an off-canvas drawer ── */
@media (max-width: 1024px) {
  .admin-burger { display: flex; }
  .admin-topbar-back .admin-topbar-section { display: none; }
  .admin-shell {
    grid-template-columns: 1fr;
    padding: var(--space-6);
    gap: 0;
  }
  .admin-side {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: 280px; max-width: 84vw;
    max-height: none;
    border-radius: 0;
    border: 0; border-right: 1px solid var(--line);
    z-index: 45;
    transform: translateX(-100%);
    transition: transform .22s ease;
    box-shadow: var(--shadow-lg);
  }
  .admin-shell.is-nav-open .admin-side { transform: translateX(0); }
}
@media (min-width: 1025px) {
  .admin-nav-scrim { display: none; }
}
@media (max-width: 560px) {
  .admin-topbar { padding: 0 var(--space-5); gap: var(--space-3); }
  .admin-topbar-user { display: none; }
  .admin-shell { padding: var(--space-4); }
}

/* Migration 027: drawer-style modal for the AdminUserDrawer (slide-in
   right panel, full height, no chamfer). Pairs with <Modal size="drawer">.
   Tokens-only; no new colors/radii. */
.modal-root.drawer-root { place-items: stretch; padding: 0; justify-content: flex-end; }
.modal-shell.drawer{
  width: min(760px, 70vw);
  max-width: none;
  height: 100vh;
  max-height: 100vh;
  border-radius: 0;
  clip-path: none;
  border-left: 1px solid var(--line);
  animation: drawerIn .25s cubic-bezier(.4,.8,.3,1.1);
}
@keyframes drawerIn { from { transform: translateX(40px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (max-width: 720px) {
  .modal-shell.drawer { width: 100vw; }
}
.card[data-variant="frame"] {
  position: relative; isolation: isolate; border: 0;
}
.card[data-variant="frame"]::before {
  content: ""; position: absolute; inset: 0; padding: 1px;
  border-radius: inherit;
  background: linear-gradient(180deg, var(--accent-25), var(--white-04) 30%, var(--white-02));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  pointer-events: none;
}
.card[data-variant="dense"] {
  padding: var(--space-5); gap: var(--space-3);
}
.card[data-variant="hero"] {
  padding: var(--space-9); border-radius: var(--radius-lg);
}

/* ---- 3. .input ---------------------------------------------
   Single text-field look. Replaces .dw-input / .sa-prompt-input
   and the inline-styled <input> blocks scattered across pages. */
.input {
  appearance: none;
  width: 100%;
  padding: var(--space-5) var(--space-6);
  background: var(--bg-3);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--text-md);
  transition: border-color var(--t-base), box-shadow var(--t-base);
}
.input:focus {
  outline: 0;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-15);
}
.input:disabled { opacity: .55; cursor: not-allowed; }
.input[data-size="sm"] {
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
}
.input[data-size="lg"] {
  padding: var(--space-6) var(--space-7);
  font-size: var(--text-lg);
}

/* ---- 4. .popover -------------------------------------------
   Dropdown / menu shell. Replaces .bal-dropdown, .notif-dropdown,
   .user-menu-dropdown, .sd-bp-menu, .rail-search-pop, .slots-dd-menu. */
.popover {
  position: absolute;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-3);
  box-shadow: var(--shadow-xl);
  z-index: 200;
  display: flex; flex-direction: column; gap: 2px;
  min-width: 240px;
}
/* Sidebar search loading indicator */
.rail-search-loading {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-5);
  color: var(--text-dim);
  font-family: var(--font-ui);
  font-size: 13px;
}
.rail-search-spinner {
  width: 16px;
  height: 16px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: rail-search-spin .6s linear infinite;
  flex-shrink: 0;
}
@keyframes rail-search-spin {
  to { transform: rotate(360deg); }
}

.popover[data-size="sm"] { min-width: 200px; padding: var(--space-2); }
.popover[data-size="lg"] { min-width: 320px; }
.popover .popover-row {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-sm);
  background: transparent; color: var(--text);
  cursor: pointer; border: 0;
  font: inherit; text-align: left;
  transition: background var(--t-base), color var(--t-base);
}
.popover .popover-row:hover { background: var(--white-04); }
.popover .popover-row.on,
.popover .popover-row[aria-selected="true"] {
  background: var(--accent-15);
  color: var(--accent);
}
.popover .popover-divider {
  height: 1px;
  background: var(--line);
  margin: var(--space-2) 0;
}

/* ---- 5. .badge ---------------------------------------------
   Status chip / pill. data-tone selects the semantic palette.
   Replaces .slot-badge / .tx-kind / .sd-prov-pill / .sd-stat-pill /
   .kbd / .n-badge / .aff-k. */
.badge {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 3px var(--space-4);
  font-family: var(--font-display);
  font-size: var(--text-2xs);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  border-radius: var(--radius-xs);
  background: var(--white-06);
  color: var(--text-dim);
  white-space: nowrap;
}
.badge[data-tone="hot"]    { background: rgba(255,67,97,.18); color: #ff647d; }
.badge[data-tone="new"]    { background: var(--accent-25); color: var(--blue); }
.badge[data-tone="accent"] { background: var(--accent-15);    color: var(--accent); }
.badge[data-tone="purple"] { background: rgba(124,77,255,.18); color: #a575ff; }
.badge[data-tone="danger"] { background: rgba(242,77,92,.18); color: var(--red); }
.badge[data-tone="muted"]  { background: var(--white-04);     color: var(--text-mute); }
.badge[data-size="lg"] {
  padding: var(--space-2) var(--space-5);
  font-size: var(--text-xs);
}

/* ---- 6. .pager ---------------------------------------------
   Prev/Next pagination row. */
.pager {
  display: flex; justify-content: center; align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-7);
}
.pager .pager-info {
  padding: var(--space-2) var(--space-5);
  color: var(--text-mute);
  font-size: var(--text-sm);
  font-family: var(--font-display);
}

/* ---- 7. .empty ---------------------------------------------
   Empty / loading state block. Replaces 14 inline copies of
   <div style={{padding:30, textAlign:'center', color:...}}>. */
.empty {
  padding: var(--space-10);
  text-align: center;
  color: var(--text-mute);
  font-family: var(--font-display);
  font-size: var(--text-sm);
}
.empty[data-variant="dashed"] {
  border: 1px dashed var(--line);
  border-radius: var(--radius);
}

/* ---- 8a. .meta-label ---------------------------------------
   The single most-repeated inline-style pattern in the codebase
   is `style={{fontFamily:'var(--font-display)', fontSize:11, color:
   'var(--text-mute)'}}` — appearing 50+ times in user-pages.jsx
   alone. This class is its named replacement. */
.meta-label {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  color: var(--text-mute);
  letter-spacing: .08em;
}
.meta-label[data-tone="accent"] { color: var(--accent); }
.meta-label[data-tone="dim"]    { color: var(--text-dim); }
.meta-label[data-size="sm"]     { font-size: var(--text-2xs); }

/* ---- 8b. .stack / .row -------------------------------------
   Tiny flexbox utilities that show up 100+ times as inline style.
   `.stack` is vertical, `.row` is horizontal. The data-attr lets
   call sites choose gap and alignment without inline overrides. */
.stack { display: flex; flex-direction: column; gap: var(--space-5); }
.stack[data-gap="xs"] { gap: var(--space-1); }
.stack[data-gap="sm"] { gap: var(--space-3); }
.stack[data-gap="md"] { gap: var(--space-5); }
.stack[data-gap="lg"] { gap: var(--space-7); }
.row   { display: flex; align-items: center; gap: var(--space-3); }
.row[data-gap="xs"] { gap: var(--space-1); }
.row[data-gap="sm"] { gap: var(--space-3); }
.row[data-gap="md"] { gap: var(--space-5); }
.row[data-gap="lg"] { gap: var(--space-7); }
.row[data-justify="between"] { justify-content: space-between; }
.row[data-justify="end"]     { justify-content: flex-end; }
.row[data-justify="center"]  { justify-content: center; }
.row[data-align="start"]     { align-items: flex-start; }
.row[data-align="end"]       { align-items: flex-end; }

/* ---- 9. .progress-bar --------------------------------------
   Single horizontal progress bar. Replaces 3+ inline progress
   div constructions (Affiliate tier, Rewards challenge, etc.). */
.progress-bar {
  height: 6px;
  background: var(--bg-3);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.progress-bar > .fill {
  height: 100%;
  background: var(--accent);
  border-radius: inherit;
  transition: width var(--t-slow) var(--ease);
}
.progress-bar[data-tone="purple"] > .fill { background: var(--purple); }
.progress-bar[data-tone="danger"] > .fill { background: var(--red); }


/* =============================================================
   ALIAS BRIDGE — Phase 1 back-compat
   -------------------------------------------------------------
   Each existing variant class points at the canonical so the JSX
   keeps rendering identically while we incrementally migrate
   call sites in Phase 2.4. After migration these alias rules can
   be deleted (or kept as defensive fallbacks).
   ============================================================= */

/* These alias rules use the same CSS-variable values as the canonical
   primitives above. They're scoped to the EXACT class so any inline
   style overrides (e.g. `style={{padding:18}}`) still take precedence.
   Visual goal: the variants render identically to .card / .tab-strip
   / .input / etc. without any JSX change required. */

/* TAB STRIP aliases — gp-mode-tabs is already the canonical pattern
   (so its existing rules are kept). Bring the others into line by
   pointing their visual properties at the same tokens. The classnames
   stay as-is so existing JSX keeps working. */
.sd-mode-toggle,
.bd-bet-pill {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  background: var(--bg-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}
.sd-mode-toggle > button,
.bd-bet-pill  > button {
  appearance: none; cursor: pointer; border: 0;
  background: transparent; color: var(--text-dim);
  font-family: var(--font-display);
  font-size: var(--text-2xs); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  transition: background var(--t-base), color var(--t-base);
}
.sd-mode-toggle > button:hover,
.bd-bet-pill  > button:hover { color: var(--text); }
.sd-mode-toggle > button.on,
.bd-bet-pill  > button.on {
  background: var(--accent-15);
  color: var(--accent);
}

/* CARD aliases — every "card" class shares the same panel + line-soft
   + radius treatment. Existing rules already apply most of these;
   this bridge unifies any stragglers. Inline padding overrides on
   specific pages still win because they're applied at higher
   specificity (inline > class). */
/* Migration 027 follow-up: make every legacy ".*-card" alias visually
   identical to the Phase 1 .card primitive. Prior bridge only set
   background + border, leaving inconsistent padding/radius/gap so the
   pages that hadn't migrated their JSX still looked off — the user
   complaint about "user pages don't follow the home design rules"
   traces straight here. Now they pick up the same padding + flex
   layout + box-shadow as .card. */
.profile-card,
.aff-card,
.redeem-card,
.settings-card,
.sp-card,
.si-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-7);
  display: flex; flex-direction: column;
  gap: var(--space-5);
  box-shadow: var(--shadow-sm);
}

/* INPUT aliases — .dw-input is the canonical historic name and most
   pages already use it. The new .input class is the forward-looking
   name; both produce identical output. */
.dw-input {
  /* visual unchanged; left here as a marker for future migration */
}

/* BADGE aliases — .slot-badge already has a working rule; the others
   below are normalized to the same compact-pill recipe. */
.tx-kind,
.sd-prov-pill,
.sd-stat-pill {
  /* Already use small padding + radius via existing rules; the radius
     migration in Phase 2.1 already snapped them onto the same rung. */
}

/* EMPTY aliases — none yet (the inline copies in JSX migrate in 2.5). */

/* PROGRESS-BAR aliases — the .bar class in sidebar XP and various
   inline progress divs all produce identical output to .progress-bar
   so we don't duplicate; just confirm they consume the same tokens
   via Phase 2.1/2.2 migrations already applied. */


/* =============================================================
   REWARDS V2 — sidebar empty state, tier-card claim button,
                reload-slot grid (modal).
   All paddings/radii/colors via Phase-0 design tokens.
   ============================================================= */

.reward-empty {
  padding: var(--space-7);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  /* Task #18 — was var(--font-display), but both empty-state strings
     ("Nothing to claim right now…" and "Sign in to track your
     rewards.") are plain English, not numeric data. Mono stays
     reserved for amounts/IDs/odds elsewhere. Size unchanged. */
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: var(--text-xs);
  color: var(--text-mute);
  text-align: center;
  line-height: 1.5;
  background: var(--bg-2);
}

.vtier.has-claim {
  padding-bottom: var(--space-9);
  position: relative;
}
.vtier-claim {
  position: absolute;
  left: var(--space-3); right: var(--space-3); bottom: var(--space-3);
  padding: var(--space-3) var(--space-5);
  font-size: var(--text-xs);
  letter-spacing: .06em;
  justify-content: center;
}

.reload-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3);
}
@media (max-width: 540px) {
  .reload-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.reload-slot {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--space-1);
  padding: var(--space-5) var(--space-3);
  background: var(--bg-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  text-align: center;
  min-height: 92px;
}
.reload-slot .rs-pos {
  font-family: var(--font-display);
  font-size: var(--text-2xs);
  color: var(--text-mute);
  letter-spacing: .14em;
}
.reload-slot .rs-amount {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  color: var(--text);
  letter-spacing: .02em;
}
.reload-slot .rs-amount .rs-ccy {
  font-size: var(--text-2xs);
  color: var(--text-mute);
  margin-left: 4px;
  letter-spacing: .12em;
}
.reload-slot .rs-state {
  font-family: var(--font-display);
  font-size: var(--text-2xs);
  letter-spacing: .1em;
  color: var(--text-mute);
}
.reload-slot[data-state="claimed"] {
  border-color: var(--accent);
  background: var(--accent-15);
}
.reload-slot[data-state="claimed"] .rs-state { color: var(--accent); }
.reload-slot[data-state="claimed"] .rs-amount { color: var(--accent); }
.reload-slot[data-state="missed"] {
  opacity: .6;
  border-color: rgba(242, 77, 92, .35);
  background: rgba(242, 77, 92, .05);
}
.reload-slot[data-state="missed"] .rs-state { color: var(--red); }
.reload-slot[data-state="cancelled"] {
  opacity: .4;
}
.reload-slot[data-state="ready"] {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-25);
  animation: reload-slot-pulse 1.6s ease-in-out infinite;
}
.reload-slot[data-state="ready"] .rs-state-ready {
  color: var(--accent);
  font-weight: 700;
}
@keyframes reload-slot-pulse {
  0%, 100% { box-shadow: 0 0 0 2px var(--accent-25); }
  50%      { box-shadow: 0 0 0 3px var(--accent-40); }
}
.reload-slot[data-state="pending"] .rs-state {
  color: var(--text-dim);
}

/* ============================================================
   CRASH game — Phase 24+ canvas + history polish
   ============================================================ */

/* Wrapper inherits .gp-canvas centering. Add column flex so the canvas
   fills the top region and the history strip sits cleanly below it. */
.gp-canvas.crash-canvas {
  display: flex !important;
  flex-direction: column;
  align-items: stretch;
  justify-content: stretch;
  padding: 14px 16px 12px;
  gap: 10px;
}
.gp-canvas.crash-canvas canvas {
  /* Canvas dimensions fully driven by JS (style.width / style.height set
     in CrashGame's render-loop useEffect). DO NOT add `width: 100%` or
     `height: auto` here — that creates a feedback loop where the canvas
     pushes the wrapper taller, ResizeObserver fires, canvas grows again,
     ad infinitum. Leaving width/height unset means the inline style wins
     unambiguously.
     NO `max-height` here either — the V2 layout sizes the canvas to
     stage.clientHeight via JS, so a fixed pixel cap clamped the chart
     to ~420 px and produced the dead-band-below-canvas bug. */
  display: block;
  border-radius: 12px;
  background:
    radial-gradient(85% 100% at 50% 0%, rgba(52,192,235,.04), transparent 60%),
    linear-gradient(180deg, rgba(7,12,40,.45), rgba(4,6,14,.65));
  border: 1px solid rgba(255,255,255,.04);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.03);
  max-width: 100%;
}

/* History strip — solid plain-color pills (matches the plinko bucket
   style: opaque fill on the chip, no transparency). Two-row max via
   flex-wrap, centered. */
.crash-history {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: center;
  max-height: 64px;
  overflow: hidden;
  padding: 0 4px;
}

/* Pill base — opaque fill + colored top-border accent so it reads as a
   crisp tag, not a translucent ghost. Hover lifts + bright. Click opens
   the per-round provably-fair view (wired in game-page.jsx). */
.crash-pill {
  appearance: none; cursor: pointer;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .02em;
  padding: 5px 10px;
  border-radius: 8px;
  border: 0;
  border-top: 2px solid currentColor;
  color: #fff;
  background: var(--bg-2);   /* solid panel-2 (no rgba alpha) */
  box-shadow: 0 1px 0 rgba(0,0,0,.4), 0 0 0 1px rgba(255,255,255,.04) inset;
  transition: transform .12s ease, filter .12s ease, box-shadow .15s ease;
  white-space: nowrap;
  flex-shrink: 0;
}
.crash-pill:hover {
  transform: translateY(-1px);
  filter: brightness(1.12);
  box-shadow: 0 4px 14px rgba(0,0,0,.4), 0 0 0 1px currentColor inset;
}
.crash-pill:active { transform: translateY(0); }
.crash-pill:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* Tone variants — solid background flavor + accent color for top border.
   Matches the plinko bucket palette: red (low) → amber (mid) → blue (high). */
.crash-pill.tone-low  { color: #F24D5C; background: #2a0e14; }
.crash-pill.tone-mid  { color: #34c0eb; background: #0A1B22; }
.crash-pill.tone-high { color: #3D7EFF; background: #0e1939; }

/* Per-round provably-fair modal — opens on history pill click. */
.crash-fair-overlay{
  position: fixed; inset: 0;
  background: rgba(2,4,12,.72);
  z-index: 9999;
  display: grid; place-items: center;
  padding: 24px;
  animation: crashFairFadeIn .15s ease-out;
}
@keyframes crashFairFadeIn { from { opacity: 0; } to { opacity: 1; } }
.crash-fair-modal{
  position: relative;
  width: min(440px, calc(100vw - 32px));
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: 14px;
  padding: 22px 22px 18px;
  box-shadow: 0 24px 60px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.04);
  animation: crashFairSlideIn .22s cubic-bezier(.4,.8,.3,1.05);
}
@keyframes crashFairSlideIn { from { transform: translateY(12px) scale(.98); opacity: 0; } to { transform: none; opacity: 1; } }
.crash-fair-close{
  appearance: none; cursor: pointer;
  position: absolute; top: 10px; right: 10px;
  width: 32px; height: 32px;
  background: transparent;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  color: var(--text-mute);
  font-size: 20px; line-height: 1;
  display: grid; place-items: center;
  transition: color .15s, border-color .15s;
}
.crash-fair-close:hover{ color: var(--text); border-color: var(--text-dim); }
.crash-fair-eyebrow{
  font-family: var(--font-display);
  font-size: 10px; letter-spacing: .18em;
  color: var(--text-mute);
  margin-bottom: 8px;
}
.crash-fair-mult{
  font-family: var(--font-display);
  font-size: 56px; font-weight: 700;
  letter-spacing: -.02em;
  text-shadow: 0 0 18px currentColor;
  margin: 4px 0 18px;
  text-align: center;
}
.crash-fair-row{
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 8px 0;
  border-bottom: 1px dashed rgba(255,255,255,.05);
  font-size: 12px;
}
.crash-fair-row:last-of-type{ border-bottom: 0; }
.crash-fair-row .k{
  color: var(--text-mute); text-transform: uppercase;
  letter-spacing: .08em; font-family: var(--font-display); font-size: 10px;
}
.crash-fair-row .v{
  color: var(--text); font-weight: 600;
}
.crash-fair-row .v.mono{ font-family: var(--font-display); font-size: 11px; color: var(--text-dim); }
.crash-fair-help{
  margin: 14px 0 16px;
  padding: 12px 14px;
  background: var(--white-04);
  border-left: 3px solid #3D7EFF;
  border-radius: 6px;
  font-size: 11.5px; line-height: 1.55;
  color: var(--text-dim);
}
.crash-fair-help code{
  background: rgba(255,255,255,.06);
  padding: 1px 5px; border-radius: 4px;
  font-family: var(--font-display); font-size: 10.5px;
  color: var(--text);
}
.crash-fair-cta{
  appearance: none; cursor: pointer;
  width: 100%;
  padding: 11px;
  background: var(--accent);
  color: var(--accent-ink);
  border: 0; border-radius: 9px;
  font-family: var(--font-display); font-size: 12px;
  font-weight: 700; letter-spacing: .12em;
  transition: filter .15s, transform .12s;
}
.crash-fair-cta:hover{ filter: brightness(1.08); transform: translateY(-1px); }
.crash-fair-cta:active{ transform: translateY(0); }

/* ==================================================================
   Admin — Hero Editor (live preview)
   ==================================================================
   Two-column form/preview shell. Collapses to single column on
   narrow viewports so the operator can scroll between form + preview
   without horizontal overflow. */

.hero-editor { width: 100%; }

.hero-editor-grid {
  display: grid;
  grid-template-columns: minmax(360px, 1fr) minmax(420px, 1.2fr);
  gap: var(--space-6);
  align-items: start;
}
@media (max-width: 1100px) {
  .hero-editor-grid { grid-template-columns: 1fr; }
}

.hero-editor-form { min-width: 0; }

/* ---- Field primitives ---- */
.hero-editor-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  flex: 1 1 220px;
  min-width: 0;
}
.hero-editor-field-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 600;
}
.hero-editor-field input.input,
.hero-editor-field textarea.input {
  width: 100%;
  font-family: var(--font-ui);
}
.hero-editor-field textarea.input {
  resize: vertical;
  min-height: 56px;
  line-height: 1.45;
}
.hero-editor-field-hint {
  font-size: 11px;
  color: var(--text-mute);
  line-height: 1.4;
}
.hero-editor-revert {
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: 10px;
  color: var(--accent);
  letter-spacing: .04em;
}
.hero-editor-revert:hover { text-decoration: underline; }

/* ---- Range slider, color picker, swatches ---- */
.hero-editor-range {
  width: 100%;
  height: 4px;
  -webkit-appearance: none;
  appearance: none;
  background: linear-gradient(90deg, var(--accent) 0%, rgba(255,255,255,.08) 100%);
  border-radius: 2px;
  outline: none;
}
.hero-editor-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg);
  cursor: pointer;
  box-shadow: 0 0 0 1px var(--accent-25);
}
.hero-editor-range::-moz-range-thumb {
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg);
  cursor: pointer;
}
.hero-editor-color {
  width: 44px;
  height: 36px;
  padding: 2px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
}
.hero-editor-color::-webkit-color-swatch { border: 0; border-radius: 4px; }
.hero-editor-color::-moz-color-swatch { border: 0; border-radius: 4px; }

.hero-editor-swatch-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.hero-editor-swatch {
  width: 24px; height: 24px;
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 4px;
  cursor: pointer;
  transition: transform .12s;
}
.hero-editor-swatch:hover { transform: scale(1.1); border-color: var(--accent); }

/* ---- Live preview frame ---- */
.hero-editor-preview {
  position: sticky;
  top: 24px;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}
.hero-editor-preview-frame {
  background: linear-gradient(180deg, rgba(0,0,0,.4), rgba(0,0,0,.2));
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: 0 4px 24px rgba(0,0,0,.3);
}
.hero-editor-preview-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 14px;
  background: rgba(0,0,0,.3);
  border-bottom: 1px solid var(--line-soft);
  font-family: var(--font-display);
}
.hero-editor-preview-bar .dim { color: var(--text-mute); }
.hero-editor-preview-tip {
  font-size: 11px;
  color: var(--text-mute);
  line-height: 1.5;
  padding: 0 var(--space-2);
}

.hero-preview-stage {
  background: var(--bg);
  padding: 16px;
  /* The hero CSS uses fluid units that assume a viewport — clamp it
     here so the preview always fits its column. */
  --hero-scale: .8;
}
.hero-preview-stage .hero {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 12px;
  margin: 0;
}
.hero-preview-stage .hero-main {
  position: relative;
  min-height: 280px;
  border-radius: var(--radius-md);
  overflow: hidden;
}
.hero-preview-stage .hero-side {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.hero-preview-stage .hero-card {
  position: relative;
  padding: 16px;
  border-radius: var(--radius-md);
  min-height: 130px;
  overflow: hidden;
}
.hero-preview-stage .hero-card .tag {
  display: inline-block;
  font-size: 10px;
  letter-spacing: .12em;
  background: var(--accent);
  color: #1a1206;
  padding: 3px 8px;
  border-radius: 4px;
  font-weight: 700;
  margin-bottom: 8px;
}
.hero-preview-stage .hero-card h4 {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-size: 18px;
  color: var(--text);
  line-height: 1.15;
}
.hero-preview-stage .hero-card p {
  margin: 0 0 10px;
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.4;
}
.hero-preview-stage .hero-card .h-link {
  font-family: var(--font-display);
  font-size: 11px;
  color: var(--accent);
  letter-spacing: .04em;
  cursor: pointer;
}
.hero-preview-stage .hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .12em;
  color: var(--accent);
  background: var(--accent-15);
  padding: 4px 8px;
  border-radius: 4px;
  margin-bottom: 12px;
}
.hero-preview-stage .hero-eyebrow .pulse {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent-25);
  animation: heroPulse 1.6s infinite;
}
@keyframes heroPulse {
  0%   { box-shadow: 0 0 0 0 var(--accent-25); }
  100% { box-shadow: 0 0 0 8px transparent; }
}
.hero-preview-stage .hero-title {
  margin: 0 0 12px;
  font-family: var(--font-display);
  font-size: 36px;
  line-height: 1.0;
  font-weight: 900;
}
.hero-preview-stage .hero-title .glow {
  background: linear-gradient(90deg, #34c0eb, #6FD4F2);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0 0 28px rgba(52,192,235,.35);
}
.hero-preview-stage .hero-sub {
  font-size: 13px;
  color: var(--text-dim);
  line-height: 1.5;
  margin: 0 0 16px;
  max-width: 480px;
}
.hero-preview-stage .hero-stats {
  display: none;  /* hide live stats in preview — operator can't edit them */
}
.hero-preview-stage .hero-ctas {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
@media (max-width: 1380px) {
  .hero-preview-stage .hero { grid-template-columns: 1fr; }
  .hero-preview-stage .hero-side { flex-direction: row; }
  .hero-preview-stage .hero-card { flex: 1; }
}

/* ==================================================================
   Admin — Bots / Sim Command Center
   ==================================================================
   Switches + telemetry grid for the live admin tab. Mirrors the
   hero-editor's vocabulary so the operator sees the same affordances
   across the admin surface. */

.bots-grid {
  display: grid;
  grid-template-columns: minmax(320px, 1fr) minmax(280px, 1fr);
  gap: var(--space-4);
}
@media (max-width: 1100px) {
  .bots-grid { grid-template-columns: 1fr; }
}

.bots-toggle {
  padding: 10px 0;
  border-bottom: 1px solid var(--line-soft);
}
.bots-toggle:last-child { border-bottom: 0; }

.bots-switch {
  position: relative;
  width: 44px;
  height: 24px;
  border-radius: 999px;
  background: rgba(255,255,255,.08);
  border: 1px solid var(--line-soft);
  cursor: pointer;
  transition: background .15s, border-color .15s;
  flex-shrink: 0;
}
.bots-switch.on {
  background: var(--accent);
  border-color: var(--accent);
}
.bots-switch-knob {
  position: absolute;
  top: 2px; left: 2px;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--bg);
  transition: left .15s, background .15s;
}
.bots-switch.on .bots-switch-knob {
  left: 22px;
  background: var(--accent-ink, #1a1206);
}

/* ==================================================================
   Hero — Carousel mode  (migration 031, Phase 25)
   ==================================================================
   Admin-toggleable layout: 3 promo cards rendered in place of the
   classic 1-main + 2-side hero.

   Cards reuse the existing `.hero-card.frame` design primitives from
   styles.css (gold-hairline frame, chamfered clip-path, panel base,
   `.tag` chip, `<h4>` display title, `<p>` subtitle, `.h-link` CTA).
   The `.hero-card-promo` modifier just bumps padding + title scale so
   3 cards spanning the full hero width breathe like full-bleed promos
   instead of narrow side cards.

   Layout uses the same gap as the classic .hero grid (clamp 10/14/16)
   and the same @container main (max-width: 720px) breakpoint as
   styles.css line 804 so both layouts switch to mobile in lockstep. */

/* Compound selector (2 classes) — but we still need `!important` here
   because styles.css line ~915 has
     @media (max-width: 860px) .hero { display: grid !important;
                                       grid-template-columns: 1fr 1fr !important; }
   which collapses the classic hero into a 2-column mobile layout.
   We're a different layout entirely (single horizontally-scrolled
   row), so we override that mobile rule explicitly. */
.hero.hero-carousel-section {
  display: block !important;
  grid-template-columns: none !important;
  padding: 0 !important;
  background: transparent !important;
  border: 0 !important;
  margin: 4px 0 0 !important;
  min-height: 0 !important;
}

.hero-carousel {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(10px, 1.4vw, 16px);
  position: relative;
}

/* `.hero-card-promo` is a MODIFIER on top of `.hero-card` — it inherits
   the chamfered clip-path, panel + frame hairline, all the existing
   typography rules (.tag, h4, p, .h-link) and only bumps the inner
   sizing so a row of 3 cards reads as full-bleed promos rather than
   tiny side tiles.

   `!important` on the box-model props is forced because styles.css has
   `@media (max-width: 860px) .hero-card { padding/min-height/display
   !important }` for the classic side-card mobile layout. The carousel
   is a different layout — we must override that mobile rule. */
.hero-card.hero-card-promo {
  /* Match the .hero-main height/padding scale (styles.css:810-811) so
     the carousel row feels equivalent in visual weight to the classic
     1-main + 2-side hero it's replacing. */
  min-height: 280px !important;
  padding: 22px 26px !important;
  aspect-ratio: auto !important;
  /* The HTML element is a <button>; reset native button affordances. */
  appearance: none;
  border: 0;
  background-color: transparent;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  display: flex !important;
  flex-direction: column;
  justify-content: space-between;
  align-items: stretch;
  transition: transform .12s ease, filter .15s ease;
}
.hero-card.hero-card-promo:hover,
.hero-card.hero-card-promo:focus-visible {
  transform: translateY(-1px);
  filter: brightness(1.04);
  outline: none;
}

/* Title — bigger than the side-card h4 (which is 18px), scaled down
   from the .hero-title display size. Keeps the existing `.hero-card
   h4` typography (display font, uppercase, -0.01em tracking) and only
   overrides font-size/line-height. */
.hero-card.hero-card-promo h4 {
  font-size: clamp(20px, 2.1vw, 26px);
  line-height: 1.05;
  margin: 10px 0 6px;
  text-shadow: 0 2px 14px rgba(0, 0, 0, .45);
}
/* Subtitle — slight bump so it's legible at the larger card width.
   .hero-card p sets 12px / text-dim / line-height 1.4; we keep the
   same colour and tracking, just nudge the size for the promo scale. */
.hero-card.hero-card-promo p {
  font-size: 13px;
  line-height: 1.45;
  max-width: 38ch;
  margin: 0 0 12px;
}
/* CTA reuses .h-link (gold uppercase + arrow). The base `.hero-card
   .h-link` rule in styles.css already handles colour, font, gap, etc.
   — we only ensure the CTA sits at the bottom of the card.

   `display: inline-flex !important` overrides the
   `@media (max-width: 860px) .hero-card .h-link { display: none
   !important }` rule from styles.css. That rule hides the link on
   the classic mobile layout (whole card is tappable); the carousel
   keeps the CTA visible because it's the only call-to-action signal. */
.hero-card.hero-card-promo .h-link {
  display: inline-flex !important;
  margin-top: auto;
  align-self: flex-start;
}

/* Dot indicators — hidden on desktop; shown on mobile under the strip.
   Tiny gold pill grows to indicate the active slide, matching the
   accent-driven visual language used elsewhere. */
.hero-carousel-dots {
  display: none;
  gap: 6px;
  justify-content: center;
  margin-top: 12px;
}
.hero-carousel-dot {
  width: 7px;
  height: 7px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--white-04);
  cursor: pointer;
  transition: background .15s, width .15s;
}
.hero-carousel-dot.is-active {
  background: var(--accent);
  width: 18px;
  border-radius: 4px;
}

/* Mobile breakpoint — same 720px container threshold as the classic
   .hero so layouts collapse together. Cards become a horizontally
   scroll-snapped strip with auto-cycle handled by the JS setInterval
   in <HeroCarousel>; manual swipe is handled natively by scroll-snap.
   Flex (rather than grid) here because flex's "0 0 100%" gives each
   card the full container width cleanly across all browsers. */
@container main (max-width: 720px) {
  .hero-carousel {
    display: flex;
    grid-template-columns: none;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    scroll-behavior: smooth;
    gap: 10px;
  }
  .hero-carousel::-webkit-scrollbar { display: none; }
  .hero-card.hero-card-promo {
    flex: 0 0 100%;
    scroll-snap-align: start;
    min-height: 240px !important;
    padding: 18px 20px !important;
  }
  .hero-card.hero-card-promo h4 { font-size: clamp(20px, 5vw, 24px); }
  .hero-carousel-dots { display: flex; }
}

/* ==================================================================
   Hero Editor — Mode toggle UI  (Phase 25)
   ================================================================== */

.hero-editor-mode-row {
  /* Slimmer card than the section forms below. */
  padding: 14px 16px;
}
.hero-editor-mode-toggle {
  display: inline-flex;
  border-radius: 12px;
  background: rgba(255, 255, 255, .04);
  padding: 4px;
  border: 1px solid var(--line-soft);
  gap: 0;
}
.hero-editor-mode-btn {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text-mute);
  cursor: pointer;
  padding: 8px 16px;
  border-radius: 9px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .01em;
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.15;
  gap: 2px;
  min-width: 130px;
  transition: background .15s, color .15s;
}
.hero-editor-mode-btn:hover {
  background: rgba(255, 255, 255, .04);
  color: var(--text);
}
.hero-editor-mode-btn.is-active {
  background: var(--accent);
  color: var(--accent-ink, #1a1206);
  box-shadow: 0 2px 10px rgba(52, 192, 235, .25);
}
.hero-editor-mode-btn.is-active .dim {
  color: rgba(26, 18, 6, .72);
}

/* Carousel preview inside the admin Hero Editor — shrink everything so
   the 3 cards fit comfortably in the ~480px-wide preview pane. The
   live page renders at full width via the rules above. The selectors
   override `.hero-card.hero-card-promo` (the same primitive the live
   hero uses) so the preview shape mirrors the runtime exactly, just
   scaled down. */
.hero-preview-stage .hero-carousel-preview {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}
.hero-preview-stage .hero-carousel-preview .hero-card.hero-card-promo {
  min-height: 170px;
  padding: 14px 14px 16px;
}
.hero-preview-stage .hero-carousel-preview .hero-card.hero-card-promo h4 {
  font-size: 14px;
  line-height: 1.05;
  margin: 6px 0 4px;
}
.hero-preview-stage .hero-carousel-preview .hero-card.hero-card-promo p {
  font-size: 11px;
  line-height: 1.35;
  margin: 0 0 8px;
  -webkit-line-clamp: 2;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.hero-preview-stage .hero-carousel-preview .hero-card.hero-card-promo .tag {
  font-size: 8px;
  padding: 2px 5px;
}
.hero-preview-stage .hero-carousel-preview .hero-card.hero-card-promo .h-link {
  font-size: 10px;
}

/* ==================================================================
   Phase 26 follow-up — Balance + Wallet pill pair (Shuffle-style).
   ==================================================================
   Centered in the topbar between the brand (left) and the
   notifications cluster (right). Balance and Wallet sit flush
   together as one rounded "pill pair":
     [ ◯ $123.45 ▾ ][ Wallet ]
   The balance side is a dark pill with mono-font numbers; the
   Wallet side is a bright accent pill. Border-radius is asymmetric
   to give a single combined shape (left-side rounded on its left,
   right-side rounded on its right, flat where they meet). */

.topbar .topbar-center {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  position: relative;          /* anchor for BalanceDropdown */
}
/* Desktop — center the wallet pill over the MAIN CONTENT column (the area
   between the left rail and the chat panel), NOT the whole topbar. The
   topbar spans the main + right grid columns, so the default flex centering
   (two flex:1 spacers) sat too far right whenever the chat panel was open.
   --main-cx (set by the ResizeObserver in app.jsx) is the live horizontal
   centre of the .main column measured from its left edge — which the topbar
   shares — so the pill sits at the true content centre and re-tracks whenever
   the rail collapses or the chat panel opens/closes. The 50% fallback covers
   first paint before the observer fires. */
@media (min-width: 861px){
  .topbar .topbar-center.bal-wallet-pair{
    position: absolute;
    top: 50%;
    left: var(--main-cx, 50%);
    transform: translate(-50%, -50%);
  }
}
.topbar .bal-wallet-pair {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  background: rgba(255, 255, 255, .03);
  border: 1px solid var(--line-soft);
  border-radius: 999px;
}

/* Balance pill — left half. Dark, mono numbers, chevron. */
.bal-btn.bal-btn-pill {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px 8px 10px;
  border-radius: 999px;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .02em;
  transition: background .15s ease;
}
.bal-btn.bal-btn-pill:hover { background: rgba(255, 255, 255, .04); }
.bal-btn.bal-btn-pill.on    { background: rgba(255, 255, 255, .06); }
.bal-btn.bal-btn-pill .bal-val {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
}

/* Wallet pill — right half. Bright accent. */
.wallet-btn.wallet-btn-pill {
  clip-path: none !important;
  border-radius: 999px;
  padding: 8px 22px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
  color: var(--accent-ink, #1a1206);
  border: 0;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(52, 192, 235, .35);
  transition: transform .12s ease, box-shadow .15s ease, filter .15s ease;
}
.wallet-btn.wallet-btn-pill:hover {
  transform: translateY(-1px);
  filter: brightness(1.06);
  box-shadow: 0 6px 18px rgba(52, 192, 235, .45);
}

/* ============ Phase 29.8 — Loading + Empty State primitives ============
   Used by `<LoadingSkeleton/>` and `<EmptyState/>` from src/loading.jsx.
   Adopt these everywhere a page used to print its own "loading…" message. */
.skeleton-row {
  background: linear-gradient(90deg,
    rgba(255,255,255,.04) 0%,
    rgba(255,255,255,.10) 50%,
    rgba(255,255,255,.04) 100%);
  background-size: 200% 100%;
  animation: skeleton-pulse 1.6s ease infinite;
  border-radius: 6px;
}
@keyframes skeleton-pulse {
  0%   { background-position:  200% 0; }
  100% { background-position: -200% 0; }
}
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 40px 20px;
  color: var(--text-dim);
  text-align: center;
}
.empty-state svg { opacity: 0.4; }
.empty-state h4 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 16px;
  color: var(--text);
  margin: 0;
}
.empty-state p {
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.4;
  margin: 0;
  max-width: 320px;
}

/* Phase 29.1 — Wallet pill icon variant (mobile). On phones the
   "Wallet" word becomes a "+" SVG so the balance pill keeps its
   digits. Square 36px pill, same gold gradient + glow. Topbar.jsx
   adds .wallet-btn-icon when isMobile. */
.wallet-btn.wallet-btn-pill.wallet-btn-icon {
  padding: 8px 10px;
  min-width: 36px;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.wallet-btn.wallet-btn-pill.wallet-btn-icon svg {
  display: block;
}

/* Mobile compaction — keep the pair visible but tighter padding. */
@media (max-width: 860px) {
  .topbar .bal-wallet-pair { padding: 3px; gap: 2px; }
  .bal-btn.bal-btn-pill { padding: 6px 10px 6px 8px; gap: 6px; font-size: 12px; }
  .bal-btn.bal-btn-pill .bal-val { font-size: 12px; }
  .wallet-btn.wallet-btn-pill { padding: 6px 14px; font-size: 11px; }
  .wallet-btn.wallet-btn-pill.wallet-btn-icon {
    padding: 6px 8px;
    min-width: 32px;
    width: 32px;
    height: 32px;
  }
}
@media (max-width: 540px) {
  .wallet-btn.wallet-btn-pill { padding: 6px 12px; }
  .wallet-btn.wallet-btn-pill.wallet-btn-icon { padding: 6px 8px; min-width: 32px; width: 32px; }
}

/* Task #247 — phone-width tightening pass on the centre group. The
   IN PLAY pill + Wallet `+` were dominating the topbar (taller than
   the burger / notifications / avatar to the sides), so the whole
   centre group now reads as a compact pill. Keeps desktop and tablet
   appearance unchanged (larger breakpoints above are untouched). */
@media (max-width: 540px) {
  .topbar .bal-wallet-pair { padding: 2px; gap: 2px; }
  .bal-btn.bal-btn-pill {
    padding: 4px 8px 4px 6px;
    gap: 4px;
    font-size: 11px;
    min-height: 28px;
  }
  .bal-btn.bal-btn-pill .bal-val { font-size: 11px; }
  /* Coin glyph: shrink the SVG (or text fallback) so it doesn't
     pancake the pill height. */
  .bal-btn.bal-btn-pill > svg,
  .bal-btn.bal-btn-pill .bal-coin { width: 14px; height: 14px; min-width: 14px; }
  .bal-btn.bal-btn-pill .bal-coin { font-size: 9px; line-height: 14px; }
  /* Chevron */
  .bal-btn.bal-btn-pill > svg:last-child { width: 10px; height: 10px; }
  /* IN PLAY label (replaces value text during slot/originals play) */
  .bal-btn.bal-btn-pill .bal-val-playing { font-size: 9.5px; gap: 4px; }
  .bal-btn.bal-btn-pill .bal-playing-dot { width: 5px; height: 5px; }
  /* Wallet `+` button — shrink so the centre group stops crowding
     the burger, notifications and avatar on a 390px viewport. */
  .wallet-btn.wallet-btn-pill.wallet-btn-icon {
    padding: 4px 6px;
    min-width: 28px;
    width: 28px;
    height: 28px;
  }
  .wallet-btn.wallet-btn-pill.wallet-btn-icon svg { width: 14px; height: 14px; }
}

/* Task #247 — IN PLAY pill mode at phone width: collapse the padding
   even further and lock the min-height to match the smaller wallet
   button so the pair stays vertically aligned. Overrides the desktop
   .bal-btn-playing rule below (which sets 28px / 8px padding). */
@media (max-width: 540px) {
  .bal-btn.bal-btn-pill.bal-btn-playing {
    padding: 3px 8px 3px 6px;
    min-height: 26px;
  }
}

/* ==================================================================
   Phase 26.3d — Floating Live Support widget (Gamdom/Stake-style).
   ==================================================================
   FAB at bottom-right of every page (except game pages where the
   widget self-hides via `.gp-bottombar` detection). Click → opens a
   chat panel anchored at the bottom-right that slides up. Reuses the
   existing FAQ-bot logic from LiveSupportPage. */

.ls-fab {
  position: fixed;
  bottom: 18px;
  /* Operator rebuild — moved to bottom-RIGHT (was bottom-left). When
     the right chat panel is open, the body gets `.right-open` and
     the FAB shifts left by --right-w + 14 px so it docks against the
     panel edge instead of being hidden behind it. The CSS variable
     `--right-w` is already declared in :root (336 px desktop). */
  right: 18px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
  color: var(--on-accent, #1a1206);
  border: 0;
  display: grid; place-items: center;
  cursor: pointer;
  box-shadow: 0 8px 22px rgba(52, 192, 235, .3), 0 2px 8px rgba(0, 0, 0, .3);
  z-index: 80;            /* below modal-root (100) but above page chrome */
  transition: transform var(--dur-base) var(--ease-standard),
              box-shadow var(--dur-base) var(--ease-standard),
              opacity var(--dur-base) var(--ease-standard);
}
.ls-fab svg { width: 16px; height: 16px; }
.ls-fab:hover {
  transform: translateY(-2px);
  box-shadow: 0 18px 44px rgba(52, 192, 235, .45), 0 6px 16px rgba(0, 0, 0, .4);
}
.ls-fab.is-hidden {
  opacity: 0;
  pointer-events: none;
  transform: scale(.7);
}

/* Chat panel — anchored bottom-right, slides up on open. Sized to feel
   like a Crisp/Intercom widget. Adopts the existing modal panel
   styles (panel bg, border, soft shadow) so it matches the rest of
   the app's chrome. */
.ls-panel {
  position: fixed;
  bottom: 22px;
  /* Operator rebuild — mirrored to the right corner so it opens
     from the same edge as its FAB. Pushed by --right-w when the
     chat panel is open (see body.right-open below). */
  right: 22px;
  width: 380px;
  max-width: calc(100vw - 24px);
  height: 560px;
  max-height: calc(100dvh - 44px);
  z-index: 81;
  display: flex;
  flex-direction: column;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg, 14px);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .55), 0 8px 24px rgba(0, 0, 0, .4);
  overflow: hidden;
  animation: ls-panel-in var(--dur-slow) var(--ease-entrance);
}
@keyframes ls-panel-in {
  from { transform: translateY(18px) scale(.96); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

.ls-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line-soft);
  background: linear-gradient(180deg, rgba(52, 192, 235, .07), transparent);
}
.ls-panel-title {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--text);
}
.ls-status-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #4ee6a8;
  box-shadow: 0 0 0 0 rgba(78, 230, 168, .6);
  animation: ls-pulse 1.6s infinite;
}
@keyframes ls-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(78, 230, 168, .6); }
  70%  { box-shadow: 0 0 0 8px rgba(78, 230, 168, 0); }
  100% { box-shadow: 0 0 0 0 rgba(78, 230, 168, 0); }
}
.ls-panel-close {
  appearance: none;
  width: 28px; height: 28px;
  border: 1px solid var(--line-soft);
  background: transparent;
  color: var(--text-mute);
  border-radius: 6px;
  display: grid; place-items: center;
  cursor: pointer;
  transition: color .15s, border-color .15s;
}
.ls-panel-close:hover { color: var(--text); border-color: var(--accent); }

.ls-panel-body {
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding: 14px 12px;
  display: flex; flex-direction: column; gap: 8px;
}
.ls-msg { display: flex; }
.ls-msg.bot { justify-content: flex-start; }
.ls-msg.me  { justify-content: flex-end;   }
.ls-bubble {
  max-width: 78%;
  padding: 10px 12px;
  border-radius: 12px;
  font-size: 13px;
  line-height: 1.45;
  word-wrap: break-word;
}
.ls-msg.bot .ls-bubble {
  background: rgba(255, 255, 255, .04);
  border: 1px solid var(--line-soft);
  color: var(--text);
  border-bottom-left-radius: 4px;
}
.ls-msg.me .ls-bubble {
  background: var(--accent);
  color: var(--on-accent, #1a1206);
  border-bottom-right-radius: 4px;
}

.ls-panel-input {
  display: flex; gap: 8px;
  padding: 10px 12px;
  border-top: 1px solid var(--line-soft);
  background: rgba(0, 0, 0, .25);
}
.ls-panel-input input {
  flex: 1;
  background: rgba(255, 255, 255, .04);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  padding: 9px 12px;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  outline: none;
}
.ls-panel-input input:focus { border-color: var(--accent); }
.ls-send {
  appearance: none; border: 0; cursor: pointer;
  width: 36px; height: 36px;
  border-radius: 8px;
  background: var(--accent);
  color: var(--on-accent, #1a1206);
  display: grid; place-items: center;
  transition: filter .15s, transform .12s;
}
.ls-send:hover { filter: brightness(1.05); transform: translateY(-1px); }

/* Mobile — anchor to the SAME corner but slightly smaller padding so
   the panel doesn't dominate the viewport. */
/* Operator rebuild — when the right chat panel is open, push the
   support FAB + panel left by the panel's width so they stay
   visible against the panel's edge instead of being hidden behind
   it. The body gets `.right-open` from app.jsx (already wired for
   layout grid); we use it here for offset, not display:none. */
body.right-open .ls-fab,
body.right-open .ls-panel {
  right: calc(var(--right-w) + 14px);
}
/* Operator-toggleable: the user can disable the support FAB from the
   tweaks/settings panel. App writes `data-support="off"` on <body>
   when the toggle is off. */
body[data-support="off"] .ls-fab,
body[data-support="off"] .ls-panel {
  display: none !important;
}

@media (max-width: 540px) {
  /* Operator rebuild — clear the mobile bottom-nav (64 px) + safe-area
     inset so the FAB never overlaps the tab bar. */
  .ls-fab {
    width: 38px; height: 38px;
    bottom: calc(var(--bottom-nav-h, 64px) + 14px + env(safe-area-inset-bottom, 0px));
    right: 14px; left: auto;
  }
  .ls-fab svg { width: 14px; height: 14px; }
  .ls-panel {
    bottom: calc(var(--bottom-nav-h, 64px) + 14px + env(safe-area-inset-bottom, 0px));
    left: 14px; right: 14px;
    width: auto; max-width: none;
    height: calc(100dvh - var(--bottom-nav-h, 64px) - 100px);
  }
  /* When the mobile chat sheet is open, hide the FAB entirely — the
     sheet covers the screen and the support entry-point belongs in
     the panel header, not floating over the message composer. */
  body.right-open .ls-fab,
  body.right-open .ls-panel { display: none !important; }
}
/* Desktop: when the right chat panel is open, lift the FAB above the
   chat input row in addition to pushing it left of the panel. Was a
   pure horizontal shift; the screenshot showed the icon still sitting
   on top of the message composer. */
@media (min-width: 541px) {
  body.right-open .ls-fab {
    right: calc(var(--right-w) + 14px);
    bottom: 88px;
  }
}

/* ==================================================================
   Phase 26.2c — ORIGINALS chip on home Originals tiles + View More
   link on every home rail.
   ================================================================== */

/* `.t-prov-tab` mirrors `.slot-card-prov-tab` (top of slots-page.jsx)
   but is fixed gold (var(--accent)) for in-house games. Sits at the
   top-center of `.game-tile`. The .game-tile container needs
   `position: relative` and `overflow: visible` for absolute children
   — both are already set on the existing `.game-tile` rule. */
.game-tile { position: relative; }
.game-tile .t-prov-tab {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  padding: 3px 12px 4px;
  font-family: var(--font-display);
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: .12em;
  color: var(--accent-ink, #1a1206);
  text-transform: uppercase;
  background: var(--accent);
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  border-bottom-left-radius: 6px;
  border-bottom-right-radius: 6px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .35), 0 0 12px rgba(52, 192, 235, .25);
  pointer-events: none;
}

/* "View More →" link in `.sec-tools` of every home rail. Right-aligned
   next to the prev/next arrow buttons. Uses gold accent + mono font
   for the same look as `.h-link` elsewhere. */
.sec-view-all {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-mute);
  cursor: pointer;
  border-radius: var(--radius-xs);
  transition: color .15s, background .15s;
  margin-right: 4px;
}
.sec-view-all:hover {
  color: var(--accent);
  background: rgba(52, 192, 235, .08);
}

/* ==================================================================
   Phase 26 follow-up — Roulette UI redesign (Stake-style).
   ================================================================== */

.rl-game-v2 {
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 100%;
  max-width: 1100px;
  margin: 0 auto;
  padding: 12px clamp(8px, 1.5vw, 20px);
}

/* === Phase bar (top) === */
.rl-phase-bar {
  position: relative;
  text-align: center;
  padding: 14px 0 10px;
}
.rl-phase-label {
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
  color: var(--text-dim);
  letter-spacing: .02em;
}
.rl-phase-time {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 800;
  color: var(--text);
  letter-spacing: -.02em;
  line-height: 1.1;
  margin-top: 2px;
}
.rl-phase-progress {
  position: relative;
  height: 3px;
  margin: 10px auto 0;
  width: min(560px, 80%);
  background: rgba(255, 255, 255, .04);
  border-radius: 999px;
  overflow: hidden;
}
.rl-phase-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #ff4d65, #c12c41);
  border-radius: 999px;
  transition: width .25s linear;
}

/* === 26.6d — Wheel stage wraps the stripe + lays the countdown
       overlay on top. position:relative so the overlay can absolute-
       fill it. Decorative outer frame matches the customer reference
       (rounded, slight inset, faint vignette). */
.rl-wheel-stage {
  position: relative;
  border-radius: 14px;
  padding: 10px;
  background: linear-gradient(180deg, rgba(20, 27, 46, .9), rgba(12, 17, 30, .95));
  border: 1px solid rgba(255, 255, 255, .06);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .35), inset 0 0 0 1px rgba(255, 255, 255, .02);
}

/* === 26.6d — Top header row: PREVIOUS ROUNDS | trophy | LAST 100 === */
.rl-top-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 18px;
  padding: 4px 4px 12px;
}
/* Operator rebuild (PDF page 4): pills moved below the wheel; this
   variant is a 2-col layout with trophy left + LAST 100 right. */
.rl-top-row.rl-top-row-2col {
  grid-template-columns: 1fr 1fr;
}
/* Operator rebuild — trophy removed entirely; LAST 100 right-aligns. */
.rl-top-row.rl-top-row-end {
  display: flex;
  justify-content: flex-end;
}
.rl-top-left {
  display: flex; align-items: center; gap: 12px;
  min-width: 0;
}
.rl-top-center { display: flex; justify-content: center; }
.rl-top-right  { display: flex; align-items: center; justify-content: flex-end; gap: 10px; min-width: 0; }
.rl-prev-rounds-label,
.rl-stats-label {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .14em;
  color: var(--text-mute);
  white-space: nowrap;
}
.rl-stats-100 {
  display: inline-flex;
  gap: 6px;
}
.rl-stats-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 8px;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .06);
}
.rl-stats-pill em { font-style: normal; }
.rl-stats-dot {
  width: 8px; height: 8px; border-radius: 50%;
  display: inline-block;
  flex: 0 0 8px;
}
.rl-dot-red   { background: linear-gradient(180deg, #ff4d65, #c12c41); box-shadow: 0 0 6px rgba(255, 77, 101, .55); }
.rl-dot-black { background: #1d1f23; box-shadow: inset 0 0 0 1px rgba(255,255,255,.18); }
.rl-dot-green { background: linear-gradient(180deg, #2ecc7b, #1a8e58); box-shadow: 0 0 6px rgba(46, 204, 123, .55); }
.rl-stats-pill-red    { color: #ff8395; }
.rl-stats-pill-black  { color: #c8cdd6; }
.rl-stats-pill-green  { color: #6cf0b1; }

/* === 26.6d — Countdown overlay over the stripe.
   Visible during betting + settled (label + numeric countdown +
   thin progress bar). Fades in/out via .is-visible toggle. The
   pointer-events:none keeps clicks on the bet boxes below working. */
.rl-overlay {
  position: absolute;
  inset: 10px;                       /* match stage padding so it
                                        sits on top of the stripe */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border-radius: 8px;
  background: linear-gradient(180deg, rgba(8, 12, 22, .55), rgba(8, 12, 22, .82));
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  pointer-events: none;
  opacity: 0;
  transform: translateY(2px);
  transition: opacity .45s ease, transform .45s ease;
  z-index: 5;
}
.rl-overlay.is-visible {
  opacity: 1;
  transform: translateY(0);
}
.rl-overlay-label {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .72);
}
.rl-overlay-time {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 700;
  line-height: 1;
  color: #fff;
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  text-shadow: 0 0 18px rgba(52, 192, 235, .35);
}
.rl-overlay-time-num { letter-spacing: -.02em; }
.rl-overlay-time-unit {
  font-size: 14px;
  font-weight: 500;
  color: rgba(255, 255, 255, .55);
}
.rl-overlay-progress {
  position: absolute;
  bottom: 8px;
  left: 14px; right: 14px;
  height: 3px;
  background: rgba(255, 255, 255, .08);
  border-radius: 999px;
  overflow: hidden;
}
.rl-overlay-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), #5CCDEF);
  box-shadow: 0 0 10px rgba(52, 192, 235, .55);
  border-radius: 999px;
  transition: width .25s linear;
}
/* Task #31 — Settled "X Won" announcement. The numeric countdown is
   gone; the moment is now just the headline + a thinned progress
   bar. The label is bumped up to display-headline weight + size so
   the layout still feels balanced and premium without the timer
   sitting under it. */
.rl-overlay.rl-overlay-settled {
  /* Push the headline closer to the optical centre of the stripe
     now that the timer no longer occupies a row below it. */
  justify-content: center;
  gap: 0;
}
.rl-overlay.rl-overlay-settled .rl-overlay-label {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 800;
  letter-spacing: .14em;
  color: #fff;
  text-shadow: 0 0 24px var(--accent-glow);
  /* Subtle entrance so the announcement reads as a beat, not a snap. */
  animation: rlSettledIn .35s cubic-bezier(.22, .9, .26, 1);
}
.rl-overlay.rl-overlay-settled .rl-overlay-progress-fill {
  background: linear-gradient(90deg, var(--accent), var(--accent-bright));
  box-shadow: 0 0 12px var(--accent-glow);
}
@keyframes rlSettledIn {
  0%   { opacity: 0; transform: translateY(6px); letter-spacing: .04em; }
  100% { opacity: 1; transform: translateY(0);   letter-spacing: .14em; }
}

/* === 26.6e — Mobile layout (≤720 px). Customer reference shows a
   single-column stack with the wheel up top, bet boxes stacked below,
   and the PREVIOUS ROUNDS + LAST 100 stats moved to the BOTTOM as
   small-print badges. Achieved with CSS `order` reordering inside
   .rl-game-v2 (which is already display:flex; flex-direction:column).
   The countdown overlay also gets a bigger numeral so the "Rolling
   in: 13.06" reads at a glance on a 375px phone. */
@media (max-width: 720px) {
  /* Reorder children of .rl-game-v2 so the top row drops to the
     bottom of the page on mobile. The numbers reserve large gaps
     between blocks for safe rearrangement. */
  .rl-game-v2 > .rl-wheel-stage      { order: 0; }
  .rl-game-v2 > .rl-bet-input-row    { order: 1; }
  .rl-game-v2 > .rl-boxes            { order: 2; }
  .rl-game-v2 > .rl-fair             { order: 4; }
  .rl-game-v2 > .rl-top-row          { order: 99; }   /* footer-ish */

  /* Compact "footer" header on mobile — a stack of two centred
     labelled rows (PREVIOUS ROUNDS · 8 pips, then LAST 100 ·
     stats). The trophy is dropped on mobile (the bet-box totals
     already show per-colour stake). */
  .rl-top-row {
    grid-template-columns: 1fr;
    gap: 6px;
    padding: 6px 0 0;
  }
  .rl-top-left,
  .rl-top-center,
  .rl-top-right {
    justify-content: center;
    flex-direction: column;
    gap: 6px;
  }
  .rl-top-center { display: none; }                 /* trophy hidden on mobile */
  .rl-prev-rounds-label,
  .rl-stats-label  { font-size: 9px; letter-spacing: .18em; text-align: center; }

  /* Overlay scaled UP on mobile so it reads as the focal point of
     the wheel (matches the customer's mobile mockup where "Rolling
     in: 13.06" dominates the wheel area). Stack label over time on
     two lines for the right rhythm. */
  .rl-overlay { gap: 4px; }
  .rl-overlay-label {
    font-size: 13px;
    letter-spacing: .14em;
    color: rgba(255, 255, 255, .85);
  }
  .rl-overlay-time {
    font-size: 36px;
    line-height: 1.05;
  }
  .rl-overlay-time-unit { font-size: 16px; }

  /* Wheel stage: a touch more vertical room so the overlay text
     doesn't crowd the tiles. */
  .rl-wheel-stage { padding: 8px; }
  /* Task #31 — mobile stripe also gets a thicker rail (was 88px). */
  .rl-stripe-wrap-v2 { height: 104px; }
  .rl-tile-v2 { height: 88px; font-size: 24px; }
  /* Task #31 — settled headline keeps its display-headline size on
     mobile so the win moment stays the focal point even without the
     timer underneath. Overrides the 13px label rule above. */
  .rl-overlay.rl-overlay-settled .rl-overlay-label { font-size: 22px; }
}

/* === Wheel stripe ===
   Task #31 — bumped from 84px → 116px so the spinning line reads as
   a substantial casino rail instead of a thin ribbon. Tile heights
   step up in lockstep below. The horizontal landing math (TILE_WIDTH
   / TILE_MARGIN in roulette-game.jsx) is independent of height, so
   the spin still lands pixel-accurate. */
.rl-stripe-wrap-v2 {
  position: relative;
  height: 116px;
  background: var(--bg-2);
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  overflow: hidden;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .04),
    inset 0 -1px 0 rgba(0, 0, 0, .35),
    0 6px 18px rgba(0, 0, 0, .35);
}
.rl-stripe-wrap-v2 .rl-pointer {
  position: absolute;
  top: -2px;
  left: 50%;
  transform: translateX(-50%) rotate(180deg);
  z-index: 4;
  pointer-events: none;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .55));
}
.rl-stripe-wrap-v2::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 50%;
  transform: translateX(-50%);
  border-left: 9px solid transparent;
  border-right: 9px solid transparent;
  border-bottom: 11px solid rgba(255, 255, 255, .85);
  z-index: 4;
  pointer-events: none;
  filter: drop-shadow(0 -2px 4px rgba(0, 0, 0, .55));
}
.rl-stripe-wrap-v2::before {
  /* Vertical centerline (subtle) */
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  left: 50%;
  width: 1px;
  background: rgba(255, 255, 255, .12);
  z-index: 3;
  pointer-events: none;
}
.rl-stripe-v2 {
  display: flex;
  height: 100%;
  align-items: center;
  padding: 6px 0;
  will-change: transform;
}
.rl-tile-v2 {
  flex: 0 0 84px;
  width: 84px;
  /* Task #31 — 72 → 100 so the tile fills the new 116px-tall wrap
     with a small breathing margin top/bottom. The COLORED tile gets
     more presence so the spinning line reads cleanly. */
  height: 100px;
  margin: 0 3px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 800;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .5);
  transition: filter .25s ease;
  position: relative;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .12),
    inset 0 -1px 0 rgba(0, 0, 0, .25);
}
.rl-tile-v2 .rl-tile-num {
  letter-spacing: -.01em;
}
.rl-tile-red    { background: linear-gradient(180deg, #ee4156, #c12c41); }
.rl-tile-black  { background: linear-gradient(180deg, #34373c, #1d1f23); }
.rl-tile-green  { background: linear-gradient(180deg, #2ecc7b, #1a8e58); color: #061712; }
.rl-tile-v2.is-winner {
  outline: 3px solid var(--accent);
  outline-offset: -2px;
  filter: brightness(1.1);
  box-shadow: 0 0 22px rgba(52, 192, 235, .55);
}

/* === Trophy + history pips row === */
.rl-trophy-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  padding: 0 4px;
}
.rl-trophy {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
/* 26.6c — SVG icon, not emoji. Force a fixed line-height + alignment
   so the trophy sits on the same baseline as the dollar amount. */
.rl-trophy-ico {
  display: inline-flex;
  align-items: center;
  color: var(--accent);
  line-height: 0;
}
.rl-trophy-ico svg { display: block; }
.rl-trophy-amt {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  color: var(--accent);
}
/* Operator rebuild (PDF page 4): pills moved below the wheel, count
   bumped to 10, size bumped 28→40 so the row reads from across the
   table. Lives inside the new .rl-history-row. */
.rl-history-pips {
  display: inline-flex;
  flex-wrap: nowrap;
  gap: 6px;
  overflow: hidden;
}
.rl-history-pips .rl-pip {
  width: 26px;
  height: 26px;
  flex: 0 0 26px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, .5);
  border: 0; padding: 0;
  cursor: default;
  transition: transform var(--dur-fast) var(--ease-standard),
              box-shadow var(--dur-fast) var(--ease-standard);
}
.rl-history-pips .rl-pip-red    { background: #c12c41; }
.rl-history-pips .rl-pip-black  { background: #1d1f23; border: 1px solid var(--line-soft); }
.rl-history-pips .rl-pip-green  { background: #1a8e58; color: #061712; }
.rl-history-pips .rl-pip-clickable { cursor: pointer; }
.rl-history-pips .rl-pip-clickable:hover {
  transform: translateY(-2px);
  box-shadow: 0 0 0 2px var(--accent-40);
}
.rl-history-pips .rl-pip-clickable:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Container for the history strip below the wheel. Lays out: label
   on the left, pills in the middle, "view past hits" link right. */
.rl-history-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius);
  margin: 12px 0;
  flex-wrap: nowrap;
  height: 44px;
  min-height: 44px;
  overflow: hidden;
  white-space: nowrap;
}
.rl-history-row .rl-prev-rounds-label {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  flex-shrink: 0;
}
.rl-history-row .rl-history-pips {
  flex: 1 1 auto;
  min-width: 0;
  justify-content: flex-start;
}
.rl-history-more {
  appearance: none;
  border: 1px solid var(--border-default);
  background: var(--white-04);
  color: var(--text-secondary);
  padding: 5px 10px;
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: .04em;
  cursor: pointer;
  flex-shrink: 0;
  white-space: nowrap;
  transition: color var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard);
}
.rl-history-more:hover {
  color: var(--accent);
  border-color: var(--accent-40);
  background: var(--accent-soft);
}
@media (max-width: 480px) {
  .rl-history-row {
    gap: 6px;
    padding: 6px 8px;
    height: 40px;
    min-height: 40px;
  }
  .rl-history-row .rl-prev-rounds-label { display: none; }
  .rl-history-pips { gap: 4px; }
  .rl-history-pips .rl-pip {
    width: 22px;
    height: 22px;
    flex: 0 0 22px;
    font-size: 10px;
  }
  .rl-history-more {
    padding: 4px 8px;
    font-size: 10px;
  }
}

/* === Bet input row (amount + chips) === */
.rl-bet-input-row {
  display: grid;
  grid-template-columns: minmax(220px, 1fr) auto;
  gap: 12px;
  padding: 12px 14px;
}
@media (max-width: 720px) { .rl-bet-input-row { grid-template-columns: 1fr; } }
.rl-bet-input label {
  display: block;
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: .14em;
  color: var(--text-mute);
  text-transform: uppercase;
  margin-bottom: 4px;
}
.rl-bet-input-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  background: rgba(255, 255, 255, .03);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  padding: 4px 4px 4px 10px;
}
.rl-bet-input-wrap:focus-within { border-color: var(--accent); }
.rl-bet-input-coin {
  width: 22px; height: 22px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: linear-gradient(135deg, #4ee6a8, #1a8e58);
  color: #061712;
  font-weight: 800;
  font-size: 12px;
}
.rl-bet-input-wrap input {
  flex: 1;
  background: transparent;
  border: 0;
  outline: none;
  color: var(--text);
  font: inherit;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  padding: 6px 0;
}
.rl-bet-clear {
  appearance: none;
  border: 0;
  background: rgba(255, 255, 255, .04);
  color: var(--text-dim);
  padding: 6px 14px;
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: .06em;
  cursor: pointer;
}
.rl-bet-clear:hover { color: var(--text); background: rgba(255, 255, 255, .06); }

/* Operator request — roulette quick-amount chips (+$10 / +$50 /
   +$100 / 1/2 / x2 / Max) now match the canonical .gp-input .mini
   styling used by every other game's bet panel: neutral elevated
   background, Inter UI 12px/700, 6×10 padding, gold-on-hover. The
   prior gold-ghost treatment was unique to roulette and read as
   inconsistent against the rest of the lobby. */
.rl-bet-chips {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 6px;
  align-self: end;
}
@media (max-width: 720px) {
  .rl-bet-chips { grid-template-columns: repeat(3, 1fr); }
}
.rl-bet-chips button {
  appearance: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-elevated);
  border: 0;
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0;
  /* Match the bet input wrap height (~38px = inner padding 4+4 plus
     input padding 6+6 plus 14px font line). Drop vertical padding —
     the explicit min-height is what controls the row alignment so
     the chips read as one continuous row with the bet field. */
  padding: 0 14px;
  min-height: 38px;
  border-radius: var(--radius-sm);
  transition: color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard);
}
.rl-bet-chips button:hover {
  background: var(--accent);
  color: var(--accent-contrast);
}
.rl-bet-chips button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* === Three bet boxes === */
.rl-boxes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}
@media (max-width: 720px) { .rl-boxes { grid-template-columns: 1fr; } }

.rl-box {
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 12px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* Constant multiplier badge (×2 / ×14 / ×2) — replaces the old
   "Potential Profit: $0.00" line that only made sense once the user
   had typed a stake. The multiplier is the box's permanent attribute
   so it reads at a glance even with an empty bet input. */
.rl-box-mult {
  align-self: flex-start;
  display: inline-flex;
  align-items: baseline;
  padding: 4px 10px;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .02em;
  color: var(--accent);
  background: rgba(52, 192, 235, .10);
  border: 1px solid rgba(52, 192, 235, .28);
  border-radius: var(--radius-pill, 999px);
  font-variant-numeric: tabular-nums;
}
/* Task #31 — Bet-color button now speaks the SAME visual language as
   the site's canonical .btn-primary CTA: signature chamfer clip, Sora
   display typography, lift-on-hover, brand-amber focus ring + glow.
   The only thing that changes per color is the gradient + on-button
   text color so the red/green/black cue still reads at a glance.
   The label is now the literal color name (RED / GREEN / BLACK), set
   in the same display font + tracking as the rest of the buttons on
   the site. */
.rl-box-btn {
  /* Operator rebuild — match the originals' bet-control language:
     pill shape (no chamfer), cleaner solid fill (gradient kept lightly
     for color identity), bigger touch target, same lift-on-hover as
     .gp-bet. Each variant overrides the gradient + glow below. */
  appearance: none;
  border: 0;
  width: 100%;
  padding: 16px 0;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .55);
  border-radius: var(--radius-pill);
  clip-path: none;
  transition:
    transform var(--dur-fast) var(--ease-standard),
    box-shadow var(--dur-base) var(--ease-standard),
    filter var(--dur-base) var(--ease-standard);
}
.rl-box-btn-red {
  background: linear-gradient(180deg, #ff5b71, #b32437);
  box-shadow: 0 8px 22px rgba(216, 57, 84, .35);
}
.rl-box-btn-green {
  background: linear-gradient(180deg, #3fe39a, #169059);
  color: #061712;
  text-shadow: none;
  box-shadow: 0 8px 22px rgba(46, 204, 123, .35);
}
.rl-box-btn-black {
  background: linear-gradient(180deg, #565a61, #16181c);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .55);
}
.rl-box-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  filter: brightness(1.06);
}
.rl-box-btn-red:hover:not(:disabled)   { box-shadow: 0 12px 30px rgba(216, 57, 84, .5); }
.rl-box-btn-green:hover:not(:disabled) { box-shadow: 0 12px 30px rgba(46, 204, 123, .5); }
.rl-box-btn-black:hover:not(:disabled) { box-shadow: 0 12px 30px rgba(0, 0, 0, .65); }
.rl-box-btn:active:not(:disabled) {
  transform: translateY(1px);
  filter: brightness(.96);
}
.rl-box-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.rl-box-btn:disabled { opacity: .5; cursor: not-allowed; }
.rl-box-btn.is-winner {
  /* Winning box gets the brand-amber halo treatment so the moment
     reads as the round's resolution without overwhelming the
     button's color cue. */
  filter: brightness(1.08);
  box-shadow:
    0 0 0 2px var(--accent),
    0 0 28px var(--accent-glow);
}

.rl-box-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-family: var(--font-display);
  font-size: 11px;
  color: var(--text-dim);
}
.rl-box-mybet {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: rgba(52, 192, 235, .08);
  border: 1px solid rgba(52, 192, 235, .22);
  border-radius: var(--radius-xs);
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--accent);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.rl-box-mybet-amt { color: var(--text); }
.rl-box-mybet-arrow {
  color: var(--text-mute);
  font-family: var(--font-display);
  font-weight: 600;
}
.rl-box-mybet-win {
  margin-left: auto;
  color: var(--accent);
  font-weight: 800;
}
.rl-box-you {
  font-size: 9px;
  letter-spacing: .12em;
  background: var(--accent);
  color: var(--accent-ink, #1a1206);
  padding: 2px 6px;
  border-radius: 3px;
  font-weight: 800;
}

/* Operator rebuild (PDF page 4): "make the betters name bigger too,
   the other font makes everything hard to see". Names + amounts went
   from 11px to 14px; rows are taller so they read at a glance.
   Scrollable per the brief — taller list height. */
.rl-box-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 180px;
  overflow-y: auto;
}
.rl-box-list-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 10px;
  background: var(--white-04);
  border-radius: var(--radius-sm);
  font-size: 14px;
}
.rl-box-list-name {
  display: inline-flex;
  align-items: center;
  /* Operator brief — tightened from 6 px so the rank icon sits visually
     attached to the username in the roulette side-bet list. */
  gap: 4px;
  color: var(--text);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rl-box-list-amt {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--text);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

/* Task #31 — the under-grid bet status popup was removed. Confirmations
   are implicit (the bet now appears live in the per-color grid + the YOU
   chip lights up); gating errors surface as global toasts. The previous
   .rl-bet-msg{ok,err,svg} rules lived here and have been deleted with
   the markup that referenced them. */

/* 26.6c — bet-box footer "players" pill: was an emoji + count, now a
   sized SVG user icon + emphasised count. Inline-flex keeps the icon
   aligned to the count's mono baseline. */
.rl-box-foot .rl-box-players {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.rl-box-foot .rl-box-players svg {
  opacity: .85;
}
.rl-box-foot .rl-box-players em {
  font-style: normal;
  font-family: var(--font-display);
  font-weight: 700;
}

/* 26.6c — phase bar collapses when the timer + progress bar are hidden
   (during locked + rolling phases). Center the label so the wheel
   feels like the indicator instead of a stale countdown. */
.rl-phase-bar.rl-phase-bar-spinning {
  justify-items: center;
  text-align: center;
}
.rl-phase-bar.rl-phase-bar-spinning .rl-phase-label {
  font-size: 14px;
  letter-spacing: .12em;
}

/* 26.6c — bettor-list rows: SVG diamond fallback when no rank icon
   available. Keep alignment consistent with the rank-icon size. */
.rl-box-list-name {
  display: inline-flex;
  align-items: center;
  /* Operator brief — same 4 px tightness as the desktop variant above. */
  gap: 4px;
}
.rl-box-list-name svg { opacity: .7; flex: 0 0 auto; }

/* === Server seed reveal === */
.rl-fair {
  padding: 10px 14px;
  background: rgba(0, 0, 0, .35);
  border: 1px dashed var(--line-soft);
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: 10px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.rl-fair-k { color: var(--text-mute); letter-spacing: .14em; }
.rl-fair-v { color: var(--accent); word-break: break-all; }

/* ==================================================================
   Old (Phase 26.6) Roulette CSS — superseded by .rl-game-v2 above.
   Kept for the same `.rl-fair` reuse + safe to delete later.
   ================================================================== */

.rl-game {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 760px;
  width: 100%;
  margin: 0 auto;
}

/* Phase indicator — strip across the top of the game showing current
   round phase + countdown. Color-codes the dot by phase. */
.rl-phase {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 20px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  color: var(--text);
  text-align: center;
}
.rl-phase-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 12px currentColor;
}
.rl-phase-dot-green { background: #4ee6a8; color: #4ee6a8; animation: rl-pulse 1.4s infinite; }
.rl-phase-dot-amber { background: var(--accent); color: var(--accent); }
.rl-phase-dot-red   { background: #F24D5C; color: #F24D5C; }
.rl-phase-dot-black { background: #2a2a2a; color: #888; }
@keyframes rl-pulse {
  0%   { transform: scale(1);   opacity: 1; }
  50%  { transform: scale(1.4); opacity: .55; }
  100% { transform: scale(1);   opacity: 1; }
}
.rl-phase-locked  { background: rgba(52, 192, 235, .08); }
.rl-phase-rolling { background: rgba(52, 192, 235, .14); }
.rl-phase-settled { background: rgba(78, 230, 168, .08); }

/* Wheel stripe — viewport with center pointer + horizontally-scrolling
   tile reel. Each tile is 64×64 px. */
.rl-stripe-wrap {
  position: relative;
  height: 80px;
  background: var(--bg-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.rl-pointer {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  pointer-events: none;
  filter: drop-shadow(0 4px 8px rgba(52, 192, 235, .55));
}
.rl-stripe-wrap::before,
.rl-stripe-wrap::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  width: 64px;
  z-index: 2;
  pointer-events: none;
}
.rl-stripe-wrap::before { left: 0;  background: linear-gradient(90deg, var(--bg-2), transparent); }
.rl-stripe-wrap::after  { right: 0; background: linear-gradient(-90deg, var(--bg-2), transparent); }
.rl-stripe {
  display: flex;
  height: 100%;
  align-items: center;
  padding: 8px 0;
  /* Initial transform set inline by JS during phases. */
  will-change: transform;
}
.rl-tile {
  flex: 0 0 64px;
  height: 64px;
  margin: 0 2px;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 800;
  color: #fff;
  border-radius: 6px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .55);
  position: relative;
}
.rl-tile-red    { background: linear-gradient(180deg, #ff4d65, #c12c41); }
.rl-tile-black  { background: linear-gradient(180deg, #2a2a2a, #131313); }
.rl-tile-green  { background: linear-gradient(180deg, #4ee6a8, #1a8557); color: #061712; }
.rl-tile.is-winner {
  outline: 3px solid var(--accent);
  outline-offset: -2px;
  box-shadow: 0 0 24px rgba(52, 192, 235, .55);
}

/* Last-rounds history pip strip */
.rl-history {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  padding: 0 4px;
}
.rl-history-label {
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: .14em;
  color: var(--text-mute);
  margin-right: 4px;
}
.rl-history-pip {
  width: 14px; height: 14px;
  border-radius: 4px;
  display: inline-block;
}
.rl-history-pip-red    { background: #ff4d65; }
.rl-history-pip-black  { background: #2a2a2a; }
.rl-history-pip-green  { background: #4ee6a8; }

/* Bet form */
.rl-bet-form {
  padding: 18px 20px 22px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.rl-bet-colors {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
}
.rl-color-btn {
  appearance: none;
  border: 2px solid transparent;
  cursor: pointer;
  padding: 14px 12px;
  border-radius: var(--radius-sm);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  transition: transform .12s, border-color .15s, box-shadow .15s;
  color: #fff;
  font-family: var(--font-display); font-weight: 800;
}
.rl-color-btn:hover { transform: translateY(-1px); }
.rl-color-btn.on { border-color: var(--accent); box-shadow: 0 0 18px rgba(52, 192, 235, .35); }
.rl-color-btn-red    { background: linear-gradient(180deg, #ff4d65, #b8233b); }
.rl-color-btn-black  { background: linear-gradient(180deg, #333, #0a0a0a); }
.rl-color-btn-green  { background: linear-gradient(180deg, #4ee6a8, #1a8557); color: #061712; }
.rl-color-name {
  font-size: 13px;
  letter-spacing: .14em;
  font-weight: 800;
}
.rl-color-mult {
  font-size: 11px;
  letter-spacing: .08em;
  opacity: .85;
}

.rl-bet-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.rl-bet-amount label,
.rl-bet-payout label {
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: .14em;
  color: var(--text-mute);
  text-transform: uppercase;
  display: block;
  margin-bottom: 4px;
}
.rl-bet-amount input {
  width: 100%;
  background: rgba(255, 255, 255, .04);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-xs);
  padding: 10px 12px;
  color: var(--text);
  font: inherit;
  font-size: 14px;
  outline: none;
}
.rl-bet-amount input:focus { border-color: var(--accent); }
.rl-bet-payout-v {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  color: var(--accent);
  padding: 10px 12px;
  background: rgba(52, 192, 235, .06);
  border: 1px solid rgba(52, 192, 235, .25);
  border-radius: var(--radius-xs);
}

/* 26.6c — duplicate .rl-bet-msg block from a previous roulette
   layout has been removed; the v2 rule (defined ~290 lines above
   with the SVG-aligning flex layout) is now the single source of
   truth. */

.rl-place-btn {
  padding: 14px 20px;
  font-size: 14px;
  letter-spacing: .08em;
  width: 100%;
  justify-content: center;
}

/* Live bet feed */
.rl-feed {
  padding: 14px 16px;
}
.rl-feed-head {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .14em;
  color: var(--text-mute);
  margin-bottom: 8px;
}
.rl-feed-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 180px;
  overflow-y: auto;
}
.rl-feed-row {
  display: flex;
  justify-content: space-between;
  padding: 6px 10px;
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: 11px;
  background: rgba(255, 255, 255, .025);
}
.rl-feed-row-red    .rl-feed-color { color: #ff4d65; font-weight: 700; }
.rl-feed-row-black  .rl-feed-color { color: #888;    font-weight: 700; }
.rl-feed-row-green  .rl-feed-color { color: #4ee6a8; font-weight: 700; }

/* Server seed reveal block */
.rl-fair {
  padding: 10px 14px;
  background: rgba(0, 0, 0, .35);
  border: 1px dashed var(--line-soft);
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: 10px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.rl-fair-k { color: var(--text-mute); letter-spacing: .14em; }
.rl-fair-v { color: var(--accent); word-break: break-all; }

/* ==================================================================
   Wager Race page — coat-of-arms identity rebuild.

   Identity vocab pulled from the site's real design system:
   - var(--font-display) (Sora) for titles + podium ranks
   - var(--font-mono) (JetBrains Mono) for every numeric — prize
     amounts, countdown, ranks, wagered totals
   - var(--font-ui) (Inter) only for body copy / blurb
   - .frame.chamfer for hero + sections — gold-hairline gradient
     border + clipped corners (the site's signature spotlight shape)
   - kicker labels (uppercase Sora 11px / .14em letterspacing)
   ================================================================== */

.wr2-page {
  padding: 24px clamp(14px, 2.4vw, 32px);
  max-width: 1180px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 24px;
  color: var(--text);
}

/* Typography helpers reused across the page. */
.wr2-kicker {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-mute);
}
.wr2-mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  font-weight: 700;
  letter-spacing: -.005em;
}
.wr2-accent { color: var(--accent); }
.wr2-muted  { color: var(--text-mute); font-style: italic; }

/* --- Back row + breadcrumb ---------------------------------------- */
.wr2-back-row {
  display: flex;
  align-items: center;
  gap: 14px;
}
.wr2-back-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--line-soft);
  background: rgba(255, 255, 255, .03);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
  border-radius: var(--radius-xs, 6px);
  cursor: pointer;
  transition: background var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard);
}
.wr2-back-btn:hover {
  background: rgba(255, 255, 255, .07);
  border-color: rgba(52, 192, 235, .35);
}
.wr2-breadcrumb {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-mute);
}

/* --- Hero card (uses .frame.chamfer.chamfer-lg from the JSX) ------ */
.wr2-hero {
  position: relative;
  display: grid;
  /* Body wide on the LEFT, emblem fixed on the RIGHT — previous
     rebuild had this inverted which caused tile overflow. */
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 36px;
  align-items: center;
  padding: clamp(28px, 4vw, 44px) clamp(28px, 4vw, 52px);
  background:
    radial-gradient(120% 80% at 100% 0%, rgba(52, 192, 235, .08) 0%, transparent 55%),
    radial-gradient(70% 60% at 0% 100%, rgba(52, 192, 235, .04) 0%, transparent 60%),
    var(--panel, rgba(0, 0, 0, .35));
  overflow: hidden;
}

.wr2-hero-body {
  display: flex;
  flex-direction: column;
  gap: 18px;
  min-width: 0;
}

.wr2-hero-tag {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.wr2-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 8px;
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-mute);
  background: rgba(255, 255, 255, .04);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-pill, 999px);
}
.wr2-status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-mute);
}
.wr2-status.is-live {
  color: #6BD49B;
  border-color: rgba(107, 212, 155, .35);
  background: rgba(107, 212, 155, .08);
}
.wr2-status.is-live .wr2-status-dot {
  background: #6BD49B;
  box-shadow: 0 0 0 3px rgba(107, 212, 155, .18);
}
.wr2-status.is-soon {
  color: var(--accent);
  border-color: rgba(52, 192, 235, .35);
  background: rgba(52, 192, 235, .08);
}
.wr2-status.is-soon .wr2-status-dot { background: var(--accent); }

.wr2-hero-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(28px, 3.4vw, 40px);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -.01em;
  color: var(--text);
}
.wr2-hero-blurb {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
  line-height: 1.55;
  color: var(--text-mute);
  max-width: 56ch;
}

/* Single horizontal strip — replaces the two stacked grids that
   were overflowing the body column. */
.wr2-hero-strip {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) auto minmax(0, 1.4fr) auto minmax(0, .9fr) auto minmax(0, .9fr);
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  background: rgba(0, 0, 0, .28);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm, 8px);
}
.wr2-strip-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.wr2-strip-k {
  font-size: 9px;
  letter-spacing: .14em;
}
.wr2-strip-v {
  font-size: 18px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wr2-strip-pool .wr2-strip-v { font-size: 22px; }
.wr2-strip-divider {
  width: 1px;
  height: 32px;
  background: linear-gradient(180deg, transparent 0%, var(--line-soft) 50%, transparent 100%);
  justify-self: center;
}

/* "Your rank" callout — sits between hero strip and CTA. */
.wr2-hero-mine {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 14px 18px;
  background:
    linear-gradient(90deg, rgba(52, 192, 235, .10) 0%, rgba(52, 192, 235, 0) 60%),
    rgba(0, 0, 0, .25);
  border: 1px solid rgba(52, 192, 235, .28);
  border-radius: var(--radius-sm, 8px);
  flex-wrap: wrap;
}
.wr2-mine-badge {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-right: 18px;
  border-right: 1px solid rgba(52, 192, 235, .22);
}
.wr2-mine-rank {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 800;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.wr2-mine-stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.wr2-mine-stat .wr2-mono {
  font-size: 16px;
  color: var(--text);
}
.wr2-mine-stat-v {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-mute);
}
.wr2-hero-mine--empty {
  flex-direction: row;
  align-items: center;
  gap: 12px;
}

.wr2-hero-cta { margin-top: 4px; }

.wr2-btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 24px;
  background: var(--accent);
  color: var(--accent-ink, #1A1A1A);
  border: 0;
  border-radius: var(--radius-xs, 6px);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: filter var(--dur-base) var(--ease-standard),
              transform var(--dur-base) var(--ease-standard);
}
.wr2-btn-primary:hover { filter: brightness(1.08); }
.wr2-btn-primary:active { transform: translateY(1px); }
.wr2-btn-sm {
  padding: 9px 16px;
  font-size: 11px;
  letter-spacing: .08em;
}

/* Hero emblem column — fixed-width on right. */
.wr2-hero-art {
  align-self: center;
  justify-self: end;
  display: flex;
  align-items: center;
  justify-content: center;
  filter: drop-shadow(0 18px 24px rgba(0, 0, 0, .45));
}

/* --- Section frames (use .frame.chamfer when applied at JSX) ----- */
.wr2-section {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: clamp(20px, 2.6vw, 30px);
  background: rgba(0, 0, 0, .28);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md, 10px);
}
.wr2-section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
}
.wr2-section-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -.005em;
  color: var(--text);
}
.wr2-section-sub {
  margin: 6px 0 0;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-mute);
}

/* --- Podium row --------------------------------------------------- */
.wr2-podium-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  align-items: end;
}
.wr2-podium {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 22px 16px;
  background: rgba(255, 255, 255, .03);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm, 8px);
  text-align: center;
  min-width: 0;
}
.wr2-podium-1 {
  background:
    linear-gradient(180deg, rgba(52, 192, 235, .14) 0%, rgba(52, 192, 235, 0) 60%),
    rgba(255, 255, 255, .03);
  border-color: rgba(52, 192, 235, .42);
  padding: 28px 18px;
  transform: translateY(-12px);
  box-shadow: 0 12px 28px rgba(0, 0, 0, .35);
}
.wr2-podium-2 {
  background:
    linear-gradient(180deg, rgba(210, 215, 223, .10) 0%, rgba(210, 215, 223, 0) 60%),
    rgba(255, 255, 255, .03);
  border-color: rgba(210, 215, 223, .28);
}
.wr2-podium-3 {
  background:
    linear-gradient(180deg, rgba(203, 138, 91, .10) 0%, rgba(203, 138, 91, 0) 60%),
    rgba(255, 255, 255, .03);
  border-color: rgba(203, 138, 91, .28);
}
.wr2-podium.is-me { border-color: rgba(52, 192, 235, .60); }
.wr2-podium-medal {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 4px;
}
.wr2-podium-name {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.wr2-podium-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  width: 100%;
  margin-top: 6px;
  padding-top: 14px;
  border-top: 1px solid var(--line-soft);
}
.wr2-podium-stats > div {
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: center;
}
.wr2-stat-k {
  font-family: var(--font-display);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-mute);
}
.wr2-stat-v {
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wr2-you {
  position: absolute;
  top: 8px;
  right: 8px;
  padding: 3px 8px;
  font-family: var(--font-display);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .16em;
  color: var(--accent-ink, #1A1A1A);
  background: var(--accent);
  border-radius: var(--radius-pill, 999px);
}

/* --- Prize breakdown grid ----------------------------------------- */
.wr2-prize-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 12px;
}
.wr2-prize-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px;
  background: rgba(255, 255, 255, .025);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm, 8px);
  transition: border-color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard),
              transform var(--dur-base) var(--ease-standard);
}
.wr2-prize-card:hover {
  background: rgba(255, 255, 255, .04);
  border-color: rgba(52, 192, 235, .25);
  transform: translateY(-2px);
}
.wr2-prize-card.is-top {
  background:
    linear-gradient(180deg, rgba(52, 192, 235, .08) 0%, rgba(52, 192, 235, 0) 60%),
    rgba(255, 255, 255, .03);
  border-color: rgba(52, 192, 235, .28);
}
.wr2-prize-card.is-me { border-color: rgba(52, 192, 235, .60); }
.wr2-prize-pos {
  display: flex;
  align-items: center;
  height: 36px;
}
.wr2-prize-pos-num {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 800;
  letter-spacing: .04em;
  color: var(--text-mute);
}
.wr2-prize-amt {
  font-family: var(--font-mono);
  font-size: 22px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
  color: var(--accent);
}
.wr2-prize-pct {
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  color: var(--text-mute);
  text-transform: uppercase;
}
.wr2-prize-claim {
  margin-top: 4px;
  padding-top: 10px;
  border-top: 1px solid var(--line-soft);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 500;
  color: var(--text-mute);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wr2-prize-claim strong {
  color: var(--text);
  font-weight: 700;
  font-family: var(--font-display);
  letter-spacing: .01em;
}

/* --- Viewer strip (rank > 3) -------------------------------------- */
.wr2-viewer-strip {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 18px;
  padding: 18px 22px;
  background:
    linear-gradient(90deg, rgba(52, 192, 235, .10) 0%, rgba(52, 192, 235, 0) 60%),
    rgba(0, 0, 0, .30);
  border: 1px solid rgba(52, 192, 235, .30);
  border-radius: var(--radius-md, 10px);
}
.wr2-viewer-rank {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  min-width: 64px;
  text-align: center;
  padding: 8px 12px;
  background: rgba(0, 0, 0, .35);
  border: 1px solid rgba(52, 192, 235, .22);
  border-radius: var(--radius-xs, 6px);
}
.wr2-viewer-body { min-width: 0; }
.wr2-viewer-k {
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-mute);
}
.wr2-viewer-v {
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
}

/* --- Full leaderboard table --------------------------------------- */
.wr2-table {
  display: flex;
  flex-direction: column;
  background: rgba(0, 0, 0, .22);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm, 8px);
  overflow: hidden;
}
.wr2-table-head,
.wr2-table-row {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) 140px 140px;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
}
.wr2-table-head {
  background: rgba(255, 255, 255, .025);
  border-bottom: 1px solid var(--line-soft);
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-mute);
}
.wr2-table-row {
  border-bottom: 1px solid rgba(255, 255, 255, .04);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  transition: background var(--dur-base) var(--ease-standard);
}
.wr2-table-row:last-child { border-bottom: 0; }
.wr2-table-row:hover { background: rgba(255, 255, 255, .025); }
.wr2-table-row.is-me {
  background: rgba(52, 192, 235, .07);
  border-color: rgba(52, 192, 235, .22);
}
.wr2-table-row.is-me:hover { background: rgba(52, 192, 235, .10); }
.wr2-table-rank {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--text-mute);
}
.wr2-table-row.is-me .wr2-table-rank { color: var(--accent); }
.wr2-table-player {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: .005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.wr2-table-wagered,
.wr2-table-prize {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  text-align: right;
}
.wr2-table-prize { color: var(--accent); }
.wr2-table-head > div:nth-child(3),
.wr2-table-head > div:nth-child(4) { text-align: right; }

/* --- Countdown tiles ---------------------------------------------- */
.wr2-countdown {
  display: flex;
  align-items: center;
  gap: 6px;
}
.wr2-cd-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 38px;
  padding: 4px 8px;
  background: rgba(0, 0, 0, .35);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-xs, 6px);
}
.wr2-cd-v {
  font-family: var(--font-mono);
  font-size: 17px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
  color: var(--text);
}
.wr2-cd-k {
  font-family: var(--font-display);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-mute);
}
.wr2-countdown.is-dense .wr2-cd-v { color: var(--accent); }

/* --- Podium row (top 3) ------------------------------------------- */
/* Three card tiles for ranks 1/2/3, accent-colored per rank. The tiles
   share the .card primitive used across the player surface (rewards,
   affiliate, etc.) so the wager-race page reads as part of the same
   design family. */
.wr2-podium.stack {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin: 24px 0;
}
.wr2-podium-card {
  position: relative;
  display: grid;
  grid-template-rows: auto auto auto auto;
  gap: 8px;
  padding: 20px 18px;
  border-left: 4px solid var(--accent);
  overflow: hidden;
}
.wr2-podium-card.is-empty { opacity: 0.45; border-style: dashed; }
.wr2-podium-1 { border-left-color: #f6c84a; box-shadow: inset 0 0 0 1px rgba(246,200,74,.18); }
.wr2-podium-2 { border-left-color: #c7c9d4; box-shadow: inset 0 0 0 1px rgba(199,201,212,.16); }
.wr2-podium-3 { border-left-color: #d18b5a; box-shadow: inset 0 0 0 1px rgba(209,139,90,.16); }
.wr2-podium-card::after {
  content: '';
  position: absolute;
  inset: auto -30% -40% auto;
  width: 180px; height: 180px;
  background: radial-gradient(circle at center, var(--accent-glow, rgba(246,200,74,.18)), transparent 65%);
  pointer-events: none;
}
.wr2-podium-1::after { background: radial-gradient(circle at center, rgba(246,200,74,.22), transparent 65%); }
.wr2-podium-2::after { background: radial-gradient(circle at center, rgba(199,201,212,.18), transparent 65%); }
.wr2-podium-3::after { background: radial-gradient(circle at center, rgba(209,139,90,.18), transparent 65%); }
.wr2-podium-rank {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 900;
  color: var(--text);
  line-height: 1;
  letter-spacing: -.01em;
}
.wr2-podium-user {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text);
  min-width: 0;
}
.wr2-podium-user span {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  flex: 1;
}
.wr2-podium-points {
  font-family: var(--font-mono, var(--font-display));
  font-weight: 700;
  font-size: 18px;
  color: var(--accent);
}
.wr2-podium-points span {
  color: var(--text-mute);
  font-size: 11px; font-weight: 400;
  margin-left: 4px;
  text-transform: uppercase;
  letter-spacing: .1em;
}
.wr2-podium-prize {
  font-size: 14px;
  color: var(--text);
  font-weight: 700;
  padding-top: 8px;
  border-top: 1px solid var(--line-soft);
}
@media (max-width: 720px) {
  .wr2-podium.stack { grid-template-columns: 1fr; }
}

/* --- Standings wrapper card ---------------------------------------- */
.wr2-standings-card {
  padding: 0;
  overflow: hidden;
}
.wr2-standings-card .lb2-table { margin: 0; }

/* --- Empty / error states ----------------------------------------- */
.wr2-empty {
  padding: 32px 24px;
  text-align: center;
  font-family: var(--font-ui);
  color: var(--text-mute);
  font-size: 14px;
  background: rgba(0, 0, 0, .22);
  border: 1px dashed var(--line-soft);
  border-radius: var(--radius-md, 10px);
}
.wr2-empty-err {
  color: #E07A7A;
  border-color: rgba(224, 122, 122, .35);
  background: rgba(224, 122, 122, .06);
}

/* --- Responsive --------------------------------------------------- */
@media (max-width: 980px) {
  .wr2-hero {
    grid-template-columns: 1fr;
    gap: 24px;
    text-align: left;
  }
  .wr2-hero-art {
    order: -1;
    justify-self: center;
  }
  .wr2-hero-art svg { width: 220px; height: 220px; }
  .wr2-hero-strip {
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    grid-template-areas:
      "pool divider1 time"
      "players divider2 winners";
    row-gap: 14px;
  }
  .wr2-hero-strip .wr2-strip-divider:nth-of-type(2) { display: none; }
  .wr2-hero-strip .wr2-strip-divider:nth-of-type(4) { grid-area: divider2; }
}
@media (max-width: 720px) {
  .wr2-podium-row { grid-template-columns: 1fr; }
  .wr2-podium-1 { transform: none; }
  .wr2-table-head,
  .wr2-table-row {
    grid-template-columns: 48px minmax(0, 1fr) 110px;
    padding: 12px 14px;
  }
  .wr2-table-head > div:nth-child(4),
  .wr2-table-row .wr2-table-prize { display: none; }
  .wr2-hero-mine {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
  .wr2-mine-badge {
    border-right: 0;
    padding-right: 0;
    padding-bottom: 12px;
    border-bottom: 1px solid rgba(52, 192, 235, .22);
    width: 100%;
  }
}
@media (max-width: 540px) {
  .wr2-hero-strip {
    grid-template-columns: 1fr;
    grid-template-areas: none;
    row-gap: 12px;
  }
  .wr2-hero-strip .wr2-strip-divider { display: none; }
  .wr2-viewer-strip {
    grid-template-columns: auto 1fr;
    row-gap: 10px;
  }
  .wr2-viewer-strip .wr2-btn-primary {
    grid-column: 1 / -1;
    justify-self: stretch;
  }
}

/* ==================================================================
   Live-stats widget — race accordion meta row
   ================================================================== */
.lsw-race-meta {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  padding: 10px;
  background: rgba(0, 0, 0, .25);
  border: 1px solid rgba(255, 255, 255, .04);
  border-radius: 6px;
  margin-bottom: 10px;
}
.lsw-race-meta-cell { text-align: center; min-width: 0; }
.lsw-race-meta-k {
  font-family: var(--font-display);
  font-size: 8px;
  letter-spacing: .14em;
  color: var(--text-mute);
  text-transform: uppercase;
  margin-bottom: 3px;
}
.lsw-race-meta-v {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.lsw-race-meta-v.accent { color: var(--accent); }

/* ==================================================================
   Phase 26.7b — Profile inline stats cards.
   ================================================================== */
.profile-stats-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}
@media (max-width: 720px) {
  .profile-stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 420px) {
  .profile-stats-grid { grid-template-columns: 1fr; }
}
.profile-stat-card {
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: border-color .15s, transform .12s;
}
.profile-stat-card:hover {
  border-color: var(--white-08);
  transform: translateY(-1px);
}
.profile-stat-card .profile-stat-k {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .12em;
  color: var(--text-mute);
  text-transform: uppercase;
}
.profile-stat-card .profile-stat-v {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--text);
}
.profile-stat-card .profile-stat-v.up   { color: #4ee6a8; }
.profile-stat-card .profile-stat-v.down { color: #ff6b8a; }

/* ==================================================================
   Phase 26.7a — Sports → Coming Soon placeholder.
   ================================================================== */
.sports-coming-soon {
  min-height: calc(100dvh - 200px);
  display: grid;
  place-items: center;
  padding: 40px 20px;
}
.sports-coming-soon-card {
  max-width: 520px;
  text-align: center;
  padding: 48px 32px;
  background:
    radial-gradient(70% 80% at 30% 30%, rgba(52, 192, 235, .12), transparent 60%),
    radial-gradient(70% 80% at 70% 70%, rgba(46, 200, 200, .10), transparent 60%),
    var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg, 14px);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .35);
}
.sports-coming-soon-card .kicker { color: var(--accent); }
.sports-coming-soon-card h1 {
  font-family: var(--font-display);
  font-size: clamp(36px, 6vw, 64px);
  letter-spacing: -.02em;
  margin: 12px 0 14px;
  text-transform: uppercase;
  line-height: .95;
}
.sports-coming-soon-card h1 em {
  font-style: normal;
  color: var(--accent);
}
.sports-coming-soon-card p {
  font-size: 14px;
  color: var(--text-dim);
  line-height: 1.55;
  margin: 0 0 22px;
}

/* ==================================================================
   Phase 26.4c — Full Providers page (paginated grid).
   ================================================================== */

.providers-page {
  padding: 24px clamp(12px, 2vw, 24px);
  max-width: 1280px;
  margin: 0 auto;
}
.providers-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 18px;
  margin-bottom: 24px;
}
.providers-header h1 {
  font-family: var(--font-display);
  font-size: clamp(28px, 3.4vw, 42px);
  margin: 6px 0 0;
  letter-spacing: -.01em;
  text-transform: uppercase;
}
.providers-header h1 em {
  font-style: normal;
  color: var(--accent);
}
.providers-search {
  flex: 0 0 auto;
  max-width: 280px;
}
.providers-search input {
  width: 100%;
  background: rgba(255, 255, 255, .04);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  outline: none;
}
.providers-search input:focus { border-color: var(--accent); }

.providers-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}
@media (max-width: 900px) { .providers-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 640px) { .providers-grid { grid-template-columns: repeat(2, 1fr); } }

.provider-grid-tile {
  appearance: none;
  border: 1px solid var(--line-soft);
  background: var(--panel);
  border-radius: var(--radius);
  padding: 22px 16px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 110px;
  text-align: center;
  transition: transform .12s, border-color .15s, background .15s;
}
.provider-grid-tile:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
  background: rgba(52, 192, 235, .04);
}
.provider-grid-wordmark {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: .04em;
  color: var(--text);
}
.provider-grid-count {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .08em;
  color: var(--text-mute);
  text-transform: uppercase;
}

.providers-pagination {
  margin-top: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
}
.providers-pagination .pagination-btn {
  appearance: none;
  border: 1px solid var(--line-soft);
  background: var(--panel);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: .06em;
  padding: 9px 18px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.providers-pagination .pagination-btn:hover:not(:disabled) {
  border-color: var(--accent);
  background: rgba(52, 192, 235, .06);
}
.providers-pagination .pagination-btn:disabled {
  opacity: .35;
  cursor: not-allowed;
}
.providers-pagination .pagination-status {
  font-family: var(--font-display);
  font-size: 12px;
  color: var(--text-dim);
  letter-spacing: .04em;
}

/* Chat-input emoji button (operator rebuild — replaces the old
   chat-support-btn). Sits between message input and send button.
   Ghost styling so it doesn't compete with the gold send button. */
.chat-emoji-wrap { position: relative; display: inline-flex; }
.chat-emoji-btn {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border: 1px solid var(--border-default);
  background: var(--white-04);
  border-radius: var(--radius-sm);
  font-size: 18px; line-height: 1;
  cursor: pointer;
  transition: border-color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard);
}
.chat-emoji-btn:hover {
  border-color: var(--accent-40);
  background: var(--accent-soft);
}
.chat-emoji-btn:disabled { opacity: .5; cursor: not-allowed; }
.chat-emoji-btn[aria-expanded="true"] {
  border-color: var(--accent);
  background: var(--accent-soft);
}

/* Emoji popover — anchored above the button (chat input lives at the
   bottom of the right panel, so the popover opens upward). 8-column
   grid; 32 emojis = 4 rows. Closes on outside click / Esc (handled in
   ChatEmojiButton). */
.chat-emoji-pop {
  position: absolute;
  bottom: calc(100% + 8px);
  right: 0;
  z-index: var(--z-dropdown);
  width: 264px;
  padding: 8px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 2px;
  animation: chat-emoji-pop-in var(--dur-base) var(--ease-entrance);
}
@keyframes chat-emoji-pop-in {
  from { opacity: 0; transform: translateY(6px) scale(.96); }
  to   { opacity: 1; transform: none; }
}
.chat-emoji-cell {
  appearance: none; border: 0; background: transparent;
  width: 28px; height: 28px;
  font-size: 18px; line-height: 1;
  cursor: pointer;
  border-radius: var(--radius-sm);
  display: grid; place-items: center;
  transition: background var(--dur-fast) var(--ease-standard);
}
.chat-emoji-cell:hover, .chat-emoji-cell:focus-visible {
  background: var(--accent-soft);
  outline: none;
}



/* ================== TASK 35 — IN-GAME LIVE SEARCH ================== */
/* A compact typeahead that lives directly under the game title strip on
   every game page (slot detail + originals). Matches the visual weight
   of .sd-title-strip / .sd-prov-pill so the two rows feel like one unit. */
/* Operator rebuild — collapsible search. Default is a compact icon
   button (44 px circle). Click expands it smoothly to a full input
   with the search icon staying anchored on the left. Click-away or
   Esc collapses. */
.ig-search-wrap {
  position: relative;
  margin: 8px 0 14px;
  max-width: 520px;
  /* Width + alignment animate on the wrapper so the dropdown stays
     correctly anchored regardless of state. */
  width: 100%;
  display: flex;
}
/* Operator feedback — wrap was 44px wide while the inner pill is
   36×36, so a `display:flex` wrap with no justify shoved the icon
   to the left edge of its box. Match the wrap width to the inner
   pill (or center the inner) so the magnifier sits dead-centre. */
.ig-search-wrap.is-collapsed {
  width: 36px;
  justify-content: center;
}
.ig-search-wrap.ig-search-inline.is-collapsed {
  width: 32px;
  justify-content: center;
}
.ig-search-wrap.is-expanded {
  width: 100%;
}
.ig-search {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
  transition: border-color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard),
              box-shadow var(--dur-base) var(--ease-standard),
              padding var(--dur-base) var(--ease-emphasized),
              border-radius var(--dur-base) var(--ease-emphasized);
  cursor: text;
}
.ig-search-wrap.is-collapsed .ig-search {
  /* Operator feedback — collapsed mode is now a clean centred icon
     button. The previous rule kept gap:10px which pushed the SVG to
     one side because the still-rendered (zero-width) input ate the
     residual space. Forcing gap:0 + padding:0 + grid centring locks
     the magnifier to the geometric centre of the disc.
     `overflow:hidden` is critical — without it, the input's
     placeholder text bleeds past the 36 px disc and shows next to
     the icon (visible on mobile narrow widths). */
  padding: 0;
  width: 36px; height: 36px;
  gap: 0;
  cursor: pointer;
  border-radius: 50%;
  display: grid;
  place-items: center;
  overflow: hidden;
}
.ig-search-wrap.is-collapsed .ig-search:hover {
  background: var(--bg-3);
  border-color: var(--accent-40);
  color: var(--accent);
}
.ig-search-wrap.is-expanded .ig-search {
  padding: 12px 14px;
  border-radius: var(--radius);
}
.ig-search:hover { border-color: var(--accent-40); }
/* Operator feedback — removed the 4px accent-soft halo on focus.
   The brighter border + bg shift is enough; the halo read as a
   "weird glow" overlay. */
.ig-search:focus-within {
  border-color: var(--border-default);
  background: var(--bg-2);
}
.ig-search > svg {
  color: var(--text-tertiary);
  flex-shrink: 0;
  transition: color var(--dur-base) var(--ease-standard);
}
.ig-search:focus-within > svg { color: var(--text-tertiary); }
.ig-search-wrap.is-collapsed .ig-search > svg {
  color: var(--text-secondary);
}
.ig-search-wrap.is-collapsed .ig-search:hover > svg { color: var(--accent); }
.ig-search input {
  flex: 1; min-width: 0;
  appearance: none; background: transparent; border: 0; outline: 0;
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0;
  /* Hide the input completely when collapsed. */
  transition: opacity var(--dur-fast) var(--ease-standard);
}
.ig-search-wrap.is-collapsed .ig-search input {
  width: 0; padding: 0; opacity: 0; pointer-events: none;
}

/* Inline variant — slimmer, anchored next to the rail title. The
   .sec-head-inline-search modifier on the parent wraps the search
   inside .sec-tools so it lives next to View-all + arrow buttons. */
.sec-head-inline-search .sec-tools {
  display: flex; align-items: center;
  gap: var(--space-3);
}
.ig-search-wrap.ig-search-inline {
  margin: 0;
  flex-shrink: 0;
}
.ig-search-wrap.ig-search-inline.is-collapsed { width: 32px; }
.ig-search-wrap.ig-search-inline.is-collapsed .ig-search {
  width: 32px; height: 32px;
  border: 1px solid var(--border-default);
  background: var(--bg-2);
  /* Centre the icon with flex (not grid) so the still-rendered but
     visually-collapsed <input> doesn't claim a second grid row and
     push the magnifier off-centre. position:relative so the input
     can be absolutely-pinned out of flow. */
  display: flex; align-items: center; justify-content: center;
  gap: 0; padding: 0;
  position: relative;
  overflow: hidden;
  border-radius: 50%;
}
.ig-search-wrap.ig-search-inline.is-collapsed .ig-search input {
  position: absolute;
  inset: 0;
}

/* Operator feedback — kill the global :focus-visible amber halo on
   the in-game search. The container's own border + background
   already telegraph focus; the extra 4px accent-soft glow read as
   the "yellow glow" the client wanted gone. Applies to:
     • the wrapper div when it acts as the collapsed icon button
       (role="button" + tabindex=0 → matched by the global selector)
     • the inner <input> element when expanded + focused
   We re-state the brand-amber border on focus so keyboard users
   still get a clear focus state without the halo. */
.ig-search-wrap:focus-visible,
.ig-search-wrap [role="button"]:focus-visible,
.ig-search input:focus-visible {
  outline: none;
  box-shadow: none;
}
.ig-search:focus-within {
  border-color: var(--border-default);
  background: var(--bg-2);
  box-shadow: none;
}
.ig-search-wrap.ig-search-inline.is-expanded { width: 240px; }
.ig-search-wrap.ig-search-inline.is-expanded .ig-search {
  padding: 6px 10px 6px 12px;
  height: 32px;
  border-radius: 8px;
}
.ig-search-wrap.ig-search-inline .ig-search input {
  font-size: 13px;
}
.ig-search-wrap.ig-search-inline .ig-search-pop {
  /* Anchor the dropdown to the right edge so it doesn't blow off
     the rail header on narrow widths. */
  left: auto; right: 0;
  min-width: 280px;
}
@media (max-width: 540px) {
  .ig-search-wrap.ig-search-inline.is-expanded { width: 200px; }
}
.ig-search input::placeholder { color: var(--text-mute); }
.ig-search-clear {
  appearance: none; cursor: pointer;
  background: transparent; border: 0;
  color: var(--text-mute);
  font-size: 18px; line-height: 1;
  padding: 0 2px;
}
.ig-search-clear:hover { color: var(--text); }

.ig-search-pop {
  position: absolute;
  top: calc(100% + 8px); left: 0; right: 0;
  z-index: 60;
  max-height: 360px; overflow-y: auto;
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--bg-2) 92%, #fff 8%) 0%,
      var(--bg-1) 100%);
  border: 1px solid color-mix(in srgb, var(--border-default) 80%, transparent 20%);
  border-radius: var(--radius-lg, 12px);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .04) inset,
    0 18px 44px -18px rgba(0, 0, 0, .65),
    0 4px 10px rgba(0, 0, 0, .35);
  padding: 6px;
}
.ig-search-empty {
  padding: 14px;
  text-align: center;
  color: var(--text-mute);
  font-family: var(--font-display);
  font-size: 12px; letter-spacing: .04em;
}
/* Section header for the empty-state panel ("Recently played" /
   "Popular now"). Visually subordinate to the rows so the eye still
   lands on the game cards first. */
.ig-search-section {
  padding: 8px 10px 4px;
  color: var(--text-mute);
  font-family: var(--font-display);
  font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase;
}
.ig-search-section + .ig-search-section,
.ig-search-row + .ig-search-section {
  margin-top: 4px;
  border-top: 1px solid color-mix(in srgb, var(--border-default) 50%, transparent 50%);
  padding-top: 8px;
}
.ig-search-row {
  display: flex; align-items: center; gap: 10px; width: 100%;
  appearance: none; cursor: pointer;
  background: transparent; border: 0;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  text-align: left;
  color: var(--text);
  transition: background .12s;
}
.ig-search-row:hover,
.ig-search-row.on { background: rgba(255,255,255,.06); }
.ig-search-thumb {
  flex: 0 0 auto;
  width: 36px; height: 36px;
  border-radius: var(--radius-xs);
  background: linear-gradient(135deg, rgba(52,192,235,.20), rgba(61, 126, 255,.18));
  background-size: cover; background-position: center;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--accent);
  font-family: var(--font-display);
  font-size: 14px;
  border: 1px solid var(--line-soft);
}
.ig-search-meta {
  display: flex; flex-direction: column;
  min-width: 0; flex: 1;
}
.ig-search-name {
  font-family: var(--font-sans);
  font-size: 13px; font-weight: 600;
  color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ig-search-prov {
  font-family: var(--font-display);
  font-size: 10px; letter-spacing: .06em;
  color: var(--text-mute);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ig-search-tag {
  flex-shrink: 0;
  padding: 2px 6px;
  border-radius: var(--radius-xs);
  background: rgba(52,192,235,.14);
  color: var(--accent);
  font-family: var(--font-display);
  font-size: 9px; font-weight: 700;
  letter-spacing: .08em;
}

/* Originals title strip — re-uses .sd-title-strip layout but adds its own
   class so we can tune spacing / margins later without touching slots. */
/* Operator rebuild — match the slot-detail page's title-strip margins
   exactly so the trophy/RTP pills sit at the same vertical position
   on originals as they do on slots. Was 0/0/8 → now 20/0/4 (mirror
   of .sd-title-strip). */
.ig-title-strip {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-7); flex-wrap: wrap;
  margin: 20px 0 4px;
}

@media (max-width: 600px) {
  .ig-search-wrap { max-width: 100%; }
  .ig-search-pop { max-height: 300px; }
}

/* =============================================================
   ============== OPERATOR REBUILD — PLAYER MODAL ==============
   Matches the operator's reference screenshot 1:1 — three rounded
   cards on a dark surface: identity, tabs, stats grid. Gold reserved
   for the Tip CTA + the rank icon hex glyph; everything else is
   neutral grey. */

.pm-v2 {
  display: flex;
  flex-direction: column;
  /* Operator follow-up — popup felt roomy / over-spaced. Tighten the
     outer gap + padding so identity card, tabs, and stats sit closer
     and the modal reads as a denser bet receipt vs a settings page. */
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5) var(--space-5);
}

.pm-v2-head {
  display: flex; align-items: center; justify-content: space-between;
  padding-bottom: var(--space-3);
}
.pm-v2-head-title {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-display);
  font-size: 14px; font-weight: 700;
  letter-spacing: .06em;
  color: var(--text-primary);
}
.pm-v2-close {
  appearance: none; cursor: pointer;
  width: 28px; height: 28px;
  border: 0; border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-secondary);
  display: grid; place-items: center;
  font-size: 18px; line-height: 1;
  transition: color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard),
              transform var(--dur-fast) var(--ease-standard);
}
.pm-v2-close:hover {
  color: var(--accent);
  background: var(--accent-soft);
  transform: rotate(90deg);
}

/* Card surface — used by identity + tabs + stats */
.pm-v2-card {
  /* Tighter padding (was --space-6 = 14px) so card content hugs the
     edges; mod-actions row + meta row still breathe but the overall
     popup is materially shorter. */
  padding: var(--space-4) var(--space-5);
  background: var(--bg-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
}

/* Identity row: avatar + rank icon + name + actions */
.pm-v2-id-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.pm-v2-avatar {
  width: 36px; height: 36px;
  border-radius: var(--radius-sm);
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: var(--accent-contrast);
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 800;
  flex-shrink: 0;
}
.pm-v2-name {
  flex: 1; min-width: 0;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 800;
  color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pm-v2-rank-fallback {
  width: 22px; height: 22px;
  display: grid; place-items: center;
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: 9px;
  font-weight: 800;
  color: var(--accent-contrast);
  flex-shrink: 0;
}
.pm-v2-id-actions {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
  margin-left: auto;
}

/* Buttons — primary (gold pill, Tip), ghost (Ignore) */
.pm-v2-btn {
  appearance: none;
  border: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 16px;
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard),
              transform var(--dur-fast) var(--ease-standard);
}
.pm-v2-btn-ghost {
  background: var(--bg-elevated);
  color: var(--text-secondary);
}
.pm-v2-btn-ghost:hover {
  background: var(--bg-3);
  color: var(--text-primary);
}
.pm-v2-btn-primary {
  background: var(--accent);
  color: var(--accent-contrast);
}
.pm-v2-btn-primary:hover {
  filter: brightness(1.05);
  transform: translateY(-1px);
}
.pm-v2-btn-primary:disabled {
  opacity: .5; cursor: not-allowed; filter: grayscale(.4);
  transform: none;
}

/* Divider between identity row and rank/joined row */
.pm-v2-divider {
  height: 1px;
  background: var(--border-subtle);
  /* Was --space-5 / --space-4 (12 / 10) — halve the inset for a denser
     identity card. */
  margin: var(--space-3) 0 var(--space-3);
}

/* Rank pill (left) + Joined date (right) */
.pm-v2-meta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.pm-v2-rank-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  color: var(--text-primary);
}
.pm-v2-rank-hex {
  font-size: 14px;
  filter: drop-shadow(0 0 6px var(--accent-glow));
}
.pm-v2-joined {
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--text-tertiary);
}

/* Inline tip form (under divider) */
.pm-v2-tip {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px dashed var(--border-subtle);
  display: flex; flex-direction: column;
  gap: var(--space-3);
}
.pm-v2-tip-row {
  display: flex; gap: var(--space-3); align-items: stretch;
}
.pm-v2-tip-amt {
  flex: 1; min-width: 0;
  background: var(--bg-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: var(--font-display);
  font-size: 14px; font-weight: 700;
  padding: 10px 12px;
  outline: 0;
}
.pm-v2-tip-amt:focus { border-color: var(--accent); }
.pm-v2-tip-quick {
  display: flex; gap: 6px; flex-wrap: wrap;
}
.pm-v2-tip-quick button {
  appearance: none; border: 0; cursor: pointer;
  background: var(--bg-elevated);
  color: var(--text-secondary);
  font-family: var(--font-display);
  font-size: 12px; font-weight: 700;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.pm-v2-tip-quick button:hover {
  background: var(--accent);
  color: var(--accent-contrast);
}
.pm-v2-tip-actions {
  display: flex; gap: var(--space-3); justify-content: flex-end;
}
.pm-v2-tip-err {
  font-family: var(--font-display);
  font-size: 12px;
  color: var(--color-danger);
}

/* Tabs */
.pm-v2-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  padding: 4px;
  background: var(--bg-3);
  border-radius: var(--radius-pill);
}
.pm-v2-tabs button {
  appearance: none; border: 0; cursor: pointer;
  padding: 10px 16px;
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-display);
  font-size: 13px; font-weight: 700;
  border-radius: var(--radius-pill);
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.pm-v2-tabs button:hover:not(.on) { color: var(--text-primary); }
.pm-v2-tabs button.on {
  background: var(--bg-elevated);
  color: var(--text-primary);
  box-shadow: 0 1px 0 rgba(255,255,255,.04) inset;
}

/* Stats grid — 2×2 on the screenshot */
.pm-v2-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* Tighter gap so the four stat tiles read as a single block, not
     four floating cards. */
  gap: var(--space-3);
}
.pm-v2-stat {
  padding: var(--space-4) var(--space-5);
  background: var(--bg-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  display: flex; flex-direction: column;
  gap: var(--space-1);
}
.pm-v2-stat-k {
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--text-tertiary);
}
.pm-v2-stat-v {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

/* Races empty state */
.pm-v2-races {
  background: var(--bg-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  padding: var(--space-9) var(--space-7);
  text-align: center;
}
.pm-v2-races-empty-icon {
  font-size: 36px;
  margin-bottom: var(--space-3);
  opacity: .6;
}
.pm-v2-races-empty-title {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: var(--space-2);
}
.pm-v2-races-empty-body {
  font-size: 13px;
  color: var(--text-tertiary);
  max-width: 280px;
  margin: 0 auto;
  line-height: 1.5;
}

@media (max-width: 540px) {
  .pm-v2 { padding: var(--space-5); gap: var(--space-4); }
  .pm-v2-card { padding: var(--space-5); }
  .pm-v2-stats { grid-template-columns: 1fr; }
  .pm-v2-id-row { gap: var(--space-3); }
  .pm-v2-id-actions { width: 100%; justify-content: stretch; margin-left: 0; }
  .pm-v2-id-actions .pm-v2-btn { flex: 1; justify-content: center; }
  .pm-v2-meta-row { flex-direction: column; align-items: flex-start; gap: var(--space-2); }
}

/* =============================================================
   OPERATOR REBUILD — Slot-playing anti-spoil indicators.
   While a slot iframe session is active:
     • Topbar wallet pill swaps its balance number for a "Playing"
       label with a pulsing accent dot.
     • The slot-player's own header shows "Playing · {ccy}" instead
       of a live balance number.
   Both prevent the user from inferring the outcome of an in-flight
   spin off the live balance ticker.
   ============================================================= */
/* 2C: chat moderation kebab — hidden by default, fades in on row hover
   so the message itself reads cleanly. The kebab keeps its hit area
   even when invisible (opacity:0 is still focusable / clickable for
   keyboard users with the menu already open). */
.chat-msg:hover .chat-mod-kebab { opacity: 1 !important; }
.chat-mod-kebab:focus { opacity: 1 !important; outline: none; }
.chat-mod-item:hover:not(:disabled) { background: rgba(255, 255, 255, .04); }
.chat-mod-item:disabled { opacity: .5; cursor: wait; }

/* P3-2: IN PLAY pill tightened per operator feedback ("too big at the
   moment"). Was 13px font + 8px dot; now 11px + 6px so the pill
   visually balances against the gold WALLET button next to it. */
.bal-val-playing {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--accent);
  text-transform: uppercase;
}
.bal-playing-dot,
.sp-playing-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent-glow);
  /* PDF p.6 audit: pulse ring tightened from 10px → 4px and the cadence
     slowed from 1.6s → 2.8s so the topbar pill no longer "throbs"
     against the gold WALLET button next to it. The dot is preserved
     as the activity indicator. */
  animation: bal-playing-pulse 2.8s ease-in-out infinite;
  flex-shrink: 0;
}
/* Tighten the pill itself (height + padding) when it's in IN PLAY mode
   so the smaller text doesn't leave large internal whitespace. Stays in
   sync with the WALLET button's height at the same breakpoint. */
.bal-btn.bal-btn-pill.bal-btn-playing {
  padding: 4px 10px 4px 8px;
  min-height: 28px;
}
@keyframes bal-playing-pulse {
  0%   { box-shadow: 0 0 0 0 var(--accent-glow); }
  70%  { box-shadow: 0 0 0 4px rgba(52, 192, 235, 0); }
  100% { box-shadow: 0 0 0 0 rgba(52, 192, 235, 0); }
}

/* In-iframe header — same pattern, smaller. Replaces .sp-bal which
   used to show the live amount. */
.sp-playing {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px;
  background: var(--bg-elevated);
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--accent);
  text-transform: uppercase;
}

/* =============================================================
   OPERATOR REBUILD — Roulette round-bets table
   Rendered inside the Provably Fair modal when the user opens a
   previous round. Compact 4-col table: Player / Bet / Bet on / Profit.
   ============================================================= */
.rl-bets-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-3);
}
.rl-bets-share {
  appearance: none; cursor: pointer;
  background: var(--bg-elevated); border: 0;
  color: var(--text-secondary);
  font-family: var(--font-display);
  font-size: 11px; font-weight: 700;
  letter-spacing: .04em;
  padding: 6px 10px;
  border-radius: var(--radius-pill);
  display: inline-flex; align-items: center; gap: 6px;
  transition: color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard);
}
.rl-bets-share:hover {
  color: var(--accent);
  background: var(--accent-soft);
}
.rl-bets-empty {
  font-family: var(--font-display);
  font-size: 12px;
  color: var(--text-tertiary);
  line-height: 1.5;
  padding: 16px 14px;
  background: var(--bg-2);
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-sm);
}
.rl-bets-table {
  display: flex; flex-direction: column;
  gap: 4px;
}
.rl-bets-row {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, .9fr) minmax(0, .8fr) minmax(0, 1fr);
  gap: var(--space-3);
  align-items: center;
  padding: 10px 12px;
  background: var(--bg-2);
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.rl-bets-row.rl-bets-head-row {
  background: transparent;
  padding: 4px 12px;
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  font-weight: 700;
}
.rl-bets-player {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--text-primary);
  font-weight: 600;
  min-width: 0;
}
.rl-bets-player > span:last-child {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rl-bets-rank-fb {
  width: 22px; height: 22px;
  display: grid; place-items: center;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: var(--radius-xs);
  flex-shrink: 0;
}
.rl-bets-num {
  text-align: right;
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--text-primary);
}
.rl-bets-profit-win  { color: var(--color-success); }
.rl-bets-profit-loss { color: var(--color-danger); }
.rl-bets-coloron {
  font-weight: 700;
  text-transform: capitalize;
}
.rl-bets-coloron-red    { color: #ff6680; }
.rl-bets-coloron-green  { color: #4fdc94; }
.rl-bets-coloron-black  { color: var(--text-secondary); }
@media (max-width: 540px) {
  .rl-bets-row {
    grid-template-columns: minmax(0, 1.3fr) minmax(0, .9fr) minmax(0, 1fr);
    font-size: 12px;
  }
  /* Hide "Bet on" col on tiny phones; the profit color cue carries it. */
  .rl-bets-row > :nth-child(3) { display: none; }
}

/* =============================================================
   OPERATOR REBUILD — Originals card chrome strip.
   Originals tiles now use customer-supplied PNG art that already
   carries the full identity. Both the "ORIGINALS" prov-tab and the
   colored scrim/overlay competed with the artwork, so we suppress:
     • .t-prov-tab (defensive — JSX no longer renders it on originals,
       but kill any leftover reference too)
     • .t-overlay hover dim
     • .slot-card.v3::before (hover dim)
     • .slot-card.v3::after  (brand-tinted bottom fade)
     • per-provider inset border ring (hides --prov-color outline)
   Slot cards (NOT .is-originals) keep the full chrome. */
.game-tile.is-originals .t-overlay,
.game-tile.is-originals .t-prov-tab {
  display: none !important;
}
/* On originals tiles the bottom name strip stays, but readability
   is preserved by the Poster's own bottom vignette baked into the
   .poster-img layer — no extra scrim needed. */

/* Hover-dim still hides on originals (the artwork already contains
   its own dim). The bottom fade overlay was previously hidden too,
   but operator feedback now wants a SUBTLE brand-tinted fade + dot
   pattern back on originals (matches the slots overlay treatment).
   The .slot-card.v3::after rule above already drives both surfaces
   identically; just re-allowing it here is enough. */
.slot-card.v3.is-originals::before {
  display: none;
}
.slot-card.v3.is-originals .slot-card-prov-tab {
  display: none !important;
}
/* Drop the per-provider inset ring on originals; just keep a faint
   neutral hairline so the card's edge reads against the page bg. */
.slot-card.v3.is-originals {
  box-shadow:
    inset 0 0 0 1px var(--border-subtle),
    0 4px 14px rgba(0, 0, 0, .35) !important;
}
.slot-card.v3.is-originals:hover {
  transform: translateY(-3px) scale(1.025);
  box-shadow:
    inset 0 0 0 1px var(--accent-40),
    0 16px 36px rgba(0, 0, 0, .55),
    0 0 28px var(--accent-glow) !important;
}
/* Bottom strip on originals tiles — simple dark plate behind the
   name, no per-provider color fade. */
.slot-card.v3.is-originals .slot-card-bottom {
  background: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, .45) 60%, rgba(0, 0, 0, .85) 100%) !important;
}

/* "More from Originals" rail on every originals game page —
   horizontal scroller of mid-sized cards, smaller than the slots
   page's 3:4 tiles so the rail stays compact under the bet panel. */
.originals-rail {
  display: flex;
  gap: var(--space-5);
  overflow-x: auto;
  padding: 4px 2px 12px;
  scroll-behavior: smooth;
  scrollbar-width: none;
  scroll-snap-type: x mandatory;
}
.originals-rail::-webkit-scrollbar { display: none; }
.originals-rail-card {
  flex: 0 0 auto;
  width: 168px;
  aspect-ratio: 3 / 4;
  scroll-snap-align: start;
  appearance: none;
  padding: 0;
}

/* =============================================================
   OPERATOR REBUILD — secondary-font bold-up
   The operator flagged a thin "generic AI" look on labels +
   subtitles. Inter at 400-500 reads spindly at 11-13 px on dark
   surfaces; floor everything at 600 (semibold) so labels read with
   the same confidence as the rest of the typography.
   ============================================================= */
.kicker,
.gp-field label,
.gp-stat .k,
.section-head .kicker,
.sd-prov-pill,
.sd-stat-pill,
.gp-input label,
.pm-v2-stat-k,
.pm-v2-rank-pill,
.pm-v2-joined,
.gp-mode-tabs button,
.gp-chips button,
.sec-head .kicker,
.activity-row.head,
.activity-tabs button,
.right-tabs button,
.ft-sub,
.profile-sidemenu-item,
.kicker em,
.empty-state h4,
.empty-state p {
  font-weight: 600 !important;
}
/* Section eyebrow / kicker text — was 500/uppercase Inter, now
   uppercase Sora (display) so it reads as a chunky label rather
   than a thin grey caption. */
.kicker,
.section-head .kicker,
.sec-head .kicker {
  font-family: var(--font-display);
  font-weight: 700 !important;
}

/* =============================================================
   ============== OPERATOR REBUILD — TABLE POLISH ===============
   Brief: "Tables (bet history, transactions, leaderboards): dense
   rows, tabular-nums for all amounts, monospaced hashes, win/loss
   colored amount column, sticky header with subtle blur backdrop,
   zebra rows via surface-1 / surface-2 not bg-gray-800/50.
   Pagination is compact." */

/* Games-history table — JSX uses className="gh-table" + inline styles. */
.gh-table {
  table-layout: auto;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
}
.gh-table thead tr {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--bg-2) !important;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-family: var(--font-display);
  font-size: 11px !important;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.gh-table tbody tr {
  transition: background var(--dur-base) var(--ease-standard);
}
.gh-table tbody tr:nth-child(even) {
  background: var(--white-02);
}
.gh-table tbody tr:hover {
  background: var(--accent-soft) !important;
}
.gh-table tbody tr:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  background: var(--accent-soft) !important;
}
.gh-table th, .gh-table td {
  padding: 12px 14px !important;
}

/* Generic data-table utility — drop-in for any future table that
   wants the same look without inline-style scaffolding. */
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
}
.data-table thead {
  position: sticky;
  top: 0;
  background: var(--bg-2);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  z-index: var(--z-sticky);
}
.data-table thead th {
  text-align: left;
  padding: 12px 14px;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  border-bottom: 1px solid var(--border-default);
}
.data-table tbody td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border-subtle);
  color: var(--text-primary);
}
.data-table tbody tr {
  transition: background var(--dur-base) var(--ease-standard);
}
.data-table tbody tr:nth-child(even) { background: var(--white-02); }
.data-table tbody tr:hover { background: var(--accent-soft); }
.data-table .col-num {
  text-align: right;
  font-family: var(--font-display);
  font-weight: 600;
}
.data-table .col-num.win  { color: var(--color-success); }
.data-table .col-num.loss { color: var(--color-danger); }
.data-table .col-hash {
  font-family: var(--font-display);
  font-size: 12px;
  color: var(--text-secondary);
}

/* Pagination — compact chip style (used in gh-pager + similar). */
.gh-pager .chip,
.data-pager .chip {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-default);
  background: var(--bg-2);
  color: var(--text-secondary);
  cursor: pointer;
  transition: all var(--dur-base) var(--ease-standard);
}
.gh-pager .chip:hover,
.data-pager .chip:hover {
  color: var(--accent);
  border-color: var(--accent-40);
  background: var(--accent-soft);
}
.gh-pager .chip:disabled,
.data-pager .chip:disabled {
  opacity: .4; cursor: not-allowed;
  filter: grayscale(.4);
}

/* =============================================================
   ============== OPERATOR REBUILD — POLISH LAYER ===============
   =============================================================
   Pure additions, no rewrites. Targets the brief's checklist
   items: skeletons / modal backdrop blur / button family /
   input baseline / scrollbar refinement / selection color /
   reduced-motion respect / focus polish.
   ============================================================= */

/* ---- Selection color ---- */
::selection { background: var(--accent-soft); color: var(--accent); }

/* ---- Scrollbar refinement (overrides the earlier 10px rule) ---- */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--accent-15);
  border-radius: var(--radius-pill);
  transition: background var(--dur-base) var(--ease-standard);
}
::-webkit-scrollbar-thumb:hover { background: var(--accent-40); }
* { scrollbar-color: var(--accent-15) transparent; scrollbar-width: thin; }

/* ---- Modal backdrop — heavier blur per the brief ---- */
.modal-root {
  /* Brief: "Backdrop is a heavy blur + dark overlay, not just black-50%." */
  backdrop-filter: blur(16px) !important;
  -webkit-backdrop-filter: blur(16px) !important;
  background: rgba(2, 4, 12, 0.62) !important;
  z-index: var(--z-modal) !important;
}
/* Modal entrance — scale-from-0.96 + fade per brief, with new tokens. */
.modal-shell {
  animation: sa-modal-in var(--dur-base) var(--ease-emphasized);
}
@keyframes sa-modal-in {
  from { opacity: 0; transform: scale(0.96) translateY(4px); }
  to   { opacity: 1; transform: none; }
}

/* ---- Skeleton primitive (use anywhere a loading shimmer is needed) ---- */
.skel {
  position: relative;
  display: block;
  background: var(--bg-3);
  border-radius: var(--radius-sm);
  overflow: hidden;
  isolation: isolate;
}
.skel::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.06) 50%,
    transparent 100%
  );
  animation: sa-skel-shimmer 1.4s linear infinite;
  transform: translateX(-100%);
}
@keyframes sa-skel-shimmer {
  to { transform: translateX(100%); }
}
.skel--text   { height: 12px; border-radius: var(--radius-xs); }
.skel--title  { height: 20px; border-radius: var(--radius-xs); }
.skel--circle { border-radius: 50%; }
.skel--card   { aspect-ratio: 3 / 4; border-radius: var(--radius); }
.skel--row    { height: 44px; border-radius: var(--radius-sm); }

/* ---- Empty state primitive ---- */
.empty-state {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: var(--space-5);
  padding: var(--space-11) var(--space-9);
  text-align: center;
  color: var(--text-secondary);
}
.empty-state-icon {
  width: 96px; height: 96px;
  display: grid; place-items: center;
  background: radial-gradient(circle at 30% 30%, var(--accent-soft), transparent 70%);
  border-radius: 50%;
  color: var(--accent);
  margin-bottom: var(--space-3);
}
.empty-state-icon svg { width: 56px; height: 56px; opacity: .7; }
.empty-state-title {
  font-family: var(--font-display);
  font-size: 18px;
  color: var(--text-primary);
  margin: 0;
}
.empty-state-body {
  max-width: 360px;
  font-size: 14px;
  line-height: 1.5;
  margin: 0;
}

/* ---- Secondary button (medium-emphasis; ghost is too quiet for some CTAs) ---- */
.btn-secondary {
  appearance: none;
  border: 1px solid var(--accent-40);
  background: var(--accent-soft);
  color: var(--accent);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .06em;
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard),
              transform var(--dur-fast) var(--ease-standard);
}
.btn-secondary:hover {
  background: var(--accent);
  color: var(--accent-contrast);
  border-color: var(--accent);
  transform: translateY(-1px);
}
.btn-secondary:active { transform: translateY(0); }
.btn-secondary:disabled {
  opacity: .5; cursor: not-allowed; transform: none;
  filter: grayscale(.3);
}

/* ---- Standardize disabled state across all primary/secondary/danger ---- */
/* Brief: "Disabled state is desaturated, not just opacity 50%." */
.btn-primary:disabled,
.btn-danger:disabled,
.btn-secondary:disabled {
  filter: grayscale(.4) brightness(.7);
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* ---- Form input baseline (only applies where no per-component rule wins) ----
   Operator rebuild — wrapped in :where() so the specificity is 0,0,0.
   Any per-component selector (`.rail-search input`, `.ig-search input`,
   `.gp-input input`, etc.) wins now, killing the double-box overlap on
   the sidebar / topbar / in-game search where this baseline used to
   stack a second border + bg INSIDE the wrapper's frame. */
:where(input[type="text"],
       input[type="email"],
       input[type="password"],
       input[type="number"],
       input[type="search"],
       input[type="tel"],
       textarea,
       select) {
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--text-primary);
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  outline: none;
  transition: border-color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard);
}
:where(input:not([type]):not(.no-baseline)) {
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--text-primary);
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  outline: none;
}
:where(input[type="text"]:focus,
       input[type="email"]:focus,
       input[type="password"]:focus,
       input[type="number"]:focus,
       input[type="search"]:focus,
       input[type="tel"]:focus,
       textarea:focus,
       select:focus) {
  border-color: var(--accent);
  background: var(--bg-3);
}
input::placeholder, textarea::placeholder {
  color: var(--text-tertiary);
}

/* ---- Reduced motion respect (brief mandate) ---- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .skel::after { animation: none; }
}

/* ---- Section-header rhythm (used above grids: title left, see-all right) ---- */
.section-head {
  display: flex; align-items: center; justify-content: space-between;
  margin: var(--space-10) 0 var(--space-6);
  gap: var(--space-7);
}
.section-head-title {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -.01em;
  text-transform: uppercase;
  color: var(--text-primary);
  margin: 0;
}
.section-head-title em {
  font-style: normal;
  color: var(--accent);
}
.section-head-eyebrow {
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: 4px;
  display: block;
}
.section-head-actions {
  display: flex; align-items: center; gap: var(--space-3);
  flex-shrink: 0;
}
.section-head-link {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  transition: color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard);
}
.section-head-link:hover {
  color: var(--accent);
  background: var(--accent-soft);
}

/* Horizontal scroll-rail arrows (used by section heads + posters / providers). */
.rail-arrow {
  appearance: none;
  border: 1px solid var(--border-default);
  background: var(--bg-2);
  color: var(--text-secondary);
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: 50%;
  cursor: pointer;
  transition: color var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard),
              opacity var(--dur-base) var(--ease-standard);
}
.rail-arrow:hover {
  color: var(--accent);
  border-color: var(--accent-40);
  background: var(--accent-soft);
}
.rail-arrow:disabled {
  opacity: 0; pointer-events: none;
}

/* ============================================================
   GameIcon — used in the live bet feed and any surface that needs
   a small per-game chip. Originals get a gold-tinted disc with the
   game's own glyph; slot/live games get a provider-tinted disc
   with the brand's monogram. The disc is sized via inline width/
   height so callers can control the dimension.
   ============================================================ */
.game-icon {
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  flex-shrink: 0;
  user-select: none;
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -.01em;
  line-height: 1;
  transition: transform var(--dur-fast) var(--ease-standard),
              box-shadow var(--dur-base) var(--ease-standard);
}
/* Operator feedback — originals now render as a clean white glyph on
   a transparent background (no yellow/gold disc). The artwork's own
   shape carries the cue; the disc was reading as visual noise. */
.game-icon-original {
  background: transparent;
  color: #fff;
  box-shadow: none;
}
.game-icon-original svg {
  width: 100%;
  height: 100%;
  display: block;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .55));
}
.game-icon-provider {
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--gi-tint) 92%, #fff 8%) 0%,
                            color-mix(in srgb, var(--gi-tint) 70%, #000 30%) 100%);
  color: #fff;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .14) inset,
              0 0 0 1px color-mix(in srgb, var(--gi-tint) 60%, transparent 40%),
              0 4px 10px rgba(0, 0, 0, .35);
}
.game-icon-fallback {
  background: var(--bg-elevated);
  color: var(--text-secondary);
  box-shadow: inset 0 0 0 1px var(--border-default);
  font-family: var(--font-display);
  font-weight: 700;
}
/* Provider chips that resolve to a real bundled wordmark sit on top of
   the same brand-tinted disc as the monogram fallback. Real provider
   logos arrive in their native brand colours (orange Pragmatic crown,
   red BTG mark, blue Play'n GO pill, …) — at the chip's 26 px size
   those multi-colour marks would mud the disc and clash with the
   tint. brightness(0)+invert(1) collapses every opaque pixel to pure
   white while preserving the alpha shape, so each brand reads as a
   crisp white silhouette on its tinted disc, matching the monogram
   fallback's visual language. The drop-shadow lifts the silhouette
   off lighter brand tints without darkening already-readable ones. */
.game-icon-provider-logo {
  overflow: hidden;
}
.game-icon-provider-logo img {
  padding: 14%;
  filter: brightness(0) invert(1)
          drop-shadow(0 1px 1px rgba(0, 0, 0, .35));
}
.activity-row.clickable:hover .game-icon-provider {
  transform: translateY(-1px);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .14) inset,
              0 0 0 1px rgba(255, 255, 255, .12),
              0 6px 14px rgba(0, 0, 0, .45);
}
.activity-row.clickable:hover .game-icon-original svg {
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .65));
}
/* The wrapping button used to draw its own pill — now the GameIcon
   is the visual; strip the button chrome so the disc reads cleanly. */
.g-chip-icon {
  width: auto !important;
  height: auto !important;
  background: transparent !important;
  border: 0 !important;
  padding: 0 !important;
  box-shadow: none !important;
}

/* ============================================================
   PANEL CONTAINER REWORK — Live Feed / Recent Wins + every other
   panel surface. The previous .activity / .frame.chamfer cards
   read as flat boxes; the new pass:
   • softens the corner radius (var(--radius-lg)),
   • uses a layered linear-gradient so the panel has top-down depth,
   • adds a subtle hairline + soft drop shadow so it lifts off the
     page without looking AI/tailwind-generic.
   The rules below are scoped tightly so we don't override existing
   game / bet panels (.gp-canvas, .gp-panel, etc.).
   ============================================================ */
.activity-wrap,
.section-card,
.home-section-card {
  border-radius: var(--radius-lg, 18px);
  /* Operator feedback — surface ~30 % darker so the live-feed panel
     reads as set-back from the page bg. The previous gradient lifted
     it slightly above the canvas (mix bg-2 + 8 % white at the top);
     swapped for a pure dark stack that mixes 70 % bg-2 with 30 %
     black at the top, fading to bg-1 mixed with 30 % black. */
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--bg-2) 70%, #000 30%) 0%,
      color-mix(in srgb, var(--bg-1) 70%, #000 30%) 100%);
  border: 1px solid color-mix(in srgb, var(--border-default) 70%, transparent 30%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .03) inset,
    0 18px 40px -24px rgba(0, 0, 0, .65),
    0 2px 6px rgba(0, 0, 0, .3);
  padding: var(--space-5, 18px);
  position: relative;
}
.activity-wrap {
  padding: 0; /* the inner .activity carries its own padding */
  overflow: hidden;
}
.activity {
  border-radius: var(--radius-lg, 18px);
  background: transparent;
  border: 0;
  box-shadow: none;
}
.activity-head {
  border-bottom: 1px solid color-mix(in srgb, var(--border-default) 60%, transparent 40%);
}
.activity-row {
  border-bottom: 1px solid color-mix(in srgb, var(--border-default) 35%, transparent 65%);
}
.activity-row.head {
  background: color-mix(in srgb, var(--bg-3) 60%, transparent 40%);
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .12em;
  color: var(--text-tertiary);
}
.activity-row.clickable {
  transition: background var(--dur-base) var(--ease-standard);
}
.activity-row.clickable:hover {
  background: color-mix(in srgb, var(--accent-soft) 50%, transparent 50%);
}
.activity-row.new {
  animation: act-row-flash .6s var(--ease-entrance) both;
}
@keyframes act-row-flash {
  0%   { background: var(--accent-15); }
  100% { background: transparent; }
}

/* ============================================================
   VIP cards — smoother corner radius. The hero, tier card, and
   benefit/perk tiles previously used --radius-md (10px) which read
   as the standard "AI tailwind" tile shape. Bumping to --radius-lg
   (18px) and letting the .frame.chamfer's diagonal hairline still
   nibble two corners gives them a more bespoke silhouette.
   ============================================================ */
.vip-hero-banner.frame.chamfer,
.vtier-card.frame,
.vtier-card,
.vip-perk,
.vip-benefit-card,
.vip-faq-item {
  border-radius: var(--radius-lg, 18px) !important;
}
.vtier-card,
.vip-perk,
.vip-benefit-card,
.vip-faq-item {
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--bg-2) 92%, #fff 8%) 0%,
      var(--bg-1) 100%);
  border: 1px solid color-mix(in srgb, var(--border-default) 70%, transparent 30%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .04) inset,
    0 12px 28px -20px rgba(0, 0, 0, .55);
}
.vtier-card.is-current {
  border-color: var(--accent-40);
  box-shadow:
    0 0 0 1px var(--accent-40),
    0 1px 0 rgba(255, 255, 255, .06) inset,
    0 16px 36px -20px rgba(52, 192, 235, .35);
}
.vip-perk:hover,
.vip-benefit-card:hover {
  border-color: var(--accent-40);
  transform: translateY(-1px);
  transition: transform var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard);
}

/* Sidebar collapsible group — the section-label header doubles as a
   chevron toggle. State persists via localStorage in sidebar.jsx so the
   user's preference survives reloads. */
.section-label-toggle {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: left;
  transition: color var(--dur-base) var(--ease-standard);
}
.section-label-toggle:hover { color: var(--text-primary); }
.section-chev {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  color: var(--text-tertiary);
  transition: transform var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.section-chev.is-open {
  transform: rotate(-180deg);
  color: var(--accent);
}
.nav-group { display: contents; }
.sidebar.collapsed .section-label-toggle { justify-content: center; }
.sidebar.collapsed .section-chev { display: none; }

/* ============================================================
   Favorites page — grid of the user's favourite games + an empty
   state when the list is empty. Uses the same SlotCard / GameTile
   primitives as the lobby pages, so visual style is consistent.
   ============================================================ */
.fav-page {
  padding: 0;
}
.fav-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  gap: 14px;
  margin-top: var(--space-3);
}
.fav-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 60px 24px;
  text-align: center;
  border-radius: var(--radius-lg, 18px);
  border: 1px dashed var(--border-default);
  background: color-mix(in srgb, var(--bg-2) 50%, transparent);
}
.fav-empty-icon {
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent-15);
  color: var(--accent);
}
.fav-empty-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 800;
  color: var(--text-primary);
  letter-spacing: .02em;
}
.fav-empty-sub {
  font-size: 13px;
  color: var(--text-secondary);
  max-width: 360px;
  line-height: 1.5;
}
.fav-empty-cta {
  margin-top: var(--space-2);
}

/* ============================================================
   PROMOTIONS PAGE
   Featured cards: split layout (image left + content right) on
   desktop, stacked on mobile. Standard cards: grid (image top +
   content below). Tabs are a small segmented control. The page
   uses the same .page-shell + .page-back-row chrome as the rest
   of the site so navigation feels continuous.
   ============================================================ */
.promo-page { padding-bottom: 80px; }
.promo-head { margin: 6px 0 16px; }
.promo-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 28px;
  letter-spacing: -.01em;
  color: var(--text-primary);
}

.promo-tabs {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  background: var(--bg-3);
  border: 1px solid var(--border-default);
  border-radius: 12px;
  margin-bottom: 22px;
}
.promo-tab {
  appearance: none;
  background: transparent;
  border: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: 8px;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.promo-tab:hover { color: var(--text-primary); }
.promo-tab.is-active {
  background: var(--bg-elevated);
  color: var(--text-primary);
  box-shadow: 0 1px 0 rgba(255,255,255,.04) inset;
}

.promo-empty {
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-lg, 18px);
  padding: 60px 24px;
  text-align: center;
  background: color-mix(in srgb, var(--bg-2) 50%, transparent);
}
.promo-empty-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 800;
  color: var(--text-primary);
  margin-bottom: 6px;
}
.promo-empty-sub { color: var(--text-secondary); font-size: 13px; }

.promo-tag {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 6px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  font-family: var(--font-display);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--text-secondary);
}

/* Featured (split-layout) card */
.promo-feat {
  display: grid;
  grid-template-columns: minmax(280px, 460px) 1fr;
  gap: 36px;
  align-items: center;
  padding: 0;
  margin-bottom: 22px;
  cursor: pointer;
}
.promo-feat:not(:last-child) {
  border-bottom: 1px solid color-mix(in srgb, var(--border-default) 60%, transparent 40%);
  padding-bottom: 26px;
}
.promo-feat-art {
  border-radius: 16px;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: var(--bg-2);
  position: relative;
}
.promo-feat-art img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform var(--dur-slower, 0.4s) var(--ease-standard);
}
.promo-feat:hover .promo-feat-art img { transform: scale(1.02); }
.promo-feat-art-fallback {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 80% at 50% 100%, var(--accent-15) 0%, transparent 70%),
    linear-gradient(180deg, var(--bg-2) 0%, var(--bg-1) 100%);
}
.promo-feat-body { display: flex; flex-direction: column; gap: 12px; }
.promo-feat-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 28px;
  line-height: 1.2;
  color: var(--text-primary);
}
.promo-feat-body-text {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-secondary);
  max-width: 56ch;
}
.promo-cta {
  align-self: flex-start;
  margin-top: 4px;
}

/* Standard grid card */
.promo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 24px;
}
.promo-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0;
  cursor: pointer;
  background: transparent;
  border: 0;
}
.promo-card-art {
  border-radius: 14px;
  overflow: hidden;
  aspect-ratio: 16 / 10;
  background: var(--bg-2);
  position: relative;
}
.promo-card-art img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform var(--dur-slower, 0.4s) var(--ease-standard);
}
.promo-card:hover .promo-card-art img { transform: scale(1.03); }
.promo-card-art-fallback {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 80% at 50% 100%, var(--accent-15) 0%, transparent 70%),
    linear-gradient(180deg, var(--bg-2) 0%, var(--bg-1) 100%);
}
.promo-card-body { display: flex; flex-direction: column; gap: 8px; }
.promo-card-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 18px;
  color: var(--text-primary);
}
.promo-card-body-text {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-secondary);
}

@media (max-width: 760px) {
  .promo-feat { grid-template-columns: 1fr; gap: 14px; }
  .promo-feat-title { font-size: 22px; }
  .promo-grid { grid-template-columns: 1fr 1fr; gap: 16px; }
  .promo-card-title { font-size: 16px; }
}
@media (max-width: 480px) {
  .promo-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   HERO ROW — auto-sliding 3-card carousel. Outer .hero-row clips,
   inner .hero-track is a flex row JS translates per page. perPage
   is computed from container width (≥380px-wide cards). The dots
   sit pinned at the bottom of the row. Scoped via .hero-row to
   override the legacy .hero-card rules from styles.css cleanly.
   ============================================================ */
.hero-row {
  position: relative;
  margin-bottom: 28px;
  padding-bottom: 36px;
  border-bottom: 1px solid rgba(255, 255, 255, .04);
  /* Phase 27 hover-clip fix — was `overflow: hidden`, which clipped the
     `.hero-row .hero-card:hover` lift (translateY(-2px)) and its drop
     shadow at the top/bottom edges of the row. Switching to a horizontal
     clip-path keeps the carousel's off-screen slides hidden on the LEFT
     and RIGHT (the only axis the .hero-track ever translates on) while
     letting the cards' hover transform + box-shadow extend freely above
     and below the row. The inset(-60px 0) extends the visible area 60 px
     above + below the box; sides are clipped at exactly 0 so nothing
     bleeds horizontally. `overflow: visible` is required so clip-path
     governs clipping (otherwise overflow:hidden + clip-path would still
     clip vertically). */
  overflow: visible;
  clip-path: inset(-60px 0 -60px 0);
}
.hero-row .hero-track {
  display: flex;
  gap: 16px;
  transition: transform .55s cubic-bezier(.4, 0, .2, 1);
  will-change: transform;
}
.hero-row .hero-card {
  position: relative;
  height: 220px;
  border-radius: 14px;
  overflow: hidden;
  display: flex;
  align-items: stretch;
  /* Operator feedback — container ~30 % darker than the previous
     `var(--bg-3)` (#15191f). Mixing 70 % bg-3 with 30 % black gives
     ≈ #0F1115, which sits clearly under the page bg without going
     pure-black. */
  background: color-mix(in srgb, var(--bg-3, #15191f) 70%, #000 30%);
  border: 1px solid rgba(255, 255, 255, .04);
  isolation: isolate;
  cursor: pointer;
  padding: 0;
  margin: 0;
  text-align: left;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
  /* Override the legacy .hero-card rules (margin / clip-path) from
     styles.css so the carousel cards keep their straight rectangle. */
  clip-path: none !important;
}
.hero-row .hero-card:hover {
  transform: translateY(-2px);
  border-color: rgba(255, 255, 255, .10);
  box-shadow: 0 14px 32px rgba(0, 0, 0, .55);
}
.hero-row .hero-content {
  flex: 1 1 50%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 22px 14px 22px 24px;
  gap: 6px;
  min-width: 0;
  min-height: 0;
  z-index: 2;
}
/* Operator feedback — artwork sits CONTAINED inside its column with
   breathing room top/right/bottom. Using box-sizing:border-box +
   simple block layout (NOT inner flex) so the <img> inside actually
   takes width:100% / height:100% of the padded box; an inner flex
   was clamping the img back to its intrinsic min-content size and
   leaving it as a tiny thumbnail in the corner on mobile. */
.hero-row .hero-visual {
  flex: 0 0 42%;
  align-self: stretch;
  position: relative;
  overflow: hidden;
  padding: 18px 18px 18px 0;
  box-sizing: border-box;
}
.hero-row .hero-visual img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center right;
  display: block;
}
.hero-row .hero-tag {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  padding: 4px 10px;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 999px;
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--text-secondary, #c5cad4);
  margin-bottom: 4px;
}
.hero-row .hero-card h3 {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 800;
  margin: 0;
  line-height: 1.18;
  letter-spacing: -.015em;
  color: var(--text-primary, #fff);
  max-height: calc(1.18em * 2);
  overflow: hidden;
  flex-shrink: 0;
}
.hero-row .hero-card p {
  margin: 4px 0 0;
  font-family: var(--font-ui);
  font-size: 12.5px;
  color: var(--text-secondary, #c5cad4);
  line-height: 1.45;
  max-height: calc(1.45em * 2);
  overflow: hidden;
  flex-shrink: 0;
}
.hero-row .hero-card .cta {
  align-self: flex-start;
  appearance: none;
  background: rgba(20, 24, 30, .85);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 8px;
  padding: 10px 22px;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  color: var(--text-primary, #fff);
  margin-top: 14px;
  cursor: pointer;
  transition: background .15s, transform .15s;
}
.hero-row .hero-card .cta:hover {
  background: rgba(40, 46, 56, .95);
  transform: translateY(-1px);
}
.hero-row .hero-dots {
  position: absolute;
  bottom: 12px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 6px;
  pointer-events: auto;
}
.hero-row .hero-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .20);
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: background .2s, width .2s;
}
.hero-row .hero-dot:hover { background: rgba(255, 255, 255, .40); }
.hero-row .hero-dot.active {
  background: var(--accent);
  width: 22px;
}

/* Responsive — match the Degen breakpoints so card height + text +
   paddings scale together across narrow desktop / tablet widths. */
@media (max-width: 1500px) {
  .hero-row .hero-card { height: 200px; }
  .hero-row .hero-card h3 { font-size: 17px; }
  .hero-row .hero-card p  { font-size: 12px; }
  .hero-row .hero-content { padding: 20px 12px 20px 22px; gap: 5px; }
  .hero-row .hero-card .cta { padding: 8px 16px; font-size: 12px; margin-top: 10px; }
}
@media (max-width: 1300px) {
  .hero-row .hero-card { height: 180px; }
  .hero-row .hero-card h3 { font-size: 15px; line-height: 1.18; }
  .hero-row .hero-content { padding: 16px 10px 16px 18px; gap: 4px; }
  .hero-row .hero-card p { font-size: 11.5px; max-height: calc(1.45em * 2); }
  .hero-row .hero-card .cta { padding: 7px 14px; font-size: 11.5px; margin-top: 8px; }
  .hero-row .hero-tag { padding: 3px 8px; font-size: 10.5px; }
}
/* Operator bug fix — styles.css has a legacy `@media (max-width:860px)
   .hero-card { display:flex !important; flex-direction:column;
   aspect-ratio:1.25/1; padding:var(--space-6) !important; min-height:0
   !important }` block left over from the old 2-up promo hero layout.
   That selector still matches the new carousel cards because it isn't
   scoped — and the `!important`s overrode my mobile cascade, flipping
   each card to column mode (text on top, tiny image at the bottom).
   Forcing the carousel-scoped values back so the row layout sticks. */
@media (max-width: 860px) {
  .hero-row .hero-card {
    flex-direction: row !important;
    aspect-ratio: auto !important;
    padding: 0 !important;
    min-height: 0 !important;
    justify-content: stretch !important;
  }
  /* Legacy block also clamps `.hero-card p` line-clamp to 3 + tightens
     `.hero-card h4` font-size; both leak into our cards' h3/p. Re-state
     the carousel typography here. */
  .hero-row .hero-card h3 { line-height: 1.18 !important; }
  .hero-row .hero-card p {
    -webkit-line-clamp: unset !important;
    -webkit-box-orient: unset !important;
    display: block !important;
  }
}

@media (max-width: 720px) {
  /* Operator feedback — keep the desktop layout (text left, image
     right, both fully visible). object-fit: contain (NOT cover) so
     the artwork is never cropped or stretched horizontally — wide
     PNGs just letterbox vertically. The image is anchored to the
     right edge of the column so it visually balances with the text. */
  .hero-row .hero-card { height: 190px; }
  .hero-row .hero-content {
    flex: 1 1 50%;
    padding: 16px 8px 16px 16px;
    text-align: left;
  }
  .hero-row .hero-visual {
    flex: 0 0 50%;
    padding: 12px 12px 12px 0;
  }
  .hero-row .hero-visual img {
    object-fit: contain;
    object-position: center right;
    border-radius: 0;
  }
  .hero-row .hero-card h3 { font-size: 15px; }
  .hero-row .hero-card p  { font-size: 12px; }
  .hero-row .hero-card .cta { padding: 7px 14px; font-size: 11.5px; }
}
@media (max-width: 480px) {
  /* Single-card view on very narrow phones — keep the same 50/50
     split so the picture sits in the same relative spot as desktop. */
  .hero-row .hero-card { height: 180px; }
  .hero-row .hero-content { flex: 1 1 52%; padding: 14px 6px 14px 14px; }
  .hero-row .hero-visual  { flex: 0 0 48%; padding: 10px 10px 10px 0; }
  .hero-row .hero-card .hero-tag { font-size: 9.5px; padding: 2px 6px; }
  .hero-row .hero-card h3 { font-size: 14px; }
}

/* ====================================================================
   Phase 3 — Wager tab (wallet popup → "Wager")
   src/wager-tab.jsx renders here. Visual language matches the rest
   of the wallet modal (dw-body / dw-tabs). All amounts shown are
   USD-equivalent and read from /api/me/wager-requirements.
   ==================================================================== */
.wager-tab {
  display: flex; flex-direction: column; gap: 18px;
  /* Operator brief — center the wager content within the wallet
     popup body so the empty-state card + summary read as a focused
     status panel rather than a left-justified strip. Padding-x is
     0 because the wallet modal body already has its own gutter. */
  padding: 4px 0 8px;
  width: 100%;
  max-width: 420px;
  margin: 0 auto;
  text-align: center;
  font-family: var(--font-sans);
}
.wager-tab .wager-summary,
.wager-tab .wager-section { text-align: left; }

.wager-empty {
  padding: 40px 24px;
  text-align: center;
  color: var(--text-mute);
}
.wager-empty-title { font-size: 14px; font-weight: 600; color: var(--text); margin-bottom: 4px; }
.wager-empty-sub   { font-size: 12px; color: var(--text-mute); }

.wager-summary {
  background: var(--bg-3);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 18px;
}
.wager-summary-label  { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-mute); display: flex; align-items: center; gap: 8px; }
.wager-refresh        { background: transparent; border: 1px solid var(--line); color: var(--text-mute); font-size: 12px; line-height: 1; padding: 2px 8px; border-radius: 999px; cursor: pointer; transition: color .15s ease, border-color .15s ease; }
.wager-refresh:hover  { color: var(--text); border-color: var(--text-mute); }
.wager-refresh:disabled { opacity: .55; cursor: default; }
.wager-summary-amount { font-size: 26px; font-weight: 700; color: var(--text); margin-top: 4px; line-height: 1; }
.wager-summary-sub    { font-size: 12px; color: var(--text-mute); margin-top: 8px; line-height: 1.4; }

.wager-cards { display: flex; flex-direction: column; gap: 10px; }

.wager-card {
  background: var(--bg-3);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
}
.wager-card-head {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 10px;
}
.wager-card-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  border-radius: 6px;
  background: rgba(255,255,255,.04);
  color: var(--accent);
  flex-shrink: 0;
}
.wager-card-title { flex: 1 1 auto; min-width: 0; }
.wager-card-title strong { display: block; font-size: 13px; color: var(--text); }
.wager-card-sub { font-size: 11px; color: var(--text-mute); }
.wager-expiry { font-style: normal; }
.wager-card-pct {
  font-size: 14px; font-weight: 700; color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.wager-card-bar {
  height: 6px; border-radius: 3px;
  background: rgba(255,255,255,.06);
  overflow: hidden;
  position: relative;
}
.wager-card-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-2, var(--accent)));
  border-radius: 3px;
  transition: width .25s ease-out;
}
.wager-card-meta {
  display: flex; justify-content: space-between;
  margin-top: 8px;
  font-size: 11px; color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}

.wager-section { padding-top: 4px; }
.wager-section-title {
  font-size: 12px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-mute); margin-bottom: 8px;
}

.wager-legend-intro {
  font-size: 12px; color: var(--text-mute); margin: 0 0 10px;
  line-height: 1.4;
}
.wager-legend {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 4px 10px;
}
.wager-legend-row {
  display: flex; justify-content: space-between;
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 4px;
  background: rgba(255,255,255,.02);
}
.wager-legend-cat { color: var(--text-mute); text-transform: capitalize; }
.wager-legend-pct { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }


/* ============================================================
   VERIFY EMAIL BANNER — viewport-fixed bottom toast
   ============================================================
   Phase 27 — Renders only when the signed-in user has
   `email_verified === false`. Lives outside the .app CSS Grid
   (was being auto-placed into the rail/sidebar cell when rendered
   inline) and floats at the bottom of the viewport so it never
   pushes page content. On mobile (≤860 px) we offset by
   `--bottom-nav-h` so the banner sits ABOVE the fixed bottom-nav
   instead of being hidden behind it. On desktop the bottom-nav
   element isn't rendered (`.bottom-nav { display: none }`) so we
   pin the banner to bottom: 0.
   ============================================================ */
.verify-email-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: env(safe-area-inset-bottom, 0px);
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 20px;
  background: rgba(20, 16, 8, .96);
  border-top: 1px solid rgba(52, 192, 235, .35);
  box-shadow: 0 -8px 24px rgba(0, 0, 0, .45);
  font-family: var(--font-display);
  font-size: 12px;
  color: var(--text);
  flex-wrap: wrap;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
@media (max-width: 860px) {
  .verify-email-banner {
    bottom: calc(var(--bottom-nav-h, 64px) + env(safe-area-inset-bottom, 0px));
  }
}

/* ============================================================
   VIP PAGE — match home-page Hero carousel chrome (Phase 27)
   ============================================================
   Operator brief: "make the VIP containers rounded with the exact
   same style as the Home page Hero — same buttons, same containers,
   same fonts." The home Hero is the 3-card auto-sliding carousel
   (`.hero-row .hero-card`) defined ~line 13920 of this file:
     • border-radius: 14px (no chamfer)
     • background: color-mix(in srgb, var(--bg-3) 70%, #000 30%)
     • border: 1px solid rgba(255,255,255,.04)
     • hover: translateY(-2px) + 14px/32px black shadow
     • CTA button: dark rgba(20,24,30,.85), 8px radius, white text

   These rules sit at the bottom of the file so they win over the
   earlier `.vrw-v2 .frame.chamfer`, `.vtier.frame.chamfer-sm`,
   `.vbenefit-row.frame.chamfer-sm`, `.vfaq-row.frame.chamfer-sm`,
   `.vip-cta-band.frame.chamfer`, and `.vip-hero-banner` blocks
   without having to touch the JSX className lists. The match is
   scoped under `.vip-v3` so nothing else on the site is affected.
   ============================================================ */

/* --- Container chrome: rounded card, dark mix bg, hairline border --- */
.vip-v3 .frame,
.vip-v3 .vip-hero-banner,
.vip-v3 .vip-cta-band {
  border-radius: 14px !important;
  /* Override the chamfered clip-path so corners are smoothly rounded.
     The legacy `--c: NN` custom property each card defines becomes a
     no-op once clip-path is removed. */
  clip-path: none !important;
  background: color-mix(in srgb, var(--bg-3, #15191f) 70%, #000 30%);
  border: 1px solid rgba(255, 255, 255, .04);
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
/* `.frame::before` paints a 1px gradient hairline border using
   padding+mask. With clip-path removed the rectangle border would
   show with sharp corners — hide it; we use the simple `border`
   above instead, exactly like .hero-row .hero-card. */
.vip-v3 .frame::before { display: none !important; }

/* Hover lift — same vector as .hero-row .hero-card:hover. Applied
   to every card-shaped VIP container so the family reads consistently.
   The hero banner and CTA band are page-level surfaces (not
   "browseable" cards), so we skip the lift on those — matching how
   the home page top nav strip / brand bar don't lift either. */
.vip-v3 .vrw-v2:hover,
.vip-v3 .vtier:hover,
.vip-v3 .vbenefit-row:hover,
.vip-v3 .vfaq-row:hover {
  transform: translateY(-2px);
  border-color: rgba(255, 255, 255, .10);
  box-shadow: 0 14px 32px rgba(0, 0, 0, .55);
}

/* The current-tier card already lifts itself (`.vtier.current` sets
   transform: translateY(-2px)); preserve its amber halo on hover
   instead of re-applying the white border tint. */
.vip-v3 .vtier.current:hover {
  border-color: rgba(52, 192, 235, .35);
  box-shadow: 0 14px 32px rgba(0, 0, 0, .55), 0 0 0 1px rgba(52, 192, 235, .25);
}

/* Per-state tier backgrounds — keep the semantic accent tint, but
   layer it OVER the new dark base so locked / reached / current
   still read distinctly without bringing back the old flat bg. */
.vip-v3 .vtier.locked  { background: color-mix(in srgb, var(--bg-3, #15191f) 78%, #000 22%); }
.vip-v3 .vtier.reached { background: color-mix(in srgb, var(--bg-3, #15191f) 65%, #000 35%); }
.vip-v3 .vtier.current {
  background:
    linear-gradient(180deg, rgba(52,192,235,.10), rgba(52,192,235,.02)),
    color-mix(in srgb, var(--bg-3, #15191f) 70%, #000 30%);
  border-color: rgba(52, 192, 235, .25);
}
/* Kill the legacy gold solid hairline that .vtier.current::before
   was painting on top of the now-hidden .frame::before — the
   border-color above handles the accent ring cleanly. */
.vip-v3 .vtier.current::before { display: none !important; }

/* Same treatment for the VIP hero banner — drop the gold/purple/blue
   gradient sandwich and the chamfer clip; use the carousel chrome.
   Keep the soft top streak (::before) for a touch of identity. */
.vip-v3 .vip-hero-banner {
  background: color-mix(in srgb, var(--bg-3, #15191f) 70%, #000 30%);
}
.vip-v3 .vip-hero-banner::after { display: none; }

/* Open FAQ row keeps its subtle amber wash but on the new base. */
.vip-v3 .vfaq-row.open {
  background:
    linear-gradient(180deg, rgba(52,192,235,.04), transparent),
    color-mix(in srgb, var(--bg-3, #15191f) 70%, #000 30%);
}

/* CTA band glow stays but tones down so it reads on the darker bg. */
.vip-v3 .vip-cta-band { position: relative; overflow: hidden; }
.vip-v3 .vip-cta-band::after {
  background: radial-gradient(40% 80% at 100% 50%, rgba(52,192,235,.10), transparent 60%);
}

/* --- Typography — match the carousel cards' font scale ---
   .hero-row .hero-card uses font-display 19px/800 for headings and
   font-ui 12.5px for body. The VIP page already uses font-display +
   font-ui, but a few headings were oversized for the new compact card
   look. Pull them in line with the carousel without crushing the hero
   banner (which is the page H1). */
.vip-v3 .vbenefit-title,
.vip-v3 .vrw-v2 .vrw-title { font-size: 16px; letter-spacing: -.005em; }
.vip-v3 .vbenefit-desc,
.vip-v3 .vrw-v2 .vrw-sub { font-size: 12.5px; }
.vip-v3 .vfaq-head { font-size: 13.5px; }

/* --- Buttons — match `.hero-row .hero-card .cta` exactly ---
   The carousel CTA is a muted dark pill: rgba(20,24,30,.85) bg,
   1px hairline, 8px radius, font-ui 13/700, white text. We re-paint
   every button on the VIP page with this style so primary CTAs,
   reward Claim buttons, and tier-claim buttons all read identically
   to the Hero. */
.vip-v3 .btn-primary,
.vip-v3 .vrw-btn,
.vip-v3 .vtier-claim {
  appearance: none;
  background: rgba(20, 24, 30, .85);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 8px;
  padding: 10px 22px;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--text-primary, #fff);
  text-transform: none;
  /* Override the legacy chamfer clip + box-shadow that .btn-primary
     paints from styles.css ~line 1117. */
  clip-path: none !important;
  box-shadow: none;
  cursor: pointer;
  transition: background .15s ease, transform .15s ease, border-color .15s ease;
}
/* Hover only on enabled buttons — `:not(:disabled)` guards prevent
   the lift / brighten visuals from misleadingly firing on busy or
   inactive states (e.g. .vrw-btn while claiming, .btn-primary while
   the network call is in flight). */
.vip-v3 .btn-primary:hover:not(:disabled),
.vip-v3 .vrw-btn.on:hover:not(:disabled),
.vip-v3 .vtier-claim:hover:not(:disabled) {
  background: rgba(40, 46, 56, .95);
  border-color: rgba(255, 255, 255, .12);
  transform: translateY(-1px);
  filter: none;
}
/* "Not yet claimable" reward button — softer than the active state
   but still sits in the carousel-CTA family. */
.vip-v3 .vrw-btn:not(.on) {
  background: rgba(20, 24, 30, .55);
  color: var(--text-mute);
  cursor: not-allowed;
}
.vip-v3 .vrw-btn:not(.on):hover {
  transform: none;
  background: rgba(20, 24, 30, .55);
  border-color: rgba(255, 255, 255, .06);
}
/* Disabled enabled-state buttons (e.g. claim in flight) — neutralise
   any inherited transforms / shadows so the spinner / "Claiming…"
   label sits flat. */
.vip-v3 .btn-primary:disabled,
.vip-v3 .vrw-btn:disabled,
.vip-v3 .vtier-claim:disabled {
  cursor: not-allowed;
  transform: none;
  filter: none;
  opacity: .65;
}

/* Responsive parity with .hero-row .hero-card .cta — the carousel
   CTA shrinks at 1500/1300 (additions.css ~14064/14071). Mirror
   those breakpoints so VIP buttons scale identically to the home
   hero buttons across narrow desktop / tablet widths. */
@media (max-width: 1500px) {
  .vip-v3 .btn-primary,
  .vip-v3 .vrw-btn,
  .vip-v3 .vtier-claim {
    padding: 8px 16px;
    font-size: 12px;
  }
}
@media (max-width: 1300px) {
  .vip-v3 .btn-primary,
  .vip-v3 .vrw-btn,
  .vip-v3 .vtier-claim {
    padding: 7px 14px;
    font-size: 11.5px;
  }
}

/* ============ KYC IDENTITY MODAL (Task #193) ============
   Lives inside the standard .modal-shell (chamfered + neon hairline +
   modalIn animation already provided by styles.css line 2297). This
   block is just the inner layout: header (kicker + display title +
   subtitle), two-column field grid that collapses at narrow widths,
   gold pill submit, standardized inline-error chip, and a staggered
   entrance for header → fields → CTA so the form doesn't pop in
   all-at-once feeling robotic. */
.kyc-modal {
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
  padding: 36px 40px 32px;
}
.kyc-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  animation: kycRowIn var(--dur-base) var(--ease-emphasized) both;
  animation-delay: 60ms;
}
.kyc-head .kicker {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .22em;
  color: var(--accent);
  text-transform: uppercase;
}
.kyc-title {
  font-family: var(--font-display);
  font-size: clamp(22px, 2.6vw, 28px);
  font-weight: 800;
  letter-spacing: -.01em;
  text-transform: uppercase;
  line-height: 1.05;
  margin: 0;
  color: var(--text);
}
.kyc-title em {
  font-style: normal;
  background: linear-gradient(180deg, var(--accent-bright, var(--accent)), var(--accent));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.kyc-sub {
  font-size: 13px;
  color: var(--text-dim);
  line-height: 1.55;
  margin: 0;
  max-width: 56ch;
}

.kyc-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* Two-column grid using site spacing tokens. Collapses to a single
   column on narrow viewports so the inputs aren't squeezed. */
.kyc-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
}
@media (max-width: 600px) {
  .kyc-row { grid-template-columns: 1fr; gap: var(--space-4); }
}

/* Inputs/select inherit .field, but the global rule only targets
   `input` — extend it to `select` so the country dropdown lines up
   with the text fields. Native dropdown chevron is hidden via
   appearance:none and replaced with an SVG glyph for parity with
   the rest of the site's selects. */
.kyc-modal .field input,
.kyc-modal .field select {
  background: rgba(255,255,255,.03);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  color: var(--text);
  font: inherit;
  font-size: 14px;
  outline: 0;
  appearance: none;
  -webkit-appearance: none;
  transition: border-color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard),
              box-shadow var(--dur-base) var(--ease-standard);
}
.kyc-modal .field select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'><path d='M1 1.5L6 6.5L11 1.5' stroke='%23a6aecb' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 36px;
  cursor: pointer;
}
.kyc-modal .field input:focus,
.kyc-modal .field select:focus {
  border-color: var(--accent-40, rgba(52,192,235,.4));
  background: rgba(255,255,255,.045);
  box-shadow: 0 0 0 3px rgba(52,192,235,.12);
}
.kyc-modal .field .hint {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .04em;
  color: var(--text-mute);
}
/* Date input picker icon — invert it on the dark theme so it's visible. */
.kyc-modal .field input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(.7);
  cursor: pointer;
}

/* Standardized inline error chip — magenta soft tone matching
   .bm-err / .pf-verify-result.bad on the rest of the site. */
.field-error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: rgba(255, 59, 107, .08);
  border: 1px solid rgba(255, 59, 107, .25);
  color: var(--magenta);
  font-family: var(--font-display);
  font-size: 12px;
  line-height: 1.45;
}
.field-error-mark {
  font-size: 10px;
  line-height: 1.7;
  flex-shrink: 0;
  opacity: .9;
}

/* Gold pill submit — same chrome as .auth .a-submit so the KYC
   modal feels native to the auth flow it's part of. */
.kyc-submit {
  appearance: none; border: 0; cursor: pointer;
  background: var(--accent); color: var(--accent-contrast, var(--accent-ink));
  font-family: var(--font-display); font-weight: 800;
  font-size: 15px; letter-spacing: .04em;
  padding: 16px var(--space-7);
  border-radius: var(--radius-pill);
  box-shadow: 0 4px 14px rgba(52, 192, 235, .22);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-3);
  min-height: 52px;
  margin-top: var(--space-2);
  transition: transform var(--dur-fast) var(--ease-standard),
              filter var(--dur-base) var(--ease-standard),
              box-shadow var(--dur-base) var(--ease-standard);
}
.kyc-submit:hover:not(:disabled) {
  transform: translateY(-1px);
  filter: brightness(1.04);
  box-shadow: 0 8px 22px rgba(52, 192, 235, .35);
}
.kyc-submit:active:not(:disabled) {
  transform: translateY(0);
  filter: brightness(.96);
}
.kyc-submit:disabled {
  cursor: wait;
  filter: grayscale(.3) brightness(.85);
  box-shadow: none;
}

/* Three-dot loader replaces the previous bare "…" string. Uses
   currentColor so the dots stay legible against the gold pill. */
.kyc-busy {
  display: inline-flex;
  gap: 6px;
  align-items: center;
  height: 19px;
}
.kyc-busy span {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: currentColor;
  opacity: .55;
  animation: kycBusyDot 1s ease-in-out infinite;
}
.kyc-busy span:nth-child(2) { animation-delay: .15s; }
.kyc-busy span:nth-child(3) { animation-delay: .3s; }
@keyframes kycBusyDot {
  0%, 80%, 100% { transform: scale(.55); opacity: .35; }
  40%           { transform: scale(1);   opacity: 1;   }
}

/* Staggered entrance — header → row 1 → row 2 → (error) → CTA.
   Uses --n inline so the JSX stays declarative; combines with the
   shell's modalIn so the form animates in on top of the panel pop. */
@keyframes kycRowIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.kyc-stagger {
  animation: kycRowIn var(--dur-base) var(--ease-emphasized) both;
  animation-delay: calc(var(--n, 0) * 60ms + 120ms);
}

/* ---- EXIT animation ----
   The Modal base unmounts as soon as `open` flips to false, so the
   KYC modal owns its own `closing` state and delays the parent's
   onClose by --dur-base. While `.kyc-closing` is on the inner
   wrapper, the shell + backdrop animate out via :has() so the panel
   doesn't pop off-screen. Mirrors the entrance (modalIn + modalFadeIn)
   in reverse with the emphasized easing token. */
.modal-shell:has(.kyc-closing) {
  animation: kycShellOut var(--dur-base) var(--ease-emphasized) forwards;
}
.modal-root:has(.kyc-closing) {
  animation: kycBackdropOut var(--dur-base) var(--ease-standard) forwards;
}
.kyc-closing,
.kyc-closing .kyc-stagger,
.kyc-closing .kyc-head {
  animation: none;
}
@keyframes kycShellOut {
  to { opacity: 0; transform: translateY(8px) scale(.985); }
}
@keyframes kycBackdropOut {
  to { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .kyc-head,
  .kyc-stagger,
  .modal-shell:has(.kyc-closing),
  .modal-root:has(.kyc-closing) { animation: none; }
}

/* Mobile: tighten interior padding, drop the title a notch so the
   header+sub still fit above the fold, and re-pad the modal-body
   the global mobile override clears (additions.css line 4961
   forces .modal-body { padding: 0 !important }, which means the
   .kyc-modal wrapper IS our padding source on phones). */
@media (max-width: 760px) {
  .kyc-modal { padding: 28px 22px 24px; gap: var(--space-6); }
  .kyc-title { font-size: 20px; }
  .kyc-sub { font-size: 12px; }
  .kyc-submit { font-size: 13px; padding: 14px 20px; min-height: 48px; }
}

/* ============================================================
   Task #215 — customer May 2026 PDF feedback (visual additions)
   ============================================================ */

/* Centered win popup — fired by window.spinarmoryWinPop on house-game wins.
   Task #232 refresh: the card centres on the active game canvas (felt)
   instead of the whole viewport — the JS attaches `.sa-win-pop-felt` and
   inline left/top/width/height pinned to the canvas's bbox.
   Task #233: visual rework. The previous card was a thin gold-bordered
   box that read as a "small toast"; this version turns it into a premium
   celebration moment — layered halo + outer glow ring, a generous dark
   glass card with double-stroke border, a clear label/multiplier/payout
   hierarchy with a hairline divider beneath the label, larger 56px
   multiplier with stronger glow, smoother spring-in / blur-out
   animation. The Blackjack side-bet stack (.sa-win-pop-sides) introduced
   in Task #232 still appears below the payout line. The helper
   signature, auto-dismiss timing, coalescing behavior, role="status" /
   aria-live="polite" semantics, mobile breakpoint, and reduced-motion
   override are all unchanged so existing callers (Keno, Wheel, Mines,
   Blackjack) keep working. Plinko / Dice / Limbo / Crash no longer call
   the helper. */
/* Task #277 — flat compact result card. Replaces the previous
   gold-glow celebration with a small dark rounded plate that matches
   the customer reference: red headline, coin + signed amount row,
   thin divider, small Verify link. No outer drop-shadow halo, no
   pulsing animation — a quick fade/scale in/out is fine. The shared
   helper still pins itself to the active `.gp-canvas` so every
   Originals game (blackjack, mines, plinko, dice, crash, limbo,
   hi-lo, keno, roulette) inherits the same look. */
.sa-win-pop {
  position: fixed; inset: 0; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  z-index: 9999;
  animation: sa-win-pop-in 220ms cubic-bezier(.2, .85, .35, 1);
}
/* In-canvas mount (Mines/Keno/etc.) — JS sets `position: absolute;
   inset: 0` inline so the popup tracks the canvas through scroll/
   resize without any JS listener. The viewport-fixed branch above
   only applies when no `.gp-canvas` is on the page. */
.sa-win-pop.sa-win-pop-felt { z-index: 50; }
.sa-win-pop-card {
  position: relative;
  padding: 16px 22px 12px;
  text-align: center;
  min-width: 200px;
  max-width: min(300px, 82vw);
  border-radius: 14px;
  background: #1d1f2c;
  border: 1px solid rgba(255,255,255,0.06);
  box-shadow: 0 6px 18px -8px rgba(0,0,0,0.55);
  pointer-events: auto;
}
/* Card grows to fit the side-bets table cleanly without crushing
   columns when both Perfect Pairs and 21+3 hit. */
.sa-win-pop-card.has-sides {
  min-width: 260px;
  max-width: min(340px, 88vw);
  padding-bottom: 10px;
}
.sa-win-pop-lbl {
  font: 800 18px/1.05 var(--font-display, system-ui);
  letter-spacing: 0.04em;
  color: #ff4d5a;
  text-transform: uppercase;
  margin-bottom: 12px;
}
/* Main payout block — coin + amount on one line, multiplier chip
   centered underneath. Discrete from the side-bets section so the
   chip never collides with a side-bet amount. */
.sa-win-pop-main {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
.sa-win-pop-mult-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.08);
  font-variant-numeric: tabular-nums;
}
.sa-win-pop-mult-k {
  font: 700 10px/1 var(--font-mono, monospace);
  color: rgba(255,255,255,0.45);
  letter-spacing: 0.04em;
}
.sa-win-pop-mult-v {
  font: 700 13px/1 var(--font-display, system-ui);
  color: rgba(255,255,255,0.92);
  letter-spacing: 0.01em;
}
.sa-win-pop-amt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 0;
  font: 700 20px/1 var(--font-display, system-ui);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}
.sa-win-pop-coin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #5CCDEF 0%, #f0b733 55%, #b97e10 100%);
  color: #6a4406;
  font: 800 12px/1 var(--font-display, system-ui);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.18), 0 1px 2px rgba(0,0,0,0.45);
  flex-shrink: 0;
}
/* Bitmap variant — drops the gold disc so the supplied PNG (which
   already has its own coin styling) renders cleanly. Slightly larger
   than the text glyph to match its visual weight. */
.sa-win-pop-coin-img {
  background: transparent;
  box-shadow: none;
  width: 26px; height: 26px;
  object-fit: contain;
}
.sa-win-pop-num { color: rgba(255,255,255,0.96); }
/* Operator request (May 2026) — win/loss colour rule on the popup:
   wins render green (--green), losses red (--magenta). Replaces the
   prior gold-on-win / white-on-loss palette. The card-level class
   (`sa-win-pop-card-pos|neg`) drives the headline label colour too,
   so "MINES WIN" / "KENO WIN" reads green on a win and the loss
   variant reads red. */
.sa-win-pop-amt-pos .sa-win-pop-num { color: var(--green); }
.sa-win-pop-amt-neg .sa-win-pop-num { color: var(--magenta); }
.sa-win-pop-card-pos .sa-win-pop-lbl { color: var(--green); }
.sa-win-pop-card-neg .sa-win-pop-lbl { color: var(--magenta); }
.sa-win-pop-rule {
  height: 1px;
  background: rgba(255,255,255,0.08);
  margin: 4px -6px 8px;
}
.sa-win-pop-verify {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: transparent;
  border: 0;
  padding: 4px 8px;
  margin: 0 auto;
  color: rgba(255,255,255,0.6);
  font: 600 11px/1 var(--font-sans, system-ui);
  letter-spacing: 0.02em;
  cursor: pointer;
  border-radius: 6px;
  transition: color 120ms ease, background-color 120ms ease;
}
.sa-win-pop-verify:hover { color: #fff; background: rgba(255,255,255,0.04); }
.sa-win-pop-verify svg { opacity: 0.85; }

/* Side-bet section — only rendered when at least one side bet paid.
   3-column grid keeps [type] [tier badge] [+amount] on their own
   tracks so the eye scans cleanly even when both Perfect Pairs and
   21+3 hit at once. Faint header strip ("SIDE BETS") separates the
   block from the main payout above. */
.sa-win-pop-sides {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 4px -6px 10px;
  padding: 8px 10px 6px;
  background: rgba(0,0,0,0.22);
  border: 1px solid rgba(255,255,255,0.04);
  border-radius: 10px;
}
.sa-win-pop-sides-hd {
  font: 700 9px/1 var(--font-mono, monospace);
  letter-spacing: 0.16em;
  color: rgba(255,255,255,0.42);
  text-transform: uppercase;
  text-align: left;
  padding: 0 2px 4px;
  border-bottom: 1px dashed rgba(255,255,255,0.06);
  margin-bottom: 2px;
}
.sa-win-pop-side {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, auto);
  align-items: center;
  column-gap: 10px;
  padding: 4px 2px;
}
.sa-win-pop-side-lbl {
  font: 700 11px/1.1 var(--font-sans, system-ui);
  color: rgba(255,255,255,0.88);
  text-align: left;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sa-win-pop-side-tier {
  font: 700 9px/1 var(--font-mono, monospace);
  letter-spacing: 0.1em;
  color: #1a1206;
  background: linear-gradient(180deg, #5CCDEF, #f0b733);
  padding: 4px 7px;
  border-radius: 4px;
  white-space: nowrap;
  min-height: 14px;
}
.sa-win-pop-side-tier:empty { background: transparent; padding: 0; }
.sa-win-pop-side-amt {
  font: 700 12px/1 var(--font-display, system-ui);
  color: #5CCDEF;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.sa-win-pop-out { animation: sa-win-pop-out 220ms ease forwards; }
@keyframes sa-win-pop-in {
  0%   { opacity: 0; transform: scale(0.92); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes sa-win-pop-out {
  0%   { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(0.96); }
}
@media (prefers-reduced-motion: reduce) {
  .sa-win-pop, .sa-win-pop-out { animation: none; }
}
@media (max-width: 560px) {
  .sa-win-pop-card {
    padding: 14px 18px 10px;
    min-width: 168px;
    border-radius: 12px;
  }
  .sa-win-pop-lbl { font-size: 16px; margin-bottom: 12px; }
  .sa-win-pop-amt { font-size: 16px; }
  .sa-win-pop-coin { width: 20px; height: 20px; font-size: 11px; }
}

/* Footer social buttons — give the new SVG icons a circular pill so
   they read as proper brand chips rather than bare glyphs. */
.ft-social-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  color: rgba(255,255,255,0.78);
  text-decoration: none;
  margin-right: 8px;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.ft-social-btn:hover {
  background: rgba(52,192,235,0.12);
  color: var(--accent, #34c0eb);
  border-color: rgba(52,192,235,0.45);
}

/* Profile wagered card — compact value should never overflow the card. */
.profile-stat-v-compact {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* ==========================================================
 * Task #240 — Admin design-system polish.
 * Shared styles for the new <PageHeader/> primitive (in
 * modals.jsx) and a baseline of table rhythm — sticky header,
 * zebra striping, right-aligned numerics — so every admin tab
 * looks the same without each tab inlining its own styles.
 * ========================================================== */
.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 16px;
  border: 1px solid var(--line-soft);
  background: linear-gradient(180deg, rgba(255,255,255,.02), transparent);
  border-radius: var(--radius-sm, 6px);
  margin-bottom: 14px;
}
.page-header-main { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.page-header-title-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.page-header-title {
  margin: 0;
  font-size: var(--text-xl, 18px);
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--text);
}
.page-header-sub {
  margin: 2px 0 0;
  color: var(--text-mute);
  font-size: var(--text-sm, 13px);
  max-width: 70ch;
}
.page-header-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.page-header .kicker {
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: .12em;
  color: var(--accent);
  text-transform: uppercase;
}

/* Admin data-table rhythm — used by AdminStyleguide + any tab
 * that opts into the .data-table class. Sticky header inside
 * scrolling parents, zebra striping, right-aligned numeric
 * columns via inline `style={{ textAlign:'right' }}`.            */
.data-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--text-sm, 13px);
}
.data-table thead th {
  position: sticky; top: 0;
  background: var(--panel, #14141c);
  color: var(--text-mute);
  font-weight: 600;
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  z-index: 1;
}
.data-table tbody td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}
.data-table tbody tr:nth-child(even) td { background: rgba(255,255,255,.012); }
.data-table tbody tr:hover td { background: rgba(255,255,255,.04); }
.data-table tbody tr:last-child td { border-bottom: 0; }

/* Task #240 — narrow-screen responsive admin tables. Add the
 * .data-table--responsive class to any table that has a key
 * "first column" identifier (user · bet · deposit · withdrawal id).
 * Below 720 px the first column stays anchored on the left while the
 * rest scrolls horizontally, so dense admin tables stay readable on
 * tablet-width screens without collapsing to a card list. The parent
 * .data-table-scroll wrapper provides the scroll viewport. */
.data-table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
@media (max-width: 720px) {
  .data-table--responsive thead th:first-child,
  .data-table--responsive tbody td:first-child {
    position: sticky;
    left: 0;
    background: var(--panel, #14141c);
    z-index: 1;
    box-shadow: 1px 0 0 var(--line-soft);
  }
  .data-table--responsive tbody tr:nth-child(even) td:first-child {
    background: var(--panel-2, #1a1a22);
  }
}

/* ============================================================
   Task #254 — cold-load auth skeleton.
   The topbar paints LOG IN / SIGN UP for ~200–600 ms on every cold
   load while /auth/refresh is in flight, even for users who are
   actually signed in. The new <div.tb-auth-skel> renders in that
   gap (gated by the gmb_has_session hint cookie + the
   authBootstrapped flag), then swaps to the real user pill once
   /auth/refresh resolves. Sized to roughly match the wallet pill +
   avatar group it replaces so the swap doesn't shift sibling
   layout. Pure inert decoration: aria-hidden in the JSX, no
   pointer-events, no focus target.
   ============================================================ */
.tb-auth-skel {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2, 6px);
  margin-left: var(--space-2, 6px);
  pointer-events: none;
  user-select: none;
}
.tb-auth-skel-pill {
  display: inline-block;
  width: 84px;
  height: 28px;
  border-radius: var(--radius-pill, 999px);
  background: linear-gradient(
    90deg,
    var(--bg-3, #1F1F24) 0%,
    rgba(255,255,255,.05) 50%,
    var(--bg-3, #1F1F24) 100%
  );
  background-size: 200% 100%;
  animation: tb-auth-skel-shimmer 1.4s ease-in-out infinite;
}
.tb-auth-skel-avatar {
  display: inline-block;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-pill, 999px);
  background: linear-gradient(
    90deg,
    var(--bg-3, #1F1F24) 0%,
    rgba(255,255,255,.05) 50%,
    var(--bg-3, #1F1F24) 100%
  );
  background-size: 200% 100%;
  animation: tb-auth-skel-shimmer 1.4s ease-in-out infinite;
}
@keyframes tb-auth-skel-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (max-width: 860px) {
  /* Mobile topbar: hide the wide login pill skeleton, keep only the
     avatar circle so the row matches the eventual mobile state
     (just avatar + bell, no LOG IN / SIGN UP buttons rendered). */
  .tb-auth-skel-pill { display: none; }
  .tb-auth-skel-avatar { width: 32px; height: 32px; }
}
@media (prefers-reduced-motion: reduce) {
  .tb-auth-skel-pill, .tb-auth-skel-avatar {
    animation: none;
    background: var(--bg-3, #1F1F24);
  }
}

/* Task #254 — mobile bell-shape skeleton (parity with desktop pill).
   Sized to match the .icon-btn the real bell renders into so the
   topbar row doesn't shift width when the swap happens. */
.tb-auth-skel-bell {
  display: inline-block;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-md, 10px);
  margin-left: var(--space-2, 6px);
  background: linear-gradient(
    90deg,
    var(--bg-3, #1F1F24) 0%,
    rgba(255,255,255,.05) 50%,
    var(--bg-3, #1F1F24) 100%
  );
  background-size: 200% 100%;
  animation: tb-auth-skel-shimmer 1.4s ease-in-out infinite;
  pointer-events: none;
  user-select: none;
}
@media (prefers-reduced-motion: reduce) {
  .tb-auth-skel-bell { animation: none; background: var(--bg-3, #1F1F24); }
}

/* ----------------------------------------------------------------- */
/* Task #296 — shared "Claim" CTA glow.                              */
/* Applied to: rightpanel reward `.r-btn`, reload-grid Claim button, */
/* free-spins modal Play button, hero primary CTA, and HeroCarousel  */
/* `.cta`. Per operator feedback the original pulsing heartbeat read */
/* as too loud on the home hero (three pulsing CTAs at once felt     */
/* like a notification, not a CTA), so the animation is gone — a    */
/* static, low-intensity yellow halo remains so the buttons still   */
/* get a "claim me" affordance without strobing.                     */
/* ----------------------------------------------------------------- */
.btn-claim-glow:not(:disabled) {
  position: relative;
  box-shadow: 0 0 8px 0 rgba(var(--accent-rgb, 52, 192, 235), 0.22);
}
.btn-claim-glow:not(:disabled):hover {
  box-shadow: 0 0 10px 0 rgba(var(--accent-rgb, 52, 192, 235), 0.32);
}
.btn-claim-glow:disabled {
  box-shadow: none;
}

/* ──────────────────────────────────────────────────────────────────────
   Modal head/body/foot — the WalletAdjustModal + RoleChangeModal in
   admin-user-drawer.jsx (and any future admin modal) reference
   .modal-head / .modal-x / .modal-foot, but only .modal-body was styled.
   Result: the title sat at column 0 and got CLIPPED by the modal-shell's
   22px chamfer (the missing "A" in "Adjust wallet"), and the close
   button + footer fell to a vertical stack.
   ────────────────────────────────────────────────────────────────────── */
.modal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  padding: 22px 26px 14px;       /* clears the 22px chamfer at top-left */
  border-bottom: 1px solid var(--line-soft, rgba(255,255,255,.08));
}
.modal-head h3 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -.005em;
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
}
.modal-x {
  appearance: none;
  flex-shrink: 0;
  width: 32px; height: 32px;
  border-radius: 8px;
  border: 1px solid var(--line-soft, rgba(255,255,255,.08));
  background: rgba(255,255,255,.03);
  color: var(--text-mute);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.modal-x:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: rgba(52, 192, 235, .08);
}
.modal-shell .modal-body {
  /* Re-add padding (the global .modal-body rule only handles
     overflow/flex). */
  padding: 18px 26px 18px;
}
.modal-foot {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 10px;
  padding: 14px 26px 22px;       /* clears the 22px chamfer at bottom-right */
  border-top: 1px solid var(--line-soft, rgba(255,255,255,.08));
  background: rgba(0,0,0,.18);
}
@media (max-width: 760px) {
  .modal-head { padding: 18px 22px 12px; }
  .modal-shell .modal-body { padding: 14px 22px; }
  .modal-foot { padding: 12px 22px 18px; flex-wrap: wrap; }
  .modal-foot .btn-primary,
  .modal-foot .btn-secondary,
  .modal-foot .btn-danger { flex: 1; min-width: 120px; }
}

/* ──────────────────────────────────────────────────────────────────────
   Inline alert banners — used by admin modals (RoleChangeModal,
   WalletAdjustModal) and several admin pages. Previously rendered
   unstyled because the class was referenced in JSX but never declared,
   which is part of why some admin forms read as "basic HTML".
   ────────────────────────────────────────────────────────────────────── */
.alert {
  padding: 10px 12px;
  border-radius: var(--radius-sm, 8px);
  font-size: 13px;
  line-height: 1.45;
  border: 1px solid var(--line-soft);
  background: rgba(255, 255, 255, .03);
  color: var(--text);
}
.alert.error {
  border-color: rgba(255, 88, 116, .55);
  background: rgba(255, 88, 116, .10);
  color: #ffb3c0;
}
.alert.warn {
  border-color: rgba(52, 192, 235, .55);
  background: rgba(52, 192, 235, .10);
  color: #ffe6a0;
}
.alert.info {
  border-color: rgba(124, 92, 255, .55);
  background: rgba(124, 92, 255, .10);
  color: #d6c8ff;
}
.alert strong { color: inherit; }

/* ──────────────────────────────────────────────────────────────────────
   ADMIN UX — shared primitives (Round 4 D1).
   These deliberately match the existing .frame / .input / .btn-* token
   vocabulary so admin pages get a consistent look without per-tab
   inline styles. Used by the new admin-tips tab + retroactively by the
   existing admin-* tabs as they're refactored.
   ────────────────────────────────────────────────────────────────────── */

/* Card — replaces ad-hoc {padding:14, border:1px solid var(--line-soft),
   borderRadius:var(--radius-sm), background:var(--panel)} blocks. */
.admin-card {
  padding: 14px 18px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm, 8px);
  background: var(--panel);
}
.admin-card[data-variant="dense"] { padding: 10px 14px; }
.admin-card + .admin-card { margin-top: 14px; }
.admin-card-title {
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
}
.admin-card-sub {
  font-size: 12px;
  color: var(--text-mute);
  margin: -4px 0 12px;
  line-height: 1.45;
}

/* Page header — sits at top of every admin tab. Title + optional
   subtitle on the left, action slot on the right. */
.admin-page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 18px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line-soft);
  flex-wrap: wrap;
}
.admin-page-head .kicker {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .15em;
  color: var(--accent);
  text-transform: uppercase;
}
.admin-page-head h2 {
  margin: 4px 0 2px;
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -.005em;
  color: var(--text);
}
.admin-page-head .admin-page-sub {
  font-size: 13px;
  color: var(--text-mute);
  max-width: 56ch;
  line-height: 1.45;
}
.admin-page-head .admin-page-actions {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
}

/* Form field wrapper — pairs label + input + optional hint text. */
.admin-field-label {
  display: flex; flex-direction: column; gap: 6px;
}
.admin-field-label > label,
.admin-field-label > .label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  text-transform: none;
  letter-spacing: 0;
}
.admin-field-label > .label-row {
  display: flex; align-items: center; gap: 6px;
}
.field-hint, .field-help {
  font-size: 12px;
  color: var(--text-mute);
  line-height: 1.45;
}

/* Help icon — small (?) circle next to a field label. Hover to see
   the explanation in the title attribute. */
.field-help-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 1px solid var(--line-soft);
  font-size: 9px;
  font-family: var(--font-display);
  color: var(--text-mute);
  cursor: help;
  background: rgba(255,255,255,.03);
  user-select: none;
}
.field-help-icon:hover {
  color: var(--accent);
  border-color: var(--accent);
}

/* Status badge — color via data-status attribute. */
.status-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 4px;
  font-size: 11px; font-family: var(--font-display); letter-spacing: .05em;
  border: 1px solid currentColor;
  background: transparent;
}
.status-badge[data-status="active"],
.status-badge[data-status="approved"],
.status-badge[data-status="success"],
.status-badge[data-status="finished"] { color: #4ee6a8; }
.status-badge[data-status="pending"],
.status-badge[data-status="warning"],
.status-badge[data-status="submitted"] { color: #ffe6a0; }
.status-badge[data-status="error"],
.status-badge[data-status="rejected"],
.status-badge[data-status="failed"],
.status-badge[data-status="banned"] { color: #ffb3c0; }
.status-badge[data-status="inactive"],
.status-badge[data-status="cancelled"],
.status-badge[data-status="expired"] { color: var(--text-mute); }

/* Data-table polish — used by every admin list. */
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.data-table th {
  font-weight: 700;
  padding: 10px 12px;
  background: rgba(255,255,255,.02);
  border-bottom: 2px solid var(--line-soft);
  text-transform: uppercase;
  letter-spacing: .05em;
  font-size: 11px;
  color: var(--text-mute);
  text-align: left;
}
.data-table td {
  padding: 10px 12px;
  border-top: 1px solid var(--line-soft);
  vertical-align: top;
}
.data-table tbody tr:hover td {
  background: rgba(52,192,235,.04);
}
.data-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-display);
}
.data-table .center { text-align: center; }
.data-table .muted { color: var(--text-mute); }

/* Empty state — replaces every bare "No X yet" div. */
.empty-state {
  padding: 36px 24px;
  text-align: center;
  color: var(--text-mute);
  font-size: 13px;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.empty-state .es-icon {
  width: 36px; height: 36px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(255,255,255,.04);
  color: var(--text-mute);
  margin-bottom: 4px;
}
.empty-state .es-title {
  color: var(--text);
  font-weight: 600;
  font-size: 14px;
}
.empty-state .es-sub { max-width: 44ch; line-height: 1.45; }
.empty-state .es-action { margin-top: 10px; }

/* Filter bar — used at the top of every list tab (Tips, Bets, KYC, …). */
.admin-filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: end;
  padding: 14px 16px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm, 8px);
  background: rgba(255,255,255,.02);
  margin-bottom: 14px;
}
.admin-filter-bar .admin-field-label { min-width: 140px; }
.admin-filter-bar .admin-filter-actions {
  display: flex; gap: 8px; margin-left: auto;
}

/* Pagination footer — shared across list tabs. */
.admin-pagination {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 14px;
  font-size: 12px;
  color: var(--text-mute);
}
.admin-pagination .pages { display: flex; gap: 6px; }
.admin-pagination button { min-width: 32px; }

/* ==================================================================
   ADMIN v2 — dashboard / control-panel primitives. Additive: extends
   the .admin-card / .admin-page-head vocabulary above with stat cards,
   sections, a toolbar, a real modal, and sortable data-table heads.
   Untouched tabs already use .card/.data-table so they inherit the
   refreshed look with zero JSX change.
   ================================================================== */

/* Section — titled block inside a card/pane. */
.admin-section + .admin-section { margin-top: 18px; }
.admin-section-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 12px; margin-bottom: 12px;
}
.admin-section-title {
  font-family: var(--font-display);
  font-size: 14px; font-weight: 700; color: var(--text);
  letter-spacing: .01em;
}

/* StatCard — the dashboard KPI tile. */
.admin-statcard {
  padding: 16px 18px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md, 10px);
  background: var(--panel);
  position: relative;
  transition: border-color .14s ease, transform .14s ease;
  overflow: hidden;
}
.admin-statcard.is-clickable { cursor: pointer; }
.admin-statcard.is-clickable:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}
.admin-statcard-k {
  font-family: var(--font-display);
  font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-mute);
}
.admin-statcard-v {
  font-family: var(--font-display);
  font-size: 25px; margin-top: 8px; color: var(--text);
  line-height: 1.1; word-break: break-word;
}
.admin-statcard-delta {
  margin-top: 6px; font-size: 11px; font-weight: 700;
  color: var(--text-mute);
}
.admin-statcard-delta[data-dir="up"]   { color: var(--accent); }
.admin-statcard-delta[data-dir="down"] { color: var(--magenta); }
.admin-statcard-spark { margin-top: 10px; }
.admin-statcard-note {
  margin-top: 6px; font-size: 10px; font-style: italic;
  color: var(--text-mute);
}
.admin-statgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 12px;
}

/* Toolbar — search + filters + actions row above a list. */
.admin-toolbar {
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap; margin-bottom: 14px;
}
.admin-toolbar-search { flex: 1; min-width: 200px; }
.admin-toolbar-filters { display: flex; gap: 6px; flex-wrap: wrap; }
.admin-toolbar-actions { display: flex; gap: 8px; margin-left: auto; }

/* Sortable data-table heads (DataTable component). */
.admin-datatable th.is-sortable { cursor: pointer; user-select: none; }
.admin-datatable th.is-sortable:hover { color: var(--accent); }

/* Modal — real centered dialog + drawer variant. Sits above the
   app (toast host is z 6000; this stays just below at 5800 so a
   toast fired from inside a modal is still visible). */
.admin-modal-root {
  position: fixed; inset: 0; z-index: 5800;
  background: rgba(2, 4, 12, .72);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  animation: admin-modal-fade .14s ease-out;
}
@keyframes admin-modal-fade { from { opacity: 0; } to { opacity: 1; } }
.admin-modal-shell {
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md, 10px);
  box-shadow: 0 24px 64px rgba(0,0,0,.55);
  width: 100%; max-height: 88vh; display: flex; flex-direction: column;
}
.admin-modal-sm  { max-width: 420px; }
.admin-modal-md  { max-width: 560px; }
.admin-modal-lg  { max-width: 760px; }
.admin-modal-shell.is-wide { max-width: 960px; }
.admin-modal-drawer {
  max-width: 520px; margin-left: auto; height: 100%; max-height: 100vh;
  border-radius: 0; align-self: stretch;
}
.admin-modal-root:has(.admin-modal-drawer) { padding: 0; justify-content: flex-end; }
.admin-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 16px 20px; border-bottom: 1px solid var(--line-soft);
  font-family: var(--font-display); font-size: 15px; font-weight: 700;
  color: var(--text);
}
.admin-modal-x { padding: 4px 10px; }
.admin-modal-body { padding: 20px; overflow: auto; }
.admin-modal-foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 14px 20px; border-top: 1px solid var(--line-soft);
}

/* Tiny user-pill — clickable username + role chip + (hidden) tag,
   used by the Tips list and (eventually) by every admin row that
   shows a player. */
.user-pill {
  display: inline-flex;
  align-items: center;
  /* Operator brief — tightened from 6 px so the rank icon sits visually
     attached to the username. The role chip below gets a small margin-
     left so it doesn't visually kiss the name. */
  gap: 4px;
  padding: 3px 8px;
  border-radius: 4px;
  background: rgba(255,255,255,.03);
  border: 1px solid var(--line-soft);
  font-size: 12px;
  cursor: pointer;
  transition: border-color .12s, background .12s;
  white-space: nowrap;
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.user-pill:hover {
  border-color: var(--accent);
  background: rgba(52,192,235,.06);
}
.user-pill .up-name {
  color: var(--text);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.user-pill .up-role {
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 1px 5px;
  border-radius: 3px;
  background: rgba(255,255,255,.05);
  color: var(--text-mute);
  /* Restore secondary spacing after the parent .user-pill gap was
     tightened to 4 px — the role chip would otherwise kiss the
     username. Only the icon→name gap got tightened; the name→role
     break stays comfortable. */
  margin-left: 4px;
}
.user-pill[data-role="admin"]    .up-role { color: #ff7a7a; background: rgba(255,122,122,.12); }
.user-pill[data-role="owner"]    .up-role { color: #ff5577; background: rgba(255,85,119,.12); }
.user-pill[data-role="mod"]      .up-role { color: #4ee6a8; background: rgba(78,230,168,.12); }
.user-pill[data-role="streamer"] .up-role { color: #b07dff; background: rgba(176,125,255,.12); }

/* ──────────────────────────────────────────────────────────────────────
   Sidebar reward stack — narrower variant of the VIP page's
   `.vrw vrw-v2 frame chamfer` cards. Stacks vertically inside the
   right panel where horizontal width is limited (~290px). The
   underlying .vrw-v2 + .vrw-art-band + .vrw-body classes already
   handle the chamfer + tone gradient + medallion layout.
   ────────────────────────────────────────────────────────────────────── */
.sidebar-rewards-stack {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0 12px;
}
.sidebar-reward-card {
  /* Narrower than the VIP-page variant (which spans the home grid).
     The chamfer scales with --c, kept at the parent default. */
  width: 100%;
}
.sidebar-reward-card .vrw-art-band {
  /* Slim the art strip so the medallion + amount line read tight. */
  min-height: 78px;
  padding: 10px 14px;
}
.sidebar-reward-card .vrw-body {
  padding: 10px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.sidebar-reward-card .vrw-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: 0;
}
.sidebar-reward-card .vrw-sub {
  font-size: 11px;
  color: var(--text-mute);
  line-height: 1.35;
}
.sidebar-reward-card .vrw-btn {
  /* Mirror the hero's .btn-primary gold pill — the .vrw-btn class
     already handles the on/off variants on the VIP page; we just
     enforce full-width inside the narrow sidebar. */
  width: 100%;
  margin-top: 4px;
}

/* ──────────────────────────────────────────────────────────────────────
   Sidebar rewards — Shuffle-style 2×2 grid (operator brief).
   Replaces the vertical stack with four illustrated tiles arranged
   in a 2-column grid. Each tile carries a tinted illustration band on
   top, a "Claim now" / countdown chip, the reward title, and a wide
   amber claim CTA. Colors stay in the SpinArmory amber palette so the
   branding remains consistent.
   ────────────────────────────────────────────────────────────────────── */
.sidebar-rewards-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  padding: 0 12px;
}
.sidebar-reward-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, #1a1810 0%, #121008 100%);
  border: 1px solid color-mix(in srgb, var(--accent, #34c0eb) 22%, transparent 78%);
  border-radius: 12px;
  overflow: hidden;
  min-width: 0;
}
.sidebar-reward-tile.ready {
  border-color: color-mix(in srgb, var(--accent, #34c0eb) 55%, transparent 45%);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #34c0eb) 18%, transparent 82%) inset,
              0 6px 18px -10px rgba(52,192,235,.45);
}
.sidebar-reward-tile.soon {
  opacity: .85;
}
/* Status chip — top-left "Claim now" or countdown. */
.srt-status-chip {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 2;
  padding: 3px 8px;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-mute);
  background: rgba(0,0,0,.45);
  border: 1px solid rgba(255,255,255,.06);
  white-space: nowrap;
}
.srt-status-chip.is-ready {
  color: #fff;
  background: rgba(52,192,235,.20);
  border-color: rgba(52,192,235,.45);
}
/* Art panel — illustration centered on a soft gradient backdrop.
   The status chip (.srt-status-chip) is absolutely positioned at
   top:8/left:8, so the panel reserves a top inset of 26px (chip
   height + breathing room) to keep the centered illustration clear
   of the "CLAIM NOW" pill. Without this the new coin-bag PNGs
   collide with the chip on cards narrower than ~150 px.
   `place-items: center` honors the padding box, so adding
   padding-top shifts the centroid down without altering left/right
   centering. */
.srt-art {
  position: relative;
  height: 96px;
  padding-top: 22px;
  display: grid;
  place-items: center;
  background: radial-gradient(120% 100% at 50% 0%,
                rgba(52,192,235,.16) 0%,
                rgba(52,192,235,.04) 45%,
                rgba(0,0,0,0) 70%);
}
.srt-art > picture,
.srt-art > picture > img,
.srt-art > svg {
  display: block;
  margin: 0 auto;
}
/* Body — title centered, button full-width. */
.srt-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 10px 12px 12px;
}
.srt-title {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--text);
  text-align: center;
  line-height: 1.2;
}
.srt-sub {
  font-family: var(--font-display);
  font-size: 10px;
  color: var(--text-mute);
  text-align: center;
  line-height: 1.3;
  /* Never let the "$X each · N× claims left · daily" string spill past
     the tile edge — it must wrap inside the padded body, not clip. */
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
  hyphens: none;
}
.srt-btn {
  width: 100%;
  appearance: none;
  border: 1px solid color-mix(in srgb, var(--accent, #34c0eb) 30%, transparent 70%);
  background: rgba(0,0,0,.35);
  color: var(--text-mute);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 7px 10px;
  border-radius: 8px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, transform .15s ease;
}
.srt-btn.on {
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
  border-color: var(--accent);
  color: var(--on-accent);
  box-shadow: 0 6px 18px var(--accent-glow);
}
.srt-btn.on:hover { transform: translateY(-1px); filter: brightness(1.05); }
.srt-btn:disabled { cursor: not-allowed; opacity: .55; }

/* Operator: the Rewards side-tab read "oversized" inside the ~320px mobile
   drawer — the desktop tile art/fonts were too big for two columns at that
   width. Shrink the art height, typography, and padding on phones so the
   tiles stay compact and nothing overflows the drawer. */
@media (max-width: 860px){
  .sidebar-rewards-grid { gap: 8px; padding: 0 10px; }
  .srt-art { height: 72px; padding-top: 20px; }
  .srt-body { gap: 6px; padding: 8px 10px 10px; }
  .srt-title { font-size: 12px; }
  .srt-sub { font-size: 9px; }
  .srt-btn { font-size: 10px; padding: 6px 8px; }
  .srt-status-chip { font-size: 8px; padding: 2px 6px; top: 6px; left: 6px; }
}

/* ==================================================================
   BIG WINS TICKER (home-page, under hero) — Stake/BC.Game-style
   auto-sliding marquee. Two click targets per card (cover + info).
   Pause-on-hover, edge-fade mask, mobile-aware.
   ================================================================== */
.bwt-section {
  margin: 16px clamp(14px, 2.4vw, 32px) 28px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.bwt-head {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.bwt-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: 800 14px/1 var(--font-display, system-ui);
  color: var(--text);
  letter-spacing: .01em;
}
.bwt-title-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #4ade80;
  box-shadow: 0 0 0 0 rgba(74, 222, 128, .55);
  animation: bwtTitlePulse 1.8s ease-out infinite;
}
@keyframes bwtTitlePulse {
  0%   { box-shadow: 0 0 0 0 rgba(74, 222, 128, .55); }
  70%  { box-shadow: 0 0 0 8px rgba(74, 222, 128, 0); }
  100% { box-shadow: 0 0 0 0 rgba(74, 222, 128, 0); }
}
.bwt-tabs {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.bwt-tabs::-webkit-scrollbar { display: none; }
.bwt-tab {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 6px 10px;
  border-radius: 6px;
  cursor: pointer;
  font: 700 12px/1 var(--font-display, system-ui);
  letter-spacing: .02em;
  color: var(--text-mute);
  white-space: nowrap;
  transition: color .12s ease, background-color .12s ease;
}
.bwt-tab:hover { color: var(--text); background: rgba(255, 255, 255, .04); }
.bwt-tab.on {
  color: var(--text);
  background: rgba(255, 255, 255, .08);
}

/* Viewport: hides the duplicated track overflow + applies the edge
   fade so cards visually slide in/out instead of popping. */
.bwt-viewport {
  position: relative;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
}
.bwt-empty {
  padding: 28px 0;
  text-align: center;
  font: 600 12px/1.4 var(--font-mono, monospace);
  color: var(--text-mute);
}

.bwt-track {
  display: flex;
  gap: 12px;
  width: max-content;
  animation: bwtSlide 60s linear infinite;
  will-change: transform;
}
.bwt-track:hover,
.bwt-track:focus-within { animation-play-state: paused; }
.bwt-track-static { animation: none; }
@keyframes bwtSlide {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Card */
.bwt-card {
  flex: 0 0 auto;
  width: 116px;
  background: var(--panel);
  border: 1px solid rgba(255, 255, 255, .04);
  border-radius: 10px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.bwt-card:hover {
  transform: translateY(-2px);
  border-color: rgba(52, 192, 235, .35);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .45);
}
.bwt-card-fresh {
  border-color: rgba(52, 192, 235, .55);
  box-shadow: 0 0 0 1px rgba(52, 192, 235, .35), 0 0 24px rgba(52, 192, 235, .35);
  animation: bwtFresh 1.6s ease-out;
}
@keyframes bwtFresh {
  0%   { box-shadow: 0 0 0 1px rgba(52, 192, 235, .9), 0 0 30px rgba(52, 192, 235, .6); }
  100% { box-shadow: 0 0 0 1px rgba(52, 192, 235, .35), 0 0 24px rgba(52, 192, 235, .35); }
}
.bwt-cover {
  appearance: none;
  border: 0;
  padding: 0;
  margin: 0;
  background: #000;
  cursor: pointer;
  width: 100%;
  aspect-ratio: 3 / 4;
  display: block;
  position: relative;
}
.bwt-cover-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.bwt-cover-fallback {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  background: var(--accent-15, rgba(52, 192, 235, .15));
}
.bwt-cover-fallback-letter {
  font: 800 36px/1 var(--font-display, system-ui);
  color: var(--accent);
}
.bwt-info {
  appearance: none;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 8px 6px 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-align: center;
  width: 100%;
  transition: background-color .12s ease;
}
.bwt-info:hover { background-color: rgba(255, 255, 255, .03); }
.bwt-info .u {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font: 600 10px/1.1 var(--font-mono, monospace);
  color: var(--text-mute);
  max-width: 100%;
}
.bwt-uname {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 84px;
}
.bwt-dot {
  flex-shrink: 0;
  width: 5px; height: 5px; border-radius: 50%;
  background: rgba(255, 255, 255, .25);
}
.bwt-info .v {
  font: 800 13px/1 var(--font-display, system-ui);
  color: #4ade80;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}
.bwt-info .m {
  font: 700 10px/1 var(--font-mono, monospace);
  color: var(--text-mute);
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
}

/* ==================================================================
   PROVABLY FAIR MODAL v2 — built on top of the .pm-v2 (player modal)
   surfaces so the two popups share a single visual language. The
   .pf-v2-* rules here only add the bits that don't exist in the
   player-modal stylesheet (code blocks, copy chips, history table,
   formula box, verify result chips, roulette bets table).
   ================================================================== */

.pf-v2 {
  /* nothing extra — inherits .pm-v2 layout (column flex, gap, padding) */
}

.pf-v2-head {
  /* tighter than the player modal's title row — a single inline lockup
     is enough; the heavy "identity" treatment lives in pf-v2-id-card. */
  padding-bottom: 0;
}
.pf-v2-head-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-primary);
}
.pf-v2-shield {
  display: inline-grid;
  place-items: center;
  width: 22px; height: 22px;
  border-radius: var(--radius-xs);
  background: var(--accent-soft);
  color: var(--accent);
}

/* Identity-style card — mirrors the .pm-v2-card avatar+name lockup so
   the popup leads with the same visual weight as the profile popup. */
.pf-v2-id-card { padding: var(--space-5) var(--space-6); }
.pf-v2-id-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}
.pf-v2-id-badge {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: var(--accent-contrast);
  flex-shrink: 0;
}
.pf-v2-id-body { min-width: 0; }
.pf-v2-id-name {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 800;
  letter-spacing: .02em;
  color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pf-v2-id-blurb {
  margin-top: 2px;
  font-family: var(--font-ui);
  font-size: 12.5px;
  color: var(--text-tertiary);
  line-height: 1.5;
}

/* Tabs — 4-up segmented pill, same chrome as .pm-v2-tabs but flexible
   column count + horizontal-scroll on narrow widths. */
.pf-v2-tabs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  padding: 4px;
  background: var(--bg-3);
  border-radius: var(--radius-pill);
}
.pf-v2-tabs button {
  appearance: none; border: 0; cursor: pointer;
  padding: 9px 12px;
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-display);
  font-size: 12.5px;
  font-weight: 700;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.pf-v2-tabs button:hover:not(.on) { color: var(--text-primary); }
.pf-v2-tabs button.on {
  background: var(--bg-elevated);
  color: var(--text-primary);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .04) inset;
}

/* Content card — shares .pm-v2-card backdrop, adds an inner title row
   so the section heading sits inside the card not above it. */
.pf-v2-section {
  padding: var(--space-5) var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.pf-v2-section-title {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.pf-v2-section-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* Key/value code rows — one-row "label · value · copy" lockup. The
   value is always one line (truncates with ellipsis on overflow). */
.pf-v2-kv-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.pf-v2-kv {
  display: grid;
  grid-template-columns: 130px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  padding: 8px 12px;
  background: var(--bg-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}
.pf-v2-kv-k {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.pf-v2-kv-v {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pf-v2-kv-v.is-mono {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 12px;
}
.pf-v2-kv-v.is-accent { color: var(--accent); }
.pf-v2-kv-copy {
  appearance: none;
  border: 0;
  cursor: pointer;
  padding: 4px 10px;
  border-radius: var(--radius-xs);
  background: var(--bg-elevated);
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.pf-v2-kv-copy:hover {
  background: var(--accent);
  color: var(--accent-contrast);
}

/* Inline note copy — tertiary text under a kv stack. */
.pf-v2-note {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-tertiary);
}
.pf-v2-note-strong { color: var(--text-secondary); }
.pf-v2-note strong { color: var(--text-primary); font-weight: 700; }

/* "How it works" steps */
.pf-v2-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.pf-v2-steps li {
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: var(--space-3);
  align-items: flex-start;
}
.pf-v2-step-num {
  display: grid;
  place-items: center;
  width: 36px; height: 36px;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .04em;
}
.pf-v2-step-title {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 2px;
}
.pf-v2-step-body {
  font-family: var(--font-ui);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-secondary);
}

/* Bullet list (Guarantees panel) */
.pf-v2-bullets {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.pf-v2-bullets li {
  position: relative;
  padding-left: 18px;
  font-family: var(--font-ui);
  font-size: 12.5px;
  color: var(--text-secondary);
  line-height: 1.55;
}
.pf-v2-bullets li::before {
  content: '◆';
  position: absolute;
  left: 0;
  color: var(--accent);
  font-size: 10px;
  top: 3px;
}

/* Formula / algorithm code block */
.pf-v2-formula {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px;
  background: var(--bg-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-secondary);
  word-break: break-word;
}
.pf-v2-formula .is-accent { color: var(--accent); }

/* Input row + buttons (Edit-seed, Verify) */
.pf-v2-input-row {
  display: flex;
  gap: var(--space-3);
  align-items: stretch;
  flex-wrap: wrap;
}
.pf-v2-input {
  flex: 1; min-width: 0;
  background: var(--bg-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 500;
  padding: 10px 12px;
  outline: 0;
  transition: border-color var(--dur-base) var(--ease-standard);
}
.pf-v2-input:focus { border-color: var(--accent); }
.pf-v2-input::placeholder { color: var(--text-tertiary); }

.pf-v2-verify-btn { align-self: flex-start; }

/* Result chip (Verify ok/bad) */
.pf-v2-result {
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.5;
}
.pf-v2-result.is-ok {
  background: rgba(74, 222, 128, .08);
  border: 1px solid rgba(74, 222, 128, .25);
  color: #4ade80;
}
.pf-v2-result.is-bad {
  background: rgba(244, 63, 94, .08);
  border: 1px solid rgba(244, 63, 94, .25);
  color: #fb7185;
}
.pf-v2-result strong {
  color: inherit;
  font-weight: 800;
}

/* Empty / loading state inside cards */
.pf-v2-empty {
  padding: var(--space-5) 0;
  text-align: center;
  font-family: var(--font-ui);
  font-size: 12.5px;
  color: var(--text-tertiary);
}

/* History table */
.pf-v2-history {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.pf-v2-history-row {
  display: grid;
  grid-template-columns: 80px minmax(0, 1fr) 90px 70px;
  align-items: center;
  gap: var(--space-3);
  padding: 10px 14px;
  background: var(--bg-2);
  border-bottom: 1px solid var(--border-subtle);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-secondary);
}
.pf-v2-history-row:last-child { border-bottom: 0; }
.pf-v2-history-row.pf-v2-history-head {
  background: var(--bg-3);
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.pf-v2-history-idx { color: var(--text-tertiary); }
.pf-v2-history-hash {
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pf-v2-num {
  font-variant-numeric: tabular-nums;
  text-align: right;
  font-weight: 700;
}
.pf-v2-num.is-win  { color: #4ade80; }
.pf-v2-num.is-loss { color: #fb7185; }
.pf-v2-history-action {
  text-align: right;
  font-family: var(--font-display);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .04em;
}
.pf-v2-history-link {
  appearance: none;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: var(--radius-xs);
  color: var(--accent);
  transition: background var(--dur-base) var(--ease-standard);
}
.pf-v2-history-link:hover { background: var(--accent-soft); }

/* ----- Roulette PF modal: history list + drill-in back row ------- */
.pf-v2-back-row {
  display: flex;
  align-items: center;
  margin: -4px 0 8px;
}
.pf-v2-back-btn {
  appearance: none;
  cursor: pointer;
  border: 1px solid var(--border-subtle);
  background: rgba(255, 255, 255, .03);
  color: var(--text-secondary);
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  padding: 6px 12px;
  border-radius: var(--radius-xs);
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard);
}
.pf-v2-back-btn:hover {
  background: rgba(255, 255, 255, .06);
  color: var(--text-primary);
  border-color: var(--accent-40);
}

.pf-v2-rl-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 8px;
  margin-bottom: 12px;
}
.pf-v2-rl-summary-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  background: var(--bg-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
}
.pf-v2-rl-summary-k {
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.pf-v2-rl-summary-v {
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.pf-v2-rl-summary-v.is-red    { color: #ff6b6b; }
.pf-v2-rl-summary-v.is-black  { color: var(--text-primary); }
.pf-v2-rl-summary-v.is-green  { color: #4ee6a8; }

.pf-v2-rl-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.pf-v2-rl-row {
  display: grid;
  grid-template-columns: 80px minmax(0, 1fr) 100px 100px;
  align-items: center;
  gap: var(--space-3);
  padding: 10px 14px;
  background: var(--bg-2);
  border-bottom: 1px solid var(--border-subtle);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-secondary);
  text-align: left;
}
.pf-v2-rl-row:last-child { border-bottom: 0; }
.pf-v2-rl-row.pf-v2-rl-head {
  background: var(--bg-3);
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  padding-top: 8px;
  padding-bottom: 8px;
}
button.pf-v2-rl-row-btn {
  appearance: none;
  border: 0;
  border-bottom: 1px solid var(--border-subtle);
  cursor: pointer;
  width: 100%;
  transition: background var(--dur-base) var(--ease-standard);
}
button.pf-v2-rl-row-btn:hover { background: var(--bg-3); }
button.pf-v2-rl-row-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.pf-v2-rl-id {
  font-weight: 700;
  color: var(--text-primary);
}
.pf-v2-rl-result {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.pf-v2-rl-pip {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 800;
  color: #fff;
  flex-shrink: 0;
  border: 1px solid rgba(0, 0, 0, .35);
}
.pf-v2-rl-pip.is-red   { background: linear-gradient(135deg, #d6394f, #8b1f30); }
.pf-v2-rl-pip.is-black { background: linear-gradient(135deg, #2a2c33, #14161b); }
.pf-v2-rl-pip.is-green { background: linear-gradient(135deg, #2dc88a, #1a8e58); }
.pf-v2-rl-color {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.pf-v2-rl-color.is-red   { color: #ff6b6b; }
.pf-v2-rl-color.is-black { color: var(--text-secondary); }
.pf-v2-rl-color.is-green { color: #4ee6a8; }
.pf-v2-rl-time {
  font-family: var(--font-mono);
  color: var(--text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pf-v2-rl-action {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  text-align: right;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--accent);
  text-transform: uppercase;
}
@media (max-width: 540px) {
  .pf-v2-rl-row {
    grid-template-columns: 56px minmax(0, 1fr) 80px;
    padding: 9px 10px;
  }
  .pf-v2-rl-row > .pf-v2-rl-time { display: none; }
  .pf-v2-rl-pip { width: 24px; height: 24px; font-size: 11px; }
}

/* Roulette per-round bets table inside the PF modal */
.pf-v2-share-btn {
  appearance: none;
  cursor: pointer;
  border: 1px solid var(--border-subtle);
  background: var(--bg-elevated);
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  padding: 5px 10px;
  border-radius: var(--radius-xs);
  display: inline-flex;
  align-items: center;
  gap: 5px;
  transition: color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard);
}
.pf-v2-share-btn:hover {
  color: var(--text-primary);
  background: var(--bg-3);
}
.pf-v2-bets {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.pf-v2-bets-row {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, .9fr) minmax(0, .8fr) minmax(0, .9fr);
  align-items: center;
  gap: var(--space-3);
  padding: 9px 14px;
  border-bottom: 1px solid var(--border-subtle);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-secondary);
}
.pf-v2-bets-row:last-child { border-bottom: 0; }
.pf-v2-bets-head {
  background: var(--bg-3);
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.pf-v2-bets-player {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: var(--font-ui);
  font-weight: 600;
}
.pf-v2-bets-coloron {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 11.5px;
  letter-spacing: .04em;
}
.pf-v2-bets-coloron.is-red    { color: #f87171; }
.pf-v2-bets-coloron.is-black  { color: var(--text-secondary); }
.pf-v2-bets-coloron.is-green  { color: #4ade80; }
.pf-v2-rank-fb {
  display: inline-grid;
  place-items: center;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
}

/* Footer note */
.pf-v2-footer {
  text-align: center;
  font-family: var(--font-ui);
  font-size: 11px;
  letter-spacing: .06em;
  color: var(--text-tertiary);
  padding: var(--space-2) 0 var(--space-1);
}

/* Mobile */
@media (max-width: 640px) {
  .pf-v2-tabs { grid-template-columns: repeat(4, 1fr); }
  .pf-v2-tabs button { padding: 8px 6px; font-size: 11.5px; }
  .pf-v2-kv { grid-template-columns: 100px minmax(0, 1fr) auto; padding: 8px 10px; }
  .pf-v2-kv-k { font-size: 10px; }
  .pf-v2-history-row { grid-template-columns: 60px minmax(0, 1fr) 70px 60px; padding: 9px 10px; }
  .pf-v2-bets-row { grid-template-columns: minmax(0, 1.2fr) minmax(0, .8fr) minmax(0, .7fr) minmax(0, .9fr); padding: 8px 10px; }
}

/* ==================================================================
   BET MODAL v2 — built on the same .pm-v2 surfaces as the player /
   provably-fair modals, plus the bet-specific bits (head buttons,
   placed-by row, 3-stat grid, preview card, fair section toggle).
   ================================================================== */

.bm-v2 {
  /* Inherits .pm-v2 column layout / gap / padding. The few overrides
     below tighten line-height for a denser betting receipt feel. */
}

.bm-v2-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.bm-v2-head-title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}
.bm-v2-head-icon {
  display: inline-grid;
  place-items: center;
  width: 30px; height: 30px;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  color: var(--accent);
  flex-shrink: 0;
}
.bm-v2-head-icon-fb {
  font-family: var(--font-display);
  font-weight: 800;
  color: var(--accent);
}
.bm-v2-head-game {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 800;
  letter-spacing: .01em;
  color: var(--text-primary);
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bm-v2-head-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.bm-v2-head-btn {
  appearance: none; cursor: pointer;
  border: 1px solid var(--border-subtle);
  background: var(--bg-elevated);
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  padding: 5px 9px;
  border-radius: var(--radius-xs);
  display: inline-flex;
  align-items: center;
  gap: 5px;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.bm-v2-head-btn:hover {
  background: var(--bg-3);
  color: var(--text-primary);
}

.bm-v2-id-line {
  margin-top: -4px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-tertiary);
}
.bm-v2-id-line code {
  background: transparent;
  padding: 0;
  word-break: break-all;
}

.bm-v2-err {
  background: var(--bg-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: var(--space-5);
  text-align: center;
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--text-tertiary);
}

/* PLACED BY — identity-style row inside a .pm-v2-card */
.bm-v2-placed {
  appearance: none;
  cursor: pointer;
  width: 100%;
  text-align: left;
  display: grid;
  grid-template-columns: 36px 1fr auto;
  align-items: center;
  gap: var(--space-3);
  transition: border-color var(--dur-base) var(--ease-standard);
}
.bm-v2-placed:hover { border-color: var(--accent); }
.bm-v2-placed-disabled { cursor: default; opacity: .85; }
.bm-v2-placed-disabled:hover { border-color: var(--border-subtle); }
.bm-v2-placed-avatar {
  width: 36px; height: 36px;
  border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 800;
  color: #fff;
}
.bm-v2-placed-body { min-width: 0; }
.bm-v2-placed-label {
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: 2px;
}
.bm-v2-placed-name {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bm-v2-placed-hidden {
  font-family: var(--font-ui);
  font-size: 9px;
  color: var(--text-tertiary);
  font-style: italic;
}
.bm-v2-placed-ts {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-tertiary);
  white-space: nowrap;
}

/* Stats — 3-up grid (collapses to 1-col on narrow widths) */
.bm-v2-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
}
.bm-v2-stat {
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.bm-v2-stat-k {
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.bm-v2-stat-v {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bm-v2-stat-v-stack {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  align-items: flex-start;
  line-height: 1.15;
}
.bm-v2-stat-sub {
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 500;
  color: var(--text-tertiary);
  letter-spacing: 0;
}
@media (max-width: 540px) {
  .bm-v2-stats { grid-template-columns: 1fr 1fr; }
  .bm-v2-stat-v { font-size: 15px; }
}

/* Outcome preview wrapper — keeps the per-game visual on the same
   card surface as the rest of the popup. The legacy .bp-* internals
   are unchanged. */
.bm-v2-preview-card {
  padding: var(--space-5) var(--space-5);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
}

/* Play CTA — uses the .pm-v2-btn primary look but stretches full-width
   so it reads as the modal's primary action like the screenshot. */
.bm-v2-play-cta {
  width: 100%;
  justify-content: center;
  padding: 14px 22px;
  font-size: 14px;
  letter-spacing: .04em;
  text-transform: uppercase;
}

/* Provably Fair section — collapsed by default, expands inline. The
   header is a button so the whole row is clickable + keyboard-friendly. */
.bm-v2-fair {
  padding: 0;
  overflow: hidden;
}
.bm-v2-fair-head {
  width: 100%;
  appearance: none;
  border: 0;
  cursor: pointer;
  background: transparent;
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  text-align: left;
  transition: background var(--dur-base) var(--ease-standard);
}
.bm-v2-fair-head:hover { background: var(--bg-3); }
.bm-v2-fair-shield {
  display: inline-grid;
  place-items: center;
  width: 24px; height: 24px;
  border-radius: var(--radius-xs);
  background: var(--accent-soft);
  color: var(--accent);
}
.bm-v2-fair-title {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-primary);
}
.bm-v2-fair-state {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--text-tertiary);
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  background: var(--bg-3);
}
.bm-v2-fair.is-open .bm-v2-fair-state {
  background: var(--accent-soft);
  color: var(--accent);
}
.bm-v2-fair-chev {
  font-family: var(--font-mono);
  color: var(--text-tertiary);
}

.bm-v2-fair-body {
  padding: 0 var(--space-5) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  border-top: 1px dashed var(--border-subtle);
  padding-top: var(--space-4);
  margin-top: 0;
}
.bm-v2-fair-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}
.bm-v2-fair-verify {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.bm-v2-fair-ticket {
  font-family: var(--font-ui);
  font-size: 12.5px;
  color: var(--text-secondary);
  font-weight: 500;
  line-height: 1.55;
}
.bm-v2-fair-ticket strong {
  color: var(--text-primary);
  font-weight: 700;
  font-family: var(--font-mono);
}

/* Mobile bet modal */
@media (max-width: 540px) {
  .bm-v2-head-game { font-size: 15px; }
  .bm-v2-head-btn span { display: none; }      /* compact icons on phones */
  .bm-v2-head-btn { padding: 5px 7px; }
  .bm-v2-placed { grid-template-columns: 32px 1fr auto; }
  .bm-v2-placed-avatar { width: 32px; height: 32px; font-size: 13px; }
  .bm-v2-fair-head { grid-template-columns: auto 1fr auto auto; padding: 12px var(--space-4); }
  .bm-v2-fair-state { display: none; }         /* free up width on mobile */
}

/* Mobile — smaller cards, slower marquee so labels stay legible. */
@media (max-width: 720px) {
  .bwt-section { margin: 12px 12px 22px; }
  .bwt-card { width: 96px; }
  .bwt-track { animation-duration: 90s; }
  .bwt-info .v { font-size: 12px; }
  .bwt-uname { max-width: 70px; }
}
@media (max-width: 480px) {
  .bwt-card { width: 88px; }
}

/* Reduced motion — kill the marquee, fall back to a native horizontal
   scroller so the user can still browse. Fade mask is preserved. */
@media (prefers-reduced-motion: reduce) {
  .bwt-track {
    animation: none;
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
  }
  .bwt-card { scroll-snap-align: start; }
  .bwt-card-fresh { animation: none; }
  .bwt-title-dot { animation: none; }
}

/* ============================================================
   VIP page — V4 Degen-style rebuild
   ------------------------------------------------------------
   Cloned 1:1 from the customer-supplied Degen reference.
   Sections (top-down):
     .vip-v4 .v4-hero          — Legendary Rewards hero
     .vip-v4 .v4-section       — VIP Ranks section header + rail
     .vip-v4 .v4-tc            — individual tier card
     .vip-v4 .v4-rb            — Rank Bonuses carousel
     .vip-v4 .v4-faq-*         — FAQ 2-column grid
     .vip-v4 .v4-cta           — sign-out CTA bar

   Companion JSX: src/vip-page.jsx (V4 components).
   The legacy V2/V3 CSS blocks earlier in this file are
   harmless — no V2/V3 classNames remain in the JSX.

   Color palette mirrors the reference: dark surfaces
   (#13131a / #1a1a22), soft purple/blue progress
   (#7c5cff → #4a2fc8), brand gold accents (--accent),
   green checkmarks (#34c0eb), thin neutral hairlines.
   ============================================================ */

/* Page wrapper — own the viewport-side gutters so the cards
   land flush at the responsive max-width without an extra
   container. The site shell already centers .page-shell
   children; .vip-v4 lives directly inside that. */
.vip-v4 {
  display: flex;
  flex-direction: column;
  gap: 28px;
  font-family: var(--font-ui);
  color: var(--text);
}
.vip-v4 .page-back-row {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 4px;
}
.vip-v4 .v4-page-mark {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .14em;
  color: var(--text-mute);
  text-transform: uppercase;
}
.vip-v4 .v4-page-mark-diamond {
  color: var(--accent);
  margin-right: 4px;
}

/* ============================================================
   1. HERO — "Legendary Rewards"
   ============================================================ */
.vip-v4 .v4-hero {
  position: relative;
  display: grid;
  grid-template-columns: 1fr minmax(320px, 420px);
  gap: 32px;
  align-items: center;
  padding: 36px 44px;
  border-radius: 16px;
  background:
    linear-gradient(180deg, #16161c 0%, #11111a 100%);
  border: 1px solid rgba(255,255,255,.04);
  overflow: hidden;
  isolation: isolate;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .55s ease, transform .55s ease;
}
.vip-v4 .v4-hero.in-view {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .vip-v4 .v4-hero { opacity: 1; transform: none; transition: none; }
}
.vip-v4 .v4-hero-pattern {
  position: absolute;
  inset: 0;
  width: 60%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
  opacity: .9;
  mask-image: linear-gradient(90deg, #000 60%, transparent 100%);
  -webkit-mask-image: linear-gradient(90deg, #000 60%, transparent 100%);
}
.vip-v4 .v4-hero-text {
  position: relative;
  z-index: 1;
  min-width: 0;
}
.vip-v4 .v4-hero-title {
  font-family: var(--font-display, 'Inter', sans-serif);
  font-size: clamp(28px, 3.4vw, 44px);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -.01em;
  color: #fff;
  margin: 0 0 10px;
}
.vip-v4 .v4-hero-sub {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-dim, #98a0b8);
  max-width: 56ch;
}
.vip-v4 .v4-hero-card {
  position: relative;
  z-index: 1;
  background: rgba(20,20,26,.85);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(255,255,255,.06);
  border-radius: 12px;
  padding: 18px 20px;
}
.vip-v4 .v4-hero-card-head {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 16px;
}
.vip-v4 .v4-hero-card-icon {
  width: 28px; height: 28px;
  display: grid; place-items: center;
}
.vip-v4 .v4-hero-card-fallback {
  color: var(--accent);
  font-family: var(--font-display);
  font-size: 22px;
}
.vip-v4 .v4-hero-card-title {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 700;
  color: #fff;
  letter-spacing: 0;
}
.vip-v4 .v4-hero-progress {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.vip-v4 .v4-hero-progress-row {
  display: flex; justify-content: space-between; align-items: baseline;
}
.vip-v4 .v4-hero-progress-label {
  font-size: 13px;
  color: var(--text-dim, #98a0b8);
}
.vip-v4 .v4-hero-progress-pct {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.vip-v4 .v4-hero-progress-bar {
  position: relative;
  height: 6px;
  background: rgba(255,255,255,.06);
  border-radius: 3px;
  overflow: hidden;
}
.vip-v4 .v4-hero-progress-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  background: linear-gradient(90deg, #6c4cff 0%, #8a73ff 50%, #a08aff 100%);
  border-radius: 3px;
  box-shadow: 0 0 12px rgba(124,92,255,.4);
  transition: width .8s cubic-bezier(.22,1,.36,1);
}

/* Hero responsive — stack on tablet, tighten gutters on mobile */
@media (max-width: 860px) {
  .vip-v4 .v4-hero {
    grid-template-columns: 1fr;
    padding: 28px 22px;
    gap: 22px;
  }
  .vip-v4 .v4-hero-pattern { width: 100%; opacity: .55; }
}
@media (max-width: 540px) {
  .vip-v4 .v4-hero { padding: 22px 18px; }
}

/* ============================================================
   2. SECTION HEAD — "VIP Ranks" / "Frequently Asked"
   ============================================================ */
.vip-v4 .v4-section {
  display: flex; flex-direction: column;
  gap: 16px;
}
.vip-v4 .v4-sec-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.vip-v4 .v4-sec-title {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  letter-spacing: .01em;
}
.vip-v4 .v4-sec-title svg { color: var(--accent); }

/* Arrow controls (mirror the Degen reference: small dark
   square buttons with rounded corners + chevron icons). */
.vip-v4 .v4-arrows {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.vip-v4 .v4-arrow {
  appearance: none; cursor: pointer;
  width: 32px; height: 32px;
  display: grid; place-items: center;
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.06);
  border-radius: 8px;
  color: var(--text-dim, #98a0b8);
  transition: background var(--t-base, .15s) ease, color var(--t-base, .15s) ease, border-color var(--t-base, .15s) ease;
}
.vip-v4 .v4-arrow:hover {
  background: rgba(255,255,255,.08);
  color: #fff;
  border-color: rgba(255,255,255,.12);
}

/* ============================================================
   3. TIER RAIL — horizontal scroll-snap row of 4 cards
   ============================================================ */
.vip-v4 .v4-tier-rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 18px;
  /* horizontal scroll only when there are too many tiers to fit */
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
  scrollbar-color: rgba(52,192,235,.35) transparent;
  /* `overflow-x: auto` forces the y-axis to clip at the padding edge
     (CSS spec — any non-visible value on one axis clips the other).
     Without vertical padding here, the per-card hover `translateY(-3px)`
     lift and the `box-shadow` underneath get cropped, making the lifted
     top of the card look like it slips behind the section above. The
     8px top room absorbs the lift; 22px bottom room gives the shadow
     space to render. */
  padding: 8px 0 22px;
}
.vip-v4 .v4-tier-rail::-webkit-scrollbar { height: 6px; }
.vip-v4 .v4-tier-rail::-webkit-scrollbar-thumb {
  background: rgba(52,192,235,.35);
  border-radius: 3px;
}
.vip-v4 .v4-tier-rail > * { scroll-snap-align: start; }
.vip-v4 .v4-tier-empty {
  padding: 24px;
  color: var(--text-mute, #6B7599);
  font-size: 13px;
}

/* When more than 4 cards, narrow them so 4 fit AND the rail
   becomes scrollable for the rest. */
@media (min-width: 861px) {
  .vip-v4 .v4-tier-rail {
    grid-auto-columns: minmax(280px, 1fr);
  }
}
@media (max-width: 860px) {
  .vip-v4 .v4-tier-rail {
    grid-auto-columns: clamp(220px, 65vw, 300px);
  }
}

/* Tier card — compact silhouette (rank name + state-aware footer
   only). The Reward subtitle + perks list were removed per operator
   brief, so the previous 430px min-height was leaving dead space
   below the body. 290px is enough room for the larger 104px rank
   icon in the art band plus the body content beneath. */
.vip-v4 .v4-tc {
  position: relative;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, #16161c 0%, #11111a 100%);
  border: 1px solid rgba(255,255,255,.05);
  border-radius: 14px;
  overflow: hidden;
  transition: transform var(--t-base, .15s) ease, box-shadow var(--t-base, .15s) ease, border-color var(--t-base, .15s) ease;
  min-height: 290px;
}
.vip-v4 .v4-tc:hover {
  transform: translateY(-3px);
  border-color: rgba(255,255,255,.10);
  box-shadow: 0 14px 28px rgba(0,0,0,.35);
}
/* Operator brief — flip the dim/bright logic. Past tiers (reached
   but not current) read as "completed, move on" → desaturated icon
   + muted text. Current and future tiers read as "this is what
   you're working toward" → full rank-color glow + green accent
   text. Matches the reference screenshot 1:1. */
.vip-v4 .v4-tc.is-current {
  border-color: rgba(34, 197, 94, .55);
  box-shadow: 0 0 0 1px rgba(34, 197, 94, .22), 0 14px 28px rgba(0,0,0,.35);
}
.vip-v4 .v4-tc.is-current .v4-tc-name,
.vip-v4 .v4-tc.is-locked  .v4-tc-name {
  color: #34c0eb;
}
/* Past tiers — desaturated, like "done, behind you". Greyscale on
   the SVG icon strips the rank colour entirely; the text and chip
   labels collapse to a muted palette. The card body keeps its dark
   backdrop so the ladder still reads as a continuous strip. */
.vip-v4 .v4-tc.is-reached:not(.is-current) .v4-tc-icon {
  filter: grayscale(.95) brightness(.55) drop-shadow(0 0 6px rgba(255,255,255,.04));
  opacity: .65;
}
.vip-v4 .v4-tc.is-reached:not(.is-current) .v4-tc-name {
  color: rgba(255,255,255,.55);
}
.vip-v4 .v4-tc.is-reached:not(.is-current) .v4-tc-sub {
  color: rgba(255,255,255,.30);
}

/* Top art band — the rank logo sits centred here on a dark vertical
   gradient. We layer a rank-coloured radial glow centred on the icon
   when JSX has wired `--rank-glow` (per-tier from window.rankColor).
   `color-mix` softens the glow to ~22% opacity so it's a subtle wash,
   not a halo. Falls back gracefully to the original purple-tinted
   ambient when --rank-glow is unset (e.g. cold-boot before tier data
   resolves). */
.vip-v4 .v4-tc-art {
  position: relative;
  height: 168px;
  display: grid;
  place-items: center;
  background:
    radial-gradient(60% 70% at 50% 50%,
      color-mix(in srgb, var(--rank-glow, #7c5cff) 22%, transparent) 0%,
      color-mix(in srgb, var(--rank-glow, #7c5cff) 8%, transparent) 45%,
      transparent 75%),
    radial-gradient(80% 100% at 50% 100%, rgba(124,92,255,.06), transparent 70%),
    linear-gradient(180deg, #1c1c24 0%, #14141c 100%);
  border-bottom: 1px solid rgba(255,255,255,.04);
}
/* Past tiers (reached, not current) — strip the rank-colored wash so
   the desaturated icon doesn't sit on a vibrant backdrop. */
.vip-v4 .v4-tc.is-reached:not(.is-current) .v4-tc-art {
  background:
    radial-gradient(80% 100% at 50% 100%, rgba(255,255,255,.02), transparent 70%),
    linear-gradient(180deg, #1c1c24 0%, #14141c 100%);
}
/* Soft drop-shadow on the rank icon — same rank colour, low alpha.
   Reads as the icon "glowing" rather than just sitting on a tinted
   backdrop. Default applied to all cards; past-tier rule above
   overrides via grayscale/opacity. */
.vip-v4 .v4-tc-icon {
  filter: drop-shadow(0 0 14px color-mix(in srgb, var(--rank-glow, #7c5cff) 38%, transparent));
}
/* Top art-band progress bar is hidden — the current-tier card now
   shows progress in its footer (pct + cumulative wager + bar) which
   matches the reference screenshot 1:1. Past/future tier cards no
   longer carry a redundant 100%/0% strip. */
.vip-v4 .v4-tc-bar { display: none; }
.vip-v4 .v4-tc-icon {
  display: grid; place-items: center;
  width: 130px; height: 130px;
}
.vip-v4 .v4-tc-icon-fallback {
  font-size: 88px;
}

/* Card body — compact: just the rank name + the state-aware footer.
   No subtitle, no perks list. Margin-top:auto on the footer slot
   pushes it to the bottom edge so the rank name sits flush under
   the art band. */
.vip-v4 .v4-tc-body {
  padding: 16px 18px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
}
.vip-v4 .v4-tc-pill {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 6px;
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.06);
  color: var(--text-dim, #98a0b8);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .02em;
}
.vip-v4 .v4-tc-pill.is-on {
  background: rgba(94,201,143,.10);
  border-color: rgba(94,201,143,.30);
  color: #34c0eb;
}
.vip-v4 .v4-tc-name {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 800;
  color: #fff;
  margin: 0;
  letter-spacing: -.01em;
}
.vip-v4 .v4-tc-range {
  font-size: 12.5px;
  color: var(--text-mute, #6B7599);
}
.vip-v4 .v4-tc-perks {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.vip-v4 .v4-tc-perks li {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  color: rgba(255,255,255,.85);
}
.vip-v4 .v4-tc-perks li svg { flex-shrink: 0; }

/* Pending claim button + current marker */
.vip-v4 .v4-tc-claim-wrap {
  position: relative;
  margin-top: auto;
  padding-top: 14px;
}
.vip-v4 .v4-tc-claim {
  appearance: none; cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 10px 16px;
  width: 100%;
  justify-content: center;
  background: var(--accent, #34c0eb);
  color: var(--on-accent, #1A1205);
  border: none;
  border-radius: 8px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  transition: background var(--t-base, .15s) ease, transform var(--t-base, .15s) ease;
}
.vip-v4 .v4-tc-claim:hover:not(:disabled) {
  background: var(--accent-bright, #6FD4F2);
  transform: translateY(-1px);
}
.vip-v4 .v4-tc-claim:disabled {
  opacity: .5; cursor: not-allowed;
}
.vip-v4 .v4-tc-current-marker {
  position: absolute;
  top: 14px; right: 14px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .14em;
  color: var(--accent);
  background: rgba(52,192,235,.10);
  border: 1px solid rgba(52,192,235,.32);
  padding: 3px 6px;
  border-radius: 4px;
  z-index: 2;
}

/* === Operator rebuild — corner status badge =====================
   Tiny lock / check icon tucked into the top-right corner of the
   art band. Replaces the inline "Locked / Unlocked" pill that used
   to sit in the body — matches the reference screenshot's compact
   silhouette. */
.vip-v4 .v4-tc-corner {
  position: absolute;
  top: 12px; right: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px; height: 24px;
  background: rgba(0, 0, 0, .35);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 50%;
  color: rgba(255, 255, 255, .65);
  z-index: 2;
}
.vip-v4 .v4-tc.is-reached:not(.is-current) .v4-tc-corner {
  color: #34c0eb;
  border-color: rgba(94, 201, 143, .22);
}
.vip-v4 .v4-tc.is-current .v4-tc-corner {
  color: rgba(255, 255, 255, .85);
  border-color: rgba(255, 255, 255, .15);
}

/* "Reward" subtitle below the tier name (matches the screenshot). */
.vip-v4 .v4-tc-sub {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  color: rgba(255, 255, 255, .55);
  margin-top: -6px;
  margin-bottom: 4px;
}

/* === State-aware footer slot ====================================
   Mounted at the bottom of .v4-tc-body (margin-top:auto pushes it
   to the card's last row). Three flavors driven by the parent
   modifier classes:
     • Past   → "Completed" disabled chip
     • Current → progress strip (% + cumulative + thin bar)
     • Future → "Claim Reward" gold CTA (live or teaser)              */
.vip-v4 .v4-tc-foot {
  margin-top: auto;
  padding-top: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.vip-v4 .v4-tc-foot--progress {
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 10px;
  padding: 12px 14px;
  margin-top: auto;
}
.vip-v4 .v4-tc-prog-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 700;
  margin-bottom: 8px;
}
.vip-v4 .v4-tc-prog-pct  { color: #34c0eb; }
.vip-v4 .v4-tc-prog-xp   { color: rgba(255, 255, 255, .85); }
.vip-v4 .v4-tc-prog-bar {
  height: 5px;
  background: rgba(255, 255, 255, .06);
  border-radius: 3px;
  overflow: hidden;
}
.vip-v4 .v4-tc-prog-fill {
  height: 100%;
  background: linear-gradient(90deg, #2dc88a 0%, #34c0eb 100%);
  border-radius: 3px;
  transition: width .7s cubic-bezier(.22, 1, .36, 1);
}

/* Generic CTA primitive used by Completed / Claim / Future slots. */
.vip-v4 .v4-tc-cta {
  appearance: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 11px 14px;
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 10px;
  background: rgba(255, 255, 255, .04);
  color: rgba(255, 255, 255, .55);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  transition: background var(--t-base, .15s) ease, color var(--t-base, .15s) ease, border-color var(--t-base, .15s) ease;
}
.vip-v4 .v4-tc-cta:disabled { cursor: default; }
/* Past — completed chip stays neutral grey, no hover. */
.vip-v4 .v4-tc-cta.is-completed {
  background: rgba(255, 255, 255, .03);
  color: rgba(255, 255, 255, .45);
}
/* Future — "Claim Reward" teaser (disabled). Reads as the next step
   in the ladder, but doesn't pretend to be actionable. */
.vip-v4 .v4-tc-cta.is-locked-cta {
  background: rgba(255, 255, 255, .04);
  border-color: rgba(255, 255, 255, .08);
  color: rgba(255, 255, 255, .68);
}
/* Live claim CTA (when pendingClaim is wired). Gold accent — the
   one moment in the ladder where the player can actually act. */
.vip-v4 .v4-tc-cta.is-claim {
  background: var(--accent, #34c0eb);
  border-color: var(--accent, #34c0eb);
  color: var(--on-accent, #1A1205);
}
.vip-v4 .v4-tc-cta.is-claim:hover:not(:disabled) {
  background: var(--accent-bright, #6FD4F2);
  transform: translateY(-1px);
}
.vip-v4 .v4-tc-cta.is-claim:disabled {
  opacity: .55;
}

/* ============================================================
   4. RANK BONUSES carousel — single full-width card with
   pagination dots top-left + 2-column content (text + gem).
   ============================================================ */
.vip-v4 .v4-rb {
  position: relative;
  background: linear-gradient(180deg, #16161c 0%, #11111a 100%);
  border: 1px solid rgba(255,255,255,.05);
  border-radius: 16px;
  padding: 28px 36px 32px;
  overflow: hidden;
  isolation: isolate;
}
.vip-v4 .v4-rb::after {
  content: "";
  position: absolute;
  right: -8%; top: 50%;
  width: 60%; height: 200%;
  transform: translateY(-50%);
  background: radial-gradient(closest-side, rgba(124,92,255,.10), transparent 70%);
  pointer-events: none;
  z-index: 0;
}
/* Header row — dots on the left, "X / N" counter on the right. The
   counter is the unambiguous "there are more slides" affordance for
   users who didn't notice the small dots; combined with the always-
   visible chevron prev/next buttons below it covers every signal. */
.vip-v4 .v4-rb-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
  position: relative;
  z-index: 2;
}
.vip-v4 .v4-rb-counter {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  color: rgba(255,255,255,.55);
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.06);
  font-variant-numeric: tabular-nums;
}
.vip-v4 .v4-rb-dots {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  position: relative;
  z-index: 1;
}
.vip-v4 .v4-rb-dot {
  appearance: none; cursor: pointer;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: rgba(255,255,255,.18);
  border: none;
  padding: 0;
  transition: background var(--t-base, .15s) ease, width var(--t-base, .15s) ease;
}
.vip-v4 .v4-rb-dot.is-active {
  background: var(--accent, #34c0eb);
  width: 18px; border-radius: 4px;
}
.vip-v4 .v4-rb-dot:hover { background: rgba(255,255,255,.32); }
.vip-v4 .v4-rb-dot.is-active:hover { background: var(--accent-bright, #6FD4F2); }

/* Prev / Next chevron buttons — vertical-center pinned at the
   left/right edges. Always visible (not just on hover) so the
   "multi-slide" nature is obvious at a glance. Touch-friendly hit
   area; subtle dark capsule that matches the panel without competing
   with the title or gem art. */
.vip-v4 .v4-rb-nav {
  appearance: none;
  cursor: pointer;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 50%;
  color: rgba(255, 255, 255, .80);
  z-index: 3;
  transition: background var(--t-base, .15s) ease, color var(--t-base, .15s) ease,
              border-color var(--t-base, .15s) ease, transform var(--t-base, .15s) ease;
}
.vip-v4 .v4-rb-nav:hover:not(:disabled) {
  background: rgba(255, 255, 255, .10);
  color: #fff;
  border-color: rgba(255, 255, 255, .14);
}
.vip-v4 .v4-rb-nav:active:not(:disabled) { transform: translateY(calc(-50% + 1px)); }
.vip-v4 .v4-rb-nav:disabled {
  opacity: .35;
  cursor: default;
}
.vip-v4 .v4-rb-nav-prev { left: 12px; }
.vip-v4 .v4-rb-nav-next { right: 12px; }

.vip-v4 .v4-rb-content {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 32px;
  /* Pointer-drag affordance — grab cursor on hover, grabbing while
     a drag is in progress. `touch-action: pan-y` lets vertical
     page scroll work normally while letting us capture horizontal
     gestures for slide navigation. `user-select: none` prevents
     text selection from being created by the drag. */
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
  will-change: transform;
}
.vip-v4 .v4-rb-content.is-dragging { cursor: grabbing; }
.vip-v4 .v4-rb-text {
  max-width: 560px;
}
.vip-v4 .v4-rb-title {
  margin: 0 0 12px;
  font-family: var(--font-display);
  font-size: clamp(24px, 2.6vw, 34px);
  font-weight: 800;
  color: #fff;
  letter-spacing: -.01em;
  line-height: 1.1;
}
.vip-v4 .v4-rb-sub {
  margin: 0 0 20px;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--text-dim, #98a0b8);
}
.vip-v4 .v4-rb-claim {
  appearance: none; cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.08);
  color: #fff;
  border-radius: 8px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  transition: background var(--t-base, .15s) ease, border-color var(--t-base, .15s) ease, transform var(--t-base, .15s) ease;
}
.vip-v4 .v4-rb-claim:hover:not(:disabled) {
  background: var(--accent, #34c0eb);
  color: var(--on-accent, #1A1205);
  border-color: var(--accent, #34c0eb);
  transform: translateY(-1px);
}
.vip-v4 .v4-rb-claim:disabled { opacity: .55; cursor: not-allowed; }
.vip-v4 .v4-rb-art {
  display: grid;
  place-items: center;
}

@media (max-width: 860px) {
  .vip-v4 .v4-rb { padding: 24px 22px 26px; }
  .vip-v4 .v4-rb-content {
    grid-template-columns: 1fr;
    gap: 18px;
  }
  .vip-v4 .v4-rb-art { justify-self: center; }
  /* Hide the side chevron buttons on mobile — the 22 px gutters
     can't fit a 34 px circle without overlapping the title/text.
     Touch swipe is the natural mobile gesture and is fully wired;
     the dots + "X / N" counter still surface the multi-slide
     state, so removing the arrows loses no functionality here. */
  .vip-v4 .v4-rb-nav { display: none; }
}

/* ============================================================
   5. FAQ — 2-column grid, dark rounded rows with chevron toggle
   ============================================================ */
.vip-v4 .v4-faq-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}
@media (max-width: 720px) {
  .vip-v4 .v4-faq-grid { grid-template-columns: 1fr; }
}
.vip-v4 .v4-faq-row {
  background: linear-gradient(180deg, #16161c 0%, #11111a 100%);
  border: 1px solid rgba(255,255,255,.05);
  border-radius: 12px;
  overflow: hidden;
  transition: border-color var(--t-base, .15s) ease, background var(--t-base, .15s) ease;
}
.vip-v4 .v4-faq-row.is-open {
  border-color: rgba(52,192,235,.25);
  background: linear-gradient(180deg, #1a1a22 0%, #14141c 100%);
}
.vip-v4 .v4-faq-row .v4-faq-head {
  appearance: none; cursor: pointer;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 22px;
  background: transparent;
  border: 0;
  text-align: left;
  color: rgba(255,255,255,.92);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
  transition: color var(--t-base, .15s) ease;
}
.vip-v4 .v4-faq-row .v4-faq-head:hover { color: #fff; }
.vip-v4 .v4-faq-row.is-open .v4-faq-head { color: #fff; }
.vip-v4 .v4-faq-q { min-width: 0; }
.vip-v4 .v4-faq-chev {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-dim, #98a0b8);
  transition: transform var(--t-base, .15s) cubic-bezier(.4,.8,.3,1.1), color var(--t-base, .15s) ease;
}
.vip-v4 .v4-faq-row.is-open .v4-faq-chev {
  transform: rotate(180deg);
  color: var(--accent);
}
.vip-v4 .v4-faq-body-clip {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .35s cubic-bezier(.22,1,.36,1);
}
.vip-v4 .v4-faq-row.is-open .v4-faq-body-clip {
  grid-template-rows: 1fr;
}
.vip-v4 .v4-faq-body {
  overflow: hidden;
  padding: 0 22px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-dim, #98a0b8);
}
.vip-v4 .v4-faq-row.is-open .v4-faq-body { padding: 4px 22px 18px; }

/* ============================================================
   6. Sign-out CTA bar
   ============================================================ */
.vip-v4 .v4-cta {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 22px;
  align-items: center;
  background: linear-gradient(180deg, #16161c 0%, #11111a 100%);
  border: 1px solid rgba(52,192,235,.22);
  border-radius: 16px;
  padding: 24px 28px;
}
.vip-v4 .v4-cta-text h3 {
  margin: 0 0 4px;
  font-family: var(--font-display);
  font-size: 18px;
  color: #fff;
  font-weight: 800;
  letter-spacing: -.01em;
}
.vip-v4 .v4-cta-text p {
  margin: 0;
  font-size: 13px;
  color: var(--text-dim, #98a0b8);
}
.vip-v4 .v4-cta-btn {
  appearance: none; cursor: pointer;
  background: var(--accent, #34c0eb);
  color: var(--on-accent, #1A1205);
  border: none;
  border-radius: 10px;
  padding: 12px 20px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .06em;
  transition: background var(--t-base, .15s) ease, transform var(--t-base, .15s) ease;
}
.vip-v4 .v4-cta-btn:hover {
  background: var(--accent-bright, #6FD4F2);
  transform: translateY(-1px);
}
@media (max-width: 540px) {
  .vip-v4 .v4-cta { grid-template-columns: 1fr; }
}

/* ============================================================
   End of VIP V4 rebuild
   ============================================================ */

/* ==================================================================
   Money typography — single source of truth.

   The site previously rendered every money amount with
   var(--font-display) (Sora). Sora is a chunky display face with
   proportional figures; on bet-pill / topbar sizes the numerals
   read as cramped and the `$` reads as a logotype rather than a
   currency mark. Operator wants the cleaner Inter look from the
   reference screenshot ($1,234.56 with vertical-stroke $ and
   conventional digit shapes).

   This block is the LAST `font-family` declaration for every money
   class on the site, so it wins over the existing display-font
   rules in styles.css / earlier in this file. To swap the money
   typeface in the future, change `var(--font-ui)` here in one place.

   `tabular-nums` + `tnum` lock the digit widths so a live-updating
   balance doesn't shift horizontally when 1s and 4s rotate. The
   small negative letter-spacing tightens the column slightly to
   match the reference screenshot.
   ================================================================== */
.bal-val,
.bal-val-playing,
.bd-amt,
.bd-head-amt,
.bd-usd,
.bc-pay,
.bc-meta,
.gp-bet-result,
.gp-stat .v,
.bj-side-chip-amount,
.lsw-stat-v,
.lsw-race-amt,
.bm-stat-v,
.bm-v2-stat-v,
.bm-v2-stat-v-stack,
.profile-stat-v,
.tx-card-amt,
.tx-card-bal,
.tx-bal,
.vr-bal,
.wr2-stat-v,
.wr2-prize-amt,
.wr2-mine-stat-v,
.wr2-mine-rank,
.wr2-strip-v,
.wr2-cd-v,
.wr2-tile-v,
.wr2-table-wagered,
.wr2-table-prize,
.wr2-viewer-rank,
.wr2-viewer-v,
.dw-amount,
.dw-coin-bal,
.dw-vault-chip-value,
.rs-amount,
.rpc-pot,
.rpc-last,
.pm-v2-stat-v,
.pm-v2-tip-amt,
.lb-row .amt,
.rl-box-mybet-amt,
.rl-box-mybet-win,
.rl-box-list-amt,
.rl-box-mult,
.ft-coin-usd,
.pf-v2-rl-id,
.activity-row .mono {
  font-family: var(--font-ui), system-ui, -apple-system, "Segoe UI", sans-serif !important;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  letter-spacing: -0.005em;
}

/* ==================================================================
   CRASH GAME v2 — Stake-style rebuild. Bet panel on the LEFT (Manual /
   Auto tabs, Bet Amount, Cashout At with stepper, Profit on Win, Bet
   button, players + stake totals, round bets feed). Game canvas on the
   RIGHT with a single header row carrying the network-status indicator
   (left) and the 8-pill round history (right).
   ================================================================== */

/* Canvas card — flex column. Height is driven by an INLINE
   style.height set in JS (CrashGame resize-sync useEffect) from
   .gp-panel.scrollHeight, so the card always matches the panel's
   intrinsic content height. No `height: 100%` here — that created
   a circular grid-cell→row→100% resolution chain that left the
   stage shorter than the visible card on some browsers. With a
   definite inline pixel height, flex-1 on .crash-v2-canvas-stage
   resolves cleanly and the canvas fills end-to-end. */
.crash-v2-canvas {
  position: relative;
  display: flex !important;
  flex-direction: column;
  align-items: stretch;
  align-self: stretch;
  padding: 14px;
  gap: 8px;
}
.crash-v2-canvas-stage {
  flex: 1 1 0;
  position: relative;
  min-height: 0;
}
.crash-v2-canvas-stage canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.crash-v2-canvas-stage .crash-v2-loading {
  /* The loader inherits the stage as its containing block — already
     `position: absolute; inset: 0;` from its own rule. */
}
.crash-v2-canvas-head {
  /* Normal flex child — sits at the top of the card, sized to its
     own content. The stage below takes the remainder via flex 1. */
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
/* (canvas styling consolidated above into `.crash-v2-canvas-stage canvas`) */

.crash-v2-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  color: var(--text-secondary);
  white-space: nowrap;
}
.crash-v2-status-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--text-tertiary);
}
.crash-v2-status.is-on .crash-v2-status-dot {
  background: #4ade80;
  box-shadow: 0 0 0 0 rgba(74, 222, 128, .6);
  animation: crashStatusPulse 1.8s ease-out infinite;
}
.crash-v2-status.is-on { color: var(--text-primary); }
@keyframes crashStatusPulse {
  0%   { box-shadow: 0 0 0 0 rgba(74, 222, 128, .55); }
  70%  { box-shadow: 0 0 0 7px rgba(74, 222, 128, 0); }
  100% { box-shadow: 0 0 0 0 rgba(74, 222, 128, 0); }
}

.crash-v2-history {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.crash-v2-history::-webkit-scrollbar { display: none; }
.crash-v2-history-pill {
  appearance: none;
  border: 1px solid var(--border-subtle);
  background: var(--bg-3);
  color: var(--text-secondary);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .02em;
  padding: 4px 10px;
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  transition: transform .12s ease, border-color .15s ease, color .15s ease;
}
.crash-v2-history-pill:hover {
  transform: translateY(-1px);
  border-color: rgba(52, 192, 235, .35);
  color: var(--text-primary);
}
/* Tone-coded — gold for solid wins (≥ 2x), magenta for instabusts. */
.crash-v2-history-pill.tone-low  { color: #f87171; border-color: rgba(248, 113, 113, .25); }
.crash-v2-history-pill.tone-mid  { color: var(--accent); border-color: rgba(52, 192, 235, .3); }
.crash-v2-history-pill.tone-high { color: var(--accent);
  border-color: rgba(52, 192, 235, .55);
  background: rgba(52, 192, 235, .1);
}

/* ==== Bet panel — Manual/Auto tabs ==== */
.crash-v2-modes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  padding: 4px;
  background: var(--bg-3);
  border-radius: var(--radius-pill);
  margin-bottom: 4px;
}
.crash-v2-mode {
  appearance: none; border: 0; cursor: pointer;
  padding: 9px 12px;
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  border-radius: var(--radius-pill);
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.crash-v2-mode:hover:not(.on) { color: var(--text-primary); }
.crash-v2-mode.on {
  background: var(--bg-elevated);
  color: var(--text-primary);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .04) inset;
}

/* ==== Cashout At — number input with chevron stepper ==== */
.crash-v2-cashout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 6px;
  background: var(--bg-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  padding: 4px;
  transition: border-color var(--dur-base) var(--ease-standard);
}
.crash-v2-cashout:focus-within { border-color: var(--accent); }
.crash-v2-cashout input {
  background: transparent;
  border: 0;
  outline: 0;
  padding: 6px 8px;
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  min-width: 0;
}
.crash-v2-cashout input::placeholder { color: var(--text-tertiary); }
.crash-v2-cashout-steppers {
  display: inline-flex;
  align-items: stretch;
  gap: 4px;
}
.crash-v2-cashout-steppers button {
  appearance: none;
  border: 0;
  cursor: pointer;
  width: 30px;
  background: var(--bg-elevated);
  color: var(--text-secondary);
  border-radius: var(--radius-xs);
  display: grid;
  place-items: center;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.crash-v2-cashout-steppers button:hover {
  background: var(--bg-2);
  color: var(--text-primary);
}

/* ==== Bet button — full-width gold pill (matches reference's lone CTA) ==== */
.crash-v2-bet {
  width: 100%;
  padding: 13px 16px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: .02em;
  text-transform: none;            /* keep "Bet (Next Round)" mixed case per ref */
}
.crash-v2-cashout {
  /* nothing extra */
}

/* ==== My-bets list (player's own stack) ==== */
.crash-v2-mybets {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 4px;
  max-height: 220px;
  overflow-y: auto;
  padding-right: 4px;
}
.crash-v2-mybet {
  padding: 8px 10px;
  background: var(--bg-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.crash-v2-mybet-head {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-tertiary);
  letter-spacing: .02em;
}
.crash-v2-cashout {
  /* duplicate selector — already styled above; keeps grid honest */
}
.crash-v2-mybet-chip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 5px 10px;
  background: var(--bg-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
}
.crash-v2-mybet-chip .k { color: var(--text-tertiary); }
.crash-v2-mybet-chip .v { font-variant-numeric: tabular-nums; font-weight: 700; }
.crash-v2-mybet-chip.is-win  .v { color: var(--green); }
.crash-v2-mybet-chip.is-loss .v { color: #f87171; }

/* Cash Out button — prominent gold pill on the active row. */
.crash-v2-cashout {
  /* (cashout input wrapper above) */
}
button.crash-v2-cashout,
.gp-bet.crash-v2-cashout {
  width: 100%;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 800;
  font-family: var(--font-display);
  background: var(--accent);
  color: var(--accent-contrast);
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-transform: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  letter-spacing: .02em;
  transition: filter .12s ease, transform .12s ease;
}
button.crash-v2-cashout:hover,
.gp-bet.crash-v2-cashout:hover {
  filter: brightness(1.05);
  transform: translateY(-1px);
}

/* ==== Phase status line (Round starts in 5.0s / Crashed at 1.41x) ==== */
.crash-v2-status-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 10px;
  background: var(--bg-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 12px;
}
.crash-v2-status-line .k { color: var(--text-tertiary); letter-spacing: .04em; text-transform: uppercase; font-size: 10px; }
.crash-v2-status-line .v { color: var(--text-primary); font-weight: 700; font-variant-numeric: tabular-nums; }
.crash-v2-status-line .v.is-loss { color: #f87171; }

/* ==== Players + stake totals row (mirrors the reference) ==== */
.crash-v2-totals {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  background: transparent;
  border-top: 1px solid var(--border-subtle);
  border-bottom: 1px solid var(--border-subtle);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--text-secondary);
}
.crash-v2-totals-cell {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-variant-numeric: tabular-nums;
}
.crash-v2-totals-stake {
  color: var(--accent);
}
.crash-v2-totals-coin {
  display: inline-grid;
  place-items: center;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: linear-gradient(135deg, #4ade80, #1a8e58);
  color: #061712;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 800;
}

/* ==== Round bets feed (collapses to a clean blank slate when empty) ==== */
.crash-v2-feed {
  flex: 1 1 auto;
  min-height: 80px;
  background: var(--bg-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  overflow-y: auto;
  max-height: 220px;
}
.crash-v2-feed-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 8px;
  align-items: center;
  padding: 4px 0;
  font-variant-numeric: tabular-nums;
}
.crash-v2-feed-row .u { color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crash-v2-feed-row .a { color: var(--text-primary); }
.crash-v2-feed-row .m { color: var(--text-tertiary); }
.crash-v2-feed-row .m.is-on { color: var(--accent); font-weight: 700; }

/* Mobile (.gp stacks at <=760px) — tighten paddings + history overflow. */
@container main (max-width: 760px) {
  .crash-v2-canvas { padding: 10px; gap: 8px; }
  .crash-v2-canvas canvas { min-height: 220px; }
  .crash-v2-canvas-head {
    flex-wrap: nowrap;
    gap: 8px;
  }
  /* Operator rebuild — phone-portrait history row matches the
     reference screenshot 1:1: four uniform gray pills aligned to the
     right edge, no tone coloring, fits one row alongside the Stable
     Connection chip without wrapping. */
  .crash-v2-history {
    width: auto;
    flex: 0 0 auto;
    gap: 4px;
    justify-content: flex-end;
    overflow: hidden;
  }
  .crash-v2-history-pill,
  .crash-v2-history-pill.tone-low,
  .crash-v2-history-pill.tone-mid,
  .crash-v2-history-pill.tone-high {
    color: var(--text-secondary);
    background: var(--bg-3);
    border-color: var(--border-subtle);
    padding: 4px 8px;
    border-radius: 6px;
    font-size: 11px;
    font-weight: 600;
  }
  .crash-v2-history-pill:hover,
  .crash-v2-history-pill.tone-low:hover,
  .crash-v2-history-pill.tone-mid:hover,
  .crash-v2-history-pill.tone-high:hover {
    transform: none;
    color: var(--text-primary);
    border-color: var(--border-default);
    background: var(--bg-3);
  }
  /* Match the reference card proportion. Phone-portrait crash card
     is a shorter rectangle than the previous 4:3 — operator brief
     "reduce the crash canvas a bit" — so we drop to ~5:4 with a
     lower min-height. The canvas-stage is flex-1 inside the card so
     setting the card's aspect-ratio gives both the head row and the
     chart their share. */
  .crash-v2-canvas {
    aspect-ratio: 5 / 4;
    min-height: 240px;
  }
  .crash-v2-canvas-stage canvas { min-height: 0; }
}

/* ==================================================================
   CRASH AUTO-BET PANEL — Stake-style controls. Number-of-bets input
   with an infinity chip on the right, Show Players toggle button,
   Advanced Settings disclosure with a iOS-style switch, Profit-on-Win
   strip, and a Start/Stop Autobet primary button (gold accent).
   ================================================================== */

/* Number of Bets — number input + ∞ chip combo. Mirrors the cashout
   stepper visual (same outer shell) so the panel reads cohesively. */
.crash-v2-numbets {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 6px;
  background: var(--bg-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  padding: 4px;
  transition: border-color var(--dur-base) var(--ease-standard);
}
.crash-v2-numbets:focus-within { border-color: var(--accent); }
.crash-v2-numbets input {
  background: transparent;
  border: 0;
  outline: 0;
  padding: 6px 8px;
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  min-width: 0;
}
.crash-v2-numbets input:disabled { opacity: .55; cursor: not-allowed; }
.crash-v2-numbets-inf {
  appearance: none;
  border: 0;
  cursor: pointer;
  width: 36px;
  background: var(--bg-elevated);
  color: var(--text-secondary);
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  display: grid;
  place-items: center;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.crash-v2-numbets-inf:hover { color: var(--text-primary); background: var(--bg-2); }
.crash-v2-numbets-inf.is-on {
  color: var(--accent-contrast);
  background: var(--accent);
}
.crash-v2-numbets-inf:disabled { opacity: .55; cursor: not-allowed; }

/* Show Players — full-width chip button. Toggles the round bets
   feed below; "is-on" shows muted "Hide Players" copy. */
.crash-v2-show-players {
  appearance: none;
  cursor: pointer;
  border: 1px solid var(--border-default);
  background: var(--bg-3);
  color: var(--text-secondary);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .02em;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard);
}
.crash-v2-show-players:hover {
  border-color: rgba(52, 192, 235, .3);
  color: var(--text-primary);
}
.crash-v2-show-players.is-on {
  color: var(--text-primary);
}

/* Advanced Settings — label + iOS-style toggle + collapsible body. */
.crash-v2-advanced {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.crash-v2-advanced-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.crash-v2-advanced-label {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  color: var(--text-secondary);
  letter-spacing: .02em;
}
.crash-v2-toggle {
  appearance: none;
  cursor: pointer;
  width: 36px;
  height: 20px;
  border-radius: 999px;
  background: var(--bg-3);
  border: 1px solid var(--border-default);
  position: relative;
  transition: background var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard);
}
.crash-v2-toggle-knob {
  position: absolute;
  top: 2px; left: 2px;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--text-tertiary);
  transition: left var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard);
}
.crash-v2-toggle.is-on {
  background: var(--accent);
  border-color: var(--accent);
}
.crash-v2-toggle.is-on .crash-v2-toggle-knob {
  left: 18px;
  background: var(--accent-contrast);
}
.crash-v2-advanced-body {
  padding: 8px 10px;
  background: var(--bg-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

/* Profit On Win — bottom strip above the Start Autobet button.
   Sits in a thin bordered chip so the action button below reads as
   a clear separate primary element. */
.crash-v2-profit-strip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 14px;
  background: transparent;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-secondary);
}
.crash-v2-profit-k {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--text-tertiary);
  text-transform: none;
}
.crash-v2-profit-coin {
  display: inline-grid;
  place-items: center;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: linear-gradient(135deg, #4ade80, #1a8e58);
  color: #061712;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 800;
}
.crash-v2-profit-v {
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

/* Start Autobet button — same chrome as the manual Bet button, with
   a "running" state that flips to a stop-red when the loop is on. */
.crash-v2-autobet.is-running {
  background: linear-gradient(135deg, #f87171, #c0263d);
  color: #fff;
}
.crash-v2-autobet.is-running:hover {
  filter: brightness(1.05);
}

/* ==================================================================
   CRASH WAITING-PHASE LOADER — DOM overlay positioned over the canvas
   while phase=betting. The headline is the loader: a CSS gradient
   mask sweeps a bright band across the text continuously, reading as
   "loading" to the player. Pure CSS, runs on the compositor.
   ================================================================== */
.crash-v2-loading {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 2;
  text-align: center;
  padding: 0 16px;
}
.crash-v2-loading-text {
  font-family: var(--font-display);
  font-size: clamp(20px, 3.4vw, 32px);
  font-weight: 800;
  letter-spacing: -.005em;
  font-variant-numeric: tabular-nums;
  /* Skeleton-shimmer gradient — a bright pulse sweeps across a dim
     base. background-clip:text + transparent fill paints the
     gradient onto the glyphs themselves so the text reads as the
     loading indicator (matches the customer reference). */
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, .35) 0%,
    rgba(255, 255, 255, .35) 35%,
    rgba(255, 255, 255, 1)   50%,
    rgba(255, 255, 255, .35) 65%,
    rgba(255, 255, 255, .35) 100%
  );
  background-size: 250% 100%;
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: crashLoadingShimmer 2.4s linear infinite;
  white-space: nowrap;
}
@keyframes crashLoadingShimmer {
  from { background-position: 200% 0; }
  to   { background-position: -100% 0; }
}
.crash-v2-loading-sub {
  margin-top: 8px;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  color: rgba(255, 255, 255, .45);
  letter-spacing: .01em;
}
@media (prefers-reduced-motion: reduce) {
  .crash-v2-loading-text {
    animation: none;
    background: none;
    -webkit-text-fill-color: rgba(255, 255, 255, .85);
    color: rgba(255, 255, 255, .85);
  }
}

/* ==================================================================
   PLINKO BET PANEL v2 — Stake-style controls. Risk becomes a styled
   <select> dropdown; Pegs (rows) becomes a range slider with tick
   marks + endpoint labels. Both inherit the site's gold-accent
   design tokens so the panel still reads as part of SpinArmory.
   ================================================================== */

/* ---- Field-label tweak: when the inner <span> is the value (Pegs ·
        12) we need the label row to space them. The default .gp-field
        label has flex; reuse it but make sure the value chip aligns
        right. The selector targets only the label children we add. */
.gp-field > label .plk-slider-value {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  padding: 2px 8px;
  background: var(--accent-soft);
  border-radius: 999px;
}

/* ---- Risk select ----
   Now uses the canonical `select.input` rule from styles.css (inline-
   SVG chevron baked into the bg, color-scheme:dark for the OS option
   list, brand-amber focus ring, etc). The bespoke .plk-select wrapper
   that lived here was removed so Plinko reads as part of the same
   dropdown family as KYC modal / admin settings / profile prefs. */

/* ---- Pegs slider ----
   The track uses `--plk-slider-pct` (set inline) to draw the gold-
   filled portion behind the thumb. Tick marks sit on top and switch
   to the accent color as the thumb passes them. Endpoint labels
   (8 .. 16) sit beneath the track in a grid. */
.plk-slider {
  position: relative;
  padding: 6px 0 22px;
  --plk-slider-pct: 50%;
}
.plk-slider input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 22px;
  background: transparent;
  outline: 0;
  margin: 0;
  position: relative;
  z-index: 2;
  cursor: pointer;
}
.plk-slider[aria-disabled="true"] input[type="range"] {
  opacity: .55;
  cursor: not-allowed;
}
/* Track — dark base + gold-filled left side via inline --plk-slider-pct. */
.plk-slider input[type="range"]::-webkit-slider-runnable-track {
  height: 6px;
  background: linear-gradient(
    to right,
    var(--accent) 0%,
    var(--accent) var(--plk-slider-pct, 50%),
    var(--bg-3) var(--plk-slider-pct, 50%),
    var(--bg-3) 100%
  );
  border-radius: 999px;
  border: 1px solid var(--border-subtle);
}
.plk-slider input[type="range"]::-moz-range-track {
  height: 6px;
  background: var(--bg-3);
  border-radius: 999px;
  border: 1px solid var(--border-subtle);
}
.plk-slider input[type="range"]::-moz-range-progress {
  height: 6px;
  background: var(--accent);
  border-radius: 999px;
}
/* Thumb — circular gold disc with subtle ring + lift-on-grab. */
.plk-slider input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg-1, #04060e);
  box-shadow: 0 0 0 1px var(--accent),
              0 4px 10px rgba(52, 192, 235, .45);
  margin-top: -7px;
  cursor: grab;
  transition: transform var(--dur-fast) var(--ease-standard),
              box-shadow var(--dur-base) var(--ease-standard);
}
.plk-slider input[type="range"]:active::-webkit-slider-thumb {
  cursor: grabbing;
  transform: scale(1.08);
}
.plk-slider input[type="range"]::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg-1, #04060e);
  box-shadow: 0 0 0 1px var(--accent),
              0 4px 10px rgba(52, 192, 235, .45);
  cursor: grab;
}
.plk-slider input[type="range"]:focus::-webkit-slider-thumb {
  box-shadow: 0 0 0 3px var(--accent-soft),
              0 0 0 1px var(--accent),
              0 4px 10px rgba(52, 192, 235, .45);
}
/* Tick row — 5 dots positioned across the track. Pointer-events off
   so the thumb still claims clicks. The "is-on" tone signals which
   ladder steps are at-or-below the current value. */
.plk-slider-ticks {
  position: absolute;
  left: 8px;
  right: 8px;
  top: 18px;
  height: 6px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  pointer-events: none;
  z-index: 1;
}
.plk-slider-tick {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--text-tertiary);
  opacity: .6;
}
.plk-slider-tick.is-on {
  background: var(--bg-1, #04060e);   /* punches a dark hole into the gold-filled track */
  opacity: 1;
}
/* Endpoint labels — same horizontal grid as the ticks. */
.plk-slider-labels {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  color: var(--text-tertiary);
  letter-spacing: .04em;
  font-variant-numeric: tabular-nums;
  padding: 0 2px;
}

/* ─── Footer Responsible-Gaming row ──────────────────────────────── */
.ft-resp-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ft-resp-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.ft-resp-logo {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  transition: opacity .15s ease;
}
.ft-resp-logo:hover { opacity: .85; }
.ft-resp-age {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 6px;
  background: #ef4444;
  color: #fff;
  font-weight: 800;
  font-family: var(--font-display, sans-serif);
  font-size: 12px;
  letter-spacing: .04em;
}

/* Bottom-of-footer responsible-gaming strip. Sits to the right of
   the licensing paragraph (`.ft-legal-copy`), aligned with the
   legal copy's vertical center on desktop; stacks under it on
   narrow viewports. Hosts the operator-supplied gambleaware.jpg +
   gamtalk.png plus the existing red `18+` chip. */
.ft-legal-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}
.ft-legal-copy {
  flex: 1;
  min-width: 0;
  margin: 0;
}
.ft-resp-bottom {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}
.ft-resp-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding: 4px 6px;
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 6px;
  transition: background .15s ease, border-color .15s ease, opacity .15s ease;
}
.ft-resp-badge:hover {
  background: rgba(255, 255, 255, .08);
  border-color: rgba(255, 255, 255, .14);
  opacity: 1;
}
.ft-resp-badge img {
  display: block;
  height: 32px;
  width: auto;
  object-fit: contain;
}

@media (max-width: 720px) {
  .ft-legal-row {
    flex-direction: column;
    align-items: flex-start;
  }
  .ft-resp-bottom {
    width: 100%;
    justify-content: flex-start;
  }
}

/* ─── User-facing KYC status + upload tiles ──────────────────────── */
.kyc-status-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  border-radius: var(--radius-sm);
  margin-bottom: 10px;
  border: 1px solid var(--line-soft);
  background: var(--panel);
}
.kyc-status-glyph {
  width: 38px; height: 38px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--font-display, sans-serif);
  font-size: 14px;
  background: rgba(255,255,255,.05);
  color: var(--text-mute);
  flex-shrink: 0;
}
.kyc-status-kicker {
  font-family: var(--font-display, sans-serif);
  font-size: 12px;
  letter-spacing: .08em;
  color: var(--text-mute);
}
.kyc-status-label {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  margin-top: 2px;
}
.kyc-status-reason {
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.4;
}
.kyc-status-reason strong { color: var(--text); margin-right: 4px; }

/* Verified */
.kyc-status-ok {
  border-color: rgba(52,192,235,.28);
  background: rgba(52,192,235,.05);
}
.kyc-status-ok .kyc-status-glyph {
  background: var(--accent);
  color: var(--accent-ink, #1a1208);
}
.kyc-status-ok .kyc-status-kicker { color: var(--accent); }

/* Pending review — gold/amber tone */
.kyc-status-pending {
  border-color: rgba(252,211,77,.32);
  background: rgba(252,211,77,.06);
}
.kyc-status-pending .kyc-status-glyph {
  background: rgba(252,211,77,.18);
  color: #6FD4F2;
  animation: kyc-pending-spin 2.4s linear infinite;
}
.kyc-status-pending .kyc-status-kicker { color: #6FD4F2; }
@keyframes kyc-pending-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* Rejected — danger red */
.kyc-status-rejected {
  border-color: rgba(239,68,68,.36);
  background: rgba(239,68,68,.06);
}
.kyc-status-rejected .kyc-status-glyph {
  background: rgba(239,68,68,.20);
  color: #ef4444;
}
.kyc-status-rejected .kyc-status-kicker { color: #ef4444; }

/* Upload tile — replaces the bare native <input type="file"> chrome
   with a custom drop-zone surface that matches the rest of the
   player surface. Keyboard-focusable; Enter / Space opens the file
   picker via the hidden child input. */
.kyc-upload { display: flex; flex-direction: column; }
.kyc-upload-tile {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border: 1.5px dashed rgba(52,192,235,.28);
  border-radius: var(--radius-sm);
  background: rgba(52,192,235,.03);
  color: var(--text);
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease, transform .15s ease;
  min-height: 64px;
  outline: none;
}
.kyc-upload-tile:hover,
.kyc-upload-tile:focus-visible {
  border-color: var(--accent);
  background: rgba(52,192,235,.07);
}
.kyc-upload-tile.is-picked {
  border-style: solid;
  border-color: rgba(52,192,235,.45);
  background: rgba(52,192,235,.08);
}
.kyc-upload-glyph {
  flex-shrink: 0;
  width: 38px; height: 38px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  background: rgba(52,192,235,.12);
  color: var(--accent);
  font-size: 18px;
  font-weight: 700;
  font-family: var(--font-display, sans-serif);
}
.kyc-upload-tile.is-picked .kyc-upload-glyph {
  background: var(--accent);
  color: var(--accent-ink, #1a1208);
}
.kyc-upload-copy {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 2px;
}
.kyc-upload-copy strong {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}
.kyc-upload-hint {
  font-size: 11px;
  color: var(--text-mute);
}
.kyc-upload-name {
  font-size: 13px;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

/* ─── Admin KYC Reviews (image previews + reject reason) ─────────── */
.admin-kyc-row {
  padding: 16px 18px;
  border-top: 1px solid var(--line-soft);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.admin-kyc-row:first-child { border-top: none; }
.admin-kyc-row-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}
.admin-kyc-row-name {
  font-weight: 600;
  color: var(--text);
  font-size: 14px;
}
.admin-kyc-row-meta {
  font-size: 11px;
  color: var(--text-mute);
  margin-top: 2px;
}
.admin-kyc-row-doc {
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-dim);
}
.admin-kyc-files-loading,
.admin-kyc-files-empty,
.admin-kyc-files-err {
  font-size: 12px;
  color: var(--text-mute);
  padding: 10px 12px;
  background: rgba(255,255,255,.02);
  border: 1px dashed var(--line-soft);
  border-radius: var(--radius-sm);
}
.admin-kyc-files-err { color: var(--danger); border-color: rgba(239,68,68,.35); }
.admin-kyc-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
}
.admin-kyc-tile {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.admin-kyc-tile-frame {
  position: relative;
  background: rgba(0,0,0,.35);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  overflow: hidden;
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
}
.admin-kyc-tile-frame img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
}
.admin-kyc-tile-loading,
.admin-kyc-tile-err {
  font-size: 11px;
  color: var(--text-mute);
}
.admin-kyc-tile-err { color: var(--danger); }
.admin-kyc-tile-pdf {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-decoration: none;
  color: var(--text);
  font-size: 12px;
  padding: 14px;
}
.admin-kyc-tile-pdf-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 54px;
  background: #ef4444;
  color: #fff;
  font-weight: 800;
  font-size: 12px;
  border-radius: 4px;
  letter-spacing: .04em;
}
.admin-kyc-tile-pdf-name {
  color: var(--text-mute);
  text-align: center;
  word-break: break-all;
  font-size: 11px;
}
.admin-kyc-tile-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11px;
}
.admin-kyc-tile-kind {
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-mute);
  font-weight: 600;
}
.admin-kyc-tile-link {
  color: var(--accent);
  text-decoration: none;
}
.admin-kyc-tile-link:hover { text-decoration: underline; }

.admin-kyc-action {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 4px;
}
.admin-kyc-notes {
  width: 100%;
  resize: vertical;
  min-height: 56px;
  padding: 10px 12px;
  background: rgba(0,0,0,.25);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
  box-sizing: border-box;
}
.admin-kyc-notes:focus {
  outline: none;
  border-color: var(--accent);
}
.admin-kyc-act-err {
  font-size: 12px;
  color: var(--danger);
}
.admin-kyc-action-btns {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* Wager-race fallback banner shown when the active period tab has
   no live race. Uses the same .frame.chamfer surface as the live
   banner so the empty state stays inside the page rhythm. */
.wr2-empty-banner {
  padding: 24px 28px;
  margin-bottom: 24px;
  color: var(--text-mute);
  font-size: 14px;
  line-height: 1.55;
}
.wr2-empty-banner strong { color: var(--text); text-transform: capitalize; }

/* Polished "No race currently" state — centred hero copy on the same
   .frame.chamfer surface so an ended/paid race leaves a clean, on-brand
   page instead of a stale finalized board. */
.wr2-empty-banner--polished {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
  padding: 56px 28px;
}
.wr2-empty-banner--polished .wr2-empty-ico {
  font-size: 40px;
  line-height: 1;
  margin-bottom: 4px;
  filter: grayscale(.15) drop-shadow(0 4px 10px rgba(0,0,0,.35));
}
.wr2-empty-banner--polished .wr2-empty-title {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 800;
  letter-spacing: .01em;
  color: var(--text);
}
.wr2-empty-banner--polished .wr2-empty-sub {
  max-width: 420px;
  color: var(--text-mute);
  font-size: 13.5px;
  line-height: 1.6;
}
.wr2-empty-banner--polished .wr2-empty-sub strong {
  color: var(--text);
  text-transform: capitalize;
}

/* ─── Leaderboard v2 (race banner + ranked table) ────────────────── */
.lb2-page { padding-bottom: 60px; }
.lb2-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 14px 0;
}
.lb2-tabs {
  display: inline-flex;
  background: rgba(255,255,255,.04);
  border-radius: 999px;
  padding: 4px;
}
.lb2-tab {
  background: none;
  border: none;
  color: var(--text-mute);
  padding: 8px 18px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, color .15s;
}
.lb2-tab:hover { color: var(--text); }
.lb2-tab.on {
  background: linear-gradient(135deg, #6FD4F2, #34c0eb);
  color: #1a1208;
}
.lb2-howto {
  font-size: 13px;
  color: var(--text-mute);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.lb2-howto:hover { color: var(--text); }
.lb2-howto-i { font-size: 14px; }

.lb2-headline {
  margin: 8px 0 16px;
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
}

.lb2-banner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 22px 28px;
  margin-bottom: 24px;
  background:
    radial-gradient(ellipse at 0% 100%, rgba(252,211,77,.22), transparent 60%),
    linear-gradient(135deg, rgba(252,211,77,.10), rgba(251,191,36,.05));
  border: 1px solid rgba(252,211,77,.28);
  position: relative;
  overflow: hidden;
}
.lb2-banner::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 16%;
  width: 70%;
  height: 200%;
  background-image:
    radial-gradient(circle 8px at 20% 40%, #6FD4F2 0 100%, transparent 0),
    radial-gradient(circle 6px at 60% 70%, #34c0eb 0 100%, transparent 0),
    radial-gradient(circle 4px at 35% 80%, #6FD4F2 0 100%, transparent 0);
  background-repeat: no-repeat;
  transform: translateY(-50%) rotate(-12deg);
  opacity: .6;
  pointer-events: none;
}
.lb2-banner-pool {
  display: flex;
  align-items: baseline;
  gap: 12px;
  position: relative;
  z-index: 1;
}
.lb2-banner-pool strong {
  font-size: 56px;
  font-weight: 800;
  color: #6FD4F2;
  font-family: var(--font-display, sans-serif);
  letter-spacing: -.02em;
  text-shadow: 0 4px 16px rgba(252,211,77,.45);
}
.lb2-banner-pool span {
  font-size: 22px;
  font-weight: 800;
  color: #6FD4F2;
  letter-spacing: .02em;
}
.lb2-banner-clock {
  display: flex;
  gap: 4px;
  position: relative;
  z-index: 1;
}
.lb2-clock-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 60px;
  background: rgba(0,0,0,.35);
  border: 1px solid rgba(255,255,255,.08);
  border-radius: 6px;
}
.lb2-clock-cell strong {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.lb2-clock-cell span {
  margin-top: 2px;
  font-size: 9px;
  color: var(--text-mute);
  letter-spacing: .08em;
}

.lb2-table {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.lb2-row {
  display: grid;
  grid-template-columns: 80px 1fr 200px 200px;
  align-items: center;
  padding: 14px 18px;
  background: rgba(255,255,255,.02);
  border: 1px solid rgba(255,255,255,.04);
  border-radius: 10px;
  transition: background .15s ease;
}
.lb2-row:hover { background: rgba(255,255,255,.04); }
.lb2-head {
  background: none;
  border: none;
  padding: 8px 18px;
}
.lb2-head .lb2-col {
  color: var(--text-mute);
  font-size: 12px;
  font-weight: 600;
}
.lb2-row-me {
  border-color: rgba(252,211,77,.45);
  background: rgba(252,211,77,.06);
}
.lb2-col { display: flex; align-items: center; gap: 8px; }
.lb2-col-rank { justify-content: flex-start; }
.lb2-rank-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1.5px solid rgba(255,255,255,.10);
  color: var(--text);
  font-weight: 700;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  background: rgba(255,255,255,.03);
}
.lb2-rank-1 .lb2-rank-pill {
  border-color: #45C6EC;
  color: #45C6EC;
  box-shadow: 0 0 16px rgba(250,204,21,.35);
  background: rgba(250,204,21,.08);
}
.lb2-rank-2 .lb2-rank-pill {
  border-color: #cbd5e1;
  color: #cbd5e1;
  background: rgba(203,213,225,.08);
}
.lb2-rank-3 .lb2-rank-pill {
  border-color: #fb923c;
  color: #fb923c;
  background: rgba(251,146,60,.08);
}
.lb2-tier-chip {
  width: 18px;
  height: 18px;
  border-radius: 4px;
  display: inline-block;
  flex-shrink: 0;
}
.lb2-user-name {
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lb2-col-points { color: var(--text); font-weight: 500; font-variant-numeric: tabular-nums; }
.lb2-col-reward { color: #6FD4F2; font-weight: 700; font-variant-numeric: tabular-nums; }
.lb2-info { color: var(--text-mute); margin-left: 4px; cursor: help; }

@media (max-width: 760px) {
  .lb2-row {
    grid-template-columns: 50px 1fr 100px 110px;
    padding: 10px 12px;
  }
  .lb2-banner { flex-direction: column; gap: 18px; padding: 18px 20px; }
  .lb2-banner-pool strong { font-size: 36px; }
  .lb2-banner-pool span { font-size: 16px; }
}

/* ─── Affiliate page v2 (sidebar + banner + earnings footer) ─────── */
.aff2-layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 20px;
  margin-top: 16px;
}
.aff2-sidemenu {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-self: start;
  position: sticky;
  top: 16px;
}
.aff2-sidemenu-title {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  padding: 4px 8px 14px;
}
.aff2-sidemenu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 13px;
  text-align: left;
  height: 36px;
  padding: 0 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.aff2-sidemenu-item:hover { background: rgba(255,255,255,.04); color: var(--text); }
.aff2-sidemenu-item.on {
  background: rgba(255,255,255,.06);
  color: var(--text);
}
.aff2-sidemenu-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--text-mute);
  flex-shrink: 0;
}
.aff2-sidemenu-item.on .aff2-sidemenu-dot { background: var(--accent); }
/* position:relative so the first-visit onboarding overlay covers ONLY
   the pane (page content) — the sidebar + global topbar live outside it
   and stay sharp. */
.aff2-pane { min-width: 0; position: relative; }

.aff2-banner {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: stretch;
  padding: 24px;
  overflow: hidden;
  background:
    radial-gradient(ellipse 80% 100% at 100% 50%, rgba(167,139,250,.18), transparent 60%),
    var(--bg-2, #131316);
}
.aff2-banner-body { flex: 1; min-width: 0; padding-right: 20px; }
.aff2-banner-body h3 {
  margin: 0 0 12px;
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
}
.aff2-banner-body p {
  margin: 0;
  color: var(--text-mute);
  font-size: 13px;
  line-height: 1.55;
  max-width: 56ch;
}
.aff2-banner-art {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.aff2-banner-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin-top: 14px;
  padding: 14px 18px;
  border: 1px solid rgba(255,255,255,.06);
  border-radius: 10px;
  background: rgba(255,255,255,.02);
}
.aff2-banner-stat { text-align: center; }
.aff2-banner-stat-v { color: var(--text); font-size: 13px; }
.aff2-banner-stat-v strong { font-size: 18px; font-weight: 700; }
.aff2-banner-stat-k { color: var(--text-mute); font-size: 12px; margin-top: 4px; }

.aff2-stub {
  padding: 28px;
  text-align: center;
  color: var(--text-mute);
}
.aff2-stub h3 { margin: 0 0 8px; color: var(--text); }
.aff2-stub p  { margin: 0; font-size: 13px; }

.aff2-footer-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-top: 18px;
}
.aff2-footer-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px;
  background: rgba(255,255,255,.02);
  border: 1px solid rgba(255,255,255,.06);
  border-radius: 10px;
}
.aff2-footer-icon {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(99,102,241,.14);
  font-size: 22px;
}
.aff2-footer-meta { flex: 1; min-width: 0; }
.aff2-footer-v { color: var(--text); font-weight: 700; font-size: 18px; font-variant-numeric: tabular-nums; }
.aff2-footer-k { color: var(--text-mute); font-size: 12px; margin-top: 2px; }
.aff2-footer-claim {
  background: linear-gradient(135deg, #22c55e, #16a34a);
  color: #fff;
  border: none;
  padding: 0 22px;
  height: 36px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: filter .15s ease;
}
.aff2-footer-claim:hover { filter: brightness(1.1); }
.aff2-footer-claim:disabled { opacity: .5; cursor: default; filter: none; }

/* ── Stats header + period segmented control ── */
.aff2-stats-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin: 18px 0 10px;
}
.aff2-period { display: inline-flex; gap: 4px; background: var(--bg-3); border: 1px solid var(--line-soft); border-radius: 999px; padding: 3px; }
.aff2-period-btn {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  color: var(--text-mute); font-family: var(--font-display); font-weight: 700;
  font-size: 11px; letter-spacing: .04em; padding: 5px 12px; border-radius: 999px;
  transition: background .15s, color .15s;
}
.aff2-period-btn:hover { color: var(--text); }
.aff2-period-btn.on { background: var(--accent); color: var(--accent-ink, #0a0a0f); }

/* ── ResponsiveTable (window.ResponsiveTable / AffTable) ──────────────
   Container-width-aware table: a real .data-table when the component's
   own box is wide, a labeled card per row when it is narrow. Driven by a
   ResizeObserver in JS (src/user-pages.jsx useContainerWidth), so it
   reflows when the chat sidebar shrinks/grows the pane — NOT off the
   viewport. Shared by the affiliate tiers/referred/breakdown/claims
   tables and reusable on any player page. */
.rt-root { width: 100%; min-width: 0; }
.rt-empty { padding: 22px 18px; text-align: center; color: var(--text-mute); font-size: 13px; }

/* Grid "table" (wide containers) — modeled on the live bet feed. The
   column template comes from the inline --rt-cols custom property the
   component sets per table; explicit tracks mean every column is ALWAYS
   rendered (no auto-layout column-drop). */
.rt-grid { display: flex; flex-direction: column; width: 100%; }
.rt-grid-head, .rt-grid-row {
  display: grid; grid-template-columns: var(--rt-cols, 1fr); gap: 14px;
  align-items: center; padding: 11px 16px;
}
.rt-grid-head {
  font-family: var(--font-display); font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; font-weight: 700; color: var(--text-mute);
  background: var(--white-02);
}
.rt-grid-row {
  border-top: 1px solid var(--line-soft); font-size: 13px;
  color: var(--text); transition: background .15s ease;
}
.rt-grid-row:hover { background: rgba(52,192,235,.04); }
.rt-grid-row.highlight { background: rgba(52,192,235,.06); }
.rt-gc { min-width: 0; word-break: break-word; }
.rt-gc.r { text-align: right; }
.rt-grid-row.rt-dim, .rt-rowcard.rt-dim { opacity: .55; }

/* Card-list (narrow containers) — every field labelled so nothing is lost. */
.rt-cardlist { display: flex; flex-direction: column; gap: 8px; padding: 6px; }
.rt-rowcard {
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm, 8px);
  background: var(--panel); padding: 12px 14px;
}
.rt-rowcard.highlight { border-color: color-mix(in srgb, var(--accent) 55%, transparent); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent) inset; }
.rt-rowcard-h { font-family: var(--font-display); font-weight: 700; margin-bottom: 8px; }
.rt-rowcard-b { display: flex; flex-direction: column; gap: 5px; }
.rt-rowcard-f { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 12.5px; }
.rt-rowcard-f .k { color: var(--text-mute); flex-shrink: 0; }
.rt-rowcard-f .v { color: var(--text); text-align: right; min-width: 0; }

/* ── Opt-in responsive mode for plain .data-table consumers ───────────
   Any existing `<table class="data-table">` becomes a labeled card-list
   on narrow widths by adding the `data-table--cards` modifier and a
   `data-label` attr on each <td> (the value's column header). No JS and
   no markup restructuring required — purely additive, so it cannot
   regress tables that don't opt in. Reacts to the `.main` container
   width (so chat open/close reflows it) with a viewport fallback for
   tables rendered outside the `.main` container (e.g. modals). */
.data-table--cards td[data-label]::before { content: none; }
@container main (max-width: 560px) {
  .data-table--cards, .data-table--cards tbody { display: block; width: 100%; }
  .data-table--cards thead { display: none; }
  .data-table--cards tr {
    display: block; border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm, 8px); background: var(--panel);
    margin-bottom: 8px; padding: 6px 12px;
  }
  .data-table--cards td {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px; border: 0; padding: 7px 0; text-align: right;
  }
  .data-table--cards td[data-label]::before {
    content: attr(data-label); color: var(--text-mute);
    font-weight: 600; text-align: left; flex-shrink: 0;
  }
}
@media (max-width: 560px) {
  .data-table--cards, .data-table--cards tbody { display: block; width: 100%; }
  .data-table--cards thead { display: none; }
  .data-table--cards tr {
    display: block; border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm, 8px); background: var(--panel);
    margin-bottom: 8px; padding: 6px 12px;
  }
  .data-table--cards td {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px; border: 0; padding: 7px 0; text-align: right;
  }
  .data-table--cards td[data-label]::before {
    content: attr(data-label); color: var(--text-mute);
    font-weight: 600; text-align: left; flex-shrink: 0;
  }
}

/* ── First-visit onboarding (page-scoped blur) ── */
.aff2-onboard {
  position: absolute; inset: 0; z-index: 30;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 36px 16px;
  backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
  background: rgba(6, 8, 14, .42);   /* fallback dim where blur unsupported */
  border-radius: var(--radius, 12px);
}
.aff2-onboard-card {
  position: relative; z-index: 31; max-width: 460px; width: 100%;
  background: var(--panel); padding: 26px 26px 22px; text-align: left;
}
.aff2-onboard-badge { font-size: 34px; line-height: 1; margin-bottom: 8px; }
.aff2-onboard-card h2 { margin: 0 0 8px; font-size: 20px; font-weight: 800; font-family: var(--font-display); }
.aff2-onboard-card p { margin: 0 0 12px; color: var(--text-mute); font-size: 13.5px; line-height: 1.6; }
.aff2-onboard-list { list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.aff2-onboard-list li { color: var(--text-dim); font-size: 12.5px; line-height: 1.5; padding-left: 18px; position: relative; }
.aff2-onboard-list li::before { content: '◆'; position: absolute; left: 0; color: var(--accent); font-size: 10px; top: 2px; }
.aff2-onboard-list strong { color: var(--text); }
.aff2-onboard-actions { display: flex; gap: 10px; flex-wrap: wrap; }

@media (max-width: 760px) {
  .aff2-layout { grid-template-columns: 1fr; }
  .aff2-sidemenu { position: static; flex-direction: row; overflow-x: auto; }
  .aff2-banner { flex-direction: column; }
  .aff2-banner-art { margin-top: 16px; }
  .aff2-banner-stats { grid-template-columns: 1fr 1fr; }
  .aff2-footer-grid { grid-template-columns: 1fr; }
}

/* ─── Wallet dropdown v3 (compact per-currency rows + settings) ───── */
.bal-dropdown.bd-v3 {
  width: 232px;
  padding: 8px 6px;
  border-radius: 12px;
  background: #0f1115;
  border: 1px solid rgba(255,255,255,.06);
  box-shadow: 0 16px 48px rgba(0,0,0,.6);
}
/* Center the dropdown under the balance/wallet pair instead of hanging
   off its left edge. The pair (.bal-wallet-pair) is itself centered on
   the main column via `left: var(--main-cx)`, so centering the dropdown
   on the pair makes it track the button when the rail / chat sidebars
   open or close. Margin-offset (half of the 232px width) avoids
   clobbering the base modalIn transform. Mobile bottom-sheet (.bd-sheet)
   keeps its own positioning. */
.bal-dropdown.bd-v3:not(.bd-sheet) { left: 50%; right: auto; margin-left: -116px; }
.bal-dropdown.bd-v3 .bd-list {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 0;
  padding: 0;
}
.bal-dropdown.bd-v3 .bd-row {
  /* icon | symbol (flex) | amount (right) — a fixed 3-track grid so the
     symbols start at one x and the amounts all align to one right column. */
  display: grid;
  grid-template-columns: 26px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: none;
  border: none;
  border-radius: 8px;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
  transition: background .12s ease;
  text-align: left;
  width: 100%;
}
.bal-dropdown.bd-v3 .bd-row:hover { background: rgba(255,255,255,.04); }
.bal-dropdown.bd-v3 .bd-row.on   { background: rgba(255,255,255,.06); }
.bal-dropdown.bd-v3 .bd-meta {
  display: flex;
  align-items: center;
  min-width: 0;
}
.bal-dropdown.bd-v3 .bd-sym {
  font-weight: 600;
  font-size: 13px;
  color: var(--text);
  letter-spacing: 0;
}
.bal-dropdown.bd-v3 .bd-usd {
  font-size: 13px;
  color: var(--text-mute);
  font-variant-numeric: tabular-nums;
  text-align: right;
  justify-self: end;
}
.bal-dropdown.bd-v3 .bd-settings {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: calc(100% - 4px);
  margin: 6px 2px 2px;
  padding: 10px;
  background: none;
  border: none;
  border-top: 1px solid rgba(255,255,255,.06);
  color: var(--text-mute);
  font-size: 13px;
  cursor: pointer;
  transition: color .12s ease;
}
.bal-dropdown.bd-v3 .bd-settings:hover { color: var(--text); }
.bal-dropdown.bd-v3 .bd-settings-icon {
  font-size: 14px;
}

/* The inline `.bd-fiat` picker that briefly lived in the wallet
   dropdown was removed — the fiat display-currency control now lives
   on the Settings page (PrefsForm → "Fiat display currency"). */

/* ─── Profile (flat redesign) ────────────────────────────────────── */
.profile-page-flat {
  display: flex;
  flex-direction: column;
  padding-bottom: 32px;
}

/* ─── Unified Account shell (Profile + Settings share this layout) ─── */
.account-shell {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}
.account-content {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}
.account-rail {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px;
  align-self: start;
  position: sticky;
  top: 16px;
}
.account-rail-section {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  padding: 4px 12px 12px;
  font-family: var(--font-display);
  letter-spacing: -.01em;
}
.account-rail-item {
  display: flex;
  align-items: center;
  gap: 10px;
  background: none;
  border: none;
  color: var(--text-dim, rgba(255,255,255,.6));
  font-size: 13.5px;
  font-weight: 500;
  text-align: left;
  height: 38px;
  padding: 0 12px;
  border-radius: 8px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.account-rail-item svg {
  flex-shrink: 0;
  opacity: .85;
}
.account-rail-item:hover {
  background: rgba(255,255,255,.04);
  color: var(--text, #fff);
}
.account-rail-item.on {
  background: rgba(255,255,255,.05);
  color: var(--text, #fff);
  font-weight: 600;
}
.account-rail-item.on svg { opacity: 1; }
@media (max-width: 860px) {
  .account-shell {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .account-rail {
    flex-direction: row;
    flex-wrap: wrap;
    position: static;
    padding: 0;
    gap: 4px;
  }
  .account-rail-section { width: 100%; padding: 4px 4px 8px; }
  .account-rail-item { height: 34px; padding: 0 10px; font-size: 12.5px; }
}

.profile-flat-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  gap: 16px;
  background: var(--bg-elev-2, rgba(255,255,255,.025));
  border: 1px solid rgba(255,255,255,.05);
  border-radius: 10px;
}
.profile-flat-header-l {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.profile-flat-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  font-family: var(--font-display);
  flex-shrink: 0;
  overflow: hidden;
}
.profile-flat-avatar > span {
  font-size: 17px;
  letter-spacing: 0;
}
.profile-flat-rank {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
}
.profile-flat-username {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.profile-flat-joined {
  font-size: 12.5px;
  color: var(--text-mute);
  flex-shrink: 0;
}

.profile-overview-card {
  padding: 20px;
  background: var(--bg-elev-2, rgba(255,255,255,.025));
  border: 1px solid rgba(255,255,255,.05);
  border-radius: 10px;
}
.profile-overview-head {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 16px;
}
.profile-tier-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.profile-tier-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: 14px;
  font-family: var(--font-display);
}
.profile-tier-glyph {
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.profile-tier-glyph svg { display: block; }
.profile-tier-pct {
  font-size: 13px;
  color: var(--text-mute);
  font-variant-numeric: tabular-nums;
  font-family: var(--font-display);
}
.profile-tier-bar {
  height: 8px;
  background: rgba(255,255,255,.05);
  border-radius: 999px;
  overflow: hidden;
  margin-bottom: 22px;
}
.profile-tier-bar-fill {
  height: 100%;
  background: linear-gradient(90deg,
    var(--profile-tier-color, #6366f1),
    color-mix(in srgb, var(--profile-tier-color, #a78bfa) 70%, #fff 30%));
  border-radius: 999px;
  transition: width .4s ease;
  box-shadow: 0 0 12px color-mix(in srgb, var(--profile-tier-color, #6366f1) 60%, transparent);
}

.profile-overview-card .profile-stats-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-bottom: 14px;
}
.profile-overview-card .profile-stat-card {
  background: rgba(255,255,255,.025);
  border: 1px solid rgba(255,255,255,.05);
  border-radius: 8px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: border-color .15s ease, background .15s ease;
}
.profile-overview-card .profile-stat-card:hover {
  background: rgba(255,255,255,.035);
  border-color: rgba(255,255,255,.08);
}
.profile-overview-card .profile-stat-k {
  font-size: 12px;
  color: var(--text-mute);
  font-weight: 500;
}
.profile-overview-card .profile-stat-v {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  font-family: var(--font-display);
}

.profile-request-stats {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  height: 42px;
  background: rgba(255,255,255,.025);
  border: 1px solid rgba(255,255,255,.05);
  border-radius: 8px;
  color: var(--text-dim);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.profile-request-stats:hover {
  background: rgba(255,255,255,.05);
  color: var(--text);
  border-color: rgba(255,255,255,.08);
}
.profile-request-stats:disabled { opacity: .6; cursor: default; }
.profile-request-icon {
  font-size: 14px;
  color: var(--text-mute);
}
.profile-request-msg {
  margin-top: 8px;
  font-size: 12px;
  color: var(--accent);
}
.profile-overview-foot {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 12px;
  color: var(--text-mute);
  align-items: center;
}
.profile-avatar-foot-link {
  background: none;
  border: none;
  color: var(--text-mute);
  font-size: 12px;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.profile-avatar-foot-link:hover { color: var(--accent); }
.profile-avatar-foot-err {
  color: #ef4444;
  font-size: 12px;
}

.profile-badges-card { padding: 20px; }
.profile-badges-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
}
.profile-badges-info {
  font-size: 14px;
  color: var(--text-mute);
  cursor: help;
}
.profile-badges-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.profile-badge {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 700;
  font-family: var(--font-display);
  border: 1.5px solid rgba(255,255,255,.18);
  color: rgba(255,255,255,.65);
  background: rgba(255,255,255,.04);
  letter-spacing: 0;
}
.profile-badge.off {
  opacity: .35;
  filter: grayscale(.7);
}

.profile-info-card {
  padding: 20px;
  background: var(--bg-elev-2, rgba(255,255,255,.025));
  border: 1px solid rgba(255,255,255,.05);
  border-radius: 10px;
}
.profile-info-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
}
.profile-info-eye {
  background: none;
  border: none;
  color: var(--text-mute);
  font-size: 16px;
  cursor: pointer;
  padding: 0;
}
.profile-info-field {
  margin-bottom: 14px;
}
.profile-info-field label {
  display: block;
  font-size: 12px;
  color: var(--text-mute);
  margin-bottom: 6px;
}
.profile-info-input {
  width: 100%;
  height: 40px;
  background: rgba(255,255,255,.03);
  border: 1px solid rgba(255,255,255,.08);
  border-radius: 6px;
  color: var(--text);
  padding: 0 12px;
  font-size: 13px;
  box-sizing: border-box;
}
.profile-info-input:disabled,
.profile-info-input[readonly] { color: var(--text-mute); }
.profile-info-row {
  display: flex;
  align-items: stretch;
  gap: 0;
  border: 1px solid rgba(255,255,255,.08);
  border-radius: 6px;
  background: rgba(255,255,255,.03);
  overflow: hidden;
}
.profile-info-row .profile-info-input {
  border: none;
  border-radius: 0;
  flex: 1;
  background: transparent;
}
.profile-info-update {
  background: linear-gradient(135deg, #22c55e, #16a34a);
  color: #fff;
  border: none;
  padding: 0 18px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: filter .15s ease;
}
.profile-info-update:hover { filter: brightness(1.1); }
.profile-info-update:disabled { opacity: .6; cursor: default; }
.profile-info-msg {
  margin-top: 10px;
  font-size: 12px;
  color: var(--accent);
}

/* ─── Settings page sidebar ──────────────────────────────────────── */
.settings-page { padding-bottom: 32px; }
.settings-layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 20px;
  margin-top: 16px;
}
.settings-sidemenu {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 16px 8px;
  background: rgba(255,255,255,.02);
  border: 1px solid rgba(255,255,255,.04);
  border-radius: 10px;
  align-self: start;
  position: sticky;
  top: 16px;
}
.settings-sidemenu-section {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-mute);
  text-transform: uppercase;
  letter-spacing: .08em;
  padding: 8px 12px 6px;
}
.settings-sidemenu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 13px;
  text-align: left;
  height: 36px;
  padding: 0 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.settings-sidemenu-item:hover { background: rgba(255,255,255,.04); color: var(--text); }
.settings-sidemenu-item.on {
  background: rgba(99,102,241,.12);
  color: var(--text);
}
.settings-sidemenu-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--text-mute);
  flex-shrink: 0;
}
.settings-sidemenu-item.on .settings-sidemenu-dot {
  background: #a78bfa;
}
.settings-pane {
  min-width: 0;
}
@media (max-width: 760px) {
  .settings-layout {
    grid-template-columns: 1fr;
  }
  .settings-sidemenu {
    flex-direction: row;
    overflow-x: auto;
    position: static;
  }
  .settings-sidemenu-section { display: none; }
}

/* ==================================================================
   Wallet Modal v2 — operator rebuild matching the supplied reference
   screenshots. Single-column dark modal: header (Wallet + close),
   pill tab strip, hairline divider, then a body that picks one of
   five flavors per tab (Deposit / Withdraw / Gift Cards / Buy /
   Tip). All money amounts use the `$` green-coin prefix, all CTAs
   are full-width pill-radius green buttons, and informational
   footers render in soft amber.
   ================================================================== */

/* ----- Modal shell ----- */
.wm-root {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  display: grid; place-items: center;
  z-index: var(--z-modal, 5000);
  padding: 20px;
}
.wm-shell {
  width: 100%;
  /* Operator request — bumped from 460 → 560 px so the 6-tab strip
     (Deposit / Withdraw / Gift Cards / Buy Crypto / Tip / Vault) fits
     on a single row instead of wrapping Vault to a second line. The
     mobile breakpoint below clamps back to 100 % width for small
     screens where one-line tabs aren't possible anyway. */
  max-width: 560px;
  background: linear-gradient(180deg, #1a1d23 0%, #15171d 100%);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 14px;
  box-shadow: 0 24px 48px rgba(0, 0, 0, .55);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 40px);
  font-family: var(--font-ui);
  color: var(--text);
}

/* ----- Header ----- */
.wm-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px 14px;
}
.wm-head-title {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 800;
  letter-spacing: .005em;
  color: var(--text);
}
.wm-head-title svg { color: var(--text-mute); }
.wm-close {
  appearance: none;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .06);
  color: var(--text-mute);
  border-radius: 8px;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.wm-close:hover { background: rgba(255, 255, 255, .08); color: var(--text); }

/* ----- Tab strip ----- */
.wm-tabs {
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 0 14px 14px;
  /* No wrapping — every tab stays on a single row at the new wider
     shell width. The mobile media query below restores `wrap` since a
     narrow phone screen cannot fit 6 tabs in one row regardless of
     padding tuning. */
  flex-wrap: nowrap;
}
.wm-tab {
  appearance: none;
  cursor: pointer;
  /* Slightly tighter pill padding so 6 tabs (incl. Wager when active)
     fit comfortably in a single row inside the 560 px shell. */
  padding: 7px 11px;
  background: transparent;
  border: 0;
  color: var(--text-mute);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .02em;
  border-radius: 999px;
  white-space: nowrap;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.wm-tab:hover { color: var(--text); background: rgba(255, 255, 255, .04); }
.wm-tab.is-on {
  background: rgba(0, 0, 0, .42);
  color: var(--text);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .04) inset;
}

.wm-divider {
  height: 1px;
  background: rgba(255, 255, 255, .06);
  margin: 0;
}

/* ----- Body ----- */
.wm-body {
  padding: 18px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* ----- Field / label ----- */
.wm-field { display: flex; flex-direction: column; gap: 6px; }
.wm-label {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-mute);
  letter-spacing: .01em;
}
.wm-label-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px;
}
.wm-balance {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}

/* ----- Generic input ----- */
.wm-input {
  width: 100%;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 10px;
  padding: 13px 14px;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
  outline: 0;
  transition: border-color var(--dur-base) var(--ease-standard),
              background-color var(--dur-base) var(--ease-standard);
}
.wm-input::placeholder { color: var(--text-mute); }
.wm-input:focus { border-color: rgba(255, 255, 255, .18); background-color: rgba(255, 255, 255, .045); }

/* ----- Currency dropdown ----- */
.wm-currency { position: relative; }
.wm-currency-trigger {
  appearance: none;
  cursor: pointer;
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 10px;
  padding: 11px 14px;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  transition: border-color var(--dur-base) var(--ease-standard),
              background-color var(--dur-base) var(--ease-standard);
}
.wm-currency-trigger:hover { background: rgba(255, 255, 255, .045); }
.wm-currency-name { flex: 1; min-width: 0; }
.wm-currency-trigger > svg:last-child { color: var(--text-mute); }
.wm-currency-pop {
  position: absolute;
  top: calc(100% + 6px);
  left: 0; right: 0;
  background: #1a1d23;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 10px;
  box-shadow: 0 12px 24px rgba(0, 0, 0, .45);
  z-index: 10;
  max-height: 320px;
  overflow-y: auto;
  padding: 4px;
}
.wm-currency-opt {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  appearance: none; cursor: pointer; border: 0;
  background: transparent;
  padding: 9px 10px;
  border-radius: 6px;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 13px;
  text-align: left;
  transition: background var(--dur-base) var(--ease-standard);
}
.wm-currency-opt:hover { background: rgba(255, 255, 255, .04); }
.wm-currency-opt.is-on { background: rgba(255, 255, 255, .06); }
.wm-currency-opt-name { flex: 1; }
.wm-currency-opt-sym {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}
/* Settings → Ignored Users — one row per ignored player with an
   Unignore action. List is client-side (window.spinarmoryIgnore) so
   it reflects whatever this device has accumulated. */
.ignored-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ignored-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 8px;
}
.ignored-name {
  font-size: 13.5px;
  color: var(--text);
  font-family: var(--font-display);
}
.ignored-unbtn {
  font-size: 12px;
  padding: 6px 12px;
}

/* Per-coin spendable-value pill on each dropdown row — shows the
   player's balance for that coin converted to display-fiat. Same
   muted treatment as the trailing symbol but with a small accent
   tone so the eye picks it up as the "value" column. */
.wm-currency-opt-fiat {
  margin-left: 6px;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  border-radius: 999px;
  background: rgba(255, 255, 255, .05);
  color: var(--text-dim, rgba(255,255,255,.75));
}
.wm-currency-opt.is-on .wm-currency-opt-fiat {
  background: rgba(255, 255, 255, .08);
  color: var(--text);
}
/* Crypto-equivalent preview line under the fiat amount input. The
   user types fiat (USD/EUR/…), this shows the authoritative crypto
   figure the wallet will actually move. Designed to be UNMISSABLE
   on the Tip surface — a small accent-toned chip-style card that
   sits directly below the input. */
.wm-amount-hint {
  margin-top: 10px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  font-size: 13px;
  border-radius: 8px;
  background: rgba(52, 192, 235, .08);
  border: 1px solid rgba(52, 192, 235, .18);
  color: var(--accent, #34c0eb);
  font-variant-numeric: tabular-nums;
}
.wm-amount-hint-arrow {
  font-size: 14px;
  opacity: .8;
  font-weight: 700;
}
.wm-amount-hint strong {
  color: var(--text, #fff);
  font-weight: 700;
  letter-spacing: .01em;
}
.wm-amount-hint-sym {
  color: var(--text-dim, rgba(255,255,255,.7));
  font-weight: 600;
  font-size: 12px;
}
.wm-amount-hint-loading {
  color: var(--text-mute);
  font-style: italic;
  font-size: 12px;
}

/* ----- Network chips ----- */
.wm-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.wm-chip {
  appearance: none;
  cursor: pointer;
  padding: 6px 12px;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 999px;
  color: var(--text-mute);
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .02em;
  transition: color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard);
}
.wm-chip:hover { color: var(--text); }
.wm-chip.is-on {
  background: rgba(52, 192, 235, .10);
  border-color: rgba(52, 192, 235, .35);
  color: var(--accent);
}

/* ----- Address bar ----- */
.wm-addr {
  display: flex; align-items: center; gap: 8px;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 10px;
  padding: 4px 6px 4px 14px;
  min-height: 46px;
  transition: border-color var(--dur-base) var(--ease-standard);
}
.wm-addr:focus-within { border-color: rgba(255, 255, 255, .18); }
.wm-addr-text {
  flex: 1; min-width: 0;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wm-addr-input {
  flex: 1; min-width: 0;
  appearance: none;
  background: transparent;
  border: 0; outline: 0;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 14px;
  padding: 6px 0;
}
.wm-addr-input::placeholder { color: var(--text-mute); }
.wm-icon-btn {
  appearance: none;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .06);
  color: var(--text-mute);
  border-radius: 8px;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.wm-icon-btn:hover { background: rgba(255, 255, 255, .08); color: var(--text); }

/* ----- Amount input ($ prefix + Max + suffix) ----- */
.wm-amount {
  display: flex; align-items: center; gap: 10px;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 10px;
  padding: 4px 6px 4px 8px;
  min-height: 46px;
  transition: border-color var(--dur-base) var(--ease-standard);
}
.wm-amount:focus-within { border-color: rgba(255, 255, 255, .18); }
.wm-coin-prefix {
  display: inline-grid; place-items: center;
  width: 28px; height: 28px;
  border-radius: 50%;
  /* Brand-amber accent (was green per the screenshots; operator
     wants the site's gold tone instead). */
  background: linear-gradient(135deg, var(--accent-bright, #6FD4F2), var(--accent, #34c0eb));
  color: #1A1205;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 800;
  flex-shrink: 0;
  overflow: hidden;
}
.wm-coin-prefix--img { padding: 3px; }
.wm-coin-prefix--img img {
  width: 100%; height: 100%;
  object-fit: cover;
  border-radius: 50%;
  display: block;
}
.wm-amount-input {
  flex: 1; min-width: 0;
  appearance: none;
  background: transparent;
  border: 0; outline: 0;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 16px;
  font-weight: 600;
  padding: 6px 0;
  font-variant-numeric: tabular-nums;
}
.wm-amount-input::placeholder { color: var(--text-mute); }
.wm-amount-suffix {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  color: var(--text-mute);
  padding-right: 10px;
}
.wm-max {
  appearance: none;
  cursor: pointer;
  padding: 7px 14px;
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .06);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .02em;
  border-radius: 8px;
  transition: background var(--dur-base) var(--ease-standard);
}
.wm-max:hover { background: rgba(255, 255, 255, .08); }

/* ----- QR code block ----- */
.wm-qr-wrap { display: grid; place-items: center; padding: 12px 0 6px; }
.wm-qr {
  background: #fff;
  padding: 8px;
  border-radius: 8px;
  display: inline-block;
}
.wm-qr svg, .wm-qr div { display: block; }

/* ----- CTA / button -----
   Was a green gradient — operator wants the site's brand-amber tone
   instead so the wallet modal reads as part of the same family as
   the topbar Wallet pill, the rightpanel Claim buttons, and every
   other site CTA. Inked text uses the dark-on-amber contrast token. */
.wm-cta {
  appearance: none;
  cursor: pointer;
  width: 100%;
  padding: 14px 18px;
  background: linear-gradient(180deg, var(--accent-bright, #6FD4F2) 0%, var(--accent, #34c0eb) 100%);
  border: 0;
  border-radius: 10px;
  color: var(--accent-ink, #1A1205);
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: .02em;
  transition: filter var(--dur-base) var(--ease-standard),
              transform var(--dur-base) var(--ease-standard);
}
.wm-cta:hover:not(:disabled) { filter: brightness(1.06); }
.wm-cta:active:not(:disabled) { transform: translateY(1px); }
.wm-cta:disabled { opacity: .55; cursor: not-allowed; }

/* ----- Footer note (soft amber) ----- */
.wm-footer {
  font-family: var(--font-ui);
  font-size: 12px;
  line-height: 1.5;
  color: rgba(52, 192, 235, .82);
  text-align: center;
  padding: 4px 8px;
}

/* ----- Status / error / success messages ----- */
.wm-status {
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--text-mute);
  text-align: center;
  padding: 24px 8px;
  background: rgba(255, 255, 255, .02);
  border: 1px dashed rgba(255, 255, 255, .08);
  border-radius: 10px;
}
.wm-error {
  font-family: var(--font-ui);
  font-size: 12px;
  color: #ff6b6b;
  background: rgba(255, 107, 107, .08);
  border: 1px solid rgba(255, 107, 107, .25);
  padding: 9px 12px;
  border-radius: 8px;
}
.wm-success {
  font-family: var(--font-ui);
  font-size: 12px;
  color: #4ee6a8;
  background: rgba(78, 230, 168, .08);
  border: 1px solid rgba(78, 230, 168, .25);
  padding: 9px 12px;
  border-radius: 8px;
}

/* ----- Tip "Public" toggle row ----- */
.wm-toggle-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  padding: 12px 4px;
}
.wm-toggle-title {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
}
.wm-toggle-sub {
  margin-top: 2px;
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--text-mute);
}
.wm-switch {
  appearance: none;
  cursor: pointer;
  position: relative;
  width: 38px; height: 22px;
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .10);
  border-radius: 999px;
  flex-shrink: 0;
  transition: background var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard);
}
.wm-switch-knob {
  position: absolute;
  top: 2px; left: 2px;
  width: 16px; height: 16px;
  background: #fff;
  border-radius: 50%;
  transition: transform var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard);
}
.wm-switch.is-on {
  background: linear-gradient(180deg, var(--accent-bright, #6FD4F2) 0%, var(--accent, #34c0eb) 100%);
  border-color: rgba(52, 192, 235, .55);
}
.wm-switch.is-on .wm-switch-knob { transform: translateX(16px); }

/* ----- Buy Crypto: provider radio rows ----- */
.wm-providers { display: flex; flex-direction: column; gap: 6px; }
.wm-provider {
  display: flex; align-items: center; justify-content: space-between;
  padding: 11px 14px;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 10px;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard);
}
.wm-provider em {
  font-style: normal;
  color: var(--text-mute);
  font-size: 11px;
  font-weight: 600;
}
.wm-provider:hover { background: rgba(255, 255, 255, .045); }
.wm-provider.is-on {
  border-color: rgba(52, 192, 235, .35);
  background: rgba(52, 192, 235, .06);
}

/* ----- Vault — two balance chips (Main / Vault) -----
   Clicking a chip flips the transfer direction so the player is
   always pulling from the side they just tapped. Selected chip gets
   the gold accent treatment matching the other selectable chips in
   the modal. */
.wm-vault-chips {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.wm-vault-chip {
  appearance: none;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 12px 14px;
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 10px;
  text-align: left;
  transition: background var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard);
}
.wm-vault-chip:hover { background: rgba(255, 255, 255, .045); }
.wm-vault-chip.is-on {
  background: rgba(52, 192, 235, .08);
  border-color: rgba(52, 192, 235, .35);
}
.wm-vault-chip-label {
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-mute);
}
.wm-vault-chip.is-on .wm-vault-chip-label { color: var(--accent); }
.wm-vault-chip-fiat {
  font-family: var(--font-mono);
  font-size: 16px;
  font-weight: 800;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.wm-vault-chip-crypto {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}

/* Live crypto-equivalent preview under the amount input. */
.wm-vault-eq {
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--text-mute);
  margin-top: 2px;
}
.wm-vault-eq strong {
  font-family: var(--font-mono);
  color: var(--text);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ----- Tip recipient autocomplete -----
   Anchors to .wm-ac (positioned wrapper around the User input). Pop
   sits flush below the input with a small offset so the focus ring
   never overlaps a suggestion row. Click-outside closes the popover
   via a 150ms onBlur delay so onMouseDown on a row still fires. */
.wm-ac { position: relative; }
.wm-ac-pop {
  position: absolute;
  top: calc(100% + 6px);
  left: 0; right: 0;
  background: #1a1d23;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 10px;
  box-shadow: 0 12px 24px rgba(0, 0, 0, .45);
  z-index: 20;
  max-height: 240px;
  overflow-y: auto;
  padding: 4px;
}
.wm-ac-opt {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  appearance: none; cursor: pointer; border: 0;
  background: transparent;
  padding: 9px 10px;
  border-radius: 6px;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  transition: background var(--dur-base) var(--ease-standard);
}
.wm-ac-opt:hover,
.wm-ac-opt.is-active {
  background: rgba(255, 255, 255, .06);
}
.wm-ac-name {
  flex: 1; min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wm-ac-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--text-mute);
  flex-shrink: 0;
}
.wm-ac-role {
  font-family: var(--font-display);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 3px;
  color: var(--accent-ink, #1A1205);
  background: var(--accent, #34c0eb);
}
.wm-ac-role--mod    { background: #6BD49B; }
.wm-ac-role--admin  { background: var(--accent, #34c0eb); }
.wm-ac-role--owner  { background: #ff6b6b; color: #fff; }
.wm-ac-hint {
  position: absolute;
  top: calc(100% + 4px); right: 8px;
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-mute);
  pointer-events: none;
}

/* ----- Responsive ----- */
@media (max-width: 540px) {
  .wm-shell { max-width: 100%; max-height: calc(100vh - 24px); }
  .wm-tabs {
    padding: 0 10px 12px;
    /* Narrow screens can't fit all 6 tabs in one row — let them wrap
       (or the strip would clip the rightmost tabs out of view). */
    flex-wrap: wrap;
  }
  .wm-body { padding: 14px; gap: 12px; }
}

/* ==================================================================
   Settings → Display currency → Fiat picker. Reuses the canonical
   SelectMenu (.sd-bp-*) plumbing but overrides the icon container so
   the fiat PNG flag renders cleanly inside the round dot — the
   default `.sd-bp-dot` paints an accent-gold background that would
   bleed through the PNG's transparent corners.
   ================================================================== */
.prefs-fiat-picker .sd-bp-dot.prefs-fiat-dot,
.prefs-fiat-picker .sm-btn .sd-bp-dot {
  background: transparent !important;
  padding: 0 !important;
  width: 20px; height: 20px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .06);
}
.prefs-fiat-picker .sd-bp-dot img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 50%;
}
.prefs-fiat-picker .sd-bp-menu {
  min-width: 200px;
}
.prefs-fiat-picker .sd-bp-item {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
}
.prefs-fiat-code {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--text);
}
.prefs-fiat-sym {
  font-family: var(--font-display);
  font-size: 11px;
  color: var(--text-mute);
  margin-left: 2px;
}

/* ==================================================================
   Live feed (Latest Hits) — vibrancy pass.

   Pre-fix every loss row was hit with a global `opacity: .6` which
   greyed every column out and made the table read flat. The operator
   wanted the feed to have more soul: brighter game / player names,
   gold-on-amber multiplier + payout on wins, saturated red on
   losses (not dimmed magenta), and a richer treatment for big wins
   (multiplier ≥ 5×).
   ================================================================== */

/* Default row text — brighter than the muted greys of the prior pass.
   Players, game names, bet amounts all read white-ish so the eye sees
   "real activity" instead of "ghost text". */
.activity-row.clickable .game-name,
.activity-row.clickable button .game-name,
.activity-row.clickable > button > span {
  color: var(--text);
}
.activity-row.clickable .bet {
  color: var(--text);
  font-weight: 700;
}
.activity-row.clickable .user {
  color: var(--text);
  font-weight: 600;
}

/* ----- Loss state -------------------------------------------------
   No more global opacity-dim. Each loss row keeps full text legibility
   but the multiplier + payout get the saturated red (#FF4D6A) so the
   eye can still cluster "all the losses" at a glance. Game / player /
   bet stay at a slightly cooler white so the row reads as a record
   rather than fully active. */
.activity-row.is-loss > button,
.activity-row.is-loss .bet,
.activity-row.is-loss .user {
  color: rgba(255, 255, 255, .82);
}
.activity-row.is-loss .multiplier,
.activity-row.is-loss .win {
  color: #FF4D6A;
  font-weight: 800;
  text-shadow: 0 0 8px rgba(255, 77, 106, .25);
}

/* ----- Win state --------------------------------------------------
   Brand-amber multiplier + payout with a soft glow. Game / player /
   bet jump to full white so the row pops over loss rows. */
.activity-row.is-win > button,
.activity-row.is-win .bet,
.activity-row.is-win .user {
  color: #fff;
}
.activity-row.is-win .multiplier,
.activity-row.is-win .win {
  color: var(--accent-bright, #6FD4F2);
  font-weight: 800;
  text-shadow: 0 0 8px rgba(52, 192, 235, .28);
}

/* ----- Big win (multiplier ≥ 5×) -----------------------------------
   Adds a subtle amber wash across the row + brighter glow on the
   multiplier so a 41.68× hit doesn't read identical to a 1.5× hit.
   Background uses a thin left→right tint so it doesn't fight the
   row-hover state. */
.activity-row.is-big-win {
  background: linear-gradient(90deg,
    rgba(52, 192, 235, .08) 0%,
    rgba(52, 192, 235, .03) 60%,
    transparent 100%);
}
.activity-row.is-big-win .multiplier {
  color: #FFE38A;
  text-shadow: 0 0 12px rgba(246, 213, 117, .55);
}
/* Win AMOUNT renders green (operator request — "Lucky Bets" payouts were
   showing yellow). The amber multiplier stays as the lucky eye-catcher;
   the payout reads as money won. */
.activity-row.is-big-win .win {
  color: var(--green, #5ec98f);
  text-shadow: 0 0 12px rgba(94, 201, 143, .5);
}
.activity-row.is-big-win .multiplier {
  /* Big multipliers get a touch more visual weight without breaking
     the 50px row height — letterspacing tightens slightly so the
     bigger digits still fit the column. */
  font-size: 14px;
  letter-spacing: -.01em;
}

/* ----- Coin chip + avatar tinting ---------------------------------
   The CoinChip / avatar dots already carry their crypto/rank colour
   — but the surrounding row was washing them out. Reset opacity to
   full so the accepted-payments-style vibrance survives. */
.activity-row .g-chip,
.activity-row .user .av,
.activity-row .win .gc,
.activity-row .bet .gc {
  opacity: 1;
}

/* ----- Hover lift -------------------------------------------------
   Slightly stronger hover tint than the prior pass so a row "lifts"
   meaningfully when the mouse lands. */
.activity-row.clickable:hover {
  background: color-mix(in srgb, var(--accent-soft) 70%, transparent 30%);
}
.activity-row.is-big-win.clickable:hover {
  background:
    linear-gradient(90deg,
      rgba(52, 192, 235, .14) 0%,
      rgba(52, 192, 235, .06) 60%,
      transparent 100%),
    color-mix(in srgb, var(--accent-soft) 30%, transparent 70%);
}

/* ----- Header row -------------------------------------------------
   Slightly brighter kicker so the columns headers read against the
   richer body rows. */
.activity-row.head {
  color: rgba(255, 255, 255, .55);
}


