/* ============================================================
   BET BOYZ — "LIQUID GLASS" design tokens
   Source of truth: Claude Design project 638ecafd, turn 6
   ("Liquid Glass — four screens"). Replaces NIGHT CLUBHOUSE.

   Dark only. There is no light theme — the aurora backdrop is
   the design. The recap PNG and settlement email keep their own
   light values (see §6.6 of spec.md), which are NOT tokens here.

   Fonts: Sora (display + UI), JetBrains Mono (ALL numbers).
   Load: Google Fonts — Sora 400/500/600/700/800,
         JetBrains Mono 500/600/700/800.

   THREE STRUCTURAL RULES — the whole system depends on them:
   1. Numbers NEVER sit on blur alone. Any element containing a
      line, score, margin, or dollar amount gets a solid core
      (--core / --core-dim) with a glass rim. Blur behind digits
      is the single fastest way to make this design unreadable.
   2. Glass depth is capped at THREE levels: backdrop (aurora) →
      card → floating (nav, sheet). Never nest a fourth.
   3. Bandit sits on a glass tile, never directly on the aurora.
   ============================================================ */

:root {
  /* ---- Ground ---- */
  --bg: #0e0b18;              /* page base, under the aurora */
  --bg-deep: #0c0b10;         /* outside the app frame */

  /* ---- Aurora light sources (backdrop layer) ----
     Three blurred orbs, position varies per screen. Never more
     than three. Blur 80-95px, opacity .35-.75. Layer is
     pointer-events:none and sits at inset:0 behind everything. */
  --aurora-purple: #6b3fd4;
  --aurora-pink:   #c2418a;
  --aurora-blue:   #2f6ad9;
  --aurora-green:  #1f9d6b;   /* Money screen only — money-in hue */

  /* ---- Glass surfaces (card layer) ---- */
  --glass:          rgba(255, 255, 255, .09);   /* standard card */
  --glass-raised:   rgba(255, 255, 255, .10);   /* hero / primary card */
  --glass-floating: rgba(255, 255, 255, .12);   /* bottom nav */
  --glass-sheet:    rgba(255, 255, 255, .13);   /* pick slip, search pill */
  --glass-chip:     rgba(255, 255, 255, .14);   /* chips, Bandit tile */
  --glass-quiet:    rgba(255, 255, 255, .08);   /* inactive tabs, ghost buttons */

  --glass-blur:          blur(26px);   /* cards */
  --glass-blur-raised:   blur(28px);   /* hero cards */
  --glass-blur-floating: blur(30px);   /* nav, docked search */
  --glass-blur-sheet:    blur(36px) saturate(1.4);  /* bottom sheet only */

  /* ---- Glass edges ---- */
  --rim:          rgba(255, 255, 255, .18);  /* standard card border */
  --rim-bright:   rgba(255, 255, 255, .24);  /* floating / chip border */
  --rim-quiet:    rgba(255, 255, 255, .14);  /* inactive controls */
  --rim-hairline: rgba(255, 255, 255, .10);  /* dividers inside a card */

  /* Top-edge specular highlight. Every glass surface gets one —
     it is what separates "glass" from "translucent grey box". */
  --sheen:        inset 0 1px 0 rgba(255, 255, 255, .28);
  --sheen-bright: inset 0 1px 0 rgba(255, 255, 255, .35);
  --sheen-sheet:  inset 0 1px 0 rgba(255, 255, 255, .40);

  /* ---- Solid cores — RULE 1. Numbers live here. ---- */
  --core:      rgba(14, 11, 24, .62);   /* odds cells, stat wells */
  --core-soft: rgba(14, 11, 24, .55);   /* inline stat strip on a hero card */
  --core-dim:  rgba(14, 11, 24, .45);   /* locked / unavailable cells */
  --core-rim:      rgba(255, 255, 255, .20);
  --core-rim-dim:  rgba(255, 255, 255, .10);
  --core-sheen:    inset 0 1px 0 rgba(255, 255, 255, .22);

  /* ---- Drop shadows ---- */
  --shadow-card:     0 14px 36px rgba(0, 0, 0, .42);
  --shadow-raised:   0 16px 40px rgba(0, 0, 0, .42);
  --shadow-tile:     0 12px 30px rgba(0, 0, 0, .35);
  --shadow-floating: 0 10px 30px rgba(0, 0, 0, .45);
  --shadow-sheet:    0 -14px 44px rgba(0, 0, 0, .55);
  --shadow-logo:     0 3px 10px rgba(0, 0, 0, .35);
  --shadow-bandit:   drop-shadow(0 8px 18px rgba(0, 0, 0, .5));

  /* ---- Text ---- */
  --text:          #f4f1fc;
  --text-muted:    #b7abd8;
  --text-faint:    #9e92c4;
  --text-disabled: #6d6392;
  --text-on-glass: #d8cfef;   /* label text inside a tinted control */

  /* ---- Purple = interactive, selection, "you". Nothing else. ---- */
  --purple:      #a687f5;
  --purple-fill: rgba(166, 135, 245, .45);  /* selected chip, primary button */
  --purple-fill-strong: rgba(166, 135, 245, .55);  /* confirm CTA */
  --purple-fill-soft:   rgba(166, 135, 245, .32);  /* picked cell, locked */
  --purple-rim:  rgba(255, 255, 255, .32);
  --purple-glow: 0 0 22px rgba(166, 135, 245, .35);
  --purple-glow-strong: 0 0 20px rgba(166, 135, 245, .50);
  --purple-text: #ece4ff;
  --purple-text-soft: #ded4fb;

  /* ---- Gold = rank flair and Top 25 ONLY. Never an action. ---- */
  --gold: #ffd97a;
  --gold-fill: rgba(255, 217, 122, .16);
  --gold-rim:  rgba(255, 217, 122, .40);

  /* ---- Green = winning and money-in ONLY. Never an action. ---- */
  --win: #4bE8a8;
  --win-soft: #8ff5c8;
  --win-fill: rgba(75, 232, 168, .28);
  --win-fill-quiet: rgba(75, 232, 168, .16);
  --win-rim: rgba(75, 232, 168, .55);
  --win-rim-quiet: rgba(75, 232, 168, .40);
  --win-glow: 0 0 24px rgba(75, 232, 168, .35);

  /* ---- Red = losing, money-out, LIVE. Never an action. ---- */
  --loss: #ff7a8d;
  --loss-soft: #ff9db0;
  --loss-softer: #ffb3c2;
  --loss-fill: rgba(255, 105, 135, .20);
  --loss-fill-quiet: rgba(255, 105, 135, .14);
  --loss-surface: rgba(255, 105, 135, .16);  /* shame wall, live-losing strip */
  --loss-rim: rgba(255, 140, 165, .38);
  --loss-rim-quiet: rgba(255, 140, 165, .34);
  --live-dot-glow: 0 0 8px #ff7a8d;

  /* ---- Radius ---- */
  --radius-card:  26px;  /* contest cards, game cards, panels */
  --radius-tile:  22px;  /* half-width tiles, inline strips, alert cards */
  --radius-well:  18px;  /* stat strip inside a card */
  --radius-cell:  16px;  /* odds cells, result strips */
  --radius-chip:  12px;  /* Bandit tile */
  --radius-sheet: 32px;  /* bottom sheet, top corners only */
  --radius-pill:  50px;  /* nav, tabs, chips, buttons, search */

  /* ---- Type ---- */
  --font-ui:   'Sora', system-ui, sans-serif;
  --font-num:  'JetBrains Mono', ui-monospace, Menlo, monospace;

  --t-h1:      700 24px/1.2 var(--font-ui);   /* page title, -.03em */
  --t-h2:      700 17px var(--font-ui);       /* card title, -.02em */
  --t-body:    500 12px var(--font-ui);
  --t-strong:  600 13px var(--font-ui);
  --t-label:   600 10px var(--font-ui);       /* .1em tracking, caps */
  --t-chip:    700 10px var(--font-ui);       /* .08em tracking, caps */

  --n-hero:    800 36px var(--font-num);      /* season net, -.03em */
  --n-score:   800 19px var(--font-num);      /* live score */
  --n-line:    700 16px var(--font-num);      /* odds cell value */
  --n-stat:    700 13px var(--font-num);      /* margin, dollar amounts */
  --n-meta:    500 10px var(--font-num);      /* team records, timestamps */

  /* ---- Motion ---- */
  --pulse: pulse-live 1.6s ease-in-out infinite;  /* LIVE dot only */
}

@keyframes pulse-live {
  0%, 100% { opacity: 1; }
  50%      { opacity: .35; }
}

/* Nothing moves on hover. Press states only — see spec §6.4. */
@media (prefers-reduced-motion: reduce) {
  :root { --pulse: none; }
  * { animation: none !important; transition: none !important; }
}

/* ============================================================
   COMPOSED PATTERNS — copy these, don't re-derive them.
   ============================================================ */

/* Backdrop layer. One per screen, first child, behind everything. */
.aurora {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.aurora > i {
  position: absolute;
  border-radius: 50%;
  display: block;
}
/* Standard placement (Home / Games / Pick slip):
   1: 340px  purple  left:-90..-100px  top:-110..-120px  blur(80px)  opacity .70-.75
   2: 280-300px blue right:-100..-110px top:120..200px   blur(95px)  opacity .40-.42
   3: 300-320px pink left:-60..-70px   bottom:-120..-130px blur(95px) opacity .35-.40
   Money swaps orb 1 for --aurora-green at right:-90px top:-100px, opacity .50. */

/* Standard card */
.glass-card {
  background: var(--glass);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--rim);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card), var(--sheen);
}

/* Odds cell — RULE 1 in practice. Default / picked / locked. */
.odds-cell {
  border-radius: var(--radius-cell);
  background: var(--core);
  border: 1px solid var(--core-rim);
  box-shadow: var(--core-sheen);
  padding: 9px 4px;
  text-align: center;
}
.odds-cell .value { font: var(--n-line); }
.odds-cell .source {
  font: 600 8px var(--font-ui);
  letter-spacing: .1em;
  color: var(--text-faint);
}
.odds-cell[aria-pressed="true"] {
  background: rgba(166, 135, 245, .50);
  border-color: rgba(255, 255, 255, .40);
  box-shadow: var(--purple-glow-strong), inset 0 1px 0 rgba(255, 255, 255, .45);
}
.odds-cell[aria-pressed="true"] .source { color: var(--purple-text); }
.odds-cell[aria-disabled="true"] {
  background: var(--core-dim);
  border-color: var(--core-rim-dim);
  box-shadow: none;
  color: var(--text-disabled);
}
/* A picked cell on a locked game keeps identity but drops the glow. */
.odds-cell[aria-pressed="true"][aria-disabled="true"] {
  background: var(--purple-fill-soft);
  border-color: rgba(255, 255, 255, .34);
  box-shadow: var(--core-sheen);
  color: #e5daff;
}

/* Floating bottom nav — the third and last glass level. */
.nav-float {
  background: var(--glass-floating);
  backdrop-filter: var(--glass-blur-floating);
  -webkit-backdrop-filter: var(--glass-blur-floating);
  border: 1px solid var(--rim-bright);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-floating), var(--sheen-bright);
  padding: 8px;
}
.nav-float .active {
  background: var(--purple-fill);
  border: 1px solid rgba(255, 255, 255, .30);
  border-radius: var(--radius-pill);
  box-shadow: var(--sheen-bright);
  padding: 8px 15px;
  font: 700 12px var(--font-ui);
}

/* Bottom sheet (pick slip). Content behind it dims via
   filter: brightness(.6) saturate(.85) on the page wrapper. */
.sheet {
  background: var(--glass-sheet);
  backdrop-filter: var(--glass-blur-sheet);
  -webkit-backdrop-filter: var(--glass-blur-sheet);
  border-top: 1px solid rgba(255, 255, 255, .28);
  border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
  box-shadow: var(--shadow-sheet), var(--sheen-sheet);
}
.sheet .grabber {
  width: 42px; height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, .34);
  margin: 0 auto 16px;
}

/* Team logo puck — white disc so real logos read on the aurora. */
.logo-puck {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .94);
  box-shadow: var(--shadow-logo);
  display: flex; align-items: center; justify-content: center;
  flex: none;
}

/* Bandit tile — RULE 3. */
.bandit-tile {
  width: 34px; height: 34px;
  border-radius: var(--radius-chip);
  background: var(--glass-chip);
  border: 1px solid var(--rim-bright);
  box-shadow: var(--sheen-bright);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}

* { box-sizing: border-box; }
html { background: var(--bg-deep); }
body { margin: 0; min-width: 320px; min-height: 100vh; background: var(--bg-deep); color: var(--text); font: 500 14px/1.5 var(--font-ui); }
button, input, select { font: inherit; }
h1 { margin: .25rem 0 .6rem; font: var(--t-h1); letter-spacing: -.03em; }
h2 { font: var(--t-h2); letter-spacing: -.02em; }
h3 { font: 700 14px var(--font-ui); }
p { color: var(--text-muted); }
a { color: var(--purple-text-soft); font-weight: 700; text-decoration: none; }
code, time, td:not(:nth-child(2)), .numeric, .margin-value, .shame-number, [data-testid="deadline-countdown"], .market-cell, .market-empty, .season-net-hero strong, .ledger-row > strong, .game-meta strong { font-family: var(--font-num); }

.screen { position: relative; isolation: isolate; min-height: 100vh; overflow: hidden; background: var(--bg); }
.screen-content { position: relative; z-index: 1; min-height: 100vh; }
.aurora > i:nth-child(1) { width: 340px; height: 340px; left: -90px; top: -110px; background: var(--aurora-purple); filter: blur(80px); opacity: .75; }
.aurora > i:nth-child(2) { width: 290px; height: 290px; right: -100px; top: 160px; background: var(--aurora-blue); filter: blur(95px); opacity: .42; }
.aurora > i:nth-child(3) { width: 310px; height: 310px; left: -65px; bottom: -125px; background: var(--aurora-pink); filter: blur(95px); opacity: .38; }
.money-screen .aurora > i:nth-child(1) { left: auto; right: -90px; top: -100px; width: 330px; height: 330px; background: var(--aurora-green); filter: blur(85px); opacity: .5; }
.money-screen .aurora > i:nth-child(2) { right: auto; left: -100px; top: 140px; width: 320px; height: 320px; background: var(--aurora-purple); filter: blur(85px); opacity: .6; }
.money-screen .aurora > i:nth-child(3) { left: auto; right: -80px; bottom: -120px; width: 300px; height: 300px; opacity: .4; }

/* The orb sizes above are drawn from the 390px mockups. Left fixed, three ~300px
   blobs pinned to the corners of a 1120px page leave the whole middle unlit, and
   the cards then read as flat grey panels instead of glass. Scale the light
   sources with the viewport so the aurora actually reaches the content. */
@media (min-width: 700px) {
  .aurora > i:nth-child(1) { width: 62vw; height: 62vw; left: -14vw; top: -22vw; filter: blur(130px); opacity: .62; }
  .aurora > i:nth-child(2) { width: 54vw; height: 54vw; right: -12vw; top: 8vw; filter: blur(150px); opacity: .38; }
  .aurora > i:nth-child(3) { width: 58vw; height: 58vw; left: 12vw; bottom: -26vw; filter: blur(150px); opacity: .34; }
  .money-screen .aurora > i:nth-child(1) { right: -12vw; left: auto; top: -20vw; width: 58vw; height: 58vw; filter: blur(135px); opacity: .44; }
  .money-screen .aurora > i:nth-child(2) { left: -14vw; right: auto; top: 6vw; width: 58vw; height: 58vw; filter: blur(140px); opacity: .5; }
  .money-screen .aurora > i:nth-child(3) { right: -10vw; left: auto; bottom: -24vw; width: 54vw; height: 54vw; filter: blur(150px); opacity: .36; }
}

main { width: min(1120px, calc(100% - 32px)); margin: 30px auto 110px; }
.card {
  margin-bottom: 16px;
  padding: 20px;
  background: var(--glass);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--rim);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card), var(--sheen);
}
button { min-height: 44px; padding: 10px 18px; border: 1px solid var(--purple-rim); border-radius: var(--radius-pill); color: var(--text); background: var(--purple-fill); box-shadow: var(--sheen-bright); cursor: pointer; font-weight: 700; }
button:active:not(:disabled), a.pay-button:active { transform: scale(.98); }
button:disabled { cursor: not-allowed; opacity: .62; }
button:hover:not(:disabled), a:hover { filter: brightness(1.06); }
button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible, summary:focus-visible { outline: 3px solid var(--purple); outline-offset: 3px; }
.secondary, .tabs button, .chips button, .close, .user-dropdown button, .sort-toggle button { background: var(--glass-quiet); border-color: var(--rim-quiet); color: var(--text-on-glass); }
.selected, .tabs button.selected, .chips button.selected, .sort-toggle button.selected { background: var(--purple-fill); border-color: var(--purple-rim); box-shadow: var(--purple-glow), var(--sheen-bright); color: var(--text); }
.chips button.selected::after, .sort-toggle button.selected::after { content: " ✓"; }
input, select { width: 100%; min-height: 46px; padding: 10px 14px; color: var(--text); background: var(--core); border: 1px solid var(--core-rim); border-radius: var(--radius-pill); box-shadow: var(--core-sheen); }
/* Radios and checkboxes must opt OUT of the text-input styling above — it was
   drawing a bordered, shadowed pill box over the native control, which read as
   a stray line across the radio. */
input[type="checkbox"], input[type="radio"] { width: 22px; min-height: 22px; padding: 0; flex: none; background: none; border: 0; border-radius: 0; box-shadow: none; accent-color: var(--purple); }
label { display: grid; gap: 7px; color: var(--text-on-glass); font-weight: 700; }
form { display: grid; gap: 16px; }

.top-nav { position: sticky; z-index: 20; top: 12px; width: min(1120px, calc(100% - 32px)); margin: 12px auto; padding: 9px 13px; display: flex; align-items: center; justify-content: space-between; background: var(--glass-floating); backdrop-filter: var(--glass-blur-floating); -webkit-backdrop-filter: var(--glass-blur-floating); border: 1px solid var(--rim-bright); border-radius: var(--radius-pill); box-shadow: var(--shadow-floating), var(--sheen-bright); }
.brand { display: flex; align-items: center; gap: 9px; color: var(--text); font-weight: 800; letter-spacing: -.02em; }
.brand .bandit-tile img { width: 30px; height: 30px; object-fit: contain; }
.desktop { display: flex; align-items: center; gap: 24px; }
.user-menu { position: relative; }
.user-menu summary { min-height: 40px; display: flex; align-items: center; cursor: pointer; color: var(--text-on-glass); font-weight: 600; }
.user-dropdown { position: absolute; z-index: 30; right: 0; top: 44px; min-width: 155px; padding: 10px; display: grid; gap: 7px; background: var(--glass-floating); backdrop-filter: var(--glass-blur-floating); -webkit-backdrop-filter: var(--glass-blur-floating); border: 1px solid var(--rim-bright); border-radius: var(--radius-tile); box-shadow: var(--shadow-floating), var(--sheen-bright); }
.user-dropdown a { min-height: 42px; padding: 10px; }
.bottom { display: none; }

.auth { min-height: calc(100vh - 24px); display: grid; place-items: center; margin-top: 0; padding: 20px; }
.login-card, .form-card { width: min(500px, 100%); margin-inline: auto; }
.login-card header { justify-content: center; }
.login-card [data-testid="link-sent"] { display: grid; justify-items: center; text-align: center; }
.login-card [data-testid="link-sent"] .bandit-tile { width: 104px; height: 104px; border-radius: var(--radius-tile); }
.login-card [data-testid="link-sent"] img { width: 92px; height: 92px; object-fit: contain; }
.error, .negative { color: var(--loss-soft); }
.positive, .paid { color: var(--win); }
.neutral { color: var(--text-muted); }
.error-card { border-color: var(--loss-rim); background: var(--loss-fill-quiet); }

.page-head { display: flex; justify-content: space-between; align-items: center; gap: 16px; margin-bottom: 20px; }
.chip { display: inline-flex; align-items: center; margin: 0 5px 5px 0; padding: 5px 11px; border: 1px solid var(--rim-bright); border-radius: var(--radius-pill); background: var(--glass-chip); color: var(--text-on-glass); font: var(--t-chip); letter-spacing: .06em; text-transform: uppercase; }
.chip.live { color: var(--loss-soft); background: var(--loss-fill); border-color: var(--loss-rim); }
.chip.live::before { content: ""; width: 7px; height: 7px; margin-right: 6px; border-radius: 50%; background: var(--loss); box-shadow: var(--live-dot-glow); animation: var(--pulse); }
.chip.won, .chip.paid { color: var(--win-soft); background: var(--win-fill-quiet); border-color: var(--win-rim-quiet); }
.chip.lost { color: var(--loss-soft); background: var(--loss-fill-quiet); border-color: var(--loss-rim-quiet); }
.chip.buy-in { color: var(--win-soft); }
.dashboard-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; }
.contest-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.contest-card { display: block; color: var(--text); }
.contest-card h2 { margin-bottom: 6px; }
/* Core wells belong on the numbers themselves. `.shame-number` and the money
   hero's subline were getting one too, which read as a pile of little cards
   stacked inside a card. Numbers there stay mono and coloured, but unboxed. */
.board-progress strong, .season-net-hero strong, .my-pick h3 { display: inline-block; padding: 7px 10px; background: var(--core-soft); border: 1px solid var(--core-rim); border-radius: var(--radius-cell); box-shadow: var(--core-sheen); }
/* Contest cards: tags at the top, then a title, then ONE plain meta line.
   The date and the pick count each used to sit in their own well, which turned
   every card into a stack of ovals. */
.card-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 0; }
.card-meta { margin: 6px 0 0; color: var(--text-muted); font-size: 13px; }
.card-meta, [data-testid="deadline-countdown"] { font-family: var(--font-num); }
.chip.locks-soon { margin-left: auto; color: var(--loss-soft); background: var(--loss-fill); border-color: var(--loss-rim); font-size: 9px; }
.contest-card > p { display: block; width: fit-content; }
.chip.buy-in { background: var(--core-soft); border-color: var(--core-rim); box-shadow: var(--core-sheen); }
.invite code { display: block; margin: 12px 0; padding: 8px 10px; overflow-wrap: anywhere; color: var(--text); background: var(--core); border: 1px solid var(--core-rim); border-radius: var(--radius-cell); }
.empty { display: grid; justify-items: center; text-align: center; padding: 28px; }
.bandit-tile.bandit-large { width: 92px; height: 92px; border-radius: var(--radius-tile); box-shadow: var(--shadow-tile), var(--sheen-bright); }
.bandit-large img { width: 84px; height: 84px; object-fit: contain; filter: var(--shadow-bandit); }
.chips, .actions, .toolbar { display: flex; gap: 12px; flex-wrap: wrap; }
.extra-date { display: grid; grid-template-columns: 1fr auto; gap: 8px; }
.extra-date button { width: 46px; padding: 0; }
.add-date { justify-self: start; }

.tabs { display: flex; gap: 6px; margin: 18px 0 14px; }
.tabs button { flex: 1; }
.board-progress { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; border-radius: var(--radius-tile); }
.board-progress > span:first-of-type { flex: 1; color: var(--text-muted); }
.sort-toggle { display: flex; justify-content: flex-end; align-items: center; gap: 8px; margin-bottom: 14px; }
.sort-toggle > span, .market-head { color: var(--text-faint); font: var(--t-label); letter-spacing: .1em; }
.game-search { margin-bottom: 14px; }
/* A translucent field floating over arbitrary content is unreadable whenever
   something bright scrolls behind it. The blur stays for the glass look, but the
   fill is now mostly opaque so the text always has a stable ground. */
.game-search input { background: rgba(20, 16, 34, .92); backdrop-filter: var(--glass-blur-floating); -webkit-backdrop-filter: var(--glass-blur-floating); border-color: var(--rim-bright); box-shadow: var(--shadow-floating), var(--sheen-bright); color: var(--text); }
.game-search input::placeholder { color: var(--text-muted); opacity: 1; }
/* Half-point stepper for a custom line. */
.stepper { display: grid; grid-template-columns: 52px 1fr 52px; align-items: center; gap: 8px; }
.stepper button { min-width: 52px; min-height: 48px; padding: 0; font: 700 20px var(--font-ui); }
.stepper input { text-align: center; font-family: var(--font-num); font-weight: 700; }
.stepper input::-webkit-outer-spin-button, .stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* teams | kickoff | markets. The meta column is in the flow now rather than an
   absolutely-positioned strip, so the card no longer reserves ~58px of blank
   height at the top for a timestamp. */
.game-row { position: relative; display: grid; grid-template-columns: minmax(200px, 1fr) minmax(330px, 1.15fr); gap: 18px; align-items: center; padding-top: 20px; overflow: hidden; }
.game-row.top-25 { border-color: var(--gold-rim); }
.game-row.has-pick { box-shadow: var(--shadow-card), var(--sheen), inset 4px 0 0 var(--purple); }
.game-meta { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; max-width: 92px; text-align: center; color: var(--text-muted); font: var(--n-meta); }
.game-meta > span:first-child { white-space: normal; line-height: 1.25; }
.game-meta strong { padding: 5px 8px; color: var(--text); background: var(--core); border: 1px solid var(--core-rim); border-radius: var(--radius-cell); }
.game-meta > span:first-child, .team-line small { padding: 3px 6px; background: var(--core-dim); border: 1px solid var(--core-rim-dim); border-radius: var(--radius-cell); }
.top-25-tag, .ap-badge { color: var(--gold); background: var(--gold-fill); border: 1px solid var(--gold-rim); border-radius: var(--radius-pill); font: var(--t-chip); }
.top-25-tag { position: absolute; top: 8px; left: 14px; padding: 3px 8px; font-size: 8px; }
.ap-badge { padding: 2px 6px; }
.teams-block { display: grid; gap: 6px; }
/* Sits in the logo column, centred between the two crests — replaces the HOME
   pill, which cost real horizontal space to say what "@" says. Home is always
   the bottom line. */
.at-mark { display: block; width: 32px; text-align: center; color: var(--text-faint); font: 700 12px var(--font-ui); }
.team-line { display: grid; grid-template-columns: 32px auto minmax(0, auto) 1fr auto; align-items: center; gap: 8px; min-height: 44px; }
.logo-puck img { width: 25px; height: 25px; object-fit: contain; }
.team-logo-fallback { color: #241a38; font: 800 9px var(--font-ui); }
.team-line strong { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.team-line small { color: var(--text-faint); font: var(--n-meta); white-space: nowrap; }
.team-abbr { display: none; }
.market-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.market-head { text-align: center; }
.market-cell, .market-empty { position: relative; min-height: 58px; display: flex; flex-direction: column; align-items: center; justify-content: center; color: var(--text); font: var(--n-line); white-space: nowrap; }
/* No checkmark on a picked cell — the purple fill and glow already say it,
   and the floating ✓ collided with the line value. */
.market-cell[data-source]::after { content: attr(data-source); color: var(--text-faint); font: 600 8px var(--font-ui); letter-spacing: .1em; }
.market-empty { border-radius: var(--radius-cell); background: var(--core-dim); border: 1px solid var(--core-rim-dim); color: var(--text-disabled); }

.overlay { position: fixed; z-index: 50; inset: 0; display: flex; justify-content: flex-end; align-items: stretch; background: rgba(8, 6, 14, .58); }
.pick-slip { position: relative; width: min(460px, 100%); height: 100%; padding: 14px 18px 24px; overflow-y: auto; border-left: 1px solid var(--rim-bright); border-radius: var(--radius-sheet) 0 0 var(--radius-sheet); }
.pick-slip label { display: flex; align-items: center; gap: 11px; margin: 9px 0; padding: 13px 14px; border: 1px solid var(--rim-quiet); border-radius: 20px; background: var(--core-dim); }
.pick-slip label:has(input:checked) { background: rgba(166, 135, 245, .35); border-color: rgba(255, 255, 255, .36); box-shadow: var(--purple-glow), var(--sheen-sheet); }
.pick-slip .close { position: absolute; right: 16px; top: 24px; width: 38px; padding: 0; }
.confirm-pick { width: 100%; margin-top: 18px; background: var(--purple-fill-strong); box-shadow: 0 8px 26px rgba(166,135,245,.4), var(--sheen-sheet); }

.table-wrap { overflow-x: auto; }
/* Symbol headers let all nine columns fit a phone without sideways scrolling. */
[data-testid="season-table"] table { width: 100%; table-layout: auto; font-variant-numeric: tabular-nums; }
[data-testid="season-table"] th { font: var(--t-label); letter-spacing: .06em; color: var(--text-faint); white-space: nowrap; }
[data-testid="season-table"] th, [data-testid="season-table"] td { padding: 9px 6px; text-align: right; }
[data-testid="season-table"] th.col-rank, [data-testid="season-table"] td:first-child { width: 1%; text-align: left; }
[data-testid="season-table"] th.col-name, [data-testid="season-table"] td:nth-child(2) { text-align: left; }
@media (max-width: 640px) {
  [data-testid="season-table"] th, [data-testid="season-table"] td { padding: 8px 4px; font-size: 12px; }
  [data-testid="season-table"] td:nth-child(2) { max-width: 9ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* Symbol headers alone were not enough — nine columns still overflowed inside
     the card, so the sideways scroll just moved rather than went away. The three
     per-sport win rates are the least-used, so they drop on a phone and the
     remaining six (#, name, weeks won, record, overall %, net $) fit outright.
     Desktop keeps the full table. */
  [data-testid="season-table"] th:nth-child(6), [data-testid="season-table"] td:nth-child(6),
  [data-testid="season-table"] th:nth-child(7), [data-testid="season-table"] td:nth-child(7),
  [data-testid="season-table"] th:nth-child(8), [data-testid="season-table"] td:nth-child(8) { display: none; }
}
/* `min-width: 620px` here was the real cause of the sideways scroll on every
   table, standings included — it outranked any per-table sizing and forced a
   620px floor onto a 356px card. min() keeps the comfortable floor on desktop
   and lets tables fit the viewport on a phone. */
table { width: 100%; min-width: min(620px, 100%); border-collapse: separate; border-spacing: 0 5px; }
th, td { padding: 10px; text-align: left; border-bottom: 1px solid var(--rim-hairline); }
th { color: var(--text-faint); font: var(--t-label); letter-spacing: .08em; }
/* Every cell shares one background, so a row reads as a single solid band.
   Excluding the name column meant the aurora showed through in stripes between
   the numbers. Numbers still sit on a solid core, which is the rule that
   matters — it just extends across the whole row now. */
td { background: var(--core-soft); border-block: 1px solid var(--core-rim-dim); }
td:first-child { border-left: 1px solid var(--core-rim-dim); border-top-left-radius: var(--radius-cell); border-bottom-left-radius: var(--radius-cell); }
td:last-child { border-right: 1px solid var(--core-rim-dim); border-top-right-radius: var(--radius-cell); border-bottom-right-radius: var(--radius-cell); }
.winner td { color: var(--gold); }
[data-testid="winner-badge"] .bandit-tile { display: inline-flex; width: 34px; height: 34px; vertical-align: middle; }
[data-testid="winner-badge"] img { width: 31px; height: 31px; object-fit: contain; }
.standing-name { position: relative; padding-right: 42px; }
/* Leads the row on the left as a disclosure affordance, in flow rather than
   floated to the far edge. */
.standings-chevron { display: inline-block; width: 16px; margin-right: 7px; color: var(--text-faint); font-size: 19px; line-height: 1; text-align: center; transition: transform .15s ease; }
.standings-chevron.expanded { transform: rotate(90deg); color: var(--purple-text); }
.standing-name { cursor: pointer; }
/* Expanded picks: the line, the game, and — when live — clock and margin. */
.picks-row td { background: var(--core-dim); }
.pick-line { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 6px 0; }
.pick-label { color: var(--text); font-family: var(--font-num); font-weight: 700; }
.pick-game { color: var(--text-faint); font-size: 12px; }
.pick-live { display: inline-flex; align-items: center; gap: 8px; margin-left: auto; font-family: var(--font-num); font-weight: 700; font-size: 12px; }
.pick-clock { padding: 2px 7px; border-radius: var(--radius-chip); background: var(--loss-fill); color: var(--loss-soft); }
.margin-positive { color: var(--win); }
.margin-negative { color: var(--loss-soft); }
.margin-zero { color: var(--text-muted); }
.live-pick { display: flex; align-items: center; gap: 10px; margin: 12px 0; padding: 8px 10px; background: var(--core-soft); border: 1px solid var(--core-rim); border-radius: var(--radius-cell); font-family: var(--font-num); }
.live-winning, .live-losing { padding: 4px 9px; border-radius: var(--radius-pill); }
.live-winning { color: var(--win-soft); background: var(--win-fill-quiet); border: 1px solid var(--win-rim-quiet); }
.live-losing { color: var(--loss-soft); background: var(--loss-fill-quiet); border: 1px solid var(--loss-rim-quiet); }

.board-row { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 14px; align-items: center; }
.board-row label { display: flex; align-items: center; }
.warning { padding: 9px 12px; color: var(--gold); background: var(--gold-fill); border: 1px solid var(--gold-rim); border-radius: var(--radius-cell); }
.toast { position: fixed; z-index: 60; left: 50%; bottom: 28px; transform: translateX(-50%); padding: 12px 20px; background: var(--glass-floating); backdrop-filter: var(--glass-blur-floating); -webkit-backdrop-filter: var(--glass-blur-floating); border: 1px solid var(--rim-bright); border-radius: var(--radius-pill); box-shadow: var(--shadow-floating), var(--sheen-bright); }
.loading { min-height: 100vh; display: grid; place-items: center; font: var(--t-h1); }

.season-net-hero { display: flex; align-items: center; justify-content: space-between; gap: 14px; background: var(--glass-raised); backdrop-filter: var(--glass-blur-raised); -webkit-backdrop-filter: var(--glass-blur-raised); box-shadow: var(--shadow-raised), var(--sheen-bright); }
/* Stack the hero: label, then the big number, then the subline — each on its
   own row with real breathing room, instead of crowding onto one line. */
.season-net-hero > div { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; padding: 4px 0; }
.season-net-hero > div > span:first-child { font: var(--t-label); letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); }
.season-net-hero strong { margin: 2px 0; color: var(--win); font: var(--n-hero); letter-spacing: -.03em; text-shadow: var(--win-glow); }
.season-net-hero strong.negative { color: var(--loss); text-shadow: none; }
.season-net-hero p { margin: 0; color: var(--text-muted); font-size: 13px; }
.ledger-row { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 14px; padding: 14px 0; border-bottom: 1px solid var(--rim-hairline); }
.ledger-row > strong { padding: 6px 9px; background: var(--core); border: 1px solid var(--core-rim); border-radius: var(--radius-cell); }
.transfer-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
.transfer-actions button, .transfer-actions a { min-height: 38px; padding: 8px 12px; font-size: 12px; }
.pay-button { display: inline-flex; align-items: center; border: 1px solid var(--purple-rim); border-radius: var(--radius-pill); padding: 10px 14px; color: var(--text); background: var(--purple-fill); box-shadow: var(--sheen-bright); }
.shame-wall { display: flex; align-items: center; gap: 14px; background: var(--loss-fill-quiet); border-color: var(--loss-rim-quiet); box-shadow: var(--shadow-card), var(--sheen); }
.shame-wall h2 { color: var(--loss-softer); }
.shame-wall p { margin: 7px 0; }
/* Mono + colour carry these, no well. */
.shame-number { font-family: var(--font-num); color: var(--loss-soft); }
/* The mascot reads fine on the tinted card; a glass tile around it was one
   more nested box than this panel needs. */
.shame-bandit { width: 62px; height: auto; flex: none; align-self: flex-start; filter: var(--shadow-bandit); }
/* A link that acts like a primary action should look like one. */
.settle-up { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; margin-top: 10px; padding: 10px 20px; border: 1px solid var(--purple-rim); border-radius: var(--radius-pill); background: var(--purple-fill); box-shadow: var(--sheen-bright); color: var(--text); font-weight: 700; text-decoration: none; }
.settle-up:active { transform: scale(.98); }

@media (max-width: 1024px) {
  .dashboard-grid, .contest-grid { grid-template-columns: 1fr; }
}
@media (max-width: 720px) {
  .desktop { display: none; }
  .top-nav { position: relative; top: 0; width: 100%; margin: 0; padding: 12px 16px; background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; border: 0; border-radius: 0; box-shadow: none; }
  .bottom { position: fixed; z-index: 40; display: flex; justify-content: space-around; left: 16px; right: 16px; bottom: max(14px, env(safe-area-inset-bottom)); }
  /* Icon-only: no labels, so the whole tab is the touch target and stays ≥44px.
     Every tab is an identical box — `flex: 1 1 0` with the SAME padding and
     margin on active and inactive alike. The active state may only change
     colour, never geometry; the old `.nav-float .active` padding made the
     highlighted tab wider and shoved its neighbours sideways on each tap. */
  .bottom a { flex: 1 1 0; min-width: 0; min-height: 44px; margin: 0 3px; padding: 0; display: flex; align-items: center; justify-content: center; color: var(--text-faint); border: 1px solid transparent; border-radius: var(--radius-pill); background: transparent; box-shadow: none; }
  .bottom a.active { padding: 0; color: var(--text); background: var(--purple-fill); border-color: rgba(255, 255, 255, .30); box-shadow: var(--sheen-bright); }
  .bottom a svg { display: block; }
  main { width: min(100% - 32px, 1120px); margin-top: 18px; padding-bottom: 76px; }
  .page-head { align-items: flex-start; flex-direction: column; }
  .tabs { position: sticky; z-index: 15; top: 4px; }
  .game-row { grid-template-columns: minmax(0, 1fr) minmax(180px, .9fr); gap: 12px; padding: 18px 12px 14px; }
  .game-meta { left: 12px; right: 12px; }
  .team-name { display: none; }
  .team-abbr { display: inline; }
  .team-line { grid-template-columns: 32px auto minmax(0, 1fr); gap: 5px; }
  .team-line > small { display: none; }  /* records drop on a phone; the matchup is what matters */
  .market-cell, .market-empty { min-height: 54px; font-size: 12px; }
  .sort-toggle { justify-content: flex-start; flex-wrap: wrap; }
  .sort-toggle > span { width: 100%; }
  .game-search { position: fixed; z-index: 35; left: 16px; right: 16px; bottom: calc(78px + env(safe-area-inset-bottom)); }
  /* The docked search and the floating nav together occupy ~140px of the bottom
     edge. Padding the inner <section> left the last cards sliding under both —
     the clearance has to be on main so it applies to the whole scroll length. */
  main:has([data-testid="game-search"]) { padding-bottom: 104px; }
  .overlay { align-items: flex-end; }
  .pick-slip { position: fixed; left: 0; right: 0; bottom: 0; width: 100%; height: auto; max-height: 88vh; border-left: 0; border-radius: var(--radius-sheet) var(--radius-sheet) 0 0; }
  .board-row { grid-template-columns: 1fr 1fr; }
  .board-row label { grid-column: 1 / -1; }
  .ledger-row { grid-template-columns: 1fr auto; }
  .transfer-actions { grid-column: 1 / -1; justify-content: flex-start; }
  .toast { bottom: 84px; }
}
@media (max-width: 420px) {
  /* Deliberately NOT collapsing .game-row to one column here. Stacking the
     markets under the teams made each game card enormously tall on a phone;
     keeping teams and markets side by side is what makes the slate scannable. */
  /* Teams need less room now that records are hidden and the HOME pill is gone,
     so give the width to the market cells — a wrapped "Under 46.0" looks broken. */
  .game-row { grid-template-columns: minmax(0, .95fr) minmax(150px, 1fr); gap: 8px; padding: 16px 10px 12px; }
  .market-grid { grid-template-columns: 1fr 1fr; gap: 6px; }
  .market-cell, .market-empty { min-height: 46px; font-size: 12px; }
  .tabs button { padding-inline: 8px; font-size: 12px; }
  .shame-wall { align-items: flex-start; }
  .shame-wall .bandit-large { width: 58px; height: 58px; flex: none; }
  .shame-wall .bandit-large img { width: 54px; height: 54px; }
}
@media (prefers-reduced-motion: reduce) {
  :root { --pulse: none; }
  * { animation: none !important; transition: none !important; }
}

/* ---- Game card: team rows carry their own score; the middle row carries the
   kickoff pill, or the clock once the game is live. No separate meta column. ---- */
.at-row { display: flex; align-items: center; gap: 8px; }
.at-mark { flex: none; }
.game-pill { display: inline-flex; align-items: center; padding: 3px 10px; border: 1px solid var(--core-rim-dim); border-radius: var(--radius-pill); background: var(--core-dim); color: var(--text-muted); font: var(--n-meta); white-space: nowrap; }
.game-pill.live { border-color: var(--loss-rim); background: var(--loss-fill); color: var(--loss-soft); }
.team-score { font-family: var(--font-num); font-weight: 800; color: var(--text); }

/* ---- Board header: pips + count + countdown on one line ---- */
.board-progress { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; padding: 14px 16px; }
.pips { display: flex; gap: 4px; }
.pips span { width: 20px; height: 7px; border-radius: 4px; background: rgba(255,255,255,.16); }
.pips span.on { background: var(--purple); box-shadow: 0 0 8px rgba(166,135,245,.7); }
.board-progress strong { font-family: var(--font-num); font-size: 15px; }
.board-hint { color: var(--text-faint); font-size: 11px; }
.board-locks { margin-left: auto; font-family: var(--font-num); font-size: 11px; color: var(--text-muted); white-space: nowrap; }

/* ---- My Picks: one hierarchy per card instead of a pile of pills ---- */
.my-pick { padding: 14px 16px; }
.pick-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.pick-head h3 { margin: 0; font-family: var(--font-num); font-size: 17px; font-weight: 800; }
.pick-head .chip { margin: 0; }
.pick-countdown { font-family: var(--font-num); font-size: 11px; color: var(--text-muted); white-space: nowrap; }
.pick-sub { margin: 3px 0 0; color: var(--text-muted); font-size: 13px; }
.pick-source { color: var(--text-faint); text-transform: lowercase; }
.pick-live-strip { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; padding: 8px 12px; border: 1px solid var(--core-rim); border-radius: var(--radius-cell); background: var(--core); font-family: var(--font-num); font-size: 13px; font-weight: 700; }
.pick-actions { display: flex; gap: 8px; margin-top: 12px; }
.pick-actions button { flex: 1; min-height: 40px; padding: 8px 12px; font-size: 13px; }

/* The grab bar must own the vertical gesture; without touch-action the browser
   scrolls the page behind the sheet and the swipe never arrives. */
.pick-slip .grabber { touch-action: none; cursor: grab; width: 64px; height: 22px; padding: 9px 0; box-sizing: content-box; background: none; }
.pick-slip .grabber::before { content: ""; display: block; width: 46px; height: 5px; margin: 0 auto; border-radius: 3px; background: rgba(255,255,255,.38); }
.picks-progress-line { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 0 4px 12px; }
.picks-progress-line strong { font-family: var(--font-num); font-size: 15px; }
.picks-progress-line .warning { color: var(--gold); font-size: 12px; }
@media (max-width: 430px) {
  /* Five pips and "5/5" already communicate this; the sentence is what forced
     the header onto two or three lines on a phone. */
  .board-hint { display: none; }
  .board-progress { gap: 8px; padding: 12px 14px; }
}
