/* Arcade: Daily Huddle's theme. Plum ground, a steel-blue primary, and controls that
   press in.
   Loaded after every other stylesheet; their colours were remapped to this palette,
   so this file sets the type and the shared component shapes. The faces and the palette
   tokens are in tokens.css (UI-593), loaded first and shared with admin.html. */
:root { font-family:var(--font-body); }
html body { font-family:var(--font-body); background:var(--bg); color:var(--ink); }
html body :is(button, input, select, textarea) { font-family:inherit; }
html body :is(h1, h2, h3) { font-family:var(--font-display); letter-spacing:0; }
/* Big Shoulders is a caps face: page and section headings set in capitals, heavy. */
html body :is(h1, h2) { text-transform:uppercase; font-weight:900; }
html body :is(.bet-side, .studio-odds-button, .bet-quote, .percentage-log-quote) { font-variant-numeric:tabular-nums; }

/* Header: badge logo, pill nav, pressable actions. */
html body[data-layout] .app-topbar { background:var(--bg); border-bottom:2px solid var(--line); box-shadow:none; }
html body[data-layout] .app-topbar .app-brand { font-family:var(--font-display); font-weight:900; font-size:1.5rem; letter-spacing:0; text-transform:uppercase; color:var(--ink); }
html body[data-layout] .app-topbar .app-brand .brand-lab { color:var(--accent); margin-left:0.3rem; }
html body[data-layout] .app-topbar .brand-circle-up { display:block; flex:none; width:3rem; height:3rem; }
.app-topbar .notebook-tabs { flex:0 1 auto; height:auto; align-self:center; align-items:center; gap:0.25rem; padding:0.25rem; background:var(--surface); border:1px solid var(--line); border-radius:var(--r-control); box-shadow:none; }
html body[data-layout] .app-topbar .notebook-tabs :is(.nav-tab, .tab-group-button, .nav-link) {
  height:2.25rem; display:inline-flex; align-items:center; gap:0.3rem; padding:0 1rem; margin:0; border:2px solid transparent; border-radius:var(--r-control);
  background:none; color:var(--muted); font:700 0.875rem/1 var(--font-body); text-decoration:none; box-shadow:none; white-space:nowrap; }
html body[data-layout] .app-topbar .notebook-tabs :is(.nav-tab, .tab-group-button, .nav-link):hover { color:var(--ink); background:var(--surface-raised); }
/* The current tab keeps its qualifier: its colour must out-rank layout-switcher.css's tab rules. */
html body[data-layout] .app-topbar .notebook-tabs .nav-tab[aria-current=page] {
  background:var(--accent); color:var(--accent-ink); border-color:var(--edge); }
.app-topbar .notebook-tabs .tab-group:has(.nav-tab[aria-current=page]) > .tab-group-button {
  background:var(--accent); color:var(--accent-ink); border-color:var(--edge); }
/* The gliding pill (UI-167, StudioHeader.glideTab): a copy of the pill rides under the labels
   from the old tab to the new one, while the new tab's own fill waits. */
.app-topbar .notebook-tabs { position:relative; }
.app-topbar .notebook-tabs :is(.nav-tab, .tab-group-button, .nav-link) { position:relative; }
.app-topbar .notebook-tabs > .nav-glide { position:absolute; box-sizing:border-box; border:1px solid var(--line); border-radius:var(--r-control); background:var(--accent); pointer-events:none; }
.app-topbar .notebook-tabs .is-glide-target { background:transparent !important; border-color:transparent !important; }
.app-topbar .notebook-tabs .tab-group-menu {
  padding:0.375rem; background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card); box-shadow:none; }
html body[data-layout] .app-topbar .notebook-tabs .tab-group-menu .nav-tab { width:100%; justify-content:flex-start; border-radius:var(--r-control); }

/* Team logo badges (StudioFormat.teamBadge): a neutral disc holds the space until the nfl.com
   logo loads, and stays if it fails. The team code never shows beside text that already
   names the team; only badges built with { code: true } (.shows-code) print it. */
html body .team-logo-badge:not(.has-team-logo)::before { content:""; position:absolute; inset:14%; border-radius:var(--r-data); background:var(--surface-raised); box-shadow:inset 0 0 0 1px var(--line); }
html body .team-logo-badge .team-abbreviation { display:none; }

/* Team boxes (team-colors.js, UI-204): a club as a square block in its colours, a matchup
   as two blocks side by side, away then home. A faint inner rule keeps a navy or black block
   apart from the plum ground; clubs whose colour alone matches another's carry a bar in
   their second colour along the foot.
   One width per size (UI-602), so DAL is never wider than TB beside it: the bare logo (no
   disc, Danny 2026-10-08), then the code centred in the rest. Every measure is in em of the
   box's own type, so sm, md and lg (and enlarged text) share the one formula below.
     --tb-logo-w / --tb-logo-h  the logo slot; the image is contained in it (players.css). The
                                NFL files are square with the mark floating inside; trimmed
                                files would suit a wide, short slot (about 1.6em by 1.1em):
                                change these two and every size follows.
     --tb-code-w                the widest code, WAS: 1.746em in Big Shoulders Display 900 at
                                0.01em tracking (MIN 1.548, NYG 1.501), measured in Chromium.
   The width is a floor (min-width), so a wider fallback font before the webfont loads grows
   the box instead of clipping the code. A logo that fails leaves the box its width, the code
   centred in all of it; where a container query hides the logos (Today's bug and cards, the
   guide) it also zeroes the slot (--tb-logo-w and --tb-gap), so those boxes narrow to the code.
   Logos that sink into their own colour (team-colors.js marks them .is-logo-low: NFL's IND, TB,
   DAL, TEN, NE, BAL, NO, LV, CHI; no NBA club yet, UI-778) take a light edge, on since UI-611 (Danny 2026-10-08):
   --tb-low-logo-filter (players.css) is drop-shadow(0 0 0.75px rgb(255 255 255 / 0.9)) twice.
   TEN's logo is also scaled 1.3x so its disc fills the slot (UI-612). */
.team-boxes { display:inline-flex; flex:none; vertical-align:middle; height:1.625rem; border-radius:var(--r-data); overflow:hidden; }
.team-box { --tb-logo-w:1.2em; --tb-logo-h:1.2em; --tb-gap:0.1em; --tb-code-w:1.75em; --tb-pad-start:0.2em; --tb-pad-end:0.15em;
  --tb-w:calc(var(--tb-pad-start) + var(--tb-logo-w) + var(--tb-gap) + var(--tb-code-w) + var(--tb-pad-end));
  display:inline-flex; flex:none; align-items:center; justify-content:flex-start; gap:var(--tb-gap); min-width:var(--tb-w); padding:0 var(--tb-pad-end) 0 var(--tb-pad-start); box-sizing:border-box;
  background:var(--tb-bg, var(--surface-raised)); color:var(--tb-fg, var(--ink)); box-shadow:inset 0 0 0 var(--tb-edge-w, 1px) var(--tb-edge, rgb(255 255 255 / 0.12));
  font:900 1rem/1 var(--font-display); letter-spacing:0.01em; }
.team-box-code { flex:1 1 auto; text-align:center; white-space:nowrap; }
.team-box.tb-ari { --tb-bg:#97233F; --tb-fg:#FFFFFF; }
.team-box.tb-atl { --tb-bg:#A71930; --tb-fg:#FFFFFF; }
.team-box.tb-bal { --tb-bg:#241773; --tb-fg:#FFFFFF; --tb-bar:#9E7C0C; }
.team-box.tb-buf { --tb-bg:#00338D; --tb-fg:#FFFFFF; --tb-bar:#C60C30; }
.team-box.tb-car { --tb-bg:#0085CA; --tb-fg:#000000; }
.team-box.tb-chi { --tb-bg:#0B162A; --tb-fg:#F26A2E; }
.team-box.tb-cin { --tb-bg:#FB4F14; --tb-fg:#000000; }
.team-box.tb-cle { --tb-bg:#311D00; --tb-fg:#FF3C00; }
.team-box.tb-dal { --tb-bg:#003594; --tb-fg:#FFFFFF; }
.team-box.tb-den { --tb-bg:#0A2343; --tb-fg:#FB4F14; }
.team-box.tb-det { --tb-bg:#0069A3; --tb-fg:#FFFFFF; }
.team-box.tb-gb { --tb-bg:#203731; --tb-fg:#FFB612; }
.team-box.tb-hou { --tb-bg:#03202F; --tb-fg:#FFFFFF; --tb-bar:#A71930; }
.team-box.tb-ind { --tb-bg:#002C5F; --tb-fg:#FFFFFF; }
.team-box.tb-jax { --tb-bg:#006778; --tb-fg:#FFFFFF; --tb-bar:#D7A22A; }
.team-box.tb-kc { --tb-bg:#E31837; --tb-fg:#FFFFFF; }
.team-box.tb-la { --tb-bg:#003594; --tb-fg:#FFD100; }
.team-box.tb-lac { --tb-bg:#0072B1; --tb-fg:#FFFFFF; --tb-bar:#FFC20E; }
.team-box.tb-lv { --tb-bg:#000000; --tb-fg:#A5ACAF; }
.team-box.tb-mia { --tb-bg:#00777E; --tb-fg:#FFFFFF; --tb-bar:#FC4C02; }
.team-box.tb-min { --tb-bg:#4F2683; --tb-fg:#FFC62F; }
.team-box.tb-ne { --tb-bg:#002244; --tb-fg:#B0B7BC; --tb-bar:#C60C30; }
.team-box.tb-no { --tb-bg:#101820; --tb-fg:#D3BC8D; }
.team-box.tb-nyg { --tb-bg:#0B2265; --tb-fg:#FFFFFF; --tb-bar:#A71930; }
.team-box.tb-nyj { --tb-bg:#125740; --tb-fg:#FFFFFF; }
.team-box.tb-phi { --tb-bg:#004C54; --tb-fg:#FFFFFF; }
.team-box.tb-pit { --tb-bg:#101820; --tb-fg:#FFB612; }
.team-box.tb-sea { --tb-bg:#002244; --tb-fg:#69BE28; }
.team-box.tb-sf { --tb-bg:#AA0000; --tb-fg:#FFFFFF; }
.team-box.tb-tb { --tb-bg:#D50A0A; --tb-fg:#FFFFFF; }
.team-box.tb-ten { --tb-bg:#0C2340; --tb-fg:#6BA7E3; }
.team-box.tb-was { --tb-bg:#5A1414; --tb-fg:#FFB612; }
/* NBA (UI-778): the NBA pack's colours (sport-config.js), on sport-scoped classes so a club that
   shares an NFL code (PHI, CHI, MIA...) never takes the NFL rule above. team-colors-css.test.js
   checks both blocks against the packs. */
.team-box.tb-nba-atl { --tb-bg:#C8102E; --tb-fg:#FFFFFF; }
.team-box.tb-nba-bkn { --tb-bg:#000000; --tb-fg:#FFFFFF; --tb-bar:#FFFFFF; }
.team-box.tb-nba-bos { --tb-bg:#008348; --tb-fg:#FFFFFF; }
.team-box.tb-nba-cha { --tb-bg:#008CA8; --tb-fg:#000000; }
.team-box.tb-nba-chi { --tb-bg:#CE1141; --tb-fg:#FFFFFF; }
.team-box.tb-nba-cle { --tb-bg:#860038; --tb-fg:#FFFFFF; }
.team-box.tb-nba-dal { --tb-bg:#0064B1; --tb-fg:#FFFFFF; }
.team-box.tb-nba-den { --tb-bg:#0E2240; --tb-fg:#FFFFFF; --tb-bar:#FEC524; }
.team-box.tb-nba-det { --tb-bg:#1D428A; --tb-fg:#FFFFFF; --tb-bar:#C8102E; }
.team-box.tb-nba-gsw { --tb-bg:#FDB927; --tb-fg:#000000; }
.team-box.tb-nba-hou { --tb-bg:#CE0E2D; --tb-fg:#FFFFFF; }
.team-box.tb-nba-ind { --tb-bg:#0C2340; --tb-fg:#FFFFFF; --tb-bar:#FFD520; }
.team-box.tb-nba-lac { --tb-bg:#12173F; --tb-fg:#FFFFFF; }
.team-box.tb-nba-lal { --tb-bg:#552583; --tb-fg:#FFFFFF; }
.team-box.tb-nba-mem { --tb-bg:#5D76A9; --tb-fg:#000000; }
.team-box.tb-nba-mia { --tb-bg:#98002E; --tb-fg:#FFFFFF; }
.team-box.tb-nba-mil { --tb-bg:#00471B; --tb-fg:#FFFFFF; }
.team-box.tb-nba-min { --tb-bg:#266092; --tb-fg:#FFFFFF; }
.team-box.tb-nba-nop { --tb-bg:#0A2240; --tb-fg:#FFFFFF; --tb-bar:#B4975A; }
.team-box.tb-nba-nyk { --tb-bg:#1D428A; --tb-fg:#FFFFFF; --tb-bar:#F58426; }
.team-box.tb-nba-okc { --tb-bg:#007AC1; --tb-fg:#FFFFFF; }
.team-box.tb-nba-orl { --tb-bg:#0150B5; --tb-fg:#FFFFFF; }
.team-box.tb-nba-phi { --tb-bg:#1D428A; --tb-fg:#FFFFFF; --tb-bar:#E01234; }
.team-box.tb-nba-phx { --tb-bg:#29127A; --tb-fg:#FFFFFF; }
.team-box.tb-nba-por { --tb-bg:#E03A3E; --tb-fg:#000000; }
.team-box.tb-nba-sac { --tb-bg:#5A2D81; --tb-fg:#FFFFFF; }
.team-box.tb-nba-sas { --tb-bg:#000000; --tb-fg:#FFFFFF; --tb-bar:#C4CED4; }
.team-box.tb-nba-tor { --tb-bg:#D91244; --tb-fg:#FFFFFF; }
.team-box.tb-nba-uta { --tb-bg:#4E008E; --tb-fg:#FFFFFF; }
.team-box.tb-nba-was { --tb-bg:#E31837; --tb-fg:#FFFFFF; }
.team-box.has-bar { box-shadow:inset 0 -3px 0 var(--tb-bar), inset 0 0 0 var(--tb-edge-w, 1px) var(--tb-edge, rgb(255 255 255 / 0.12)); }
.team-boxes.is-sm { height:1.375rem; }
.team-boxes.is-sm .team-box { font-size:0.875rem; }
.team-boxes.is-lg { height:3.5rem; }
.team-boxes.is-lg .team-box { font-size:1.75rem; }
.team-boxes.is-lg .team-box.has-bar { box-shadow:inset 0 -4px 0 var(--tb-bar), inset 0 0 0 var(--tb-edge-w, 1px) var(--tb-edge, rgb(255 255 255 / 0.12)); }
/* A box that links to its Teams page (team-colors.js, UI-617): no underline; on hover and focus
   its faint edge brightens to a 2px light rim and the colour lifts a little. The focus ring is
   drawn inside the box (the group's rounded overflow would clip one outside): the accent over
   a 4px light rim, so it reads on every club's colour. */
a.team-box { text-decoration:none; cursor:pointer; transition:filter var(--dur-fast, 0.12s) ease, box-shadow var(--dur-fast, 0.12s) ease; }
a.team-box:hover, a.team-box:focus-visible { --tb-edge:rgb(255 255 255 / 0.75); --tb-edge-w:2px; filter:brightness(1.15); }
html body a.team-box:focus-visible { --tb-edge:#fff; --tb-edge-w:4px; outline:2px solid var(--accent); outline-offset:-2px; }
@media (prefers-reduced-motion: reduce) { a.team-box { transition:none; } }
html body .team-logo-badge.shows-code:not(.has-team-logo) .team-abbreviation { display:inline; position:relative; opacity:1; color:var(--muted); font:800 0.5625rem/1 var(--font-body); letter-spacing:0; }

/* Buttons press in. */
html body[data-layout] .pd-button {
  border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); color:var(--ink);
  box-shadow:none; font-weight:700; }
html body[data-layout] .app-topbar .betslip-toggle { background:var(--accent); color:var(--accent-ink); }
.app-topbar .betslip-toggle #betslipToggleCount { background:var(--bg); color:var(--accent); border-radius:var(--r-control); }

/* Fields. */
html body[data-layout] :is(select, input[type=search], input[type=text], input[type=number], input:not([type])) {
  border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); color:var(--ink); }

/* Prices: one pressable component everywhere; picked = filled blue. */
html body[data-layout] :is(.bet-side, .studio-odds-button) {
  border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); box-shadow:none; }
html body[data-layout] :is(.bet-side, .studio-odds-button)[aria-pressed=true] { background:var(--accent); color:var(--accent-ink); border-color:var(--edge); }
html body[data-layout] :is(.bet-side, .studio-odds-button)[aria-pressed=true] * { color:inherit; }

/* Surfaces: 8px boxes with a 1px rule, no shadow (UI-204). */
html body[data-layout] :is(.layout-panel, .percentage-filters, .defense-board, .usage-card, .usage-home-card, .fantasy-home-card, .team-card, .selection-panel, .team-picker-panel) {
  border:1px solid var(--line); border-radius:var(--r-card); box-shadow:none; }
html body[data-layout] dialog { border:1px solid var(--line); border-radius:var(--r-card); box-shadow:none; }
html body[data-layout] dialog.betslip-drawer { border-radius:var(--r-card) 0 0 var(--r-card); }
.studio-game-button { border:1px solid var(--line); border-radius:var(--r-control); box-shadow:none; }

/* Segmented filters (positions and similar): one pill track, the choice filled. */
.position-segments { border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); box-shadow:none; padding:0.1875rem; gap:0.1875rem; }
html body[data-layout] .position-segments button { border:0; border-radius:var(--r-control); color:var(--muted); font-weight:700; }
html body[data-layout] .position-segments button[aria-pressed=true] { background:var(--selected-bg); color:var(--ink); box-shadow:inset 0 0 0 1px var(--accent); }

/* Today lives in today.css. */

/* Header extras: search, line freshness, week chip (studio-header.js). */
html body[data-layout] .app-topbar { display:flex; align-items:center; gap:1rem; padding:0 1.5rem; }
html body[data-layout] .app-topbar > .app-brand { flex:0 0 auto; }
.app-search { position:relative; flex:0 1 15rem; min-width:10rem; height:2.75rem; margin-left:auto; display:flex; align-items:center; gap:0.5rem; padding:0 0.625rem 0 0.875rem;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-control); color:var(--muted); }
/* UI-347: one focus state, on the whole box: the accent border plus a soft ring. The input
   draws none of its own (the sitewide :focus-visible outlines would inset a second ring).
   The transparent outline shows in forced-colors mode, where box-shadow is dropped. */
.app-search:focus-within { border-color:var(--accent); box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); outline:2px solid transparent; }
html body[data-layout] .app-search input:is(:focus, :focus-visible) { outline:none; box-shadow:none; }
.app-search:focus-within kbd { display:none; }
.app-search input { flex:1; min-width:0; height:100%; padding:0; border:0 !important; background:none !important; color:var(--ink); font:600 0.875rem var(--font-body); outline:none; text-overflow:ellipsis; }
.app-search input::placeholder { color:var(--muted); }
.app-search kbd { padding:0.125rem 0.4375rem; border-radius:var(--r-data); background:var(--surface-raised); color:var(--muted); font:700 0.6875rem var(--font-mono); white-space:nowrap; }
.app-search-results { position:absolute; top:calc(100% + 0.5rem); left:0; right:0; z-index:80; margin:0; padding:0.375rem; list-style:none; display:grid; gap:0.25rem;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card); box-shadow:none; max-height:24rem; overflow:auto; }
.app-search-result { width:100%; display:grid; grid-template-columns:auto 1fr auto; align-items:center; gap:0.625rem; padding:0.5rem 0.625rem; border:0; border-radius:var(--r-control);
  background:none; color:var(--ink); text-align:left; text-decoration:none; font:600 0.875rem var(--font-body); cursor:pointer; }
.app-search-result:hover, .app-search-result.is-active { background:var(--surface-raised); }
.app-search-result small { color:var(--muted); font-size:0.75rem; }
/* Search headshots (UI-161): initials show until the photo loads, and stay when there's
   none (players.css .has-photo). */
.app-search-avatar { position:relative; display:block; flex:0 0 1.75rem; width:1.75rem; height:1.75rem; padding:0; overflow:hidden; border:2px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); box-sizing:border-box; cursor:inherit; }
html body[data-layout] .app-search-avatar .player-avatar { position:relative; display:grid; place-items:center; width:100%; height:100%; border:0; border-radius:0; background:none; box-shadow:none;
  color:var(--muted); font:800 0.625rem var(--font-body); }
html body[data-layout] .app-search-avatar .player-headshot { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:center top; }
.app-search-logo.team-logo-badge { flex:0 0 1.75rem; width:1.75rem; height:1.75rem; } /* team rows (UI-176): the face's box */
.app-search-who { display:flex; align-items:center; gap:0.5rem; min-width:0; }
.app-search-who strong { min-width:0; overflow-wrap:anywhere; }
/* The avatar takes room from the name, so on wider screens the list may grow past a narrow
   search box, leftward (it stays anchored to the box's right edge). */
@media (min-width: 45em) { .app-search .app-search-results { left:auto; width:max(100%, 21rem); } }
.app-search-tag { min-width:2.5rem; padding:0.125rem 0.375rem; border-radius:var(--r-data); background:var(--line); color:var(--ink); font:700 0.6875rem var(--font-mono); text-align:center; }
.app-search-empty { padding:0.625rem; color:var(--muted); font-size:0.875rem; }
.app-freshness { display:inline-flex; align-items:center; gap:0.4375rem; color:var(--muted); font:700 0.75rem var(--font-mono); white-space:nowrap; }
.app-freshness-dot { width:0.5625rem; height:0.5625rem; border-radius:50%; background:var(--green); border:1px solid var(--line); }
/* Lines over six hours old with a kickoff within 18 hours (studio-header.js sets data-stale): the dot turns gold. */
.app-freshness[data-stale="true"] .app-freshness-dot { background:var(--thin); }
/* The Wk chip is a link to Slate on that week (studio-header.js), pressed like the buttons beside it. */
.app-week { height:2.75rem; display:inline-flex; align-items:center; padding:0 0.875rem; background:var(--surface-raised); border:1px solid var(--line); border-radius:var(--r-control);
  box-shadow:none; color:var(--ink); font:700 0.875rem var(--font-mono); white-space:nowrap; text-decoration:none; cursor:pointer; transition:transform 80ms ease, box-shadow 80ms ease; }
.app-week:hover { border-color:var(--muted); }
.app-week:active { transform:translateY(1px); }
.app-week:focus-visible { outline:0.1875rem solid var(--cyan); outline-offset:0.1875rem; }
@media (prefers-reduced-motion: reduce) { .app-week { transition:none; } }
html body[data-layout] .app-topbar .guide-open { height:2.75rem; width:2.75rem; padding:0; justify-content:center; }
.app-topbar .guide-open .guide-open-label { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); }
html body[data-layout] .app-topbar .betslip-toggle { height:2.75rem; padding:0 0.5rem 0 1rem; border-radius:var(--r-control); font-weight:800; }
/* Your data (UI-85): an icon button like Guide's, opening Back up / Restore in a popover
   that studio-entry.js places under it. */
html body[data-layout] .app-topbar .data-menu-open { flex:0 0 auto; height:2.75rem; width:2.75rem; padding:0; display:inline-flex; align-items:center; justify-content:center; }
.data-menu-icon { display:block; width:1.25rem; height:1.25rem; color:var(--accent); }
.data-menu-label { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
html body .data-menu { position:fixed; inset:auto; z-index:90; margin:0; width:min(20rem, calc(100vw - 1rem)); padding:1rem; box-sizing:border-box;
  background:var(--surface); color:var(--ink); border:1px solid var(--line); border-radius:var(--r-card); box-shadow:none; }
html body .data-menu h2 { margin:0 0 0.375rem; font-size:1rem; }
html body .data-menu p { margin:0 0 0.875rem; color:var(--muted); font-size:0.875rem; line-height:1.45; }
html body .data-menu-actions { display:flex; gap:0.5rem; }
html body[data-layout] .data-menu-actions .pd-button { flex:1 1 0; min-height:2.75rem; padding:0 0.75rem; font-size:0.875rem; }
html body[data-layout] .data-menu-actions .pd-button.primary { background:var(--accent); color:var(--accent-ink); }
.app-search svg { flex:0 0 auto; pointer-events:none; }
/* Sport switch: one chip beside the brand with the open sport ("NFL ▾") that opens
   the choices. studio-header.js builds it when a second sport is ready, or in a preview. */
/* Laptops (1200-1600px): the header is one row with no spare width (UI-346), so with the switch
   in it the brand keeps its mark (still the home link) and drops the wordmark, the switch sits
   closer to the mark, and My Picks stays on the top row.
   Wider screens keep the wordmark. */
@media (min-width:75.0625em) and (max-width:100em) {
  html body[data-layout][data-layout-mode] .app-topbar:has(> .app-sport) .app-brand > span:last-child { display:none; }
  html body[data-layout][data-layout-mode] .app-sport { gap:0.125rem; padding:0.125rem; margin-left:-0.3125rem; }
}
.app-sport { flex:0 0 auto; display:inline-flex; align-items:stretch; gap:0.1875rem; height:2.75rem; padding:0.1875rem; box-sizing:border-box;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-control); }
:is(html body[data-layout], html body) .app-sport button { display:inline-flex; align-items:center; padding:0 0.625rem; border:0; border-radius:var(--r-control); background:none; box-shadow:none;
  color:var(--muted); font:800 0.8125rem var(--font-mono); letter-spacing:0.04em; cursor:pointer; transition:background-color 80ms ease, color 80ms ease; }
:is(html body[data-layout], html body) .app-sport button:hover { color:var(--ink); background:var(--surface-raised); }
:is(html body[data-layout], html body) .app-sport button[aria-pressed=true] { background:var(--accent); color:var(--accent-ink); cursor:default; }
.app-sport button:focus-visible { outline:0.1875rem solid var(--cyan); outline-offset:0.125rem; }
@media (prefers-reduced-motion: reduce) { :is(html body[data-layout], html body) .app-sport button { transition:none; } }
/* Before the page lays out only the brand shows in the header (layouts.css); the switch shows
   too, so a preview whose pages stop while loading still has its way back. */
html body:not([data-layout]) .app-topbar > .app-sport { display:inline-flex; }

/* Layout geometry: the only place these are set. --topbar-height is the header's designed
   height (its floor on phones); --header-height starts equal to it and studio-header.js
   writes the measured height over it (inline, on html and body), so focus, in-page jumps
   and sticky offsets stop below the header. --slip-width is the My Picks drawer's width;
   --content-max caps the content column on wide screens (the root font is 110%, 17.6px,
   so 91rem is about 1600px). */
:root { --topbar-height:4rem; --header-height:4rem; --slip-width:24vw; --content-max:91rem; }
html { scroll-padding-top:calc(var(--header-height) + 0.5rem); }
@media (max-width: 75.55625em) { :root { --slip-width:21.25rem; } }
@media (max-width: 40em) { :root { --topbar-height:min(3.375rem, 59.4px); --header-height:min(3.375rem, 59.4px); } }

/* Below laptop width search is an icon button; it (or Ctrl K) opens the box over the header. */
html body[data-layout] .app-topbar > .app-search-open { display:none; }
@media (max-width: 81.25em) {
  html body[data-layout][data-layout-mode] .app-topbar > .app-search-open { display:inline-flex; flex:0 0 auto; align-items:center; justify-content:center; width:2.75rem; height:2.75rem; padding:0; margin-left:auto; }
  html body[data-layout][data-layout-mode] .app-topbar > .app-search { display:none; }
  html body[data-layout][data-layout-mode] .app-topbar[data-search-open] > .app-search { display:flex; position:absolute; z-index:5; top:0.625rem; left:1rem; right:1rem; width:auto; max-width:none; min-width:0; margin:0; }
  html body[data-layout][data-layout-mode] .app-topbar[data-search-open] > .app-search .app-search-results { left:0; width:auto; }
}

/* Tablets: one row; the tabs that don't fit fold into More (studio-header.js). */
@media (width > 40em) and (width <= 75em) {
  html body[data-layout][data-layout-mode] .app-topbar { display:flex; flex-wrap:wrap; align-items:center; align-content:center; column-gap:0.5rem; row-gap:0.375rem;
    height:auto; min-height:var(--topbar-height); padding:0.5rem 1rem; }
  html body[data-layout][data-layout-mode] .app-topbar > * { flex:none; max-width:100%; margin-block:0; }
  html body[data-layout][data-layout-mode] .app-topbar > :is(.app-freshness, .app-week, #userGuideButton, .data-menu-open) { display:none; }
  html body[data-layout][data-layout-mode] .app-topbar > .app-actions { display:flex; }
  html body[data-layout][data-layout-mode] .app-topbar:has(> .app-sport) .app-brand > span:last-child { display:none; }
  html body[data-layout][data-layout-mode] .app-topbar > .notebook-tabs { flex-wrap:nowrap; width:auto; height:auto; overflow:visible; }
  html body[data-layout][data-layout-mode] .app-topbar .notebook-tabs > #todayTab { display:none; }
  html body[data-layout][data-layout-mode] .app-topbar .notebook-tabs :is(.nav-tab, .tab-group-button, .nav-link) { padding:0 0.3125rem; }
  html body[data-layout][data-layout-mode] .app-topbar .notebook-tabs .tab-group-menu .nav-tab { padding:0 0.75rem; }
  html body[data-layout][data-layout-mode] .app-topbar .betslip-toggle { display:inline-flex; align-items:center; gap:0.375rem; padding:0 0.375rem 0 0.625rem; }
  .app-topbar .betslip-toggle .betslip-toggle-icon { display:block; }
  html body[data-layout][data-layout-mode] .app-topbar .betslip-toggle .betslip-toggle-label { display:none; }
}
.app-topbar > .app-actions { display:none; position:relative; }
html body[data-layout] .app-topbar .app-actions-open { width:2.75rem; height:2.75rem; padding:0; display:inline-flex; align-items:center; justify-content:center; }
.app-actions-menu { position:absolute; top:calc(100% + 0.375rem); right:0; z-index:85; display:grid; gap:0.125rem; min-width:12rem; padding:0.375rem;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card); }
.app-actions-menu > div { display:grid; gap:0.125rem; }
html body[data-layout] .app-actions-menu button { min-height:2.75rem; padding:0 0.75rem; border:0; border-radius:var(--r-control); background:none; box-shadow:none;
  color:var(--ink); font:700 0.875rem var(--font-body); text-align:left; cursor:pointer; }
html body[data-layout] .app-actions-menu button:hover { background:var(--surface-raised); }
.app-actions-menu button:focus-visible { outline:0.1875rem solid var(--cyan); outline-offset:-0.1875rem; }
:is(.app-actions-group, .tab-more-heading) { margin:0.375rem 0 0; padding:0 0.75rem; color:var(--muted); font:700 0.6875rem/1.6 var(--font-mono); letter-spacing:0.08em; text-transform:uppercase; }
.tab-more-group { display:grid; gap:0.125rem; padding-left:0.75rem; }
.betslip-toggle-icon { display:none; flex:none; }
html body[data-layout] .app-topbar .betslip-toggle .betslip-toggle-label { display:inline; min-width:0; height:auto; margin:0; padding:0; border-radius:0; background:none; color:inherit; font-size:inherit; }

/* Phone: one header row (its floor is --topbar-height, never the measured --header-height); the pages are in the bottom bar. */
@media (max-width: 40em) {
  html body[data-layout][data-layout-mode] .app-topbar { display:flex; flex-wrap:wrap; align-items:center; align-content:center; column-gap:0.375rem; row-gap:0.25rem;
    height:auto; min-height:var(--topbar-height); padding:0.25rem min(0.625rem, 11px); }
  html body[data-layout][data-layout-mode] .app-topbar > * { flex:none; max-width:100%; }
  html body[data-layout][data-layout-mode] .app-topbar > :is(.notebook-tabs, .app-freshness, .data-menu-open) { display:none; }
  html body[data-layout][data-layout-mode] .app-topbar:has(> .app-sport) > .app-brand { display:none; }
  html body[data-layout][data-layout-mode] .app-topbar > .app-brand { gap:0.25rem; min-height:min(2.75rem, 48.4px); }
  html body[data-layout][data-layout-mode] .app-topbar .app-brand > span:last-child { font-size:1rem; }
  html body[data-layout][data-layout-mode] .app-topbar .brand-circle-up { width:2rem; height:2rem; }
  html body[data-layout][data-layout-mode] .app-topbar > .app-search-open { width:auto; height:auto; min-width:44px; min-height:44px; }
  html body[data-layout][data-layout-mode] .app-topbar[data-search-open] > .app-search { top:0.25rem; left:min(0.625rem, 11px); right:min(0.625rem, 11px); }
  .app-week { height:auto; min-height:44px; padding:0 0.5rem; font-size:0.8125rem; }
  html body[data-layout][data-layout-mode] .app-topbar > #userGuideButton { width:auto; height:auto; min-width:44px; min-height:44px; }
  html body[data-layout][data-layout-mode] .app-topbar .betslip-toggle { height:auto; min-height:44px; padding:0 0.375rem 0 0.625rem; font-size:0.8125rem; }
}
/* Large text on a phone: the header keeps to one row (the mark without its wordmark, capped sizes). */
@media (max-width: 19.99em) {
  html body[data-layout][data-layout-mode] .app-topbar { column-gap:min(0.375rem, 6.6px); }
  html body[data-layout][data-layout-mode] .app-topbar > .app-week { display:none; }
  html body[data-layout][data-layout-mode] .app-topbar .app-brand > span:last-child { display:none; }
  html body[data-layout][data-layout-mode] .app-topbar .brand-circle-up { width:min(2rem, 36px); height:min(2rem, 36px); }
  html body[data-layout][data-layout-mode] .app-topbar .betslip-toggle { font-size:min(0.8125rem, 14px); }
}

.app-topbar > .app-sport { position:relative; height:auto; min-height:44px; }
:is(html body[data-layout], html body) .app-sport .app-sport-chip { display:inline-flex; gap:0.25rem; padding:0 0.5rem; background:var(--accent); color:var(--accent-ink); }
:is(html body[data-layout], html body) .app-sport .app-sport-chip:hover { background:var(--accent); color:var(--accent-ink); }
.app-sport-choices { display:none; position:absolute; top:calc(100% + 0.375rem); left:0; z-index:85; min-width:7rem; padding:0.375rem; gap:0.25rem;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card); }
.app-sport[data-open] > .app-sport-choices { display:grid; }
:is(html body[data-layout], html body) .app-sport .app-sport-choices button { min-height:44px; padding:0 0.75rem; font-size:0.8125rem; }

/* Phone pages bar (layouts.js); anything pinned to the screen's foot sits above it. */
.bottom-nav { display:none; }
@media (max-width: 40em) {
  /* Capped in px so five labels still fit a 320px bar at 200% text. */
  :root { --bottom-nav-height:calc(min(3.5rem, 64px) + env(safe-area-inset-bottom, 0px)); }
  html body[data-layout] { padding-bottom:var(--bottom-nav-height); }
  html body[data-layout] .bottom-nav { position:fixed; left:0; right:0; bottom:0; z-index:35; display:flex; align-items:stretch; height:var(--bottom-nav-height); box-sizing:border-box;
    padding:0 max(0.25rem, env(safe-area-inset-right, 0px)) env(safe-area-inset-bottom, 0px) max(0.25rem, env(safe-area-inset-left, 0px)); background:var(--bg); border-top:2px solid var(--line); }
  html body .bottom-nav-more { flex:1 1 0; min-width:0; display:flex; }
  html body[data-layout] .bottom-nav .bottom-nav-item { flex:1 1 0; min-width:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:0.125rem; margin:0; padding:0;
    border:0; border-radius:var(--r-control); background:none; box-shadow:none; color:var(--muted); font:700 min(0.6875rem, 13px)/1.1 var(--font-body); text-decoration:none; cursor:pointer; }
  html body .bottom-nav-icon { flex:none; width:min(3rem, 52px); height:min(1.75rem, 30px); padding:min(0.125rem, 2px) 0; box-sizing:border-box; border:2px solid transparent; border-radius:var(--r-control); }
  html body[data-layout] .bottom-nav .bottom-nav-item:hover { color:var(--ink); }
  html body[data-layout] .bottom-nav .bottom-nav-item:is([aria-current=page], .is-active) { color:var(--ink); }
  html body .bottom-nav-item:is([aria-current=page], .is-active) .bottom-nav-icon { background:var(--accent); color:var(--accent-ink); border-color:var(--edge); }
  html body .bottom-nav-item[aria-expanded=true] .bottom-nav-icon { background:var(--surface-raised); border-color:var(--line); }
  html body .bottom-nav-item:focus-visible { outline:0.1875rem solid var(--cyan); outline-offset:-0.1875rem; }
  html body .bottom-nav-menu { position:fixed; left:0.5rem; right:0.5rem; bottom:calc(var(--bottom-nav-height) + 0.5rem); display:grid; gap:0.125rem; max-height:calc(100dvh - var(--header-height) - var(--bottom-nav-height) - 1rem);
    overflow:auto; padding:0.5rem; box-sizing:border-box; background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card); }
  html body .bottom-nav-menu[hidden] { display:none; }
  html body .bottom-nav-sub { display:grid; gap:0.125rem; padding-left:0.75rem; }
  html body .bottom-nav-group { margin:0.375rem 0 0; padding:0 0.75rem; color:var(--muted); font:700 0.6875rem/1.6 var(--font-mono); letter-spacing:0.08em; text-transform:uppercase; }
  html body[data-layout] .bottom-nav .bottom-nav-link { display:flex; align-items:center; min-height:44px; padding:0 0.75rem; border:2px solid transparent; border-radius:var(--r-control);
    color:var(--ink); font:700 0.9375rem var(--font-body); text-decoration:none; }
  html body[data-layout] .bottom-nav .bottom-nav-link:hover { background:var(--surface-raised); }
  html body[data-layout] .bottom-nav .bottom-nav-link[aria-current=page] { background:var(--accent); color:var(--accent-ink); border-color:var(--edge); }
  html body .bottom-nav-link:focus-visible { outline:0.1875rem solid var(--cyan); outline-offset:-0.1875rem; }
  html body :is(.bet-toast, .fantasy-undo, .back-to-top) { bottom:calc(1rem + var(--bottom-nav-height)); }
  html body[data-active-view=player]:has(.pp.has-action) .back-to-top { bottom:calc(9rem + var(--bottom-nav-height)); }
  html body .pp-action { bottom:calc(0.75rem + var(--bottom-nav-height)); }
  html body .percentage-match.is-open { bottom:calc(0.75rem + var(--bottom-nav-height)); }
  html body .team-nav-menu { top:auto !important; bottom:calc(var(--bottom-nav-height) + 0.5rem); max-height:calc(100dvh - var(--header-height) - var(--bottom-nav-height) - 1rem); overflow:auto; }
}

/* ------------------------------------------------------------------------------------
   Component kit. Every redesigned screen builds from these, so prices, scores and hit
   dots look the same everywhere.
   .ar-card      ruled surface card                .ar-label   small uppercase mono label
   .ar-row       a list row card (.is-picked)      .ar-rank    "01" rank tile
   .ar-pos       "QB1" position tag
   .ar-price     pickable price; aria-pressed=true = picked (filled, with a check)
   .ar-score     Play Score badge (.is-high / .is-mid / .is-low)
   .ar-dots      hit dots: .ar-dot.hit / .miss / .push
   .ar-seg       segmented chips; the chosen one takes --selected-bg; buttons use aria-pressed
   .ar-btn       pressable button; .ar-btn.primary = blue
   ------------------------------------------------------------------------------------ */
.ar-card { background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card); box-shadow:none; }
.ar-label { color:var(--muted); font:700 0.6875rem/1.2 var(--font-mono); letter-spacing:0.06em; text-transform:uppercase; }
.ar-row { display:grid; align-items:center; gap:0.875rem; padding:0.625rem 0.875rem; background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card); box-shadow:none; }
.ar-row.is-picked { border-color:var(--accent); box-shadow:0 0 0 1px var(--accent); }
.ar-rank { width:2.25rem; height:2.25rem; display:grid; place-items:center; border-radius:var(--r-data); background:var(--surface-raised); border:1px solid var(--line); color:var(--muted); font:700 0.875rem var(--font-mono); }
.ar-pos { display:inline-block; padding:0.0625rem 0.375rem; border-radius:var(--r-data); background:var(--line); color:var(--ink); font:700 0.6875rem var(--font-mono); }
/* Position colours (UI-387; moved here from players.css so every page has them). Any element
   with data-position gets --position-color (card rules, heatmap heads, avatars) and, for
   chips, a tinted fill and a light label: label on fill is 6.0:1 (QB) to 7.5:1 (TE), AA.
   QB red, RB green, WR blue, TE gold, K lilac, DEF copper (UI-463: WR was orange, DEF cyan,
   which sat too close to the new blue). Position chips are the one identity colour on the
   site; elsewhere colour means performance. StudioKit.posChip draws the chip; BN and IR stay grey. */
[data-position=QB] { --position-color:#ef6461; --position-bg:#4e2b38; --position-ink:#f59f9d; }
[data-position=RB] { --position-color:#57c99a; --position-bg:#2d4144; --position-ink:#97dec0; }
[data-position=WR] { --position-color:#5aa8f2; --position-bg:#2a3b57; --position-ink:#a8cff7; }
[data-position=TE] { --position-color:#f1ce57; --position-bg:#4f4235; --position-ink:#f6e197; }
[data-position=K] { --position-color:#b48cf2; --position-bg:#413458; --position-ink:#d1b8f7; }
[data-position=DEF] { --position-color:#c98a5e; --position-bg:#4a3529; --position-ink:#e8c1a0; }
:where(.pos-chip) { display:inline-block; padding:0.0625rem 0.375rem; border-radius:var(--r-data); background:var(--line); color:var(--ink); font:700 0.6875rem var(--font-mono); text-align:center; white-space:nowrap; }
html body :is(.pos-chip, .team-pos-chip, .ar-pos)[data-position] { background:var(--position-bg); color:var(--position-ink); border-color:var(--position-color); }
/* One width per kind of chip (UI-602), so QB, DEF and WR line up in a list: StudioKit.posChip
   names the kind (data-chip) and the label centres in a content box as wide as the kind's
   widest label, in em of the chip's own type (Big Shoulders Figures 700, measured in Chromium):
   pos DST 1.327em (DEF 1.268; D/ST and defensive spots other than DL, LB, DB get no kind),
   slot FLEX 1.624em (long spellings show their short name: posChip), depth DEF32 2.323em
   (WR12 2.263; a 3-digit rank grows). The site sizes border boxes, so a chip with a kind
   measures its content box, and each page keeps its padding and its floor: beside its own
   min-width (for chips without a kind) a page sets --chip-min, that floor less its padding,
   so no chip is ever narrower than the page's min-width. A column that shows more than one
   kind sets --chip-kind-w for all of it: a lineup's slot column (here: every chip takes the
   slot width, QB or FLEX) and a Teams room (teams.css: the depth width). Matchups' position
   buttons and the Fantasy week's outlined slots keep their own sizes. */
:where(.pos-chip) { --chip-pos-w:1.33em; --chip-slot-w:1.63em; --chip-depth-w:2.33em; }
.pos-chip[data-chip=pos] { --chip-kind-w:var(--chip-pos-w); }
.pos-chip[data-chip=depth] { --chip-kind-w:var(--chip-depth-w); }
.pos-chip[data-chip=slot], .pos-chip.fantasy-slot-chip { --chip-kind-w:var(--chip-slot-w); }
html body .pos-chip:is([data-chip], .fantasy-slot-chip):not(.mu-pos-chip, .fw-slot) { box-sizing:content-box; min-width:max(var(--chip-min, 0px), var(--chip-kind-w)); text-align:center; }
/* Flex slots (UI-463): the chip blends the positions the slot takes, its fill each colour mixed 40%
   into the ground (brighter than a single position's tint, so the blend reads), and any border
   the bright colours. FLEX and W/R/T RB > WR > TE, W/R RB > WR, W/T WR > TE, SF QB > RB > WR > TE.
   White label: 6.3:1 on the TE stop, 7.6:1 or better on the rest. Fill only: a flex slot sets no
   --position-color (a slot with a player keeps that player's). */
html body .pos-chip[data-slot] { --slot-fill:#315c50, #324f73, #6e5e35; --slot-edge:#57c99a, #5aa8f2, #f1ce57; color:#ffffff; border-color:transparent;
  background:linear-gradient(90deg, var(--slot-fill)) padding-box, linear-gradient(90deg, var(--slot-edge)) border-box; }
html body .pos-chip[data-slot="W/R"] { --slot-fill:#315c50, #324f73; --slot-edge:#57c99a, #5aa8f2; }
html body .pos-chip[data-slot="W/T"] { --slot-fill:#324f73, #6e5e35; --slot-edge:#5aa8f2, #f1ce57; }
html body .pos-chip[data-slot=SF] { --slot-fill:#6d3339, #315c50, #324f73, #6e5e35; --slot-edge:#ef6461, #57c99a, #5aa8f2, #f1ce57; }
/* NBA positions (Sleeper's colours) on [data-sport=nba][data-pos], as data-position is NFL's; G and F blend two. */
[data-sport=nba][data-pos=PG] { --position-color:#f0547e; --position-bg:#4d2635; --position-ink:#f79ab3; }
[data-sport=nba][data-pos=SG] { --position-color:#f59a4a; --position-bg:#4d3526; --position-ink:#f8c497; }
[data-sport=nba][data-pos=SF] { --position-color:#3fcfb4; --position-bg:#234541; --position-ink:#93e3d3; }
[data-sport=nba][data-pos=PF] { --position-color:#58b7f0; --position-bg:#263f55; --position-ink:#a6d6f6; }
[data-sport=nba][data-pos=C] { --position-color:#e8c547; --position-bg:#4a4128; --position-ink:#f2de92; }
[data-sport=nba][data-pos=UTIL] { --position-color:#a77bff; --position-bg:#3d2f5c; --position-ink:#d6c0ff; }
[data-sport=nba][data-pos=G] { --position-fill:#6a2c43, #6a4529; --position-edge:#f0547e, #f59a4a; }
[data-sport=nba][data-pos=F] { --position-fill:#255a52, #2b4f70; --position-edge:#3fcfb4, #58b7f0; }
html body .pos-chip[data-sport=nba][data-pos] { background:var(--position-bg); color:var(--position-ink); border-color:var(--position-color); }
html body .pos-chip[data-sport=nba]:is([data-pos=G], [data-pos=F]) { color:#ffffff; border-color:transparent;
  background:linear-gradient(90deg, var(--position-fill)) padding-box, linear-gradient(90deg, var(--position-edge)) border-box; }
.ar-price { min-width:8.5rem; height:2.5rem; display:inline-flex; align-items:center; justify-content:space-between; gap:0.75rem; padding:0 0.75rem; cursor:pointer;
  background:var(--bg); color:var(--ink); border:1px solid var(--line); border-radius:var(--r-control); box-shadow:none; font:700 0.875rem var(--font-mono); }
.ar-price[aria-pressed=true] { background:var(--accent); color:var(--accent-ink); }
/* Picked is the accent fill (and aria-pressed for screen readers): no check mark, so the button keeps its width (UI-642). */
.ar-price:disabled { opacity:0.55; cursor:not-allowed; }
.ar-score { min-width:3.75rem; height:2.5rem; display:inline-grid; place-items:center; padding:0 0.5rem; border:1px solid var(--line); border-radius:var(--r-control);
  background:var(--surface-raised); color:var(--ink); font:700 1rem var(--font-mono); }
.ar-score.is-high { background:var(--green); color:var(--accent-ink); }
.ar-score.is-mid { background:var(--accent); color:var(--accent-ink); }
.ar-dots { display:inline-flex; flex-wrap:wrap; gap:0.3125rem; }
.ar-dot { width:0.5625rem; height:0.5625rem; border-radius:50%; background:var(--line); }
.ar-dot.hit { background:var(--green); }
.ar-dot.push { background:none; box-shadow:inset 0 0 0 2px var(--ink); }
.ar-seg { display:inline-flex; gap:0.1875rem; padding:0.1875rem; background:var(--bg); border:1px solid var(--line); border-radius:var(--r-control); }
.ar-seg button { height:1.875rem; padding:0 0.75rem; border:0; border-radius:var(--r-control); background:none; color:var(--muted); font:700 0.8125rem var(--font-body); cursor:pointer; }
.ar-seg button:hover { color:var(--ink); }
.ar-seg button[aria-pressed=true] { background:var(--selected-bg); color:var(--ink); box-shadow:inset 0 0 0 1px var(--accent); }
.ar-btn { min-height:2.75rem; display:inline-flex; align-items:center; justify-content:center; gap:0.5rem; padding:0 1.125rem; cursor:pointer; text-decoration:none;
  background:var(--surface-raised); color:var(--ink); border:1px solid var(--line); border-radius:var(--r-control); box-shadow:none; font:800 0.9375rem var(--font-body); }
.ar-btn.primary { background:var(--accent); color:var(--accent-ink); }
/* Stacked wordmark, as in the mockup, so the full nav fits at desktop widths. */
html body[data-layout] .app-topbar .app-brand > span:last-child { display:grid; line-height:0.88; font-size:1.375rem; }
html body[data-layout] .app-topbar .app-brand .brand-lab { display:block; margin-left:0; }
html body[data-layout] .app-topbar .notebook-tabs :is(.nav-tab, .tab-group-button, .nav-link) { padding:0 0.875rem; }
/* Seven top-level tabs: on laptops the tabs tighten so the header stays one row (My Picks
   wrapped to a second row at 1210-1366). */
@media (min-width:75.0625em) and (max-width:90em) {
  html body[data-layout][data-layout-mode] .app-topbar .notebook-tabs :is(.nav-tab, .tab-group-button, .nav-link) { padding:0 0.625rem; }
}
@media (min-width:75.0625em) and (max-width:85em) {
  html body[data-layout][data-layout-mode] .app-topbar .notebook-tabs :is(.nav-tab, .tab-group-button, .nav-link) { padding:0 0.3125rem; }
}
html body[data-layout][data-layout-mode] .app-topbar[data-nav-tight] .notebook-tabs :is(.nav-tab, .tab-group-button, .nav-link) { padding:0 0.3125rem; }

/* ------------------------------------------------------------------------------------
   Proposed site (v3): performance colour, motion tokens, and the evidence pieces from
   studio-kit.js. Colour means performance: --good supports the side being viewed,
   --bad works against it, --thin is too little data. Blue (--accent) is only for
   actions and picked prices.
   ------------------------------------------------------------------------------------ */
:root {
  --good: #5fe0a8; --good-bg: #16382c; --bad: #ff7a8a; --bad-bg: #46202c; --thin: #ffd166; --thin-bg: #3b3424;
  --dur-instant: 90ms; --dur-fast: 140ms; --dur-base: 220ms; --dur-slow: 360ms; --dur-hero: 600ms;
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1); --ease-in: cubic-bezier(0.55, 0, 1, 0.45);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); --ease-press: cubic-bezier(0.3, 0, 0.5, 1);
  --spring-soft: linear(0, 0.092, 0.301, 0.545, 0.767, 0.939, 1.052, 1.11, 1.126, 1.114, 1.088, 1.057, 1.029, 1.008, 0.993, 0.986, 0.984, 0.986, 0.989, 0.993, 0.996, 0.999, 1);
  --spring-bouncy: linear(0, 0.132, 0.438, 0.785, 1.074, 1.251, 1.309, 1.271, 1.178, 1.071, 0.98, 0.924, 0.905, 0.915, 0.943, 0.977, 1.005, 1.023, 1.029, 1.027, 1.018, 1.008, 0.999, 0.993, 0.991, 0.992, 0.994, 0.997, 1);
  --stagger: 30ms; --move: 1;
}
@media (prefers-reduced-motion: reduce) {
  :root { --dur-fast: 1ms; --dur-base: 1ms; --dur-slow: 120ms; --dur-hero: 160ms; --stagger: 0ms; --move: 0; }
}
/* Scores are secondary now: the verdict carries the colour. */
.ar-score, .ar-score.is-mid { background: var(--surface-raised); color: var(--ink); }
.ar-score.is-high { background: var(--surface-raised); color: var(--good); }

/* The press (UI-162; the Motion Lab's .press, without the shadow since UI-204). Every
   pressable piece sinks --press-depth (1px) and darkens in 90ms on --ease-press, and comes
   back in 220ms on --spring-soft. Hover lightens the border (pointer devices only). Movement
   is scaled by --move, so with reduced motion the press only darkens.
   tests/press-browser.cjs checks it. Hover and press use !important because pages style the
   resting price with ID selectors (#percentageResults, #studioSurface) and teams.css lifts with
   transform; the press is a momentary state and must always win. */
:is(.pd-button, .ar-btn, .ar-price, .bet-side) {
  transition: translate var(--dur-base) var(--spring-soft), filter var(--dur-base) var(--spring-soft),
    background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out); }
:where(.pd-button, .ar-btn, .ar-price, .bet-side) { --press-depth: 1px; }
@media (hover: hover) {
  html body[data-layout] :is(.pd-button, .ar-btn, .ar-price, .bet-side):not(:disabled):hover {
    border-color: var(--muted); transform: none !important; }
}
html body[data-layout] :is(.pd-button, .ar-btn, .ar-price, .bet-side):not(:disabled):active {
  translate: 0 calc(var(--press-depth) * var(--move)) !important; transform: none !important; filter: brightness(0.86);
  /* Only the press is quick: colours keep their fade. */
  transition: translate var(--dur-instant) var(--ease-press), filter var(--dur-instant) var(--ease-press),
    background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out); }

/* House chart: bars through the line.
   Bars sit in slots from the left, oldest first, with --gap between, then a dashed "this
   week" slot at the line's height. Micro: a slot is --bar-max wide and the frame is as wide
   as its slots, capped at the box. Card and full: the frame fills the box and the slots
   share it evenly, each bar at most --bar-max wide and centred in its slot, so three games
   don't leave the right of the card empty; the week axis spans the same slots. The gutter
   on the right holds the line's label (--gutter). Card and full sizes put the value above
   each bar and week + opponent in an axis under the plot (--axis tall); micro stays bare.
   A value that would sit on the line moves inside the top of its bar (.val-in) or
   just above the line (.val-over); studio-kit.js picks which. */
.ar-chart { position: relative; display: inline-block; vertical-align: middle; --gap: 3px; --gutter: 0rem; --axis: 0rem; }
.ar-chart-micro { width: 7.5rem; height: 1.75rem; --bar-max: 0.875rem; }
.ar-chart-card { width: 100%; height: var(--chart-h); --chart-h: 8.5rem; --bar-max: 2.25rem; --gap: 0.375rem; --gutter: 3rem; --axis: 2rem; }
/* A line of 5+ characters ("245.5"): a gutter wide enough for its label (UI-439). */
:is(.ar-chart-card, .ar-chart-full).is-long-line { --gutter: 3.625rem; }
.ar-chart.is-empty { display: inline-grid; place-items: center; color: var(--muted); font-size: 0.75rem; border: 1px dashed var(--line); border-radius: var(--r-card); }
/* Card and full grow under the plot for the key (below); the frame keeps the chart's height. */
:is(.ar-chart-card, .ar-chart-full):not(.is-empty) { height: auto; container: ar-chart / inline-size; }
:is(.ar-chart-card, .ar-chart-full) :is(.ar-frame, .ar-key) { --frame-h: calc(var(--chart-h) - var(--axis) * var(--listed, 0)); }
:is(.ar-chart-card, .ar-chart-full) .ar-frame { height: var(--frame-h); }
.ar-frame { position: relative; display: block; height: 100%; max-width: 100%;
  width: calc(var(--n) * (var(--bar-max) + var(--gap)) - var(--gap) + var(--gutter)); }
.ar-plot { position: absolute; inset: 0 var(--gutter) calc(var(--axis) * (1 - var(--listed, 0))) 0; border-bottom: 1px solid var(--line); }
.ar-bars, .ar-ticks { display: flex; justify-content: flex-start; gap: var(--gap); }
.ar-bars { position: absolute; inset: 0; align-items: flex-end; }
.ar-slot, .ar-ticks > span { flex: 1 1 0; min-width: 0; max-width: var(--bar-max); }
.ar-slot { position: relative; height: 100%; display: flex; align-items: flex-end; justify-content: center; }
/* The frame sits in a body one pitch wide (.ar-body, below) but spans the chart: it is placed
   on the chart itself, and the key under it keeps the frame's height free (UI-445). */
:is(.ar-chart-card, .ar-chart-full) .ar-frame { position: absolute; top: 0; left: 0; width: 100%; }
:is(.ar-chart-card, .ar-chart-full) :is(.ar-slot, .ar-ticks > span) { max-width: none; }
:is(.ar-chart-card, .ar-chart-full) :is(.ar-bar, .ar-next) { max-width: var(--bar-max); }
.ar-bar { width: 100%; height: var(--h); min-width: 3px; border-radius: 0; background: var(--bad); transform-origin: bottom;
  animation: ar-grow var(--dur-slow) var(--spring-soft) both; animation-delay: calc(var(--i) * var(--stagger)); }
.ar-bar.is-hit { background: var(--good); }
.ar-bar.is-push { background: none; box-shadow: inset 0 0 0 2px var(--thin); }
/* A game with a 0: a short stub on the baseline; its value label reads "0". */
.ar-bar.is-zero { height: max(var(--h), 4px); min-height: 4px; }
@keyframes ar-grow { from { transform: scaleY(calc(1 - var(--move))); } }
/* The value above each bar (card and full), centred in its pitch: the slot plus half the
   gap each side, a size container (UI-439) so the value can tell when it no longer fits. */
.ar-pitch { position: absolute; top: 0; bottom: 0; left: calc(var(--gap) / -2); right: calc(var(--gap) / -2); pointer-events: none; }
:is(.ar-chart-card, .ar-chart-full) .ar-pitch { container: ar-pitch / inline-size; }
.ar-val { position: absolute; z-index: 1; left: 50%; bottom: calc(var(--h) + 1px); translate: -50% 0; padding: 1px 2px; border-radius: var(--r-data); background: var(--surface); color: var(--ink); font: 700 0.75rem/1 var(--font-mono); white-space: nowrap; }
/* Just under the line: inside the top of the bar, dark on the bar's colour. */
.ar-slot.val-in .ar-val { bottom: auto; top: calc(100% - var(--h) + 2px); background: none; color: var(--accent-ink); }
/* Just under the line with no room inside (or a push on it): above the line. */
.ar-slot.val-over .ar-val { bottom: calc(var(--at) + 4px); }
.ar-chart-micro .ar-val { display: none; }
/* This week: an outline at the line's height, the number he needs. */
/* No dashed top: the line closes the slot, so the dashes never sit on the line and hide it (UI-457). */
.ar-next { width: 100%; height: var(--h); min-height: 4px; border: 2px dashed var(--muted); border-block: 0; border-radius: 0; background: color-mix(in srgb, var(--ink) 6%, transparent); }
.ar-chart-micro .ar-next { border-width: 1px; }
/* Week and opponent under each slot (card and full); this week in the accent. Each sits in a
   pitch (its slot plus half the gap each side, as the values above do), so the rules below
   can tell how much room a label has before it meets the next one (UI-439). */
.ar-ticks { position: absolute; left: calc(var(--gap) / -2); right: calc(var(--gutter) - var(--gap) / 2); bottom: 0; height: var(--axis); padding-top: 0.25rem; gap: 0; }
.ar-ticks > span { container-type: inline-size; display: grid; justify-items: center; align-content: start; overflow: visible; white-space: nowrap; color: var(--muted); font: 600 0.6875rem/1.25 var(--font-body); }
.ar-ticks b { color: var(--ink); font: 700 0.6875rem/1.2 var(--font-mono); }
.ar-ticks i { font-style: normal; }
/* Too narrow for "@NYG" (10+ games in a small card): the week stays, the tooltip names him. */
@container (max-width: 2.375rem) { .ar-ticks i { display: none; } }
.ar-ticks .is-next, .ar-ticks .is-next b { color: var(--accent); }
/* Too narrow for the week too, "W3" (about 0.86rem) or "W12" (ar-ww-3, about 1.22rem): the
   key below names the weeks. It shows at these pitches and wider (1.25rem, 1.375rem), so a
   chart never loses its weeks without the key. */
@container (max-width: 1rem) { .ar-ticks b { display: none; } }
@container (max-width: 1.375rem) { .ar-ww-3 .ar-ticks b { display: none; } }
/* Large text (UI-439). Every unit here is a rem, the page's text size, so at the default size
   these hold only for a chart squeezed past what it can draw (10+ games in a narrow card).
   1. Under 10rem wide, the chart drops the gutter and the line's label (it was a third of
      the chart and more) and names the line in the key instead: "Line 19.5".
   2. When a game's pitch is too narrow for its value (the widest value's length is ar-vw-N;
      a digit is about 0.39rem, plus the label's padding and a little room), the values over
      the bars go and the key lists every game instead: "W3 @DEN 22", oldest first like the
      bars, each with its result's colour, then this week. The frame and the key sit in a body
      that is a size container one pitch wide (the plot plus a gap, over the slot count), so
      its query sees what a value does; the list then spans the chart (--n pitches, less a
      gap, plus the gutter), and the frame is placed on the chart itself. A pitch too narrow for the week under its bar
      always gets the key (1.25rem; ar-ww-3 1.375rem).
   3. While the list shows, it carries every week and opponent, so the week row under the
      bars goes and the frame closes up over it (--listed, UI-445); the plot keeps its height. */
.ar-body { display: block; width: calc((100% - var(--gutter) + var(--gap)) / var(--n, 1)); container: ar-key / inline-size; }
/* Listed, the key also clears the line's tag, which hangs half under a line at the baseline. */
.ar-key { display: block; padding-top: calc(var(--frame-h) + var(--listed, 0) * 0.3125rem); }
.ar-key-games { display: none; width: calc(var(--n, 1) * 100cqi - var(--gap) + var(--gutter)); margin-top: 0.375rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 6.25rem), 1fr)); gap: 0.125rem 0.75rem; color: var(--muted); font: 600 0.75rem/1.35 var(--font-body); }
.ar-key-games > span { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.25rem; min-width: 0; overflow-wrap: anywhere; }
.ar-key-games > span::before { content: ""; flex: none; align-self: center; width: 0.5rem; height: 0.5rem; background: var(--bad); }
.ar-key-games > .ar-key-hit::before { background: var(--good); }
.ar-key-games > .ar-key-push::before { background: none; box-shadow: inset 0 0 0 2px var(--thin); }
.ar-key-games > .ar-key-next::before { background: none; box-shadow: inset 0 0 0 1px var(--muted); }
.ar-key-games b { color: var(--ink); font: 700 0.75rem/1.35 var(--font-mono); }
.ar-key-games i { font-style: normal; }
.ar-key-games i:empty { display: none; }
.ar-key-games strong { margin-left: auto; color: var(--ink); font: 700 0.75rem/1.35 var(--font-mono); }
.ar-key-games > .ar-key-next, .ar-key-games > .ar-key-next :is(b, strong) { color: var(--accent); }
.ar-key-line { display: none; width: max-content; max-width: calc(var(--n, 1) * 100cqi - var(--gap)); margin-top: 0.375rem; color: var(--muted); font: 600 0.75rem/1.35 var(--font-body); }
.ar-key-line strong { padding: 0 0.3125rem; border-radius: var(--r-data); background: var(--ink); color: var(--bg); font: 900 0.875rem/1.35 var(--font-mono); }
@container ar-chart (max-width: 10rem) {
  .ar-body { --gutter: 0rem; }
  .ar-line-label { display: none; }
  .ar-key-line { display: block; }
}
@container ar-pitch (max-width: 1.25rem) { .ar-val { display: none; } }
@container ar-key (max-width: 1.25rem) { .ar-key-games { display: grid; }
  .ar-ticks { display: none; } :is(.ar-frame, .ar-key) { --listed: 1; } }
@container ar-pitch (max-width: 1.375rem) { .ar-ww-3 .ar-val { display: none; } }
@container ar-key (max-width: 1.375rem) { .ar-ww-3 .ar-key-games { display: grid; }
  .ar-ww-3 .ar-ticks { display: none; } .ar-ww-3 :is(.ar-frame, .ar-key) { --listed: 1; } }
@container ar-pitch (max-width: 1.52rem) { :is(.ar-vw-3, .ar-vw-4, .ar-vw-5, .ar-vw-6) .ar-val { display: none; } }
@container ar-key (max-width: 1.52rem) { :is(.ar-vw-3, .ar-vw-4, .ar-vw-5, .ar-vw-6) .ar-key-games { display: grid; }
  :is(.ar-vw-3, .ar-vw-4, .ar-vw-5, .ar-vw-6) .ar-ticks { display: none; } :is(.ar-vw-3, .ar-vw-4, .ar-vw-5, .ar-vw-6) :is(.ar-frame, .ar-key) { --listed: 1; } }
@container ar-pitch (max-width: 1.91rem) { :is(.ar-vw-4, .ar-vw-5, .ar-vw-6) .ar-val { display: none; } }
@container ar-key (max-width: 1.91rem) { :is(.ar-vw-4, .ar-vw-5, .ar-vw-6) .ar-key-games { display: grid; }
  :is(.ar-vw-4, .ar-vw-5, .ar-vw-6) .ar-ticks { display: none; } :is(.ar-vw-4, .ar-vw-5, .ar-vw-6) :is(.ar-frame, .ar-key) { --listed: 1; } }
@container ar-pitch (max-width: 2.3rem) { :is(.ar-vw-5, .ar-vw-6) .ar-val { display: none; } }
@container ar-key (max-width: 2.3rem) { :is(.ar-vw-5, .ar-vw-6) .ar-key-games { display: grid; }
  :is(.ar-vw-5, .ar-vw-6) .ar-ticks { display: none; } :is(.ar-vw-5, .ar-vw-6) :is(.ar-frame, .ar-key) { --listed: 1; } }
@container ar-pitch (max-width: 2.69rem) { .ar-vw-6 .ar-val { display: none; } }
@container ar-key (max-width: 2.69rem) { .ar-vw-6 .ar-key-games { display: grid; }
  .ar-vw-6 .ar-ticks { display: none; } .ar-vw-6 :is(.ar-frame, .ar-key) { --listed: 1; } }
/* The line, drawn as a yard line (UI-204): solid, with short hash marks hanging under it, and
   its number in a square tag just past the right end, by this week. */
.ar-line { position: absolute; left: 0; right: 0; bottom: var(--at); border-top: 2px solid var(--ink); pointer-events: none; --hash: 0.5rem; --hash-gap: 1rem; }
.ar-line::after { content: ""; position: absolute; left: 0; right: 0; top: 0; height: var(--hash); opacity: 0.45;
  background: repeating-linear-gradient(90deg, var(--ink) 0 2px, transparent 2px var(--hash-gap)); }
.ar-chart-micro .ar-line { --hash: 0.25rem; --hash-gap: 0.5rem; }
.ar-line-label { position: absolute; left: calc(100% + 0.25rem); top: -1px; translate: 0 -50%; padding: 0 0.3125rem; border-radius: var(--r-data); background: var(--ink); color: var(--bg); font: 900 0.9375rem/1.35 var(--font-mono); white-space: nowrap; }
.ar-chart-micro .ar-line-label { display: none; }

/* The four signals. */
.ar-signals { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.3125rem; }
/* A long chip ("Matchup WR1s fell short of 42.5 in 3 of 3") wraps inside its row on a phone
   rather than running past the card. */
.ar-sig { display: inline-flex; align-items: center; gap: 0.3125rem; height: auto; min-height: 1.625rem; max-width: 100%; min-width: 0; padding: 0.1875rem 0.5rem; border-radius: var(--r-data);
  background: var(--surface-raised); color: var(--muted); font-size: 0.75rem; font-weight: 700; line-height: 1.25; white-space: normal; overflow-wrap: break-word; }
/* The title stays whole; the stat after it is what wraps. */
.ar-sig > .ar-sig-title { flex: none; }
.ar-sig-stat { min-width: 0; font-family: var(--font-mono); color: var(--ink); }
.ar-sig.tone-for { background: var(--good-bg); color: var(--good); } .ar-sig.tone-for .ar-sig-stat { color: var(--good); }
.ar-sig.tone-against { background: var(--bad-bg); color: var(--bad); } .ar-sig.tone-against .ar-sig-stat { color: var(--bad); }
/* Thin data: no fill and a dashed outline, so it never reads as Neutral's solid grey chip by colour
   alone (UI-462). */
.ar-sig.tone-thin { background: none; outline: 1px dashed var(--thin); outline-offset: -1px; color: var(--thin); }
/* UI-729: the "who's out" chips beside Context: shown, never counted. Outlined in the tone's
   colour with no fill, the name in ink, and a minus or plus mark, so they can't be taken for a
   counted chip (a filled block with no mark). Grey with no mark where the direction isn't
   settled (interception props). */
/* The transparent outline is the edge in forced-colors mode, where box-shadow is dropped. */
.ar-sig.ar-sig-out { background: none; box-shadow: inset 0 0 0 1px var(--line); outline: 1px solid transparent; outline-offset: -1px; color: var(--muted); }
.ar-sig.ar-sig-out.tone-for { color: var(--good); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--good) 55%, transparent); }
.ar-sig.ar-sig-out.tone-against { color: var(--bad); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--bad) 55%, transparent); }
.ar-sig.ar-sig-out:is(.tone-for, .tone-against, .tone-neutral) .ar-sig-stat { color: var(--ink); }
.ar-sig-mark { margin-right: 0.25rem; font-family: var(--font-mono); font-weight: 900; }
/* The same people in the Why row: one line a chip, its mark in its colour. */
.ar-sig-out-line { display: block; }
.ar-sig-out-line.tone-for .ar-sig-mark { color: var(--good); } .ar-sig-out-line.tone-against .ar-sig-mark { color: var(--bad); }
.ar-signal-rows { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.375rem; }
.ar-sig-row { display: grid; grid-template-columns: 1rem 5.5rem minmax(0, 1fr) auto; gap: 0.5rem; align-items: baseline; padding: 0.5rem 0.625rem;
  border-radius: var(--r-control); background: var(--surface-raised); font-size: 0.875rem; }
.ar-sig-row .ar-sig-title { font-weight: 800; }
.ar-sig-row .ar-sig-tone { font-size: 0.75rem; color: var(--muted); }
.ar-sig-row.tone-for { background: var(--good-bg); } .ar-sig-row.tone-for :is(.ar-sig-glyph, .ar-sig-tone) { color: var(--good); }
.ar-sig-row.tone-against { background: var(--bad-bg); } .ar-sig-row.tone-against :is(.ar-sig-glyph, .ar-sig-tone) { color: var(--bad); }
.ar-sig-row.tone-thin :is(.ar-sig-glyph, .ar-sig-tone) { color: var(--thin); }
/* The Why row's tone dot (UI-462: no ✓/✕ marks, colour carries it; the row also says it in words):
   filled green, red or grey, and a dashed ring for thin data. */
.ar-sig-glyph { width: 0.5rem; height: 0.5rem; align-self: center; border-radius: 50%; background: currentColor; color: var(--muted); }
.ar-sig-row.tone-thin .ar-sig-glyph { background: none; border: 1px dashed currentColor; box-sizing: border-box; }
/* "Supports the Under" keeps its own case wherever a tile capitalises the tone. */
.ar-sig-tone-words { text-transform: none; }
/* The price in the Context row: plain information, not a signal. */
.ar-sig-note { display: block; margin-top: 0.125rem; font-size: 0.75rem; color: var(--muted); font-family: var(--font-mono); }
/* Fact rows rise 40ms apart, 60ms after their Why starts to open (the Motion Lab's offset). */
.ar-sig-row { animation: ar-rise var(--dur-base) var(--ease-out) both; animation-delay: calc((60ms + var(--i, 0) * 40ms) * var(--move)); }
@keyframes ar-rise { from { opacity: 0; translate: 0 calc(4px * var(--move)); } }
@media (max-width: 40em) { .ar-sig-row { grid-template-columns: 1rem minmax(0, 1fr); } .ar-sig-row .ar-sig-text { grid-column: 2; }
  /* The ✓ / ✕ mark carries it on screen; screen readers still hear "supports the Under". */
  .ar-sig-row:not(.pp-why .ar-sig-row) .ar-sig-tone { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } }

/* Verdict chip: stamps in once. */
.ar-verdict { display: inline-flex; align-items: center; height: 1.625rem; padding: 0 0.625rem; border-radius: var(--r-data); font-weight: 800; font-size: 0.8125rem; white-space: nowrap;
  animation: ar-stamp var(--dur-slow) var(--spring-bouncy) both; }
.ar-verdict.v-strong { background: var(--good); color: var(--accent-ink); }
.ar-verdict.v-lean { color: var(--good); box-shadow: inset 0 0 0 2px var(--good); }
/* UI-872: Thin data is "nothing to say yet", so it stays quiet beside real plays: muted text in a
   1px dashed outline (Neutral is a solid 2px ring, so the two never read alike), not loud gold. */
.ar-verdict.v-thin { color: var(--muted); font-weight: 700; box-shadow: none; outline: 1px dashed var(--muted); outline-offset: -1px; }
.ar-verdict.v-against { color: var(--bad); box-shadow: inset 0 0 0 2px var(--bad); }
.ar-verdict.v-neutral { color: var(--muted); box-shadow: inset 0 0 0 2px var(--line); }
/* A Play Score's decimal just under a cut (LOGIC-62, StudioKit.scoreHtml): small, so a badge keeps its two-digit width. */
.ar-score-decimal { font-size: 0.55em; }
@keyframes ar-stamp { from { opacity: 0; scale: calc(1 + 0.4 * var(--move)); rotate: calc(-4deg * var(--move)); } }
/* The reason after the stamp (UI-169, the Motion Lab's verdict reveal): verdict first, then
   its one-line reason rises 6px (220ms), starting as the stamp lands (140ms + 60ms). The
   reason classes take it in percentage-plays.css (.percentage-headline), slate.css
   (.slate-play-headline) and today.css (.today-card-why); they play once like the stamp and
   never under reduced motion. */
@keyframes ar-reason { from { opacity: 0; translate: 0 calc(6px * var(--move)); } }

/* Matchup chip: Soft / Neutral / Tough, reused wherever a matchup appears. */
.ar-mu { display: inline-flex; align-items: center; gap: 0.25rem; height: 1.375rem; padding: 0 0.4375rem; border-radius: var(--r-data); font-size: 0.6875rem; font-weight: 800; white-space: nowrap; }
.ar-mu b { font-family: var(--font-mono); font-weight: 700; }
.ar-mu.band-soft { background: var(--good-bg); color: var(--good); }
.ar-mu.band-tough { background: var(--bad-bg); color: var(--bad); }
.ar-mu.band-neutral { background: var(--surface-raised); color: var(--muted); }
/* StudioKit.muChip adds the side's tone: the colour says whether the band helps the bet
   shown (a Tough defense behind an Under is green). Chips without a tone keep the band's. */
.ar-mu.mu-for { background: var(--good-bg); color: var(--good); }
.ar-mu.mu-against { background: var(--bad-bg); color: var(--bad); }
.ar-mu.mu-neutral { background: var(--surface-raised); color: var(--muted); }

/* A tappable rank chip (UI-244, muChip's open): the same chip in a bare button that opens
   the rank journey. The button's padding grows the tap area to 2.75rem without moving the
   chip (the negative margin gives the space back); a chevron says it opens. */
.ar-mu-open { display:inline-flex; align-items:center; margin:-0.6875rem 0; padding:0.6875rem 0; border:0; background:none; color:inherit; font:inherit; line-height:1; cursor:pointer; vertical-align:middle; }
.ar-mu-open .ar-mu::after { content:"›" / ""; margin-left:0.0625rem; font-size:0.875rem; line-height:1; opacity:0.75; }
.ar-mu-open:hover .ar-mu { box-shadow:inset 0 0 0 1px currentColor; }
.ar-mu-open:focus-visible { outline:none; }
.ar-mu-open:focus-visible .ar-mu { outline:2px solid var(--accent); outline-offset:2px; }

/* The rank journey dialog (#rankJourneyDialog): the Teams rankings dialog's frame and table
   (.team-rank-dialog, .team-rank-table in teams.css), a Season / Last 4 switcher, team
   buttons in the rows, and a games step with Back. */
.ar-rank-dialog .dialog-heading > div { min-width:0; }
.ar-rank-back { display:inline-flex; align-items:center; min-height:2.75rem; margin:-0.5rem 0 0; padding:0; border:0; background:none; color:var(--accent); font:800 0.8125rem var(--font-body); cursor:pointer; }
.ar-rank-window { display:inline-flex; align-self:flex-start; gap:0.25rem; margin:0 0 0.75rem; padding:0.1875rem; border:1px solid var(--line); border-radius:var(--r-data); background:var(--surface-raised); }
.ar-rank-window-btn { min-height:2.25rem; padding:0 0.875rem; border:0; border-radius:var(--r-data); background:none; color:var(--muted); font:800 0.75rem var(--font-body); cursor:pointer; }
.ar-rank-window-btn[aria-pressed="true"] { background:var(--surface); color:var(--ink); box-shadow:0 0 0 1px var(--line); }
.ar-rank-badge { display:inline-flex; align-items:center; justify-content:center; min-width:2.75rem; height:1.375rem; padding:0 0.375rem; border-radius:var(--r-data); font:700 0.75rem var(--font-mono); white-space:nowrap; background:var(--surface-raised); color:var(--muted); }
.ar-rank-badge.mu-for { background:var(--good-bg); color:var(--good); }
.ar-rank-badge.mu-against { background:var(--bad-bg); color:var(--bad); }
.ar-rank-team { display:inline-flex; align-items:center; min-height:2.75rem; padding:0; border:0; background:none; color:var(--accent); font:inherit; font-weight:800; text-align:left; cursor:pointer; }
.ar-rank-table tr.is-current { background:var(--surface-raised); }
#rankJourneyDialog .ar-rank-table :is(th, td) { padding-block:0; }
.ar-rank-table tr.is-current .ar-rank-team { color:var(--ink); }
/* minmax(0, 1fr) on both lists: a long player name ellipsizes instead of widening the card past the dialog. */
.ar-rank-games { display:grid; grid-template-columns:minmax(0, 1fr); gap:0.75rem; min-height:0; margin:0; padding:0 0.125rem 0.25rem 0; overflow-y:auto; list-style:none; }
.ar-rank-game { padding:0.75rem; border:1px solid var(--line); border-radius:var(--r-data); background:var(--surface-raised); }
.ar-rank-game-head { display:flex; align-items:center; justify-content:space-between; gap:0.75rem; }
.ar-rank-game-head p { display:flex; flex-wrap:wrap; align-items:baseline; gap:0 0.625rem; min-width:0; margin:0; }
.ar-rank-game-head span { color:var(--muted); font-size:0.8125rem; white-space:nowrap; }
.ar-rank-game-head b { color:var(--ink); font-family:var(--font-mono); }
.ar-rank-box { flex:none; min-height:2.25rem; padding:0 0.75rem; font-size:0.75rem; }
.ar-rank-players { display:grid; grid-template-columns:minmax(0, 1fr); gap:0; margin:0.375rem 0 0; padding:0; list-style:none; }
.ar-rank-players li { display:flex; align-items:center; justify-content:space-between; gap:0.75rem; border-top:1px solid var(--line); }
.ar-rank-players li > span { font-family:var(--font-mono); font-size:0.8125rem; }
.ar-rank-player { min-width:0; min-height:2.5rem; padding:0; overflow:hidden; border:0; background:none; color:var(--accent); font:700 0.8125rem var(--font-body); text-align:left; text-overflow:ellipsis; white-space:nowrap; cursor:pointer; }
.ar-rank-note { margin:0.375rem 0 0; color:var(--muted); font-size:0.75rem; }
.ar-rank-empty { margin:0.5rem 0; }
/* UI-641: only controls point; the vs-line rows are one target each. The row's team button
   stretches over the row (::after), so hover and keyboard focus light the whole row. */
#rankJourneyDialog { cursor:default; }
.ar-rank-rows tbody tr { position:relative; transition:background-color var(--dur-fast) var(--ease-out); }
.ar-rank-rows .ar-rank-team::after { content:""; position:absolute; inset:0; }
.ar-rank-rows .ar-rank-team:focus-visible { outline:none; }
.ar-rank-rows tbody tr:is(:hover, :has(.ar-rank-team:focus-visible)) { background:color-mix(in srgb, var(--accent) 10%, var(--surface-raised)); }
.ar-rank-rows tbody tr:has(.ar-rank-team:focus-visible) { outline:2px solid var(--accent); outline-offset:-2px; }
.ar-rank-rows tbody tr:is(:hover, :has(.ar-rank-team:focus-visible)) .ar-rank-team { color:var(--ink); }
.ar-rank-line-nums { display:grid; flex:none; grid-template-columns:4.75rem 2.75rem 6.25rem; align-items:baseline; gap:0.5rem; text-align:right; }
.ar-rank-line-at { color:var(--muted); font-size:0.75rem; }
.ar-rank-line-nums b { color:var(--ink); }
.ar-rank-verdict { font-size:0.75rem; font-weight:700; white-space:nowrap; }
.ar-rank-line.is-beat .ar-rank-verdict { color:var(--good); }
.ar-rank-line.is-missed .ar-rank-verdict { color:var(--bad); }
.ar-rank-line:is(.is-push, .is-pending) .ar-rank-verdict { color:var(--muted); }
.ar-rank-line.is-unlined :is(.ar-rank-player, b) { color:var(--muted); font-weight:600; }
.ar-rank-foot { display:flex; justify-content:flex-end; margin-top:0.75rem; }
.ar-rank-full { min-height:2.5rem; padding:0 0.875rem; font-size:0.75rem; }
@media (max-width:30em) {
  #rankJourneyDialog .team-rank-full { display:none; }
  #rankJourneyDialog .team-rank-table :is(th, td) { padding-inline:0.375rem; }
  .ar-rank-game { padding:0.625rem; }
  .ar-rank-line-nums { grid-template-columns:auto 2.25rem 5.25rem; gap:0.375rem; }
}

/* Live pick progress. */
.ar-progress { position: relative; display: block; height: 0.5rem; border-radius: var(--r-data); background: var(--surface-raised); overflow: hidden; }
.ar-progress-fill { position: absolute; inset: 0 auto 0 0; border-radius: 0; background: var(--good); transition: width var(--dur-base) var(--ease-out), background-color var(--dur-base) var(--ease-out); }
.ar-progress.is-behind .ar-progress-fill { background: var(--thin); }
.ar-progress.is-lost .ar-progress-fill { background: var(--bad); }

/* The season loader reveals these only after 300ms. The status is announced once;
   the placeholder lines are decorative and never imply saved results. */
.ar-skeleton { display:grid; gap:0.75rem; padding:1.25rem; border:1px solid var(--line); border-radius:var(--r-card); background:var(--surface); }
.ar-skeleton > span { display:block; height:1rem; width:100%; border-radius:var(--r-data); background:var(--surface-raised); animation:ar-skeleton-fade var(--dur-hero) var(--ease-out) infinite alternate; }
.ar-skeleton > span:first-child { width:45%; height:1.5rem; }
.ar-skeleton > span:last-child { width:70%; }
@keyframes ar-skeleton-fade { from { opacity:0.45; } to { opacity:1; } }
@media (prefers-reduced-motion: reduce) {
  .ar-progress-fill { transition:none; }
  .ar-skeleton > span { animation:none; }
}

/* Why layer: opens with height, no measuring. */
.ar-why { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--dur-base) var(--ease-out); }
/* Clip the expanding contents without making a scrollbox: focusing/clicking a link
   during the opening must not scroll its content underneath the pointer. Unlike hidden,
   clip keeps min-height:auto, so the 0fr row needs min-height:0 to collapse (UI-256). */
.ar-why > * { overflow: clip; min-height: 0; }
.ar-why.is-open { grid-template-rows: 1fr; }
/* Closed, its buttons and links leave the Tab order (and screen readers); the delay keeps
   them painted while the close animation runs. Open, it inherits rather than forcing
   visible, so an open Why inside a closed one (or any hidden ancestor) stays out of the
   Tab order too (UI-224). */
.ar-why:not(.is-open) > * { visibility: hidden; transition: visibility 0s var(--dur-base); }
.ar-why.is-open > * { visibility: inherit; transition-delay: 0s; }

/* A line that moved since you saved it: one quiet glow. */
.ar-moved { animation: ar-flash 800ms var(--ease-out); }
@keyframes ar-flash { from { background-color: rgb(111 164 224 / 0.35); } }
@media (prefers-reduced-motion: reduce) { .ar-moved { animation:none; } }

/* Reveal motion plays once (UI-163), as in the Motion Lab: when an element first appears,
   never again when its tab or panel is shown again (display: none and back restarts every
   CSS animation). studio-motion.js marks a revealed element .ar-played when its rise, grow,
   stamp or glow ends. Renderers that redraw the same content mark the container
   .ar-settled, so the redrawn charts and chips keep still (Today; Slate keeps .is-settled
   and Props data-motion=off). New content is new elements in an unsettled container, and
   plays. */
.ar-played:not(.just-picked), .ar-settled :is(.ar-bar, .ar-verdict, .ar-sig-row, .ar-moved, .ar-dot) { animation: none !important; }

/* Panels arrive with a short rise; never on re-sort (renderers opt in with .ar-enter). A
   panel rises each time a tab switch shows it (UI-167, as in the Motion Lab's tabs), so it has
   its own keyframes, which studio-motion.js doesn't mark .ar-played. Showing the tab that's
   already open doesn't hide the panel, so it stays still. Its content still plays once. */
:is(.nav-panel, [role=tabpanel]):not([hidden]) { animation: ar-panel-rise var(--dur-base) var(--ease-out); }
@keyframes ar-panel-rise { from { opacity: 0; translate: 0 calc(6px * var(--move)); } }
.ar-enter > * { animation: ar-rise var(--dur-base) var(--ease-out) both; animation-delay: calc(var(--i, 0) * 40ms * var(--move)); }
@media (prefers-reduced-motion: reduce) {
  .ar-bar, .ar-verdict, .ar-sig-row, .ar-enter > *,:is(.nav-panel, [role=tabpanel]):not([hidden]) { animation: none; }
}

/* Hit dots pop in (UI-168): the first time a row of .ar-dots scrolls into view, its dots pop
   one after another, --stagger (30ms) apart. studio-motion.js watches the rows: it adds
   html.ar-dots-watch, which keeps every dot at scale 0 until its row is seen (.ar-seen, with
   --i set on each dot in the same step), and marks a dot .ar-played when its pop ends or is
   cut short (a tab hidden mid-pop), so a tab shown again doesn't replay it. The pop is only
   created once the row is seen: a paused pop whose delay changes as it starts ends at once
   in Chromium. A row redrawn in the same place with the same dots keeps still. No watching
   with reduced motion (or without IntersectionObserver): the dots just show. */
html.ar-dots-watch .ar-dots:not(.ar-seen) .ar-dot { scale: 0; }
html.ar-dots-watch .ar-dots.ar-seen .ar-dot { animation: ar-dot-pop var(--dur-slow) var(--spring-bouncy) both; animation-delay: calc(var(--i, 0) * var(--stagger)); }
@keyframes ar-dot-pop { from { scale: calc(1 - var(--move)); } }
@media (prefers-reduced-motion: reduce) { html.ar-dots-watch .ar-dot { scale: none !important; animation: none !important; } }

/* ---- Weather badge popover (UI-366) ----------------------------------------------------
   compactWeather's badge (game-context.js) is a button where it has forecast facts: hover,
   keyboard focus or a tap shows them in a popover in the top layer, placed under the badge by
   game-context.js, so nothing on the page moves. The button keeps the badge's own layout. */
html body .studio-weather.has-details>.studio-weather-trigger { display:inherit; flex-wrap:inherit; align-items:inherit; gap:inherit; min-width:0; max-width:100%;
  margin:0; padding:0; border:0; border-radius:var(--r-control); background:none; box-shadow:none; color:inherit; font:inherit; letter-spacing:inherit; text-align:start; text-transform:none; cursor:pointer; }
html body .studio-weather.has-details>.studio-weather-trigger:focus-visible { outline:2px solid var(--accent); outline-offset:3px; }
@media (hover:hover) { html body .studio-weather.has-details>.studio-weather-trigger:hover .studio-weather-copy>strong { color:var(--accent); } }
.studio-weather-copy>.studio-weather-stale { color:var(--thin); font-weight:700; }
/* Hidden where popovers are unknown (the badge still reads on its own). */
html body .studio-weather-pop { display:none; }
html body .studio-weather-pop:popover-open { display:block; position:fixed; inset:auto; z-index:95; margin:0; box-sizing:border-box; width:max-content; max-width:min(20rem, calc(100vw - 1rem));
  padding:0.625rem 0.75rem; overflow:visible; background:var(--surface-raised); color:var(--ink); border:1px solid var(--line); border-radius:var(--r-card); box-shadow:0 8px 24px rgb(0 0 0 / 0.35);
  font:400 0.8125rem/1.45 var(--font-body); letter-spacing:0; text-transform:none; white-space:normal; text-align:start; }
/* The forecast facts: the popover above and Fantasy Start/Sit's weather panel. */
.weather-facts { display:grid; grid-template-columns:max-content minmax(0, 1fr); gap:0.25rem 0.75rem; margin:0; min-width:0; }
.weather-facts>div { display:contents; }
.weather-facts dt { color:var(--muted); }
.weather-facts dd { min-width:0; margin:0; color:var(--ink); overflow-wrap:anywhere; }
.weather-facts a { color:var(--ink); text-decoration:underline; text-underline-offset:3px; }
.weather-facts a:focus-visible { outline:2px solid var(--accent); outline-offset:3px; border-radius:2px; }

/* ---- Glossary tooltips (UI-350) ---------------------------------------------------------
   StudioKit.term / termAttrs mark a term with a faint dotted underline; the one shared #arTip
   (studio-kit.js tooltip) shows its definition above it, or below where there's no room,
   placed through --tip-x / --tip-y. A long-press on a term is the tooltip's, not the
   browser's callout. Hidden until the tooltip opens it (class is-open, plus the popover). */
html body .ar-term, html body [data-term] { text-decoration:underline dotted color-mix(in srgb, currentColor 55%, transparent); text-decoration-thickness:1px; text-underline-offset:0.2em; -webkit-touch-callout:none; }
/* A verdict chip carries its verdict.<key> term (UI-546); its box already marks it, so no underline (signal chips use data-tip and have none either). */
html body .ar-verdict[data-term] { text-decoration:none; }
html body .ar-term { cursor:help; border-radius:var(--r-data); }
html body .ar-term:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
html body .ar-tip { display:none; }
html body .ar-tip.is-open { display:block; position:fixed; inset:auto; left:var(--tip-x, 8px); top:var(--tip-y, 8px); z-index:96; margin:0; box-sizing:border-box;
  width:max-content; max-width:min(22rem, calc(100vw - 16px)); padding:0.5rem 0.625rem; overflow:visible;
  background:var(--surface-strong); color:var(--ink); border:1px solid var(--line); border-radius:var(--r-control); box-shadow:0 8px 24px rgb(0 0 0 / 0.35);
  font:400 0.8125rem/1.4 var(--font-body); letter-spacing:0; text-transform:none; text-align:start; white-space:normal; overflow-wrap:break-word;
  animation:ar-tip-in var(--dur-fast) var(--ease-out); }
@media (max-width:600px) { html body .ar-tip.is-open { max-width:90vw; } }
@keyframes ar-tip-in { from { opacity:0; } }
@media (prefers-reduced-motion: reduce) { html body .ar-tip.is-open { animation:none; } }
