:root {
  /* Green-grey dark theme — the night inverse of the sage light theme. Neutrals carry a green
     cast (G is the dominant channel, R the lowest), matching the light theme's G>B>R ordering so
     the green runs consistently across both. */
  --bg: #0e130f;
  --panel: #171e19;
  --panel-2: #1d261f;
  --line: #2b382f;
  --text: #e6ebe7;
  --muted: #8b988f;
  /* Primary = vibrant green (the Live/win colour); secondary = blue */
  --accent: #34d399;
  --accent-2: #10b981;
  --accent-rgb: 52,211,153;
  --blue: #3b82f6;
  --blue-2: #2563eb;
  --blue-rgb: 59,130,246;
  --ok: #34d399;
  --warn: #fbbf24;
  --neg: #f87171;
  --pos: #34d399;

  /* Scores board surfaces: the league title blends into the table panel; match rows are the
     visible alternating cards (a = lighter, b = darker). */
  --lg-band: #171d19; --board-row-a: #1d261f; --board-row-b: #19221b;

  /* ── Layout system ──────────────────────────────────────────────────────────
     ONE content frame for every page. Pages must not set their own max-width /
     padding / centering — they get it from `main` (or the `.reading` variant for
     long-form text). Two deliberate widths only: data-dense app pages and reading
     pages. `main` is a fixed centered column, so future side-rail content lives in
     the gutters and can never change the content width. */
  --content-max: 1200px;   /* every page — content area is 1160 (max minus the 20px gutters) */
  --reading-max: var(--content-max);   /* one width everywhere; kept as a hook for future long-form */
  --page-pad-x: 20px;      /* horizontal gutter — desktop & tablet */
  --page-pad-x-sm: 16px;   /* horizontal gutter — mobile */
  --page-gap: 16px;        /* vertical rhythm between stacked sections */
  --page-top: 22px;        /* space under the sticky topbar */
  --rail: 180px;           /* reserved side-rail width (ads/widgets/insights) */
}
:root[data-theme="light"] {
  /* Sage grey-green light theme — a clear green-grey cast (the daylight inverse of the
     cool near-black dark theme), deliberately not white. */
  --bg: #cbd8d1;
  --panel: #dbe4df;
  --panel-2: #d0dbd4;
  --line: #b3c3bb;
  --text: #1b2726;
  --muted: #4f5f5b;
  --accent: #15803d;
  --accent-2: #166534;
  --accent-rgb: 21,128,61;
  --blue: #2563eb;
  --blue-2: #1d4ed8;
  --blue-rgb: 37,99,235;
  --ok: #15803d;
  --warn: #b45309;
  --neg: #dc2626;
  --pos: #15803d;
  /* League blends into the light table panel; rows alternate around it. */
  --lg-band: #d9e2dd; --board-row-a: #e7eee9; --board-row-b: #d1dcd5;
}
:root[data-theme="light"] body { background: var(--bg); }
:root[data-theme="light"] .card {
  box-shadow: 0 1px 2px rgba(30,42,42,.05), 0 1px 3px rgba(30,42,42,.07);
  border-color: var(--line);
}
:root[data-theme="light"] .stat {
  background: #d3ded7; border-color: var(--line);
}
/* Alternating match-row bands (a / b / a / b). Band every cell EXCEPT the green chance blocks
   (prob-hi/mid), so uncolored chance cells match the row instead of the dark table base. */
table.board tr.match-row.row-b td:not(.prob-hi):not(.prob-mid) { background: var(--board-row-b); }
:root[data-theme="light"] .topbar {
  box-shadow: 0 1px 3px rgba(30,42,42,.06);
}
:root[data-theme="light"] table.board tr.match-row td { background: var(--board-row-a); }
/* Chance % colour blocks on light: the old .12 mid was invisible on the pale surface. Stronger
   green + a hair of border so both tiers read clearly. Covers desktop AND the mobile card cells
   (the extra :root/[data-theme] specificity beats the mobile-layout rules). */
:root[data-theme="light"] table.board td.prob-hi,
:root[data-theme="light"] table.board tr.match-row td.c-p.prob-hi { background: rgba(21,128,61,.92); color: #fff; }
:root[data-theme="light"] table.board td.prob-mid,
:root[data-theme="light"] table.board tr.match-row td.c-p.prob-mid { background: rgba(21,128,61,.24); }
:root[data-theme="light"] .panel-2, :root[data-theme="light"] .money-input,
:root[data-theme="light"] .league-search { background: var(--panel-2); }
:root[data-theme="light"] .btn.ghost:hover { background: rgba(37,99,235,.06); }
:root[data-theme="light"] .nav-btn:hover { color: var(--accent); }

* { box-sizing: border-box; }
/* `clip`, not `hidden`: hidden forces the other axis to compute to `auto`, turning html/body
   into scroll containers that capture position:sticky (topbar + board headers) and make them
   scroll away. clip contains stray horizontal width without creating a scroll container. */
html { overflow-x: clip; }
body {
  margin: 0;
  font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
  overflow-x: clip;
}
.muted { color: var(--muted); }
.small { font-size: 12px; }
code { background: var(--panel-2); padding: 1px 5px; border-radius: 4px; }

/* ── login ── */
.login-body {
  display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 20px;
}
.login-card {
  width: min(320px, 100%); background: var(--panel); border: 1px solid var(--line);
  border-radius: 14px; padding: 28px; display: flex; flex-direction: column; gap: 12px;
  box-shadow: 0 20px 50px rgba(0,0,0,.4);
}
.login-card .brand { font-size: 22px; font-weight: 800; display: inline-flex; align-items: center; gap: 9px; }
.login-card .brand .brand-logo { width: 30px; height: 30px; }
.login-card label { display: flex; flex-direction: column; gap: 5px; font-size: 13px; color: var(--muted); }
.login-card input[type="text"],
.login-card input[type="email"],
.login-card input[type="password"] {
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
  border-radius: 8px; padding: 10px 12px; font-size: 15px;
  transition: border-color .15s, background .15s; font-weight: 500;
}
.login-card input:focus { outline: none; border-color: var(--accent); }
.login-card input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.login-card .hint { text-align: center; margin: 4px 0 0; }
.login-card .checkbox-label {
  display: flex; flex-direction: row; align-items: flex-start; gap: 8px;
  font-size: 12px; color: var(--text); margin-top: 4px;
}
.login-card .checkbox-label input[type="checkbox"] {
  margin-top: 3px; flex-shrink: 0; cursor: pointer;
}
.login-card .checkbox-label span { flex: 1; }
.recaptcha-wrapper { margin: 8px 0; text-align: center; }
.recaptcha-wrapper .g-recaptcha { display: inline-block; margin-bottom: 8px; }
.recaptcha-wrapper p { margin: 4px 0; }
.error {
  background: rgba(248,113,113,.12); color: var(--neg); padding: 12px 14px; border-radius: 8px;
  font-size: 13px; border: 1px solid rgba(248,113,113,.3); font-weight: 500; margin-bottom: 12px;
}

/* ── buttons ── */
.btn {
  appearance: none; border: 1px solid var(--line); background: var(--panel-2);
  color: var(--text); padding: 9px 16px; border-radius: 9px; font-size: 14px;
  cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; gap: 6px;
  transition: filter .15s, background .15s; font-weight: 500;
}
.btn:hover { filter: brightness(1.12); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn:disabled { opacity: .55; cursor: default; }
@media (max-width: 640px) {
  .btn { padding: 11px 14px; font-size: 13px; min-height: 44px; }
}
.btn.primary { background: var(--accent); border-color: var(--accent-2); color: #fff; font-weight: 600; }
.btn.warn-btn { background: rgba(251,191,36,.16); border-color: var(--warn); color: var(--warn); font-weight: 600; }
.btn.ghost { background: transparent; }

/* ── topbar ── */
.topbar {
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap; row-gap: 10px;
  /* Full-bleed bar, but its content aligns to the same centred frame as the page body:
     the logo sits at the content's left edge, the toggle at its right edge. */
  padding: 14px max(var(--page-pad-x), calc((100% - var(--content-max)) / 2 + var(--page-pad-x)));
  background: var(--panel); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 50;
}
/* Base (desktop) topbar element rules — defined BEFORE the mobile override so the
   media query at the end wins by source order. */
.topbar .brand { font-size: 18px; font-weight: 700; flex-shrink: 0; display: inline-flex;
  align-items: center; gap: 9px; color: var(--text); text-decoration: none; }
.topbar .brand:hover { color: var(--text); }
.brand-logo { width: 30px; height: 30px; display: block; flex-shrink: 0; }
.brand-name { font-size: 19px; font-weight: 800; letter-spacing: -.01em; }
/* BETA badge — bold amber pill riding the wordmark; we're launching soon. */
.beta-badge {
  font-size: 11px; font-weight: 800; letter-spacing: .12em; line-height: 1;
  color: #1c1512; background: var(--warn); padding: 4px 7px; border-radius: 5px;
  text-transform: uppercase; transform: translateY(-8px) rotate(3deg); flex-shrink: 0;
  box-shadow: 0 2px 8px rgba(251,191,36,.35);
}
.header-search-nav { display: flex; align-items: center; gap: 12px; margin: 0 auto; flex-shrink: 0; }
.header-search { margin: 0 !important; }
.header-right { display: flex; align-items: center; gap: 12px; margin-left: auto; flex-wrap: wrap; }
.auth-actions { display: flex; align-items: center; gap: 8px; }
.auth-actions .btn { display: inline-flex; align-items: center; gap: 6px; }
.auth-actions .btn .icon { flex: 0 0 15px; }
/* Rounded-square outlined icon buttons (DataSight style): primary border + fill on hover */
.mobile-menu-btn, .theme-toggle {
  display: none; appearance: none; border: 1.5px solid var(--accent); background: transparent;
  color: var(--accent); cursor: pointer; border-radius: 8px; padding: 8px;
  min-width: 40px; min-height: 40px; align-items: center; justify-content: center;
  transition: background .15s, color .15s, transform .1s;
}
.theme-toggle { display: flex; font-size: 16px; }
.theme-toggle svg { display: block; }
/* Dark mode → show Sun (click to go light); light mode → show Moon (DataSight behaviour) */
.theme-toggle .ti-moon { display: none; }
.theme-toggle .ti-sun { display: block; }
:root[data-theme="light"] .theme-toggle .ti-sun { display: none; }
:root[data-theme="light"] .theme-toggle .ti-moon { display: block; }
.mobile-menu-btn:hover, .theme-toggle:hover {
  background: var(--accent); color: var(--bg);
}
.mobile-menu-btn:active, .theme-toggle:active { transform: scale(.94); }
.mobile-menu-btn:focus-visible, .theme-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.theme-toggle #theme-icon { line-height: 1; }
.mobile-nav { display: none; }

/* Nav link hover dots (DataSight): green + blue dots slide in, staggered */
.nav-btn { --dot-shown: 0; }
.nav-hover-dots { display: inline-flex; align-items: center; gap: 2px; margin-left: 5px; }
.nav-hover-dots i {
  width: 5px; height: 5px; border-radius: 50%; opacity: 0;
  transform: scale(.5) translateX(-3px); transition: opacity .15s ease-out, transform .15s ease-out;
}
.nav-hover-dots i.d-green { background: var(--accent); }
.nav-hover-dots i.d-blue { background: var(--blue); }
.nav-btn:hover .nav-hover-dots i.d-green,
.nav-btn.active .nav-hover-dots i.d-green { opacity: 1; transform: scale(1) translateX(0); transition-delay: 0s; }
.nav-btn:hover .nav-hover-dots i.d-blue,
.nav-btn.active .nav-hover-dots i.d-blue { opacity: 1; transform: scale(1) translateX(0); transition-delay: .075s; }
.nav-btn {
  font-size: 14px; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 12px; border: none; background: transparent; color: var(--muted); cursor: pointer;
  transition: all .15s; position: relative; white-space: nowrap; min-height: 44px; min-width: 44px;
  font-weight: 500; border-radius: 6px; text-decoration: none;
}
.nav-btn svg.icon { width: 16px; height: 16px; flex-shrink: 0; }
.nav-btn:hover { color: var(--text); background: transparent; }
.nav-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nav-btn.active { color: var(--accent); font-weight: 700; }
.nav-btn.active::after { display: none; }

/* Mobile topbar: hamburger + theme toggle only; full nav collapses into dropdown. */
@media (max-width: 640px) {
  .topbar {
    padding: 12px 14px; gap: 8px; row-gap: 0; flex-wrap: nowrap;
    justify-content: flex-start; align-items: center;
  }
  .topbar .brand { font-size: 16px; margin-right: auto; flex: 1 1 auto; min-width: 0; gap: 7px; }
  .topbar .brand .brand-name { font-size: 17px; white-space: nowrap; overflow: hidden;
    text-overflow: ellipsis; min-width: 0; }
  .brand-logo { width: 26px; height: 26px; }
  .beta-badge { font-size: 10px; padding: 3px 5px; transform: translateY(-7px) rotate(3deg); }
  .mobile-menu-btn { display: flex !important; flex: 0 0 40px; order: 3; }
  .theme-toggle { flex: 0 0 40px; order: 2; }
  .header-search-nav { display: none !important; }
  .header-right { display: none !important; }
  .mobile-nav { display: none; }
  .mobile-nav.active {
    display: flex; position: absolute; top: 100%; left: 0; right: 0; background: var(--panel);
    border-bottom: 1px solid var(--line); flex-direction: column; gap: 0; z-index: 60;
    box-shadow: 0 8px 24px rgba(0,0,0,.2); order: 4;
  }
  .mobile-nav.active a { display: flex; align-items: center; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--line); color: var(--text); text-decoration: none; font-weight: 500; }
  .mobile-nav.active a .icon { flex: 0 0 18px; color: var(--accent); }
  .mobile-nav.active a:last-child { border-bottom: none; }
  .mobile-nav.active a:active { background: var(--panel-2); }
}
.balance-box { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.balance-box label { color: var(--muted); font-size: 13px; }
.money-input { display: flex; align-items: center; background: var(--panel-2); border: 1px solid var(--line); border-radius: 9px; padding: 0 10px; }
.money-input span { color: var(--muted); }
.money-input input {
  width: 110px; background: transparent; border: 0; color: var(--text);
  font-size: 18px; font-weight: 700; padding: 8px 6px; outline: none;
}
.saved-tag { color: var(--ok); font-size: 12px; min-width: 34px; }
.manual-star { color: var(--accent); font-weight: 700; margin-left: 2px; cursor: help; }
.bal-static { font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
.balance-box { flex-wrap: wrap; justify-content: flex-end; row-gap: 4px; }
.reset-box { display: flex; align-items: center; gap: 6px; }
.reset-box .money-input input { width: 74px; font-size: 15px; padding: 6px 4px; }
.reset-flag { color: var(--accent); margin-left: 3px; cursor: help; }
.reset-note { flex-basis: 100%; text-align: right; font-size: 12px; color: var(--warn); }
.reset-note.muted { color: var(--muted); }
.cur-form select {
  background: var(--panel-2); color: var(--text); border: 1px solid var(--line);
  border-radius: 8px; padding: 6px 8px; font-size: 13px; cursor: pointer;
}

/* ── freemium locks / role badges ── */
.lock-chip {
  display: inline-flex; align-items: center; gap: 4px; text-decoration: none;
  background: rgba(251,191,36,.12); color: var(--warn); border: 1px solid rgba(251,191,36,.32);
  font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 6px; white-space: nowrap;
}
.lock-chip:hover { filter: brightness(1.12); }
.unlock-chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: rgba(52,211,153,.12); color: var(--ok); border: 1px solid rgba(52,211,153,.3);
  font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 6px; white-space: nowrap;
}
.btn.locked { background: rgba(251,191,36,.12); border-color: rgba(251,191,36,.35); color: var(--warn); font-weight: 600; }
.credit-chip { font-size: 12px; font-weight: 700; padding: 3px 9px; border-radius: 6px;
  background: rgba(59,130,246,.14); color: #93c5fd; white-space: nowrap; }
/* Subscription status pill in the header (trial countdown / active plan / free tier). */
.sub-chip { font-size: 12px; font-weight: 700; padding: 3px 10px; border-radius: 999px;
  white-space: nowrap; text-decoration: none; line-height: 1.6; }
.sub-chip.trial { background: rgba(34,197,94,.16); color: #4ade80; }
.sub-chip.subscribed { background: rgba(234,179,8,.16); color: #fbbf24; }
.sub-chip.free { background: rgba(148,163,184,.16); color: var(--muted); }
a.sub-chip:hover { filter: brightness(1.12); }
/* Signed-in username replaces the "Account" nav label — cap it so long emails don't wrap. */
.nav-username { display: inline-block; max-width: 130px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; vertical-align: middle; }
.head-right { display: flex; align-items: center; gap: 10px; }

/* ── layout ── */
/* Wide enough that the board's 11 columns fit without a horizontal scrollbar on a laptop;
   still centred and padded on anything narrower. */
/* The single page frame every template inherits. Do not set width/padding/centering on
   a page — use this, or add `class="reading"` for long-form pages. */
main { width: 100%; max-width: var(--content-max); margin: var(--page-top) auto; padding: 0 var(--page-pad-x);
  display: flex; flex-direction: column; gap: var(--page-gap); }
main.reading { max-width: var(--reading-max); }

/* Skeleton loading (Scores + Results shells): an empty table that fades in/out while the real
   content is fetched, then swaps in. */
@keyframes skel-pulse { 0%, 100% { opacity: .4; } 50% { opacity: .8; } }
.skel-wrap { display: flex; flex-direction: column; gap: 16px; }
.skel-table { display: flex; flex-direction: column; gap: 8px; }
.skel-bar { border-radius: 8px; background: var(--panel-2); animation: skel-pulse 1.25s ease-in-out infinite; }
.skel-bar.head { background: var(--panel); height: 40px; }
.skel-row { height: 46px; }
/* Loaded content containers stack their sections (skeleton or real) with the page rhythm. */
#board-body, #perf-body { display: flex; flex-direction: column; gap: var(--page-gap); }
.card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 18px 20px;
  box-shadow: 0 2px 8px rgba(0,0,0,.12);
}
.card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; gap: 16px; flex-wrap: wrap; row-gap: 10px; }
.card h2 { margin: 0; font-size: 16px; font-weight: 600; color: var(--text); }
.totals { display: flex; gap: 18px; align-items: baseline; }
.totals strong { font-size: 16px; }
.match-head { align-items: center; }
.match-nav { display: flex; align-items: center; gap: 8px; }
.match-nav h2 { display: flex; align-items: baseline; gap: 8px; }

/* ── day picker: month header over a Mon–Sun grid; only scanned days are selectable ── */
.cal-wrap { position: relative; }
.cal-pop { position: absolute; z-index: 40; top: calc(100% + 6px); left: 0; width: 260px;
  padding: 10px; background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.45); }
@media (max-width: 640px) {
  .cal-pop { max-width: calc(100vw - 20px); left: 50%; transform: translateX(-50%); }
}
.cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.cal-month { font-weight: 700; font-size: 13px; letter-spacing: .02em; }
.cal-nav { appearance: none; border: 1px solid var(--line); background: var(--panel);
  color: var(--text); border-radius: 6px; width: 24px; height: 24px; cursor: pointer; line-height: 1; }
.cal-nav[disabled] { opacity: .3; cursor: not-allowed; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-dow { text-align: center; font-size: 10px; text-transform: uppercase; color: var(--muted);
  font-weight: 700; padding: 2px 0 4px; }
.cal-day { appearance: none; border: 0; background: none; color: var(--text); font-size: 12px;
  border-radius: 6px; height: 30px; cursor: pointer; font-variant-numeric: tabular-nums; }
.cal-day:hover:not([disabled]) { background: var(--panel); }
.cal-day[disabled] { color: #4b5361; cursor: default; }
.cal-day.is-today { box-shadow: inset 0 0 0 1px var(--line); font-weight: 700; }
.cal-day.is-current { background: var(--accent); color: #fff; font-weight: 800; }
.cal-empty { height: 30px; }
.match-date { font-weight: 400; }

.scan-card { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.scan-state { display: flex; flex-direction: column; margin-right: auto; }
.scan-state .warn { color: var(--warn); }
.scan-state .ok { color: var(--ok); }
.scan-state .muted { font-size: 13px; }

/* ── tables ── */
/* `safe center`: centre a table that fits, but fall back to start-alignment the moment it's
   wider than the container — otherwise centring splits the overflow to both sides and the left
   columns become unreachable (they scroll off-canvas / widen the page). Wide tables now left-
   align and scroll fully inside this container. */
.table-scroll { overflow-x: auto; overflow-y: visible; -webkit-overflow-scrolling: touch; margin: 0 auto; padding: 0; display: flex; justify-content: safe center; }
@media (max-width: 768px) {
  .table-scroll { overflow-x: visible; }
}
table.bets { width: 100%; border-collapse: collapse; font-size: 14px; }
table.bets th {
  text-align: left; color: var(--muted); font-weight: 600; font-size: 12px; text-transform: uppercase;
  letter-spacing: .03em; padding: 8px 10px; border-bottom: 1px solid var(--line);
}
.th-sort-btn {
  background: none; border: none; padding: 4px 6px; margin: -4px -6px; font: inherit; text-transform: inherit;
  letter-spacing: inherit; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center;
  gap: 4px; border-radius: 3px; transition: all .15s; min-height: 36px;
}
.th-sort-btn:hover, .th-sort-btn[aria-pressed="true"] { color: var(--accent); background: rgba(59,130,246,.08); }
.th-sort-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.th-sort-btn .sort-icon { font-size: 11px; }
table.bets td { padding: 9px 10px; border-bottom: 1px solid rgba(42,49,61,.5); }
table.bets tr:last-child td { border-bottom: 0; }
table.bets .num { text-align: right; font-variant-numeric: tabular-nums; }
table.bets td.stake { font-weight: 700; }
.pos { color: var(--pos); }
.neg { color: var(--neg); }
.model-pct { color: var(--text); font-weight: 600; }
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; }
.stat {
  display: flex; flex-direction: column; gap: 4px; padding: 14px 16px; background: var(--panel-2);
  border: 1px solid var(--line); border-radius: 10px; transition: all .15s;
}
.stat:hover { background: rgba(29,34,43,.6); border-color: rgba(59,130,246,.3); }
.stat-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted);
  font-weight: 600; font-variant-numeric: tabular-nums;
}
.stat-val { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--text); }
@media (max-width: 640px) {
  .stat-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .stat { padding: 12px 14px; }
  .stat-val { font-size: 20px; }
}
.link { color: var(--accent); text-decoration: none; }
.link:hover { text-decoration: underline; }
.tag-risk { background: rgba(248,113,113,.14); color: var(--neg); font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 5px; text-transform: uppercase; margin-right: 4px; }
.mp-score { margin-top: 8px; font-size: 12.5px; color: var(--muted); }
.mp-score strong { color: var(--text); }
.lg { display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 5px; background: var(--panel-2); color: var(--muted); font-size: 11px; }
/* ── livescore-style per-league group header (dashboard match table) ── */
table.bets tr.league-group-row td { padding: 8px 10px; background: var(--panel-2); border-bottom: 1px solid var(--line); }
.lg-group-logo { width: 18px; height: 18px; object-fit: contain; vertical-align: -4px; margin-right: 7px; }
.lg-group-label { font-weight: 700; font-size: 12.5px; text-transform: uppercase; letter-spacing: .03em; color: var(--text); margin-right: 8px; }
/* ── livescore-style match row (time/FT, crest, team, score) ── */
.ls-row { display: flex; align-items: center; gap: 7px; font-variant-numeric: tabular-nums; }
.ls-time { flex: 0 0 40px; font-size: 12px; font-weight: 700; color: var(--muted); }
.ls-team { display: inline-flex; align-items: center; gap: 6px; }
.ls-logo { width: 16px; height: 16px; object-fit: contain; flex-shrink: 0; }
.ls-score { font-weight: 700; color: var(--text); min-width: 18px; text-align: center; }
.mtype { display: inline-block; margin-left: 4px; padding: 1px 6px; border-radius: 5px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; }
.mtype-league { background: var(--panel-2); color: var(--muted); }
.mtype-cup { background: rgba(167,139,250,.16); color: #c4b5fd; }
.mtype-international { background: rgba(59,130,246,.16); color: #93c5fd; }
.mtype-youth { background: rgba(251,191,36,.16); color: var(--warn); }
.value-toggle.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.empty {
  color: var(--muted); padding: 20px 16px; font-size: 14px; text-align: center;
  background: rgba(139,148,163,.06); border-radius: 10px; border: 1px dashed var(--line);
}
.note {
  margin: 12px 0; padding: 12px 14px; border-radius: 8px; font-size: 13px; font-weight: 500;
  border: 1px solid rgba(139,148,163,.3);
}
.note.ok { background: rgba(52,211,153,.12); color: var(--ok); border-color: rgba(52,211,153,.3); }

/* ── manual result entry ── */
.settle-form { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0; }
.settle-form input[type="number"] {
  width: 46px; background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
  border-radius: 7px; padding: 6px 4px; font-size: 14px; text-align: center;
}
.settle-form .dash { color: var(--muted); }
.settle-form .score-in, .settle-form .ht-in { display: inline-flex; align-items: center; gap: 5px; }
.settle-form .score-group { display: inline-flex; flex-direction: column; gap: 3px; }
.settle-form .score-lbl { font-size: 11px; font-weight: 600; }

/* ── date navigation ── */
.datenav { display: flex; align-items: center; gap: 8px; }
.btn.sm { padding: 5px 10px; font-size: 13px; }
.btn.disabled { opacity: .3; cursor: default; pointer-events: none; }
.cur-date { font-weight: 600; min-width: 150px; text-align: center; }

/* ── analyst predictions ── */
.preds { display: flex; flex-direction: column; gap: 12px; }
.match-pred { border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; background: var(--panel-2); }
.mp-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.mp-teams { font-weight: 600; }
.analyst-call { color: var(--muted); font-size: 13px; }
.analyst-call strong { color: var(--text); font-size: 18px; margin: 0 4px; font-variant-numeric: tabular-nums; }
.model-grid { margin-left: auto; }
.conf { font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 6px; }
.conf-high { background: rgba(52,211,153,.16); color: var(--ok); }
.conf-medium { background: rgba(251,191,36,.16); color: var(--warn); }
.conf-low { background: rgba(139,148,163,.16); color: var(--muted); }
.mp-summary { margin-top: 8px; font-size: 13.5px; color: #c4ccd8; line-height: 1.55; }
.mp-missing { margin-top: 6px; font-size: 12px; color: var(--muted); }
.tag-missing { background: rgba(251,191,36,.14); color: var(--warn); font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 5px; text-transform: uppercase; letter-spacing: .03em; margin-right: 4px; }

/* ── market selector + tags ── */
.market-select {
  background: var(--panel-2); color: var(--text); border: 1px solid var(--line);
  border-radius: 9px; padding: 8px 12px; font-size: 14px; font-weight: 600;
}
.tag-value { background: rgba(59,130,246,.18); color: #93c5fd; font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 5px; text-transform: uppercase; margin-left: 5px; }
.tag-auto { background: rgba(52,211,153,.18); color: var(--ok); font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 5px; text-transform: uppercase; margin-left: 5px; }
.tag-manual { background: rgba(167,139,250,.18); color: #c4b5fd; font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 5px; margin-left: 6px; }
.tag-cs3 { background: rgba(56,189,248,.18); color: #7dd3fc; font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 5px; text-transform: uppercase; margin-left: 6px; }
.cs3-list { list-style: none; margin: 0 0 4px; padding: 0; font-size: 13px; }
.cs3-list li { display: flex; align-items: baseline; gap: 6px; }
.cs3-combined { font-size: 14px; margin-bottom: 4px; }
.cs3-combined strong { color: var(--accent); }
.cs3-rule { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.cs3-unit { display: inline-flex; align-items: center; gap: 6px; }
.cs3-unit input { width: 72px; }
.inline { display: inline; margin: 0; }

/* ── auto-place matrix editor ── */
.matrix-panel summary { cursor: pointer; list-style: none; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.matrix-panel summary::-webkit-details-marker { display: none; }
.matrix-panel .m-title { font-size: 16px; font-weight: 700; }
.matrix-panel .m-title::before { content: "▸ "; color: var(--muted); }
.matrix-panel[open] .m-title::before { content: "▾ "; }
.matrix-table { margin-top: 14px; max-width: 560px; }
.matrix-table input[type="number"] { width: 64px; background: var(--panel-2); border: 1px solid var(--line); color: var(--text); border-radius: 7px; padding: 6px 8px; font-size: 14px; text-align: right; }
.switch { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: 13px; cursor: pointer; }
.switch input { accent-color: var(--accent); width: 15px; height: 15px; }

/* ── results ── */
.won, .lost { font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 6px; }
.won { background: rgba(52,211,153,.16); color: var(--ok); }
.lost { background: rgba(248,113,113,.16); color: var(--neg); }
/* Correct-score result: gold = single top-pick bet landed exactly; green = the 3-way
   trio landed on one of its 3 legs; red = missed; grey = fixture voided (cancelled). */
.cs-result { font-size: 12px; font-weight: 700; padding: 1px 8px; border-radius: 6px; display: inline-flex; align-items: center; gap: 5px; }
.cs-gold { background: rgba(251,191,36,.18); color: var(--warn); }
.cs-green { background: rgba(52,211,153,.16); color: var(--ok); }
.cs-red { background: rgba(248,113,113,.16); color: var(--neg); }
.cs-void { background: var(--panel-2); color: var(--muted); }
.cs-mode-toggle { display: flex; gap: 4px; margin-bottom: 6px; }
.res-actual { font-size: 13px; margin-bottom: 3px; }
.badge-won { color: var(--ok); font-weight: 700; font-size: 12px; margin-left: 6px; }
.badge-lost { color: var(--neg); font-weight: 700; font-size: 12px; margin-left: 6px; }
.profit { font-weight: 700; margin-left: 8px; font-variant-numeric: tabular-nums; }
.pl { font-variant-numeric: tabular-nums; }

/* ── reasoning write-up: click ⓘ to expand a row underneath the match ── */
.info-btn {
  appearance: none; border: none; background: transparent; margin-left: auto; padding: 6px;
  color: var(--accent); font-weight: 700; font-size: 14px; cursor: pointer; line-height: 1;
  flex-shrink: 0; border-radius: 4px; min-width: 40px; min-height: 40px;
  display: flex; align-items: center; justify-content: center;
  transition: all .15s;
}
.info-btn:hover { background: rgba(59,130,246,.12); }
.info-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── crown: this row is one of today's curated Write-Ups ── */
.crown-link {
  margin-left: auto; padding: 6px; color: var(--warn); flex-shrink: 0; border-radius: 4px;
  min-width: 32px; min-height: 32px; display: flex; align-items: center; justify-content: center;
  transition: all .15s;
}
.crown-link:hover { background: rgba(251,191,36,.14); }
.crown-link:focus-visible { outline: 2px solid var(--warn); outline-offset: 2px; }
.crown-link + .info-btn { margin-left: 0; }
.info-row td, table.board tr.info-row td { padding: 14px 16px; background: var(--panel-2);
  border-bottom: 1px solid var(--line); border-radius: 6px; }
.info-panel { font-size: 13px; color: var(--text); line-height: 1.5; max-width: 640px; }
.tip-title { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-bottom: 8px; }
.tip-row { font-size: 13px; margin-bottom: 6px; }
.tip-row strong { font-variant-numeric: tabular-nums; }
.tip-sec { font-size: 12.5px; color: #c4ccd8; margin-top: 8px; }
.mp-head { margin-top: 8px; }
.mp-top3 { list-style: none; margin: 4px 0 0; padding-left: 0; font-size: 13px; }
.mp-top3 li { margin-bottom: 3px; display: flex; align-items: baseline; gap: 6px; }
.mp-top3 .mp-rank { display: inline-block; min-width: 52px; font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em; color: var(--muted); }
.mp-top3 strong { font-variant-numeric: tabular-nums; }
.mp-combined strong { color: var(--text); font-variant-numeric: tabular-nums; }

/* ── availability + analyst details ── */
.avail-groups { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 6px; max-width: 480px; }
.avail-h { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; margin: 8px 0 2px; }
.avail-h.a-ok { color: var(--ok); }
.avail-h.a-no { color: var(--warn); }
details.mini { display: inline-block; }
details.mini summary { cursor: pointer; color: var(--muted); font-size: 12px; list-style: none; }
details.mini summary::-webkit-details-marker { display: none; }
details.mini[open] summary { color: var(--text); }
ul.avail { list-style: none; padding: 8px 0 2px; margin: 6px 0 0; border-top: 1px solid var(--line); max-width: 460px; }
ul.avail li { font-size: 12px; padding: 2px 0; }
.a-ok { color: #b9c2cf; }
.a-no { color: var(--warn); }
.conf { font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 6px; margin-left: 5px; }
.conf-high { background: rgba(52,211,153,.16); color: var(--ok); }
.conf-medium { background: rgba(251,191,36,.16); color: var(--warn); }
.conf-low { background: rgba(139,148,163,.16); color: var(--muted); }
.mp-summary { margin-top: 8px; font-size: 13px; color: #c4ccd8; line-height: 1.5; max-width: 520px; }
.mp-missing { margin-top: 6px; font-size: 12px; color: var(--muted); max-width: 520px; }
.tag-missing { background: rgba(251,191,36,.14); color: var(--warn); font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 5px; text-transform: uppercase; margin-right: 4px; }

/* ── results-over-time chart ── */
.chart-toggle { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.chart-mode-radio { position: absolute; opacity: 0; width: 0; height: 0; }
.chart-toggle-btn {
  cursor: pointer; padding: 8px 16px; border-radius: 8px; font-size: 13px; font-weight: 600;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted); user-select: none;
  min-height: 40px; transition: all .15s;
}
.chart-mode-radio:checked + .chart-toggle-btn { background: var(--accent); border-color: var(--accent-2); color: #fff; }
.chart-mode-radio:focus-visible + .chart-toggle-btn { outline: 2px solid var(--accent); outline-offset: 2px; }
.chart-toggle-btn:hover:not(:disabled) { border-color: var(--accent); }
@media (max-width: 640px) {
  .chart-toggle-btn { flex: 1; min-width: 100px; }
}
.chart-hint-cum, .chart-hint-bank { display: none; }
.card:has(#chart-mode-cum:checked) .chart-hint-cum { display: inline; }
.card:has(#chart-mode-bank:checked) .chart-hint-bank { display: inline; }
.chart-panel { display: none; }
.card:has(#chart-mode-cum:checked) .chart-panel-cum { display: block; }
.card:has(#chart-mode-bank:checked) .chart-panel-bank { display: block; }
.chart-wrap { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; }
.chart-body { display: flex; gap: 6px; }
.chart-yaxis {
  display: flex; flex-direction: column; justify-content: space-between;
  height: 160px; width: 44px; flex-shrink: 0; text-align: right; white-space: nowrap;
  font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums;
}
.chart-col { flex: 1; min-width: 0; }
.chart-plot { position: relative; height: 160px; }
@media (max-width: 480px) {
  .chart-plot { height: 140px; }
  .chart-yaxis { width: 48px; font-size: 10px; }
  .chart-xaxis { font-size: 10px; }
}
.results-chart { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.chart-zero { stroke: var(--line); stroke-width: 1; stroke-dasharray: 4 4; vector-effect: non-scaling-stroke; }
.chart-line { stroke-width: 2; vector-effect: non-scaling-stroke; }
.chart-line.pos { stroke: var(--pos); }
.chart-line.neg { stroke: var(--neg); }
.chart-month-line { stroke: var(--line); stroke-width: 1; stroke-dasharray: 2 3; opacity: .7; vector-effect: non-scaling-stroke; }
.chart-pt { position: absolute; width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; border-radius: 50%; cursor: pointer; }
.chart-pt.pos { background: var(--pos); }
.chart-pt.neg { background: var(--neg); }
.chart-reset-pt { position: absolute; top: -4px; width: 9px; height: 9px; margin-left: -4.5px; border-radius: 50%; background: var(--warn); border: 2px solid var(--panel); cursor: pointer; z-index: 2; }
.chart-pt .tip-body, .chart-reset-pt .tip-body, .market-dot .tip-body {
  display: none; position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);
  margin-bottom: 8px; z-index: 30; white-space: nowrap; width: auto;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 7px 10px; box-shadow: 0 16px 44px rgba(0,0,0,.55);
  font-size: 12.5px; color: var(--text); line-height: 1.4; cursor: default;
}
.chart-pt:hover .tip-body, .chart-pt:focus .tip-body,
.chart-reset-pt:hover .tip-body, .chart-reset-pt:focus .tip-body,
.market-dot:hover .tip-body, .market-dot:focus .tip-body { display: block; }
.chart-xaxis { position: relative; height: 44px; margin-top: 10px; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; overflow: visible; }
@media (max-width: 640px) {
  .chart-xaxis { height: 40px; font-size: 10px; }
}

/* ── performance page: monthly summary / reset divider ── */
.sub-head { font-size: 13px; color: var(--muted); margin: 4px 0 8px; text-transform: uppercase; letter-spacing: .04em; }
.month-reset-row td { padding: 2px 0 10px; border: none; }
.month-reset-line { border: none; border-top: 1px dashed var(--line); margin: 0 0 4px; }

/* ── account settings page ── */
.acct-form { display: flex; flex-direction: column; gap: 14px; max-width: 360px; }
.acct-field { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--muted); font-weight: 500; }
.acct-field label { color: var(--text); font-weight: 600; }
.acct-field input, .acct-field select {
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
  border-radius: 8px; padding: 10px 12px; font-size: 14px; font-weight: 500;
  transition: border-color .15s, background .15s; min-height: 40px;
}
.acct-field input:focus, .acct-field select:focus {
  outline: none; border-color: var(--accent); background: rgba(59,130,246,.04);
}
.acct-field input:focus-visible, .acct-field select:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.acct-list { display: flex; flex-direction: column; }
.acct-list-item {
  padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 14px;
}
.acct-list-item:last-child { border-bottom: none; }
.acct-list-link { color: var(--text); text-decoration: none; }
.acct-list-link:hover { color: var(--accent, #6ea8fe); }

/* ── scan progress ── */
.row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.log {
  background: #0a0d0b; border: 1px solid var(--line); border-radius: 8px; padding: 12px;
  max-height: 280px; overflow: auto; font: 12px/1.5 ui-monospace, Menlo, monospace; color: #c8d4cc; white-space: pre-wrap;
}
.spinner {
  width: 16px; height: 16px; border: 2px solid var(--line); border-top-color: var(--accent);
  border-radius: 50%; display: inline-block; animation: spin .8s linear infinite;
}
.skeleton {
  background: linear-gradient(90deg, var(--panel-2) 0%, var(--panel) 50%, var(--panel-2) 100%);
  background-size: 200% 100%; animation: skeleton-load 1.5s infinite; border-radius: 6px;
}
@keyframes skeleton-load { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* ── reusable dismiss (×) button — rounded square, top-right of a card ── */
.card-close {
  position: absolute; top: 12px; right: 12px; z-index: 2;
  appearance: none; border: 1px solid var(--line); background: var(--panel-2);
  color: var(--muted); cursor: pointer; border-radius: 8px; width: 32px; height: 32px;
  font-size: 20px; line-height: 1; display: flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s, border-color .15s;
}
.card-close:hover { background: var(--neg); color: #fff; border-color: var(--neg); }
.card-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── yesterday's winners carousel (anon) ── */
.wins-card { border-color: rgba(52,211,153,.35); position: relative; }
.carousel-nav { display: flex; gap: 6px; }
.carousel-nav .btn { padding: 8px 10px; min-height: 40px; }
.carousel { overflow-x: hidden; }
/* Keep the wins-card header clear of the absolute × dismiss button */
.wins-card .card-head { padding-right: 44px; }
@media (max-width: 640px) {
  .wins-card .card-head { flex-direction: column; align-items: flex-start; padding-right: 44px; }
  .wins-card .head-right { width: 100%; flex-wrap: wrap; gap: 10px; row-gap: 8px; align-items: center; }
  .wins-card .balance-box { margin-left: 0; }
  .wins-card .carousel-nav { margin-left: auto; }
}
.carousel-track { display: flex; gap: 14px; }
.win-card {
  position: relative; flex: 0 0 calc(50% - 7px); min-width: 0;
  background: var(--panel-2); border: 1px solid rgba(52,211,153,.3); border-radius: 12px;
  padding: 16px 18px; display: flex; flex-direction: column; gap: 10px;
  transition: all .15s;
}
.win-card:hover { border-color: rgba(52,211,153,.6); }
@media (max-width: 640px) {
  .win-card { flex: 0 0 100%; }
}
.win-check {
  position: absolute; top: 12px; right: 14px; width: 26px; height: 26px; border-radius: 50%;
  background: rgba(52,211,153,.18); color: var(--ok); font-weight: 800;
  display: flex; align-items: center; justify-content: center;
}
.win-teams { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding-right: 30px; }
.win-team { display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
.win-logo { width: 28px; height: 28px; object-fit: contain; border-radius: 5px; background: #fff2; }
.win-logo-ph {
  display: inline-flex; align-items: center; justify-content: center; font-size: 10px;
  font-weight: 700; color: var(--muted); border: 1px solid var(--line);
}
.win-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.win-vs { color: var(--muted); }
.win-bet { font-size: 14px; }
.win-market { color: var(--muted); margin-right: 6px; }
.win-odds { color: var(--ok); font-weight: 700; }
@media (max-width: 560px) { .win-card { flex: 0 0 100%; } }

/* ── teaser (anon) ── */
.teaser {
  margin-top: 16px; padding: 16px 18px; border: 1px dashed rgba(59,130,246,.5);
  border-radius: 12px; background: rgba(59,130,246,.06);
}
.teaser p { margin: 0 0 12px; }
.teaser-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.js-buy { cursor: pointer; }

/* Account banners (welcome / trial countdown / trial-ended) shown at the top of the board. */
.acct-banner { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; padding: 12px 16px; border-radius: 10px; margin-bottom: 14px; font-size: 14px;
  border: 1px solid var(--line); background: var(--panel); }
.acct-banner.welcome { background: rgba(34,197,94,.12); border-color: rgba(34,197,94,.35); }
.acct-banner.trial { background: rgba(59,130,246,.1); border-color: rgba(59,130,246,.35); }
.acct-banner.ended { background: rgba(234,179,8,.1); border-color: rgba(234,179,8,.4); }
.acct-banner-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.acct-banner .btn { white-space: nowrap; }
.acct-banner-x { text-decoration: none; color: var(--muted); font-size: 20px; line-height: 1;
  padding: 0 4px; }
.acct-banner-x:hover { color: var(--text); }

/* ── buy-a-prediction modal (anon) ── */
body.modal-open { overflow: hidden; }
.modal-overlay {
  position: fixed; inset: 0; z-index: 50; background: rgba(4,7,12,.72);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.modal-overlay[hidden] { display: none; }
.modal {
  position: relative; width: 560px; max-width: calc(100% - 40px); background: var(--panel);
  border: 1px solid var(--line); border-radius: 16px; padding: 28px;
  box-shadow: 0 30px 70px rgba(0,0,0,.55);
}
@media (max-width: 600px) {
  .modal { padding: 20px; max-width: calc(100% - 24px); }
}
.modal h2 { margin: 0 0 6px; }
.modal-close {
  position: absolute; top: 14px; right: 16px; background: none; border: none; color: var(--muted);
  font-size: 26px; line-height: 1; cursor: pointer;
}
.modal-close:hover { color: var(--text); }
.price-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 18px 0; }
.price-card {
  position: relative; border: 1px solid var(--line); border-radius: 12px; padding: 18px 12px;
  text-align: center; background: var(--panel-2);
}
.price-card.best { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.price-card.chosen { border-color: var(--line); box-shadow: 0 0 0 1px rgba(139,148,163,.4) inset; }
.price-buy { appearance: none; font: inherit; color: inherit; width: 100%; cursor: pointer;
  transition: filter .15s, border-color .15s; }
.price-buy:hover { filter: brightness(1.15); border-color: var(--accent); }
.price-badge {
  position: absolute; top: -10px; left: 50%; transform: translateX(-50%);
  background: var(--accent); color: #fff; font-size: 10px; font-weight: 700;
  padding: 2px 8px; border-radius: 999px; white-space: nowrap;
}
.price-badge.chosen { background: var(--panel); color: var(--muted); border: 1px solid var(--line); }
.price-amt { font-size: 26px; font-weight: 800; }
.price-unit { color: var(--muted); font-size: 13px; margin-top: 2px; }
.price-note { color: var(--ok); font-size: 12px; margin-top: 6px; }
.modal-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
@media (max-width: 480px) { .price-grid { grid-template-columns: 1fr; } }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── mobile: transform match table into cards (CSS-only, single DOM) ── */
@media (max-width: 768px) {
  /* Keep overflow visible on the whole board ancestry so the sticky mobile header isn't captured
     (html{overflow-x:hidden} already clips any stray horizontal width at the top level). The
     earlier capture bug was an inline `main{overflow-y:auto}` in dashboard.html, now removed. */
  main, main.reading { padding: 0 var(--page-pad-x-sm); margin: 14px auto; gap: 12px; overflow: visible; max-width: 100%; }
  .card { padding: 14px 14px; border-radius: 12px; max-width: 100%; overflow: visible; }
  .balance-box { margin-left: 0; }
  .datenav { gap: 4px; flex-wrap: wrap; }
  .cur-date { min-width: 0; font-size: 13px; }
  .card h2 { font-size: 15px; font-weight: 600; }
  .stat-grid { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
  .modal { padding: 20px; }
  .price-amt { font-size: 22px; }

  /* Match-head control bar must wrap, not force the card wide */
  .card-head.match-head { flex-wrap: wrap; }
  .match-nav { flex-wrap: wrap; gap: 6px; row-gap: 6px; }
  /* Keep the day label inline BETWEEN the ◀ / ▶ buttons (its DOM position), not pulled out
     onto its own line. The nav wraps if it must. */
  .match-nav h2 { order: 0; flex: 0 0 auto; font-size: 14px; margin: 0 2px; white-space: nowrap; }
  .league-search { width: 100% !important; min-width: 0 !important; max-width: 100%; box-sizing: border-box; }

  /* Board table → card rows. overflow stays visible so the sticky mobile header below sticks
     to the VIEWPORT (any clip/hidden ancestor would capture it instead and it'd scroll away). */
  .board-scroll { display: block; overflow: visible; max-width: 100%; }
  table.board, table.board tbody { display: block; width: 100%; max-width: 100%; min-width: 0; }
  table.board thead { display: none; }
  /* Mobile column header — mirrors the match-row flex layout so labels line up over the cards.
     `.board-scroll` prefix outranks the base `.board-mhead{display:none}` that follows in source. */
  .board-scroll .board-mhead {
    display: flex; align-items: center; gap: 6px;
    position: sticky; top: var(--board-head-top, 56px); z-index: 8;
    padding: 8px 10px; margin-bottom: 6px;
    background: var(--panel); border-bottom: 1px solid var(--line);
    font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted);
  }
  /* Header cells mirror the match-row flex bases below (must stay in sync to line up). */
  .board-mhead .mh-date { flex: 0 0 auto; min-width: 28px; }
  .board-mhead .mh-match { flex: 1 1 auto; min-width: 66px; }
  .board-mhead .mh-p { flex: 0 0 22px; text-align: center; }
  .board-mhead .mh-tips { flex: 0 1 auto; min-width: 40px; max-width: 96px; text-align: right; }
  .board-mhead .mh-ft { flex: 0 0 auto; min-width: 30px; text-align: right; }
  /* Locked tip: icon only (drop the "paid" label), tight box, and lifted above neighbours. */
  .lock-label { display: none; }
  /* Alternating bands on mobile apply to the whole card (tr), not per cell — so neutralise the
     desktop per-cell rule here and band the row background instead. */
  table.board tr.match-row.row-b td:not(.prob-hi):not(.prob-mid) { background: transparent; }
  :root[data-theme="light"] table.board tr.match-row.row-b td:not(.prob-hi):not(.prob-mid) { background: transparent; }
  table.board tr.match-row.row-b { background: var(--board-row-b); }
  .c-tips .lock-chip { gap: 0; padding: 2px 4px; position: relative; z-index: 2; background: var(--panel); }
  table.board tr.league-group-row { display: block; padding: 10px 4px 4px; }
  /* Value/tips/search filters hide empty league headers via [hidden]; the display:block above
     would otherwise override the UA hidden rule and leave the strip behind (web already hides it). */
  table.board tr.league-group-row[hidden] { display: none; }
  table.board tr.league-group-row td { display: block; padding: 0; background: transparent; }
  table.board tr.match-row {
    display: flex; align-items: center; gap: 6px; width: 100%; box-sizing: border-box;
    background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
    padding: 10px 10px; margin-bottom: 6px; cursor: pointer;
  }
  /* Respect JS filters (value/live/tips/search) which hide rows via the hidden attribute */
  table.board tr.match-row[hidden] { display: none; }
  table.board tr.match-row.expanded { background: var(--panel-2); }
  /* Hide all cells, then show only the ones that matter */
  table.board tr.match-row td { display: none; padding: 0; border-radius: 0; background: transparent; }
  table.board tr.match-row td.c-date { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; flex: 0 0 auto; min-width: 28px; font-size: 11px; font-weight: 700; color: var(--muted); }
  table.board tr.match-row td.c-match { display: block; flex: 1 1 auto; min-width: 66px; width: auto; white-space: normal; overflow: hidden; }
  /* 1X2 Chance percentages — compact cells pulled tight together, keep magnitude colouring */
  table.board tr.match-row td.c-p {
    display: flex; align-items: center; justify-content: center; flex: 0 0 22px;
    font-size: 10.5px; font-weight: 600; text-align: center; border-radius: 4px; padding: 2px 0; height: 28px;
  }
  table.board tr.match-row td.c-p.prob-mid { background: rgba(52,211,153,.14); }
  table.board tr.match-row td.c-p.prob-hi { background: rgba(22,128,90,.85); }
  table.board tr.match-row td.c-p .pct { display: none; }
  /* FT score */
  table.board tr.match-row td.c-ft { display: flex; align-items: center; justify-content: flex-end; flex: 0 0 auto; min-width: 30px; font-size: 12px; font-weight: 700; white-space: nowrap; }
  /* Tip column — more room now the 1X2 are tighter, so tip labels aren't clipped */
  table.board tr.match-row td.c-tips { display: flex; align-items: center; justify-content: flex-end; flex: 0 1 auto; gap: 4px; text-align: right; white-space: nowrap; min-width: 40px; width: auto; max-width: 96px; overflow: hidden; }
  table.board tr.match-row td.c-tips .tip { flex-wrap: nowrap; overflow: hidden; }
  table.board tr.match-row td.c-tips .tip-abbr { font-size: 11px; }
  table.board tr.match-row td.c-match .m-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
  /* A name too long for its slot gets a slow, continuous slide instead of a frozen ellipsis, so
     the full name becomes readable over time. An inline script at the end of the board partial
     (dashboard.html) decides which names actually overflow (scrollWidth vs clientWidth — CSS
     alone can't measure that): only those get wrapped in an inner .m-name-inner span and this
     class. `.m-name` itself must stay the fixed clip window — animating the SAME element that
     clips it would just slide the whole (already-clipped) box sideways as one rigid unit and
     reveal nothing, so it's the inner span that gets translated inside the outer, unmoving crop.
     Ellipsis would also freeze a "…" over text sliding underneath it, so swap to a hard clip. */
  table.board tr.match-row td.c-match .m-name.m-name-marquee { text-overflow: clip; }
  table.board tr.match-row td.c-match .m-name.m-name-marquee .m-name-inner {
    display: inline-block;
    animation: m-name-marquee var(--marquee-dur, 7s) ease-in-out infinite;
  }
  /* Tapping a row open (ⓘ) is a request for full context — stop truncating/sliding the names in
     an expanded row so both are fully readable immediately, wrapping onto a 2nd line if needed.
     Declared after the marquee rules above so it wins the specificity tie when a name is both
     overflowing and expanded. */
  table.board tr.match-row.expanded td.c-match .m-name {
    white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: break-word;
  }
  table.board tr.match-row.expanded td.c-match .m-name .m-name-inner {
    display: inline; animation: none; transform: none;
  }
  table.board tr.match-row td.c-match .m-team { min-width: 0; }
  /* Teams stack vertically inside their cell */
  .m-teams { flex-direction: column; align-items: flex-start; gap: 3px; }
  .m-vs { display: none; }
  /* `align-items: flex-start` above means a row (.m-team) hugs its own content width instead of
     the card's — a long name was rendering at full natural width and bleeding across the row
     into the Chance/Tips cells rather than actually being clipped by the ellipsis rule below it
     (which needs a genuinely narrower box to have anything to do). `width: 100%` clamps it to
     the cell; `.m-name`'s `min-width: 0` lets it shrink inside that flex row instead of the
     default `min-width: auto`, which pins a nowrap span to its full text width regardless. */
  .m-team { display: flex; align-items: center; gap: 6px; width: 100%; }
  .m-name { font-size: 13px; font-weight: 600; min-width: 0; }
  .m-teams .info-btn, .m-teams .crown-link { display: none; }
  /* Tips: show abbreviated */
  .tip-full { display: none; }
  .tip-abbr { display: inline; font-weight: 700; }
  .c-tips .tip { justify-content: flex-end; }
  /* Expanded analyst info row spans full width — but stay hidden until toggled */
  table.board tr.info-row[hidden] { display: none; }
  table.board tr.info-row { display: block; }
  table.board tr.info-row td { display: block; padding: 12px; background: var(--panel-2); border-radius: 8px; margin: 0 0 6px; }
  table.board tr.info-row .info-panel { max-width: 100%; }

  /* Performance page tables: fit to width, hide low-priority columns */
  .table-scroll { overflow-x: visible; display: block; max-width: 100%; }
  table.bets { font-size: 12px; width: 100%; min-width: 0; }
  table.bets th, table.bets td { padding: 8px 5px; }
  table.bets .hide-mobile { display: none; }
}

/* Team-name marquee (mobile card overflow) — slow slide left and back, holding at both ends so
   the start and full tail both get read-time. Not scoped to a viewport: the .m-name-marquee
   class above is only ever added on mobile, so this is inert on desktop regardless. */
@keyframes m-name-marquee {
  0%, 12% { transform: translateX(0); }
  50% { transform: translateX(var(--marquee-shift, 0)); }
  88%, 100% { transform: translateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  table.board tr.match-row td.c-match .m-name.m-name-marquee { text-overflow: ellipsis; }
  table.board tr.match-row td.c-match .m-name.m-name-marquee .m-name-inner { animation: none; }
}

@media (max-width: 480px) {
  .card { padding: 12px 12px; }
  .card h2 { font-size: 14px; }
  table.board { font-size: 12px; }
  table.board td, table.board th { padding: 6px 4px; }
  .c-date { width: 40px; font-size: 11px; }
  .c-match { min-width: 140px; }
  .c-tips { min-width: 80px; font-size: 11px; }
  .c-stake { font-size: 11px; }
  .c-ft { font-size: 11px; }
  .m-name { font-size: 12px; }
}

/* ── zulubet-style main board ─────────────────────────────────────────────── */
/* Match rows are the content: dark (--bg) cards, rounded, floating on the card's own
   --panel surface with a hair of vertical breathing room. The league strip is the surface
   itself (--panel), borderless, so it recedes into the background — the crest hangs a few
   px left of the rows as a barely-there tab. `separate` (not `collapse`) is what buys us
   the per-row rounding and the row gap. */
.board-mhead { display: none; }  /* desktop uses the real <thead>; shown only on mobile */
table.board { width: 100%; max-width: 100%; margin: 0 auto; border-collapse: separate; border-spacing: 0 3px; font-size: 13.5px; }
table.board th { text-align: left; color: var(--muted); font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: .04em; padding: 4px 8px 3px; }
/* All header labels top-align on one line — the single-tier headers (Date/Match/Tips/Stake/FT)
   level with the Chance/Odds group labels — so the 1 X 2 sub-headers tuck underneath. */
table.board thead th { vertical-align: top; }
table.board td { padding: 9px 8px; border: 0; vertical-align: middle; background: var(--board-row-a); }
table.board tr.match-row td:first-child { border-radius: 6px 0 0 6px; }
table.board tr.match-row td:last-child { border-radius: 0 6px 6px 0; }
/* League title = a subtle band (--panel-2: #d0dbd4 light / #1d222b dark) that separates each
   competition; the match rows below sit on the lighter --bg so title and first row alternate. */
table.board tr.league-group-row td { padding: 10px 12px 8px 2px; background: var(--lg-band);
  border: 0; border-radius: 6px 6px 0 0; }
/* Indent the match rows' first column so each league title hangs a little to their left —
   makes the start of a new league easier to spot. Header matches so columns stay aligned. */
table.board thead th.c-date, table.board tr.match-row td.c-date { padding-left: 18px; }

/* Live: the row keeps a green left edge, the Date cell swaps its time for a LIVE tag. */
table.board tr.match-row.is-live td:first-child { box-shadow: inset 2px 0 0 var(--pos); }
.live-tag { display: inline-block; padding: 0 5px; border-radius: 4px; background: rgba(52,211,153,.18);
  color: var(--pos); font-size: 10px; font-weight: 800; letter-spacing: .04em; }
/* Mobile only: the row becomes a rounded card, but td:first-child above still carries the
   TABLE layout's 6px corner radius (see the desktop rule further down) — the inset shadow rounds
   against it and reads as a stray green dot/crescent in front of LIVE. Drop the shadow on mobile
   and let the tag sit in the room it used to eat into. Desktop keeps the dot/edge as-is (untouched). */
@media (max-width: 768px) {
  table.board tr.match-row.is-live td:first-child { box-shadow: none; }
  table.board tr.match-row.is-live td.c-date { padding-left: 2px; }
}

/* Live filter button — a toggle: pressed inverts foreground and background. */
.live-btn::first-letter { color: var(--pos); }
.live-btn[aria-pressed="true"] { background: var(--text); color: var(--bg); border-color: var(--text); }
.live-btn[aria-pressed="true"]::first-letter { color: var(--neg); }
.live-btn[disabled] { opacity: .45; cursor: not-allowed; }
/* Country reads as a quiet subtitle after the league name (not a badge). */
.lg-country { display: inline-block; margin-left: 8px; color: var(--muted); font-size: 11px;
  font-weight: 600; letter-spacing: .02em; vertical-align: middle; }

/* Date / time column */
.c-date { white-space: nowrap; color: var(--muted); font-weight: 700; font-size: 12px;
  font-variant-numeric: tabular-nums; width: 46px; }
.ft-tag { display: inline-block; padding: 0 5px; border-radius: 4px; background: rgba(139,148,163,.18);
  color: var(--muted); font-size: 10.5px; font-weight: 800; }
.tomorrow-tag {
  display: inline-block; font-size: 11px; color: var(--muted); background: var(--panel-2);
  padding: 2px 6px; border-radius: 3px; margin-left: 6px; font-weight: 600;
}
/* Kickoff date subtitle under the time (empty for today's matches → collapses). */
.ko-date { display: block; font-size: 10px; font-weight: 600; color: var(--muted); line-height: 1.1; }
.ko-date:empty { display: none; }

/* Match column — home and away side by side, one line. `width:1%` makes it shrink to its
   content instead of soaking up the table's spare width, which was opening a ~330px void
   between the team names and the Chance columns. The slack goes to Tips (see .c-tips). */
.c-match { min-width: 210px; max-width: 300px; }
.m-teams { display: flex; align-items: center; gap: 0; }
.m-team { display: inline-flex; align-items: center; gap: 6px; vertical-align: middle; min-width: 0; }
.m-vs { color: var(--muted); margin: 0 7px; flex-shrink: 0; }
.m-logo { width: 16px; height: 16px; object-fit: contain; flex-shrink: 0; }
.m-logo-ph {
  display: inline-flex; align-items: center; justify-content: center; font-size: 9px;
  font-weight: 700; color: var(--muted); border: 1px solid var(--line); border-radius: 2px;
}
/* Long club names wrap onto a second line instead of stretching the match column (and with
   it the whole board) past the card edge. Short names still sit on one line. */
.m-name { font-weight: 600; overflow-wrap: break-word; }

/* grouped two-tier header (Chance / Odds over 1 X 2). `border-spacing: 0 3px` gaps the match
   rows, and the same gap falls BETWEEN the two header rows — while stuck, scrolling content
   used to show through that 3px seam under Chance/Odds. The sub-row (1 X 2) cells extend their
   own --panel background UP 3px to close the seam flush; no box-shadow edge to show as a line. */
table.board thead .grp { text-align: center; border-bottom: 0; padding: 4px 8px 0;
  background: var(--panel); }
table.board thead .sub th { padding-top: 0; padding-bottom: 2px; font-size: 10px; text-align: center;
  box-shadow: 0 -3px 0 0 var(--panel); }

/* Sticky header on all screen sizes */
table.board thead th { position: sticky; z-index: 10; background: var(--panel); top: 0; }

/* Sticky header. `.table-scroll` uses overflow-x, and a non-visible overflow on one axis
   computes the other to `auto` — which would make the header stick to a container that
   never scrolls vertically, i.e. not stick at all. So on screens wide enough to need no
   horizontal scroll we drop the scroll container entirely and stick to the viewport,
   offset by the sticky topbar's height. */
@media (min-width: 1180px) {
  .board-scroll { overflow: visible; }
  table.board thead th { top: var(--board-head-top, 70px); }
  /* Offsets are measured at runtime (app.js) — the topbar is flex-wrap and its height
     changes with viewport/auth state, and the two header rows have different heights, so
     any hard-coded value leaves the sub-row overlapping or floating. */
  table.board thead tr:first-child th { top: var(--board-head-top, 70px); }
  table.board thead tr.sub th { top: var(--board-head-top2, 100px); }
}
/* Sortable headers — the whole label is the hit target. */
.sort-th {
  appearance: none; background: none; border: 0; padding: 6px 4px; margin: 0; font: inherit;
  color: inherit; text-transform: inherit; letter-spacing: inherit; cursor: pointer;
  display: inline-flex; align-items: center; gap: 4px; border-radius: 3px; transition: all .15s;
}
.sort-th:hover { color: var(--text); background: rgba(59,130,246,.08); }
.sort-th:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.sort-th[data-active] { color: var(--accent); font-weight: 600; }
.sort-th[data-active]::after { content: " ↓"; font-size: 9px; }
.sort-th[data-active][data-dir="asc"]::after { content: " ↑"; }
/* 3-way Value filter: "with" inverts (like Live), "without" uses the neg accent so the
   two active states read differently at a glance. The Live button styles its dot separately. */
.toggle-btn[data-state="with"]    { background: var(--text); color: var(--bg); border-color: var(--text); }
.toggle-btn[data-state="without"] { background: var(--neg); color: var(--bg); border-color: var(--neg); }
.toggle-btn[disabled] { opacity: .45; cursor: not-allowed; }

/* 1 X 2 probability columns — the whole cell fills green by magnitude rather than wearing a
   border: a strong chance reads dark, a fair one light, an unlikely one stays uncoloured. */
.c-p { text-align: center; width: 40px; }
.prob { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text); }
.prob .pct { font-size: 9px; color: var(--muted); margin-left: 1px; }
table.board td.prob-mid { background: rgba(52,211,153,.14); }   /* fair chance — pale */
table.board td.prob-hi  { background: rgba(22,128,90,.85); }    /* strong chance — deep */
.prob-hi .pct { color: #cdebdd; }
.prob-top { font-weight: 800; }

/* Tips — one line per tip; selection + tip odds + result mark. */
.c-tips { min-width: 150px; width: 1%; white-space: nowrap; }
/* Trailing spacer: the ONLY elastic column. Every real column therefore sizes to its own
   content and packs left, and the table's spare width collects harmlessly on the right
   instead of tearing a gap open in the middle of a row. */
.c-pad { width: 100%; padding: 0; }
.tip { display: flex; align-items: center; gap: 6px; line-height: 1.7; white-space: nowrap; }
.tip-sel { font-weight: 700; }
.tip-mkt { color: var(--muted); font-size: 11px; }
.tip-odd { color: var(--text); font-variant-numeric: tabular-nums; font-size: 12px; }
.tip-mark { font-weight: 800; font-size: 12px; }
.tip-mark.ok { color: var(--pos); }
.tip-mark.no { color: var(--neg); }
.tip-mark.void { color: var(--muted); font-size: 10px; text-transform: uppercase; }
/* Tip text variants: full on desktop, abbreviated on mobile */
.tip-full { display: inline; }
.tip-abbr { display: none; }
/* Stake sits right next to Tips (no wide gap) */
.c-stake { text-align: left; padding-left: 6px; white-space: nowrap; }
.c-stake .stake, .c-stake .stake-fixed { font-weight: 700; }
/* Odds outcome columns */
.c-o { text-align: center; width: 46px; font-variant-numeric: tabular-nums; }
.ln { line-height: 1.7; white-space: nowrap; }

/* FT result + success block */
.c-ft { white-space: nowrap; }
/* Rounded vertical ticker: green when the top 1X2 chance matched the result, red when it missed. */
.ft-ind { display: inline-block; width: 3px; height: 15px; border-radius: 3px; margin-left: 7px;
  vertical-align: middle; }
.ft-ind-win { background: var(--pos); }
.ft-ind-lose { background: var(--neg); }
.ft-score { font-weight: 800; font-variant-numeric: tabular-nums; }
/* No tip on a match → a faint grey ×; a cancelled/abandoned match → a cancel glyph at FT. */
.no-tip { color: var(--muted); opacity: .55; font-weight: 700; }
.ft-cancel { color: var(--muted); font-size: 14px; font-weight: 700; }
.lg-fav { margin-right: 5px; font-size: 13px; vertical-align: middle; }
.res-block { display: inline-block; margin-left: 6px; min-width: 10px; padding: 1px 6px;
  border-radius: 4px; font-size: 11px; font-weight: 700; vertical-align: middle; }
.res-win { background: rgba(52,211,153,.18); }
.res-lose { background: rgba(248,113,113,.18); }
.res-flat { background: transparent; }
.res-block .profit-fixed.pos { color: var(--pos); }
.res-block .profit-fixed.neg { color: var(--neg); }
.tag-cs3 { display: inline-block; padding: 0 5px; border-radius: 4px; background: rgba(59,130,246,.16);
  color: var(--accent); font-size: 10px; font-weight: 700; }
