/* text-size-adjust: without the opt-out, iOS Safari "font boosting" inflates text
   block-by-block (leaving images and fixed boxes alone), which shredded the
   opportunity cards on a real phone — words wrapping one per line, the player name
   ellipsized to nothing. Every mainstream reset carries this line; ours didn't. */
html {
  color-scheme: dark; background: var(--bg);
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
}
body {
  margin: 0;
  min-height: 100vh;
  color: var(--text-1);
  background: radial-gradient(1100px 480px at 10% -10%, rgba(255,122,26,.10), transparent 55%), var(--bg);
  background-attachment: fixed;
  font-family: var(--font);
}
a { color: inherit; }
.site-header {
  max-width: 1160px;
  margin: 0 auto;
  padding: .85rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--hairline);
}
.site-brand { display: flex; flex-direction: column; gap: .15rem; text-decoration: none; }
.site-brand-name { color: var(--text-1); font-size: 1.2rem; font-weight: 850; letter-spacing: -.025em; }
.site-brand-name b { color: var(--brand); }
.site-date { color: var(--text-4); font-size: .62rem; font-weight: 750; letter-spacing: .07em; text-transform: uppercase; }
.site-header nav { display: flex; align-items: center; gap: 1rem; color: var(--text-3); font-size: .82rem; }
.site-header nav a { text-decoration: none; }
.site-header nav .active { color: var(--text-1); }
.nav-day-toggle { display: grid; grid-template-columns: 1fr 1fr; min-width: 13rem; padding: .2rem; border: 1px solid var(--divider); border-radius: var(--r-pill); background: var(--surface-2); }
.nav-day-toggle a { padding: .4rem .8rem; border-radius: var(--r-pill); text-align: center; font-weight: 750; }
.nav-day-toggle a.active { color: var(--on-brand); background: var(--brand-grad); }
.performance-link { font-weight: 700; }
.site-header nav .performance-link.active { color: var(--brand-2); }
.nav-future { opacity: .5; cursor: default; }
.site-shell { max-width: 1160px; margin: 0 auto; padding: 2rem 1.5rem 4rem; }
.hero-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 2rem; margin-bottom: 1rem; }
.eyebrow { color: var(--text-3); font-size: .78rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; margin-bottom: .45rem; }
.hero-copy { color: var(--text-3); margin: .2rem 0 0; }
.freshness-strip { display: flex; align-items: center; gap: .65rem; margin-bottom: 1.35rem; color: var(--text-3); font-size: .78rem; }
.freshness-below-games { margin-top: .85rem; }
.freshness-strip span:not(:last-child)::after { content: "·"; margin-left: .65rem; color: var(--text-4); }
.public-chip { margin-left: auto; padding: .25rem .55rem; border-radius: var(--r-pill); background: var(--brand-soft); color: var(--brand-2); font-weight: 700; }
.filter-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.filter-pills { display: flex; flex-wrap: wrap; gap: .45rem; }
.filter-pill, .thr-pill, .games-toggle {
  text-decoration: none; border: 1px solid var(--divider); border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--text-2); padding: .5rem .85rem;
  font-size: .85rem; font-weight: 650; transition: .16s ease;
}
.games-toggle { font-family: inherit; cursor: pointer; }
.schedule-actions { display: flex; align-items: center; justify-content: flex-end; gap: .45rem; }
.filter-pill:hover, .thr-pill:hover, .games-toggle:hover { transform: translateY(-1px); color: var(--text-1); }
.filter-pill:focus-visible, .thr-pill:focus-visible, .games-toggle:focus-visible,
.site-header a:focus-visible, .text-link:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.filter-pill.active, .thr-pill.active { color: var(--on-brand); border-color: transparent; background: var(--brand-grad); }

/* Game-state filter — one segmented control in place of two independent booleans on the
   same axis. Housed like the day toggle so the two read as the same kind of control. */
.state-filter {
  display: inline-flex; padding: .2rem; gap: .15rem;
  border: 1px solid var(--divider); border-radius: var(--r-pill); background: var(--surface-2);
}
.state-filter button {
  font-family: inherit; cursor: pointer; border: 0; background: none; color: var(--text-3);
  padding: .38rem .7rem; border-radius: var(--r-pill); font-size: .8rem; font-weight: 700;
  transition: .16s ease;
}
.state-filter button:hover { color: var(--text-1); }
.state-filter button.active { color: var(--on-brand); background: var(--brand-grad); }
.state-filter button:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.opportunity-section { margin-top: 2rem; }
.thresholds { display: flex; align-items: center; gap: .35rem; color: var(--text-3); font-size: .75rem; }
.thr-pill { padding: .32rem .58rem; }
.prop-pills { margin: .8rem 0; }
.focus-chip { display: flex; justify-content: space-between; padding: .7rem .9rem; border-radius: var(--r-sm); background: var(--brand-soft); margin-bottom: .8rem; }
.focus-chip a { color: var(--brand-2); text-decoration: none; }
.notice, .empty-card { padding: 1rem 1.1rem; border-radius: var(--r-md); background: var(--surface-1); color: var(--text-2); margin: 1rem 0; }
.notice p { margin: .25rem 0; }
.notice.warning { border-left: 3px solid var(--red); }
.empty-card h2 { margin-top: 0; }
.quiet-note { color: var(--text-3); font-size: .82rem; }
.site-footer { max-width: 1160px; margin: 0 auto; padding: 1.25rem 1.5rem 2rem; color: var(--text-4); border-top: 1px solid var(--hairline); font-size: .78rem; }
@media (max-width: 720px) {
  .site-header { align-items: center; padding-inline: .9rem; }
  .site-header nav { gap: .55rem; }
  .nav-day-toggle { min-width: 9.25rem; }
  .nav-day-toggle a { padding: .36rem .48rem; }
  .performance-link { font-size: .74rem; }
  .hero-row { align-items: flex-start; flex-direction: column; gap: 1rem; }
  .filter-row { align-items: flex-start; flex-direction: column; gap: .55rem; margin-bottom: .7rem; }
  /* Eight leagues are registered; in October MLB playoffs, NFL, NCAAF, NBA and NHL can
     all be live at once. Wrapping would push the first card off the screen, so the row
     scrolls sideways and stays one row deep however many leagues are playing. */
  .filter-row .filter-pills {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    align-self: stretch; padding-bottom: .1rem;
  }
  .filter-row .filter-pills::-webkit-scrollbar { display: none; }
  .filter-row .filter-pill { flex: 0 0 auto; }
  .schedule-actions { align-self: stretch; justify-content: space-between; flex-wrap: wrap; gap: .4rem; }
  /* Chrome occupied ~42% of the viewport before the first card. Tightening the pill
     rhythm buys that back — still above the 44px touch target. */
  .filter-pill, .thr-pill, .games-toggle { padding: .42rem .72rem; font-size: .8rem; }
  .state-filter button { padding: .34rem .55rem; font-size: .76rem; }
  .thresholds > span { display: none; }
  .site-shell { padding: 1.35rem .9rem 3rem; }
}

/* Django Results + Performance */
.analytics-hero { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; margin-bottom: 1.2rem; }
.text-link { color: var(--brand-2); text-decoration: none; font-weight: 700; font-size: .88rem; }
.date-nav { display: flex; align-items: center; gap: .75rem; margin: 0 0 1rem; }
.date-arrow { display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border-radius: var(--r-pill); background: var(--surface-2); text-decoration: none; font-size: 1.3rem; }
.date-arrow.disabled { opacity: .35; }
.date-form { display: flex; align-items: center; gap: .55rem; }
.date-form label { position: absolute; width: 1px; height: 1px; overflow: hidden; }
.date-form input, .search-sort-row input, .search-sort-row select {
  min-height: 2.35rem; border: 1px solid var(--divider); border-radius: var(--r-sm);
  background: var(--surface-1); color: var(--text-1); padding: 0 .75rem; font: inherit;
}
.date-form button, .search-sort-row button {
  min-height: 2.35rem; border: 0; border-radius: var(--r-pill); padding: 0 .9rem;
  background: var(--brand-grad); color: var(--on-brand); font-weight: 750; cursor: pointer;
}
.analytics-filters { display: grid; gap: .65rem; padding: .85rem; margin-bottom: 1rem; border-radius: var(--r-md); background: rgba(255,255,255,.025); }
.analytics-filter-group { display: flex; align-items: center; gap: .8rem; min-width: 0; }
.filter-label { flex: 0 0 6rem; color: var(--text-3); font-size: .72rem; font-weight: 750; text-transform: uppercase; letter-spacing: .04em; }
.analytics-filter-group .filter-pills { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.analytics-filter-group .filter-pills::-webkit-scrollbar { display: none; }
.analytics-filter-group .filter-pill, .compact-pills .filter-pill, .performance-controls .filter-pill { white-space: nowrap; padding: .36rem .68rem; font-size: .78rem; }
.analytics-section { margin-top: 2rem; }
.analytics-section > h2 { margin: 0 0 .7rem; font-size: 1.15rem; }
.section-read { color: var(--text-2); margin: -.2rem 0 .8rem; }
.web-market-table { overflow: hidden; border-radius: var(--r-md); background: var(--surface-1); }
.web-market-row { display: grid; grid-template-columns: 1.5fr repeat(4, .75fr); gap: .75rem; padding: .7rem .9rem; border-bottom: 1px solid var(--divider); color: var(--text-2); font-size: .84rem; }
.web-market-row:last-child { border-bottom: 0; }
.web-market-head { color: var(--text-4); font-size: .7rem; font-weight: 750; text-transform: uppercase; }
.web-market-row small { color: var(--text-4); }
.search-sort-row { display: grid; grid-template-columns: minmax(0, 1fr) 10rem auto; gap: .6rem; margin-bottom: .8rem; }
.performance-controls { display: flex; flex-wrap: wrap; gap: 1.2rem 2rem; margin-bottom: 1rem; }
.performance-controls > div { display: flex; align-items: center; gap: .65rem; }
.performance-controls .filter-label { flex-basis: auto; }
.compact-pills { margin-bottom: .8rem; }
.daily-summary, .perf-headline { margin-top: 1rem; }
.cohort-comparison { display: grid; grid-template-columns: repeat(3, 1fr); gap: .55rem; margin: .65rem 0 1rem; }
.cohort-cell { display: grid; grid-template-columns: 1fr auto auto auto; align-items: baseline; gap: .55rem; padding: .65rem .75rem; border-radius: var(--r-sm); background: var(--surface-1); color: var(--text-3); font-size: .72rem; }
.cohort-cell strong, .cohort-cell b { color: var(--text-1); }
.cohort-cell small { color: var(--text-4); }

/* The one-line synthesized read: "what are we good at right now" ahead of the tables
   that back it up. Left border in the brand color gives it a headline weight the plain
   surface cards below don't have. */
.perf-takeaway { background: var(--surface-1); border: 1px solid var(--divider);
  border-left: 3px solid var(--brand); border-radius: var(--r-md); padding: .85rem 1.05rem;
  margin: 0 0 1.2rem; font-size: 1rem; line-height: 1.55; color: var(--text-2); box-shadow: var(--edge-hi); }
.perf-takeaway strong { color: var(--text-1); }

.perf-lead > h2 { color: var(--text-1); }

/* Headline record, cohort split and trend read as one compact band instead of three
   stacked cards — the surrounding tables carry plenty of visual weight on their own. */
.perf-scoreboard { margin: 1.6rem 0 0; }
.perf-scoreboard .perf-headline { margin-bottom: .3rem; }
.perf-scoreboard .cohort-comparison { margin: 0 0 .3rem; }
.perf-scoreboard .perf-compare { margin: 0; }

.deep-dive-label { margin: 1.8rem 0 -.4rem; padding-top: 1.3rem; border-top: 1px solid var(--divider);
  color: var(--text-4); font-size: .7rem; font-weight: 750; text-transform: uppercase; letter-spacing: .08em; }

.market-pulse-section { margin-top: 1.35rem; }
.market-trend-scroll { overflow-x: auto; padding-bottom: .25rem; scrollbar-width: thin; }
.market-trend { min-width: calc(12rem + var(--trend-cols) * 4rem); border: 1px solid var(--divider); border-radius: var(--r-md); overflow: hidden; background: var(--surface-1); }
/* Market, then the period summary, then slates newest-first. The summary sits second
   so the number a reader wants is on screen before any scrolling. */
.mtp-row { display: grid; grid-template-columns: minmax(8.5rem, 1.35fr) minmax(5.4rem, .9fr) repeat(var(--trend-cols), minmax(3.35rem, .7fr)); align-items: stretch; border-bottom: 1px solid var(--divider); }
.mtp-row:last-child { border-bottom: 0; }
.mtp-row > span { min-height: 3.25rem; padding: .42rem .35rem; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .08rem; border-right: 1px solid var(--divider); text-align: center; }
.mtp-row > span:last-child { border-right: 0; }
.mtp-head > span { min-height: 2.2rem; color: var(--text-4); font-size: .62rem; font-weight: 750; letter-spacing: .04em; text-transform: uppercase; background: rgba(255,255,255,.018); }
.mtp-date b { color: var(--text-2); font-size: .72rem; }
.mtp-market { align-items: flex-start !important; flex-direction: row !important; justify-content: flex-start !important; gap: .4rem !important; padding-left: .7rem !important; color: var(--text-2); font-size: .76rem; font-weight: 750; text-align: left !important; }
.mtp-market i { font-style: normal; }
.mtp-cell b, .mtp-total b { color: var(--text-1); font-size: .82rem; }
.mtp-cell small, .mtp-total small { color: var(--text-4); font-size: .55rem; }
.mtp-cell.above { background: rgba(255,126,32,.16); }
.mtp-cell.near { background: rgba(255,255,255,.035); }
.mtp-cell.below { background: rgba(255,92,92,.10); }
.mtp-cell.empty { color: var(--text-4); background: rgba(255,255,255,.012); }
.mtp-cell.small { opacity: .55; }
.mtp-market { position: sticky; left: 0; z-index: 1; background: var(--surface-1); }
.mtp-head .mtp-market, .mtp-head > span:first-child { position: sticky; left: 0; z-index: 2; background: var(--surface-1); }
.mtp-total { background: rgba(255,255,255,.025); }
.mtp-total small.up { color: var(--brand-2); }
.mtp-total small.down { color: #ff8b82; }
.mtp-legend { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: .45rem; color: var(--text-4); font-size: .62rem; }
.mtp-legend span::before { content: ""; display: inline-block; width: .55rem; height: .55rem; margin-right: .28rem; border-radius: 2px; vertical-align: -.05rem; background: var(--surface-2); }
.mtp-legend .above::before { background: rgba(255,126,32,.6); }
.mtp-legend .near::before { background: rgba(255,255,255,.18); }
.mtp-legend .below::before { background: rgba(255,92,92,.42); }
.result-date-pill { display: inline-flex; flex-direction: column; align-items: center; gap: .08rem; }
.result-date-state { color: var(--text-4); font-size: .56rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; }
.result-date-pill.active .result-date-state { color: currentColor; opacity: .78; }
.result-date-pill.missing:not(.active) { border-style: dashed; }
.result-date-pill.none:not(.active) { opacity: .7; }
.result-date-pill.pending:not(.active) .result-date-state { color: var(--brand-2); }
.pagination { display: grid; grid-template-columns: 1fr auto 1fr; gap: 1rem; align-items: center; margin-top: 1rem; color: var(--text-3); font-size: .82rem; }
.pagination a { color: var(--brand-2); text-decoration: none; font-weight: 700; }
.pagination a:last-child { text-align: right; }
.matchup-toolbar { display: flex; justify-content: space-between; gap: 1rem; align-items: center; margin-bottom: 1rem; color: var(--text-4); font-size: .78rem; }
@media (max-width: 720px) { .matchup-toolbar { align-items: flex-start; flex-direction: column; } }
@media (max-width: 720px) {
  .analytics-hero { align-items: flex-start; flex-direction: column; }
  .analytics-filter-group { align-items: flex-start; flex-direction: column; gap: .35rem; }
  .filter-label { flex-basis: auto; }
  .web-market-row { grid-template-columns: 1.4fr 1fr .8fr; }
  .web-market-row span:nth-child(4), .web-market-row span:nth-child(5) { display: none; }
  .search-sort-row { grid-template-columns: 1fr; }
  .performance-controls > div { align-items: flex-start; flex-direction: column; gap: .35rem; }
  .cohort-comparison { grid-template-columns: 1fr; }
}
/* Phones: the nav stays one row — day toggle, then the menu button beside it.

   It used to stack, and that was right at the time: the second row held a text
   "Performance" link, which was too wide to sit next to the toggle. Performance now
   lives inside the menu, so row two is a 2.1rem circle — stacking it only pushed the
   control away from the pill it belongs with and made the header taller for nothing.

   The brand keeps `min-width: 0` so the date shortens rather than shoving the nav down;
   that is what replaced a `max-width: 7.5rem` ellipsis truncating it to
   "WEDNESDAY, AUG…". `flex-shrink: 0` on the nav is the load-bearing half: without it
   the toggle is the thing that gives way when the two compete. */
@media (max-width: 560px) {
  .site-header { align-items: center; }
  .site-header nav.compact-nav {
    flex-direction: row; align-items: center; gap: .4rem; flex: 0 0 auto;
  }
  .site-brand { min-width: 0; flex: 1 1 auto; }
  .site-date { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
@media (max-width: 430px) {
  .site-brand-name { font-size: 1rem; }
  .site-date { font-size: .58rem; letter-spacing: .05em; }
  .nav-day-toggle { min-width: 7.9rem; }
  .nav-day-toggle a { padding-inline: .34rem; font-size: .7rem; }
  .performance-link { font-size: .68rem; }
}

/* The `hidden` property is only as strong as the UA rule behind it, and an author
   `display` declaration beats the UA stylesheet at equal specificity. `.game-card` sets
   `display: flex` and `.schedule-grid` sets `display: grid`, so `element.hidden = true`
   set a property that never applied — the game-state filter (and the "Hide completed"
   toggle before it) changed its own label and hid nothing. `!important` is right here:
   `hidden` is a semantic state, not a style suggestion. */
/* Market coverage — measured edge against how much of it clears the floor. */
.mc-table { display: flex; flex-direction: column; gap: 2px; margin-top: .4rem; }
.mc-row { display: grid; grid-template-columns: minmax(7rem, 1.3fr) 1fr 1fr minmax(4rem, .55fr);
  gap: .6rem; align-items: center; padding: .5rem .7rem; border-radius: var(--r-sm);
  background: var(--surface-1); font-size: .82rem; }
.mc-head { background: transparent; color: var(--text-4); font-size: .68rem; font-weight: 750;
  text-transform: uppercase; letter-spacing: .04em; }
.mc-flag { margin-left: .4rem; padding: .05rem .35rem; border-radius: var(--r-pill);
  background: rgba(255,122,26,.16); color: var(--brand-2); font-size: .62rem;
  font-weight: 800; text-transform: uppercase; letter-spacing: .03em; }
@media (max-width: 560px) {
  .mc-row { grid-template-columns: minmax(6rem, 1.2fr) 1fr 1fr; }
  .mc-row > span:nth-child(4), .mc-head > span:nth-child(4) { display: none; }
  /* .et-seg's nowrap+ellipsis is tuned for a single text run; with the Starved badge
     as a second flex child it just clips the badge's label instead of eliding it. */
  .mc-row .et-seg { white-space: normal; overflow: visible; text-overflow: clip; flex-wrap: wrap; row-gap: .2rem; }
}

/* Simplified matchup page — leagues that arrive as a schedule and nothing else. */
.simple-hero { padding: 1.1rem 1.2rem; margin: 1rem 0; border-radius: var(--r-md);
  background: var(--surface-1); box-shadow: var(--edge-hi); }
.sh-league { color: var(--text-4); font-size: .72rem; font-weight: 750;
  text-transform: uppercase; letter-spacing: .05em; }
.sh-teams { display: flex; align-items: baseline; flex-wrap: wrap; gap: .5rem 1rem;
  margin-top: .55rem; }
.sh-side { display: flex; align-items: baseline; gap: .5rem; }
.sh-name { color: var(--text-1); font-size: 1.25rem; font-weight: 800; letter-spacing: -.02em; }
.sh-rec { color: var(--text-4); font-size: .82rem; font-weight: 700; }
.sh-at { color: var(--text-4); font-size: .9rem; }
.sh-time, .sh-score { color: var(--text-3); font-size: .86rem; font-weight: 650; margin-top: .5rem; }
.sh-score { color: var(--text-1); font-weight: 750; }
@media (max-width: 560px) { .sh-teams { flex-direction: column; gap: .35rem; } }

[hidden] { display: none !important; }

/* --- accessibility utilities ------------------------------------------------------ */

/* Content that belongs in the document outline but not on screen. Clip rather than
   `display:none` or `visibility:hidden`, both of which remove it from the accessibility
   tree — which would defeat the point. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The nav renders before the slate, so a keyboard or switch user otherwise tabs through
   every filter pill and league toggle before reaching the first game. Hidden until
   focused, then pinned to the top-left. */
.skip-link {
  position: absolute;
  left: .5rem;
  top: -3rem;
  z-index: 100;
  padding: .6rem .9rem;
  background: var(--surface-2);
  color: var(--text-1);
  border-radius: var(--r-sm, 6px);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  transition: top var(--dur, .18s) var(--ease, ease);
}
.skip-link:focus { top: .5rem; }

/* `tabindex="-1"` on <main> lets the skip link move focus there; the outline it would
   otherwise draw on click is noise, but focus-visible keeps it for keyboard users. */
.site-shell:focus { outline: none; }
.site-shell:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; }

/* Readers who ask for less motion get less motion. The stylesheet animates a live-game
   dot and transitions several controls; none of it carries meaning that is lost when
   stilled. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Slate roll-over: the out-of-date state -------------------------------------
   The site is static, so the browser rolls the slate forward through the three days
   each build publishes (base.html's head script). Past those, there is no honest slate
   left to show: a schedule for a finished day is wrong rather than merely stale, so the
   page says so and withholds the rest. Hidden unless the head script sets the flag, and
   because that runs inline before the body is parsed, the correct state is the first
   thing painted — the slate never flashes up and then disappears. */
.slate-stale { display: none; }
html[data-slate-stale] .slate-stale {
  display: block;
  padding: 1.25rem 1.35rem;
  margin: 1rem 0;
  border-radius: var(--r-md);
  background: var(--surface-1);
  border-left: 3px solid var(--brand);
  color: var(--text-2);
}
html[data-slate-stale] .slate-stale h2 { margin: 0 0 .4rem; font-size: 1.05rem; color: var(--text-1); }
html[data-slate-stale] .slate-stale p { margin: .35rem 0; }
html[data-slate-stale] .slate-stale-fix code {
  background: var(--surface-2); padding: .1rem .35rem; border-radius: var(--r-sm);
}
/* Everything the stale notice replaces. The heading and the notice itself survive. */
html[data-slate-stale] .filter-row,
html[data-slate-stale] #schedule-region,
html[data-slate-stale] .freshness-strip,
html[data-slate-stale] .opportunity-section { display: none; }

/* Record + division position under the team name in the MLB hero. The sliders below
   describe how a team plays; this is the only thing on the page denominated in wins,
   so it sits directly under the name where the eye lands first. */
.mlb-hero-standing {
  font-size: .82rem;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
  margin: .1rem 0 .15rem;
}

/* --- Standings ------------------------------------------------------------------
   The one surface that shows a league whole rather than a slate. Tabular numerals so
   the columns line up down the page, and the division leader carried by a left rule
   rather than a colour fill — orange is the accent and a table of six highlighted rows
   would spend it on nothing. */
.standings-group { margin: 1.5rem 0; }
.standings-group-name {
  font-size: .95rem; font-weight: 750; color: var(--text-2);
  margin: 0 0 .5rem; letter-spacing: .01em;
}
.standings-table { border-radius: var(--r-md); background: var(--surface-1); overflow: hidden; }
.standings-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 4.5rem 3.5rem 3.5rem 3.5rem 4rem;
  gap: .5rem; align-items: center;
  padding: .6rem .9rem;
  border-bottom: 1px solid var(--hairline);
}
.standings-row:last-child { border-bottom: 0; }
.standings-head {
  color: var(--text-4); font-size: .68rem; font-weight: 750;
  letter-spacing: .06em; text-transform: uppercase;
}
.standings-row.leader { box-shadow: inset 3px 0 0 var(--brand); }
.standings-team { color: var(--text-1); font-weight: 650; min-width: 0; }
.standings-team b { color: var(--text-4); font-weight: 700; margin-right: .4rem; }
.standings-row .num { color: var(--text-2); font-variant-numeric: tabular-nums; font-size: .88rem; }
@media (max-width: 720px) {
  /* Streak and last-ten are the first things to go on a phone: the record, percentage
     and games back are what the page is for. */
  .standings-row { grid-template-columns: minmax(0, 1fr) 4rem 3rem 3rem; }
  .standings-row > :nth-child(5), .standings-row > :nth-child(6) { display: none; }
}

/* --- Header menu ----------------------------------------------------------------
   Everything that is not "today" lives behind one control, so a new league page costs
   the header nothing. `details/summary` on purpose: it opens without JavaScript, closes
   on Escape, and is keyboard-reachable without us reimplementing any of that. */
.nav-menu { position: relative; }
.nav-menu > summary {
  list-style: none; cursor: pointer; display: grid; place-items: center;
  width: 2.1rem; height: 2.1rem; border-radius: var(--r-pill);
  border: 1px solid var(--divider); background: var(--surface-2);
}
.nav-menu > summary::-webkit-details-marker { display: none; }
.nav-menu > summary:hover { border-color: var(--brand); }
.nav-menu > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.nav-menu-bars { display: grid; gap: 3px; }
.nav-menu-bars i { display: block; width: 15px; height: 2px; border-radius: 1px; background: var(--text-2); }
.nav-menu[open] > summary .nav-menu-bars i { background: var(--brand); }
.nav-menu-panel {
  position: absolute; right: 0; top: calc(100% + .45rem); z-index: 40;
  min-width: 13rem; padding: .4rem;
  display: flex; flex-direction: column; gap: .1rem;
  border: 1px solid var(--divider); border-radius: var(--r-md);
  background: var(--surface-1); box-shadow: 0 18px 40px rgba(0,0,0,.45);
}
/* Quieter than the default link. The panel is a list of destinations, not a call to
   action, and at --text-2/650 the built entries shouted over the league headings that
   are supposed to organise them — the eye met a stack of white words and had to read
   all of them to find the grouping. Dropping to --text-3 and a lighter weight lets the
   uppercase league labels do the sorting. Hover and the active state carry the
   affordance instead of resting weight. */
.nav-menu-panel a {
  padding: .45rem .65rem; border-radius: var(--r-sm);
  color: var(--text-3); text-decoration: none; font-size: .82rem; font-weight: 600;
  transition: color .12s ease, background .12s ease;
}
.nav-menu-panel a:hover { background: var(--surface-2); color: var(--text-1); }
.nav-menu-panel a:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.nav-menu-panel a.active { color: var(--brand-2); font-weight: 700; }
/* The league headings have to out-rank the links under them. Quietening the links to
   --text-3 left these at --text-4 — dimmer than the items they organise — so the
   hierarchy read upside down and they stopped working as dividers. Brightest text in
   the panel now, and a hairline above each group so the separation is structural
   rather than only tonal. Small caps keep them from shouting at full brightness. */
.nav-menu-group {
  padding: .5rem .65rem .3rem; color: var(--text-1);
  font-size: .67rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
}
.nav-menu-group ~ .nav-menu-group {
  margin-top: .45rem; padding-top: .6rem; border-top: 1px solid var(--divider);
}

/* Team marks on the standings table. `alt=""` on purpose: the team name sits right
   beside it, so announcing the logo would read the name twice. Fixed box so a slow or
   missing logo cannot shift the column — several are SVGs served from a CDN. */
.standings-team { display: flex; align-items: center; gap: .5rem; }
.standings-logo { width: 20px; height: 20px; object-fit: contain; flex: 0 0 20px; }
.standings-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-menu-panel .nav-future {
  padding: .45rem .65rem; font-size: .82rem; font-weight: 600;
  color: var(--text-4);
}
.nav-menu-sep { height: 1px; margin: .4rem .3rem; background: var(--hairline); }

/* --- Trending players ---------------------------------------------------------- */
.page-read { max-width: 44rem; margin: .35rem 0 0; color: var(--text-2); line-height: 1.5; }
.data-through, .section-heading > span {
  color: var(--text-4); font-size: .72rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; white-space: nowrap;
}
.trend-jump { display: flex; gap: .45rem; overflow-x: auto; margin: 0 0 1.5rem; scrollbar-width: none; }
.trend-jump::-webkit-scrollbar { display: none; }
.trend-jump a { flex: 0 0 auto; padding: .42rem .72rem; border: 1px solid var(--divider);
  border-radius: var(--r-pill); background: var(--surface-2); color: var(--text-2);
  text-decoration: none; font-size: .78rem; font-weight: 700; }
.trend-section, .important-games { margin-top: 2.6rem; scroll-margin-top: 1rem; }
.section-heading { display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1rem; margin-bottom: .75rem; }
.section-heading h2 { margin: 0; color: var(--text-1); font-size: 1.12rem; }
.section-heading p { margin: .22rem 0 0; color: var(--text-3); font-size: .82rem; }
/* --- Player trends: three display types ------------------------------------------
   The section explains the metric; a row only shows the result. Each type is chosen to
   match what it communicates rather than for uniformity — an ongoing streak is an
   accomplishment and keeps its photograph, a change against a baseline is a comparison
   and belongs in a table, and a rate with one delta is a stat tile. Forcing all three
   through one card was what made the page long and repetitive. */
.trend-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; margin: 0 0 .75rem;
}
.trend-head h2 { margin: 0; font-size: 1.05rem; color: var(--text-1); }
.trend-head p { margin: .15rem 0 0; color: var(--text-3); font-size: .82rem; }
.trend-window {
  flex: 0 0 auto; color: var(--text-4); font-size: .66rem; font-weight: 750;
  letter-spacing: .06em; text-transform: uppercase; white-space: nowrap;
}

/* Streaks — the number is the point, so it outweighs the name. */
.streak-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .7rem; }
.streak-card {
  display: grid; grid-template-columns: 52px 1fr; gap: .7rem; align-items: center;
  padding: .75rem .85rem; border-radius: var(--r-md); background: var(--surface-1);
  border: 1px solid var(--divider);
}
.streak-face { width: 52px; height: 52px; border-radius: 50%; object-fit: cover; background: var(--surface-2); }
.streak-figure { display: flex; align-items: baseline; gap: .3rem; }
.streak-figure b { color: var(--brand-2); font-size: 1.65rem; font-weight: 850; line-height: 1; font-variant-numeric: tabular-nums; }
.streak-figure small { color: var(--text-4); font-size: .66rem; text-transform: uppercase; letter-spacing: .05em; }
.streak-who { grid-column: 2; min-width: 0; }
.streak-name { color: var(--text-1); font-weight: 700; font-size: .86rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.streak-team { color: var(--text-3); font-size: .74rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Comparisons — a table, because the eye is meant to run down the Change column. */
.trend-table {
  border: 1px solid var(--divider); border-radius: var(--r-md);
  background: var(--surface-1); overflow: hidden;
}
.trend-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 8rem 6rem 5rem;
  gap: .6rem; align-items: center; padding: .5rem .9rem;
  border-bottom: 1px solid var(--hairline);
}
.trend-row:last-child { border-bottom: 0; }
.trend-row-head {
  color: var(--text-4); font-size: .62rem; font-weight: 750;
  letter-spacing: .06em; text-transform: uppercase;
}
.trend-player { display: flex; align-items: center; gap: .55rem; min-width: 0; }
.trend-player img { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; flex: 0 0 26px; background: var(--surface-2); }
.trend-player > span { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.trend-player b { color: var(--text-1); font-size: .85rem; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trend-player small { color: var(--text-3); font-size: .72rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trend-row .num { font-variant-numeric: tabular-nums; font-size: .86rem; color: var(--text-1); }
.trend-before { color: var(--text-3) !important; font-size: .8rem !important; }
/* Direction is carried by the arrow and the sign as well as the colour, so it survives
   a colour-vision difference. Orange for improvement rather than a trading-desk green. */
.trend-change { font-weight: 750; white-space: nowrap; }
.trend-change.up { color: var(--brand-2); }
.trend-change.down { color: #ff8a80; }

/* Rates — a few numbers each, so tiles rather than rows. */
.tile-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: .6rem; }
.trend-tile {
  padding: .7rem; border-radius: var(--r-md); background: var(--surface-1);
  border: 1px solid var(--divider); min-width: 0;
}
.tile-face { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; background: var(--surface-2); }
.tile-figure { display: flex; align-items: baseline; gap: .25rem; margin-top: .4rem; }
.tile-figure b { color: var(--text-1); font-size: 1.35rem; font-weight: 850; line-height: 1; font-variant-numeric: tabular-nums; }
.tile-figure small { color: var(--text-4); font-size: .6rem; text-transform: uppercase; letter-spacing: .04em; }
.trend-tile .trend-change { display: block; margin: .2rem 0 .35rem; font-size: .78rem; }
.tile-name { color: var(--text-1); font-size: .8rem; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tile-team { color: var(--text-3); font-size: .72rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Methodology, not a content section. */
.trend-note {
  margin: 2rem 0 0; padding-top: .9rem; border-top: 1px solid var(--hairline);
  color: var(--text-4); font-size: .76rem; line-height: 1.5; max-width: 52rem;
}

/* --- MLB playoff race ---------------------------------------------------------- */
.playoff-leagues { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
.playoff-panel { min-width: 0; }
.race-table { overflow: hidden; border: 1px solid var(--divider); border-radius: var(--r-md);
  background: var(--surface-1); }
.race-row { display: grid; grid-template-columns: 2.4rem minmax(0, 1fr) 4.3rem 4.2rem 4.2rem;
  align-items: center; gap: .5rem; min-height: 2.8rem; padding: .35rem .7rem;
  border-bottom: 1px solid var(--hairline); color: var(--text-2); font-size: .8rem; }
.race-row:last-child { border-bottom: 0; }
.race-head { min-height: 2rem; color: var(--text-4); font-size: .62rem; font-weight: 750;
  letter-spacing: .05em; text-transform: uppercase; }
.race-seed { color: var(--brand-2); text-align: center; font-variant-numeric: tabular-nums; }
.race-team { display: flex; align-items: center; gap: .55rem; min-width: 0; }
.race-team img { width: 24px; height: 24px; flex: 0 0 24px; object-fit: contain; }
.race-team > span { display: flex; flex-direction: column; min-width: 0; }
.race-team strong { overflow: hidden; color: var(--text-1); text-overflow: ellipsis; white-space: nowrap; }
.race-team small { overflow: hidden; color: var(--text-4); font-size: .64rem; text-overflow: ellipsis; white-space: nowrap; }
.race-record { font-variant-numeric: tabular-nums; }
.race-divider { padding: .38rem .7rem; border-bottom: 1px solid var(--hairline);
  background: rgba(255,255,255,.018); color: var(--text-4); font-size: .62rem;
  font-weight: 750; letter-spacing: .05em; text-transform: uppercase; }
.race-row.bubble .race-seed { color: var(--text-4); }
.race-games { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .65rem; }
.race-game { display: grid; grid-template-columns: 5.2rem minmax(0, 1fr); gap: .3rem .75rem;
  padding: .8rem; border: 1px solid var(--divider); border-radius: var(--r-md);
  background: var(--surface-1); }
.race-game-date { grid-row: 1 / 3; align-self: center; color: var(--brand-2); font-size: .72rem;
  font-weight: 750; text-transform: uppercase; }
.race-matchup { display: flex; align-items: center; gap: .45rem; min-width: 0; font-weight: 750; }
.race-matchup span { display: flex; align-items: center; gap: .3rem; min-width: 0; }
.race-matchup img { width: 24px; height: 24px; object-fit: contain; }
.race-matchup i { color: var(--text-4); font-size: .68rem; font-style: normal; font-weight: 500; }
.race-game p { margin: 0; color: var(--text-3); font-size: .72rem; line-height: 1.35; }
/* Explicit column: the date spans the first two rows of column one, so an auto-placed
   fourth child lands underneath it instead of under the reason it belongs to. */
.race-game-link {
  grid-column: 2; justify-self: start; margin-top: .15rem;
  color: var(--brand-2); font-size: .72rem; font-weight: 750; text-decoration: none;
}
.race-game-link:hover { text-decoration: underline; }

@media (max-width: 820px) {
  .streak-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tile-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .playoff-leagues { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .race-games { grid-template-columns: 1fr; }
  .section-heading { align-items: flex-start; flex-direction: column; gap: .3rem; }
  /* Only the padding survives here. This block used to declare a four-column race row
     and relabel its last header to "Left"; adding the "vs. race" column made the row
     five wide, so the 720px rule below now sets the phone grid and hides both numeric
     columns together — which leaves `span:last-child` pointing at a hidden element and
     the four-column track overridden. Dead declarations that still read as intent are
     worse than none, so they are gone rather than left to mislead the next edit. */
  .race-row { padding-inline: .5rem; }
  .race-game { grid-template-columns: 4.4rem minmax(0, 1fr); }
}

/* --- NFL season schedule ---------------------------------------------------------
   Two axes over one table: browse a week, or follow a team. Tabular numerals and a
   fixed logo box so 16 rows line up as a column rather than 16 independent rows. */
.sched-weeks { flex-wrap: wrap; }
.sched-weeks .filter-pill { min-width: 2.4rem; text-align: center; padding: .38rem .5rem; }
.sched-team-row { display: flex; align-items: center; gap: .6rem; margin: .2rem 0 1.2rem; }
.sched-team-label { color: var(--text-3); font-size: .8rem; }
.sched-team-select {
  font-family: inherit; font-size: .85rem; color: var(--text-1);
  background: var(--surface-2); border: 1px solid var(--divider);
  border-radius: var(--r-pill); padding: .4rem .7rem; max-width: 16rem;
}
.sched-team-select:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.sched-group { margin: 1.4rem 0; }
.sched-day {
  font-size: .8rem; font-weight: 750; color: var(--text-3); margin: 0 0 .5rem;
  letter-spacing: .02em;
}
.sched-list { border-radius: var(--r-md); background: var(--surface-1); overflow: hidden; }
.sched-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr) 9.5rem minmax(0, 1.2fr);
  gap: .6rem; align-items: center; padding: .6rem .9rem;
  border-bottom: 1px solid var(--hairline);
}
.sched-row:last-child { border-bottom: 0; }
.sched-week { color: var(--text-4); font-size: .7rem; font-weight: 750; min-width: 2rem; }
.sched-side { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.sched-side img { width: 22px; height: 22px; object-fit: contain; flex: 0 0 22px; }
.sched-side b { color: var(--text-1); font-weight: 700; font-size: .85rem; }
.sched-side.home { justify-content: flex-start; }
.sched-score { color: var(--text-2); font-variant-numeric: tabular-nums; margin-left: .2rem; }
.sched-at { color: var(--text-4); font-size: .75rem; }
.sched-when { color: var(--text-2); font-size: .8rem; font-variant-numeric: tabular-nums; }
.sched-venue { color: var(--text-4); font-size: .78rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sched-row.final .sched-when { color: var(--text-4); }
@media (max-width: 720px) {
  /* The venue is the first thing to go: on a phone the matchup and the kickoff are
     what the page is for. */
  .sched-row { grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr); row-gap: .2rem; }
  .sched-when { grid-column: 2 / -1; font-size: .75rem; }
  .sched-venue { display: none; }
}

/* MLS counts points, not games behind, so its table takes its own column set. */
.standings-row.points { grid-template-columns: minmax(0, 1fr) 3.5rem 3rem 5rem 3.5rem; }
.standings-row .num.pts { color: var(--text-1); font-weight: 750; }
@media (max-width: 720px) {
  .standings-row.points { grid-template-columns: minmax(0, 1fr) 3rem 2.5rem 4.5rem; }
  .standings-row.points > :nth-child(5) { display: none; }
}

/* Remaining games against the rest of the race. Dimmer than the record because it is
   context for "games left", not a second headline number. */
.race-rivals { color: var(--text-3); font-variant-numeric: tabular-nums; }
@media (max-width: 720px) {
  /* On a phone the seed, team and record carry the page; "games left" and "vs. race"
     are the pair that goes, together — one without the other is the misleading half. */
  .race-row { grid-template-columns: 2.2rem minmax(0, 1fr) 4.1rem; }
  .race-row > :nth-child(4), .race-row > :nth-child(5) { display: none; }
}

/* "Nobody is chasing" and "everybody is eliminated" look identical as an empty list. */
.race-decided {
  padding: .7rem .9rem; color: var(--text-3); font-size: .82rem;
  border-top: 1px solid var(--hairline);
}

/* --- Division races --------------------------------------------------------------
   Three small tables side by side, above the Wild Card. Deliberately lighter than the
   Wild Card table: a division race is five clubs and one number, and giving it the same
   weight as the six-seed picture would say they are the same kind of thing. */
/* Two, not three. The league panels sit side by side, so a fixed three put six of these
   on one screen line at about 190px each — the name slid under the record and the GB
   column wrapped its own unit. Two per row inside a panel gives each card room.
   A third card would otherwise leave a hole beside it, so when there are exactly three
   the last one spans the row; `:last-child:nth-child(3)` matches only that case, which
   leaves a four-division league (an NFL conference) correctly alone. */
.division-races { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .8rem; margin-bottom: 1.6rem; }
.division-races > :last-child:nth-child(3) { grid-column: 1 / -1; }
.division-race { border-radius: var(--r-md); background: var(--surface-1); overflow: hidden; }
.division-name {
  padding: .5rem .7rem; color: var(--text-4); font-size: .64rem; font-weight: 800;
  letter-spacing: .07em; text-transform: uppercase; border-bottom: 1px solid var(--hairline);
}
.division-row {
  display: grid; grid-template-columns: 1.1rem minmax(0, 1fr) 3.2rem 2.2rem;
  gap: .4rem; align-items: center; padding: .4rem .7rem; font-size: .78rem;
  color: var(--text-2);
}
.division-row.leader { box-shadow: inset 3px 0 0 var(--brand); }
.division-head {
  padding-top: .3rem; padding-bottom: .3rem; color: var(--text-4); font-size: .58rem;
  font-weight: 750; letter-spacing: .05em; text-transform: uppercase;
  border-bottom: 1px solid var(--hairline);
}
.division-place { color: var(--text-4); font-weight: 700; }
.division-team { display: flex; align-items: center; gap: .35rem; min-width: 0; color: var(--text-1); font-weight: 650; }
.division-team img { width: 18px; height: 18px; object-fit: contain; flex: 0 0 18px; }
/* The name is the only thing here that can be too long for its column, and a name that
   overruns does not wrap politely — it slides under the record beside it. */
.division-team > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.division-row .num { font-variant-numeric: tabular-nums; text-align: right; }
.division-gap { color: var(--text-3); }
@media (max-width: 860px) {
  .division-races { grid-template-columns: 1fr; }
}

/* --- Market line (NCAAF only) -----------------------------------------------------
   Deliberately not styled like our own evidence: no orange, no accent rule, a plain
   surface and a stated source. It is quoted material, and it should read as quoted. */
.market-line {
  margin: 1rem 0; padding: .9rem 1rem; border-radius: var(--r-md);
  background: var(--surface-1); border: 1px dashed var(--divider);
}
.market-line-head {
  color: var(--text-4); font-size: .64rem; font-weight: 800;
  letter-spacing: .07em; text-transform: uppercase; margin-bottom: .5rem;
}
.market-line-numbers { display: flex; gap: 1.6rem; }
.market-figure { display: flex; flex-direction: column; gap: .1rem; }
.market-figure b { color: var(--text-1); font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.market-figure small { color: var(--text-4); font-size: .66rem; letter-spacing: .04em; text-transform: uppercase; }
.market-line-note { margin: .6rem 0 0; color: var(--text-3); font-size: .76rem; line-height: 1.45; }

/* Market line on a game card. Quoted, not asserted: no accent colour, a dashed
   underline to mark it as sourced elsewhere, and tabular numerals so a column of them
   lines up. Allowed to wrap — a nowrap run in a card once sized the whole phone column
   and pushed every card off the right edge. */
.market-chip {
  color: var(--text-3); font-size: .72rem; font-variant-numeric: tabular-nums;
  border-bottom: 1px dashed var(--divider); padding-bottom: .05rem;
}
@media (max-width: 720px) { .market-chip { font-size: .68rem; } }

/* Player trends as the window narrows. Two steps, because there are two different
   problems. Between roughly 560 and 720 the table still fits comfortably — it was only
   the fixed 8rem/6rem/5rem columns that did not — so it stays a table on tighter
   columns. Stacking it there left a column of empty space beside Change and read as a
   layout fault rather than a phone layout. */
@media (max-width: 820px) {
  .trend-row { grid-template-columns: minmax(0, 1fr) 6.5rem 5.2rem 4.2rem; }
}
@media (max-width: 720px) {
  .streak-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tile-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .trend-head { align-items: flex-start; flex-direction: column; gap: .3rem; }
  .trend-row { grid-template-columns: minmax(0, 1fr) 5.4rem 4.6rem 3.6rem;
    gap: .45rem; padding: .5rem .7rem; }
  .trend-row .num { font-size: .82rem; }
  .trend-player img { width: 24px; height: 24px; flex: 0 0 24px; }
}

/* Below this the four columns genuinely stop fitting: the player's name starts
   truncating to make room for numbers. The row restacks — the player above, the three
   numbers side by side beneath, each labelled from the column heading it lost. Keeping
   them on one line matters: "Before" on a full-width line of its own was the single
   emptiest row on the page. */
@media (max-width: 560px) {
  .trend-row-head { display: none; }
  .trend-row {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    row-gap: .4rem; column-gap: .5rem; padding: .7rem .8rem;
  }
  .trend-player { grid-column: 1 / -1; }
  /* The heading is gone, so each number states what it is. */
  .trend-row .num::before {
    content: attr(data-label);
    display: block;
    margin-bottom: .1rem;
    color: var(--text-4);
    font-size: .56rem;
    font-weight: 750;
    letter-spacing: .04em;
    line-height: 1.25;
    text-transform: uppercase;
  }
  .trend-change { white-space: normal; }
}
@media (max-width: 430px) {
  .streak-grid, .tile-grid { grid-template-columns: 1fr; }
}
