/* Today (studio-today.js): the date and week, the next game as a score bug, a lead block
   on the days with picks to settle, three mini-chart cards, the Your week tiles and the
   prices note. Charts, signals, verdicts and M/U chips
   are the shared kit's (arcade.css, Proposed site v3). */
.today { display:grid; gap:1.75rem; padding:0.5rem 0 2rem; }
/* Today's headline is its own heading. */
html body[data-layout][data-active-view=today] .page-heading { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }

.today .tone-good { color:var(--good); } .today .tone-bad { color:var(--bad); } .today .tone-thin { color:var(--thin); }
.today-mono { font-family:var(--font-mono); font-weight:700; }
/* A record ("2–2–1") never breaks at its dash (UI-623). */
.today-record { white-space:nowrap; }
.today-kicker { margin:0; color:var(--muted); font-size:0.8125rem; font-weight:700; }
.today-note { margin:0; color:var(--muted); font-size:0.8125rem; line-height:1.5; }
/* Why Play Scores are missing (UI-465): a partial week's note under the cards, a whole week's above them. */
.today-attention .today-unscored { margin-top:0.75rem; }
.today-attention .today-unscored.is-week { margin:0 0 0.875rem; }
.today .profile-name-button { color:inherit; font:inherit; text-align:left; }
/* Name buttons are text-sized; pad the hit area to 44px tall without moving the text. */
.today .today-name { display:inline-block; padding:0.75rem 0; margin:-0.75rem 0; text-transform:inherit; }
.today-nowrap { white-space:nowrap; }
/* Kickoff and lock times: body font with even digits (the mono face spaces "7 : 15"). */
.today-time { font-family:var(--font-body); font-variant-numeric:tabular-nums; white-space:nowrap; }

/* Headline: the date, and the week across from it. */
.today-headline { display:flex; flex-wrap:wrap; justify-content:space-between; align-items:baseline; gap:0.25rem 1rem; }
.today-date { margin:0; color:var(--muted); font-size:0.9375rem; }
.today-headline h2 { margin:0; font-size:clamp(1.5rem, 2.6vw, 2.25rem); line-height:1; }

/* The next game, as a score bug: the two team boxes, then the kickoff on an ink panel. */
/* Large text (UI-228): when the kickoff panel can't keep 8.5rem beside the teams, it wraps
   to a second row; the 1:999 grow split gives the teams all of their own row then and next
   to nothing while the two share one. */
/* The two boxes are equal halves of the teams' row (UI-602: flex-basis 0, so a 3-letter club
   never takes more than a 2-letter one), each at least the box's one width (--tb-w, arcade.css).
   On a 320px phone at 200% that minimum is wider than the bug, so it gives way to half the
   bug each (cqi: the bug is its own size container). */
.today-bug { display:flex; flex-wrap:wrap; align-items:stretch; max-width:32rem; min-height:3.5rem; border-radius:var(--r-data); overflow:hidden; container-type:inline-size; }
.today-bug .team-boxes { flex:1 0 auto; height:auto; border-radius:0; }
.today-bug .team-boxes .team-box { flex:1 1 0; min-width:min(var(--tb-w), 50cqi); min-height:1.5em; }
/* The boxes carry logos (UI-213); when two logo + code boxes no longer fit across the bug
   (a 320px phone at 200% text), the logos give way and their slot closes (UI-602); the codes stay. */
@container (max-width:11.5rem) { .today-bug .team-box { --tb-logo-w:0px; --tb-gap:0px; } .today-bug .team-box-logo { display:none; } }
.today-bug-time { flex:999 1 8.5rem; display:flex; flex-wrap:wrap; align-items:flex-end; align-content:center; gap:0.1875rem 0.5rem; min-width:0; padding:0.375rem 0.75rem; background:var(--ink); color:var(--bg); transition:background-color var(--dur-fast) ease; }
.today-bug-time strong { flex:1 0 100%; min-width:0; font:900 1.5rem/1 var(--font-display); overflow-wrap:break-word; }
/* UI-625: the time and zone ("7:15 PM CT") move to a line of their own as one piece (UI-298),
   and only when that line is still too narrow (a 320px phone at 200% text, or the fallback
   font) do they wrap inside it, never past the panel. An inline-block is at most its line's
   width, so it breaks between words then; the type stays its size. */
.today-bug-time .today-nowrap { display:inline-block; white-space:normal; }
.today-bug-time small { flex:1 1 auto; min-width:0; font-size:0.75rem; font-weight:600; }
/* UI-523: the bug opens that game on the Slate. UI-616: a small accent "Slate ›" pill
   says where it goes; on hover and focus it brightens and its chevron nudges right. It sits at
   the end of the countdown's line, so the kickoff time keeps the panel's full width (UI-228),
   and drops to a line of its own, still at the right, before it would wrap the countdown.
   UI-685: the Slate link is an empty layer over the whole bug, and the team boxes (links to
   their Teams pages) sit above it, so a tap on a box opens the team and a tap anywhere else
   opens the game. The bug takes the link's hover and focus (:has), not a box's. */
.today-bug { position:relative; }
.today-bug-link { position:absolute; inset:0; border-radius:inherit; color:inherit; text-decoration:none; }
.today-bug-link:focus-visible { outline:none; }
.today-bug a.team-box { position:relative; z-index:1; }
.today-bug-go { flex:none; margin-left:auto; display:inline-flex; align-items:center; gap:0.25rem; padding:0.1875rem 0.375rem 0.1875rem 0.5rem;
  border-radius:var(--r-control); background:var(--accent); color:var(--accent-ink); font:800 0.6875rem/1 var(--font-body); letter-spacing:0.04em; text-transform:uppercase; white-space:nowrap;
  transition:background-color var(--dur-fast) ease, box-shadow var(--dur-fast) ease; }
.today-bug-chev { font-size:0.875rem; line-height:0.75; transition:transform var(--dur-fast) ease; }
.today-bug:has(> .today-bug-link:hover) .today-bug-time, .today-bug:has(> .today-bug-link:focus-visible) .today-bug-time { background:color-mix(in srgb, var(--ink) 82%, var(--accent)); }
.today-bug:has(> .today-bug-link:hover) .today-bug-go, .today-bug:has(> .today-bug-link:focus-visible) .today-bug-go { background:color-mix(in srgb, var(--accent) 78%, #fff); box-shadow:0 0 0 1px var(--accent-ink); }
.today-bug:has(> .today-bug-link:hover) .today-bug-chev, .today-bug:has(> .today-bug-link:focus-visible) .today-bug-chev { transform:translateX(0.1875rem); }
.today-bug:has(> .today-bug-link:focus-visible) { outline:2px solid var(--accent); outline-offset:2px; }
@media (prefers-reduced-motion: reduce) { .today-bug-go, .today-bug-chev, .today-bug-time { transition:none; } .today-bug:has(> .today-bug-link:hover) .today-bug-chev, .today-bug:has(> .today-bug-link:focus-visible) .today-bug-chev { transform:none; } }
/* NBA's Next tip-off (UI-867): the next tip-off's games as score bugs, under a line that says how many
   of the day's games they are and a View all to the Slate. Bugs share a row while each keeps
   19rem (two across from a tablet), else stack, each the full width up to the bug's own 32rem. */
.today-upnext { display:grid; gap:0.4375rem; min-width:0; }
.today-upnext .today-window-head { gap:0 0.625rem; }
.today .today-upnext .today-upnext-all { margin-left:auto; display:inline-flex; align-items:center; min-height:2.75rem; margin-block:-0.75rem; padding:0 0.5rem; margin-right:-0.5rem; font-size:0.875rem; font-weight:700; white-space:nowrap; }
.today .today-upnext .today-upnext-all::after { content:none; }
.today-upnext-games { list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; gap:0.5rem; }
.today-upnext-games > li { flex:1 1 19rem; min-width:0; max-width:32rem; }
.today-upnext-games .today-bug { max-width:none; height:100%; }
/* A day-paged sport's window: per day a row of chips, each the score bug stacked (team boxes
   over the ink clock strip), wrapping; on a phone each day scrolls sideways, so a busy day
   takes one row. Finals recede to the surface colour. */
.today-window { display:grid; gap:0.875rem; min-width:0; }
.today-window-day { display:grid; gap:0.4375rem; min-width:0; }
.today-window-head { display:flex; flex-wrap:wrap; align-items:baseline; gap:0 0.625rem; }
.today-window-head h3 { margin:0; font:900 1.125rem/1 var(--font-display); text-transform:uppercase; }
.today-window-zone { margin-left:auto; color:var(--muted); font-size:0.75rem; font-weight:600; }
.today-window-games { list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(auto-fill, minmax(min(8.75rem, 100%), 1fr)); gap:0.5rem; }
.today-chip { display:grid; grid-template-rows:auto 1fr; height:100%; border-radius:var(--r-data); overflow:hidden; color:inherit; text-decoration:none; }
.today-chip .team-boxes { display:flex; height:1.75rem; border-radius:0; }
.today-chip .team-box { flex:1 1 0; font-size:0.9375rem; }
.today-chip-time { display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:0 0.5rem; padding:0.3125rem 0.5rem; background:var(--ink); color:var(--bg); transition:background-color var(--dur-fast) ease; }
.today-chip-time strong { font:900 0.9375rem/1.1 var(--font-display); white-space:nowrap; }
.today-chip-time small { font-size:0.6875rem; font-weight:700; line-height:1.3; white-space:nowrap; }
.today-chip.is-next small { padding:0 0.3125rem; border-radius:var(--r-control); background:var(--accent); color:var(--accent-ink); }
.today-chip.is-live small::before { content:""; display:inline-block; width:0.4375rem; height:0.4375rem; margin-right:0.25rem; border-radius:50%; background:var(--bad); }
.today-chip:is(.is-final, .is-over) .today-chip-time { background:var(--surface-raised); color:var(--ink); box-shadow:inset 0 0 0 1px var(--line); }
.today-chip:is(.is-final, .is-over) small { color:var(--muted); }
.today-chip:is(:hover, :focus-visible) .today-chip-time { background:color-mix(in srgb, var(--ink) 82%, var(--accent)); }
.today-chip:is(.is-final, .is-over):is(:hover, :focus-visible) .today-chip-time { background:color-mix(in srgb, var(--surface-raised) 82%, var(--accent)); }
.today-chip:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
@media (prefers-reduced-motion: reduce) { .today-chip-time { transition:none; } }
@media (max-width: 40em) {
  .today-window-games { display:flex; overflow-x:auto; overscroll-behavior-x:contain; scroll-snap-type:x proximity; scrollbar-width:thin; padding-bottom:0.25rem; }
  .today-window-games > li { flex:0 0 min(8.75rem, 85%); scroll-snap-align:start; }
}
/* The prices note closes the page. */
.today-prices { max-width:40rem; }

/* Lead block. */
.today-lead { display:grid; gap:1rem; padding:1.25rem 1.5rem; }
.today-lead-head { display:flex; align-items:flex-start; justify-content:space-between; gap:1rem; flex-wrap:wrap; }
.today-lead-head h3 { margin:0.25rem 0 0; font-size:clamp(1.25rem, 2vw, 1.625rem); font-weight:800; }
.today-lead-head h3 small { color:var(--muted); font-size:0.9375rem; font-weight:600; }
.today-lead-head .pd-button { min-height:2.5rem; padding:0 1rem; white-space:nowrap; }
html body[data-layout] .today-lead-head .today-primary { background:var(--accent); color:var(--accent-ink); }
.today-picks { list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); gap:0.75rem; }
.today-pick { display:grid; gap:0.3125rem; align-content:start; padding:0.75rem 0.875rem; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); }
.today-pick-top { display:flex; justify-content:space-between; gap:0.75rem; font-weight:700; }
.today-pick small { color:var(--muted); font-size:0.75rem; }
.today-star { color:var(--accent); }
.today-status { font-size:0.8125rem; font-weight:700; color:var(--muted); }
.today-status.tone-good { padding:0.125rem 0.375rem; border-radius:var(--r-control); background:var(--good-bg); }
.today-status.tone-bad { padding:0.125rem 0.375rem; border-radius:var(--r-control); background:var(--bad-bg); }
/* A carried status (UI-608, "Out W3"): an earlier week's, outlined like the Slate and Props tags. */
.today-status.tone-bad.is-carried { background:transparent; box-shadow:inset 0 0 0 1px currentColor; }
.today-pick .ar-progress { margin-top:0.25rem; }
.today-units { font-family:var(--font-mono); font-weight:700; white-space:nowrap; }
.today-teaser { display:grid; grid-template-columns:minmax(0, 1fr) auto; gap:0.125rem 1rem; align-items:center; padding:0.75rem 0.875rem; text-align:left; color:var(--ink);
  border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); cursor:pointer; }
.today-teaser small { grid-column:1; color:var(--muted); }
.today-teaser > span { grid-row:1 / span 2; grid-column:2; }

/* Line moved on a saved pick. */
.today-moved { padding:0.75rem 1rem; border-radius:var(--r-card); border:1px solid var(--line); background:var(--surface); }
.today-moved-title { margin:0 0 0.5rem; font-size:0.875rem; font-weight:800; }
.today-moved ul { list-style:none; margin:0; padding:0; display:grid; gap:0.375rem; }
.today-moved-row { display:flex; flex-wrap:wrap; justify-content:space-between; gap:0.25rem 1rem; font-size:0.875rem; font-weight:600; }

/* The cards: "N props scored 80+" and three mini-chart cards. */
.today-section-head { display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:1rem; margin-bottom:0.875rem; }
.today-section-head h3, .today-section-title { margin:0 0 0.875rem; font-size:1.75rem; font-weight:900; line-height:1; text-transform:uppercase; }
.today-section-head h3 { margin:0; }
/* "View all" and "Why": the legacy .text-button is 11px and 22px tall; make them 44px targets. */
.today .today-section-head .text-button, .today .today-why { display:inline-flex; align-items:center; min-height:2.75rem; padding:0 0.5rem; font-size:0.875rem; font-weight:700; text-decoration:none; }
.today .today-section-head .text-button { flex:none; margin-right:-0.5rem; white-space:nowrap; }
/* UI-610: no phone hit-area overlay (players.css) on "View all": it's 44px tall already, and the
   overlay's 0.25rem past the box plus the -0.5rem margin used up all of a phone's 0.75rem side
   padding, so under the Slate's 0.625rem (Back from the Slate shows Today a frame before the
   page's view changes) the page scrolled sideways by 2px. */
.today .today-section-head .text-button::after { content:none; }
.today-cards { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:1.25rem; align-items:stretch; }
/* UI-522: card-sized placeholders while this week's lines load (one on a phone). */
.today-cards-loading { display:grid; grid-template-columns:repeat(auto-fit, minmax(min(16rem, 100%), 1fr)); gap:1.25rem; }
.today-cards-loading > .ar-skeleton { min-height:18rem; align-content:start; gap:1rem; }
@media (max-width: 40em) { .today-cards-loading > .ar-skeleton { min-height:14rem; } .today-cards-loading > .ar-skeleton ~ .ar-skeleton { display:none; } }
/* A card has two faces stacked in one grid cell: the card (.today-front) and its Why side
   (.today-back). Why turns it on its vertical axis; the back keeps the front's size (its
   footer pinned where the front's is, so Back lands exactly on Why) and its body scrolls. */
.today-card { display:grid; perspective:1400px; }
.today-flip { display:grid; transform-style:preserve-3d; }
.today-face { grid-area:1 / 1; position:relative; display:grid; gap:0.75rem; padding:1.125rem 1.25rem 1.125rem 1.5rem; overflow:hidden;
  backface-visibility:hidden; -webkit-backface-visibility:hidden; }
.today-front { grid-template-rows:auto auto auto auto auto 1fr auto; }
/* One column the card's width: at a large text size (200%) a long stat line or the chart
   wraps or scrolls inside the card instead of widening the face past it (UI-261). */
.today-face { grid-template-columns:minmax(0, 1fr); }
/* contain:size: the back adds no height of its own, so it takes the front's. */
.today-back { grid-template-rows:auto minmax(0, 1fr) auto; contain:size; transform:rotateY(180deg); }
.today-flip.is-back:not(.to-back) { transform:rotateY(180deg); }
/* The turned-away face is hidden outright once a turn lands (and in a card drawn turned):
   backface-visibility isn't inherited, so the front's chart labels and bars, on their own
   layers, showed through the Why side mirrored. Both faces show while it turns; the
   chart's parts keep their own backs hidden for the turn itself. */
.today-flip:not(.is-back):not(.to-front) > .today-back, .today-flip.is-back:not(.to-back) > .today-front { visibility:hidden; }
.today-face .ar-chart * { backface-visibility:hidden; -webkit-backface-visibility:hidden; }
/* The turn: 504ms (the puzzle tiles' timing), lifting 4% at the edge-on midpoint. Played on
   the click only; a card drawn turned (a re-render) is just turned. */
.today-flip.to-back { animation:today-turn-back calc(var(--dur-slow) * 1.4) var(--ease-in-out) both; }
.today-flip.to-front { animation:today-turn-front calc(var(--dur-slow) * 1.4) var(--ease-in-out) both; }
@keyframes today-turn-back { 0% { transform:rotateY(0deg) scale(1); } 50% { transform:rotateY(90deg) scale(1.04); } 100% { transform:rotateY(180deg) scale(1); } }
@keyframes today-turn-front { 0% { transform:rotateY(180deg) scale(1); } 50% { transform:rotateY(90deg) scale(1.04); } 100% { transform:rotateY(0deg) scale(1); } }
/* "Why · player" and the Play Score share a row; when they can't (200% text on a tablet's
   two-up cards or a phone), the score wraps under the name, inside the card (UI-341). */
.today-card-head { display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:0.25rem 0.5rem; }
.today-card-who { display:flex; align-items:center; gap:0.75rem; min-width:0; }
/* A long surname at 200% text ("FLOURNOY" on a tablet card) breaks rather than runs past the card (UI-316). */
.today-card-title { margin:0; min-width:0; overflow-wrap:anywhere; font-size:1.75rem; font-weight:900; line-height:0.95; text-transform:uppercase; }
/* Headshot beside the name: initials until the photo loads (or when it fails). */
.today .today-avatar { flex:none; padding:0; border:0; background:none; cursor:pointer; }
.today-avatar .player-avatar { position:relative; display:grid; place-items:center; width:3rem; height:3rem; overflow:hidden; box-sizing:border-box;
  border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); color:var(--muted); font:800 0.875rem var(--font-body); }
.today-avatar .player-headshot { position:absolute; inset:0; width:100%; height:100%; object-fit:contain; object-position:center bottom; }
.today-avatar .player-avatar.has-photo .avatar-initials { visibility:hidden; }
.today-card-game { display:flex; flex-wrap:wrap; align-items:center; gap:0.625rem; margin:0; color:var(--muted); font-size:0.875rem; }
.today-card-game .team-badge { width:1.25rem; height:1.25rem; }
/* The matchup chip sits at the row's end; a tappable one (UI-244) is wrapped in its button. */
.today-card-game > .ar-mu, .today-card-game > .ar-mu-open { margin-left:auto; }
.today-card-game > .ar-mu-open { max-width:100%; }
/* "Role change" (UI-530): a large vacancy, in the Role change card's Large vacancy colour (no mark, UI-462). */
.today-role-tag { padding:0.0625rem 0.4375rem; border-radius:var(--r-data); background:var(--thin-bg); color:var(--thin); font:800 0.6875rem var(--font-body); white-space:nowrap; cursor:help; }
/* Logo + code boxes (UI-213) need about 8rem for the pair; on a narrower card (a 320px phone
   at 200% text) the logos give way and their slot closes, so the boxes narrow (UI-602); the codes stay. */
@container (max-width:13rem) { .today-card-game .team-box { --tb-logo-w:0px; --tb-gap:0px; } .today-card-game .team-box-logo { display:none; } }
.today-card-why { display:flex; align-items:flex-start; gap:0.625rem; margin:0; font-size:0.875rem; line-height:1.4; }
.today-card-why .ar-verdict { flex:none; }
/* The reason rises after the verdict stamps (arcade.css ar-reason, UI-169); once, like the
   stamp: a settled redraw keeps it still. */
@media (prefers-reduced-motion:no-preference) { .today-card-why > span:not(.ar-verdict) { animation:ar-reason var(--dur-base) var(--ease-out) both; animation-delay:calc(var(--dur-fast) + 60ms); } }
.ar-settled .today-card-why > span:not(.ar-verdict) { animation:none; }
.today-card-stats { display:grid; grid-template-columns:1fr 1fr; gap:0.625rem 1rem; margin:0; padding:0.75rem 0.875rem; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); }
.today-card-stats dt { color:var(--muted); font-size:0.75rem; overflow-wrap:break-word; }
.today-card-stats dd { margin:0.125rem 0 0; font:700 0.9375rem var(--font-mono); overflow-wrap:break-word; }
/* A card under 14em wide (200% text on a tablet's two-up cards, or a phone) stacks the
   numbers in one column, so "KC allows all WRs" wraps inside the card instead of running
   past its edge (UI-316). Every card is wider than that at 100% text. */
.today-front { container-type:inline-size; }
@container (max-width: 14em) {
  .today-card-stats { grid-template-columns:minmax(0, 1fr); }
}
/* Under 12em (200% text on a phone; every card is over 14em at 100% text) the headshot sat
   beside the name and the verdict chip beside the reason, leaving each a ~90px column that
   broke words mid-word ("rushi / ng"). The headshot goes above the name and the reason under
   the chip, each the card's full width (UI-440). The surname scales with the card (19cqi
   keeps an 11-letter name on one line), never above its usual 1.75rem; the matchup chip,
   signal chips and per-game unit wrap instead of running past the card's clipped edge. */
@container (max-width: 12em) {
  .today-card-who { flex-direction:column; align-items:flex-start; gap:0.5rem; }
  .today-card-title { font-size:min(1.75rem, 19cqi); }
  .today-card-why { flex-direction:column; gap:0.375rem; }
  .today-card-game .ar-mu-open { margin-block:0; padding-block:0; }
  .today-card-game .ar-mu { height:auto; min-height:1.375rem; max-width:100%; flex-wrap:wrap; white-space:normal; }
  .today-front .ar-sig { flex-wrap:wrap; }
  .today-front .today-card-stats dd small { white-space:normal; }
}
.today-card-stats dd small { margin-left:0.375rem; color:var(--muted); font:600 0.75rem var(--font-body); white-space:nowrap; }
.today-card-chart { display:grid; gap:0.375rem; align-content:start; }
.today-chart-head { display:flex; justify-content:space-between; align-items:baseline; font-size:0.75rem; font-weight:700; color:var(--muted); }
.today-card .ar-chart-card { max-width:none; }
.today-card-moved { margin:0; padding:0.5rem 0.75rem; border-radius:var(--r-control); font-size:0.8125rem; line-height:1.4; border:2px solid currentColor; }
.today-card-moved.tone-good { background:var(--good-bg); } .today-card-moved.tone-bad { background:var(--bad-bg); }
.today-card-moved b { margin-right:0.375rem; }
/* The price and Why share a row; when they can't (200% text), Why wraps under the price and
   stays at the right, inside the card (UI-316). */
.today-card-foot { display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:0.75rem; }
.today-card-foot > :last-child { margin-left:auto; }
.today-price { display:flex; min-width:0; max-width:100%; }
/* Pick button: the price pill, blue once picked (colour = action only). */
html body[data-layout] .today-price .bet-side { width:auto; min-height:2.75rem; display:inline-flex; flex-direction:row; align-items:center; gap:0.5rem; padding:0 1rem;
  border:2px solid var(--ink); border-radius:var(--r-control); box-shadow:none; background:var(--surface-raised); color:var(--ink); font:900 1.375rem/1 var(--font-display); cursor:pointer;
  /* A narrow card at 200% text: the line and price wrap inside the pill rather than run out. */
  max-width:100%; flex-wrap:wrap; padding-block:0.375rem; text-align:left; }
html body[data-layout] .today-price .bet-side strong { color:var(--muted); font:900 1.375rem/1 var(--font-display); }
html body[data-layout] .today-price .bet-side:has(> .bet-side-label) { display:inline-grid; grid-template-columns:auto auto; grid-template-rows:auto auto; align-content:center; column-gap:0.75rem; row-gap:0.125rem; padding-block:0.125rem; }
.today-price .bet-side > .bet-side-label { grid-area:1 / 1; font:600 0.6875rem/1 var(--font-body); letter-spacing:0.01em; opacity:0.78; }
.today-price .bet-side > .bet-side-label + span { grid-area:2 / 1; }
html body[data-layout] .today-price .bet-side:has(> .bet-side-label) > strong { grid-area:1 / 2 / 3 / 3; align-self:stretch; display:flex; align-items:center; padding-left:0.75rem; border-left:1px solid color-mix(in srgb, currentColor 30%, transparent); }
/* Too narrow for side, line and price in a row (200% text on a small phone): the price wraps under the line. */
.today-card-foot { container:today-foot / inline-size; }
@container today-foot (max-width: 7.75em) {
  html body[data-layout] .today-price .bet-side:has(> .bet-side-label) { display:inline-flex; flex-wrap:wrap; column-gap:0.5rem; padding-block:0.375rem; }
  .today-price .bet-side > .bet-side-label { flex-basis:100%; }
  html body[data-layout] .today-price .bet-side:has(> .bet-side-label) > strong { padding-left:0; border-left:0; }
}
html body[data-layout] .today-price .bet-side[aria-pressed=true] { background:var(--accent); color:var(--accent-ink); }
html body[data-layout] .today-price .bet-side[aria-pressed=true] strong { color:var(--accent-ink); }
.today .today-why { margin-right:-0.5rem; font-weight:800; }
.today-turn-mark { display:inline-block; margin-left:0.25rem; transition:rotate var(--dur-base) var(--ease-out); }
.today-why:hover .today-turn-mark { rotate:calc(-180deg * var(--move)); }
/* The Why side: "Why · player" and the Play Score, then the chart in words, the signals as
   sentences, more evidence, the case against and the Play Score (scrolling if they don't
   fit, UI-248), then his page and Back. */
.today-back-score { flex:none; padding:0.125rem 0.5rem; border-radius:var(--r-control); background:var(--surface-raised); color:var(--muted); font-size:0.75rem; font-weight:700; }
.today-back-score b { color:var(--ink); font-family:var(--font-mono); }
.today-back > .today-card-foot { padding-top:0.5rem; border-top:2px solid var(--line); }
.today-back-body { display:grid; gap:0.625rem; align-content:start; min-height:0; overflow-y:auto; overscroll-behavior:contain; font-size:0.875rem; line-height:1.4;
  /* Scroll shadows: a soft edge shows at the top or foot while there's more that way. The
     surface-coloured covers scroll with the content and hide each shadow at its end. */
  background:linear-gradient(var(--surface) 40%, transparent) center top / 100% 1.5rem no-repeat local,
    linear-gradient(transparent, var(--surface) 60%) center bottom / 100% 1.5rem no-repeat local,
    radial-gradient(farthest-side at 50% 0, color-mix(in srgb, var(--ink) 16%, transparent), transparent) center top / 100% 0.625rem no-repeat scroll,
    radial-gradient(farthest-side at 50% 100%, color-mix(in srgb, var(--ink) 16%, transparent), transparent) center bottom / 100% 0.625rem no-repeat scroll; }
.today-back-title { margin:0; font-size:1.125rem; font-weight:800; line-height:1.2; }
.today-back-title:focus { outline:none; }
.today-back-title:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.today-back-title > span:last-child { display:block; }
.today-back-title > span:last-child::first-letter { text-transform:uppercase; }
.today-more-part { display:grid; gap:0.375rem; align-content:start; min-width:0; }
.today-more-title { margin:0; font-size:0.875rem; font-weight:800; overflow-wrap:break-word; }
/* The back's rows rise in 40ms apart as the card lands (on the click only). The kit's
   signal rows keep still here, so showing Today again doesn't replay them. */
.today-flip.to-back .today-back-body > * { animation:today-rise var(--dur-base) var(--ease-out) both; animation-delay:calc(var(--dur-slow) * 0.7 + var(--i, 0) * 40ms); }
@keyframes today-rise { from { opacity:0; translate:0 calc(4px * var(--move)); } }
.today-back .ar-sig-row { animation:none; }
.today-more-games { list-style:none; margin:0; padding:0; display:grid; gap:0.1875rem; }
/* A row: the game, then his number and how far over or under it landed, on the right. When
   they don't fit on one line (200% text on a tablet card) the number and result wrap under
   the game, still right-aligned, instead of overlapping it or running past the card (UI-365). */
.today-more-games li { display:flex; flex-wrap:wrap; align-items:baseline; gap:0 0.5rem; padding:0.1875rem 0.5rem; border-radius:var(--r-control); background:var(--surface-raised); }
.today-more-game { flex:1 1 auto; min-width:0; overflow-wrap:break-word; }
.today-more-games li > .today-mono { margin-left:auto; white-space:nowrap; }
.today-more-games small { color:var(--muted); font:600 0.75rem var(--font-body); }
.today-more-result { font-weight:700; text-align:right; white-space:nowrap; }
/* Signal rows run in ("Form Stayed under 33.5 in 3 of 3 games") so each takes a line less, and
   the tone line ("Supports the Under") is for screen readers: the mark and colour carry it. */
.today-back .ar-signal-rows { gap:0.25rem; }
.today-back .ar-sig-row { position:relative; display:block; padding:0.25rem 0.5rem 0.25rem 1.625rem; line-height:1.4; }
.today-back .ar-sig-row .ar-sig-glyph { position:absolute; left:0.5rem; top:0.25rem; }
.today-back .ar-sig-row .ar-sig-title { display:inline; margin-right:0.375rem; }
.today-back .ar-sig-row .ar-sig-text { display:inline; }
.today-back .ar-sig-row .ar-sig-tone { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
.today-more-score p { margin:0; }
.today .today-more-page { display:inline-flex; align-items:center; gap:0.25rem; min-height:2.75rem; padding:0 0.5rem; margin-left:-0.5rem; font-size:0.875rem; font-weight:800; text-decoration:none; }

/* Live days (UI-370): Live now, This week so far and Next up, one main-column block. */
.today-slate { display:grid; gap:1.25rem; min-width:0; }
.today-slate > section { display:grid; gap:0.875rem; min-width:0; padding:1.25rem 1.5rem; }
.today-block-head { display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:0.25rem 1rem; }
.today-block-head h3 { margin:0; font-size:1.375rem; font-weight:900; line-height:1.1; text-transform:uppercase; }
.today-sub { margin:0 0 0.5rem; color:var(--muted); font-size:0.8125rem; font-weight:800; }
.today-slate ul { list-style:none; margin:0; padding:0; }
/* Live now: one scrolling row of games, as the Slate's rail; each head links to its game while the Slate lists it, your picks under it.
   An edge with games off it fades, and with a mouse shows an arrow that pages the row. */
.today-live-rail { position:relative; min-width:0; --fade:2rem; }
.today-slate .today-live-games { display:flex; align-items:stretch; gap:0.75rem; margin:-0.25rem; padding:0.25rem 0.25rem 0.5rem; overflow-x:auto; overscroll-behavior-x:contain;
  scroll-snap-type:x proximity; scroll-padding-inline:var(--fade); scrollbar-width:thin; scrollbar-color:#4c3d64 var(--surface-subtle); }
.today-live-rail.has-after .today-live-games { mask-image:linear-gradient(to right, #000 calc(100% - var(--fade)), transparent); }
.today-live-rail.has-before .today-live-games { mask-image:linear-gradient(to left, #000 calc(100% - var(--fade)), transparent); }
.today-live-rail.has-before.has-after .today-live-games { mask-image:linear-gradient(to right, transparent, #000 var(--fade), #000 calc(100% - var(--fade)), transparent); }
.today-live-game { flex:1 0 min(16.5rem, 85%); max-width:24rem; min-width:0; display:grid; grid-template-rows:auto 1fr; scroll-snap-align:start;
  border:2px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); transition:border-color var(--dur-fast) var(--ease-out), translate var(--dur-instant) var(--ease-press); }
.today-live-head { display:flex; flex-wrap:wrap; align-items:center; gap:0.375rem 0.75rem; padding:0.75rem 0.875rem; color:inherit; text-decoration:none; border-radius:calc(var(--r-control) - 2px); }
.today-live-game:has(> a.today-live-head:hover) { border-color:var(--muted); }
.today-live-game:has(> a.today-live-head:active) { translate:0 calc(1px * var(--move)); }
.today-live-head:focus-visible { outline:2px solid var(--accent); outline-offset:-1px; }
/* On a row too narrow for both boxes (200% text on a 320px phone) they take half each and drop their logos, as the score bug's do. */
.today-live-game { container-type:inline-size; }
.today-live-head .team-boxes { max-width:100%; }
.today-live-head .team-box { min-width:min(var(--tb-w), 50cqi); }
@container (max-width: 6.8rem) { .today-live-head .team-box { --tb-logo-w:0px; --tb-gap:0px; } .today-live-head .team-box-logo { display:none; } }
.today-live-score { margin-left:auto; font-size:1.375rem; line-height:1; }
.today-live-clock { flex-basis:100%; display:inline-flex; align-items:center; gap:0.375rem; color:var(--muted); font-size:0.875rem; font-weight:700; }
.today-live-dot { width:0.5rem; height:0.5rem; border-radius:50%; background:var(--bad); }
.today-slate .today-live-picks { display:grid; align-content:start; gap:0.875rem; padding:0.625rem 0.875rem 0.75rem; border-top:1px solid var(--line); }
.today-live-step { position:absolute; top:50%; z-index:1; display:none; place-items:center; width:2.25rem; height:2.25rem; margin:0; padding:0 0 0.125rem; translate:0 -50%;
  background:var(--surface); color:var(--ink); border:2px solid var(--line); border-radius:var(--r-control); box-shadow:0 0.125rem 0.5rem rgb(0 0 0 / 0.3);
  font:800 1.375rem/1 var(--font-body); cursor:pointer; transition:border-color var(--dur-fast) var(--ease-out); }
.today-live-step.is-prev { left:-0.625rem; }
.today-live-step.is-next { right:-0.625rem; }
.today-live-step:hover { border-color:var(--muted); }
@media (hover:hover) and (pointer:fine) {
  .today-live-rail.has-before > .today-live-step.is-prev, .today-live-rail.has-after > .today-live-step.is-next { display:grid; }
  .today-slate .today-live-games { user-select:none; -webkit-user-select:none; }
  .today-live-games.is-dragging, .today-live-games.is-dragging * { cursor:grabbing; }
}
@media (pointer:coarse) { .today-slate .today-live-games { scroll-snap-type:x mandatory; } }
.today-slate .today-live-games.is-dragging { scroll-snap-type:none; }
.today-live-games img { -webkit-user-drag:none; }
@media (prefers-reduced-motion: reduce) { .today-live-game, .today-live-step { transition:none; } .today-live-game:has(> a.today-live-head:active) { translate:none; } }
.today-live-pick { display:grid; gap:0.25rem; }
.today-live-pick .today-pick-top { align-items:baseline; flex-wrap:wrap; font-weight:700; }
.today-live-pick small { color:var(--muted); font-size:0.75rem; font-weight:600; }
.today-progress { font-size:0.8125rem; font-weight:700; }
.today-progress-name { color:var(--muted); }
/* This week so far: your picks and the tracked Unders, final scores, notable lines. */
.today-sofar-rows { display:grid; gap:0.375rem; }
.today-sofar-rows li { display:flex; flex-wrap:wrap; justify-content:space-between; gap:0.25rem 1rem; padding:0.5rem 0.75rem; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); font-size:0.875rem; font-weight:700; }
.today-sofar-rows small { color:var(--muted); font-size:0.8125rem; font-weight:600; }
/* The value column sits right in every row, wrapped under its label or not, so Your picks
   and Tracked Unders line up (UI-619). Tracked Unders: one rule a line, label small and muted. */
.today-sofar-rows li > span:last-child { margin-left:auto; text-align:right; }
.today-rules { display:grid; justify-items:end; gap:0.25rem; }
.today-rule { display:flex; flex-wrap:wrap; justify-content:flex-end; align-items:baseline; gap:0 0.375rem; }
.today-sofar-rows .today-rule-label { color:var(--muted); font-size:0.75rem; font-weight:700; }
/* UI-620: "All weeks →" under the Tracked Unders label, to Props' card with every week's Top 5. */
.today-tracked-label { display:flex; flex-direction:column; align-items:flex-start; }
.today-all-weeks { display:inline-block; padding:0.25rem 0 0.125rem; line-height:1.15; color:#ad8ee3; font-size:0.8125rem; font-weight:700; text-decoration:none; white-space:nowrap; }
.today-all-weeks:hover { text-decoration:underline; text-underline-offset:0.1875rem; }
.today-all-weeks:focus-visible { outline:2px solid var(--accent); outline-offset:2px; border-radius:var(--r-control); }
.today-finals { display:grid; grid-template-columns:repeat(auto-fill, minmax(min(11rem, 100%), 1fr)); gap:0.375rem 0.75rem; }
.today-final { display:flex; align-items:center; gap:0.5rem; min-width:0; font-size:0.875rem; }
.today-final small { color:var(--muted); font-size:0.75rem; font-weight:600; }
.today-final.is-unofficial small { color:var(--thin); }
/* A final with a saved box score opens it (UI-632): the whole row opens it, its edge only on
   hover and focus, an arrow at the end saying it opens something. UI-685: the button is an
   empty, transparent layer over the row (the row draws its edge and fill through :has), and the
   team boxes sit above it as links to their Teams pages, so a tap on a box opens the team and
   a tap anywhere else opens the box score. */
.today-final.has-box { position:relative; gap:0.375rem; width:calc(100% + 0.75rem); margin:-0.25rem -0.375rem; padding:0.25rem 0.375rem;
  border:1px solid transparent; border-radius:var(--r-control); box-sizing:border-box; }
.today-final-box { position:absolute; inset:-1px; width:auto; margin:0; padding:0; border:0; border-radius:inherit; background:none; color:inherit; font:inherit; cursor:pointer; }
.today-final-box:focus-visible { outline:none; }
.today-final.has-box a.team-box { position:relative; z-index:1; }
.today-final.has-box .today-mono { white-space:nowrap; }
.today-final.has-box::after { content:"↗"; margin-left:auto; color:var(--muted); font-size:0.75rem; font-weight:700; }
.today-final.has-box:has(> .today-final-box:hover) { border-color:var(--line); background:var(--surface-raised); }
.today-final.has-box:has(> .today-final-box:hover)::after, .today-final.has-box:has(> .today-final-box:focus-visible)::after { color:var(--accent); }
.today-final.has-box:has(> .today-final-box:focus-visible) { outline:2px solid var(--accent); outline-offset:1px; background:var(--surface-raised); }
@media (pointer: coarse) { .today-final.has-box { min-height:2.75rem; margin-block:0; } }
.today-notable { display:grid; gap:0.25rem; }
.today-notable li { display:flex; flex-wrap:wrap; align-items:baseline; gap:0 0.625rem; font-size:0.875rem; }
.today-notable li small { color:var(--muted); font-size:0.75rem; }
.today-notable .today-name { font-weight:700; }
/* The week's recap (UI-447): its parts in one column, two once the card is wide enough (a
   tablet), three in the wide band at 1089px+ (UI-578, below), all scores folded under them. */
.today-recap { container:recap / inline-size; }
.today-recap-grid { display:grid; grid-template-columns:minmax(0, 1fr); gap:1.25rem 2rem; align-items:start; }
@container recap (min-width: 38rem) { .today-recap-grid { grid-template-columns:repeat(2, minmax(0, 1fr)); } }
.today-recap-part { display:grid; align-content:start; gap:0.375rem; min-width:0; }
.today-recap-part .today-sub { margin:0; }
.today-recap-part .today-note { margin:0; font-size:0.75rem; }
.today-sub-minor { margin:0.375rem 0 0; color:var(--muted); font-size:0.75rem; font-weight:800; }
.today-upsets { display:grid; gap:0.5rem; }
.today-upset { display:grid; gap:0.125rem; }
.today-upset-teams { display:flex; flex-wrap:wrap; align-items:center; gap:0.375rem 0.5rem; font-size:0.875rem; font-weight:700; }
.today-upset small { display:flex; flex-wrap:wrap; gap:0 0.5rem; color:var(--muted); font-size:0.75rem; font-weight:600; }
.today-upset small .today-mono { color:var(--ink); font-weight:800; }
/* Top 5 Unders: the result's colour on the stat and its word (UI-462: no ✓/✕ marks). */
.today-board { display:grid; gap:0.25rem; }
.today-board-pick { display:flex; flex-wrap:wrap; align-items:baseline; gap:0 0.625rem; font-size:0.875rem; }
.today-board-pick .today-name { font-weight:700; }
.today-board-line { color:var(--muted); font-size:0.8125rem; white-space:nowrap; }
.today-board-result { margin-left:auto; font-weight:800; white-space:nowrap; }
.today-board-result:not([class*="tone-"]) { color:var(--muted); }
.today-board-result small { font-size:0.75rem; font-weight:700; }
/* UI-894: an early pick's mark is Props' .percentage-tracking-early (percentage-plays.css);
   a dropped one sits under the list, struck through, its result muted (counted nowhere). */
.today-board-pick .percentage-tracking-early { align-self:center; }
.today-board-droplist { margin-top:0.25rem; padding-top:0.25rem; border-top:1px dashed var(--line); }
.today-board-pick.is-dropped .today-name, .today-board-pick.is-dropped .today-board-name, .today-board-pick.is-dropped .today-board-line { color:var(--muted); text-decoration:line-through; text-decoration-thickness:1.5px; }
.today-board-pick.is-dropped .today-board-result { font-weight:600; }
.today-board-dropped { flex-basis:100%; color:var(--muted); font-size:0.75rem; font-weight:600; }
.today-early-note { margin-bottom:0.25rem; }
.today-scores { border-top:1px solid var(--line); padding-top:0.75rem; }
/* A flex summary drops the browser's marker: its own turning arrow instead. */
.today-scores > summary { display:flex; align-items:center; gap:0.5rem; min-height:2.75rem; cursor:pointer; list-style:none; }
.today-scores > summary::-webkit-details-marker { display:none; }
.today-scores > summary::before { content:"▸"; color:var(--muted); font-size:0.875rem; transition:rotate var(--dur-instant) var(--ease-out); }
.today-scores[open] > summary::before { rotate:90deg; }
.today-scores > summary .today-sub { margin:0; }
.today-scores > summary small { color:var(--muted); font-size:0.75rem; }
.today-scores[open] > summary { margin-bottom:0.5rem; }
/* Next up. */
.today-next-lines { margin:0; font-weight:600; }
.today-next .today-teaser { width:100%; font:inherit; }

/* Your week: Record, Fantasy. */
.today-tiles { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:1.25rem; }
.today-tile { position:relative; display:grid; gap:0.25rem; align-content:start; padding:1rem 3rem 1rem 1.25rem; color:var(--ink); text-align:left; text-decoration:none; font:inherit; cursor:pointer;
  transition:translate var(--dur-instant) var(--ease-press), box-shadow var(--dur-instant) var(--ease-press); }
.today-tile strong { font-size:1.0625rem; font-weight:800; }
.today-tile small { color:var(--muted); font-size:0.8125rem; }
.today-tile-arrow { position:absolute; right:1.25rem; top:50%; translate:0 -50%; color:var(--muted); font-size:1.25rem; }
.today-tile:hover { border-color:var(--muted); }
.today-tile:active { translate:0 calc(1px * var(--move)); filter:brightness(0.86); }

/* Entrance on first load only (renderToday sets .ar-enter once). */
.today.ar-enter > * { animation:ar-rise var(--dur-base) var(--ease-out) both; }
.today.ar-enter .today-card { animation:ar-rise var(--dur-base) var(--ease-out) both; animation-delay:calc(var(--i, 0) * 40ms * var(--move)); }
/* The lead block's reveal (its moved glows, and any bar or chip it draws) plays with Today's
   first draw only, as its pick tiles' .ar-moved does. .ar-settled is one class on all of
   Today, and the week's first draw with cards restarts its window (UI-339) so the cards'
   verdicts stamp; when the lines arrive late, that redraw would replay the lead (UI-353).
   Progress fills are transitions, carried across redraws by StudioMotion.replaceProgress. */
.today:not(.ar-enter) .today-lead :is(.ar-bar, .ar-verdict, .ar-sig-row, .ar-moved, .ar-dot) { animation:none; }

/* Wide screens (1089px+, UI-578, Danny's layout (c)): no long side column.
     strip   while games are live, Live now runs across the top as a scoreboard strip (game
             tiles side by side, your picks under each score)
     cards   the three prop cards, beside a slim rail: your picks (the lead block), a
             moved-line notice and Your week, stacked; with no lead block (no picks to
             show) no rail: the cards take the full width and Your week goes under them
     band    the week so far / Week N recap under them, full width, its parts side by side
   With no cards (Tuesday, between weeks) the recap band leads and the lead block, Next up and
   Your week share one row of three under it.
   Rows are placed by block, not by DOM order, and the page's row gap is margins instead: a
   block that isn't there leaves a zero-height row and no gap (UI-576's double gaps). DOM order
   (and so reading order) stays the phone's: lead, Live now, the week so far, the cards, Your week.
   Today must be at least 58rem wide for this (the site's 110% text: from 1089px); at a large
   text size it keeps one column, as on a tablet. So it does beside the docked My Picks panel
   (body.slip-cards-docked): the panel shows your picks, and the switch happens with the
   class, so the cards' glide covers it (UI-166) instead of a jump as the page narrows. */
@media (min-width: 68.0625em) {
  .today { grid-template-columns:minmax(0, 1fr) 20rem; grid-template-rows:repeat(8, auto) 1fr; row-gap:0; column-gap:1.75rem; align-items:start; }
  .today:not(:has(> .today-attention)) { grid-template-columns:repeat(3, minmax(0, 1fr)); }
  .today > * { grid-column:1 / -1; }
  .today > * + * { margin-top:1.75rem; }
  @container today (min-width: 58rem) {
    body:not(.slip-cards-docked) .today > .today-headline { grid-row:1; }
    body:not(.slip-cards-docked) .today > :is(.today-bug, .today-window, .today-upnext) { grid-row:2; }
    body:not(.slip-cards-docked) .today > .today-slate { display:contents; }
    body:not(.slip-cards-docked) .today > .today-slate > * { grid-column:1 / -1; margin-top:1.75rem; }
    body:not(.slip-cards-docked) .today > .today-slate > .today-live { grid-row:3; }
    /* The rail's top lines up with the cards' top, not their heading's (UI-159; lost in UI-578,
       back in UI-743). The props block is a row subgrid over rows 4 to 10: its heading takes
       row 4, a whole-week note row 5, the cards rows 6 to 9 and a part-week note row 10. The
       rail starts in row 6, so its first block and the cards share a top edge. The cards span
       the rail's rows and a last 1fr row (9), which takes whatever height the cards have beyond
       the rail's, so the rail's blocks keep their own heights. */
    body:not(.slip-cards-docked) .today > .today-attention { grid-column:1; grid-row:4 / 11; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) > .today-attention { display:grid; grid-template-columns:minmax(0, 1fr); grid-template-rows:subgrid; align-items:start; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) > .today-attention > * { grid-column:1; grid-row:3 / 7; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) > .today-attention > .today-section-head { grid-row:1; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) > .today-attention > .today-unscored.is-week { grid-row:2; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) > .today-attention > .today-unscored:not(.is-week) { grid-row:7; }
    body:not(.slip-cards-docked) .today > .today-lead { grid-column:2; grid-row:6; }
    body:not(.slip-cards-docked) .today:has(> .today-attention) > .today-lead { margin-top:0; }
    body:not(.slip-cards-docked) .today > .today-moved { grid-column:2; grid-row:7; }
    body:not(.slip-cards-docked) .today > .today-week { grid-column:2; grid-row:8; }
    body:not(.slip-cards-docked) .today > .today-lead + .today-moved, body:not(.slip-cards-docked) .today > :is(.today-lead, .today-moved) ~ .today-week { margin-top:1.25rem; }
    body:not(.slip-cards-docked) .today > .today-slate > :is(.today-sofar, .today-recap) { grid-row:11; }
    body:not(.slip-cards-docked) .today > .today-slate > .today-next { grid-row:12; }
    body:not(.slip-cards-docked) .today > .today-prices { grid-row:13; }
    /* The rail and the row of three: picks and tiles stack. */
    body:not(.slip-cards-docked) .today > .today-lead .today-picks, body:not(.slip-cards-docked) .today > .today-week .today-tiles { grid-template-columns:minmax(0, 1fr); gap:0.75rem; }
    body:not(.slip-cards-docked) .today > .today-week .today-section-title { margin-top:0; }
    body:not(.slip-cards-docked) .today > .today-lead { gap:0.875rem; padding:1.125rem 1.25rem; }
    body:not(.slip-cards-docked) .today:has(> .today-attention):has(> .today-lead) > .today-week .today-tile { padding-block:0.875rem; }
    /* Cards but no lead block (no picks to show, Wednesday to Saturday): no rail. The cards take
       the full width, a moved-line notice goes above them and Your week under them (its tiles
       side by side), then the band. */
    body:not(.slip-cards-docked) .today:has(> .today-attention):not(:has(> .today-lead)) > .today-moved { grid-column:1 / -1; grid-row:4; }
    body:not(.slip-cards-docked) .today:has(> .today-attention):not(:has(> .today-lead)) > .today-attention { grid-column:1 / -1; grid-row:5; }
    body:not(.slip-cards-docked) .today:has(> .today-attention):not(:has(> .today-lead)) > .today-week { grid-column:1 / -1; grid-row:6; margin-top:1.75rem; }
    body:not(.slip-cards-docked) .today:has(> .today-attention):not(:has(> .today-lead)) > .today-week .today-tiles { grid-template-columns:repeat(2, minmax(0, 1fr)); gap:1.25rem; }
    /* No cards: Live now, a moved-line notice, the recap band, then lead | Next up | Your week. */
    body:not(.slip-cards-docked) .today:not(:has(> .today-attention)) > .today-moved { grid-column:1 / -1; grid-row:4; margin-top:1.75rem; }
    body:not(.slip-cards-docked) .today:not(:has(> .today-attention)) > .today-slate > .today-sofar { grid-row:5; }
    body:not(.slip-cards-docked) .today:not(:has(> .today-attention)) > :is(.today-lead, .today-week), body:not(.slip-cards-docked) .today:not(:has(> .today-attention)) > .today-slate > .today-next { grid-row:6; margin-top:1.75rem; }
    body:not(.slip-cards-docked) .today:not(:has(> .today-attention)) > .today-lead { grid-column:1; }
    body:not(.slip-cards-docked) .today:not(:has(> .today-attention)) > .today-slate > .today-next { grid-column:2; }
    body:not(.slip-cards-docked) .today:not(:has(> .today-attention)):not(:has(> .today-lead)) > .today-slate > .today-next { grid-column:1 / 3; }
    body:not(.slip-cards-docked) .today:not(:has(> .today-attention)) > .today-week { grid-column:3; }
    /* The scoreboard strip: game tiles side by side (four across at 1440px), each with your
       picks in that game under its score. */
    body:not(.slip-cards-docked) .today-live .today-live-score { font-size:1.25rem; }
  }
}
/* The recap's parts side by side in the wide band (Upsets | How the board did | Over/under,
   the two performer lists stacked as one part); 1089px+ only, so tablets keep two columns. */
.today-recap-perf { display:contents; }
@media (min-width: 68.0625em) {
  @container recap (min-width: 50rem) {
    .today-recap-grid { grid-template-columns:repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); }
    .today-recap-perf { display:grid; gap:1.25rem; align-content:start; min-width:0; }
  }
}
/* Two columns (tablets, and beside the docked My Picks panel): the third card spans both,
   laid out as two inner columns (verdict, signals and numbers | chart) so its chart keeps
   the card size instead of stretching a 178px chart across the page. */
@media (max-width: 68em) {
  .today-cards { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); }
  .today-cards .today-card:nth-child(3) { grid-column:1 / -1; }
}
/* Its Why side keeps two columns too (the chart in words, the case against and the score |
   the signals and more evidence), and a
   deeper perspective so the wide card turns without swinging over the cards above. */
@media (min-width: 40.0625em) and (max-width: 68em) {
  @container today (min-width: 33.0625rem) {
    .today-cards .today-card:nth-child(3) { perspective:3200px; }
    .today-cards .today-card:nth-child(3) .today-front { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); grid-template-rows:none; column-gap:1.5rem; }
    .today-cards .today-card:nth-child(3) .today-front > * { grid-column:1; }
    .today-cards .today-card:nth-child(3) .today-front > .today-card-chart { grid-column:2; grid-row:1 / span 5; align-self:end; }
    .today-cards .today-card:nth-child(3) .today-front > :is(.today-card-moved, .today-card-foot) { grid-column:1 / -1; }
    .today-cards .today-card:nth-child(3) .today-back-body { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); grid-template-rows:auto auto auto 1fr; column-gap:1.5rem; }
    .today-cards .today-card:nth-child(3) .today-back-body > .today-more-signals { grid-column:2; grid-row:2; }
    .today-cards .today-card:nth-child(3) .today-back-body > .today-more-extra { grid-column:2; grid-row:3 / span 2; }
    .today-cards .today-card:nth-child(3) .today-back-body > .today-back-title { grid-column:1 / -1; }
    .today-cards .today-card:nth-child(3) .today-back-body > .today-more-chart { grid-column:1; grid-row:2; }
    .today-cards .today-card:nth-child(3) .today-back-body > .today-more-against { grid-column:1; grid-row:3; }
    .today-cards .today-card:nth-child(3) .today-back-body > .today-more-score { grid-column:1; grid-row:4; }
    /* Its numbers have half the card: under 32em (200% text) they stack, clear of the chart (UI-316). */
    @container (max-width: 32em) { .today-cards .today-card:nth-child(3) .today-card-stats { grid-template-columns:minmax(0, 1fr); } }
  }
}
/* body.slip-cards-docked follows the dock (studio-betslip.js): it comes on as the panel starts
   to dock and goes only once the page has widened back, and the cards glide between the two
   grids (UI-166). */
@media (min-width: 68.0625em) {
  body.slip-cards-docked .today-cards { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); }
  @container today (min-width: 33.0625rem) {
    body.slip-cards-docked .today-cards .today-card:nth-child(3) { grid-column:1 / -1; perspective:3200px; }
    body.slip-cards-docked .today-cards .today-card:nth-child(3) .today-front { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); grid-template-rows:none; column-gap:1.5rem; }
    body.slip-cards-docked .today-cards .today-card:nth-child(3) .today-front > * { grid-column:1; }
    body.slip-cards-docked .today-cards .today-card:nth-child(3) .today-front > .today-card-chart { grid-column:2; grid-row:1 / span 5; align-self:end; }
    body.slip-cards-docked .today-cards .today-card:nth-child(3) .today-front > :is(.today-card-moved, .today-card-foot) { grid-column:1 / -1; }
    body.slip-cards-docked .today-cards .today-card:nth-child(3) .today-back-body { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); grid-template-rows:auto auto auto 1fr; column-gap:1.5rem; }
    body.slip-cards-docked .today-cards .today-card:nth-child(3) .today-back-body > .today-more-signals { grid-column:2; grid-row:2; }
    body.slip-cards-docked .today-cards .today-card:nth-child(3) .today-back-body > .today-more-extra { grid-column:2; grid-row:3 / span 2; }
    body.slip-cards-docked .today-cards .today-card:nth-child(3) .today-back-body > .today-back-title { grid-column:1 / -1; }
    body.slip-cards-docked .today-cards .today-card:nth-child(3) .today-back-body > .today-more-chart { grid-column:1; grid-row:2; }
    body.slip-cards-docked .today-cards .today-card:nth-child(3) .today-back-body > .today-more-against { grid-column:1; grid-row:3; }
    body.slip-cards-docked .today-cards .today-card:nth-child(3) .today-back-body > .today-more-score { grid-column:1; grid-row:4; }
    @container (max-width: 32em) { body.slip-cards-docked .today-cards .today-card:nth-child(3) .today-card-stats { grid-template-columns:minmax(0, 1fr); } }
  }
}
/* Large text (UI-327): Today is a size container measured in rem (the page's text size: a
   container query's rem follows <html>, unlike a media query's), so the cards' columns follow
   the text size as well as the width. Two-up cards in under 33rem (200% text on a tablet, or
   beside the docked panel) and three-up cards in under 48rem (200% text up to about 1650px)
   would each be under ~16rem wide and over 1,800px tall with a narrow chart: they go one per
   row instead, and the third card drops its two inner columns like the others. At 100% text
   the two-up cards' area is never under 34.9rem (a 641px window) and the three-up cards'
   never under 64rem, so their layout doesn't change. (At 1089px+ under 58rem Today keeps one
   column, so the cards have its full width.) */
.today { container:today / inline-size; }
@container today (max-width: 33rem) {
  .today .today-attention > .today-cards { grid-template-columns:minmax(0, 1fr); }
}
@media (min-width: 68.0625em) {
  @container today (max-width: 48rem) {
    body:not(.slip-cards-docked) .today .today-attention > .today-cards { grid-template-columns:minmax(0, 1fr); }
  }
  /* Beside the 20rem rail (UI-578), the cards have Today less 21.75rem: three across would be
     under ~16.5rem each until Today is 73.75rem wide (about a 1350px window), so from 1089px to there
     they go two up, the third spanning both with its two inner columns, as on a tablet. With
     no lead block there is no rail, and the cards keep three across. */
  @container today (min-width: 58rem) and (max-width: 73.75rem) {
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); }
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards .today-card:nth-child(3) { grid-column:1 / -1; perspective:3200px; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards .today-card:nth-child(3) .today-front { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); grid-template-rows:none; column-gap:1.5rem; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards .today-card:nth-child(3) .today-front > * { grid-column:1; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards .today-card:nth-child(3) .today-front > .today-card-chart { grid-column:2; grid-row:1 / span 5; align-self:end; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards .today-card:nth-child(3) .today-front > :is(.today-card-moved, .today-card-foot) { grid-column:1 / -1; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards .today-card:nth-child(3) .today-back-body { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); grid-template-rows:auto auto auto 1fr; column-gap:1.5rem; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards .today-card:nth-child(3) .today-back-body > .today-more-signals { grid-column:2; grid-row:2; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards .today-card:nth-child(3) .today-back-body > .today-more-extra { grid-column:2; grid-row:3 / span 2; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards .today-card:nth-child(3) .today-back-body > .today-back-title { grid-column:1 / -1; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards .today-card:nth-child(3) .today-back-body > .today-more-chart { grid-column:1; grid-row:2; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards .today-card:nth-child(3) .today-back-body > .today-more-against { grid-column:1; grid-row:3; }
    body:not(.slip-cards-docked) .today:has(> .today-lead) .today-cards .today-card:nth-child(3) .today-back-body > .today-more-score { grid-column:1; grid-row:4; }
  }
}
@media (max-width: 40em) {
  .today { gap:1.25rem; }
  .today-cards, .today-tiles { grid-template-columns:minmax(0, 1fr); }
  .today-cards .today-card:nth-child(3) { grid-column:auto; }
  .today-lead, .today-slate > section { padding:1rem; }
  .today-slate .today-live-games { align-items:flex-start; }
  .today-lead-head .pd-button { width:100%; }
  .today-picks { grid-template-columns:minmax(0, 1fr); }
  /* Phone cards read closer together (UI-247): the same parts, a tighter rhythm. */
  .today-face { gap:0.5rem; padding:1rem 1rem 1rem 1.25rem; }
}
@media (prefers-reduced-motion: reduce) {
  .today-tile, .today-turn-mark, .today-scores > summary::before { transition:none; }
  .today.ar-enter > *, .today.ar-enter .today-card { animation:none; }
  /* The card doesn't turn: the faces cross-fade. */
  .today-flip, .today-flip.is-back:not(.to-back), .today-flip.to-back, .today-flip.to-front, .today-back { transform:none; animation:none; }
  /* Visibility switches at the end of the fade out, and at once on the way in. */
  .today-face { backface-visibility:visible; -webkit-backface-visibility:visible; transition:opacity var(--dur-slow) var(--ease-out), visibility var(--dur-slow) linear; }
  .today-flip.is-back > .today-back, .today-flip:not(.is-back) > .today-front { transition-duration:var(--dur-slow), 0s; }
  .today-back, .today-flip.is-back > .today-front { opacity:0; }
  .today-flip.is-back > .today-back { opacity:1; }
}
.today-card-title > span { display:block; margin-top:0.25rem; font:600 1rem/1.3 var(--font-body); text-transform:none; }
.today-card-title > span::first-letter { text-transform:uppercase; }
