/* ml.ball design system — "Ledger": light lab-report, IBM Plex Sans + Plex
   Mono, hairlines only, single cobalt accent + semantic win/loss/warning. */

:root {
  --paper: #fafaf8;
  --paper-2: #f1f1ee;
  --ink: #191b1e;
  --muted: #565c63;
  --faint: #878e96;
  --rule: #e5e4e0;
  --rule-strong: #c9c8c2;
  --accent: #3050c8;
  --win: #1a7f4e;
  --loss: #b3372f;
  --warn: #9a6b00;
  --radius: 8px;
  --nav-h: 64px;
  /* the live .nav element overwrites --nav-h on document.documentElement
     (updateNavHeightVar/initNavHeightSync in app.js), so this fallback only
     governs first paint before JS runs; --sticky-top is the single pin point
     every sticky element below the nav uses, with 8px of deliberate
     breathing room so a sticky bar reads as its own element rather than
     flush against the nav's bottom rule. */
  --sticky-top: calc(var(--nav-h, 64px) + 8px);
  --font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  color-scheme: light;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

code, .mono { font-family: var(--font-mono); font-size: 0.92em; }

/* ---------- nav ---------- */

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  padding: 15px clamp(20px, 5vw, 56px);
  border-bottom: 1px solid var(--rule-strong);
  backdrop-filter: blur(8px);
  position: sticky;
  top: 0;
  background: color-mix(in srgb, var(--paper) 94%, transparent);
  z-index: 10;
}

.brand-group { display: flex; align-items: baseline; gap: 10px; min-width: 0; }

.nav .brand {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 16px;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.nav .brand:hover { text-decoration: none; }
.nav .brand .dot { color: var(--accent); }

.brand-sub {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--faint);
  letter-spacing: 0.04em;
  white-space: nowrap;
}

@media (max-width: 560px) {
  .brand-sub { display: none; }
}

/* ---------- page nav (index.html / accuracy.html, in-header) ---------- */

.tabs {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-shrink: 0;
}

.tab {
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.02em;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  padding: 12px 6px;
  border-bottom: 2px solid transparent;
}
.tab:hover { color: var(--ink); text-decoration: none; }
.tab.active { color: var(--ink); font-weight: 600; border-bottom-color: var(--accent); }
.tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ---------- record strip ---------- */

.record-strip {
  max-width: 1120px;
  margin: 0 auto;
  padding: 24px clamp(20px, 5vw, 56px) 6px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
}

.stat { padding: 0 18px 12px 0; }
.stat + .stat { border-left: 1px solid var(--rule); padding-left: 18px; }
.stat .label { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint); }
.stat .value { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 26px; font-weight: 600; margin-top: 4px; color: var(--ink); }
.stat .value small { font-size: 14px; color: var(--muted); font-weight: 400; }

/* ---------- games grid ---------- */

.section-head {
  max-width: 1120px;
  margin: 0 auto;
  padding: 28px clamp(20px, 5vw, 56px) 4px;
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
}
.section-head h2 {
  font-family: var(--font-sans);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
  color: var(--ink);
}
.section-head .date { font-family: var(--font-mono); color: var(--muted); font-size: 13px; }

.slate-note {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 clamp(20px, 5vw, 56px);
  color: var(--faint);
  font-size: 12.5px;
}

.record-line {
  max-width: 1120px;
  margin: 0 auto;
  padding: 22px clamp(20px, 5vw, 56px) 4px;
  color: var(--muted);
  font-size: 13px;
}
/* defensive, mirroring .legend-jump[hidden]'s own reasoning — no author
   `display` rule is set on .record-line itself, so the UA [hidden] rule
   should already apply, but this guards against that ever changing. */
.record-line[hidden] { display: none; }
.record-line .record-line-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.legend-jump { margin-top: 4px; }
/* defensive, mirroring .chip-legend[hidden]'s own reasoning — no author
   `display` rule is set on .legend-jump itself, so the UA [hidden] rule
   should already apply, but this guards against that ever changing. */
.legend-jump[hidden] { display: none; }

.date-nav { display: flex; align-items: center; gap: 10px; font-family: var(--font-mono); font-size: 13px; color: var(--muted); }

.nav-arrow {
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1;
  color: var(--muted);
  background: none;
  border: 1px solid var(--rule-strong);
  border-radius: 4px;
  width: 25px;
  height: 25px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  cursor: pointer;
}
.nav-arrow:hover:not(:disabled) { border-color: var(--ink); color: var(--ink); }
.nav-arrow:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nav-arrow:disabled {
  opacity: 0.35;
  cursor: not-allowed;
  color: var(--faint);
}

.back-today { font-size: 13px; color: var(--accent); white-space: nowrap; }
.back-today:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.day-record {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-width: 100%;
}
.day-record-count { font-family: var(--font-mono); color: var(--muted); font-size: 13px; }
.day-record-note { font-family: var(--font-sans); color: var(--muted); font-size: 12px; }

/* visually hidden but still announced by screen readers (used for the
   polite live-region status next to the date line, since #games itself
   is no longer a live region — see site.css .games / app.js renderDashboard) */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- ledger slate (home page game list) ---------- */

.slate-list {
  max-width: 1120px;
  margin: 0 auto;
  padding: 6px clamp(20px, 5vw, 56px) 56px;
}

.games { display: block; }

.slate-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  grid-template-areas:
    "away apct aruns"
    "mid  mid  ."
    "home hpct hruns"
    "flags flags flags";
  column-gap: 16px;
  align-items: start;
  padding: 12px 16px 12px 10px;
  border-bottom: 1px solid var(--rule);
  color: inherit;
}
a.slate-row:hover { background: var(--paper-2); text-decoration: none; }
a.slate-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* chevron affordance: CSS-only — matches only an actual <a class="slate-row">
   link (never a plain <div class="slate-row"> row for a date without
   details, and never #slate-head, which is a <div>). Placed as a grid item
   on the mid (@ + time) row, in the "." cell of the runs column
   (grid-template-areas "mid mid ." above) — vertically it lines up with the
   @/time line rather than the row's vertical center (which sits lower, past
   the flags line). `width: 0` + `overflow: visible` keeps the box from
   contributing to the runs column's own width — the glyph itself overflows
   rightward into the row's 16px right padding gutter, landing at the same
   x position the old absolutely-positioned chevron used. */
a.slate-row::after {
  content: "›" / "";
  grid-row: 2;
  grid-column: 3;
  justify-self: end;
  align-self: center;
  width: 0;
  overflow: visible;
  white-space: nowrap;
  font-family: var(--font-mono);
  color: var(--faint);
  font-size: 16px;
}
a.slate-row:hover::after { color: var(--accent); }

/* minimal column-header row (#slate-head) — shares .slate-row's own grid
   template so its two labels sit exactly over the pct/runs columns below;
   rows 2-4 of that template stay empty here, so the row collapses to a
   single visible line. Shown only when the slate renders as one flat list:
   a bucketed slate gives every section header the same labels instead (see
   .slate-section-label below and setSlateHeadVisible in app.js). */
.slate-head {
  padding: 0 16px 6px 10px;
  border-bottom-color: var(--rule-strong);
}
/* .slate-row's own `display: grid` is an author rule, so it otherwise beats
   the [hidden] UA rule's `display: none` on origin priority alone (a
   same-specificity author-vs-UA tie always goes to the author) — restated
   here to make the `el.hidden = true` toggle in setSlateHeadVisible actually
   hide the element. */
.slate-head[hidden] { display: none; }
/* the column labels themselves are shared by both carriers — the global
   #slate-head row and each per-bucket .slate-section-label header — since
   both sit on .slate-row's grid and only differ in which of them is on
   screen. Unscoped so the two can't drift apart. */
.col-label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  text-align: right;
  align-self: end;
}
.col-win { grid-area: apct; }
.col-final { grid-area: aruns; min-width: 80px; }

/* fully-ungraded slate: the FINAL column has nothing to show (times moved
   into the mid-line separator), so collapse its reserved width and hide the
   header label — set/removed on #games and #slate-head each render (see
   renderDashboard). Slates with at least one graded game keep the default
   80px reservation above so mixed slates stay column-aligned. The width
   half of this has to reach the per-bucket section headers inside #games
   too, since each of them reserves the same runs column its own rows do
   (slateSectionHeadHtml) and would otherwise hold 80px open while the rows
   under it collapsed to nothing. The label half doesn't: only the finished
   bucket is ever given a FINAL label, and that bucket is non-empty under
   exactly the condition (some game has a final score) that keeps .no-finals
   off in the first place, so a section header's cell is empty here anyway. */
.no-finals .runs-cell, .no-finals .col-final, .slate-head.no-finals .col-final { min-width: 0; }
.slate-head.no-finals .col-final { display: none; }

/* slate section header (slateSectionHeadHtml in app.js) — heads the
   upcoming / finished / in-progress sections, one above every non-empty
   bucket, a single-bucket day included. It carries .slate-row too, so
   the bucket name and its column labels ride the same grid as the rows
   beneath and land over the columns they name; its horizontal padding
   therefore has to match .slate-row's own (10px left, 16px right) or the
   labels drift off their columns. Each header lives inside its own
   <section class="slate-section"> wrapping that bucket's rows, so position:
   sticky constrains it to that bucket alone — it sticks under the nav while
   its own rows scroll past, then gets pushed out by the next section
   instead of the three piling up on top of each other (which is what
   happens if a sticky element's containing block is shared with its
   siblings). */
.slate-section-label {
  position: sticky;
  top: var(--sticky-top);
  z-index: 3;
  background: var(--paper);
  /* --sticky-top is nav height + 8px, and unlike the shadowed floating
     .game-sticky bar this header is flat and full-width, so that 8px reads as
     a transparent slot with row text scrolling through it. Paint it with the
     page background instead of moving the shared pin point. */
  box-shadow: 0 -8px 0 var(--paper);
  padding: 14px 16px 4px 10px;
  border-bottom: 1px solid var(--rule-strong);
}
/* the bucket name keeps the mono uppercase letter-spaced treatment this
   header has always had, but it lives on the name itself rather than on the
   container: as a container rule it inherited into the .col-label spans and
   overrode their lighter, smaller look (weight above all). */
.slate-section-label .section-name {
  grid-area: away;
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  align-self: end;
}

.team-cell { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.mcode { font-family: var(--font-mono); font-weight: 600; font-size: 16px; line-height: 1.2; color: var(--ink); }
.team-cell .sp { font-size: 12.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.slate-row .team-cell.away { grid-area: away; }
.slate-row .team-cell.home { grid-area: home; }

.code-line { display: flex; align-items: baseline; }

/* separator row between a ledger row's away/home lines — carries the "@" of
   the standard "AWAY @ HOME" notation plus, whenever the start time is
   known (graded or not), that time right-aligned at the win-prob column
   edge (see .game-time below). Spans the away+apct columns
   (grid-template-areas "mid mid ."), leaving the FINAL column untouched. */
.slate-row .mid-line {
  grid-area: mid;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 3px 0 4px;
}
.at-sep {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--faint);
  line-height: 1;
}

.pct-cell {
  font-family: var(--font-mono);
  font-size: 16px;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
  color: var(--muted);
  font-weight: 400;
}
.pct-cell.fav { color: var(--accent); font-weight: 600; }
.slate-row .pct-cell { grid-area: apct; align-self: center; }
.slate-row .pct-cell.home { grid-area: hpct; }

.row-flags { grid-area: flags; display: flex; gap: 4px; flex-wrap: wrap; margin-top: 8px; }
.row-flags .contested-chip { margin: 0; }

.runs-cell {
  font-family: var(--font-mono);
  font-size: 16px;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
  min-width: 80px;
  color: var(--ink);
  font-weight: 600;
}
.runs-cell.muted { color: var(--muted); font-weight: 400; }
.slate-row .runs-cell { grid-area: aruns; align-self: center; }
.slate-row .runs-cell.home { grid-area: hruns; }

/* game's start time (shown whether or not the game is graded) — rides the
   mid separator row alongside the "@" (see .mid-line above), right-aligned
   at the win-prob column edge via .mid-line's own flex layout; no longer
   independently grid-positioned. */
.game-time {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
}

/* legacy matchup/team layout — .matchup/.at are shared with the next-day
   preview cards (previewGameCard, which now stacks .team-cell/.mcode/.sp
   inside it for visual consistency with the ledger row above); .team/.code/
   .pct are used only by game.html's win-probability header
   (renderGameHeaderHtml) */

.matchup {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 4px;
}
.matchup .team-cell.away { align-items: flex-start; }
.matchup .team-cell.home { align-items: flex-end; text-align: right; }
.matchup .team-cell .sp { max-width: 140px; }
.team { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.team.away { align-items: flex-start; }
.team.home { align-items: flex-end; text-align: right; }
.team .code { font-family: var(--font-mono); font-weight: 600; font-size: 20px; letter-spacing: 0.01em; color: var(--ink); }
.team .sp { font-size: 12.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 140px; }
.at { color: var(--faint); font-size: 13px; padding: 0 10px; }

.team .pct { font-family: var(--font-mono); font-size: 15px; font-weight: 600; }
.pct.fav { color: var(--accent); }
.pct.dog { color: var(--muted); font-weight: 400; }

.contested-chip {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 3px;
  padding: 1.5px 6px;
  margin: 2px 0 6px;
  white-space: nowrap;
}

.flags { display: flex; gap: 6px; flex-wrap: wrap; min-height: 22px; }
.flag {
  display: inline-block;
  font-size: 10px;
  font-family: var(--font-mono);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: 3px;
  padding: 1.5px 6px;
  border: 1px solid var(--rule-strong);
  color: var(--faint);
  white-space: nowrap;
}
.flag.warn { color: var(--warn); border-color: var(--warn); }
.flag.win, .flag.result-win { color: var(--win); border-color: var(--win); }
.flag.ok { color: var(--win); border-color: var(--win); }
.flag.loss, .flag.result-loss { color: var(--loss); border-color: var(--loss); }
.flag.quiet { color: var(--faint); border-color: var(--rule); }

/* ---------- chip legend (collapsible, index.html) ---------- */

.chip-legend {
  max-width: 1120px;
  margin: 10px auto 0;
  padding: 0 calc(clamp(20px, 5vw, 56px) + 10px);
  scroll-margin-top: calc(var(--nav-h, 64px) + 12px);
}
/* defensive, mirroring .slate-head[hidden]'s own reasoning — no author
   `display` rule is set on .chip-legend itself, so the UA [hidden] rule
   should already apply, but this guards against that ever changing. */
.chip-legend[hidden] { display: none; }
.chip-legend summary {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  list-style: none;
}
.chip-legend summary::-webkit-details-marker { display: none; }
.chip-legend summary::before { content: "▸ " / ""; }
.chip-legend[open] summary::before { content: "▾ " / ""; }
.chip-legend summary:hover { color: var(--muted); }
.chip-legend summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.legend-rows {
  display: grid;
  gap: 7px 0;
  padding: 10px 0 4px;
}
/* fixed 200px label column so every description starts at the same x —
   200px comfortably clears the widest chips ("SP: SOURCES DISAGREE" /
   "LINEUPS: UNAVAILABLE", both 20 chars at 10px IBM Plex Mono: ~120px of
   glyph advance + ~10px letter-spacing + 12px padding + 2px border ≈ 144px). */
.legend-row { display: grid; grid-template-columns: 200px 1fr; gap: 2px 12px; align-items: baseline; }
.legend-row > :first-child { justify-self: start; }
.legend-row .contested-chip { margin: 0; }
.legend-text { font-size: 12.5px; color: var(--muted); }

/* nested inside #games (a block container) rather than replacing it —
   span the full row width instead of collapsing into a grid column */
.empty-state { color: var(--muted); }
.empty-state .box {
  border: 1px dashed var(--rule-strong);
  border-radius: var(--radius);
  padding: 40px;
  text-align: center;
}

/* ---------- next-day preview ---------- */

.preview-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  border: 1px dashed var(--rule-strong);
  border-radius: var(--radius);
  background: var(--paper-2);
  padding: 12px 16px;
  margin-bottom: 4px;
}
.preview-banner-tag {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--warn);
  border: 1px solid var(--warn);
  border-radius: 999px;
  padding: 2px 10px;
  white-space: nowrap;
}
.preview-banner-copy { color: var(--muted); font-size: 13.5px; }
.preview-banner-updated { color: var(--faint); font-size: 12px; font-family: var(--font-mono); flex-basis: 100%; }

/* preview rows (previewGameCard) reuse .slate-row's grid wholesale — same
   away/apct/aruns, mid, home/hpct/hruns, flags areas — plus one full-width
   row under each team's line (adet/hdet) for that starter's own collapsed
   season expander. One shared expander at the bottom of the row read as if
   it belonged to both teams; a row per starter keeps each table attached to
   the pitcher's line directly above it. The FINAL column (aruns/hruns) is
   simply never given content here (a preview never has a result), so that
   grid track collapses to zero width on its own, same as any other empty
   grid track. */
.preview-row {
  grid-template-areas:
    "away apct aruns"
    "adet adet adet"
    "mid  mid  ."
    "home hpct hruns"
    "hdet hdet hdet"
    "flags flags flags";
  /* dashed, not solid: the same preview-vs-prediction cue the old
     .preview-card border used, now carried by the row rhythm instead of a
     card edge. */
  border-bottom-style: dashed;
  border-bottom-color: var(--rule-strong);
}

/* records + venue collapsed into one line (previewGameCard's metaHtml),
   stacked above the flag chips inside the row's own "flags" grid area
   rather than claiming a template row of its own. */
.preview-foot {
  grid-area: flags;
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}
.preview-foot .meta-row { font-size: 13px; }
.preview-foot .row-flags { margin-top: 0; }

/* the small "ERA" unit label riding a preview row's pct-cell (previewEraHtml)
   — the column has no dedicated header on this page (see the #slate-head
   discussion in app.js), so the unit rides every cell instead. */
.pct-cell .pct-unit {
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--faint);
  margin-left: 3px;
}

/* collapsed season expander, one per starter (previewGameCard) — summary
   styling mirrors #chip-legend's own disclosure triangle so the two
   collapsible affordances on the site read as the same control. min-width: 0
   keeps a wide expanded table from growing the row's auto tracks out from
   under the two team lines instead of scrolling inside .table-scroll. */
.preview-det { margin-top: 4px; min-width: 0; }
.preview-det.away { grid-area: adet; }
.preview-det.home { grid-area: hdet; }
.preview-det summary {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  list-style: none;
}
.preview-det summary::-webkit-details-marker { display: none; }
.preview-det summary::before { content: "▸ " / ""; }
.preview-det[open] summary::before { content: "▾ " / ""; }
.preview-det summary:hover { color: var(--muted); }
.preview-det summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* the 6-column season table spans the whole row width (a ledger row is much
   narrower than game.html's .detail-grid) and keeps .table-scroll's
   max-width: 100%, so at 360px it wraps/scrolls within the row rather than
   widening it. */
.preview-det-body { padding-top: 8px; }
.preview-det-body .lineup-table { margin-top: 4px; }

/* ---------- footer ---------- */

footer {
  border-top: 1px solid var(--rule-strong);
  padding: 30px clamp(20px, 5vw, 56px);
  color: var(--faint);
  font-size: 13.5px;
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  justify-content: space-between;
}
footer a { color: var(--muted); }

.disclaimer { max-width: 560px; }

/* ---------- game detail ---------- */

.game-detail {
  max-width: 1120px;
  margin: 0 auto;
  padding: 26px clamp(20px, 5vw, 56px) 80px;
}

.back-nav {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin-bottom: 18px;
}
.back-link {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 500;
  color: var(--accent);
  white-space: nowrap;
}
.back-link:hover { text-decoration: underline; }
.back-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.back-nav-matchup { font-size: 13px; color: var(--faint); }

.game-header { margin-bottom: 10px; }

.micro-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
  margin: 0 0 6px;
}

.detail-section { margin: 34px 0; }
.detail-section h2 {
  font-family: var(--font-sans);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 12px;
  color: var(--ink);
}
.detail-section h3 {
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 600;
  margin: 0 0 10px;
  color: var(--ink);
}
.team-tag { color: var(--ink); font-weight: 600; }

.game-meta { margin-top: 12px; display: flex; flex-direction: column; gap: 4px; }
.meta-row { font-size: 14px; color: var(--muted); }

.detail-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}
@media (min-width: 900px) {
  .detail-grid { grid-template-columns: 1fr 1fr; }
}

/* min-width: 0 is LOAD-BEARING — do not delete it as a no-op.
   These panels are grid items (.detail-grid) and flex items, which default to
   min-width: auto: that floors an item at its *min-content* width instead of
   letting it shrink. The SP season table is wider than a phone viewport, so
   .sp-panel's min-content is ~352px inside a 332px column at 360px wide; the
   panel then refuses to shrink, pushes the grid past the viewport, and the
   whole page scrolls sideways (measured document.scrollWidth 366 vs 360).
   min-width: 0 lets the panel shrink to its column so the wide table scrolls
   inside its own .table-scroll, which is where the scrolling belongs. */
.lineup-panel, .sp-panel, .form-col {
  min-width: 0;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper-2);
  padding: 16px 18px;
}
.lineup-panel p, .sp-panel p { margin: 6px 0; font-size: 14px; color: var(--muted); }

.lineup-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  margin-top: 8px;
}
.lineup-table th, .lineup-table td {
  padding: 6px 8px;
  text-align: left;
  border-bottom: 1px solid var(--rule);
}
.lineup-table th {
  font-family: var(--font-mono);
  color: var(--faint);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 500;
}
.lineup-table td.lg-avg { color: var(--faint); font-style: italic; }
.lineup-table .player-name {
  display: inline-block;
  max-width: 19ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

/* ---------- mobile-safe wide tables ---------- */

.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
}
.table-scroll th, .table-scroll td { white-space: nowrap; }

.sp-season-table th, .sp-season-table td { text-align: center; }

/* The collapsed lineup table (game.html) is the one table-scroll consumer
   cut down to fit 360px without horizontal scrolling (5 columns instead of
   8 — see lineupPanelHtml in app.js), so it's the one deliberately NOT
   wrapped in .table-scroll: overflow-x: auto there would compute
   overflow-y to auto too (CSS spec), turning the table into its own scroll
   container and making a sticky thead stick to that box instead of the
   viewport. Scoped to .lineup-panel so this never touches the SP tables or
   the preview page's lineup table, which still scroll and don't want a
   sticky header. z-index stays below .game-sticky's 5 so the identity bar
   always wins when both are pinned at the top at once; the var(--sticky-top)
   fallback covers the instant before JS measures the real bar (or on any
   page without one). Background is .lineup-panel's own --paper-2, fully
   opaque so rows can't ghost through underneath while scrolling. The bottom
   rule has to be an inset shadow rather than the th's border: with
   border-collapse the border is painted by the table, not the cell, so it
   doesn't travel with the sticky th in Chromium/WebKit and pinned rows
   would slide flush against the header with no separating line. */
.lineup-panel .lineup-table thead th {
  position: sticky;
  top: var(--detail-sticky-top, var(--sticky-top));
  z-index: 4;
  background: var(--paper-2);
  box-shadow: inset 0 -1px 0 var(--rule);
}

/* ---------- expandable lineup rows ---------- */

/* has-detail rows are tabindex="0", so tabbing upward would otherwise scroll
   the focused row under the pinned thead (~29px: 10.5px/1.55 line box, 6px
   padding either side, 1px rule) and the .game-sticky bar already folded
   into --detail-sticky-top. */
.lineup-table tr.lineup-row {
  scroll-margin-top: calc(var(--detail-sticky-top, var(--sticky-top)) + 44px);
}
.lineup-table tr.lineup-row.has-detail { cursor: pointer; }
.lineup-table tr.lineup-row.has-detail:hover { background: var(--paper-2); }
.lineup-table tr.lineup-row.has-detail:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.lineup-table tr.lineup-row.has-detail td { padding-top: 12px; padding-bottom: 12px; }
.lineup-table tr.lineup-row.has-detail .player-name {
  text-decoration: underline dotted;
  text-decoration-color: var(--rule-strong);
  text-underline-offset: 3px;
}
.lineup-table tr.lineup-row.has-detail:hover .player-name,
.lineup-table tr.lineup-row.has-detail:focus-visible .player-name,
.lineup-table tr.lineup-row.has-detail:hover .expand-caret,
.lineup-table tr.lineup-row.has-detail:focus-visible .expand-caret {
  color: var(--accent);
}
.expand-caret { display: inline-block; margin-left: 6px; color: var(--faint); font-size: 11px; }
.lineup-table tr.row-detail > td { background: var(--paper-2); border-left: 2px solid var(--accent); padding: 10px 12px; white-space: normal; }

.row-detail-section + .row-detail-section { margin-top: 12px; }
.row-detail-heading {
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 6px;
}
/* auto-fill wraps to whatever the available width allows: ~3-4 pairs/line
   at a 360px phone, more on desktop, zero horizontal overflow either way. */
.stat-pair-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
  gap: 8px 10px;
}
.stat-pair { display: flex; flex-direction: column; gap: 2px; }
.stat-pair-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--faint); }
.stat-pair-val { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 13px; color: var(--ink); }

.lg-avg-mark { color: var(--warn); font-family: var(--font-mono); margin-left: 2px; cursor: help; line-height: 0; }

/* the numeral and its marker are one unit: an inline-block is a line-break
   opportunity even with no whitespace before it, and these columns are
   narrow enough that the marker would otherwise drop to a second line and
   double the row's height (see lineupPanelHtml's .rate-cell comment). */
.lineup-table td.rate-cell { white-space: nowrap; }

/* the marker's 10px comes out of these two columns' own left padding rather
   than out of the name column. At 360px the name cell is the one that gives
   way, and taking ~20px off it dropped the longest names' expand caret onto
   a second line, doubling those rows' height; paying for the markers here
   keeps every row one line tall and the table inside its panel. The numerals
   are left-aligned under a left-aligned header, so the header cells take the
   same padding or they stop lining up with the column they label. */
.lineup-table th.rate-cell, .lineup-table td.rate-cell { padding-left: 4px; }

/* quintile triangles on the collapsed lineup table's AVG/OPS cells
   (lineupRateMarkHtml). The span is a fixed width and renders on every row,
   empty in the neutral case, so a column never resizes as marks come and go
   between rows and the numerals above and below stay in one line. 8px of
   glyph plus a 2px gap is the whole cost per rate column: that table was cut
   to five columns to clear 360px without a horizontal scrollbar, and it
   still does. Deliberately smaller than the numeral it sits beside, so a
   marked row reads as a number with a mark next to it rather than as a
   coloured cell. Colours are the site's existing result tokens; green-up and
   red-down mean the same thing here as on a graded pick. */
.rate-mark {
  display: inline-block;
  width: 8px;
  margin-left: 2px;
  font-size: 8px;
  line-height: 1;
  vertical-align: 1px;
}
/* cursor: help only on a marker that actually has a title to show: the
   neutral span is an empty width reservation and must not advertise a
   tooltip it doesn't have. */
.rate-mark.up, .rate-mark.down { cursor: help; }
.rate-mark.up { color: var(--win); }
.rate-mark.down { color: var(--loss); }
.stale-note.lg-avg-legend { margin-top: 4px; }

/* the visible quintile legend under the lineup grid (renderLineupsHtml) —
   the same quiet .stale-note footnote treatment as the .lg-avg-legend line
   beside it, so it explains the tables without competing with them, and the
   glyphs inside it are the table's own .rate-mark spans, so a mark in the
   legend renders identically to the one in a cell. Each glyph stays on one
   line with the words it explains while the sentence itself wraps normally:
   the legend sits under a table that has to clear 360px without a
   horizontal scrollbar, so it must never establish a width of its own. */
.stale-note.quintile-legend { margin-top: 4px; }
.quintile-legend .ql-item { white-space: nowrap; }
/* the legend's glyphs are the only .rate-mark spans with no title of their
   own (the words next to them say it instead), so they drop the help cursor
   rather than advertise a tooltip that isn't there. */
.quintile-legend .rate-mark { cursor: auto; }

/* ---------- game-detail page-level floating identity bar ---------- */

/* #game-sticky is the bar's frame, and it sits outside the page flow. It
   used to be display: contents wrapped around a position: sticky bar, which
   took its scroll travel from the tall main.game-detail around it. The bar
   now has to be able to disappear while the real win-probability block in
   #game-header is still on screen (observeGameHeader in app.js), and an
   in-flow bar can only do that by leaving a hole where it was or by
   shifting every section below it at the moment it toggles. Out of flow it
   reserves nothing in either state, so revealing it is pure paint and the
   page never jumps. left/right: 0 with auto margins, plus .game-detail's
   own max-width and page padding, reproduce that content column exactly, so
   the bar still lines up with the sections it labels — the one thing that
   has to be kept in step by hand is that padding, which is repeated in the
   small-screen pass below because .game-detail's own is. Pointer events pass
   through the frame so the gutters beside the bar stay clickable; the bar
   itself takes them back below, as it had them when it was in flow. */
#game-sticky {
  position: fixed;
  top: var(--sticky-top);
  left: 0;
  right: 0;
  z-index: 5;
  margin: 0 auto;
  max-width: 1120px;
  padding: 0 clamp(20px, 5vw, 56px);
  pointer-events: none;
  transition: opacity 160ms ease, transform 160ms ease, visibility 0s;
}

/* tucked = #game-header's own win-probability block is still on screen, so
   this bar would be repeating it a few hundred pixels further down.
   visibility (not display) is what takes it out of the focus order and out
   of the accessibility tree; the opacity and the small lift are what the
   eye sees, and both are compositor-only, so neither costs a layout on a
   phone mid-scroll. The delay on visibility here lets the fade finish
   before the bar goes away; the undelayed one on the base rule brings it
   back the instant it is revealed. Without IntersectionObserver this class
   is never applied at all (app.js), so the bar just stays visible the way
   it always was. */
#game-sticky.tucked {
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 160ms ease, transform 160ms ease, visibility 0s linear 160ms;
}

@media (prefers-reduced-motion: reduce) {
  #game-sticky, #game-sticky.tucked { transition: none; }
}

.game-sticky {
  position: relative;
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 0;
  padding: 8px 14px;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  /* solid, not translucent: a blurred/translucent bar over scrolling page
     content is what made this read as fused with the nav above it. A solid
     paper fill plus a shadow reads as one floating element instead. */
  background: var(--paper);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--ink) 12%, transparent);
  font-family: var(--font-mono);
  font-size: 12.5px;
  font-weight: 600;
}

/* --sticky-top is nav height + 8px, and those 8px are bare page: with the
   article scrolling underneath, the band between the nav's bottom rule and
   the bar reads as a transparent slot with text passing through it.
   .slate-section-label paints its own copy of this gap with a block shadow,
   but that label is flat and square, while this bar is bordered, radiused
   and already carries a drop shadow that a second, opaque shadow layer
   would have to be ordered against. A pseudo-element is simpler here: it
   covers the gap (running 1px up under the nav, so a fractional --nav-h
   can't leave a hairline seam) and keeps going down behind the bar, so the
   corner notches the border radius leaves open are opaque too, rather than
   the two places content still shows through. z-index: -1 puts it behind
   the bar's own background, border and drop shadow, which holds because
   .game-sticky is position: relative at z-index: auto and so creates no
   stacking context of its own — which is also why the fade above lives on
   the #game-sticky frame and not on this element: an opacity or transform
   here would create one and flip this band in front of the bar. */
.game-sticky::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: -9px;
  right: 0;
  bottom: 0;
  left: 0;
  background: var(--paper);
}
.game-sticky .sticky-sep { color: var(--faint); font-weight: 400; }
.side { color: var(--ink); }

.compare-cols { display: grid; grid-template-columns: 1fr; }
@media (min-width: 900px) {
  .compare-cols { grid-template-columns: 1fr 1fr; gap: 0 44px; }
}
.compare-group { margin-bottom: 22px; }
.compare-group h3 {
  font-family: var(--font-sans);
  font-size: 13.5px;
  font-weight: 600;
  margin: 0;
  padding: 10px 0 6px;
  border-bottom: 1px solid var(--rule-strong);
  color: var(--ink);
}
.compare-row {
  display: grid;
  grid-template-columns: 1fr 70px 70px;
  align-items: baseline;
  gap: 10px;
  padding: 6.5px 0;
  border-bottom: 1px solid var(--rule);
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
}
.compare-row.compare-codes {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 500;
  padding: 4px 0 7px;
}
.compare-row.compare-codes .compare-val { color: var(--faint); font-family: var(--font-mono); font-weight: 500; }
.compare-label { font-size: 13px; color: var(--muted); }
.compare-val { font-family: var(--font-mono); text-align: right; color: var(--ink); }
.compare-val.better { color: var(--accent); font-weight: 600; }

.form-chip {
  display: grid;
  grid-template-columns: 64px 1fr 60px 28px;
  align-items: center;
  gap: 8px;
  padding: 5px 0;
  border-bottom: 1px solid var(--rule);
  font-size: 13px;
}
.form-chip .fc-date { color: var(--faint); font-family: var(--font-mono); font-size: 12px; white-space: nowrap; }
.form-chip .fc-opp { color: var(--muted); }
.form-chip .fc-score { font-family: var(--font-mono); }
.form-chip .flag { justify-self: start; }

/* upgradeRecentFormLinks (app.js) swaps a plain <div class="form-chip"> for
   an <a class="form-chip"> once its past game resolves to exactly one
   published prediction — same box/grid as the div (no rule above targets
   the element type), just the link affordance layered on top. */
a.form-chip { color: inherit; text-decoration: none; cursor: pointer; }
a.form-chip:hover { border-bottom-color: var(--accent); }
a.form-chip:hover .fc-opp { color: var(--ink); }
a.form-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.stale-note { color: var(--faint); font-size: 13px; margin: 6px 0; }

.detail-empty { margin: 20px 0; }
.detail-empty .box {
  border: 1px dashed var(--rule-strong);
  border-radius: var(--radius);
  padding: 30px;
  text-align: center;
  color: var(--muted);
}

/* ---------- small-screen pass (~<640px) ---------- */

@media (max-width: 640px) {
  /* defensive: the nav's fixed gaps/font-sizes can outgrow very narrow
     viewports; wrap instead of ever causing page-level horizontal scroll */
  .nav { flex-wrap: wrap; row-gap: 8px; gap: 14px; padding: 14px 16px; }
  .tabs { gap: 10px; }
  .tab { padding: 10px 3px; }

  .record-strip { padding: 18px 16px 6px; }
  .stat { padding: 0 14px 10px 0; }
  .stat .value { font-size: 20px; }
  .section-head { padding: 18px 16px 4px; }
  .date-nav { gap: 6px; row-gap: 6px; flex-wrap: wrap; }
  .nav-arrow { width: 24px; height: 24px; font-size: 13px; }
  .section-head .date { font-size: 12.5px; }
  .slate-list { padding: 6px 16px 40px; }
  .preview-banner { padding: 10px 12px; gap: 8px; }
  .preview-det-body { padding-top: 6px; }
  .legend-row { grid-template-columns: 1fr; }
  .legend-rows { gap: 10px; }

  .game-detail { padding: 18px 14px 60px; }
  .detail-section { margin: 24px 0; }

  .table-scroll th, .table-scroll td { padding: 4px 6px; }
  .lineup-table, .sp-season-table { font-size: 12px; }
  .lineup-table tr.lineup-row.has-detail td { padding-top: 11px; padding-bottom: 11px; }
  /* the base 19ch cap (.lineup-table .player-name above) holds down to
     360px: the 5-column collapsed table (# | Name | Pos | AVG | OPS) fits
     that width whatever the names are. It does not hold at 320px. The
     collapsed table is not wrapped in .table-scroll (so its thead can pin
     to the viewport), so the page's min-content width is the table's, and
     the table's is name-length dependent: the longest published names push
     it past 320px. Below 340px the narrower cap is what holds those pages
     at zero horizontal overflow; the breakpoint stays under 360 so 360px
     phones keep the 19ch cap. */
  @media (max-width: 340px) {
    .lineup-table .player-name { max-width: 14ch; }
  }

  /* tracks .game-detail's own narrow-screen padding above, so the floating
     bar keeps lining up with the content column it labels. */
  #game-sticky { padding: 0 14px; }
  .game-sticky { font-size: 11.5px; padding: 6px 10px; gap: 6px; }
  .compare-group h3 { font-size: 13.5px; }
  .compare-row { grid-template-columns: 1fr 60px 60px; gap: 6px; font-size: 12.5px; }

  .form-chip { grid-template-columns: 52px 1fr 46px 24px; gap: 6px; font-size: 12px; }
}

/* ---------- accuracy history panel ---------- */

.acc-history-panel {
  max-width: 1120px;
  margin: 0 auto;
  padding: 16px 18px;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper-2);
}
.acc-history-panel:not([hidden]) { margin: 10px auto 20px; }

@media (max-width: 1120px) {
  .acc-history-panel:not([hidden]) { margin: 10px clamp(20px, 5vw, 56px) 20px; }
}

.acc-chart-readout {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--muted);
  min-height: 18px;
}

.acc-history-panel svg { display: block; width: 100%; height: auto; }

/* ---------- accuracy page (accuracy.html) ---------- */

.acc-section {
  max-width: 1120px;
  margin: 34px auto 0;
  padding: 0 clamp(20px, 5vw, 56px);
}
.acc-section:last-of-type { padding-bottom: 60px; }
.acc-section h2 {
  font-family: var(--font-sans);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 10px;
  color: var(--ink);
}

.acc-explainer { color: var(--muted); font-size: 14px; max-width: 720px; margin: 0 0 12px; }

.acc-stat-line { font-family: var(--font-mono); font-size: 14px; color: var(--ink); margin: 0; }
.acc-stat-line strong { font-weight: 600; }

.acc-conf-row {
  display: grid;
  grid-template-columns: 150px 1fr 60px 80px;
  align-items: center;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--rule);
  font-size: 13.5px;
}
.acc-conf-row:first-child { padding-top: 0; }
.acc-conf-label { color: var(--muted); }
.acc-conf-bar-wrap {
  position: relative;
  height: 8px;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 4px;
  overflow: hidden;
}
.acc-conf-bar { position: absolute; left: 0; top: 0; bottom: 0; background: var(--accent); border-radius: 3px; }
.acc-conf-bar-ref { position: absolute; left: 50%; top: 0; bottom: 0; width: 1px; background: var(--rule-strong); }
.acc-conf-value {
  font-family: var(--font-mono);
  font-weight: 600;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.acc-conf-n {
  font-family: var(--font-mono);
  color: var(--faint);
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.acc-conf-head {
  display: grid;
  grid-template-columns: 150px 1fr 60px 80px;
  align-items: center;
  gap: 12px;
  padding: 0 0 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
}
.acc-conf-head[hidden] { display: none; }
.acc-conf-head-value, .acc-conf-head-n { text-align: right; }

.acc-team-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px 18px;
  margin: 0 0 16px;
}
.acc-team-stat .label { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint); }
.acc-team-stat .value { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 20px; font-weight: 600; margin-top: 4px; color: var(--ink); }

.acc-team-splits { max-width: 480px; }
.acc-team-split-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 90px 70px;
  align-items: baseline;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid var(--rule);
  font-size: 13.5px;
}
.acc-team-split-row:first-child { padding-top: 0; }
.acc-team-split-label { color: var(--muted); }
.acc-team-split-n { font-family: var(--font-mono); color: var(--faint); text-align: right; font-variant-numeric: tabular-nums; }
.acc-team-split-value { font-family: var(--font-mono); font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; color: var(--ink); }

.acc-team-split-head {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding-bottom: 4px;
}
.acc-team-split-head .acc-team-split-label,
.acc-team-split-head .acc-team-split-n,
.acc-team-split-head .acc-team-split-value {
  color: var(--faint);
  font-weight: 500;
  font-size: 10px;
}

/* ---------- accuracy page: by-team division panels ---------- */

.acc-team-panels {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin: 4px 0 16px;
}
@media (max-width: 900px) {
  .acc-team-panels { grid-template-columns: repeat(2, 1fr); }
}

.acc-division-panel {
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper-2);
  padding: 14px 16px;
}
.acc-division-label { margin-bottom: 8px; }

.acc-division-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 0 2px 4px;
  margin-bottom: 2px;
  border-bottom: 1px solid var(--rule);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
}
.acc-division-head-stats { display: flex; align-items: baseline; gap: 8px; }
.acc-division-head-acc { min-width: 46px; text-align: right; }
.acc-division-head-n { min-width: 28px; text-align: right; }
.acc-division-head-caret-spacer { display: inline-block; width: 17px; }

.acc-team-row-wrap { border-bottom: 1px solid var(--rule); }
.acc-team-row-wrap:last-child { border-bottom: none; }

.acc-team-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  background: none;
  border: none;
  padding: 8px 2px;
  font-family: var(--font-sans);
  font-size: 13.5px;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
}
.acc-team-row:hover { color: var(--accent); }
.acc-team-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.acc-team-row.expanded { color: var(--accent); font-weight: 600; }
.acc-team-row.expanded .acc-team-row-acc { color: var(--accent); }

.acc-team-row-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.acc-team-row-stats {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.acc-team-row-acc { font-weight: 600; color: var(--ink); min-width: 46px; text-align: right; }
.acc-team-row-n { color: var(--faint); font-size: 12px; min-width: 28px; text-align: right; }

.acc-team-row-detail {
  padding: 4px 2px 14px;
  border-top: 1px dashed var(--rule);
  margin-top: 2px;
}
.acc-team-row-detail[hidden] { display: none; }
.acc-team-row-detail .acc-team-summary {
  grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
  gap: 8px 12px;
  margin: 8px 0 10px;
}
.acc-team-row-detail .acc-team-stat .value { font-size: 16px; }
.acc-team-row-detail .acc-team-splits { max-width: none; }
.acc-team-row-detail .acc-team-split-row {
  grid-template-columns: minmax(0, 1fr) 70px 64px;
  gap: 6px;
  padding: 5px 0;
  font-size: 12.5px;
}
.acc-team-row-detail .stale-note { font-size: 11.5px; }

@media (max-width: 640px) {
  .acc-section { padding: 0 16px; }

  .acc-history-panel { padding: 12px 10px; }
  .acc-history-panel:not([hidden]) { margin: 10px 10px 20px; }
  .acc-chart-readout { font-size: 13.5px; }

  /* confidence rows: label/accuracy/games stay on one line, the bar drops
     to a thin full-width strip underneath (see .acc-conf-row's own
     grid-template-areas) instead of stacking every field vertically. */
  .acc-conf-head { grid-template-columns: 1fr 60px 80px; column-gap: 10px; }
  .acc-conf-head-bar { display: none; }
  .acc-conf-row {
    grid-template-columns: 1fr 60px 80px;
    grid-template-areas: "label value n" "bar bar bar";
    row-gap: 6px;
    column-gap: 10px;
    padding: 10px 0;
  }
  .acc-conf-label { grid-area: label; }
  .acc-conf-bar-wrap { grid-area: bar; }
  .acc-conf-value { grid-area: value; text-align: right; }
  .acc-conf-n { grid-area: n; text-align: right; }

  .acc-team-split-row { grid-template-columns: minmax(0, 1fr) 68px 54px; gap: 6px; }
  .acc-team-panels { grid-template-columns: 1fr; }
  .acc-team-row-detail .acc-team-split-row { grid-template-columns: minmax(0, 1fr) 62px 64px; gap: 6px; }
}
