/* Light is the default (dark navy/black logos read better on light). The
   toggle in the nav flips <html data-theme="dark"> and stores the choice. */
:root {
  --bg: #f6f7f9;
  --bg-raised: #eceff4;
  --bg-card: #ffffff;
  --border: #d8dee8;
  --text: #17202e;
  --text-dim: #5a6577;
  --accent: #0f8a4a;
  --accent-2: #1f6feb;
  --danger: #cf3a2f;
  --warn: #a9780a;
  --nav-bg: rgba(246, 247, 249, 0.92);
  --panel: #f1f3f7;
  --radius: 10px;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

[data-theme="dark"] {
  --bg: #0b0e14;
  --bg-raised: #121722;
  --bg-card: #151b28;
  --border: #232b3d;
  --text: #e8ecf4;
  --text-dim: #93a0b4;
  --accent: #38d17c;
  --accent-2: #4f9cf9;
  --danger: #ff5d5d;
  --warn: #ffcc4d;
  --nav-bg: rgba(11, 14, 20, 0.92);
  --panel: #131824;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 15px;
  line-height: 1.45;
}

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

/* ---------- top nav ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  padding: 10px 18px;
  background: var(--nav-bg);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--border);
}
.nav .theme-toggle {
  margin-left: auto;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 8px;
  padding: 5px 10px;
  font-size: 14px;
  line-height: 1;
}
.nav .theme-toggle:hover { color: var(--text); border-color: var(--accent-2); }
.nav .glossary-btn {
  margin-left: auto;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 8px;
  padding: 5px 10px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
}
.nav .glossary-btn:hover { color: var(--text); border-color: var(--accent-2); }
/* when both buttons are present (theme-toggle also has margin-left:auto), keep them together */
.nav .theme-toggle + .glossary-btn, .nav .glossary-btn + .theme-toggle { margin-left: 4px; }

/* ---------- glossary modal ---------- */
.gloss-backdrop {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 40px 16px;
  overflow-y: auto;
}
.gloss-dialog {
  background: var(--bg-card, var(--bg));
  border: 1px solid var(--border);
  border-radius: 12px;
  max-width: 640px;
  width: 100%;
  padding: 18px 20px 22px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
}
/* Even with every row collapsed a term-heavy page (the team page has 17) runs long on a
   phone, so the box is bounded and scrolls inside. Wider screens keep the height they
   had — the backdrop already scrolls there. */
@media (max-width: 640px) { .gloss-dialog { max-height: 80vh; overflow-y: auto; } }
.gloss-head {
  display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px;
  position: sticky; top: -18px; background: var(--bg-card, var(--bg)); padding-top: 18px;
}
.gloss-head h2 { margin: 0; }
.gloss-close {
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 6px;
}
.gloss-close:hover { color: var(--text); background: var(--bg-raised); }
.gloss-sub { color: var(--text-dim); font-size: 13px; margin: 0 0 12px; }
/* Each term is a native <details> so a phone can collapse it (see openGlossary);
   above the phone breakpoint the rows ship open and read as a plain list. */
.gloss-term { border-top: 1px solid var(--border); }
.gloss-term:first-of-type { border-top: none; }
.gloss-term > summary {
  list-style: none;
  cursor: pointer;
  padding: 10px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.gloss-term > summary::-webkit-details-marker { display: none; }
.gloss-term > summary::after { content: '▾'; color: var(--text-dim); font-size: 10px; }
.gloss-term[open] > summary::after { transform: rotate(180deg); }
.gloss-label { font-weight: 700; font-size: 13.5px; color: var(--accent); }
.gloss-def { color: var(--text); font-size: 13.5px; line-height: 1.5; margin: 2px 0 10px; }
.nav .brand {
  font-weight: 800;
  letter-spacing: 0.04em;
  margin-right: 14px;
  color: var(--text);
  font-size: 16px;
  white-space: nowrap;
}
.nav .brand span { color: var(--accent); }
.nav a.item {
  color: var(--text-dim);
  padding: 6px 11px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 13.5px;
}
.nav a.item:hover { color: var(--text); background: var(--bg-raised); text-decoration: none; }
.nav a.item.active { color: var(--accent); background: rgba(56, 209, 124, 0.1); }

/* ---------- layout ---------- */
.wrap { max-width: 1180px; margin: 0 auto; padding: 22px 18px 60px; }

h1 { font-size: 24px; margin: 6px 0 4px; letter-spacing: 0.01em; }
h2 { font-size: 17px; margin: 26px 0 10px; color: var(--text); }
.sub { color: var(--text-dim); font-size: 13.5px; margin: 0 0 18px; }
.note { color: var(--text-dim); font-size: 13px; line-height: 1.5; margin: 10px 0 14px;
        padding: 8px 12px; border-left: 3px solid var(--accent); background: var(--bg-raised);
        border-radius: 6px; }
/* one-sentence takeaway every page leads with (see summary: pages owe a lede) */
.lede { font-size: 15px; line-height: 1.5; margin: 2px 0 12px; max-width: 80ch; }
/* inside the explanation box the takeaway carries the text colour, not the dim body colour */
.note .lede { color: var(--text); margin: 0 0 6px; }
.note .sub { margin: 0 0 10px; }

.controls {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: flex-end;
  margin: 14px 0 18px;
}
.controls label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  font-weight: 700;
}
/* the author display:flex above beats the UA [hidden] rule — keep it winning */
.controls label[hidden] { display: none; }

select, input, button {
  background: var(--bg-raised);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 10px;
  font-size: 14px;
  outline: none;
}
select:focus, input:focus { border-color: var(--accent-2); }
/* keyboard-only focus ring; mouse clicks stay quiet (the outline:none above) */
:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
button { cursor: pointer; font-weight: 700; }
button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #04110a;
}
button.primary:hover { filter: brightness(1.08); }
button:disabled { opacity: 0.5; cursor: not-allowed; }

/* ---------- cards / tables ---------- */
.card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 18px;
  /* wide tables scroll inside the card instead of the whole page */
  overflow-x: auto;
}

/* pin the identity column while a wide table scrolls sideways */
.sticky-col { position: sticky; left: 0; background: var(--bg-card); z-index: 2; }
th.sticky-col { z-index: 3; }

table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
/* compact stat tables (critical stats / team stats): keep the two team value
   columns tight against the metric title instead of spreading full width */
table.data.stat-table { width: auto; }

/* CFP odds: equal fixed-width probability columns so the table lines up */
table.cfp-table { table-layout: fixed; }
table.cfp-table th:nth-child(1) { width: 24%; }
table.cfp-table th:nth-child(2) { width: 26%; }
table.cfp-table th:nth-child(n+3), table.cfp-table td:nth-child(n+3) { width: 10%; text-align: center; }
/* game page: team stats + critical stats side by side */
.stats-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  align-items: start;
}
@media (max-width: 900px) { .stats-split { grid-template-columns: 1fr; } }
table.data th {
  text-align: left;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-dim);
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
table.data td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
table.data tr:hover td { background: rgba(79, 156, 249, 0.05); }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data td.ctr, table.data th.ctr { text-align: center; }
/* "Preview →" link to the game page for a not-yet-played game (games.html and the
   team page's schedule); games.html adds its own left margin where it sits inline. */
.preview { white-space: nowrap; font-size: 12px; }

/* click-to-sort column headers */
th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover { color: var(--text); background: rgba(79, 156, 249, 0.07); }
th.sortable .sort-arrow { color: var(--accent); font-size: 9px; }

.muted { color: var(--text-dim); }
.small { font-size: 12px; }
.mono { font-family: var(--mono); font-size: 12.5px; }

/* team identity */
.tm {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.tm img { width: 22px; height: 22px; object-fit: contain; flex: none; }
.tm .init {
  width: 22px; height: 22px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 5px;
  font-size: 9.5px; font-weight: 800; color: #fff;
}
.tm .accent {
  width: 4px; height: 22px; border-radius: 2px; flex: none;
}

/* pill / badges */
.pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  border: 1px solid var(--border);
  color: var(--text-dim);
}
.pill.W { color: var(--accent); border-color: rgba(56, 209, 124, 0.4); }
.pill.L { color: var(--danger); border-color: rgba(255, 93, 93, 0.4); }
.pill.T { color: var(--warn); border-color: rgba(255, 204, 77, 0.4); }
.pill.fg { color: var(--accent-2); border-color: rgba(79, 156, 249, 0.4); }

/* win prob cell */
.wp-cell {
  border-radius: 6px;
  padding: 5px 4px;
  text-align: center;
  font-weight: 700;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,0.55);
  min-width: 52px;
}
.wp-cell .opp { display: block; font-weight: 500; font-size: 10.5px; opacity: 0.85; }

/* metric cards */
.metric-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin: 14px 0;
}
.metric {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 14px;
}
.metric .label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  font-weight: 700;
}
.metric .value {
  font-size: 24px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}
.metric .baseline {
  font-size: 11.5px;
  color: var(--text-dim);
  margin-top: 2px;
}

/* tabs */
.tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0; }
.tabs button {
  font-size: 12.5px;
  padding: 6px 12px;
  border-radius: 999px;
}
.tabs button.active {
  background: rgba(79, 156, 249, 0.16);
  border-color: var(--accent-2);
  color: var(--accent-2);
}

/* segmented chip groups (SP+ vs Model switchers, conference pickers) */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.chips .chip {
  font-size: 12.5px;
  padding: 6px 12px;
  border-radius: 999px;
  cursor: pointer;
  font-weight: 700;
}
.chips .chip.active {
  background: rgba(79, 156, 249, 0.16);
  border-color: var(--accent-2);
  color: var(--accent-2);
}
.controls .chips {
  padding-bottom: 1px;
}
/* conference picker: two fixed rows of chips on desktop, dropdown on phones */
.chips.conf-chips {
  flex-direction: column;
  gap: 6px;
}
.chips.conf-chips .chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
@media (max-width: 760px) {
  .chips.conf-chips { display: none; }
}
@media (min-width: 761px) {
  .controls .conf-select { display: none; }
}

/* status / errors */
.status { color: var(--text-dim); font-size: 13px; padding: 14px 0; }
.error-box {
  background: rgba(255, 93, 93, 0.08);
  border: 1px solid rgba(255, 93, 93, 0.4);
  color: var(--danger);
  border-radius: 8px;
  padding: 10px 14px;
  margin: 12px 0;
  font-size: 13.5px;
}

/* sp table specifics */
.sp-scroll { overflow-x: auto; }
.at-least-row td { border-top: 2px solid var(--accent-2); }
.sp-table td, .sp-table th { text-align: center; }
.sp-table th { padding: 4px 3px; font-size: 11px; }
.sp-table td { padding: 2px 2px; }
.sp-table { font-size: 12px; }
.sp-table td.tm-cell { text-align: left; min-width: 0; }
.sp-table .wp-cell { min-width: 34px; padding: 3px 4px; font-size: 10px; border-radius: 3px; }
.sp-table .wp-cell .opp { font-size: 9px; }
.sp-table td.tm-cell .team-rec {
  margin-left: 8px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-dim);
  white-space: nowrap;
}
.sp-table td.exp-wins { text-align: center; }
.sp-table td.exp-wins .exp-cell { display: inline-block; min-width: 34px; text-align: center; }
.sp-table .exp-cell { padding: 3px 6px; }
.sp-table .exp-cell small { font-size: 9px; }
.sp-table th:first-child, .sp-table td:first-child { padding-left: 6px; }
.exp-cell {
  font-weight: 800;
  border-radius: 6px;
  padding: 6px 10px;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,0.6);
  font-variant-numeric: tabular-nums;
}
.exp-cell small { display: block; font-weight: 600; font-size: 10.5px; opacity: 0.85; }

/* team page */
.team-hero {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  padding: 18px;
}
.team-hero img { width: 64px; height: 64px; object-fit: contain; }
.team-hero .rec { font-size: 20px; font-weight: 800; }
.team-hero .kpi-grid { margin-left: auto; }
.rating-chip {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
  text-align: center;
  min-width: 74px;
}
.rating-chip .label {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--text-dim); font-weight: 700;
}
.rating-chip .value { font-size: 17px; font-weight: 800; font-variant-numeric: tabular-nums; }
.legend { font-size: 12px; color: var(--text-dim); margin: 8px 0 16px; }

/* teams page */
.teams-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 10px;
}
.team-card {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 12px;
}
.team-card:hover { border-color: var(--accent-2); text-decoration: none; }
.team-card .main { min-width: 0; flex: 1; }
.team-card .name { font-weight: 700; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.team-card .sub { font-size: 11.5px; color: var(--text-dim); }
.team-card .rank-badge {
  flex: none; text-align: center; min-width: 34px;
  font-weight: 800; font-size: 15px; font-variant-numeric: tabular-nums;
}
.team-card .rank-badge .of { display: block; font-size: 9.5px; color: var(--text-dim); font-weight: 600; }

/* game recap page */
.matchup-header {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 14px;
  padding: 20px 18px;
}
.matchup-side { display: flex; align-items: center; gap: 12px; min-width: 0; }
.matchup-side.away { flex-direction: row-reverse; text-align: right; }
.matchup-side img { width: 56px; height: 56px; object-fit: contain; flex: none; }
.matchup-side .team-name { font-size: 17px; font-weight: 800; }
.matchup-side .team-sub { font-size: 12px; color: var(--text-dim); }
.matchup-score {
  text-align: center;
  font-size: 34px;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.matchup-score .meta { font-size: 11.5px; color: var(--text-dim); font-weight: 600; margin-top: 2px; }
.matchup-score .winner { color: var(--accent); }

.line-score { width: auto; margin: 0 auto; }
.line-score th, .line-score td { padding: 6px 12px; text-align: center; }
.line-score .tm-col { text-align: left; font-weight: 700; }

.drive-row { cursor: pointer; }
.drive-row .pos-cell { display: flex; align-items: center; gap: 8px; }
.drive-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.drive-dot.td { background: var(--accent); }
.drive-dot.fg { background: var(--accent-2); }
.drive-dot.turnover { background: var(--danger); }
.drive-dot.punt { background: #5a6478; }
tr.drive-plays > td { background: rgba(79, 156, 249, 0.04); }
.drive-plays .kp-meta { color: var(--text-dim); font-size: 11px; margin-right: 8px; }
.kp-text.scoring { color: var(--accent); }

svg.wp-chart { width: 100%; height: auto; }
svg.wp-chart text { fill: var(--text-dim); font-size: 9px; font-family: var(--mono); }
svg.wp-chart .grid { stroke: var(--border); stroke-width: 0.4; }
svg.wp-chart .line { fill: none; stroke: var(--accent-2); stroke-width: 1.8; }
svg.wp-chart .fifty { stroke: var(--text-dim); stroke-width: 0.6; stroke-dasharray: 4 4; opacity: 0.6; }

svg.chart { width: 100%; height: auto; }
svg.chart text { fill: var(--text-dim); font-size: 8.5px; font-family: var(--mono); }
svg.chart .grid { stroke: var(--border); stroke-width: 0.4; }
svg.chart .line { fill: none; stroke: var(--accent-2); stroke-width: 1.6; }
svg.chart .dot { fill: var(--accent-2); }

/* conference spread chart (index.html, Show: Conferences) */
svg.conf-chart { min-width: 620px; }
svg.conf-chart .range { stroke: var(--text-dim); stroke-width: 5; stroke-linecap: round; opacity: 0.4; }
svg.conf-chart .halo { fill: var(--bg-card); stroke: var(--border); stroke-width: 0.5; }
[data-theme="dark"] svg.conf-chart .halo { fill: #e8ecf4; stroke: #8f9bb0; }
svg.conf-chart .mean { stroke: var(--accent); stroke-width: 2; stroke-dasharray: 3 3; }
svg.conf-chart .axis-title { fill: var(--text); font-weight: 700; font-size: 10px; }
svg.conf-chart .xlab { fill: var(--text); font-weight: 700; font-size: 10.5px; }
.chart-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.chart-head h2 { font-size: 14px; margin: 0; }

.footer {
  margin-top: 40px;
  color: var(--text-dim);
  font-size: 12px;
  border-top: 1px solid var(--border);
  padding-top: 14px;
}

/* matchup + chart helpers (BYU-style tabs) */
.edge-win { color: var(--accent); font-weight: 700; }
.edge-loss { color: var(--text-dim); }
.bar-cell { position: relative; display: inline-flex; align-items: center; justify-content: flex-end; min-width: 70px; gap: 6px; }
.bar-cell .bar { position: absolute; left: 0; top: 50%; transform: translateY(-50%); height: 14px; border-radius: 2px; opacity: 0.35; }
.bar-cell .bar-label { position: relative; font-family: var(--mono); font-size: 11px; }
details summary::-webkit-details-marker { color: var(--text-dim); }

/* tabbed sections (team page) */
.tab-panel { display: none; }
.tab-panel.active { display: block; }

/* matchup quick links (team page) */
.mu-list { display: flex; flex-direction: column; gap: 6px; }
.mu-link {
  display: flex; align-items: center; gap: 14px;
  padding: 8px 12px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--panel, rgba(255,255,255,0.02));
  color: var(--text);
  text-decoration: none;
  transition: border-color .15s, background .15s;
}
.mu-link:hover { border-color: var(--accent-2); background: rgba(79,156,249,0.06); }
.mu-link .mu-week { min-width: 42px; }
.mu-link .mu-opp { flex: 1; }
.mu-link .mu-go { color: var(--accent-2); font-size: 12px; }
.mu-link .mu-result { min-width: 44px; text-align: right; }
.mu-mobile { display: none; }

/* matchup maker */
.matchup-header { align-items: center; }
.line-row {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px;
  font-size: 15px;
}
.line-fav { font-weight: 800; font-size: 20px; }
.line-probs { display: flex; align-items: center; gap: 6px; }
.line-probs .wp-cell { padding: 4px 10px; border-radius: 999px; font-size: 12.5px; }

@media (max-width: 640px) {
  .mu-list { display: none; }
  .mu-mobile { display: block; }
  .nav { padding: 8px 12px; gap: 2px; }
  .nav .brand { margin-right: 8px; font-size: 15px; }
  .nav a.item { padding: 5px 8px; font-size: 12.5px; }
  .wrap { padding: 18px 12px 48px; }
}

/* subsection heading inside a tab panel */
.sec-h {
  margin: 18px 0 8px;
  font-size: 14px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-dim);
}

/* KPI box grid — 3 across on desktop (6 short chips), and 3 across on a phone too. */
/* Uniform 3 across at every width, phones included: every .kpi-grid in the app is a row of
   six chips, and the ask was the same 3x2 on a phone that desktop gets. The rules that used
   to stack these (2 across below 980px, 1 below 400px) are gone on purpose — the hero is
   7 chips now, so it wraps 3+3+1 rather than 3x2. */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.kpi-grid .rating-chip { min-width: 0; width: 100%; }
/* The critical-stats chips carry the longest labels ("Points / opportunity") and at 3-across
   on a 390px phone the desktop letter-spacing pushes one 3px past its box. Drop the tracking
   on narrow screens, not the type size — the labels need the width more than the air. */
@media (max-width: 480px) {
  .kpi-grid .rating-chip .label { letter-spacing: 0.02em; }
}

/* The page's "What these numbers mean" notes: a native <details>, collapsed on a phone by the
   page's own init (same 640px rule as the glossary). The summary is the only visible part there,
   so it has to read as a control. */
.lede-notes > summary {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-dim);
  font-weight: 700; cursor: pointer; margin: 6px 0 2px;
}
.lede-notes[open] > summary { margin-bottom: 6px; }

/* matchup good/bad cells */
.mu-cell { font-variant-numeric: tabular-nums; font-weight: 600; }
.mu-cell.good { color: var(--accent); background: rgba(56, 209, 124, 0.12); }
.mu-cell.bad { color: #e5534b; background: rgba(229, 83, 75, 0.10); }
.mu-cell.even { color: var(--text-dim); font-weight: 400; }
.mu-arrow { font-size: 11px; }
.mu-arrow.good { color: var(--accent); }
.mu-arrow.bad { color: #e5534b; }
.mu-arrow.even { color: var(--text-dim); }
.mu-arrow-col { width: 24px; }

/* team-page "what explains this team" factor bars.
   Per factor: a header line (name · description … net) then one labelled line per
   side of the ball (OFF / DEF), each with its own number and a full-width lane
   measured from a visible zero line. Explicit labels beat a legend nobody reads. */
.factor-list { display: flex; flex-direction: column; gap: 0; }
.factor-list > .factor-row + .factor-row,
.factor-list > .factor-head + .factor-row { border-top: 1px solid var(--border); }
.factor-head {
  font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-dim); margin: 12px 0 0;
}
.factor-row {
  display: grid;
  grid-template-columns: 34px 62px minmax(120px, 1fr);
  grid-template-rows: auto minmax(20px, auto) minmax(20px, auto);
  grid-template-areas: "label label label" "sideOff numOff laneOff" "sideDef numDef laneDef";
  column-gap: 10px;
  row-gap: 2px;
  align-items: center;
  padding: 10px 0;
}
.factor-label { grid-area: label; min-width: 0; display: flex; align-items: baseline; gap: 8px; }
.factor-name { font-weight: 600; font-size: 13px; white-space: nowrap; }
.factor-label .small { font-size: 12px; }
.factor-side { font-size: 11px; letter-spacing: 0.06em; color: var(--text-dim); }
.factor-side.off { grid-area: sideOff; }
.factor-side.def { grid-area: sideDef; }
.factor-num { font-size: 12px; font-variant-numeric: tabular-nums; text-align: right; color: var(--text-dim); }
.factor-num.off { grid-area: numOff; }
.factor-num.def { grid-area: numDef; }
.factor-lane {
  position: relative; height: 10px; border-radius: 5px;
  background: var(--bg-raised, rgba(128,128,128,0.15));
}
.factor-lane.off { grid-area: laneOff; }
.factor-lane.def { grid-area: laneDef; }
.factor-fill { position: absolute; top: 0; bottom: 0; }
.factor-fill.good { background: #2ea06a; border-radius: 0 5px 5px 0; }
.factor-fill.bad { background: #e5534b; border-radius: 5px 0 0 5px; }
/* zero line: every lane extends right (a strength) or left (a drag) from here.
   Painted in --text-dim, not --border, so it is actually visible on the track. */
.factor-lane::after {
  content: ''; position: absolute; top: -1px; bottom: -1px; left: 50%; width: 2px;
  margin-left: -1px; background: var(--text-dim, #888);
}
.factor-val { margin-left: auto; font-variant-numeric: tabular-nums; text-align: right; }
.factor-val .net-tag { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-dim); margin-right: 5px; }
.factor-val .net-num { font-weight: 700; }
.factor-val.good { color: #2ea06a; }
.factor-val.bad { color: #e5534b; }

/* reserve the takeaway/status line so the fetch landing doesn't shift the table */
#lede:empty, #dyn:empty { min-height: 1.5em; }

/* narrow phone: same three-line shape, tighter gutters */
@media (max-width: 640px) {
  .factor-list { gap: 0; }
  .factor-row { grid-template-columns: 30px 56px minmax(60px, 1fr); column-gap: 6px; }
  .factor-label { flex-wrap: wrap; row-gap: 2px; }
  .factor-name { white-space: normal; }
}

/* Team cells carry an abbreviation and the full name; show one or the other.
   The flip is set by the WIDEST table on the site (the board, 14 columns): with full names its
   min-content width is ~950-1080px depending on the season's longest team name, so below 1100px
   it is still scrolling sideways and the long name just makes the scroll worse. 720px (where a
   phone ends) was the wrong idea -- it left a dead band from 720 to 1100 showing full names AND
   a scrolling table. */
.wide-only { display: none; }
.narrow-only { display: inline; }
@media (min-width: 1100px) {
  .wide-only { display: inline; }
  .narrow-only { display: none; }
}

/* The board is taller AND wider than a phone, so scroll it inside the card and keep the
   column headers frozen while reading down it. The card was already the horizontal
   scroller; making it the vertical one too is what lets thead stick (a sticky element
   sticks to its nearest scrollport, and an overflow-x-only ancestor computes to auto). */
.card.table-scroll {
  padding-top: 0;
  max-height: calc(100vh - 160px);
  max-height: calc(100dvh - 160px);
  overflow: auto;
}
.card.table-scroll table.data thead th {
  position: sticky;
  top: 0;
  z-index: 4;
  background: var(--bg-card);
}
.card.table-scroll table.data thead th.sticky-col { z-index: 5; }
/* Freeze the rank column alongside the team column. `width: 1%` is the shrink-to-fit trick:
   without it the auto layout hands this column a share of the table's slack, so the rank cell
   measures 43px on a phone and 49px on a desktop and no single `left` works for both. With it the
   column is its min-content width everywhere, so --rank-w is one number. */
.card.table-scroll table.data th:first-child,
.card.table-scroll table.data td:first-child {
  position: sticky;
  left: 0;
  z-index: 2;
  width: 1%;
  min-width: 43px;
  background: var(--bg-card);
}
.card.table-scroll table.data thead th:first-child { z-index: 5; }
/* 42px, not 43: two pinned columns must OVERLAP by a fraction, never meet exactly. At exactly
   the column width the rounding leaves a sub-pixel GAP between them, and the rows scrolling
   underneath show through it as a sliver of text behind the team/rank cells. Overlap is
   invisible because it only covers the rank cell's right padding (the number is right-aligned
   inside 10px of padding); a gap is not. min-width keeps the rank column from ever being
   narrower than the offset. */
.card.table-scroll table.data thead th.sticky-col,
.card.table-scroll table.data tbody td.sticky-col { left: 42px; }
