/* ===================================================================
   AcquiCup — design system
   Brand: Acquisit (navy #0F2D52, electric blue #41A4FF, yellow #FFDD65)
   Fonts: Hanken Grotesk (UI) · Geist Mono (scores, odds, tabular nums)
   Themes via [data-theme] on the app root: boardroom | stadium | editorial
   =================================================================== */

:root {
  /* fixed brand anchors (don't change per theme) */
  --brand-navy: #0F2D52;
  --brand-blue: #41A4FF;
  --brand-yellow: #FFDD65;
  --brand-light-blue: #D2EBF3;

  /* semantic status (stable across themes) */
  --pos-bg: #DDF3E9; --pos-tx: #2D7A4F;
  --neg-bg: #FFD4CB; --neg-tx: #B84040;

  --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-xl: 22px; --r-pill: 999px;
  --ff: "Hanken Grotesk", system-ui, sans-serif;
  --fm: "Geist Mono", ui-monospace, "SF Mono", monospace;

  --shadow-card: 0 1px 2px rgba(15,45,82,.04), 0 6px 18px rgba(15,45,82,.06);
  --shadow-pop: 0 10px 40px rgba(15,45,82,.16);
}

/* ---------- THEME: BOARDROOM (default, light corporate) ---------- */
[data-theme="boardroom"] {
  --bg:        #F6F7F9;
  --surface:   #FFFFFF;
  --surface-2: #F6F8FB;
  --surface-3: #EEF2F7;
  --ink:       #0F2D52;
  --ink-2:     #38506E;
  --ink-soft:  #7B8AA0;
  --line:      #E4E8EF;
  --line-2:    #EDF0F5;
  --accent:    #1E72D6;       /* slightly deeper blue for text/buttons on white */
  --accent-soft:#E8F1FC;
  --accent-ink:#FFFFFF;
  --hero-bg:   #0F2D52;       /* navy hero panels */
  --hero-ink:  #FFFFFF;
  --chip-bg:   #F0F3F8;
  --gold:      #C99A2E;
  --logo-filter: none;        /* uses navy logo */
}

/* ---------- THEME: STADIUM (dark, scoreboard energy) ---------- */
[data-theme="stadium"] {
  --bg:        #0A1E38;
  --surface:   #102945;
  --surface-2: #15314F;
  --surface-3: #1B3A5C;
  --ink:       #EAF2FB;
  --ink-2:     #B7C9DE;
  --ink-soft:  #7C93AE;
  --line:      #203F60;
  --line-2:    #1A3556;
  --accent:    #41A4FF;
  --accent-soft:#15314F;
  --accent-ink:#04203F;
  --hero-bg:   #081A30;
  --hero-ink:  #EAF2FB;
  --chip-bg:   #15314F;
  --gold:      #FFDD65;
  --logo-filter: brightness(0) invert(1);
}

/* ---------- THEME: EDITORIAL (paper, bold, yellow accent) ---------- */
[data-theme="editorial"] {
  --bg:        #ECEAE3;
  --surface:   #FBFAF6;
  --surface-2: #F3F1E9;
  --surface-3: #E9E6DB;
  --ink:       #141414;
  --ink-2:     #3A3A38;
  --ink-soft:  #807C72;
  --line:      #DAD6C8;
  --line-2:    #E4E0D3;
  --accent:    #0F2D52;
  --accent-soft:#E5E9F0;
  --accent-ink:#FFFFFF;
  --hero-bg:   #141414;
  --hero-ink:  #FBFAF6;
  --chip-bg:   #ECE9DE;
  --gold:      #B8902B;
  --logo-filter: none;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--ff);
  background: var(--bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
.acq-root { background: var(--bg); color: var(--ink); min-height: 100%; }

/* ---------------- typography helpers ---------------- */
.mono { font-family: var(--fm); font-feature-settings: "tnum" 1; letter-spacing: -.01em; }
/* "N of M" count labels under accuracy bars — tighten the wide mono spaces */
.of-cnt { word-spacing: -.28em; }
.eyebrow {
  font-family: var(--fm); font-size: 11px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft);
}
h1,h2,h3,h4 { margin: 0; font-weight: 700; letter-spacing: -.02em; line-height: 1.1; }
.h-xl { font-size: 30px; font-weight: 800; letter-spacing: -.03em; }
.muted { color: var(--ink-soft); }
.soft  { color: var(--ink-2); }

/* ---------------- layout primitives ---------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}
.card-pad { padding: 18px 20px; }
.row { display: flex; align-items: center; }
.col { display: flex; flex-direction: column; }
.gap-4{gap:4px}.gap-6{gap:6px}.gap-8{gap:8px}.gap-10{gap:10px}.gap-12{gap:12px}
.gap-16{gap:16px}.gap-20{gap:20px}.gap-24{gap:24px}
.between { justify-content: space-between; }
.center { align-items: center; justify-content: center; }
.wrap { flex-wrap: wrap; }
.grow { flex: 1; }

/* ---------------- badges / chips ---------------- */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: var(--r-pill);
  background: var(--chip-bg); color: var(--ink-2); white-space: nowrap;
}
.badge.pos { background: var(--pos-bg); color: var(--pos-tx); }
.badge.neg { background: var(--neg-bg); color: var(--neg-tx); }
.badge.blue{ background: var(--accent-soft); color: var(--accent); }
.badge.gold{ background: color-mix(in srgb, var(--brand-yellow) 35%, transparent); color: var(--gold); }
.badge.done{ background: var(--pos-bg); color: var(--pos-tx); }
.badge.amber{ background: color-mix(in srgb, var(--brand-yellow) 32%, transparent); color: var(--gold); }
.badge.navy{ background: var(--brand-navy); color: #fff; }
[data-theme="stadium"] .badge.navy{ box-shadow: inset 0 0 0 1px rgba(255,255,255,.22); }
.badge.live{ background: #FDEBD3; color: #C46A05; }
[data-theme="stadium"] .badge.live{ background: rgba(242,130,12,.20); color: #FFB266; }

/* ---- match cards: color-coded by status so state reads at a glance ---- */
/* A left accent stripe (inset shadow, respects the rounded corners) + a faint
   header tint differentiate live / finished / locked / upcoming / tbd. */
.match-card { --mc-accent: var(--line); position: relative; }
.match-card { box-shadow: var(--shadow-card), inset 4px 0 0 0 var(--mc-accent); }
.match-card .match-card-head { background: color-mix(in srgb, var(--mc-accent) 6%, transparent); }
.match-card.mc-live      { --mc-accent: #F2820C; }   /* live → orange */
.match-card.mc-finished  { --mc-accent: var(--pos-tx); }   /* finished → green */
.match-card.mc-locked    { --mc-accent: var(--gold); }
.match-card.mc-needspick { --mc-accent: var(--neg-tx); }   /* missing prediction → red */
.match-card.mc-upcoming  { --mc-accent: var(--accent); }   /* upcoming → blue */
.match-card.mc-tbd       { --mc-accent: var(--line); }
/* Live cards earn a touch more presence — a hairline glow on the accent edge. */
.match-card.mc-live { box-shadow: var(--shadow-card), inset 4px 0 0 0 var(--mc-accent), 0 0 0 1px color-mix(in srgb, #F2820C 22%, transparent); }
.match-card.mc-live .match-card-head { background: color-mix(in srgb, #F2820C 8%, transparent); }
/* Un-predicted upcoming cards: a faint red header tint reinforces the red accent. */
.match-card.mc-needspick .match-card-head { background: color-mix(in srgb, var(--neg-tx) 7%, transparent); }
/* On phones the kickoff date and time+timezone stack onto two lines instead of
   sharing one with a " · " separator (which gets cramped beside the stage badge). */
@media (max-width: 640px) {
  .match-card-when { display: inline-flex; flex-direction: column; align-items: center; text-align: center; line-height: 1.3; }
  .match-card-when .mc-sep { display: none; }
}
.dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.live-dot { width: 7px; height: 7px; border-radius: 50%; background: #F2820C; box-shadow: 0 0 0 0 rgba(242,130,12,.6); animation: pulse 1.4s infinite; }
@keyframes pulse { 0%{box-shadow:0 0 0 0 rgba(242,130,12,.5)} 70%{box-shadow:0 0 0 7px rgba(242,130,12,0)} 100%{box-shadow:0 0 0 0 rgba(242,130,12,0)} }

/* ---------------- team flag ---------------- */
.team-flag {
  flex: none;
  object-fit: cover;
  display: inline-block;
  box-shadow: 0 0 0 1px rgba(15,45,82,.12), 0 1px 2px rgba(0,0,0,.14);
}
[data-theme="stadium"] .team-flag { box-shadow: 0 0 0 1px rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.3); }
.team-flag.fallback {
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff; font-family: var(--fm); font-weight: 600; letter-spacing: -.02em;
}

/* ---------------- team badge (legacy) ---------------- */
.team-badge {
  --tc: #888;
  width: 38px; height: 38px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--fm); font-size: 12px; font-weight: 600;
  color: #fff; background: var(--tc); position: relative; flex: none;
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.12);
}
.team-badge.sm { width: 28px; height: 28px; font-size: 10px; }
.team-badge.lg { width: 56px; height: 56px; font-size: 17px; }

/* ---------------- buttons ---------------- */
.btn {
  font-family: var(--ff); font-size: 14px; font-weight: 600;
  border: 1px solid transparent; border-radius: var(--r-pill);
  padding: 10px 18px; cursor: pointer; display: inline-flex; align-items: center;
  gap: 8px; transition: transform .08s ease, background .15s ease, box-shadow .15s; white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 40%, transparent); }
.btn-navy { background: var(--brand-navy); color: #fff; }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn-ghost:hover { background: var(--surface-2); }
/* ghost buttons placed on a dark hero panel — keep icons/borders legible */
.btn-ghost.on-hero { color: var(--hero-ink); border-color: color-mix(in srgb, var(--hero-ink) 28%, transparent); }
.btn-ghost.on-hero:hover { background: color-mix(in srgb, var(--hero-ink) 12%, transparent); }
.btn-soft { background: var(--accent-soft); color: var(--accent); }
.btn-danger { background: var(--neg-tx); color: #fff; }
.btn-danger:hover { box-shadow: 0 4px 14px color-mix(in srgb, var(--neg-tx) 38%, transparent); }
.btn-sm { padding: 7px 13px; font-size: 13px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
/* keyboard focus ring (only on keyboard nav, not mouse click) — theme-aware */
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------------- progress / meters ---------------- */
.meter { height: 7px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.meter > i { display: block; height: 100%; border-radius: 99px; background: var(--accent); }

/* ---------------- table ---------------- */
.lb { width: 100%; border-collapse: collapse; }
.lb thead th {
  text-align: left; font-family: var(--fm); font-size: 10px; font-weight: 500;
  letter-spacing: .05em; text-transform: uppercase; color: var(--ink-soft);
  background: var(--surface-2); padding: 14px 12px; white-space: nowrap;
  border-bottom: 1px solid var(--line);
}
.lb thead th:first-child { padding-left: 18px; }
.lb thead th:last-child { padding-right: 18px; }
.lb td { padding: 13px 12px; border-bottom: 1px solid var(--line-2); font-size: 14px; vertical-align: middle; }
.lb td:first-child { padding-left: 18px; }
.lb td:last-child { padding-right: 18px; }
.lb tr:last-child td { border-bottom: none; }
.lb tr.me-row td { background: var(--accent-soft); }
.lb tr.hov:hover td { background: var(--surface-2); }
/* Sortable column header — clickable, subtly highlights on hover. */
.lb thead th.hov { cursor: pointer; }
.lb thead th.hov:hover { color: var(--ink); background: var(--line-2); }
.rank-num { font-family: var(--fm); font-weight: 600; font-size: 15px; }
/* Center variant — header + content (AcquiBoard Individual table). Scoped so the other
   .lb leaderboards keep their left/right alignment. */
.lb.lb-center thead th, .lb.lb-center td { text-align: center; }

/* movement arrows */
.mv { font-family: var(--fm); font-size: 12px; display: inline-flex; align-items: center; gap: 2px; }
.mv.up { color: var(--pos-tx); } .mv.dn { color: var(--neg-tx); } .mv.flat { color: var(--ink-soft); }

/* scoreboard */
.score-num { font-family: var(--fm); font-weight: 600; font-variant-numeric: tabular-nums; }

/* segmented control / tabs */
.tabs { display: flex; gap: 2px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-pill); padding: 3px; }
.tabs button {
  font-family: var(--ff); font-size: 13px; font-weight: 600; color: var(--ink-soft);
  background: transparent; border: none; padding: 7px 14px; border-radius: var(--r-pill); cursor: pointer; white-space: nowrap;
}
.tabs button.on { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-card); }
/* full-width segmented control: each tab shares the row equally (binary toggles) */
.tabs.tabs-full { width: 100%; }
.tabs.tabs-full button { flex: 1 1 0; text-align: center; }

/* inputs */
.field {
  font-family: var(--ff); font-size: 14px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 11px 13px; width: 100%; outline: none;
}
.field:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
label.lbl { font-size: 12.5px; font-weight: 600; color: var(--ink-2); display: block; margin-bottom: 6px; }

/* divider */
.hr { height: 1px; background: var(--line); border: none; margin: 0; }

/* small line separator under a page sub-header (PageHead) */
.pagehead-sep { width: 120px; height: 3px; border: none; border-radius: 3px; margin: 10px 0 0; background: var(--line); }

/* scroller hide */
.noscroll::-webkit-scrollbar { width: 8px; height: 8px; }
.noscroll::-webkit-scrollbar-thumb { background: var(--line); border-radius: 99px; }

/* ---------------- tournament: group tables + knockout bracket ---------------- */
/* compact league table inside group cards */
.gtbl td, .gtbl th { padding-top: 9px; padding-bottom: 9px; }
.gtbl th.num, .gtbl td.num { text-align: center; padding-left: 7px; padding-right: 7px; width: 34px; }
.gtbl th:last-child, .gtbl td:last-child { padding-right: 16px; }
.gtbl tr.qrow td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* match card (shared by the desktop tree, mobile rounds, 3rd-place card) */
.ko-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 10px 12px; box-shadow: var(--shadow-card);
  transition: border-color .12s, transform .08s;
}
.ko-card.pointer:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.ko-card.pointer:active { transform: translateY(1px); }
.ko-team { display: flex; align-items: center; gap: 9px; }
.ko-team .nm { font-weight: 600; font-size: 13px; }
.ko-team.ko-win .nm { font-weight: 800; }
.ko-team.ko-lose { opacity: .48; }
/* fixed-width winner mark (left) + fixed-width score column (right): keeps the two
   team rows' ticks and scores vertically aligned regardless of name length */
.ko-mark { flex: none; width: 14px; display: inline-flex; align-items: center; justify-content: center; }
.ko-score { flex: none; width: 18px; text-align: center; font-size: 14px; }

/* tentative entrant — the team currently holding a "1st/2nd Group X" slot, shown
   italic with a dashed flag + an accent slot chip (e.g. "1C") and a "Tentative" pill
   in the card meta row; the unresolved placeholder slot (a "Winner Match 73" /
   "3rd Group …" label) is shown in muted, smaller text. */
.ko-team.ko-tentative .nm { font-style: italic; font-weight: 600; color: var(--ink-soft); }
.ko-team.ko-tentative .team-flag { border: 1.5px dashed color-mix(in srgb, var(--accent) 55%, var(--line)); }
.ko-team.ko-placeholder .nm { font-size: 12px; }
.ko-slot-tag {
  flex: none; font: 800 9.5px/1 var(--fm); letter-spacing: .04em;
  color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--accent) 38%, var(--line)); border-radius: 4px; padding: 2px 4px;
}
/* the prominent "Tentative" label in the card meta row */
.ko-tentative-tag {
  display: inline-flex; align-items: center; gap: 4px;
  font: 800 9.5px/1 var(--fm); letter-spacing: .06em; text-transform: uppercase;
  color: var(--gold); background: color-mix(in srgb, var(--brand-yellow) 22%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--gold) 45%, var(--line)); border-radius: 999px; padding: 2px 8px;
}
.ko-tentative-tag .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--gold); }

/* ---- knockout bracket: connected tree with SVG path connectors ---- */
/* the host .card keeps overflow:hidden; this inner wrapper is the only scroller */
.kob-scroll { overflow-x: auto; overflow-y: hidden; padding-bottom: 8px; }
.kob-inner { position: relative; }
.kob-headers { position: relative; }
.kob-headers .kob-h { position: absolute; top: 0; text-align: center; }
.kob-stage { position: relative; }
/* SVG sized to the stage; sits under the cards and passes clicks through */
.kob-links { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 0; overflow: visible; }
.kob-links path { fill: none; stroke: var(--line-2); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
/* tree cards are absolutely placed by JS geometry; height is the geometry source of truth */
.kob-card { position: absolute; z-index: 1; box-sizing: border-box; padding: 9px 11px; overflow: hidden; }
/* legend chip + the mobile round connector chevron */
.kob-legend { display: inline-flex; align-items: center; gap: 8px; font: 500 11px/1.4 var(--fm); color: var(--ink-soft); }
.kob-legend .dot { flex: none; width: 9px; height: 9px; border-radius: 3px; border: 1px solid var(--line); background: var(--surface-2); }
.kob-mchev { display: flex; justify-content: center; color: color-mix(in srgb, var(--ink-soft) 80%, transparent); margin: -2px 0; }

/* utility */
.pointer { cursor: pointer; }
.full { width: 100%; }
.nowrap { white-space: nowrap; }
a { color: inherit; text-decoration: none; }

/* ===================================================================
   RESPONSIVE LAYER
   Tiers: mobile ≤640 · tablet 641–1023 · desktop ≥1024.
   The shell swaps top-nav↔bottom-nav in JS at 820 (useNarrow): ≥820 renders the
   sticky desktop top bar, <820 the mobile top bar + bottom tabs. These
   rules add the CSS reflow/scaling that was missing (styles.css had zero
   @media queries). Inline styles in the JSX win the cascade, so overrides of
   inline grid/padding/font/width use !important — each tightly scoped to a
   media query + class hook so nothing leaks to desktop. All colors use theme
   vars so the three [data-theme]s stay correct.
   =================================================================== */

/* let flex children shrink (ellipsis) instead of forcing overflow */
.col, .grow { min-width: 0; }
img { max-width: 100%; height: auto; }

/* Forced line break shown only on the desktop top-bar tier (≥820); below that the
   text flows/wraps naturally. Used to split a two-sentence sub-header one per line. */
.desk-br { display: none; }
@media (min-width: 820px) { .desk-br { display: inline; } }

/* The dashboard & beat-acquisit two-column grids carry .dash-grid as a reflow
   hook but no CSS ever targeted it — collapse them to one column below 900. */
@media (max-width: 900px) {
  .dash-grid { grid-template-columns: 1fr !important; }
}

/* On phones the headline stats stop auto-fitting (which would stack all three);
   instead Total points spans the full width and the two ranking tiles share one
   row below it. */
@media (max-width: 640px) {
  .dash-stats { grid-template-columns: 1fr 1fr !important; }
  .dash-stats > :first-child { grid-column: 1 / -1; }
}

/* ---- TABLET (821–1023): trim content side padding so it keeps room ---- */
@media (min-width: 821px) and (max-width: 1023px) {
  main.noscroll > div { padding-left: 22px !important; padding-right: 22px !important; }
}

/* ---- DESKTOP TOP NAV (replaces the old left sidebar; shell renders it ≥820) ----
   Hover state for non-active items: the JSX sets the active pill via an inline
   background, so scope the hover to :not(.on) and use !important to beat the
   inline `transparent` on the inactive items. */
.topnav-item:not(.on):hover { background: var(--surface-2) !important; color: var(--ink) !important; }
/* keyboard focus ring for the nav links + brand (mouse clicks stay ring-free) */
.topnav-item:focus-visible, .topnav-brand:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 10px; }
/* the nav can scroll horizontally as a safety valve on cramped widths — hide the bar */
.topnav-nav { scrollbar-width: none; }
.topnav-nav::-webkit-scrollbar { display: none; }
/* Progressive compaction so the bar never overflows as the viewport narrows:
   ≤1140 drop the name/rank text (avatar + Sign out stay); ≤900 drop the nav
   labels (icon-only — the title attr supplies a hover tooltip). Both classes
   only exist in the desktop shell, so these are inert in the mobile shell. */
@media (max-width: 1140px) { .topnav-name { display: none; } }
@media (max-width: 900px) { .topnav-label { display: none; } }

/* ---- TABLET TOP NAV (820–1023) ----
   On a tablet the five icon-only items clumped in the middle with a big empty
   gap on either side. The fix is to bring the labels back down to 901px so the
   centred nav fills the bar like it does on desktop — the wider labelled items
   leave no awkward side gaps. The items + bar chrome are tightened so all five
   labelled items still fit the centre band; only the narrowest tablets (≤900)
   fall back to icon-only. Inline styles in the JSX win the cascade, hence the
   !important on the tightening. */
@media (min-width: 820px) and (max-width: 1023px) {
  .topnav-inner { gap: 12px !important; padding-left: 18px !important; padding-right: 18px !important; }
  .topnav-nav   { gap: 2px !important; }
  .topnav-right { gap: 9px !important; }
  .topnav-item  { padding: 8px 9px !important; gap: 6px !important; font-size: 13px !important; }
}

/* ---- AUTH: the 2-panel split stacks, then drops the brand panel on phones ----
   Scoped to the auth-only .auth-split hook so the rule can't leak to other
   layouts. (The authed shell is a separate column layout — header + main — and
   carries no .auth-split, so it's untouched here.) */
/* mobile-only login logo: hidden until the brand panel drops out (≤640px below) */
.auth-mobile-brand { display: none; }
@media (max-width: 820px) {
  .auth-split { flex-direction: column !important; }
  .auth-brand { padding: 32px 24px !important; }
}
@media (max-width: 640px) {
  .auth-brand { display: none !important; }
  /* the brand panel is gone on phones, so surface the logo atop the form instead */
  .auth-mobile-brand { display: block !important; }
  /* stack the First/Last name fields (min-width:0 would otherwise keep them side-by-side) */
  .auth-names { flex-direction: column; align-items: stretch; }
}

/* ---- bottom tab bar: real touch targets (only exists while shell is mobile, <820) ---- */
@media (max-width: 819px) {
  .bottom-tab { min-height: 46px; min-width: 54px; justify-content: center; }
}

/* ---- mobile slide-out drawer ("top menu", opened by the header hamburger) ----
   Mount-time entrance animations only (no exit anim — the node unmounts on close,
   matching the conditionally-rendered Modal). Slides in from the right edge. */
@keyframes drawer-in { from { transform: translateX(100%); } to { transform: translateX(0); } }
@keyframes drawer-fade { from { opacity: 0; } to { opacity: 1; } }
.mobile-drawer { animation: drawer-in .22s cubic-bezier(.2,.8,.2,1); }
.mobile-drawer-backdrop { animation: drawer-fade .2s ease; }
@media (prefers-reduced-motion: reduce) {
  .mobile-drawer, .mobile-drawer-backdrop { animation: none; }
}

/* ---- MOBILE (≤640): scale the frozen desktop type / padding / tap targets ---- */
@media (max-width: 640px) {
  .h-xl { font-size: 23px; }
  .card-pad { padding: 14px 15px; }
  /* 16px input text stops iOS Safari auto-zooming on focus */
  .field { font-size: 16px; padding: 12px 13px; }
  .tabs button { padding: 10px 15px; }
  .btn { padding: 11px 16px; }
  .btn-sm { padding: 9px 14px; }
  .team-badge.lg { width: 46px; height: 46px; font-size: 15px; }
  /* tables reclaim horizontal room (leaderboards + admin) */
  .lb thead th, .lb td { padding: 11px 8px; }
  .lb thead th:first-child, .lb td:first-child { padding-left: 13px; }
  .lb thead th:last-child, .lb td:last-child { padding-right: 13px; }
  /* keep inline table inputs/buttons touch-sized without enlarging their text */
  .lb .field { min-height: 38px; }
  .lb .btn-sm { min-height: 36px; }
  /* Dashboard "Recent points" is a 6-column table — too wide for a phone. Give it a
     min-width so the wrapper's overflow-x scrolls cleanly instead of squeezing the
     Match cell, whose centered flex content would otherwise overflow (and clip) on
     BOTH sides, hiding the leftmost team badge with no way to scroll to it. */
  .dash-recent-table { min-width: 540px; }
  /* Dashboard KPIs: force two tiles per row on mobile (auto-fit at minmax(180px,…)
     collapses to one column on a ~360px phone). Inline grid-template wins the
     cascade, hence !important. */
  .dash-kpis { grid-template-columns: 1fr 1fr !important; gap: 12px !important; }
  /* In a half-width tile the 30px value (e.g. "0/2 used") would wrap; trim it. */
  .dash-kpis .card-pad { padding: 14px 14px !important; }
  .dash-kpis .mono { font-size: 24px !important; }
}

/* ---- dashboard / beat-acquisit hero blocks ---- */
@media (max-width: 640px) {
  .hero-card .card-pad { padding: 20px 18px !important; }
  .hero-card h1 { font-size: 22px !important; }
  .hero-card .mono { font-size: 26px !important; }
}

/* My-stats / Prediction-strategy legend labels: the legend columns are sized to
   their bar segment, so the long labels ellipsis on narrow phones. Swap to the
   short variant (Exact / Good / Wrong) at the mobile breakpoint. */
.dash-lbl-short { display: none; }
@media (max-width: 640px) {
  .dash-lbl-full { display: none; }
  .dash-lbl-short { display: inline; }
}

/* ---- Player / Company profile (screens-user) mobile tweaks ---- */
@media (max-width: 640px) {
  /* The hero banner repeats the player's points + rank, but the stat tiles right
     below show the same — drop the duplicate aside on phones. With the aside gone
     the identity block spans the full width; top-align the logo (instead of the
     desktop vertical-center) so it lines up with the eyebrow/name rather than
     floating against a taller text column (company hero with a domain link). */
  .profile-hero-aside { display: none !important; }
  .profile-hero-id { align-items: flex-start !important; }
  /* Both points donuts go full-width (one per row) so each keeps its legend on the
     right instead of wrapping it below. */
  .profile-donuts { grid-template-columns: 1fr !important; gap: 16px !important; }
  /* Keep the legend BESIDE the (shrunk) ring: no wrap, tighter gap, and a flexible
     label that wraps its text rather than pushing the whole legend onto its own row. */
  .donut-chart { flex-wrap: nowrap !important; gap: 14px !important; }
  .donut-chart .donut-legend { flex: 1 1 auto !important; min-width: 0; }
  .donut-chart .donut-legend-label { flex: 1 1 auto !important; width: auto !important; min-width: 0; white-space: normal !important; }
}

/* ---- My-stats bar hover tooltip (Accuracy rate / Risk rate) ----
   A centered popover lifted above the bar; its caret tracks the hovered segment.
   Lists every bucket's share %, count and points, with the hovered one emphasised. */
.statbar-tip {
  position: absolute; bottom: 100%; transform: translate(-50%, -10px);
  z-index: 30; width: max-content; max-width: min(320px, 92%);
  padding: 11px 13px 12px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--shadow-pop);
  pointer-events: none; /* never steal the hover from the bar/legend below */
  animation: statbar-tip-in .12s ease-out;
}
/* slide only — no opacity fade, so the popover is fully solid the instant it appears */
@keyframes statbar-tip-in {
  from { transform: translate(-50%, -4px); }
  to   { transform: translate(-50%, -10px); }
}
.statbar-tip-head { display: flex; align-items: center; gap: 8px; padding-bottom: 9px; margin-bottom: 8px; border-bottom: 1px solid var(--line-2); }
.statbar-tip-title { font-weight: 700; font-size: 13px; color: var(--ink); }
.statbar-tip-pct { margin-left: auto; font-weight: 800; font-size: 16px; letter-spacing: -.01em; }
.statbar-tip-dot { width: 11px; height: 11px; border-radius: 4px; flex: none; }
.statbar-tip-dot.sm { width: 9px; height: 9px; border-radius: 3px; }
.statbar-tip-rows { display: flex; flex-direction: column; gap: 1px; }
.statbar-tip-row {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 6px; margin: 0 -6px; border-radius: 7px;
  font-size: 12px; color: var(--ink-soft); transition: background .1s;
}
.statbar-tip-row.on { background: var(--surface-2); color: var(--ink); }
.statbar-tip-row.total { margin-top: 4px; padding-top: 7px; border-top: 1px solid var(--line-2); border-radius: 0; }
.statbar-tip-lbl { flex: 1; min-width: 0; white-space: nowrap; font-weight: 600; }
.statbar-tip-row.on .statbar-tip-lbl { font-weight: 700; }
.statbar-tip-val { flex: none; font-weight: 700; color: var(--ink); }
.statbar-tip-of { color: var(--ink-soft); font-weight: 600; }
.statbar-tip-pts { flex: none; min-width: 48px; text-align: right; font-weight: 600; color: var(--ink-soft); }
.statbar-tip-share { flex: none; min-width: 36px; text-align: right; font-weight: 800; color: var(--ink); }
.statbar-tip-caret {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  width: 0; height: 0; border-left: 7px solid transparent; border-right: 7px solid transparent;
  border-top: 7px solid var(--surface);
  filter: drop-shadow(0 1px 0 var(--line));
}

/* Portal variant (leaderboard/acquiboard table bars): fixed-positioned so the table's
   horizontal-scroll wrapper can't clip it; left/top come from inline styles. Header pct
   defaults to ink (the Dashboard sets a per-segment colour inline). A footer meta line
   carries the denominator / risk index. Fade-only animation so the inline transform that
   positions the popover isn't overridden by a keyframe. */
.statbar-tip-pct { color: var(--ink); }
.statbar-tip-foot { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-2); font-size: 11px; color: var(--ink-soft); }
.statbar-tip.is-fixed { position: fixed; bottom: auto; animation: none; }
/* flipped (rendered below the bar) → caret on top edge, pointing up */
.statbar-tip.flip .statbar-tip-caret {
  top: auto; bottom: 100%;
  border-top: 0; border-bottom: 7px solid var(--surface);
  filter: drop-shadow(0 -1px 0 var(--line));
}

/* ---- prediction-detail scoreboard (scoped so match-card .score-num is untouched) ---- */
@media (max-width: 520px) {
  .pred-hero { padding: 22px 14px 24px !important; }
  .pred-hero .score-num { font-size: 38px !important; }
  .pred-hero .stepper .score-num { width: 56px !important; font-size: 44px !important; }
  .pred-hero .stepper .btn { width: 48px !important; height: 44px !important; }
}

/* ---- calendar sticky date header: clear whichever top bar is present ----
   Both shells now have a sticky top bar, so the date header (inline top:0) must
   stick *below* it or it'd hide behind the bar: 52px for the mobile shell (<820),
   60px for the desktop top nav (≥820). Inline style wins the cascade, hence
   !important on both offsets. The bar's z-index (30 mobile / 50 desktop) sits
   above the date header's z-index:2, so the bar always covers it. */
.cal-date { background: var(--bg); z-index: 2; padding: 4px 0; }
@media (max-width: 819px) { .cal-date { top: 52px !important; } }
@media (min-width: 820px) { .cal-date { top: 60px !important; } }

/* ---- toast clears the fixed bottom-nav on mobile and never intercepts taps ---- */
@media (max-width: 819px) {
  .app-toast { bottom: calc(env(safe-area-inset-bottom, 0px) + 78px) !important; }
}

/* ============================== LANDING PAGE ==============================
   The landing page reuses the app shell & primitives wholesale (topnav, 1080
   container, hero-card, PageHead, .card/.lb, RankChartCard, buttons, gap-* scale)
   so there is no visual jump on sign-in. The only landing-specific rule: the
   center anchor links in the reused topnav collapse on small screens, exactly
   like the app's own .topnav-label does. */
.lp-nav .topnav-item:hover { background: var(--surface-2); color: var(--accent); }
@media (max-width: 720px) { .lp-nav { display: none !important; } }

/* the four rules sit in a single row, reflowing to 2 then 1 column on small screens */
.lp-rules { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
@media (max-width: 900px) { .lp-rules { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .lp-rules { grid-template-columns: 1fr; } }

/* headline stats (Matches/Teams/AI rivals/To join): the auto-fit grid collapses
   to a single column on phones, so force a 2-up layout below the mobile breakpoint
   (inline grid-template-columns wins the cascade, hence !important). */
@media (max-width: 640px) {
  .lp-stats { grid-template-columns: 1fr 1fr !important; }
}

/* "Your AI rivals": on phones drop the label to its own line and keep the three
   AI logos on a single non-wrapping row below it (tighter gap so they fit). */
@media (max-width: 640px) {
  .lp-airivals { flex-direction: column; align-items: flex-start !important; gap: 8px !important; }
  .lp-airivals-list { flex-wrap: nowrap !important; gap: 16px !important; }
}
