/* Player page (studio-player-page.js), PS-05 / PS-06. Arcade kit (.ar-card, .ar-verdict,
   .ar-mu, .ar-signal-rows, .ar-bar) plus page-only pieces, all prefixed pp-.
   Colour means performance: --good supports the side being viewed, --bad works against it,
   --thin is too little data; blue (--accent) only for actions and picked prices. */
.pp { display:grid; gap:1.25rem; padding:0.25rem 0 1.25rem; min-width:0; }
.pp h1, .pp h2 { margin:0; font-family:var(--font-display); font-weight:800; letter-spacing:0; }
.pp h2 { font-size:1.375rem; line-height:1.15; }
.pp .empty-state { margin:0; }
.pp-sub { color:var(--muted); font-size:0.75rem; font-weight:600; }
.pp-mono { font:700 0.8125rem var(--font-mono); color:var(--muted); }
.pp-note { margin:0; color:var(--muted); font-size:0.8125rem; }
.pp-link { padding:0; border:0; background:none; color:var(--accent); font:800 0.8125rem var(--font-body); cursor:pointer; text-align:left; text-decoration:underline; text-underline-offset:3px; }
.pp-link:hover { color:var(--ink); }
.pp :is(button, a, [tabindex]):focus-visible { outline:3px solid var(--accent); outline-offset:2px; }
.pp-empty { display:grid; gap:0.75rem; justify-items:start; padding:1.5rem; }
.pp .ar-card { border-radius:var(--r-card); box-shadow:none; min-width:0; }
.pp-logo.team-logo-badge { width:1.375rem; height:1.375rem; vertical-align:middle; margin:0 0.25rem 0 0.125rem; font-size:0.5rem; }

/* The page brings its own heading (breadcrumb + header). */
html body[data-layout][data-active-view=player] .page-heading { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }

/* "← Back to Props" (UI-333): above the page when a profile was opened from another page. */
.pp-back { display:inline-flex; align-items:center; gap:0.375rem; min-height:2.25rem; margin:0.25rem 0 0.25rem; padding:0.25rem 0.875rem 0.25rem 0.625rem; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); color:var(--ink); font:800 0.8125rem var(--font-body); cursor:pointer; }
.pp-back:hover { border-color:var(--accent); color:var(--accent); }
.pp-back:focus-visible { outline:3px solid var(--accent); outline-offset:2px; }
@media (pointer: coarse) { .pp-back { min-height:2.75rem; } }

/* Breadcrumb */
.pp-crumbs { display:flex; flex-wrap:wrap; align-items:center; gap:0.5rem; font-size:0.8125rem; font-weight:600; color:var(--muted); }
.pp-crumb, .pp-crumbs a { padding:0; border:0; background:none; color:var(--muted); font:inherit; text-decoration:underline; text-underline-offset:3px; cursor:pointer; }
.pp-crumb:hover, .pp-crumbs a:hover { color:var(--accent); }
.pp-crumbs [aria-current] { color:var(--ink); font-weight:800; }

/* Header: who, the prop switcher and Share this prop */
.pp-head { display:grid; grid-template-columns:auto minmax(0, 1fr) auto; gap:1rem 1.25rem; align-items:center; }
.pp-photo { width:5.5rem; height:5.5rem; }
/* The photo's top rule takes his position's colour, as player cards do (UI-442). The photo
   carries data-position (UI-444), so it reads arcade.css's --position-color, K and DEF
   included; the pp-tone-* classes stay as hooks. Any other position stays neutral. */
.pp-tone-default { --tone:var(--line); }
.pp-photo[data-position] { --tone:var(--position-color); }
.pp-photo .player-avatar { width:100%; height:100%; display:grid; place-items:center; overflow:hidden; position:relative; box-sizing:border-box;
  background:var(--surface-raised); color:var(--ink); border:1px solid var(--line); border-top:3px solid var(--tone, var(--line)); border-radius:var(--r-control); box-shadow:none; font:800 1.375rem var(--font-display); }
.pp-photo .player-headshot { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:center top; }
.pp-id { display:flex; flex-direction:column; gap:0.3125rem; min-width:0; }
.pp h1 { font-size:clamp(1.875rem, 3vw, 2.5rem); letter-spacing:0; line-height:1; overflow-wrap:anywhere; }
.pp h1:focus { outline:none; }
.pp h1:focus-visible { outline:3px solid var(--accent); outline-offset:4px; }
.pp-meta { margin:0; display:flex; flex-wrap:wrap; align-items:center; gap:0.125rem 0.25rem; color:var(--muted); font-size:0.875rem; font-weight:600; }
.pp-meta > * + *::before, .pp-meta > * + .pp-meta-game > .pp-nw:first-child::before { content:"·"; margin:0 0.375rem 0 0.125rem; color:var(--muted); font:600 0.875rem var(--font-body); }
/* The game's dot sits inside its first piece, so it wraps with "@ Browns," and never stands on a line alone (UI-405). */
.pp-meta > .pp-meta-game::before { content:none; }
.pp-meta a { color:var(--muted); }
.pp-meta a:hover { color:var(--accent); }
.pp-meta b { color:var(--ink); }
.pp-meta-game { display:inline-flex; flex-wrap:wrap; align-items:center; gap:0 0.125rem; }
/* Each piece stays whole; its separator travels with it, so a wrap never starts a line with a dot. */
.pp-nw { display:inline-flex; align-items:center; gap:0.125rem; white-space:nowrap; }
.pp-sep { margin:0 0.375rem 0 0.25rem; }
/* The kickoff is its own piece (UI-401); the margin restores the width of the space after the comma. */
.pp-meta-game > .pp-when { margin-left:0.06em; }
.pp-meta-lines { font:700 0.75rem var(--font-mono); }
.pp-meta .pp-link { font-size:0.875rem; color:var(--muted); font-weight:700; }
/* Kicked off with no stats saved (UI-414): the same label as Teams' "Started · results pending". */
.pp-started { margin:0; display:flex; flex-wrap:wrap; align-items:center; gap:0.125rem 0.25rem; color:var(--muted); font-size:0.8125rem; font-weight:600; }
.pp-started-label { color:var(--ink); font-weight:700; }
.pp-started b { color:var(--ink); }
.pp-id-tags { display:flex; flex-wrap:wrap; align-items:center; gap:0.625rem; }
.pp-late-note, .pp-moved { margin:0; color:var(--muted); font-size:0.8125rem; font-weight:600; }
.pp-chip.is-late { max-width:100%; white-space:normal; }
.pp-chip.is-late i { flex-shrink:0; }
.pp-season { font:700 0.75rem var(--font-mono); color:var(--muted); }
.pp-season b { color:var(--ink); }
.pp-owner:empty { display:none; }
/* His fantasy owner tag (fantasy-owners.js) right after the name, centred on it. */
/* On the name's last line (a two-line name on a phone keeps it by "Chase", not between lines). */
.pp-name-line { display:flex; align-items:last baseline; gap:0 0.75rem; min-width:0; }
.pp-name-line > h1 { min-width:0; }
.pp-name-line > .pp-owner { flex:0 0 auto; display:inline-flex; font-size:1.5rem; position:relative; top:-0.25em; }
html body .pp-name-line > .pp-owner > .owner-tag { margin-left:0; }
.pp-chip { display:inline-flex; align-items:center; gap:0.375rem; padding:0.125rem 0.5625rem; border-radius:var(--r-data); border:1px solid var(--line); background:var(--surface-raised); color:var(--ink); font:800 0.75rem var(--font-body); white-space:nowrap; }
.pp-chip i { width:7px; height:7px; border-radius:var(--r-data); background:currentColor; }
.pp-chip.is-clear { background:var(--good-bg); color:var(--good); border-color:transparent; }
.pp-chip.is-out { background:var(--bad); color:var(--accent-ink); }
.pp-chip.is-doubt { background:var(--thin); color:var(--accent-ink); }
.pp-chip.is-limited { background:var(--lilac); color:var(--accent-ink); }
/* A carried status (UI-606): an earlier week's, so outlined rather than filled. */
/* "Bigger role (Hall out)" (UI-613), beside his status: the pp-chip shape, outlined
   lilac as on Props and the Slate (percentage-plays.css .dk-role-tag). */
.pp-dk-role { display:inline-flex; align-items:center; max-width:100%; padding:0.125rem 0.5625rem; border-radius:var(--r-data); box-shadow:inset 0 0 0 1px var(--lilac); color:var(--ink); font:800 0.75rem var(--font-body); }
@media (max-width:40em) { .pp-dk-role { white-space:normal; } }
.pp-chip.is-carried { background:var(--bad-bg); color:var(--bad); border:1px dashed currentColor; }
.pp-head-tools { display:flex; align-items:center; gap:0.75rem; }

/* Prop switcher: one chip, a menu of props with a verdict dot each */
.pp-switch { position:relative; display:flex; align-items:center; gap:0.625rem; }
.pp-switch-label { font-family:var(--font-body); text-transform:none; letter-spacing:0; font-size:0.8125rem; }
.pp-switch-button { height:2.75rem; display:inline-flex; align-items:center; gap:0.5rem; padding:0 0.875rem; background:var(--surface); color:var(--ink); border:1px solid var(--line); border-radius:var(--r-control); box-shadow:none; font:800 0.9375rem var(--font-body); cursor:pointer; }
.pp-switch-button small { color:var(--muted); font-size:0.75rem; font-weight:700; }
.pp-switch-button svg { color:var(--muted); transition:rotate var(--dur-fast) var(--ease-out); }
.pp-switch-button[aria-expanded=true] svg { rotate:180deg; }
.pp-vdot { flex:none; width:0.625rem; height:0.625rem; border-radius:50%; background:var(--line); }
.pp-vdot.v-strong, .pp-vdot.v-lean { background:var(--good); }
.pp-vdot.v-thin { background:none; box-shadow:inset 0 0 0 2px var(--thin); }
.pp-vdot.v-against { background:var(--bad); }
.pp-vdot.v-neutral { background:var(--muted); }
.pp-menu { position:absolute; z-index:20; top:calc(100% + 0.5rem); right:0; min-width:15rem; max-height:22rem; overflow:auto; margin:0; padding:0.375rem; list-style:none;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card); box-shadow:none; transform-origin:top right;
  animation:pp-menu-in var(--dur-fast) var(--ease-out); }
@keyframes pp-menu-in { from { opacity:0; scale:calc(1 - 0.05 * var(--move)); } }
.pp-menu-item { width:100%; min-height:2.5rem; display:flex; align-items:center; gap:0.625rem; padding:0 0.75rem; border:0; border-radius:var(--r-card); background:none; color:var(--ink); font:700 0.875rem var(--font-body); text-align:left; cursor:pointer; }
.pp-menu-item span { flex:1 1 auto; }
.pp-menu-item small { color:var(--muted); font-size:0.75rem; white-space:nowrap; }
.pp-menu-item:hover { background:var(--surface-raised); }
.pp-menu-item[aria-pressed=true] { background:var(--surface-raised); box-shadow:none; }
.pp-share { height:2.75rem; display:inline-flex; align-items:center; gap:0.5rem; padding:0 1rem; background:var(--surface); color:var(--ink); border:1px solid var(--line); border-radius:var(--r-control); box-shadow:none; font:800 0.9375rem var(--font-body); cursor:pointer; }
.pp-share:hover { background:var(--surface-raised); }
.pp-share:active { translate:0 calc(1px * var(--move)); filter:brightness(0.86); transition:translate var(--dur-instant) var(--ease-press), box-shadow var(--dur-instant) var(--ease-press); }

/* Answer banner: the verdict in one sentence, the pick beside it */
.pp-answer { position:relative; display:grid; grid-template-columns:minmax(0, 1fr) minmax(15rem, 20rem); gap:1.5rem 2rem; align-items:center; padding:1.5rem 1.75rem 1.375rem 2.125rem; border-radius:var(--r-card); overflow:hidden; }
.pp-answer::before { content:""; position:absolute; inset:0 auto 0 0; width:6px; background:var(--line); }
.pp-answer.is-v-strong::before, .pp-answer.is-v-lean::before { background:var(--good); }
.pp-answer.is-v-against::before { background:var(--bad); }
.pp-answer.is-v-thin::before { background:var(--thin); }
.pp-answer-body { display:grid; gap:0.875rem; min-width:0; }
.pp-answer-tags { display:flex; flex-wrap:wrap; align-items:center; gap:0.5rem 0.75rem; }
.pp-answer-prop { font-weight:800; font-size:0.9375rem; }
.pp-answer-prop .pp-mono { font-size:0.875rem; }
.pp-answer-text { margin:0; font:800 clamp(1.5rem, 2.4vw, 2.125rem)/1.18 var(--font-display); letter-spacing:-0.025em; text-wrap:pretty;
  animation:ar-rise var(--dur-slow) var(--ease-out) both; animation-delay:calc(90ms * var(--move)); }
.pp-hl { font-weight:800; }
.pp-hl.hl-for { color:var(--good); }
.pp-hl.hl-against { color:var(--bad); }
.pp-hl.hl-thin { color:var(--thin); }
.pp-hl.hl-line { color:var(--ink); font-family:var(--font-mono); font-size:0.9em; letter-spacing:-0.03em; }
.pp-hl.hl-neutral { color:var(--ink); text-decoration:underline; text-decoration-color:var(--line); text-underline-offset:5px; }
.pp-answer-foot { margin:0; color:var(--muted); font-size:0.8125rem; }
.pp-answer-foot b { font-family:var(--font-mono); color:var(--ink); }
.pp-lines-asof { white-space:nowrap; }
/* UI-675: "Line up 18% from Week 4's 52.5", context in the foot (muted, no tone colour). */
.pp-line-move { white-space:nowrap; }
.pp-answer-pick { display:grid; gap:0.625rem; justify-items:stretch; }
html body[data-layout] .pp .pp-pick-prices { display:grid; grid-template-columns:minmax(0, 1fr); gap:0.625rem; width:auto; }
.pp :is(.pp-pick-prices, .pp-action-prices) .bet-side > span:first-child { white-space:nowrap; }
html body[data-layout] .pp :is(.pp-pick-prices, .pp-action-prices) .bet-side { width:auto; min-height:3.25rem; display:flex; flex-direction:row; align-items:center; justify-content:center; gap:0.5rem; padding:0 1rem;
  border:1px solid var(--line); border-radius:var(--r-control); box-shadow:none; background:var(--surface-raised); color:var(--ink); font:800 1rem var(--font-display); cursor:pointer; }
/* The viewed side (data-side-view, both the answer card and the sticky bar) is bigger and outlined, never filled:
   a solid accent fill with a check means saved, as on Today and Props. */
html body[data-layout] .pp :is(.pp-pick-prices, .pp-action-prices):not([data-side-view=under]) .bet-side[data-side=over],
html body[data-layout] .pp :is(.pp-pick-prices, .pp-action-prices)[data-side-view=under] .bet-side[data-side=under] { background:var(--accent-soft); border-color:var(--accent); box-shadow:inset 0 0 0 1px var(--accent); color:var(--ink); min-height:3.625rem; font-size:1.0625rem; }
.pp :is(.pp-pick-prices, .pp-action-prices)[data-side-view=under] .bet-side[data-side=under] { order:-1; }
html body[data-layout] .pp :is(.pp-pick-prices, .pp-action-prices) .bet-side strong { font:700 0.875rem var(--font-mono); color:inherit; background:none; padding:0; }
html body[data-layout] .pp :is(.pp-pick-prices, .pp-action-prices)[data-side-view] .bet-side[aria-pressed=true] { background:var(--accent); border-color:var(--edge); box-shadow:none; color:var(--accent-ink); }
.pp :is(.pp-pick-prices, .pp-action-prices) .bet-side .bet-side-action { font:700 0.6875rem var(--font-body); opacity:0.8; }
.pp :is(.pp-pick-prices, .pp-action-prices) .bet-side > .bet-side-label { margin-right:-0.25rem; font:600 0.75rem/1 var(--font-body); opacity:0.78; }
.pp :is(.pp-pick-prices, .pp-action-prices) .bet-side > .bet-side-label + span { white-space:nowrap; }
html body[data-layout] .pp :is(.pp-pick-prices, .pp-action-prices) .bet-side:has(> .bet-side-label) > strong { padding-left:0.5rem; border-left:1px solid color-mix(in srgb, currentColor 30%, transparent); }
html body[data-layout] .pp :is(.pp-pick-prices, .pp-action-prices) .bet-side:disabled { opacity:0.55; cursor:not-allowed; }
/* The Player page's worded star: taller, padded, Arcade colours (UI-293). players.css .bet-star
   sizes worded stars to fit and keeps hover off the words (UI-380). */
.pp-star { height:2.75rem; display:inline-flex; align-items:center; justify-content:center; gap:0.5rem; padding:0 1rem; background:var(--surface); color:var(--ink); border:1px solid var(--line); border-radius:var(--r-control); box-shadow:none; font:800 0.875rem var(--font-body); cursor:pointer; }
.pp-star span { color:var(--gold); font-size:1.125rem; }
.pp-star[aria-pressed=true] { background:var(--gold); color:var(--accent-ink); }
.pp-star[aria-pressed=true] span { color:var(--accent-ink); }
.pp-star:not(:disabled):hover { border-color:var(--gold); }

/* Chart card: side toggle, count, ladder and the full house chart */
.pp-chart-card, .pp-pct, .pp-evidence { display:flex; flex-direction:column; gap:1rem; padding:1.25rem 1.5rem; }
.pp-card-head { display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:0.5rem 0.75rem; min-height:2rem; }
.pp-card-foot { margin-top:auto; display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:0.5rem; padding-top:0.5rem; font-size:0.8125rem; color:var(--muted); }
.pp-chart-title { display:flex; flex-wrap:wrap; align-items:center; gap:0.75rem 1rem; }
.pp-sides { display:inline-flex; gap:0.25rem; padding:0.25rem; background:var(--bg); border:1px solid var(--line); border-radius:var(--r-data); }
.pp-sides button { height:2rem; padding:0 0.875rem; border:0; border-radius:var(--r-control); background:none; color:var(--muted); font:800 0.8125rem var(--font-body); cursor:pointer; }
.pp-sides button[aria-pressed=true] { background:var(--selected-bg); color:var(--ink); box-shadow:inset 0 0 0 1px var(--accent); }
.pp-chart-tools { display:flex; flex-wrap:wrap; align-items:center; gap:0.75rem; }
.pp-house-count { display:inline-flex; align-items:baseline; gap:0.5rem; }
.pp-house-at { color:var(--muted); font-size:0.875rem; font-weight:700; }
.pp-house-at b { font-family:var(--font-mono); color:var(--ink); }
.pp-house-count strong { font:700 2rem/1 var(--font-mono); letter-spacing:-0.04em; }
.pp-house-count small { font:700 0.8125rem var(--font-mono); color:var(--muted); }
.pp-house-count .lt-for { color:var(--good); } .pp-house-count .lt-against { color:var(--bad); } .pp-house-count :is(.lt-neutral, .lt-thin) { color:var(--thin); }
/* Average and median of the games drawn, against the line (UI-110). */
.pp-house-avg { margin:0; font-size:0.8125rem; font-weight:700; color:var(--muted); white-space:nowrap; }
.pp-house-avg b { font-family:var(--font-mono); color:var(--ink); }
.pp-house-avg .lt-for { color:var(--good); } .pp-house-avg .lt-against { color:var(--bad); }
/* Last season's games (UI-195): their own count, average and median, tagged with the year
   and set apart from this season's numbers by a rule. */
.pp-house-prior { margin:0; display:inline-flex; align-items:baseline; gap:0.25rem; padding-left:0.75rem; border-left:2px solid var(--line); font-size:0.8125rem; font-weight:700; color:var(--muted); white-space:nowrap; }
.pp-chart-tools > .pp-house-prior:first-child { padding-left:0; border-left:0; } /* no games this season: nothing to set it apart from */
.pp-house-prior b { font-family:var(--font-mono); color:var(--ink); }
.pp-house-prior .pp-house-prior-tag { padding:0 0.375rem; border:1.5px dashed var(--muted); border-radius:var(--r-data); font:700 0.6875rem var(--font-mono); }
.pp-house-prior .lt-for { color:var(--good); } .pp-house-prior .lt-against { color:var(--bad); } .pp-house-prior .pp-house-prior-count:is(.lt-neutral, .lt-thin) { color:var(--thin); }
.pp-reset { height:2.25rem; padding:0 0.875rem; background:var(--surface-raised); color:var(--ink); border:1px solid var(--line); border-radius:var(--r-control); box-shadow:none; font:700 0.8125rem var(--font-mono); cursor:pointer; }
/* The Reset button's room is kept all the time (hidden, not removed, at the book line), so
   it showing up never pushes the chart down under a dragging finger. */
.pp-reset-slot { display:inline-flex; min-height:2.25rem; }
.pp-reset-slot:empty { display:none; }
.pp-reset.is-off { visibility:hidden; }

.pp-strip { display:grid; gap:0.5rem; }
.pp-strip-head { font-size:0.75rem; font-weight:700; color:var(--muted); }
.pp-strip-scroller { display:flex; align-items:center; gap:0.5rem; min-width:0; }
.pp-strip-track { position:relative; flex:1 1 auto; min-width:0; display:flex; gap:0.625rem; overflow-x:auto; padding:0 5px 6px 0; scroll-snap-type:x proximity; scrollbar-width:thin; }
/* More chips off an edge: that edge fades out and gets an arrow. */
.pp-strip { --fade:3rem; }
.pp-strip.has-after .pp-strip-track { mask-image:linear-gradient(to right, #000 calc(100% - var(--fade)), transparent); }
.pp-strip.has-before .pp-strip-track { mask-image:linear-gradient(to left, #000 calc(100% - var(--fade)), transparent); }
.pp-strip.has-before.has-after .pp-strip-track { mask-image:linear-gradient(to right, transparent, #000 var(--fade), #000 calc(100% - var(--fade)), transparent); }
.pp-strip-nav { flex:none; margin-bottom:6px; width:2.25rem; height:2.25rem; display:none; place-items:center; padding:0;
  background:var(--surface); color:var(--ink); border:1px solid var(--line); border-radius:var(--r-control); box-shadow:none; cursor:pointer; }
.pp-strip-nav:hover { background:var(--surface-raised); }
.pp-strip.has-before .pp-strip-nav.is-prev, .pp-strip.has-after .pp-strip-nav.is-next { display:grid; }
.pp-strip-option { flex:0 0 auto; min-width:9.5rem; display:grid; gap:0.25rem; justify-items:start; padding:0.5rem 0.75rem; cursor:pointer; scroll-snap-align:start;
  background:var(--surface-raised); color:var(--ink); border:2px solid var(--line); border-radius:var(--r-control); text-align:left; }
/* UI-437: with 200% text on a phone (under 10em of the strip's own text; the default size is
   always 13em or wider) "O 45.5 -110 Book" was wider than the strip and ran under its fade.
   A chip is never wider than the strip, and its line wraps. */
.pp-strip { container-type:inline-size; }
@container (max-width: 10em) {
  .pp-strip .pp-strip-option { max-width:100%; }
  .pp-strip .pp-strip-line { white-space:normal; }
}
.pp-strip-option:hover { border-color:var(--muted); }
.pp-strip-option.is-main { border-style:dashed; border-color:var(--muted); }
.pp-strip-option.is-at { border-color:var(--ink); border-style:solid; }
.pp-strip-line { font:700 0.9375rem var(--font-mono); white-space:nowrap; }
.pp-strip-line b { color:var(--muted); font-weight:400; font-size:0.75rem; }
.pp-strip-line em { margin-left:0.375rem; font:700 0.625rem var(--font-body); font-style:normal; color:var(--muted); text-transform:uppercase; letter-spacing:0.04em; }
.pp-strip-option small { display:inline-flex; align-items:center; gap:0.375rem; font:700 0.75rem var(--font-mono); color:var(--ink); }
.pp-strip-option small i { width:0.5rem; height:0.5rem; border-radius:var(--r-control); background:currentColor; }
.pp-strip-option small.lt-for i { background:var(--good); } .pp-strip-option small.lt-neutral i { background:var(--thin); } .pp-strip-option small.lt-against i { background:var(--bad); } .pp-strip-option small.lt-thin i { background:none; box-shadow:inset 0 0 0 2px var(--thin); }
.pp-strip-option small { color:var(--ink); }
.pp-strip-option[aria-pressed=true] { background:var(--selected-bg); color:var(--ink); border-color:var(--accent); box-shadow:none; }

/* Bars sit in fixed slots from the left, oldest first (--pp-bar wide, --pp-gap between),
   then this week's dashed slot (the outline .ar-next draws too). The plot is as wide as its --n slots, capped at the card,
   and the handle's rail follows it, so the line's number sits right by this week. With a
   full season the slots shrink evenly and the plot fills the card. */
.pp-house { --pp-bar:4.5rem; --pp-gap:0.75rem; --pp-rail:5.75rem; display:grid; justify-content:start; margin-bottom:2.75rem;
  grid-template-columns:minmax(0, calc(var(--n, 10) * (var(--pp-bar) + var(--pp-gap)))) var(--pp-rail); }
.pp-house-plot { position:relative; height:17rem; border-bottom:2px solid var(--line); cursor:ns-resize; }
.pp-hbars { position:absolute; inset:0; display:flex; align-items:flex-end; justify-content:flex-start; gap:var(--pp-gap); padding-right:var(--pp-gap); }
.pp-hbar { position:relative; flex:1 1 0; min-width:0; max-width:var(--pp-bar); height:100%; }
/* This week: an outline at the line's height (follows the drag), labelled with the opponent.
   Its dashed sides stop at the line, with no dashed top: the line itself closes the box, so
   the dashes never sit on it or hide it (UI-454). It moves on the line's spring, so the two
   stay together. */
.pp-hbar.is-next .pp-hbar-fill { position:absolute; left:0; right:0; bottom:0; height:var(--at); border:2px dashed var(--muted); border-top:0; border-bottom:0; border-radius:0;
  background:color-mix(in srgb, var(--ink) 6%, transparent); transition:height var(--dur-base) var(--spring-soft); }
.pp-hbar.is-next .pp-hbar-label, .pp-hbar.is-next .pp-hbar-label small { color:var(--accent); }
.pp-house.is-dragging .pp-hbar.is-next .pp-hbar-fill, .is-still .pp-hbar-fill { transition:none; }
/* A team game he missed (UI-80): a thin hatched slot at the floor, labelled Out (on the
   injury report) or DNP, with no bar and no count. */
.pp-hbar.is-gap { flex:0 0 1.75rem; }
.pp-hbar-gap { position:absolute; left:0; right:0; bottom:0; height:2.5rem; border:2px dashed var(--line); border-bottom:0; border-radius:0;
  background:repeating-linear-gradient(135deg, color-mix(in srgb, var(--muted) 30%, transparent) 0 2px, transparent 2px 6px); }
.pp-hbar.is-gap .pp-hbar-label small { color:var(--ink); font-weight:800; }
/* Last season's bars (UI-195): faded, with muted labels, before a dashed divider tagged
   with both years. They never count toward this season's hit count or average. */
.pp-hbar.is-prior .pp-hbar-fill { opacity:0.4; }
.pp-hbar.is-prior .pp-hbar-label, .pp-hbar.is-prior:not(.val-in) .pp-hbar-value { color:var(--muted); }
.pp-hbar.is-prior.val-in .pp-hbar-value { color:var(--ink); }
.pp-hbar.is-divider { flex:0 0 1.75rem; }
.pp-hbar.is-divider::before { content:""; position:absolute; left:50%; top:0; bottom:0; border-left:2px dashed var(--line); }
.pp-season-tag { position:absolute; top:0; z-index:4; padding:0 0.25rem; border-radius:var(--r-data); background:var(--surface); font:700 0.6875rem var(--font-mono); color:var(--ink); white-space:nowrap; }
.pp-season-tag.is-prior { right:calc(50% + 0.25rem); color:var(--muted); }
.pp-season-tag:not(.is-prior) { left:calc(50% + 0.25rem); }
.pp-legend .pp-legend-prior i { background:var(--muted); opacity:0.4; }
/* UI-368: games with the teammate now out playing, his old role: hatched over the bar's
   colour, so hit and miss still read, with a legend entry ("with Etienne, his old role"). */
.pp-hbar.is-with .pp-hbar-fill { background-image:repeating-linear-gradient(135deg, color-mix(in srgb, var(--bg) 55%, transparent) 0 3px, transparent 3px 8px); }
.pp-legend .pp-legend-with i { background:repeating-linear-gradient(135deg, var(--bg) 0 2px, var(--muted) 2px 5px); }
/* UI-650: a partial game (UI-624) greyed like the Usage bars and the log's muted row, with
   "Partial" under the week; it still counts in the hit count. */
.pp-hbar.is-partial .pp-hbar-fill.ar-bar { background:var(--muted); box-shadow:none; opacity:0.45; }
.pp-hbar.is-partial:not(.val-in) .pp-hbar-value, .pp-hbar.is-partial .pp-hbar-label > span { color:var(--muted); }
.pp-hbar.is-partial .pp-hbar-label .pp-slot-status { color:var(--muted); font-weight:700; }
.pp-legend .pp-legend-partial i { background:var(--muted); opacity:0.45; }
.pp-house-count .pp-old-role { align-self:center; padding:0.125rem 0.375rem; border:1px solid var(--line); border-radius:var(--r-data); font:700 0.6875rem var(--font-mono); color:var(--thin); text-transform:uppercase; letter-spacing:0.04em; cursor:help; }
/* UI-368: the Role change card (Player page, and Props' Why when it draws roleCardHtml). */
.role-card { display:grid; gap:0.5rem; padding:1rem 1.125rem; }
.role-card-head { display:flex; flex-wrap:wrap; align-items:center; gap:0.375rem 0.75rem; }
/* UI-555: by class, not tag, since Props' Why draws the heading as an h4. The arcade h2 look at the
   h2 default size; on the Player page .pp h2 still sizes and weights it, as before. */
.role-card-title { margin:0; font-family:var(--font-display); font-size:1.5em; font-weight:900; letter-spacing:0; text-transform:uppercase; }
.role-card-tag { padding:0.125rem 0.5rem; border:1px solid var(--line); border-radius:var(--r-data); font:700 0.6875rem var(--font-mono); text-transform:uppercase; letter-spacing:0.04em; color:var(--muted); }
.role-card-tag.is-large { color:var(--thin); border-color:color-mix(in srgb, var(--thin) 50%, var(--line)); }
/* UI-350 T4: a computed sentence on a box that's already marked (a tag, a chip, the 2025
   count) shows on hover, focus or tap through the kit's tooltip: no underline, a help cursor,
   no text selection on a long-press, and a focus ring off the Player page too (Props' Why). */
:is(.pp, .role-card) [data-tip][tabindex] { cursor:help; -webkit-user-select:none; user-select:none; -webkit-touch-callout:none; }
.role-card [data-tip][tabindex]:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.role-card p { margin:0; overflow-wrap:anywhere; }
.role-card-leaves small, .role-card-basis { color:var(--muted); font-size:0.8125rem; }
.role-card-expected b { font-family:var(--font-mono); }
.role-card-price { font-size:0.875rem; }
.role-card-label { display:block; font:700 0.6875rem var(--font-mono); text-transform:uppercase; letter-spacing:0.04em; color:var(--muted); }
.role-card-cap { font-size:0.8125rem; font-weight:700; color:var(--thin); }
/* The Show/Hide 2025 button (UI-195): nothing of last season loads until it's pressed. */
.pp-prior-wrap { display:inline-flex; flex-wrap:wrap; align-items:center; gap:0.25rem 0.5rem; }
.pp-prior { display:inline-flex; align-items:center; gap:0.375rem; min-height:2rem; padding:0 0.75rem; background:var(--surface-raised); color:var(--ink); border:1px solid var(--line); border-radius:var(--r-data); font:700 0.75rem var(--font-mono); cursor:pointer; }
.pp-prior-mark { width:0.75rem; height:0.75rem; border:1.5px dashed var(--muted); border-radius:var(--r-data); }
.pp-prior.is-loading { cursor:progress; color:var(--muted); }
.pp-prior.is-loading .pp-prior-mark { border-style:solid; border-color:var(--muted) transparent; border-radius:var(--r-data); animation:pp-prior-spin 0.8s linear infinite; }
@keyframes pp-prior-spin { to { transform:rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .pp-prior.is-loading .pp-prior-mark { animation:none; } }
.pp-prior-note { font-size:0.75rem; font-weight:700; color:var(--muted); }
.pp-prior-note:empty { display:none; }
.pp-prior-note.is-error { color:var(--bad); }
.pp-hbar-fill.ar-bar { position:absolute; left:0; right:0; bottom:0; height:var(--h); min-width:0; border-radius:0; display:grid; justify-items:center; align-content:end; }
.pp-hbar-value { position:absolute; z-index:3; left:50%; translate:-50% 0; bottom:calc(var(--h) + 0.25rem); padding:0 0.25rem; border-radius:var(--r-data); background:var(--surface); text-align:center; font:700 0.8125rem var(--font-mono); color:var(--ink); white-space:nowrap; pointer-events:none; }
/* A value that would sit on the line moves inside the top of its bar (.val-in) or just
   above the line (.val-over); valuePlace in studio-player-page.js picks which (UI-34's rule). */
.pp-hbar.val-in .pp-hbar-value { bottom:auto; top:calc(100% - var(--h) + 0.25rem); background:none; color:var(--accent-ink); }
.pp-hbar.val-over .pp-hbar-value { bottom:calc(var(--pp-at, 0%) + 0.25rem); }
.pp-hbar-label { position:absolute; left:50%; top:calc(100% + 0.375rem); translate:-50% 0; display:grid; justify-items:center; font:700 0.6875rem/1.25 var(--font-mono); color:var(--ink); white-space:nowrap; }
.pp-hbar-label small { font:600 0.6875rem var(--font-body); color:var(--muted); }
.pp-house-line, .pp-house-book, .pp-house-handle-wrap { position:absolute; inset:0; pointer-events:none; transform:translateY(calc(var(--at) * -1));
  transition:transform var(--dur-base) var(--spring-soft); }
/* The line, drawn as a yard line (UI-208, as UI-204's .ar-line in arcade.css): solid, with
   short hash marks hanging under it across the plot, and its number in the square handle tag
   on the rail, by this week. The book's line stays dashed so the two never read as one. */
.pp-house-line { border-bottom:2px solid var(--ink); left:-0.25rem; right:calc(var(--pp-rail) * -1); z-index:2; --hash:0.5rem; --hash-gap:1rem; }
.pp-house-line::after { content:""; position:absolute; left:0.25rem; right:var(--pp-rail); top:100%; height:var(--hash); opacity:0.45;
  background:repeating-linear-gradient(90deg, var(--ink) 0 2px, transparent 2px var(--hash-gap)); }
.pp-house-book { border-bottom:2px dashed var(--muted); opacity:0.5; }
.pp-house-book span { position:absolute; left:0; bottom:0.25rem; font:700 0.625rem var(--font-mono); color:var(--muted); }
.pp-house-rail { position:relative; touch-action:none; cursor:ns-resize; }
.pp-house-handle { position:absolute; right:0; bottom:0; translate:0 50%; pointer-events:auto; z-index:3; height:2.125rem; display:inline-flex; align-items:center; gap:0.375rem; padding:0 0.625rem;
  background:var(--ink); color:var(--accent-ink); border:1px solid var(--line); border-radius:var(--r-data); box-shadow:none; font:900 0.9375rem/1 var(--font-mono); cursor:grab; touch-action:none; user-select:none; }
.pp-house-handle::before { content:""; position:absolute; inset:-0.75rem -0.5rem; }
.pp-house.is-dragging .pp-house-handle { cursor:grabbing; }
.pp-house.is-dragging :is(.pp-house-line, .pp-house-handle-wrap), .is-still { transition:none !important; }
.pp-house.is-dragging { user-select:none; }
.pp-chart-foot { display:flex; flex-wrap:wrap; justify-content:space-between; gap:0.5rem 1rem; font-size:0.75rem; font-weight:600; color:var(--muted); }
.pp-legend { display:flex; flex-wrap:wrap; gap:0.375rem 1rem; color:var(--ink); font-weight:800; }
.pp-legend span { display:inline-flex; align-items:center; gap:0.375rem; }
.pp-legend small { color:var(--muted); font-weight:600; font-size:0.75rem; }
.pp-legend i { width:0.75rem; height:0.75rem; border-radius:var(--r-data); background:var(--line); }
.pp-legend i.r-hit { background:var(--good); } .pp-legend i.r-miss { background:var(--bad); } .pp-legend i.r-push { background:none; box-shadow:inset 0 0 0 2px var(--thin); }

/* Why tiles: the four signals (StudioKit.signalRows) as tiles */
.pp-why { display:grid; gap:0.75rem; }
.pp-why-head { display:flex; flex-wrap:wrap; align-items:baseline; gap:0.25rem 0.75rem; }
.pp-why .ar-signal-rows { grid-template-columns:repeat(4, minmax(0, 1fr)); gap:0.875rem; }
html body[data-layout] .pp-why .ar-sig-row { grid-template-columns:auto minmax(0, 1fr) auto; grid-template-rows:auto 1fr; align-items:start; gap:0.625rem 0.5rem; min-height:8.5rem; padding:1rem 1.125rem;
  border:1px solid var(--line); border-radius:var(--r-card); box-shadow:none; font-size:0.9375rem; line-height:1.4; }
.pp-why .ar-sig-row .ar-sig-glyph { grid-area:1 / 1; }
.pp-why .ar-sig-row .ar-sig-title { grid-area:1 / 2; font-size:0.9375rem; }
.pp-why .ar-sig-row .ar-sig-tone { grid-area:1 / 3; display:inline; font-weight:800; text-transform:capitalize; }
.pp-why .ar-sig-row .ar-sig-text { grid-area:2 / 1 / 3 / -1; }
.pp-why .ar-sig-row.tone-thin { background:var(--thin-bg); }
.pp-why-links { display:flex; flex-wrap:wrap; gap:0.5rem 1.25rem; }


/* Percentile bars */
/* Full width, the three groups side by side on wide screens so the card stays short. */
.pp-pct-groups { display:grid; grid-template-columns:repeat(auto-fit, minmax(min(22rem, 100%), 1fr)); gap:0.75rem 2rem; align-items:start; }
.pp-pct-group { display:grid; gap:0.25rem; min-width:0; }
@media (min-width: 75.01rem) {
  .pp-pct-groups :is(.pp-pct-scale, .pp-pct-row) { grid-template-columns:minmax(6.5rem, 8rem) minmax(0, 1fr) 3.25rem; gap:0 0.5rem; }
  .pp-pct-groups .pp-pct-scale { grid-template-columns:minmax(6.5rem, 8rem) repeat(3, minmax(0, 1fr)) 3.25rem; gap:0; }
}
.pp-pct-scale, .pp-pct-row { display:grid; grid-template-columns:minmax(7rem, 9.5rem) minmax(0, 1fr) 4.25rem; gap:0 1rem; align-items:center; }
.pp-pct-scale { grid-template-columns:minmax(7rem, 9.5rem) repeat(3, minmax(0, 1fr)) 4.25rem; gap:0; font-size:0.6875rem; font-weight:700; color:var(--muted); }
.pp-pct-scale span:nth-child(1) { padding-right:1rem; }
.pp-pct-scale span:nth-child(3) { text-align:center; }
.pp-pct-scale span:nth-child(4), .pp-pct-scale span:nth-child(5) { text-align:right; }
.pp-pct-row { min-height:2.625rem; }
.pp-pct-name { font-size:0.9375rem; font-weight:700; }
.pp-pct-track { position:relative; height:0.375rem; margin:0 0.75rem; border-radius:var(--r-data); background:var(--line); }
.pp-pct-avg { position:absolute; left:40%; width:20%; top:-0.25rem; bottom:-0.25rem; border-radius:var(--r-data); background:var(--muted); opacity:0.35; }
.pp-pct-fill { position:absolute; left:0; top:0; bottom:0; width:var(--p); border-radius:0; background:var(--muted); transform-origin:left; animation:pp-fill var(--dur-slow) var(--ease-out) both; }
@keyframes pp-fill { from { transform:scaleX(calc(1 - var(--move))); } }
.pp-pct-bubble { position:absolute; left:var(--p); top:50%; translate:-50% -50%; min-width:1.75rem; height:1.75rem; display:grid; place-items:center; padding:0 0.25rem; box-sizing:border-box;
  border:1px solid var(--line); border-radius:var(--r-data); background:var(--muted); color:var(--accent-ink); font:700 0.6875rem var(--font-mono); }
.pp-pct-row.pt-for :is(.pp-pct-fill, .pp-pct-bubble) { background:var(--good); }
.pp-pct-row.pt-against :is(.pp-pct-fill, .pp-pct-bubble) { background:var(--bad); }
.pp-pct-row .pp-pct-value { text-align:right; font:700 0.9375rem var(--font-mono); color:var(--ink); }
/* Large text (UI-261). These containers are measured in their own text size, so the rules
   below apply only when a group or the chart header holds under 12-14em of text (200% text
   on a phone), never at the default size. Percentile rows: the name gets its own line over
   the bar and value. */
.pp-pct-group, .pp-chart-card .pp-card-head { container-type:inline-size; }
@container (max-width: 12em) {
  .pp-pct-group :is(.pp-pct-scale, .pp-pct-row) { grid-template-columns:minmax(0, 1fr) 3.5rem; gap:0 0.25rem; }
  .pp-pct-group .pp-pct-scale { grid-template-columns:repeat(3, minmax(0, 1fr)) 3.5rem; }
  .pp-pct-group :is(.pp-pct-scale span:first-child, .pp-pct-name) { grid-column:1 / -1; padding-right:0; }
  .pp-pct-group .pp-pct-track { margin:0.5rem 0.75rem; }
  /* Low and High only: three labels don't fit over the short bar. */
  .pp-pct-group .pp-pct-scale span:nth-child(3) { visibility:hidden; }
}
/* Chart header: Over/Under takes the row, Reset drops under the averages (and takes no room
   while it's off), and the averages wrap. */
@container (max-width: 14em) {
  /* UI-437: at 320 with the browser's real 200% text both words don't fit side by side
     ("Unde"), so the buttons keep their whole word and Under wraps under Over. */
  .pp-chart-card .pp-card-head .pp-sides { display:flex; flex-wrap:wrap; grid-column:1 / -1; }
  .pp-chart-card .pp-card-head .pp-sides button { flex:1 1 0; min-width:max-content; padding:0 0.5rem; }
  .pp-chart-card .pp-card-head .pp-reset-slot { grid-row:6; grid-column:1 / -1; }
  .pp-chart-card .pp-card-head .pp-reset-slot:has(.pp-reset.is-off) { display:none; }
  .pp-chart-card .pp-card-head .pp-house-avg { white-space:normal; }
  /* UI-433: the count's percent ("100%") drops to the next line instead of running past a
     320 screen at the browser's real 200% text setting. */
  .pp-chart-card .pp-card-head .pp-house-count { flex-wrap:wrap; row-gap:0.25rem; max-width:100%; }
}
/* Player name (UI-401): squeezed between the photo and Share it broke one letter per line;
   it takes its own row under them instead. */
.pp-head { container-type:inline-size; }
@container (max-width: 14em) {
  .pp-head .pp-name-line { grid-column:1 / -1; }
  /* Game page (UI-407): at 360 the kickoff wraps and "· Game page" led its line with the dot.
     Here Game page always takes its own line, so it needs no separator. */
  .pp-head .pp-meta-game { flex-basis:100%; }
  .pp-head .pp-meta-game > .pp-nw:has(> .pp-sep) { flex-basis:100%; }
  .pp-head .pp-meta-game .pp-sep { display:none; }
  /* UI-437: "Wk 4 @ Browns," ran 1px past a 320 screen at the real 200% text setting; the
     opponent may drop under "Wk 4 @". */
  .pp-head .pp-started .pp-nw { flex-wrap:wrap; white-space:normal; }
  /* An injury chip ("Week 6: Out, ankle") wraps rather than running off the screen. */
  .pp-head .pp-id-tags .pp-chip { max-width:100%; white-space:normal; }
}
/* Answer card (UI-407): at 320 the "Lines as of" time and the matchup chip don't break, so
   they widened the card's text to 352px. Under 12em of its own text (200% text on a phone;
   the default size is always 14em or wider) both may wrap. */
.pp-answer-body { container-type:inline-size; }
@container (max-width: 12em) {
  .pp-answer-body .pp-lines-asof { white-space:normal; }
  .pp-answer-body .ar-mu { height:auto; min-height:1.375rem; padding-block:0.125rem; white-space:normal; }
}
/* Under 40em of the page's own text (200% text up to ~1300px wide; the default size only
   below 640px, where the card is one column anyway) the pick buttons go under the answer
   rather than squeezing it into a sliver beside them. */
.pp { container:pp / inline-size; }
@container pp (max-width: 40em) {
  .pp-answer { grid-template-columns:minmax(0, 1fr); }
}
/* 200% text on a phone (the default size is always 17em or wider): Under and Over side by
   side ran into each other ("U 43.5 -11O 43.5"), so they stack. */
@container pp (max-width: 14em) {
  html body[data-layout] .pp .pp-answer .pp-pick-prices { grid-template-columns:minmax(0, 1fr); }
}
/* Desktop at a large text size (UI-405): beside the photo and the prop switcher + Share the
   name and meta line got a sliver ("DK / METCALF", one letter per line at 1024). On the
   three-column desktop head, under 50em of its own text (200% text up to ~1700px wide), the
   switcher and Share drop to their own row. At the default size that head is always 53em or
   wider, so nothing here applies; narrower screens have their own rules below. */
@media (min-width: 56.0625rem) {
  @container (max-width: 50em) {
    .pp-head .pp-id { grid-column:2 / -1; }
    .pp-head .pp-head-tools { grid-column:1 / -1; flex-wrap:wrap; }
    /* The game and the spread/total each get their own line, so no line starts with a dot. */
    .pp-head .pp-meta > :is(.pp-meta-game, .pp-meta-lines) { flex-basis:100%; }
    .pp-head .pp-meta > * + .pp-meta-game > .pp-nw:first-child::before, .pp-head .pp-meta > .pp-meta-lines::before { content:none; }
  }
}

/* Evidence tabs */
/* "See injuries" and the other links scroll here: clear the sticky header. */
.pp-evidence { scroll-margin-top:calc(var(--header-height) + 0.5rem); }
.pp-etabs { display:flex; gap:0.375rem; overflow-x:auto; scrollbar-width:none; padding:0.3125rem; margin:-0.1875rem -0.3125rem 0; }
.pp-etabs::-webkit-scrollbar { display:none; }
/* UI-437: on a phone the tabs are a 2x2 grid; with 200% text (under 12em of their own text;
   the default size is always 17em or wider) "Defense" and "Injuries" didn't fit a half-width
   tab, so each tab takes the full row. */
.pp-etabs { container-type:inline-size; }
@container (max-width: 12em) {
  .pp-etabs .pp-etab { grid-column:1 / -1; }
}
.pp-etab { flex:0 0 auto; display:inline-flex; align-items:baseline; gap:0.375rem; height:2.375rem; padding:0 0.875rem; border:2px solid var(--line); border-radius:var(--r-data); background:none; color:var(--muted); font:800 0.8125rem var(--font-body); cursor:pointer; white-space:nowrap; align-items:center; }
.pp-etab small { font:600 0.6875rem var(--font-body); color:var(--muted); }
.pp-etab[aria-selected=true] { background:var(--selected-bg); color:var(--ink); border-color:var(--accent); }
.pp-etab[aria-selected=true] small { color:var(--ink); opacity:0.75; }
.pp-epanel { display:grid; gap:0.75rem; min-width:0; }
.pp-epanel:focus-visible { outline:3px solid var(--accent); outline-offset:4px; border-radius:var(--r-card); }

/* Game logs: rows tinted by result */
/* Positioned so the rows' off-screen "Hit"/"Miss" labels scroll with the table instead of
   widening the page (320 at 200% text, UI-407). */
.pp-table-scroll { position:relative; overflow-x:auto; }
.pp-log { width:100%; border-collapse:separate; border-spacing:0 0.375rem; font-size:0.9375rem; }
.pp .pp-log th, .pp .pp-log td { background:none; border:0; padding:0.625rem 0.625rem; text-align:left; white-space:nowrap; }
.pp-log thead th { padding-top:0; padding-bottom:0; font:700 0.6875rem var(--font-body); color:var(--muted); }
.pp .pp-log tbody tr > * { background:var(--surface-raised); }
.pp .pp-log tbody tr.r-hit > * { background:var(--good-bg); }
.pp .pp-log tbody tr.r-miss > * { background:var(--bad-bg); }
.pp .pp-log tbody tr.r-push > * { background:var(--thin-bg); }
.pp .pp-log tbody tr > :first-child { border-radius:var(--r-card) 0 0 var(--r-card); }
.pp .pp-log tbody tr > :last-child { border-radius:0 var(--r-card) var(--r-card) 0; }
.pp-log tbody th { font:700 0.8125rem var(--font-mono); color:var(--muted); }
.pp-log-who { font-weight:700; white-space:normal !important; }
.pp-log-who small { color:var(--muted); font:700 0.6875rem var(--font-mono); }
.pp-log .profile-name-button { padding:0; border:0; background:none; color:var(--ink); font:700 0.9375rem var(--font-body); cursor:pointer; text-align:left; }
.pp-log .profile-name-button:hover { color:var(--accent); }
/* The Defense tab's Player cell: a small headshot beside the name and team (UI-161). */
.pp-who { display:flex; align-items:center; gap:0.5rem; }
.pp-who-name { min-width:0; }
.pp-num { text-align:right !important; font:700 0.9375rem var(--font-mono); }
.pp-muted { color:var(--muted); font-weight:400; }
.pp-log tr.r-hit .pp-vs { color:var(--good); }
.pp-log tr.r-miss .pp-vs { color:var(--bad); }
.pp-log tr.r-none .pp-vs { color:var(--muted); font-weight:400; }
/* UI-624: a partial game keeps its row, muted and tagged; the vs-line cell takes no colour. */
/* A game outside his season stats (the Cup final) reads the same; its tag wraps at the dot. */
.pp .pp-log tbody tr:is(.pp-partial, .pp-off-stats) > * { background:var(--surface-raised); color:var(--muted); }
.pp-log tr:is(.pp-partial, .pp-off-stats) .pp-vs { color:var(--muted); font-weight:400; }
.pp-log tr:is(.pp-partial, .pp-off-stats) :is(.profile-name-button, .pp-log-who) { color:var(--muted); }
.pp-partial-tag, .pp-off-stats-tag { display:block; margin-top:0.125rem; font:700 0.6875rem var(--font-mono); color:var(--muted); white-space:nowrap; }
.pp-off-stats-tag { white-space:normal; }
.pp-off-stats-tag > span { white-space:nowrap; }
.pp-ubar-partial i { background:var(--muted); opacity:0.45; }
.pp-ubar-partial span { color:var(--muted); }
/* UI-630: the Defense tab under legacy-v3: opponents at his position, each against his own line, game by game. */
.pp-own-summary { margin:0 0 0.5rem; font-size:0.875rem; line-height:1.45; color:var(--muted); }
.pp-own-summary strong { color:var(--ink); font-weight:700; }
.pp-own-fallback { white-space:nowrap; }
.pp .pp-own-log tbody tr.pp-own-game > * { padding:0.75rem 0.25rem 0.125rem; background:none; border-radius:0; color:var(--muted); font:700 0.75rem var(--font-body); white-space:normal; }
.pp-own-game .pp-logo.team-logo-badge { width:1rem; height:1rem; margin:0 0.25rem 0 0; }
.pp-own-usual { font-style:italic; }
.pp-own-usual small { font:700 0.625rem var(--font-body); font-style:normal; letter-spacing:0.04em; text-transform:uppercase; }

/* Usage */
.pp-usage-body { display:grid; grid-template-columns:minmax(0, 1fr) 12.5rem; gap:1.25rem; }
.pp-usage-chart { display:flex; flex-direction:column; gap:0.375rem; }
.pp-ubars { flex:1 1 auto; min-height:8rem; display:flex; align-items:flex-end; gap:1rem; border-bottom:2px solid var(--line); padding-bottom:1.5rem; position:relative; }
.pp-ubar { flex:1 1 0; max-width:6rem; height:100%; display:flex; flex-direction:column; justify-content:flex-end; align-items:center; gap:0.25rem; position:relative; }
.pp-ubar span { font:700 0.8125rem var(--font-mono); }
.pp-ubar i { width:100%; box-sizing:border-box; background:var(--accent); border-radius:0; }
.pp-ubar small { position:absolute; bottom:-1.375rem; font:700 0.6875rem var(--font-mono); color:var(--muted); }
.pp-ustats { display:flex; flex-direction:column; gap:0.5rem; }
.pp-ustat { flex:1 1 auto; min-height:2.5rem; display:flex; justify-content:space-between; align-items:center; gap:0.5rem; padding:0 0.75rem; background:var(--surface-raised); border-radius:var(--r-control); }
.pp-ustat span { font-size:0.8125rem; font-weight:700; color:var(--muted); }
.pp-ustat b { font:700 1rem var(--font-mono); }

/* Injuries */
.pp-injury { display:flex; align-items:center; gap:0.625rem; min-height:3.5rem; padding:0.375rem 0.75rem; background:var(--surface-raised); border-radius:var(--r-control); }
.pp-injury > div { flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:0.125rem; }
.pp-injury-name { font-weight:800; font-size:0.9375rem; }
.pp-injury-name small { font:700 0.6875rem var(--font-mono); color:var(--muted); }
.pp-injury .profile-name-button { padding:0; border:0; background:none; color:var(--ink); font:inherit; cursor:pointer; }
.pp-injury .profile-name-button:hover { color:var(--accent); }
.pp-injury .pp-logo.team-logo-badge { width:1rem; height:1rem; margin:0 0.25rem 0 0; }

/* Fantasy (a connected league): owner, season in the league's scoring, weekly bars. */
.pp-fantasy { display:flex; flex-direction:column; gap:0.875rem; padding:1.25rem 1.5rem; }
.pp-fantasy h2 small { font:600 0.875rem var(--font-body); color:var(--muted); }
.pp-fx-owner { display:flex; flex-wrap:wrap; align-items:center; gap:0.375rem; margin:0; font-size:0.875rem; font-weight:700; }
.pp-fx-code { display:inline-flex; align-items:center; height:1.375rem; padding:0 0.4375rem; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); color:var(--ink); font:800 0.6875rem var(--font-mono); letter-spacing:0.03em; }
.pp-fx-code.is-mine { background:var(--good); color:var(--accent-ink); }
.pp-fx-code.is-free { color:var(--accent); border-color:var(--accent); background:transparent; }
.pp-fx-body { display:grid; grid-template-columns:minmax(0, 1fr) minmax(0, auto); gap:1rem 2rem; align-items:end; }
.pp-fx-stats { display:grid; grid-template-columns:repeat(4, minmax(0, max-content)); gap:0.5rem; margin:0; }
.pp-fx-stat { min-width:6.5rem; display:grid; gap:0.125rem; padding:0.5rem 0.75rem; background:var(--surface-raised); border-radius:var(--r-control); }
.pp-fx-stat dt { font-size:0.6875rem; font-weight:800; letter-spacing:0.04em; text-transform:uppercase; color:var(--muted); }
.pp-fx-stat dd { margin:0; display:grid; gap:0.0625rem; }
.pp-fx-stat b { font:700 1.125rem var(--font-mono); }
.pp-fx-stat small { font-size:0.75rem; color:var(--muted); }
.pp-fx-weeks { display:grid; gap:0.375rem; justify-items:end; min-width:0; }
/* Capped bar width, right-aligned: three games draw as three slim bars, never slabs. */
.pp-fx-bars { display:flex; justify-content:flex-end; align-items:flex-end; gap:0.375rem; max-width:100%; margin:0; padding:0; overflow-x:auto; list-style:none; }
.pp-fx-week { flex:0 0 2.25rem; display:grid; grid-template-rows:auto 4.5rem auto; justify-items:center; gap:0.125rem; }
.pp-fx-week b { font:700 0.6875rem var(--font-mono); }
.pp-fx-week.is-gap b { color:var(--muted); font-weight:600; }
.pp-fx-week small { font:700 0.625rem var(--font-mono); color:var(--muted); }
.pp-fx-bar { position:relative; width:1.5rem; height:100%; border-bottom:2px solid var(--line); }
.pp-fx-bar::after { content:""; position:absolute; inset:auto 0 0; height:var(--h); border-radius:0; background:var(--accent); }
.pp-fx-week.is-boom .pp-fx-bar::after { background:var(--good); }
.pp-fx-week.is-bust .pp-fx-bar::after { background:var(--bad); }

/* Mobile pick bar: hidden on wide screens (the pick lives in the banner). */
.pp-action { display:none; }

/* A scorer prop has one price: it takes the whole row, never half a cell. */
.pp :is(.pp-pick-prices, .pp-action-prices) .bet-side:only-child { grid-column:1 / -1; }

/* Wide screens (UI-21): the alt-line ladder sits beside the chart, wrapped into a column
   as tall as the chart, instead of a strip over a chart that uses a third of the card. */
.pp-house-wrap { display:flex; flex-direction:column; gap:1rem; min-width:0; }
.pp-house-main { min-width:0; }
@media (min-width: 75.01rem) {
  .pp-house-wrap.has-ladder { display:grid; grid-template-columns:minmax(0, auto) minmax(20rem, 1fr); gap:1rem 2rem; align-items:start; }
  .pp-house-wrap.has-ladder > .pp-strip { order:2; align-content:start; }
  .pp-house-wrap.has-ladder > .pp-house-main { order:1; }
  .pp-house-wrap.has-ladder .pp-strip-nav { display:none !important; }
  .pp-house-wrap.has-ladder .pp-strip-track { flex-wrap:wrap; align-content:flex-start; overflow-x:hidden; overflow-y:auto; max-height:19.5rem; padding:0 6px 6px 0; mask-image:none !important; scroll-snap-type:none; }
  .pp-house-wrap.has-ladder .pp-strip-option { min-width:8.5rem; }
}

/* Touch: links and small buttons get a 44px hit area without growing their row. */
@media (pointer: coarse) {
  .pp-link, .pp-crumb, .pp-crumbs a { position:relative; }
  .pp-link::after, .pp-crumb::after, .pp-crumbs a::after { content:""; position:absolute; left:-0.25rem; right:-0.25rem; top:50%; height:2.75rem; translate:0 -50%; }
  .pp-sides button { height:2.5rem; }
  .pp-house-handle { height:2.75rem; }
}

/* Narrower screens */
@media (max-width: 75rem) {
  .pp-why .ar-signal-rows { grid-template-columns:repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 56rem) {
  .pp-answer { grid-template-columns:minmax(0, 1fr); }
  html body[data-layout] .pp .pp-pick-prices { grid-template-columns:repeat(2, minmax(0, 1fr)); }
  .pp-head { grid-template-columns:auto minmax(0, 1fr); }
  .pp-head-tools { grid-column:1 / -1; }
  .pp-fx-body { grid-template-columns:minmax(0, 1fr); }
  .pp-fx-weeks { justify-items:stretch; }
  /* The spread and total get their own line: a wrap never starts a line with the dot. */
  .pp-meta > .pp-meta-lines { flex-basis:100%; }
  .pp-meta > .pp-meta-lines::before { content:none; }
}
@media (max-width: 40rem) {
  .pp { gap:1rem; }
  /* Reserve the phone pick bar plus a small gap when bringing a card, legend or focused
     control into view. Page-end padding alone does not protect an interior chart. */
  html:has(body[data-active-view=player] .pp.has-action) { --pp-action-clearance:calc(8.75rem + var(--bottom-nav-height, env(safe-area-inset-bottom, 0px))); scroll-padding-bottom:var(--pp-action-clearance); }
  html body[data-active-view=player]:has(.pp.has-action) { padding-bottom:var(--pp-action-clearance); }
  html body[data-active-view=player]:has(.pp.has-action) .back-to-top { bottom:9rem; }
  /* While the pick bar shows, Back to top would sit over the content just above it. */
  html body[data-active-view=player]:has(.pp-action.is-shown) .back-to-top { display:none; }
  .pp-head { grid-template-columns:auto minmax(0, 1fr) auto; gap:0.625rem 0.75rem; }
  /* The name sits beside the photo; the meta line gets the full width below. */
  .pp-id { display:contents; }
  .pp-head :is(.pp-meta, .pp-moved, .pp-started, .pp-id-tags, .pp-late-note) { grid-column:1 / -1; }
  .pp-meta { row-gap:0.25rem; }
  .pp-meta > :first-child { flex-basis:100%; }
  .pp-meta > * + .pp-meta-game > .pp-nw:first-child::before { content:none; }
  .pp-photo { width:3.75rem; height:3.75rem; }
  .pp h1 { font-size:1.75rem; }
  .pp-meta { font-size:0.8125rem; }
  .pp-meta-lines, .pp-id-tags .pp-season { display:none; }
  .pp-head-tools { display:contents; }
  .pp-share { grid-row:1; grid-column:3; width:2.75rem; padding:0; justify-content:center; }
  .pp-share span { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
  .pp-switch { grid-column:1 / -1; }
  .pp-switch-label { display:none; }
  .pp-switch-button { flex:1 1 auto; }
  .pp-switch-button .pp-switch-name { flex:1 1 auto; text-align:left; }
  /* At a large text size the button stays the row's width: "2 more" and the arrow wrap
     under the prop name instead of running off the screen (UI-261). */
  .pp-switch-button { min-width:0; max-width:100%; height:auto; min-height:2.75rem; flex-wrap:wrap; }
  .pp-menu { left:0; right:0; min-width:0; }
  .pp-answer { padding:1.125rem 1.125rem 1rem 1.375rem; border-radius:var(--r-card); }
  .pp-answer-text { font-size:1.5rem; }
  .pp-chart-card, .pp-pct, .pp-evidence, .pp-fantasy { padding:1rem; }
  .pp-fx-stats { grid-template-columns:repeat(2, minmax(0, 1fr)); }
  .pp-fx-stat { min-width:0; }
  /* The roster's tag chip: 11px, as Fantasy's on a phone. */
  .pp-fantasy .usage-injury { font-size:0.6875rem; }
  .pp-chart-card { margin-inline:0; }
  .pp-house { --pp-bar:3rem; --pp-gap:0.25rem; --pp-rail:4.75rem; }
  .pp-hbar.is-gap { flex-basis:1.5rem; }
  .pp-house-plot { height:13rem; }
  .pp-hbar-value { font-size:0.6875rem; }
  .pp-hbar-label, .pp-hbar-label small { font-size:0.6875rem; }
  /* Evidence tabs: a 2x2 grid, so Usage and Injuries never sit off-screen with no cue. */
  .pp-etabs { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); overflow:visible; }
  .pp-etabs .pp-etab:last-child:nth-child(odd) { grid-column:1 / -1; }
  .pp-etab { height:auto; min-height:2.75rem; flex-wrap:wrap; justify-content:center; gap:0 0.375rem; padding:0.25rem 0.625rem; border-radius:var(--r-card); white-space:normal; text-align:center; line-height:1.2; }
  .pp-house-count strong { font-size:1.625rem; }
  /* Chart header: Reset keeps its room beside the Over/Under toggle (no empty row of its
     own), with a shorter label; the count gets the next row. */
  .pp-chart-card .pp-card-head { display:grid; grid-template-columns:auto minmax(0, 1fr); align-items:center; gap:0.625rem 0.75rem; }
  .pp-chart-card :is(.pp-chart-title, .pp-chart-tools) { display:contents; }
  .pp-chart-card .pp-chart-title h2 { grid-column:1 / -1; }
  .pp-chart-card .pp-sides { grid-row:2; grid-column:1; }
  .pp-chart-card .pp-reset-slot { grid-row:2; grid-column:2; justify-self:start; }
  /* No toggle (TD scorer props): Reset sits beside the count instead. */
  .pp-chart-card .pp-card-head:not(:has(.pp-sides)) .pp-house-count { grid-row:2; grid-column:1; }
  .pp-chart-card .pp-house-count { grid-row:3; grid-column:1 / -1; }
  .pp-chart-card .pp-house-avg { grid-row:4; grid-column:1 / -1; }
  .pp-chart-card .pp-house-prior { grid-row:5; grid-column:1 / -1; justify-self:start; padding-left:0; border-left:0; }
  .pp-hbar.is-divider { flex-basis:1.5rem; }
  .pp-reset { padding:0 0.75rem; }
  .pp-reset :is(.pp-reset-to, .pp-reset-count) { display:none; }
  /* Never wider than the strip itself (200% text at 320, UI-407). */
  .pp-strip-option { min-width:min(8rem, 100%); }
  .pp-strip-nav { display:none !important; }
  /* Chips line up with the left edge, so only the right end fades to say there's more. */
  .pp-strip { --fade:1.5rem; }
  .pp-strip.has-before .pp-strip-track { mask-image:none; }
  .pp-strip.has-before.has-after .pp-strip-track { mask-image:linear-gradient(to right, #000 calc(100% - var(--fade)), transparent); }
  .pp .pp-pick-prices .bet-side .bet-side-action { display:none; }
  .pp-why .ar-signal-rows { grid-template-columns:minmax(0, 1fr); }
  html body[data-layout] .pp-why .ar-sig-row { min-height:0; }
  .pp-pct-scale, .pp-pct-row { grid-template-columns:6.5rem minmax(0, 1fr) 3.5rem; }
  .pp-pct-scale { grid-template-columns:6.5rem repeat(3, minmax(0, 1fr)) 3.5rem; }
  .pp-pct-name { font-size:0.8125rem; }
  .pp-usage-body { grid-template-columns:minmax(0, 1fr); }
  .pp-log { font-size:0.8125rem; }
  .pp .pp-log th, .pp .pp-log td { padding:0.5rem 0.375rem; }
  .pp .pp-log :is(th, td):nth-child(4) { display:none; }
  /* The own-line table has four columns, all kept: his line is the point of it (UI-630). */
  .pp .pp-own-log :is(th, td):nth-child(4) { display:table-cell; }
  .pp-own-log .pp-mini-avatar { display:none; }
  .pp .pp-own-log :is(th, td) { padding-left:0.3rem; padding-right:0.3rem; }
  .pp-num { font-size:0.8125rem; }
  .pp-action { position:fixed; z-index:30; left:0.75rem; right:0.75rem; bottom:calc(0.75rem + env(safe-area-inset-bottom, 0px)); display:flex; flex-direction:column; gap:0.375rem; padding:0.5rem;
    background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card); box-shadow:none;
    visibility:hidden; opacity:0; translate:0 calc(1rem * var(--move)); transition:opacity var(--dur-fast) var(--ease-out), translate var(--dur-fast) var(--ease-out), visibility 0s linear var(--dur-fast); }
  /* Shown once the banner's own pick buttons have scrolled away (watchPick). */
  .pp-action.is-shown { visibility:visible; opacity:1; translate:0 0; transition:opacity var(--dur-fast) var(--ease-out), translate var(--dur-fast) var(--ease-out); }
  .pp-action-id { display:flex; justify-content:space-between; gap:0.5rem; padding:0 0.25rem; font-size:0.8125rem; }
  .pp-action-id .pp-mono { font-size:0.75rem; }
  html body[data-layout] .pp .pp-action-prices { display:grid; grid-template-columns:1.6fr 1fr; gap:0.5rem; width:auto; }
  html body[data-layout] .pp .pp-action-prices .bet-side { min-height:3rem; padding:0 0.5rem; font-size:0.9375rem; }
  .pp .pp-action-prices .bet-side .bet-side-action { display:none; }
}
@media (prefers-reduced-motion: reduce) {
  .pp-answer-text, .pp-pct-fill, .pp-menu { animation:none; }
  .pp-house-line, .pp-house-book, .pp-house-handle-wrap, .pp-hbar.is-next .pp-hbar-fill { transition:none; }
}

/* Small headshots beside player names in lists (UI-161): the Defense tab's players and
   the Injuries tab. Initials show until the photo loads, and stay when there's none
   (players.css .has-photo). */
.pp-mini-avatar { position:relative; display:block; flex:0 0 2rem; width:2rem; height:2rem; padding:0; overflow:hidden; border:2px solid var(--line); border-radius:var(--r-control); background:var(--surface-raised); box-sizing:border-box; cursor:pointer; }
span.pp-mini-avatar { cursor:default; }
html body[data-layout] .pp-mini-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] .pp-mini-avatar .player-headshot { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:center top; }
.pp-mini-avatar:hover { border-color:var(--accent); }

/* UI-198: keep each game's week, venue and opponent readable, including history
   and missed games. Dense charts scroll as one plot/slider coordinate system. */
/* The slider is centered on the plot's top at its maximum. Keep its full handle,
   keyboard outline and enlarged touch target inside the scrolling clip. */
.pp-house-scroll { max-width:100%; overflow-x:auto; overscroll-behavior-x:contain; padding:2.25rem 0.5rem 0.25rem; margin-inline:-0.5rem; }
.pp-house-scroll:focus-visible { outline:2px solid var(--accent); outline-offset:2px; border-radius:var(--r-data); }
.pp-house-scroll .pp-house { --pp-min:2rem; min-width:calc(var(--n, 10) * (var(--pp-min) + var(--pp-gap)) + var(--pp-rail)); margin-bottom:4.5rem; }
.pp-house-scroll .pp-hbar:not(.is-divider) { min-width:var(--pp-min); }
.pp-house-scroll .pp-hbar.is-gap { flex:1 1 0; }
.pp-house-scroll .pp-hbar.is-gap .pp-hbar-gap { left:20%; right:20%; }
.pp-house-scroll .pp-hbar-label { width:100%; }
.pp-house-scroll .pp-hbar-label .pp-slot-opponent { color:var(--ink); }
.pp-house-scroll .pp-hbar:is(.is-prior, .is-partial) .pp-slot-opponent { color:var(--muted); }
.pp-house-scroll .pp-hbar.is-next .pp-slot-opponent { color:var(--accent); }
.pp-house-scroll .pp-hbar-label .pp-slot-status { margin-top:0.125rem; }
.pp-chart-scroll-hint { display:none; margin-bottom:0.25rem; }
.pp-house-main:has(.pp-house-scroll.is-scrollable) .pp-chart-scroll-hint { display:block; }

/* UI-288: above phone width a short season used a third of the card (4.5rem bars packed
   to the left). Each game gets a wider slot (--pp-slot) and its bar (--pp-bar) is centred
   in it, so a few games spread across the card; a full season still shrinks the slots
   evenly to fit, as before. Phones keep their sizes (40rem block above). */
@media (min-width: 40.01rem) {
  .pp-house { --pp-slot:12rem; --pp-bar:6.5rem; grid-template-columns:minmax(0, calc(var(--n, 10) * var(--pp-slot))) var(--pp-rail); }
  .pp-hbar { max-width:var(--pp-slot); }
  .pp-house .pp-hbar .pp-hbar-fill { left:max(0px, (100% - var(--pp-bar)) / 2); right:max(0px, (100% - var(--pp-bar)) / 2); width:auto; }
  .pp-house-plot { height:18rem; }
  .pp-hbar-value { font-size:0.875rem; }
  .pp-hbar-label, .pp-hbar-label small { font-size:0.75rem; }
}
