:root { font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; line-height: 1.4; }
    *, *::before, *::after { box-sizing: border-box; }

    body{
      margin:0; padding:0;
      background: radial-gradient(circle at top, #222 0, #111 40%, #000 100%);
      color:#f5f5f5;
      /* column, so the shared .sitenav spans the top and .app stays centred under it */
      display:flex; flex-direction:column; align-items:center;
    }
    .app{ max-width:1050px; width:100%; padding:16px; }
    .card{
      background: rgba(20,20,20,0.9);
      border-radius:16px;
      padding:16px 20px;
      box-shadow:0 10px 30px rgba(0,0,0,0.5);
      margin-bottom:16px;
      border:1px solid rgba(255,255,255,0.06);
    }
    h1{ margin:0 0 4px 0; font-size:1.8rem; }
    h2{ margin:0 0 8px 0; font-size:1.2rem; }
    p{ margin:4px 0; color:#ddd; }
    .subtitle{ color:#aaa; font-size:0.9rem; margin-bottom:8px; }

    .row{ display:flex; flex-wrap:wrap; gap:10px; align-items:baseline; }
    .bankroll-display{ font-size:1.05rem; font-weight:700; }

    .stat-row{
      margin-top:8px;
      display:flex;
      flex-wrap:wrap;
      gap:8px;
      align-items:stretch;
    }

    .stat-box{
      flex: 1 1 120px;
      min-width:120px;
      padding:8px 10px;
      border-radius:12px;
      background: radial-gradient(circle at top, rgba(15,23,42,0.95) 0, rgba(15,23,42,0.85) 40%, rgba(15,23,42,0.75) 100%);
      border:1px solid rgba(148,163,184,0.6);
      box-shadow:0 4px 10px rgba(0,0,0,0.6);
      display:flex;
      flex-direction:column;
      justify-content:center;
      gap:2px;
    }

    .stat-box.primary{
      border-color:#facc15;
      box-shadow:0 6px 14px rgba(0,0,0,0.8);
    }

    .stat-label{
      font-size:0.7rem;
      text-transform:uppercase;
      letter-spacing:0.08em;
      color:#9ca3af;
    }

    .stat-value{
      font-size:1.1rem;
      font-weight:800;
      color:#f9fafb;
    }

    .stat-btn{
      align-self:stretch;
      flex: 0 0 auto;
      height:100%;
      display:flex;
      align-items:center;
      justify-content:center;
      padding-inline:16px;
      font-weight:800;
    }

    @media (max-width: 640px){
      .stat-row{
        flex-direction:row;
      }
      .stat-btn{
        width:100%;
      }
    }


    .muted{ color:#cbd5e1; opacity:0.85; }

    .badge{
      display:inline-block;
      padding:2px 8px;
      border-radius:999px;
      font-size:0.75rem;
      text-transform:uppercase;
      letter-spacing:0.04em;
      background:#1f2937;
      border:1px solid rgba(255,255,255,0.06);
      color:#f9fafb;
      user-select:none;
      white-space:nowrap;
    }
    .badge-point{ background:#1d4ed8; }
    .badge-comeout{ background:#16a34a; }
    .badge-off{ background:#374151; }
    .badge-on{ background:#16a34a; }

    /* TABLE */
    .table-card{
      background: radial-gradient(circle at top, #064e3b 0, #022c22 50%, #020617 100%);
      border-color: rgba(148, 163, 184, 0.4);
      position:relative;
      overflow:hidden;
    }
    /* minmax(0,…) + min-width:0 throughout: the Buy-bets strip below is a
       nowrap flex row of fixed-width columns, and as a grid item its automatic
       minimum size is its min-content width (~950px). Without these the whole
       felt — every bubble with it — was sized to that on phones and tablets and
       silently clipped by .table-card's overflow:hidden. The strip scrolls
       sideways on its own instead. */
    .table-felt{
      border-radius:18px;
      border:2px solid rgba(148, 163, 184, 0.5);
      padding:14px;
      display:grid;
      grid-template-columns: minmax(0, 2fr) minmax(0, 1.4fr);
      gap:12px;
    }
    .table-main{ display:flex; flex-direction:column; gap:10px; min-width:0; }
    .table-sides{
      display:grid;
      grid-template-columns: 1fr;
      gap:8px;
      align-content:start;
      min-width:0;
    }
    @media (min-width: 900px){
      .table-sides{ grid-template-columns: 1fr 1fr; }
    }

    #sideBetsGroup,
    #bonusBetsGroup{
      display: contents;
    }
    /* Only meaningful where the felt is actually two columns. Unscoped, this
       out-specifies the one-column rule below and pulled phones and tablets
       back into two ~130px columns the moment one group was hidden — bubbles
       squeezed to a third of the screen with their trackers wrapping four
       rows deep. */
    @media (min-width: 821px){
      .table-felt.one-group-wide{
        grid-template-columns: minmax(0, 2.4fr) minmax(0, 1.7fr);
      }
    }
    /* nothing left in the sides track: hand the row back to the line bets
       rather than leaving an empty column of felt beside them */
    .table-felt.no-sides{
      grid-template-columns: minmax(0, 1fr);
    }
    .table-felt.no-sides .table-sides{ display:none; }
    .bet-spot{
      border-radius:999px;
      border:1px solid rgba(148,163,184,0.8);
      padding:4px 4px;
      font-size:0.8rem;
      text-align:center;
      cursor:pointer;
      background: rgba(15,118,110,0.35);
      color:#e5e7eb;
      box-shadow:0 4px 10px rgba(0,0,0,0.5);
      transition: transform 0.05s ease, box-shadow 0.05s ease, border-color 0.1s ease, opacity 0.1s ease;
      position:relative;
      overflow:hidden;
      user-select:none;
      white-space:nowrap;
    }
    .bet-spot:hover{ transform: translateY(-1px); box-shadow:0 6px 14px rgba(0,0,0,0.7); border-color:#facc15; }
    .bet-spot:active{ transform: translateY(0); box-shadow:0 4px 10px rgba(0,0,0,0.5); }

    .bet-spot-main{
      font-size:0.95rem;
      font-weight:800;
      background: linear-gradient(135deg, rgba(22, 163, 74, 0.7), rgba(5, 150, 105, 0.7));
    }
    .bet-spot-odds{
      font-size:0.85rem;
      background: linear-gradient(135deg, rgba(59, 130, 246, 0.7), rgba(37, 99, 235, 0.7));
    }
    .bet-spot-come{
      font-size:0.85rem;
      background: linear-gradient(135deg, rgba(168, 85, 247, 0.7), rgba(99, 102, 241, 0.7));
    }

    .bet-title{ text-transform:uppercase; letter-spacing:0.08em; font-size:0.7rem; }
    .bet-subtitle{ font-size:0.7rem; opacity:0.85; white-space:normal; }
    .bet-amount{ margin-top:6px; font-weight:900; font-size:0.9rem; color:#f97316; }

    .disabled,
    [aria-disabled="true"]{
      opacity:0.45 !important;
      cursor:not-allowed !important;
      transform:none !important;
      border-color: rgba(148,163,184,0.8) !important;
      box-shadow: 0 4px 10px rgba(0,0,0,0.5) !important;
    }

    /* OFF overlay (bubble behavior) */
    .off-overlay::after{
      content:"OFF";
      position:absolute;
      inset:0;
      display:flex;
      align-items:center;
      justify-content:center;
      font-weight:900;
      letter-spacing:0.18em;
      font-size:1.05rem;
      color: rgba(255,255,255,0.85);
      background: rgba(0,0,0,0.35);
      text-shadow: 0 2px 12px rgba(0,0,0,0.8);
      pointer-events:none;
    }

    /* Places */
    .table-places{
      grid-column: 1 / -1;
      min-width:0;
      margin-top:8px;
      padding-top:8px;
      border-top:1px solid rgba(148,163,184,0.6);
    }
    .table-places-title{
      font-size:0.8rem;
      text-transform:uppercase;
      letter-spacing:0.08em;
      color:#e5e7eb;
      margin-bottom:6px;
      display:flex;
      align-items:center;
      justify-content:space-between;
      gap:10px;
      flex-wrap:wrap;
    }
    .table-places-grid{
      display:flex;
      gap:6px;
      min-width:0;
      overflow-x:auto;
      overflow-y:hidden;
      flex-wrap:nowrap;
      align-items:flex-start;
      padding-bottom:8px;
    }
    /* A game with only a few payout groups (craps has three) shares the width
       instead of scrolling — the whole board fits, even on a phone. */
    .table-places-grid.few-cols .payout-col{ flex:1 1 0; width:auto; min-width:0; }
    .payout-col{
      flex: 0 0 118px;
      width:118px;
      display:flex;
      flex-direction:column;
      gap:6px;
    }
    .payout-header{
      font-size:0.75rem;
      letter-spacing:0.06em;
      text-transform:uppercase;
      color:#e5e7eb;
      padding:6px 8px;
      border-radius:12px;
      background: rgba(2,6,23,0.35);
      border:1px solid rgba(148,163,184,0.55);
      text-align:center;
      white-space:nowrap;
    }
    .bet-spot-place{
      background: rgba(8,47,73,0.65);
      border-radius:18px;
      padding:10px;
      cursor:default;
      white-space:normal;
      padding: 4px;
    }
    .bet-spot-place:hover,
    .bet-spot-place:active{
      transform:none;
      border-color: rgba(148,163,184,0.8);
      box-shadow:0 4px 10px rgba(0,0,0,0.5);
    }
    .spot-header{
      display:flex;
      align-items:baseline;
      justify-content:space-between;
      gap:8px;
      margin-bottom:8px;
    }
    .spot-number{ font-size:1.05rem; font-weight:900; letter-spacing:0.02em; }

    .mini-spot{
      border-radius:12px;
      border:1px solid rgba(148,163,184,0.75);
      padding:8px;
      background: rgba(2,6,23,0.35);
      cursor:pointer;
      transition: transform 0.05s ease, box-shadow 0.05s ease, border-color 0.1s ease, opacity 0.1s ease;
      text-align:left;
      white-space:nowrap;
      user-select:none;
      position:relative;
      overflow:hidden;
    }
    .mini-spot:hover{ transform: translateY(-1px); box-shadow:0 6px 14px rgba(0,0,0,0.7); border-color:#facc15; }
    .mini-spot:active{ transform: translateY(0); box-shadow:0 4px 10px rgba(0,0,0,0.5); }
    /* COME and ODDS each get half a payout column; at 0.7rem/0.08em they were
       cut off by a few pixels at every width, so the tracking comes in */
    .mini-label{ font-size:0.62rem; text-transform:uppercase; letter-spacing:0.03em; opacity:0.9; }
    /* a five-figure bet is wider than the Buy/Come/Odds cell: ellipsise it so a
       clipped amount reads as truncated instead of as a smaller number */
    .mini-amt{
      margin-top:4px;
      font-weight:900;
      color:#f97316;
      font-size:0.85rem;
      overflow:hidden;
      text-overflow:ellipsis;
      font-variant-numeric: tabular-nums;
    }

    .mini-spot.disabled{ opacity:0.45; cursor:not-allowed; transform:none !important; box-shadow:none !important; }
    .mini-spot.disabled:hover{ border-color: rgba(148,163,184,0.75) !important; }

    /* the Come/Odds pair is the tightest thing on the felt — each cell is half a
       payout column, so the gap and their side padding buy the labels their
       last few pixels rather than the text being cut */
    .come-row{ display:grid; grid-template-columns: 1fr 1fr; gap:5px; margin-top:8px; }
    .come-row .mini-spot{ padding-inline:5px; }
    .come-readonly{
      opacity:0.8;
      cursor:default;
      pointer-events:none;
    }

    /* Chip rack + buttons */
    .chip-bar{
      margin-top:10px;
      display:flex;
      flex-wrap:wrap;
      gap:8px;
      align-items:left;
    }

    /* Casino chip */
    .chip{
      --chip-base: #e5e7eb;
      --chip-ring: rgba(15,23,42,0.85);
      --chip-inserts: rgba(255,255,255,0.92);
      --chip-label: #111827;

      flex:0 0 auto;      /* a chip never squashes into its neighbours */
      width:48px;
      height:48px;
      border-radius:999px;
      border:3px solid rgba(15,23,42,0.92);
      display:flex;
      align-items:center;
      justify-content:center;
      font-weight:900;
      font-size:0.8rem;
      cursor:pointer;
      user-select:none;
      position:relative;
      transition: transform 0.05s ease, box-shadow 0.05s ease, outline 0.1s ease;

      background:
        radial-gradient(circle at 30% 28%,
          color-mix(in srgb, var(--chip-base) 92%, #000 8%) 38%,
          color-mix(in srgb, var(--chip-base) 72%, #000 28%) 100%
        );
    }

    .chip::before{
      content:"";
      position:absolute;
      inset:2px;
      border-radius:999px;
      pointer-events:none;
      background: repeating-conic-gradient(
        from 0deg,
        var(--chip-inserts) 0deg 10deg,
        transparent 10deg 20deg
      );
      -webkit-mask: radial-gradient(circle, transparent 0 60%, #000 61% 100%);
              mask: radial-gradient(circle, transparent 0 60%, #000 61% 100%);
      opacity:0.95;
    }

    .chip::after{
      content:"";
      position:absolute;
      inset:7px;
      border-radius:999px;
      pointer-events:none;
      border:2px dashed var(--chip-ring);
      opacity:0.95;
    }

    .chip span{
      position:relative;
      z-index:1;
      color: var(--chip-label);
      text-shadow: 0 1px 0 rgba(0,0,0,0.25);
    }

    .chip.selected{
      outline:2px solid #facc15;
      transform: translateY(-1px) scale(1.03);
      box-shadow:
        0 10px 22px rgba(0,0,0,0.95),
        inset 0 2px 8px rgba(255,255,255,0.10),
        inset 0 -10px 18px rgba(0,0,0,0.35);
    }

    /* --- Denomination colorways --- */
    .chip[data-chip="100"]{
      --chip-base: #f1f5f9;
      --chip-ring: rgba(15,23,42,0.85);
      --chip-inserts: rgba(15,23,42,0.85);
      --chip-label: #0f172a;
    }
    .chip[data-chip="500"]{
      --chip-base: #dc2626;
      --chip-ring: rgba(255,255,255,0.92);
      --chip-inserts: rgba(255,255,255,0.92);
      --chip-label: #ffffff;
    }
    .chip[data-chip="2500"]{
      --chip-base: #16a34a;
      --chip-ring: rgba(255,255,255,0.92);
      --chip-inserts: rgba(255,255,255,0.92);
      --chip-label: #ffffff;
    }
    .chip[data-chip="10000"]{
      --chip-base: #111827;
      --chip-ring: rgba(248,250,252,0.95);
      --chip-inserts: rgba(248,250,252,0.95);
      --chip-label: #f8fafc;
    }
    .chip[data-chip="50000"]{
      --chip-base: #7c3aed;
      --chip-ring: rgba(248,250,252,0.95);
      --chip-inserts: rgba(248,250,252,0.95);
      --chip-label: #f8fafc;
    }

    button{
      border:none;
      border-radius:999px;
      padding:8px 14px;
      font-size:0.9rem;
      cursor:pointer;
      background:#16a34a;
      color:#f9fafb;
      font-weight:800;
      box-shadow:0 4px 12px rgba(0,0,0,0.4);
      transition: transform 0.06s ease, box-shadow 0.06s ease, background 0.1s ease;
      white-space:nowrap;
      user-select:none;
      -webkit-tap-highlight-color: transparent;
      touch-action: manipulation;
    }
    button.secondary{ background:#374151; }
    button.danger{ background:#b91c1c; }
    button:disabled{ opacity:0.5; cursor:not-allowed; box-shadow:none; }
    button:hover:not(:disabled){ transform: translateY(-1px); box-shadow:0 6px 16px rgba(0,0,0,0.6); }
    button:active:not(:disabled){ transform: scale(.96); box-shadow:0 3px 8px rgba(0,0,0,0.5); }
    button:focus-visible{ outline:2px solid #facc15; outline-offset:2px; }
    @media (prefers-reduced-motion: reduce){
      button:active:not(:disabled), button:hover:not(:disabled){ transform:none; }
    }

    .chip-hint{ font-size:0.75rem; text-align:center; color:#e5e7eb; margin-top:6px; }

    /* Side-bets / Bonus toggles */
    .table-toggles{
      display:flex;
      gap:8px;
      flex-wrap:wrap;
      align-items:center;
      margin: 10px 0 10px;
    }
    .table-toggles .toggle-group{
      display:flex;
      gap:8px;
      align-items:center;
      flex-wrap:wrap;
    }
    .table-toggles .toggle-label{
      font-size:0.75rem;
      letter-spacing:0.06em;
      text-transform:uppercase;
      color:#e5e7eb;
      opacity:0.9;
      margin-right:2px;
    }
    .is-hidden{ display:none !important; }


    /* Dice */
    .dice-display{
      display:flex; gap:12px; align-items:center; margin-top:4px; flex-wrap:wrap;
    }
    .die{
      width:64px; height:64px;
      border-radius:12px;
      background:#fff;
      border:2px solid #111827;
      display:flex; align-items:center; justify-content:center;
      color:#111827;
      font-weight:900;
      font-size:4.2rem;
      box-shadow:0 4px 12px rgba(0,0,0,0.6);
    }
    .total-display{ margin-left:8px; font-weight:900; }

    .status{ font-size:0.95rem; margin-top:6px; min-height:1.1em; }
    .status.good{ color:#4ade80; }
    .status.bad{ color:#f97373; }
    .status.neutral{ color:#e5e7eb; }

    #log{
      max-height: 280px;
      overflow-y:auto;
      font-size:0.85rem;
      border-radius:10px;
      background: rgba(0,0,0,0.6);
      padding:8px;
      border:1px solid rgba(255,255,255,0.06);
    }
    .log-entry{ margin-bottom:4px; }
    .log-entry span.total{ font-weight:900; }
    .log-entry.win{ color:#6ee7b7; }
    .log-entry.lose{ color:#fca5a5; }
    .log-entry.side{ color:#e5e7eb; }

    .money-win{ color:#6ee7b7; font-weight:900; }
    .money-lose{ color:#fca5a5; font-weight:900; }

    .btn-small{ padding:6px 10px; font-size:0.8rem; }

    .come-odds-bar{
      display:none;
      margin-top:10px;
      border-radius:16px;
      border:1px solid rgba(148,163,184,0.65);
      background: rgba(2,6,23,0.35);
      padding:10px;
      box-shadow: 0 6px 14px rgba(0,0,0,0.45);
    }
    .come-odds-bar.show{ display:block; }
    .come-odds-top{
      display:flex;
      align-items:center;
      justify-content:space-between;
      gap:10px;
      margin-bottom:6px;
    }
    .come-odds-title{
      font-weight:900;
      letter-spacing:0.08em;
      text-transform:uppercase;
      font-size:0.8rem;
    }
    .come-odds-info{
      font-size:0.8rem;
      color:#e5e7eb;
      opacity:0.9;
      margin-bottom:8px;
    }
    .come-odds-actions{
      display:flex;
      flex-wrap:wrap;
      gap:8px;
      justify-content:center;
    }
    .come-odds-actions button{
      background:#1d4ed8;
    }
    .come-odds-actions button.secondary{
      background:#374151;
    }

    /* Bonus trackers */
    .bonus-tracker{
      margin-top:6px;
      display:flex;
      flex-wrap:wrap;
      gap:4px;
      justify-content:center;
      align-items:center;
    }
    .bonus-pill{
      width:24px;
      height:22px;
      border-radius:8px;
      border:1px solid rgba(148,163,184,0.75);
      background: rgba(2,6,23,0.35);
      display:flex;
      align-items:center;
      justify-content:center;
      font-weight:900;
      font-size:0.75rem;
      color:#e5e7eb;
      user-select:none;
    }
    .bonus-pill.hit{
      background: rgba(34,197,94,0.25);
      border-color: rgba(34,197,94,0.85);
      color:#d1fae5;
      box-shadow:0 0 0 1px rgba(34,197,94,0.15) inset;
    }
    .bonus-pill.dead{
      background: rgba(239,68,68,0.18);
      border-color: rgba(239,68,68,0.8);
      color:#fecaca;
    }

    /* --- HOT ROLL BORDER FX --- */
/* Border-only glow (no interior fill) via outline + drop-shadows. */
.roll-card{
  position: relative;
  border-radius: 16px; /* keep in sync with .card */
  overflow: visible;   /* allow glow outside */
}

.roll-card::after{
  content:"";
  position:absolute;
  inset:-10px;
  border-radius: calc(16px + 10px);
  pointer-events:none;
  opacity:0;
  border: 2px solid rgba(255,255,255,0.06);
  transition: opacity 250ms ease;
  animation: hotPulse 1.6s ease-in-out infinite;
  z-index: 5;
}

.roll-card.hot-1::after{
  opacity:0.95;
  box-shadow:
    0 0 18px rgba(255,200,80,0.65),
    0 0 42px rgba(255,140,60,0.45);
}

.roll-card.hot-2::after{
  opacity:1;
  box-shadow:
    0 0 22px rgba(255,220,110,0.75),
    0 0 52px rgba(255,120,60,0.60),
    0 0 80px rgba(255,60,50,0.35);
}

.roll-card.hot-3::after{
  opacity:1;
  box-shadow:
    0 0 26px rgba(255,235,140,0.85),
    0 0 64px rgba(255,150,85,0.75),
    0 0 110px rgba(255,40,40,0.55);
  animation: hotPulse 1.2s ease-in-out infinite;
}

/* ===== Leaderboard modal ===== */
.hidden { display:none !important; }

.modal-overlay{
  position:fixed;
  inset:0;
  background:rgba(0,0,0,0.55);
  display:flex;
  align-items:center;
  justify-content:center;
  padding:16px;
  z-index:9999;
}
.modal{
  width:min(920px, 100%);
  max-height: min(80vh, 760px);
  overflow:hidden;
  background: var(--card, #111);
  border:1px solid rgba(255,255,255,0.12);
  border-radius:16px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
  display:flex;
  flex-direction:column;
}
.modal-header{
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap:12px;
  padding:16px 16px 10px 16px;
  border-bottom:1px solid rgba(255,255,255,0.10);
}
.modal-controls{
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  gap:12px;
  padding:12px 16px 12px 16px;
  border-bottom:1px solid rgba(255,255,255,0.08);
  flex-wrap:wrap;
}
.modal-body{
  padding:14px 16px;
  overflow:auto;
}
.modal-footer{
  padding:12px 16px 16px 16px;
  display:flex;
  gap:10px;
  justify-content:flex-end;
  border-top:1px solid rgba(255,255,255,0.08);
}
.btn-sm{
  padding:6px 10px;
  border-radius:10px;
  font-size:0.9rem;
}
.field{
  display:flex;
  flex-direction:column;
  gap:6px;
  min-width: 220px;
}
.field-label{ font-size:0.9rem; opacity:0.8; }
.text-input{
  padding:10px 12px;
  border-radius:12px;
  border:1px solid rgba(255,255,255,0.18);
  background: rgba(255,255,255,0.06);
  color: inherit;
  outline:none;
}
.text-input:focus{
  border-color: rgba(255,255,255,0.35);
  background: rgba(255,255,255,0.08);
}
.tabs{
  display:flex;
  gap:8px;
  align-items:center;
}
.tab{
  padding:10px 12px;
  border-radius:999px;
  border:1px solid rgba(255,255,255,0.18);
  background: rgba(255,255,255,0.06);
  color: inherit;
  cursor:pointer;
  font-weight:700;
  font-size:0.95rem;
}
.tab.active{
  background: rgba(255,255,255,0.14);
  border-color: rgba(255,255,255,0.30);
}
.lb-table{
  width:100%;
  border-collapse:collapse;
  font-size:0.98rem;
}
.lb-table th, .lb-table td{
  padding:10px 8px;
  border-bottom:1px solid rgba(255,255,255,0.08);
  text-align:left;
  vertical-align:top;
}
.lb-table thead th{
  position:sticky;
  top:0;
  background: rgba(20,20,20,0.95);
  backdrop-filter: blur(6px);
  z-index:1;
}
.lb-table tbody tr:hover td{
  background: rgba(255,255,255,0.04);
}


@keyframes hotPulse{
  0%,100%{ transform: scale(1.00); }
  50%{ transform: scale(1.02); }
}




    /* Seven payout groups across, the eighth centred under them. The strip keeps
       the base rule's overflow-x:auto rather than going visible: seven 110px
       columns need ~818px of felt, which the log sidebar (≥1100px) and a narrow
       window don't leave — and overflowing a .table-card that clips meant the
       last two columns were cut off with no way to reach them. 104px is the
       floor that still fits seven across at the 1280px layout. */
    @media (min-width: 860px){
      .table-places-grid{
        display:grid;
        /* --place-cols is set from the game's payout-group count, so craps'
           three groups sit three across instead of being spread over seven
           tracks with the last one orphaned onto its own row */
        grid-template-columns: repeat(var(--place-cols, 7), minmax(104px, 200px));
        justify-content:center;
        gap:8px;
      }
      .payout-col{
        flex:none;
        width:auto;
        min-width:0;
      }
      /* only when there are more groups than tracks does the last one wrap */
      .table-places-grid.wrap-last .payout-col:last-child{
        grid-column: 1 / -1;
        justify-self: center;
        width: fit-content;
      }
    }

    @media (min-width: 900px){
      .table-sides [data-bet="field"],
      .table-sides [data-bet="short"],
      .table-sides [data-bet="long"],
      .table-sides [data-bet="shitshow"]{
        grid-column: 1 / -1;
      }
    }


    @media (min-width: 1100px){
      .app{
        max-width:1280px;
        display:grid;
        grid-template-columns: 1fr 360px;
        gap:12px;
        align-items:start;
      }

      #headerCard{ grid-column: 1 / -1; }
      .phase-strip{ grid-column: 1 / -1; }

      #rollCard{
        grid-column: 1;
        position: sticky;
        top: 12px;
        z-index: 20;
      }

      #tableCard{ grid-column: 1; }

      #logCard{
        grid-column: 2;
        grid-row: 3 / span 2;
        position: sticky;
        top: 12px;
        align-self: start;
      }

      #log{
        max-height: none;
        height: calc(100vh - 180px);
        overflow-y:auto;
      }
    }

    @media (max-width: 820px){
      .table-felt{ grid-template-columns: minmax(0, 1fr); }
    }
    @media (max-width: 480px){
      /* prevent any single wide button from forcing horizontal overflow */
      .stat-row button{
        max-width: 100%;
        white-space: normal;
        overflow-wrap: anywhere;
      }
    }
    /* ==================================================================
       Structure introduced by the mobile pass (2026-08): the disclaimer
       folds away, game state lives on its own strip, and the roll card's
       innards are two fixed rows so it can double as the phone dock.
       ================================================================== */

    /* collapsed legal / coffee text — one tap away, never a screenful */
    .fineprint{ margin-top:6px; }
    .fineprint summary{
      cursor:pointer;
      color:#9ca3af;
      font-size:0.8rem;
      user-select:none;
      -webkit-tap-highlight-color: transparent;
    }
    .fineprint summary:hover{ color:#e5e7eb; }
    .fineprint p{ font-size:0.85rem; }

    /* game-state strip: phase · working · point · bankroll */
    .phase-strip{
      display:flex;
      align-items:center;
      gap:8px;
      flex-wrap:nowrap;
      margin-bottom:16px;
      padding:10px 14px;
      border-radius:14px;
      background: rgba(20,20,20,0.9);
      border:1px solid rgba(255,255,255,0.06);
      box-shadow:0 10px 30px rgba(0,0,0,0.5);
      font-size:0.85rem;
      white-space:nowrap;
    }
    .strip-state{
      display:flex;
      align-items:center;
      gap:8px;
      flex:1 1 auto;
      min-width:0;
      overflow-x:auto;
      scrollbar-width:none;
    }
    .strip-state::-webkit-scrollbar{ display:none; }
    #pointInfo{ color:#e5e7eb; }
    .strip-cash{
      flex:0 0 auto;
      margin-left:auto;
      padding-left:8px;
      font-weight:900;
      color:#f9fafb;
      font-variant-numeric: tabular-nums;
    }

    /* roll card rows: dice+result | chips+roll — fixed-height slots so a
       landing number never nudges the button being tapped */
    .dice-row{
      display:flex;
      align-items:center;
      gap:12px;
      margin-top:4px;
    }
    .dice-row .dice-display{ margin-top:0; flex:0 0 auto; flex-wrap:nowrap; gap:8px; }
    .dice-row .status{
      flex:1 1 auto;
      margin-top:0;
      min-height:2.4em;
      display:flex;
      align-items:center;
      overflow:hidden;
    }
    .total-display{ font-variant-numeric: tabular-nums; }
    .roll-controls{
      display:flex;
      align-items:center;
      gap:10px;
      margin-top:12px;
    }
    .roll-controls .chip-bar{ margin-top:0; flex:1 1 auto; flex-wrap:nowrap; }
    #rollBtn{
      flex:1 0 96px;
      min-height:48px;
      font-size:1.05rem;
      letter-spacing:0.02em;
      background: linear-gradient(180deg, #22c55e, #15803d);
      border-radius:14px;
    }
    #rollBtn:hover:not(:disabled){ background: linear-gradient(180deg, #26d065, #167f40); }
    @media (min-width: 641px){
      .roll-controls{ justify-content:flex-start; }
      .roll-controls .chip-bar{ flex:0 1 auto; }
      #rollBtn{ flex:0 0 auto; min-width:150px; padding-inline:30px; margin-left:auto; }
    }

    /* ==================================================================
       Phone layout (≤640px): one-thumb play.
       Sticky state strip up top, the roll card pinned to the bottom as a
       glass dock, the table scrolling between them.
       ================================================================== */
    @media (max-width: 640px){
      .app{ padding:10px 10px 0; }
      .card{ padding:14px; border-radius:14px; margin-bottom:12px; }
      h1{ font-size:1.45rem; }
      h2{ font-size:1.05rem; }

      /* room for the fixed dock (+ iPhone home bar) */
      body{ padding-bottom: calc(150px + env(safe-area-inset-bottom)); }

      /* --- stats: compact 3-across tiles, buttons 2×2 --- */
      .stat-grid{
        display:grid;
        grid-template-columns: repeat(3, 1fr);
        gap:6px;
      }
      .stat-grid .stat-box{ min-width:0; padding:7px 8px; border-radius:10px; }
      .stat-label{ font-size:0.6rem; letter-spacing:0.05em; }
      .stat-grid .stat-value{ font-size:0.95rem; }
      .action-row{
        display:grid;
        grid-template-columns: 1fr 1fr;
        gap:8px;
      }
      .action-row .stat-btn{ min-height:44px; padding-inline:8px; }

      /* --- sticky game-state strip --- */
      .phase-strip{
        position:sticky;
        top:0;
        z-index:40;
        margin:0 -10px 12px;
        border-radius:0 0 14px 14px;
        border-top:none;
        padding:9px 12px;
        background: rgba(11,15,20,0.85);
        -webkit-backdrop-filter: blur(14px) saturate(1.3);
        backdrop-filter: blur(14px) saturate(1.3);
      }

      /* --- the dock --- */
      #rollCard{
        position:fixed;
        left:0; right:0; bottom:0;
        z-index:50;
        margin:0;
        border-radius:18px 18px 0 0;
        border:1px solid rgba(255,255,255,0.09);
        border-bottom:none;
        background: rgba(13,17,23,0.88);
        -webkit-backdrop-filter: blur(18px) saturate(1.4);
        backdrop-filter: blur(18px) saturate(1.4);
        box-shadow: 0 -12px 34px rgba(0,0,0,0.55);
        padding:10px 12px calc(10px + env(safe-area-inset-bottom));
      }
      #rollCard h2{ display:none; }

      .dice-row{ gap:10px; margin-top:0; }
      .die{
        width:36px; height:36px;
        border-radius:9px;
        font-size:2.3rem;
        border-width:1px;
        box-shadow:0 2px 6px rgba(0,0,0,0.5);
      }
      .dice-row .dice-display{ gap:6px; }
      .total-display{ margin-left:2px; font-size:1rem; }
      .dice-row .status{ font-size:0.82rem; line-height:1.2; min-height:36px; }

      .roll-controls{ margin-top:10px; gap:8px; }
      /* if a very narrow phone can't fit rack + Roll, the rack scrolls —
         the Roll button itself never shrinks or moves */
      .roll-controls .chip-bar{
        overflow-x:auto;
        scrollbar-width:none;
        -webkit-overflow-scrolling:touch;
        overscroll-behavior-x:contain;
        padding:2px 0;
      }
      .roll-controls .chip-bar::-webkit-scrollbar{ display:none; }
      .chip{ width:42px; height:42px; font-size:0.72rem; border-width:2px; }
      .chip::after{ inset:5px; }
      #rollBtn{ min-height:52px; }

      /* --- table: full-width tap targets, one column --- */
      .table-felt{ padding:10px; gap:10px; }

      /* 27px pills were a thumb-width miss away from "Go Across (Buy)", which
         spends real chips — give the table's controls a proper target */
      .table-toggles{ gap:6px; }
      .table-toggles button,
      .table-places-title button{ min-height:40px; padding:8px 12px; }

      /* A 999px radius only reads as a bubble while the spot stays one line
         tall. At phone width every subtitle wraps, so the spot becomes an
         ellipse that clips its own title and payout against the curve — round
         the corners instead and let the text wrap rather than run off. */
      .bet-spot{
        border-radius:16px;
        padding:10px 12px;
        min-height:48px;
        white-space:normal;
        overflow-wrap:anywhere;
      }
      .bet-title{ font-size:0.72rem; }
      .bet-subtitle{ font-size:0.66rem; }
      .bet-amount{ margin-top:4px; font-variant-numeric: tabular-nums; }

      /* Short side bets pair up two-across; the ones carrying a tracker or a
         long payout line keep the full width. Halves the scroll between the
         line bets and the Buy strip. */
      .table-sides{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
      .table-sides [data-bet="field"],
      .table-sides [data-bet="short"],
      .table-sides [data-bet="long"],
      .table-sides [data-bet="shitshow"]{
        grid-column: 1 / -1;
      }
      .table-places-grid{
        overflow-x:auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        scroll-snap-type: x proximity;
        scrollbar-width:none;
      }
      .table-places-grid::-webkit-scrollbar{ display:none; }
      /* the Come/Odds pair splits the column in half, so 118px was too narrow
         for the labels even at the tighter tracking */
      .payout-col{ scroll-snap-align:start; flex-basis:130px; width:130px; }
      .mini-spot{ padding:9px 7px; }

      /* At phone width those shared columns are too narrow to split Come and
         Odds side by side, so the pair stacks rather than being cut off. */
      .table-places-grid.few-cols{ scroll-snap-type:none; }
      .table-places-grid.few-cols .come-row{ grid-template-columns: minmax(0, 1fr); gap:5px; }

      #log{ max-height:200px; }

      /* modal fits the phone */
      .modal{ max-height: calc(100dvh - 24px); }
      .modal-controls{ align-items:stretch; flex-direction:column; }
    }

    /* very small phones: keep the dock lean */
    @media (max-width: 360px){
      .chip{ width:38px; height:38px; }
      .die{ width:32px; height:32px; font-size:2rem; }
      #rollBtn{ flex-basis:84px; }
    }

    /* ==================================================================
       Game switcher — the one control that makes this a dice section
       rather than a single game. Segmented, thumb-sized, and the first
       thing on the page so the current game is never in doubt.
       ================================================================== */
    .game-switch{
      display:flex;
      gap:4px;
      margin:0 0 10px;
      padding:4px;
      width:fit-content;
      max-width:100%;
      border-radius:999px;
      background: rgba(2,6,23,0.55);
      border:1px solid rgba(148,163,184,0.35);
    }
    .game-tab{
      background:transparent;
      color:#cbd5e1;
      box-shadow:none;
      padding:8px 18px;
      font-size:0.9rem;
      min-height:40px;
      white-space:nowrap;
    }
    .game-tab:hover:not(.active){ background: rgba(148,163,184,0.14); transform:none; box-shadow:none; }
    .game-tab.active{
      background: linear-gradient(180deg, #22c55e, #15803d);
      color:#f9fafb;
      box-shadow:0 4px 12px rgba(0,0,0,0.45);
    }

    @media (max-width: 640px){
      /* full width, two equal halves — switching games is a one-thumb tap */
      .game-switch{ width:100%; }
      .game-tab{ flex:1 1 0; padding:8px 10px; min-height:44px; }
    }
