:root {
  /* Light layout — match the reference roster / histogram screen */
  --color-bg: #f2f3f5;
  --color-bg-elevated: #ffffff;
  --color-surface: #ffffff;
  --color-surface-solid: #ffffff;
  --color-surface-raised: #e8eaed;
  --color-text: #1a1d24;
  --color-text-muted: #5c6575;
  --color-text-inactive: #8b93a0;
  --color-border: rgba(0, 0, 0, 0.1);
  --color-border-strong: rgba(0, 0, 0, 0.18);
  --color-accent: #e0233f;
  /* Clickable chrome (docks, hero stat links) — matches selected histogram bars. */
  --color-link: #4e8cc6;
  --color-bar: #bdbec4;
  --color-bar-dark: #6b7382;
  --color-marker: #111111;
  --color-importance-bar: #6a9ec4;
  --color-status-positive: #1f9d4b;
  --color-status-caution: #c49212;
  --color-selection-fill: #111111;
  --color-selection-text: #ffffff;
  --color-selection-frame: #ffffff;
  --color-chart-hover-fill: #d8dde6;
  --color-chart-hover-text: #1a1d24;
  --color-chart-hover-frame: #ffffff;
  /* Selected chart while browsed/hovered — lighter than --color-hover-fill. */
  --color-chart-focus-browse-fill: rgba(0, 0, 0, 0.035);
  --chart-frame-hover-shadow:
    0 3px 28px rgba(0, 0, 0, 0.28),
    0 1px 10px rgba(0, 0, 0, 0.16),
    0 0 0 1px rgba(0, 0, 0, 0.06);
  /*
   * Inset for chart-frame box-shadows inside overflow-clipped catalog parents.
   * Bump this (not overflow) when enlarging --chart-frame-hover-shadow blur.
   * Panel width grows by 2× bleed so plot width stays ~content width.
   */
  --chart-frame-shadow-bleed: 40px;
  --chart-panel-content-width: 22rem;
  --chart-panel-width: calc(
    var(--chart-panel-content-width) + 2 * var(--chart-frame-shadow-bleed)
  );
  /* Matte around portrait + name; roomier so list text isn’t flush to the frame. */
  --selection-matte: 9px;
  /* Horizontal room so the selected frame isn’t clipped at strip ends. */
  --selection-frame-overhang: max(
    8px,
    calc(
      (
          var(--portrait-inner) + 2 * var(--selection-matte) -
            var(--portrait-slot)
        ) / 2 + 2px
    )
  );
  --selection-photo-stroke: 1.5px;
  --selection-name-gap: 0.4rem;
  --color-nav-fill: #1a1d24;
  --color-nav-text: #ffffff;
  --color-hover-fill: rgba(0, 0, 0, 0.05);
  --radius-panel: 10px;
  --radius-tile: 8px;
  --radius-capsule: 999px;
  --scrollbar-thumb: rgba(0, 0, 0, 0.2);
  --scrollbar-thumb-hover: rgba(0, 0, 0, 0.34);
  /* Shared scroll-pane component — adjust inset/size here for all scroll lists. */
  --scroll-pane-size: 5px;
  --scroll-pane-radius: 2px;
  --scroll-pane-track: transparent;
  --scroll-pane-thumb: var(--scrollbar-thumb);
  --scroll-pane-thumb-hover: var(--scrollbar-thumb-hover);
  --scroll-pane-inset-inline-end: 0.35rem;
  /* Cross-axis thickness for list (horizontal) + catalog (vertical) minimap thumbs. */
  --minimap-thumb-thickness: 10px;
  --minimap-thumb-thickness-active: 14px;
  /* List chrome shadow — tighter than chart frames so the strip needs no tall bleed. */
  --list-row-hover-shadow:
    0 2px 8px rgba(0, 0, 0, 0.2),
    0 1px 3px rgba(0, 0, 0, 0.1),
    0 0 0 1px rgba(0, 0, 0, 0.06);
  /* Horizontal only — vertical rhythm stays matte-tight (no scale, no tall bleed). */
  --list-row-shadow-bleed: 8px;
  --chart-aspect-w: 193;
  --chart-aspect-h: 144;
  --chart-count: 6;
  --sidebar-height: 100dvh;
  --chart-panel-gap: 0.3rem;
  --chart-row-label: 0.85rem;
  --chart-row-inner-gap: 0.08rem;
  /* Vertical space between stat chart rows — adjust this to change chart stack spacing. */
  --chart-stack-gap: 24px;
  --chart-height-min: 4px;
  --chart-height-max: 148px;
  --chart-width-max: 320px;
  --chart-meter-threshold: 14px;
  --chart-meter-segment-min-width: 12px;
  --chart-focus-bar-min-width: 4px;
  --chart-ref-slot-height: 148px;
  --chart-ref-width: calc(var(--chart-ref-slot-height) * var(--chart-aspect-w) / var(--chart-aspect-h));
  --chart-slot-height: calc(
    (
      var(--sidebar-height)
      - 5 * var(--chart-stack-gap)
    ) / var(--chart-count)
    - var(--chart-row-label)
    - var(--chart-row-inner-gap)
  );
  --chart-height: clamp(
    var(--chart-height-min),
    var(--chart-slot-height),
    var(--chart-height-max)
  );
  --font-family: "Inter", "Helvetica Neue", Arial, sans-serif;
  /* Trial: 150% of prior 84/92 — revert if keeping current look. */
  --portrait-inner: 126px;
  --portrait-pad: 3px;
  --portrait-slot: 138px;
  /* Slight selected upscale from portrait center. */
  --portrait-selected-scale: 1.08;
  --selection-scale-overflow: calc(
    var(--portrait-inner) * (var(--portrait-selected-scale) - 1) / 2
  );
  /*
   * Card gutters: 4px air between adjacent frames after any matte overhang.
   */
  --roster-card-gap: calc(
    max(
      0px,
      var(--portrait-inner) + 2 * var(--selection-matte) - var(--portrait-slot)
    ) + 4px
  );
  --selection-neighbor-gap: 0px;
  --portrait-label-size: 0.58rem;
  --player-list-thumb: 4.25rem;
  --player-list-name-size: var(--accordion-title-font-size);
  /* Match hero meta values (College / Exp) — Louisville, 9Y, etc. */
  --player-list-name-last-size: var(--hero-meta-size);
  /* Space under the name block inside the card; frame bottom matte keys off this. */
  --player-card-footer-pad: 0.55rem;
  --player-card-sort-label-line-height: 1.2;
  --player-card-sort-label-lines: 2;
  /*
   * Roster strip height (border-box): base card + matte + name/sort-stat.
   * No portrait-scale or tall shadow-bleed reservation.
   */
  --roster-track-height: calc(
    2 * var(--selection-matte) +
      var(--player-card-footer-pad) +
      var(--portrait-pad) +
      var(--portrait-inner) +
      0.2rem +
      3.4rem +
      var(--player-list-name-last-size) +
      0.08rem +
      var(--player-card-footer-pad)
  );
  --player-list-rank-size: 0.78rem;
  --player-list-width: 17.5rem;
  --player-list-row-height: calc(var(--player-list-thumb) + 0.5rem);
  --player-list-row-gap: 3px;
  --filter-menu-width: 24rem;
  /* Stacked SEARCH / TEAM / POSITION label above value inside each control.
     Horizontal inset matches the caret / clear affordance on the trailing edge. */
  --filter-control-pad-x: 0.65rem;
  --filter-inline-label-top: calc(0.42rem + 4px);
  --filter-inline-label-to-value: 0.12rem;
  --filter-value-pad-bottom: calc(0.42rem + 4px);
  --filter-menu-panel-extra: 0px;
  --filter-menu-columns-gap: 0.75rem;
  /* Match filter control value size (search / team / position). */
  --filter-control-font-size: 18px;
  /* Label row + value row + vertical padding. */
  --filter-menu-trigger-height: calc(
    var(--filter-inline-label-top) + var(--hero-chrome-caps-sm-size) +
      var(--filter-inline-label-to-value) + var(--filter-control-font-size) * 1.2 +
      var(--filter-value-pad-bottom) + 2px
  );
  --filter-menu-scroll-cue-offset: 8px;
  /* rem (vs former px) so laptop html { font-size } scales type globally. */
  --supporting-data-font-size: 0.923rem; /* 12px @ 13px root */
  --accordion-title-font-size: 1.077rem; /* 14px @ 13px root */
  /* Chart titles + filter/search/dropdown control text. */
  --flat-title-size: var(--accordion-title-font-size);
  --secondary-label-font-size: 0.769rem; /* 10px @ 13px root */
  --hero-chrome-caps-size: 0.846rem; /* 11px @ 13px root */
  --hero-chrome-caps-weight: 600;
  /* Selected / active all-caps chrome — tabs, chart names, cluster type, … */
  --hero-chrome-caps-weight-selected: 800;
  /* Compact all-caps — sit beside large figures (sort-stat on player cards, …). */
  --hero-chrome-caps-sm-size: 0.615rem; /* 8px @ 13px root */
  --hero-chrome-caps-sm-weight: 400;
  --hero-chrome-caps-sm-tracking: 0.08em;
  /* Cluster dock label + type-menu — size follows shared caps; option weight is menu-only. */
  --cluster-type-label-size: var(--hero-chrome-caps-size);
  --cluster-type-label-weight-option: 400;
  /* Shared all-caps chrome (College, RANKED BY, comparison kickers, …). */
  --hero-chrome-caps-tracking: 0.1em;
  --hero-chrome-caps-color: var(--color-text-inactive);
  --secondary-readable-color: #5c6575;
  --team-primary: #6b7382;
  --portrait-bg: #e6e8ec;
  /*
   * Shared with hero meta values (College, Exp) and player-list last names.
   * Live vw clamp — not MQ snaps — so type tracks resize with the cutout.
   */
  --hero-meta-size: clamp(1.05rem, 2.2vw, 1.5rem);
  /* Hero player name (+ ranked-by stat trial). */
  --hero-name-size: clamp(2rem, 4.2vw, 3.5rem);
  /*
   * Desktop hero cutout. Height fills the stage down from the meta row
   * (100% − chrome − 24px), then eased by --hero-photo-width-fit so the
   * floor is slightly smaller on narrower stages. Width follows height via
   * aspect-ratio (no separate vw width). Prefer this over browser zoom —
   * fractional zoom aliases histogram bars.
   */
  --hero-photo-aspect: 1.3;
  /* ~6% smaller at the 1440 min stage; full size by ~1920. Continuous.
     Divide by px so the fit factor stays unitless (valid in calc). */
  --hero-photo-width-fit: clamp(
    0.94,
    calc(0.94 + (100vw - 1440px) / 8000px),
    1
  );
  --hero-photo-offset-x: 0px;
  /* Horizontal nudge that separates two full-size cutouts so their heads
     sit side by side; shoulders intentionally overlap (alpha cutouts). */
  --hero-peek-shift: clamp(5.5rem, 11vw, 11rem);
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  font-size: 13px;
  height: 100%;
}

body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  font-family: var(--font-family);
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.4;
}

/* Flat light stage — no stadium / dark backdrop */
body::before,
body::after {
  display: none;
}

.app {
  --app-pad-top: 24px;
  --app-pad-x: 1.25rem;
  --app-pad-bottom: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  gap: calc(0.75rem + 24px);
  padding: var(--app-pad-top) var(--app-pad-x) var(--app-pad-bottom);
  border-left: 1px solid var(--color-border);
  overflow: hidden;
  background: var(--color-bg);
  transition: opacity 280ms ease, visibility 280ms ease;
}

.app:focus {
  outline: none;
}

/* Neural voice load — ghost roster/charts; voice chrome stays full strength. */
.app--voice-warm .header__leading .help-trigger,
.app--voice-warm .header__leading .header__chrome-sep,
.app--voice-warm .filters,
.app--voice-warm .slot-groups,
.app--voice-warm .main {
  opacity: 0.42;
  pointer-events: none;
  transition: opacity 0.18s ease;
}

@media (prefers-reduced-motion: reduce) {
  .app--voice-warm .header__leading .help-trigger,
  .app--voice-warm .header__leading .header__chrome-sep,
  .app--voice-warm .filters,
  .app--voice-warm .slot-groups,
  .app--voice-warm .main {
    transition: none;
  }
}

/* About / Help — ghost the roster UI under a centered card (not a separate screen). */
html.help-open .app {
  opacity: 0.42;
  pointer-events: none;
  transition: opacity 0.18s ease;
}

@media (prefers-reduced-motion: reduce) {
  html.help-open .app {
    transition: none;
  }
}

html.help-open #stat-chart-tooltip,
html.help-open #hold-press-ring,
html.filter-menu-open #stat-chart-tooltip,
html.filter-menu-open #hold-press-ring {
  display: none !important;
}

.help-screen {
  --help-content-max: 38rem;
  /* Wider About layout (intro + sources side by side). */
  --help-about-content-max: 58rem;
  /* Shared control column so mouse + keyboard instruction text align. */
  --help-affordance-gutter: 5.25em;
  position: fixed;
  inset: 0;
  z-index: 80;
  box-sizing: border-box;
  display: flex;
  /* Cross-axis top; main-axis centered (row). */
  align-items: flex-start;
  justify-content: center;
  height: 100dvh;
  padding: clamp(1.25rem, 4dvh, 2.5rem) 1.5rem;
  overflow: hidden;
  background: transparent;
  color: var(--color-text);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 180ms ease, visibility 180ms ease;
  cursor: default;
}

html.help-open .help-screen {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.help-screen[hidden] {
  display: none;
}

html.help-open .help-screen[hidden] {
  display: flex;
}

.help-screen__panel {
  /* Same elevated card language as neural-voice warm status. */
  position: relative;
  box-sizing: border-box;
  width: 100%;
  max-width: var(--help-content-max);
  max-height: min(90dvh, 52rem);
  margin: 0;
  flex: 0 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  padding: clamp(1.35rem, 3.2dvh, 1.85rem) clamp(1.5rem, 3.5vw, 2.1rem)
    clamp(1.45rem, 3.4dvh, 1.95rem);
  overflow: hidden;
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-panel);
  box-shadow:
    0 10px 36px rgba(0, 0, 0, 0.12),
    0 2px 8px rgba(0, 0, 0, 0.06);
  cursor: default;
  animation: help-panel-in 180ms ease-out both;
  transition: max-width 160ms ease;
}

.help-screen__panel[data-help-tab="about"] {
  max-width: var(--help-about-content-max);
}

.help-screen__close {
  /* Same filled disc + × as .cluster-dock--open .cluster-dock__toggle. */
  --cluster-dock-toggle-size: 36px;
  position: absolute;
  top: 0.7rem;
  right: 0.7rem;
  z-index: 1;
  box-sizing: border-box;
  display: block;
  width: var(--cluster-dock-toggle-size);
  height: var(--cluster-dock-toggle-size);
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-selection-fill);
  cursor: pointer;
}

.help-screen__close:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

@keyframes help-panel-in {
  from {
    opacity: 0;
    transform: translateY(0.35rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .help-screen__panel {
    animation: none;
  }
}

.help-screen__tabs {
  display: flex;
  flex-wrap: wrap;
  flex: 0 0 auto;
  gap: 0.85rem 1.35rem;
  margin: 0 0 clamp(0.95rem, 2.4dvh, 1.35rem);
  /* Leave room for the absolute close control. */
  padding: 0 2.25rem clamp(0.75rem, 1.8dvh, 1rem) 0;
  border-bottom: 1px solid var(--color-border);
}

.help-screen__tab {
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--color-link);
  cursor: pointer;
}

.help-screen__tab.is-active {
  color: var(--color-text);
  font-weight: var(--hero-chrome-caps-weight-selected);
}

.help-screen__tab:hover:not(.is-active) {
  color: var(--color-text);
}

.help-screen__tab:focus-visible {
  outline: 2px solid var(--color-link);
  outline-offset: 3px;
}

.help-screen__pane {
  flex: 1 1 auto;
  min-height: 0;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.help-screen__pane[hidden] {
  display: none;
}

.help-screen__brand {
  margin: 0 0 0.45rem;
  font-size: clamp(1.55rem, 3.2vw, 2.15rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.1;
  color: var(--color-text);
}

.help-screen__title {
  margin: 0 0 0.55rem;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.25;
  color: var(--color-text);
}

.help-screen__lead,
.help-screen__body {
  margin: 0;
  max-width: 58ch;
  font-size: 0.9375rem;
  font-weight: 500;
  /* Body copy: never tighten tracking — default spacing reads cleaner. */
  letter-spacing: 0;
  line-height: 1.55;
  color: var(--color-text-muted);
}

.help-screen__body--follow {
  margin-top: 0.85rem;
}

.help-screen__body + .help-screen__list {
  margin-top: 0.55rem;
}

.help-screen__section {
  margin-top: 1.35rem;
}

.help-screen__pane > .help-screen__section:first-child {
  margin-top: 0;
}

.help-screen__heading {
  margin: 0 0 0.55rem;
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  text-transform: none;
  color: var(--color-text);
  line-height: 1.3;
}

.help-screen__list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  max-width: none;
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1.5;
  color: var(--color-text-muted);
}

.help-screen__list--sources {
  margin-top: 0.75rem;
  max-width: none;
  gap: 0.7rem;
}

.help-screen__about-columns {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  column-gap: clamp(1.25rem, 3vw, 2rem);
  align-items: start;
}

.help-screen__about-col {
  min-width: 0;
}

.help-screen__section--sources {
  margin-top: 0;
}

.help-screen__pane--about .help-screen__lead,
.help-screen__pane--about .help-screen__body,
.help-screen__pane--about .help-screen__list {
  max-width: none;
}

@media (max-width: 720px) {
  .help-screen__about-columns {
    grid-template-columns: 1fr;
    row-gap: 0.25rem;
  }

  .help-screen__section--sources {
    margin-top: 1.35rem;
  }
}

.help-screen__source-label {
  color: var(--color-text);
  font-weight: 700;
}

.help-screen__link {
  color: var(--color-link);
  text-decoration: underline;
  text-underline-offset: 0.12em;
}

.help-screen__link:hover {
  color: var(--color-text);
}

.help-screen__link:focus-visible {
  outline: 2px solid var(--color-link);
  outline-offset: 2px;
}

.help-screen__list code {
  font-size: 0.88em;
  font-weight: 600;
  color: var(--color-text);
}

.help-screen__source-links {
  margin: 0.95rem 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.1rem;
  max-width: none;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.4;
}

.help-screen__list--affordances {
  gap: clamp(0.35rem, 1dvh, 0.55rem);
}

.help-screen__affordance {
  display: grid;
  grid-template-columns: var(--help-affordance-gutter) minmax(0, 1fr);
  column-gap: 0.45em;
  align-items: center;
  min-width: 0;
}

.help-screen__affordance-icon {
  justify-self: start;
  width: 1.5em;
  height: 1.5em;
  color: var(--color-text-muted);
}

/* Font Awesome hand-pointer — white + black outline (cursor-like). */
.help-screen__affordance-icon--cursor {
  width: 1.25em;
  height: 1.5em;
  overflow: visible;
}

.help-screen__affordance-keys {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  gap: 0.2em;
  min-width: 0;
}

.help-screen__affordance-label {
  min-width: 0;
  color: var(--color-text-muted);
  font-weight: 500;
}

.help-screen__affordance-verb {
  color: var(--color-text);
  font-weight: 700;
}

.help-screen__list kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.4em;
  min-height: 1.4em;
  padding: 0.14em 0.4em;
  border: 1px solid var(--color-border-strong);
  border-radius: 3px;
  background: var(--color-surface-raised);
  font: inherit;
  font-size: 0.875em;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  color: var(--color-text);
}

.help-screen__key-glyph {
  display: block;
  width: 0.85em;
  height: 0.85em;
}

/*
 * Minimum usable viewport (known-good layout: 1440x800).
 * `html.viewport-too-small` is toggled from an inline script in index.html
 * using window.innerWidth / innerHeight — keep those literals in sync.
 */
.viewport-gate {
  display: none;
  box-sizing: border-box;
  height: 100dvh;
  padding: 2rem 1.5rem;
  place-content: center;
  text-align: center;
  background: var(--color-bg);
  color: var(--color-text);
}

.viewport-gate__title {
  margin: 0;
  font-size: 1.385rem; /* 18px @ 13px root */
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.3;
}

.viewport-gate__body {
  margin: 0.65rem 0 0;
  max-width: 26rem;
  justify-self: center;
  font-size: 1rem;
  font-weight: 500;
  color: var(--color-text-muted);
  line-height: 1.45;
}

.viewport-gate__size {
  margin: 1.15rem 0 0;
  justify-self: center;
  font-size: 0.923rem; /* 12px @ 13px root */
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
  line-height: 1.4;
}

.viewport-gate__size--min {
  margin-top: 0.25rem;
  color: var(--color-text-muted);
  font-weight: 500;
}

html.viewport-too-small .app {
  display: none !important;
}

html.viewport-too-small .help-screen {
  display: none !important;
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

html.viewport-too-small .viewport-gate {
  display: grid;
  position: relative;
  z-index: 100;
}

.cluster-stack {
  /* Row 3 of the .player-hero__info grid — its own content height is what
     positions Experience's row (see .cluster-bar--hairstyle-anchor below, which reuses
     --cluster-row-gap so both land on the same visual top edge). */
  grid-column: 1;
  grid-row: 3;
  /* Grid items default to min-width:auto, so once College's open pack (a
     fixed, large inline width) sits inside this column, its *content*
     min-size forces column 1's "1fr" track to grow to fit it — pushing the
     grid's own right edge outward and, with it, anything placed relative to
     that edge (Experience's grid area spans both columns). min-width:0 opts this
     item out of that contribution: the track stays sized to the container,
     and an open pack simply overflows it visually (already clipped by
     .player-hero's overflow:clip) instead of dragging the grid along. */
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.65rem;
  margin-top: var(--cluster-row-gap);
  pointer-events: auto;
}

.cluster-bar {
  /* Hover expand / collapse — JS re-solves overlaps; pack size stays fixed. */
  --cluster-expand-duration: 0.45s;
  --cluster-collapse-duration: 0.45s;
  /* Membership exit / survivor reflow when the filtered population changes. */
  --cluster-member-duration: 0.28s;
  /* Enter is short — new bubbles grow as soon as reflow paints them. */
  --cluster-member-enter-duration: 0.14s;
  --cluster-transform-ease: cubic-bezier(0.22, 1, 0.36, 1);
  /* Positioning context for .cluster-dock (sibling of .cluster-bar__pack). */
  position: relative;
  flex: 0 0 auto;
  width: 8rem;
  height: 2.75rem;
  min-width: 0;
  min-height: 0;
  margin-top: 0;
  padding: 0;
  border: none;
  display: block;
  overflow: visible;
}

.cluster-bar--open {
  width: min(56rem, 88vw);
  height: min(50rem, 80vh);
  min-width: 40rem;
  min-height: 36rem;
  /* Above chart-list chrome while hero overflow is unlocked. */
  z-index: 2;
  /*
   * Below 1200px an open pack starts crowding its sibling / the portrait
   * between them, so ease the *pack* down as the viewport narrows. The dock
   * label is a bar sibling (not inside the pack), so it stays put. Pure
   * function of viewport width — clamp()/calc() track a live resize natively.
   * Ramps to the max (90px) by 720px, the breakpoint where the hero
   * clusters hide entirely for the mobile layout.
   */
  --cluster-open-nudge-y: clamp(0px, calc((1200px - 100vw) * 0.1875), 90px);
  transform: none;
}

.cluster-bar--open .cluster-bar__pack {
  transform: translateY(var(--cluster-open-nudge-y));
}

/*
 * Experience dock in the hero white pocket, hung off the right edge (above
 * the portrait). Control + pack are mirrored (see mirrorX in
 * cluster-kinds.js) so the cloud fans out leftward as the dock stays put on
 * the right.
 *
 * Placed in the *same* grid row/column span as .cluster-stack (row 3 of
 * .player-hero__info), then taken out of flow with position:absolute. Per
 * the CSS Grid spec, an absolutely-positioned item with explicit grid
 * placement is positioned relative to that grid area — so `top` here is
 * relative to row 3's own top edge, which College's content defines. That's
 * what keeps the two level with each other using nothing but CSS (no JS
 * measuring College's rect on every render/resize).
 */
.cluster-bar--hairstyle-anchor {
  grid-column: 1 / -1;
  grid-row: 3;
  position: absolute;
  top: var(--cluster-row-gap);
  /* Fixed length, not a %: percentages on an absolutely-positioned grid item
     resolve against its *grid area*, not .player-hero__info's own rendered
     box — and since this area spans column 1 (which College's own intrinsic
     open-pack width can stretch well past the container), a % offset here
     silently follows College's width instead of staying anchored to the
     visible right edge, yanking Experience sideways whenever College opens. */
  right: var(--hero-cluster-inset-end, 1.3rem);
  left: auto;
  z-index: 8;
}

.cluster-bar--hairstyle-anchor.cluster-bar--open {
  /* Five-column board with enough width to preserve its label-safe min radius. */
  width: min(43.75rem, 48vw);
  height: min(36.25rem, 58vh);
  min-width: 32.5rem;
  min-height: 26.25rem;
  /* Opposite direction from College's open-pack shift above. Experience has
     much less headroom to work with than College does — the meta text sits
     right above it — so this ramps up faster and caps lower: full effect
     kicks in by ~950px instead of crawling all the way to 720px, which
     reads as more responsive through the range that matters, without
     the cap itself pushing the pack into the meta text.
     Applied to the pack only; dock is a bar sibling so it stays put. */
  --cluster-open-nudge-y: calc(-1 * clamp(0px, calc((1200px - 100vw) * 0.138), 34px));
  transform: none;
}

/* Icon leads, label trails — reads right-to-left toward the anchored edge. */
.cluster-bar--hairstyle-anchor .cluster-dock {
  left: auto;
  right: var(--hero-dock-inset, 6px);
  flex-direction: row-reverse;
}

.cluster-bar--preview .cluster-bubble--preview {
  opacity: 0.72;
}

@media (hover: hover) and (pointer: fine) {
  .cluster-bar--preview .cluster-bubble--preview.cluster-bubble--hover {
    opacity: 1;
  }
}

.cluster-bar[hidden] {
  display: none;
}

.cluster-bar__pack {
  position: relative;
  width: 100%;
  height: 100%;
  /* Visible so hover-repel can spill without resizing the bar (same for L/R docks). */
  overflow: visible;
  --cluster-transform-duration: var(--cluster-expand-duration);
}

.cluster-bar__pack--collapsing {
  --cluster-transform-duration: var(--cluster-collapse-duration);
}

/* Population membership updates — shorter motion than hover expand. */
.cluster-bar__pack--member-anim {
  --cluster-transform-duration: var(--cluster-member-duration);
}

/* JS drives translate/scale each frame — disable CSS tween so mid-frames can’t overlap. */
.cluster-bar__pack--js-anim .cluster-bubble {
  transition: none !important;
}

.cluster-dock {
  /* Pinned in the bar corner as a pack sibling — open-pack translateY can't move it. */
  --cluster-dock-toggle-size: 36px;
  /* Caps labels read high vs a symmetric circle — shift the whole icon up. */
  --cluster-dock-icon-optical-shift: -2px;
  position: absolute;
  left: var(--hero-dock-inset, 6px);
  top: 6px;
  z-index: 4;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--color-text);
  font: inherit;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 0.6rem;
  overflow: visible;
  transform: none;
  pointer-events: none;
}

.cluster-dock__type,
.cluster-dock__toggle {
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: inherit;
  cursor: pointer;
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: center;
  height: var(--cluster-dock-toggle-size);
  line-height: 1;
}

.cluster-dock__toggle {
  font: inherit;
}

/*
 * Cluster type trigger — independent of the + toggle:
 * rest: link-blue label
 * hover / focus: black label
 * selected (type menu open): black label via [aria-expanded="true"]
 * Selected weight: shared --hero-chrome-caps-weight-selected.
 */
.cluster-dock__type {
  font-family: inherit;
  font-size: var(--cluster-type-label-size);
  font-weight: var(--hero-chrome-caps-weight-selected);
  font-style: normal;
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
  color: var(--color-link);
  line-height: 1;
  white-space: nowrap;
  flex: 0 0 auto;
  width: auto;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
  text-underline-offset: 0.15em;
  transition:
    color 0.18s ease,
    text-decoration-color 0.18s ease;
}

.cluster-dock__toggle {
  position: relative;
  flex: 0 0 auto;
  width: var(--cluster-dock-toggle-size);
  min-width: var(--cluster-dock-toggle-size);
  transform: translateY(var(--cluster-dock-icon-optical-shift));
}

.cluster-dock__icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: center;
  flex: 0 0 auto;
  width: var(--cluster-dock-toggle-size);
  height: var(--cluster-dock-toggle-size);
  min-width: var(--cluster-dock-toggle-size);
  transform: translateY(var(--cluster-dock-icon-optical-shift));
}

.cluster-dock__label {
  display: inline-flex;
  align-items: center;
  align-self: center;
  height: var(--cluster-dock-toggle-size);
  font-size: var(--hero-chrome-caps-size);
  font-weight: 700;
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
  color: var(--color-link);
  line-height: 1;
  white-space: nowrap;
  flex: 0 0 auto;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
  text-underline-offset: 0.15em;
}

.cluster-type-menu {
  position: fixed;
  z-index: 80;
  min-width: 9.5rem;
  margin: 0;
  padding: 0.15rem 0;
  border: 1px solid color-mix(in srgb, var(--color-text) 18%, transparent);
  border-radius: 6px;
  background: var(--color-surface, #fff);
  box-shadow: 0 8px 24px color-mix(in srgb, var(--color-text) 12%, transparent);
  display: flex;
  flex-direction: column;
}

/* Invisible hit bridge across the label↔menu gap so hover-open doesn't drop. */
.cluster-type-menu::before,
.cluster-type-menu::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 10px;
}

.cluster-type-menu::before {
  top: -10px;
}

.cluster-type-menu::after {
  bottom: -10px;
}

.cluster-type-menu__option {
  margin: 0;
  padding: 0.55rem 0.85rem;
  border: none;
  border-bottom: 1px solid color-mix(in srgb, var(--color-text) 10%, transparent);
  background: transparent;
  color: var(--color-text);
  font-family: inherit;
  font-size: var(--cluster-type-label-size);
  font-weight: var(--cluster-type-label-weight-option);
  font-style: normal;
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
  text-align: left;
  line-height: 1;
  cursor: pointer;
}

.cluster-type-menu__option:last-child {
  border-bottom: none;
}

.cluster-type-menu__option--selected:not(:disabled) {
  font-weight: var(--hero-chrome-caps-weight-selected);
}

.cluster-type-menu__option:hover:not(:disabled):not(.cluster-type-menu__option--selected),
.cluster-type-menu__option:focus:not(:disabled):not(.cluster-type-menu__option--selected) {
  outline: none;
  background: var(--color-hover-fill);
}

.cluster-type-menu__option--disabled,
.cluster-type-menu__option:disabled {
  opacity: 0.38;
  cursor: default;
  font-weight: 400;
}

.cluster-dock__ring {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: var(--color-selection-fill);
  opacity: 0;
  overflow: visible;
  pointer-events: none;
  transition: opacity 0.18s ease;
}

/* Close while still hovered remounts the dock; hold toggle hover only so the
   label doesn’t flash selected with the +. */
.cluster-dock--ring-hold:not(.cluster-dock--open) .cluster-dock__ring {
  opacity: 1;
  color: var(--color-selection-fill);
  transition: none;
}

.cluster-dock--ring-hold:not(.cluster-dock--open) .cluster-dock__ring circle {
  fill: none;
  transition: none;
}

.cluster-dock--ring-hold:not(.cluster-dock--open) .cluster-dock__plus {
  color: var(--color-selection-fill);
}

.cluster-dock__ring circle {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5px;
  vector-effect: non-scaling-stroke;
  transition: fill 0.18s ease;
}

.cluster-dock__plus {
  /* Same absolute box as the ring so + and circle share one pixel grid. */
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  color: var(--color-link);
  transform: rotate(0deg);
  transform-origin: center center;
  overflow: visible;
  transition:
    transform 0.18s ease,
    color 0.18s ease;
}

.cluster-dock__plus path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5px;
  stroke-linecap: square;
  stroke-linejoin: miter;
  vector-effect: non-scaling-stroke;
}

/* Selected — pack open: filled disc + white × on the toggle only.
   Type label stays independent (rest/hover/menu-open). */
.cluster-dock--open .cluster-dock__ring {
  opacity: 1;
}

.cluster-dock--open .cluster-dock__ring circle {
  fill: currentColor;
  stroke: currentColor;
}

.cluster-dock--open .cluster-dock__plus {
  color: var(--color-selection-text);
  transform: rotate(45deg);
}

/* Type chooser open — label selected without painting the +. */
.cluster-dock__type[aria-expanded="true"] {
  color: var(--color-selection-fill);
  text-decoration-color: currentColor;
}

.cluster-dock__type:focus-visible,
.cluster-dock__toggle:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

.cluster-bubble {
  position: absolute;
  left: 0;
  top: 0;
  margin: 0;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 50%;
  background: rgba(220, 227, 233, 0.76);
  box-shadow: none;
  color: var(--color-text);
  font: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  z-index: 1;
  transform-origin: center center;
  will-change: transform, opacity;
  /* Transform for hover/reflow; opacity for membership enter/exit.
     Count/radius (width/height) snap — never tween magnitude.
     Selected/deselected fill paint stays instant (not transitioned). */
  transition:
    transform var(--cluster-transform-duration) var(--cluster-transform-ease),
    opacity var(--cluster-member-duration) var(--cluster-transform-ease);
}

.cluster-bubble--exit,
.cluster-bubble--enter {
  pointer-events: none;
}

.cluster-bubble--enter {
  /* Grow/fade uses the snappier enter timing (not the longer exit/reflow beat). */
  transition:
    transform var(--cluster-member-enter-duration) var(--cluster-transform-ease),
    opacity var(--cluster-member-enter-duration) var(--cluster-transform-ease);
}

.cluster-bubble--exit {
  z-index: 0;
}

/* Filtered out of the current population — stays seated, label only, inert.
   Keep full opacity so the name stays readable; mute via fill/ink instead.
   Sit under the live size ladder so dashed min discs don't compete. */
.cluster-bubble--disabled {
  pointer-events: none;
  cursor: default;
  z-index: 0;
  opacity: 1;
  color: rgba(55, 58, 64, 0.72);
  background: rgba(232, 234, 237, 0.72);
  border-color: transparent;
  border-style: solid;
  box-shadow: none;
}

.cluster-bubble--disabled .cluster-bubble__name {
  color: inherit;
  font-weight: 600;
}

@media (hover: hover) and (pointer: fine) {
  .cluster-bubble--hover {
    background: rgba(238, 243, 247, 0.86);
    border-color: rgba(0, 0, 0, 0.45);
    box-shadow: none;
    z-index: 3;
  }

  .cluster-dock.cluster-bubble--hover {
    background: transparent;
    border: none;
    z-index: 5;
  }

  /* Hover / focus — each control paints itself only. */
  .cluster-dock .cluster-dock__type:hover,
  .cluster-dock .cluster-dock__type:focus-visible {
    color: var(--color-selection-fill);
    text-decoration-color: currentColor;
  }

  .cluster-dock:not(.cluster-dock--open) .cluster-dock__toggle:hover .cluster-dock__ring,
  .cluster-dock:not(.cluster-dock--open) .cluster-dock__toggle:focus-visible .cluster-dock__ring {
    opacity: 1;
    color: var(--color-selection-fill);
  }

  .cluster-dock:not(.cluster-dock--open) .cluster-dock__toggle:hover .cluster-dock__ring circle,
  .cluster-dock:not(.cluster-dock--open)
    .cluster-dock__toggle:focus-visible
    .cluster-dock__ring
    circle {
    fill: none;
  }

  .cluster-dock:not(.cluster-dock--open) .cluster-dock__toggle:hover .cluster-dock__plus,
  .cluster-dock:not(.cluster-dock--open) .cluster-dock__toggle:focus-visible .cluster-dock__plus {
    color: var(--color-selection-fill);
  }

  .cluster-bubble--player.cluster-bubble--hover {
    box-shadow:
      0 0 0 1px rgba(0, 0, 0, 0.28),
      inset 0 0 0 1px rgba(255, 255, 255, 0.95),
      inset 0 0 0 3px rgba(0, 0, 0, 0.18);
  }

  .cluster-bubble--active.cluster-bubble--hover {
    background: var(--color-selection-fill);
    border-color: var(--color-selection-fill);
    color: var(--color-selection-text);
    box-shadow: none;
  }

  .cluster-bubble--active.cluster-bubble--player.cluster-bubble--hover {
    box-shadow:
      0 0 0 1px #000,
      inset 0 0 0 1px #fff,
      inset 0 0 0 3px rgba(0, 0, 0, 0.78);
  }
}

.cluster-bubble:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  z-index: 2;
}

/* Selected player's school/experience — inset white/black rings plus a 1px
   outer stroke so the silhouette reads 1px wider without changing pack radii. */
.cluster-bubble--player {
  border-color: rgba(0, 0, 0, 0.34);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.28),
    inset 0 0 0 1px rgba(255, 255, 255, 0.95),
    inset 0 0 0 3px rgba(0, 0, 0, 0.18);
  z-index: 2;
  background: rgba(201, 216, 228, 0.8);
}

/* Cluster filter actually applied — same selection language as roster cards. */
.cluster-bubble--active {
  background: var(--color-selection-fill);
  border-color: var(--color-selection-fill);
  color: var(--color-selection-text);
  box-shadow: none;
  z-index: 3;
}

.cluster-bubble--active.cluster-bubble--player {
  border-color: var(--color-selection-fill);
  /* Outer 1px extends the black disc; white break + membership ring stay inset. */
  box-shadow:
    0 0 0 1px #000,
    inset 0 0 0 1px #fff,
    inset 0 0 0 3px rgba(0, 0, 0, 0.78);
}

.cluster-bubble__label {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.18rem;
  width: 100%;
  height: 100%;
  max-width: none;
  padding: 0.45rem;
  text-align: center;
  line-height: 1.05;
  pointer-events: none;
}

.cluster-bubble__name {
  font-size: 0.615rem; /* 8px @ 13px root — scales with laptop html size */
  font-weight: 400;
  letter-spacing: 0;
  max-width: 90%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: clip;
  line-height: 1.1;
  text-align: center;
  color: #1a1d24;
}

.cluster-bubble__name--wrap {
  white-space: normal;
  text-overflow: clip;
  overflow-wrap: normal;
  word-break: normal;
}

.cluster-bubble__count {
  position: static;
  left: auto;
  bottom: auto;
  transform: none;
  min-width: 0;
  padding: 0;
  border-radius: 0;
  font-size: 1.15rem;
  font-weight: 800;
  line-height: 1.05;
  color: #000;
  background: none;
  text-shadow: none;
}

.cluster-bubble--active .cluster-bubble__count {
  color: var(--color-selection-text);
  background: none;
  opacity: 0.78;
}

.cluster-bubble--active .cluster-bubble__name {
  color: var(--color-selection-text);
}

.meta-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35em;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-tile);
  background: transparent;
  font: inherit;
  font-weight: 600;
  color: var(--color-text-muted);
  cursor: pointer;
  transition:
    color 0.18s ease,
    background 0.18s ease,
    border-color 0.18s ease,
    box-shadow 0.18s ease;
}

.meta-pill:hover {
  color: var(--color-text);
  border-color: rgba(255, 255, 255, 0.4);
}

.meta-pill:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Fill-select dialect — nav-style chip */
.meta-pill--active,
.meta-pill--active:hover {
  color: var(--color-nav-text);
  background: var(--color-nav-fill);
  border-color: var(--color-nav-fill);
  box-shadow: none;
}

/* Scrollable panes use edge fades instead of visible scrollbar chrome. */
.scroll-pane {
  overflow-x: hidden;
  overflow-y: auto;
  padding-inline-end: 0;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.scroll-pane::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
}

.scroll-pane::-webkit-scrollbar-track {
  background: var(--scroll-pane-track);
  margin-block: 12px;
}

.scroll-pane::-webkit-scrollbar-track-piece {
  background: transparent;
}

.scroll-pane::-webkit-scrollbar-thumb {
  background: var(--scroll-pane-thumb);
  border-radius: 999px;
  border: 0;
  min-height: 24px;
}

.scroll-pane::-webkit-scrollbar-thumb:hover {
  background: var(--scroll-pane-thumb-hover);
}

/* Hide classic Windows up/down (and left/right) scrollbar arrows. */
.scroll-pane::-webkit-scrollbar-button,
.scroll-pane::-webkit-scrollbar-button:single-button,
.scroll-pane::-webkit-scrollbar-button:double-button,
.scroll-pane::-webkit-scrollbar-button:vertical,
.scroll-pane::-webkit-scrollbar-button:horizontal,
.scroll-pane::-webkit-scrollbar-button:start,
.scroll-pane::-webkit-scrollbar-button:end,
.scroll-pane::-webkit-scrollbar-button:decrement,
.scroll-pane::-webkit-scrollbar-button:increment,
.scroll-pane::-webkit-scrollbar-button:start:decrement,
.scroll-pane::-webkit-scrollbar-button:end:increment,
.scroll-pane::-webkit-scrollbar-button:vertical:start:decrement,
.scroll-pane::-webkit-scrollbar-button:vertical:end:increment,
.scroll-pane::-webkit-scrollbar-button:vertical:start:increment,
.scroll-pane::-webkit-scrollbar-button:vertical:end:decrement,
.scroll-pane::-webkit-scrollbar-button:horizontal:start:decrement,
.scroll-pane::-webkit-scrollbar-button:horizontal:end:increment,
.scroll-pane::-webkit-scrollbar-button:horizontal:start:increment,
.scroll-pane::-webkit-scrollbar-button:horizontal:end:decrement {
  display: none;
  width: 0;
  height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
}

.scroll-pane::-webkit-scrollbar-corner {
  background: transparent;
}

.scroll-pane:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.main {
  flex: 1;
  min-height: 0;
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: minmax(0, 1fr);
  column-gap: 1.15rem;
  row-gap: 0;
  align-items: stretch;
  box-sizing: border-box;
  /* Chart / sentence-case title metrics — match player-list first names. */
  --flat-title-size: var(--accordion-title-font-size);
  --flat-title-line: 1.15;
  --flat-title-weight: 400;
  --flat-title-tracking: -0.02em;
  --flat-title-color: var(--color-text);
  /* All-caps chrome also used for similar/different kickers.
     Size / tracking / color live on :root so header + hero share them. */
  --hero-chrome-label-size: var(--flat-title-size);
  --flat-head-gap: 3px;
  --flat-head-pad-top: 0px;
  --detail-top-inset: 0px;
  --hero-align-to-chart: calc(
    var(--detail-top-inset) + var(--flat-head-pad-top) + (var(--flat-title-size) * var(--flat-title-line)) +
      var(--flat-head-gap) - 24px
  );
}

.detail-column {
  display: contents;
}

.roster-strip {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  width: 100%;
  min-width: 0;
  --chart-compare-higher: #007a58;
  --chart-compare-lower: #d55e00;
  --roster-card-gap: calc(
    max(
      0px,
      var(--portrait-inner) + 2 * var(--selection-matte) - var(--portrait-slot)
    ) + 4px
  );
}

.roster-strip .slot-group__track--scroll.scroll-pane {
  /* Fixed slots: window offset changes content; the track does not scroll. */
  overflow-x: hidden;
  overflow-y: hidden;
  /* Drag is compare-scrub; navigate via wheel, minimap, or keyboard. */
  touch-action: none;
  /* Keep end overhang; .scroll-pane zeros padding-inline-end for vertical panes. */
  padding-inline: calc(
    var(--selection-frame-overhang) + var(--list-row-shadow-bleed)
  );
  padding-top: var(--selection-matte);
  padding-bottom: calc(var(--selection-matte) + var(--player-card-footer-pad));
  /* Locked height — hover/selected growth must not push the minimap. */
  height: var(--roster-track-height);
  min-height: var(--roster-track-height);
  box-sizing: border-box;
  scrollbar-width: none;
}

.roster-strip .slot-group__track--scroll.scroll-pane::-webkit-scrollbar {
  display: none;
}

.roster-strip .slot-group__fade--left,
.roster-strip .slot-group__fade--right {
  display: block;
}

.stats-sidebar {
  min-height: 0;
  width: var(--chart-panel-width);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  overflow: visible;
  grid-column: 1;
  grid-row: 1;
  background: transparent;
  border: none;
  border-radius: 0;
}

.stats-compare-overall,
.stats-compare-focus {
  display: none;
}

#roster-view {
  display: none;
}

.content {
  flex-shrink: 0;
  width: 100%;
  min-width: 0;
}

/* Header */
.header {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.header__toolbar {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto;
  align-items: center;
  column-gap: 1.25rem;
  row-gap: 0;
  min-width: 0;
  padding-inline-start: calc(var(--selection-frame-overhang) + var(--portrait-pad));
}

.header__leading {
  display: flex;
  align-items: center;
  grid-row: 1;
  grid-column: 1;
  min-width: 0;
  flex: unset;
  /* Same vertical box as search / team / position triggers. */
  min-height: var(--filter-menu-trigger-height);
}

.header__chrome-actions {
  display: inline-flex;
  align-items: center;
  align-self: center;
  gap: 1.1rem;
  margin: 0;
  padding: 0;
  min-height: var(--filter-menu-trigger-height);
  height: var(--filter-menu-trigger-height);
}

.header__chrome-sep {
  display: block;
  width: 1px;
  height: 0.95em;
  background: var(--color-border-strong);
  flex-shrink: 0;
  align-self: center;
}

/* Same dock control as College / Experience, but flow-layout in header chrome. */
.help-trigger.cluster-dock {
  position: relative;
  left: auto;
  top: auto;
  z-index: auto;
  pointer-events: auto;
}

.help-trigger.cluster-dock:focus {
  outline: none;
}

.help-trigger__label {
  gap: 0.4rem;
  text-decoration: none;
}

.help-trigger__info {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  font-size: 1.2em;
  line-height: 1;
  width: 1em;
  /* Optical align with caps midline. */
  transform: translateY(0.02em);
}

.help-trigger__text {
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
  text-underline-offset: 0.15em;
}

.help-trigger.cluster-dock:hover .cluster-dock__label,
.help-trigger.cluster-dock:hover .help-trigger__text {
  color: var(--color-text);
  text-decoration-color: currentColor;
}

.voiceover-block {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-width: 0;
  overflow: visible;
}

.voiceover-block__controls {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  min-width: 0;
}

.voiceover-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  user-select: none;
  margin: 0;
  padding: 0;
}

.voiceover-toggle__label {
  font-size: var(--hero-chrome-caps-size);
  font-weight: 700;
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
  color: var(--hero-chrome-caps-color);
  line-height: 1;
}

.voiceover-toggle__switch {
  position: relative;
  box-sizing: border-box;
  width: 2.5rem;
  height: 1.35rem;
  padding: 0;
  border: 1px solid var(--color-border-strong);
  border-radius: 999px;
  background: var(--color-surface-raised);
  cursor: pointer;
  flex-shrink: 0;
  align-self: center;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.voiceover-toggle__switch::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0.15rem;
  width: 0.95rem;
  height: 0.95rem;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.28);
  transform: translateY(-50%);
  transition: left 0.15s ease, background 0.15s ease;
}

.voiceover-toggle__switch[aria-checked="true"] {
  background: var(--color-selection-fill);
  border-color: var(--color-selection-fill);
}

.voiceover-toggle__switch[aria-checked="true"]::after {
  left: calc(100% - 0.15rem - 0.95rem);
  background: #fff;
}

.voiceover-toggle__switch:hover {
  background: #dfe2e8;
}

.voiceover-toggle__switch[aria-checked="true"]:hover {
  background: var(--color-nav-fill);
  border-color: var(--color-nav-fill);
}

.voiceover-toggle__switch:focus {
  outline: none;
}

.voiceover-toggle__switch:focus-visible {
  outline: 2px solid var(--color-importance-bar);
  outline-offset: 2px;
}

.voice-engine {
  display: inline-flex;
  align-items: center;
  align-self: center;
  gap: 0.85rem;
  min-width: 0;
}

/* Author `display: inline-flex` beats the UA [hidden] rule. */
.voice-engine[hidden] {
  display: none !important;
}

.voice-engine__set {
  display: inline-flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.85rem;
  margin: 0;
  padding: 0;
  min-width: 0;
}

.voice-engine__option {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  cursor: pointer;
  user-select: none;
  line-height: 1;
}

.voice-engine__option input {
  margin: 0;
  accent-color: var(--color-selection-fill);
  flex-shrink: 0;
}

.voice-engine__label {
  font-size: var(--hero-chrome-caps-size);
  font-weight: 700;
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
  color: var(--hero-chrome-caps-color);
  line-height: 1;
  white-space: nowrap;
}

.voiceover-status {
  /* Float above the switch row — does not shift Voiceover controls. */
  position: absolute;
  left: 0;
  bottom: calc(100% + 0.35rem);
  z-index: 2;
  margin: 0;
  overflow: visible;
  width: max-content;
  min-width: 14rem;
  max-width: min(calc(100vw - 2 * var(--app-pad-x)), 56rem);
}

.voiceover-status[hidden] {
  display: none !important;
}

.voiceover-status__title,
.voiceover-status__why {
  display: none;
}

.voiceover-status__line {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  margin: 0 0 0.2rem;
  overflow: visible;
  flex-wrap: nowrap;
  width: max-content;
  max-width: inherit;
}

.voiceover-status__text {
  margin: 0;
  flex: 0 0 auto;
  font-size: 0.65rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--color-text-muted);
  line-height: 1.2;
  white-space: nowrap;
}

.voiceover-status__phrases {
  margin: 0;
  flex: 0 0 auto;
  font-size: 0.58rem;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.01em;
  color: var(--color-text-muted);
  white-space: nowrap;
  opacity: 0.88;
}

.voiceover-status__phrases[hidden] {
  display: none !important;
}

.voiceover-status__track {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  width: 14rem;
  max-width: 22rem;
  min-width: 0;
}

.voiceover-status__bar {
  display: block;
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
  height: 0.35rem;
  border-radius: 999px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.08);
}

.voiceover-status__bar::-webkit-progress-bar {
  background: transparent;
  border-radius: 999px;
}

.voiceover-status__bar::-webkit-progress-value {
  background: var(--color-selection-fill);
  border-radius: 999px;
  transition: width 120ms linear;
}

.voiceover-status__bar::-moz-progress-bar {
  background: var(--color-selection-fill);
  border-radius: 999px;
}

.voiceover-status__bar--busy::-webkit-progress-value {
  animation: voiceover-bar-pulse 1.15s ease-in-out infinite;
}

.voiceover-status__bar--busy::-moz-progress-bar {
  animation: voiceover-bar-pulse 1.15s ease-in-out infinite;
}

@keyframes voiceover-bar-pulse {
  50% {
    opacity: 0.45;
  }
}

.voiceover-status__pct {
  flex: 0 0 auto;
  min-width: 2.4em;
  font-size: 0.65rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  color: var(--color-text-muted);
  line-height: 1;
  text-align: right;
}

/* Neural warm — wide centered panel over the ghosted roster. */
.app--voice-warm .voiceover-status {
  position: fixed;
  left: 50%;
  top: 50%;
  bottom: auto;
  z-index: 40;
  box-sizing: border-box;
  width: min(42rem, calc(100vw - 3rem));
  min-width: 0;
  max-width: min(42rem, calc(100vw - 3rem));
  padding: 1.75rem 2.1rem 1.85rem;
  overflow: hidden;
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-panel);
  box-shadow:
    0 10px 36px rgba(0, 0, 0, 0.12),
    0 2px 8px rgba(0, 0, 0, 0.06);
  transform: translate(-50%, -50%);
  animation: voiceover-warm-panel-in 180ms ease-out both;
}

@keyframes voiceover-warm-panel-in {
  from {
    opacity: 0;
    transform: translate(-50%, calc(-50% + 0.35rem));
  }
  to {
    opacity: 1;
    transform: translate(-50%, -50%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .app--voice-warm .voiceover-status {
    animation: none;
  }
}

.app--voice-warm .voiceover-status__title {
  display: block;
  margin: 0;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.25;
  color: var(--color-text);
}

.app--voice-warm .voiceover-status__why {
  display: block;
  margin: 0.55rem 0 0;
  max-width: 38rem;
  font-size: 0.82rem;
  font-weight: 500;
  line-height: 1.45;
  color: var(--color-text-muted);
}

.app--voice-warm .voiceover-status__line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.65rem;
  width: 100%;
  max-width: none;
  margin: 1.15rem 0 0.7rem;
}

.app--voice-warm .voiceover-status__text {
  flex: 1 1 auto;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--color-text);
  white-space: normal;
}

.app--voice-warm .voiceover-status__phrases {
  flex: 1 1 100%;
  font-size: 0.7rem;
  white-space: normal;
  opacity: 0.8;
}

.app--voice-warm .voiceover-status__track {
  width: 100%;
  max-width: none;
  gap: 0.65rem;
}

.app--voice-warm .voiceover-status__bar {
  height: 0.55rem;
}

.app--voice-warm .voiceover-status__pct {
  min-width: 2.8em;
  font-size: 0.8rem;
  color: var(--color-text);
}

.header__stat-name {
  /* Legacy AT hook — chart list header owns #focus-category-label now. */
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.header__stat-ranked-by::after {
  content: ":";
  margin-inline-end: 0.25em;
}

.filters {
  display: grid;
  grid-row: 1;
  grid-column: 2;
  grid-auto-flow: column;
  grid-auto-columns: max-content;
  justify-content: end;
  align-items: center;
  column-gap: 16px;
  padding: 0;
  min-width: 0;
}

.filter {
  position: relative;
  display: block;
  min-width: 0;
}

.filter--team,
.filter--position {
  flex: unset;
  width: var(--filter-menu-width);
  min-width: var(--filter-menu-width);
  max-width: var(--filter-menu-width);
}

.filter--search {
  flex: unset;
  width: 20rem;
  min-width: 14rem;
  max-width: 24rem;
}

.filter__label {
  position: absolute;
  left: var(--filter-control-pad-x);
  top: var(--filter-inline-label-top);
  /* Above open .filter-menu (41/42); pointer-events none so clicks still hit triggers. */
  z-index: 43;
  font-size: var(--hero-chrome-caps-sm-size);
  font-weight: var(--hero-chrome-caps-sm-weight);
  letter-spacing: var(--hero-chrome-caps-sm-tracking);
  text-transform: uppercase;
  color: var(--hero-chrome-caps-color);
  line-height: 1;
  white-space: nowrap;
  pointer-events: none;
}

.filter > :not(.filter__label) {
  width: 100%;
}

.name-filter {
  position: relative;
  width: 100%;
}

.name-filter__input {
  box-sizing: border-box;
  width: 100%;
  height: var(--filter-menu-trigger-height);
  padding: calc(
      var(--filter-inline-label-top) + var(--hero-chrome-caps-sm-size) +
        var(--filter-inline-label-to-value)
    )
    2.15rem var(--filter-value-pad-bottom) var(--filter-control-pad-x);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-tile);
  background: var(--color-surface-solid);
  color: var(--color-text);
  font: inherit;
  font-size: var(--filter-control-font-size);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.02em;
  box-shadow: none;
}

.name-filter__input::placeholder {
  color: var(--secondary-readable-color);
  opacity: 0.85;
}

.name-filter__input:hover {
  background: var(--color-surface-raised);
  border-color: rgba(0, 0, 0, 0.22);
}

.name-filter__input:focus {
  outline: none;
}

.name-filter__input:focus-visible {
  outline: 2px solid var(--color-border-strong);
  outline-offset: 1px;
}

.name-filter__input::-webkit-search-decoration,
.name-filter__input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

.name-filter__clear {
  position: absolute;
  right: var(--filter-control-pad-x);
  top: auto;
  bottom: calc(
    var(--filter-value-pad-bottom) +
      (var(--filter-control-font-size) * 1.2 - 1.5rem) / 2
  );
  transform: none;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--secondary-readable-color);
  font: inherit;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

.name-filter__clear:hover {
  color: var(--color-text);
  background: rgba(0, 0, 0, 0.06);
}

.name-filter__clear:focus-visible {
  outline: 2px solid var(--color-border-strong);
  outline-offset: 1px;
}

.filter-menu {
  position: relative;
  width: 100%;
}

/* Keep both filter triggers above the page-blocking backdrop so users can
   switch Team ↔ Position without an outside-click dismiss of the first menu. */
html.filter-menu-open .filter-menu {
  z-index: 41;
}

.filter-menu--open {
  z-index: 42;
}

.filter-menu__backdrop {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: transparent;
  cursor: default;
}

.filter-menu__trigger {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  min-width: 0;
  height: var(--filter-menu-trigger-height);
  padding: calc(
      var(--filter-inline-label-top) + var(--hero-chrome-caps-sm-size) +
        var(--filter-inline-label-to-value)
    )
    2.15rem var(--filter-value-pad-bottom) var(--filter-control-pad-x);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-tile);
  background: var(--color-surface-solid);
  color: var(--color-text);
  font: inherit;
  font-size: var(--filter-control-font-size);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.02em;
  cursor: pointer;
  text-align: left;
  box-shadow: none;
}

.filter-menu__trigger:hover {
  background: var(--color-surface-raised);
  border-color: rgba(0, 0, 0, 0.22);
}

.filter-menu__trigger:focus-visible {
  outline: 2px solid var(--color-border-strong);
  outline-offset: 1px;
}

.filter-menu__chevron {
  position: absolute;
  right: var(--filter-control-pad-x);
  top: auto;
  bottom: calc(
    var(--filter-value-pad-bottom) +
      (var(--filter-control-font-size) * 1.2 - 6px) / 2
  );
  width: 10px;
  height: 6px;
  transform: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='%231a1d24' d='M0 0l5 6 5-6z'/%3E%3C/svg%3E") center / contain no-repeat;
}

.filter-menu__logo {
  width: 1.75rem;
  height: 1.75rem;
  object-fit: contain;
  flex-shrink: 0;
  display: block;
  margin-inline-end: 4px;
  /* Grow visually without changing option row pitch. */
  transform: scale(1.3);
  transform-origin: center center;
  transition: transform 120ms ease, filter 120ms ease, opacity 120ms ease;
}

/* Team picker: mute inactive logos; selected / focused (pointer or keyboard) stay color. */
.filter-menu__panel
  .filter-menu__option:not(.filter-menu__option--selected):not(:focus)
  .filter-menu__logo {
  filter: grayscale(1);
  opacity: 0.8;
}

/* Hover / keyboard focus only — selected alone (incl. closed trigger) stays at base scale. */
.filter-menu__panel .filter-menu__option:focus .filter-menu__logo {
  transform: scale(calc(1.3 * 1.2));
}

.filter-menu__abbr {
  flex: 0 0 2.4em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 2.4em;
  height: 1.7em;
  padding: 0.1em 0 0;
  font-size: var(--player-list-name-size);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0;
  color: #fff;
  background: rgba(0, 0, 0, 0.82);
  border-radius: 2px;
  text-transform: uppercase;
  white-space: nowrap;
  transform-origin: center center;
  transition: transform 120ms ease, opacity 120ms ease;
}

/* Position picker: mute idle abbrs; selected / focused stay full and 1.2×. */
.filter-menu__panel
  .filter-menu__option:not(.filter-menu__option--selected):not(:focus)
  .filter-menu__abbr {
  opacity: 0.8;
}

.filter-menu__panel .filter-menu__option--selected .filter-menu__abbr,
.filter-menu__panel .filter-menu__option:focus .filter-menu__abbr {
  opacity: 1;
  transform: scale(1.2);
}

.filter-menu__value,
.filter-menu__option-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.filter-menu__panel {
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  width: 100%;
  box-sizing: border-box;
  max-height: calc(100dvh - 14rem);
  border: 1px solid var(--color-border-strong);
  border-radius: 6px;
  background: #ffffff;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.12);
  overflow: hidden;
}

.filter-menu--multi .filter-menu__panel {
  padding-top: 0;
}

.filter-menu__toolbar {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 2px;
  padding: 6px 6px 6px 10px;
  background: linear-gradient(to bottom, #ffffff 70%, rgba(255, 255, 255, 0));
  pointer-events: none;
}

.filter-menu__toolbar > * {
  pointer-events: auto;
}

.filter-menu__show-all {
  margin: 0;
  margin-right: auto;
  padding: 4px 8px;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: var(--secondary-readable-color);
  font: inherit;
  font-size: var(--secondary-label-font-size);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
}

.filter-menu__show-all:hover:not(:disabled),
.filter-menu__show-all:focus-visible:not(:disabled) {
  color: var(--color-text);
  background: rgba(0, 0, 0, 0.05);
  outline: none;
}

.filter-menu__show-all:disabled {
  opacity: 0.4;
  cursor: default;
}

.filter-menu__close {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: #3a3e46;
  font: 400 22px/1 system-ui, sans-serif;
  cursor: pointer;
  opacity: 0.75;
}

.filter-menu__close:hover,
.filter-menu__close:focus-visible {
  opacity: 1;
  color: #101014;
  background: rgba(0, 0, 0, 0.05);
  outline: none;
}

.filter-menu--multi .filter-menu__list {
  padding-top: 40px;
}

.filter-menu--multi .filter-menu__fade--start {
  top: 34px;
}

.filter-menu__list {
  margin: 0;
  padding: 18px 10px 24px;
  list-style: none;
  max-height: inherit;
  overflow-x: hidden;
  overflow-y: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.filter-menu__list::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
}

.filter-menu__fade {
  position: absolute;
  left: 0;
  right: 0;
  height: 40px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
  z-index: 2;
}

.filter-menu__fade::after {
  content: "";
  position: absolute;
  left: 50%;
  width: 0;
  height: 0;
  transform: translateX(-50%);
  border-inline: 4px solid transparent;
}

.filter-menu__fade--start {
  top: 0;
  background: linear-gradient(to bottom, #ffffff 15%, rgba(255, 255, 255, 0));
}

.filter-menu__fade--start::after {
  top: var(--filter-menu-scroll-cue-offset);
  border-bottom: 5px solid rgba(26, 29, 36, 0.55);
}

.filter-menu__fade--end {
  bottom: 0;
  background: linear-gradient(to top, #ffffff 15%, rgba(255, 255, 255, 0));
}

.filter-menu__fade--end::after {
  bottom: var(--filter-menu-scroll-cue-offset);
  border-top: 5px solid rgba(26, 29, 36, 0.55);
}

.filter-menu__panel--fade-start .filter-menu__fade--start,
.filter-menu__panel--fade-end .filter-menu__fade--end {
  opacity: 1;
}

.filter-menu__columns {
  display: grid;
  grid-template-columns: repeat(var(--filter-menu-column-count, 4), minmax(0, 1fr));
  gap: 0 var(--filter-menu-columns-gap);
  align-items: start;
  margin-top: 0;
  padding: 0;
  list-style: none;
}

/* Space after a leading "All …" row. */
.filter-menu__list--columns > .filter-menu__option + .filter-menu__columns,
.filter-menu__list--columns > .filter-menu__group-label + .filter-menu__columns {
  margin-top: 6px;
}

/* League / View all teams / All positions — centered above or below the grid. */
.filter-menu__list--columns > .filter-menu__group-label,
.filter-menu__list--columns > .filter-menu__option {
  justify-content: center;
  text-align: center;
}

/* Full-width rule under the grid; trailing option itself stays content-sized. */
.filter-menu__list--columns > .filter-menu__columns:has(+ .filter-menu__option),
.filter-menu__list--columns > .filter-menu__columns:has(+ .filter-menu__group-label) {
  padding-bottom: 6px;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: 6px;
}

/* Trailing "all" row — hug logo + label so focus fill isn't a full-width bar. */
.filter-menu__list--columns > .filter-menu__columns + .filter-menu__option,
.filter-menu__list--columns > .filter-menu__columns + .filter-menu__group-label {
  width: max-content;
  max-width: 100%;
  margin-inline: auto;
}

.filter-menu__column {
  margin: 0;
  padding: 0;
  list-style: none;
  min-width: 0;
}

.filter-menu__column + .filter-menu__column {
  border-left: 1px solid var(--color-border);
  padding-left: var(--filter-menu-columns-gap);
}

.filter-menu__group-label {
  padding: 10px 8px 5px;
  font-size: var(--secondary-label-font-size);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--secondary-readable-color);
  pointer-events: none;
  user-select: none;
}

.filter-menu__group-label:not(:first-child) {
  margin-top: 6px;
  border-top: 1px solid var(--color-border);
  padding-top: 12px;
}

.filter-menu__column .filter-menu__group-label {
  margin-top: 6px;
  border-top: 1px solid var(--color-border);
  padding-top: 10px;
}

.filter-menu__column .filter-menu__group-label:first-child {
  margin-top: 0;
  border-top: none;
  padding-top: 10px;
}

.filter-menu__option {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  box-sizing: border-box;
  min-height: calc(var(--filter-control-font-size) * 1.2 + 10px);
  padding: 5px 8px;
  margin-block: 0;
  font-size: var(--filter-control-font-size);
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--color-text);
  cursor: pointer;
  border-radius: 5px;
}

/* Highlight follows focus only — not :hover — so keyboard nav can leave the
   pointer-hovered row looking idle while the mouse stays over it.
   Selected stays bold-only (no fill), including when it also has focus. */
.filter-menu__option:focus:not(.filter-menu__option--disabled):not(
    .filter-menu__option--selected
  ) {
  outline: none;
  background: var(--color-hover-fill);
  box-shadow: none;
}

.filter-menu__option--selected:not(.filter-menu__option--disabled) {
  font-weight: var(--hero-chrome-caps-weight-selected);
}

.filter-menu__option--selected:focus:not(.filter-menu__option--disabled) {
  outline: none;
  background: transparent;
}

.filter-menu__option--disabled {
  color: var(--color-text-inactive);
  opacity: 0.55;
  cursor: not-allowed;
}

.filter-menu__option--disabled .filter-menu__logo,
.filter-menu__option--disabled .filter-menu__abbr {
  filter: grayscale(1);
  opacity: 0.75;
}

/* Open trigger is subdued chrome while the panel is open. */
.filter-menu--open .filter-menu__trigger,
.filter-menu--open .filter-menu__trigger:focus-visible {
  border-color: rgba(0, 0, 0, 0.16);
  background: #e8eaed;
  color: var(--color-text);
  outline: none;
}

.filter-menu--open .filter-menu__chevron {
  transform: rotate(180deg);
}

/* Slot groups */
.slot-groups {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  width: 100%;
  min-width: 0;
}

.slot-group {
  padding: 0;
}

.slot-group__hint {
  margin: 0 0 0.35rem;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  line-height: 1.2;
}

.slot-group__sort-stat {
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--color-text);
}

.slot-group__strip {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
}

.roster-strip .slot-group__strip {
  /* Pull minimap up toward the card row (~8px tighter than default strip gap). */
  gap: max(0px, calc(0.5rem - 8px));
}

.slot-group__viewport {
  position: relative;
  min-width: 0;
  /* Wide enough that edge peeks read as ghosted players, not a hairline. */
  --edge-fade: 4.5rem;
}

.slot-group__fade {
  position: absolute;
  top: 0;
  bottom: 0;
  width: var(--edge-fade);
  pointer-events: none;
  /* Geometry only — used for fade-size measurement. Edge fade is a content mask. */
  opacity: 0;
  z-index: 2;
  background: none;
}

.slot-group__viewport--fade-left .slot-group__fade--left,
.slot-group__viewport--fade-right .slot-group__fade--right {
  /* keep elements for measurement; paint comes from mask */
  opacity: 0;
}

.slot-group__fade--left {
  left: 0;
}

.slot-group__fade--right {
  right: 0;
}

.slot-group__fade--start {
  top: 0;
  bottom: auto;
  left: 0;
  right: 0;
  width: auto;
  height: var(--edge-fade);
}

.slot-group__fade--end {
  top: auto;
  bottom: 0;
  left: 0;
  right: 0;
  width: auto;
  height: var(--edge-fade);
}

.slot-group__viewport--fade-start .slot-group__fade--start,
.slot-group__viewport--fade-end .slot-group__fade--end {
  opacity: 0;
}

/* Fade list content to alpha 0 so the stadium plate shows through — no solid tint. */
.slot-group__viewport--fade-start:not(.slot-group__viewport--fade-end) {
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    #000 var(--edge-fade),
    #000 100%
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    #000 var(--edge-fade),
    #000 100%
  );
}

.slot-group__viewport--fade-end:not(.slot-group__viewport--fade-start) {
  -webkit-mask-image: linear-gradient(
    to bottom,
    #000 0%,
    #000 calc(100% - var(--edge-fade)),
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    #000 0%,
    #000 calc(100% - var(--edge-fade)),
    transparent 100%
  );
}

.slot-group__viewport--fade-start.slot-group__viewport--fade-end {
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    #000 var(--edge-fade),
    #000 calc(100% - var(--edge-fade)),
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    #000 var(--edge-fade),
    #000 calc(100% - var(--edge-fade)),
    transparent 100%
  );
}

.slot-group__viewport--fade-left:not(.slot-group__viewport--fade-right) {
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0%,
    #000 var(--edge-fade),
    #000 100%
  );
  mask-image: linear-gradient(
    to right,
    transparent 0%,
    #000 var(--edge-fade),
    #000 100%
  );
}

.slot-group__viewport--fade-right:not(.slot-group__viewport--fade-left) {
  -webkit-mask-image: linear-gradient(
    to right,
    #000 0%,
    #000 calc(100% - var(--edge-fade)),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    #000 0%,
    #000 calc(100% - var(--edge-fade)),
    transparent 100%
  );
}

.slot-group__viewport--fade-left.slot-group__viewport--fade-right {
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0%,
    #000 var(--edge-fade),
    #000 calc(100% - var(--edge-fade)),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    transparent 0%,
    #000 var(--edge-fade),
    #000 calc(100% - var(--edge-fade)),
    transparent 100%
  );
}

.slot-group__track {
  display: flex;
  align-items: flex-start;
  gap: var(--roster-card-gap, 4px);
  /* Matte-tight vertical pad; inline overhang + small bleed for end shadows. */
  padding: var(--selection-matte)
    calc(var(--selection-frame-overhang) + var(--list-row-shadow-bleed))
    calc(var(--selection-matte) + var(--player-card-footer-pad))
    calc(var(--selection-frame-overhang) + var(--list-row-shadow-bleed));
  min-width: 0;
  min-height: var(--roster-track-height);
  position: relative;
  scroll-padding-inline: calc(
    var(--selection-frame-overhang) + var(--list-row-shadow-bleed)
  );
}

.slot-group__track--scroll:not(.scroll-pane) {
  overflow-x: auto;
  scrollbar-width: none;
}

.slot-group__track--scroll:not(.scroll-pane)::-webkit-scrollbar {
  display: none;
}

.slot-group__scrubber {
  min-width: 0;
}

.list-minimap {
  width: 100%;
  cursor: pointer;
  touch-action: none;
  --chart-compare-higher: #007a58;
  --chart-compare-lower: #d55e00;
}

.list-minimap:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.list-minimap__rail {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background: #d8d9dd;
}

.list-minimap__marker {
  --minimap-t: 0;
  --minimap-thumb: 14px;
  position: absolute;
  top: 50%;
  left: calc(var(--minimap-t) * (100% - var(--minimap-thumb)));
  width: var(--minimap-thumb);
  height: var(--minimap-thumb-thickness);
  margin-left: 0;
  border-radius: 999px;
  background: var(--color-text);
  transform: translateY(-50%);
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  transition:
    left 0.12s ease,
    transform 0.12s ease,
    height 0.12s ease;
}

.list-minimap__marker:hover {
  height: var(--minimap-thumb-thickness-active);
}

.list-minimap--compare-higher .list-minimap__marker {
  background: var(--chart-compare-higher);
}

.list-minimap--compare-lower .list-minimap__marker {
  background: var(--chart-compare-lower);
}

.list-minimap--dragging {
  cursor: grabbing;
}

.list-minimap--dragging .list-minimap__marker {
  height: var(--minimap-thumb-thickness-active);
  cursor: grabbing;
  transition: none;
}

/* Catalog window remounts under the pointer while dragging — keep grabbing
   on the whole document so chart `cursor: pointer` cannot steal it. */
html.minimap-thumb-dragging,
html.minimap-thumb-dragging * {
  cursor: grabbing !important;
}

/* Rail seek (click/drag on blank track): marker jumps under the pointer —
   don't treat that as hover / don't grow the thumb. */
.list-minimap--suppress-marker-hover .list-minimap__marker,
.list-minimap--suppress-marker-hover .list-minimap__marker:hover {
  height: var(--minimap-thumb-thickness);
}

.list-minimap--empty,
.list-minimap--single,
.list-minimap--fit {
  visibility: hidden;
  pointer-events: none;
}

.slot-group__track:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.player-card {
  flex: 0 0 var(--portrait-slot);
  width: var(--portrait-slot);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
  padding: var(--portrait-pad) var(--portrait-pad) var(--player-card-footer-pad);
  border: none;
  border-radius: 4px;
  background: transparent;
  /* Comparison tiles are <button>s — inherit body type so first/last name
     metrics match the roster list’s <div> cards (no UA button font). */
  font: inherit;
  color: inherit;
  cursor: pointer;
  overflow: visible;
  user-select: none;
  transition: none;
  box-sizing: border-box;
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card {
  position: relative;
}

/*
 * Press preview — pressed portrait shrinks in place (list, comparisons, chart tips).
 * Selection stays selected; peers may ghost separately.
 */
.player-card--press .player-card__portrait,
.stat-chart__tooltip--press .player-card__portrait {
  transform: scale(0.92);
  transform-origin: center center;
  transition: transform 90ms ease;
}

/* Tip-owned / scrub-owned press must not re-animate when the focus card changes mid-drag. */
.stat-chart__tooltip--press .player-card__portrait,
.roster-strip--scrub-focus .player-card--press .player-card__portrait,
.roster-strip--keyboard-nav .player-card--press .player-card__portrait {
  transition: none;
}

.player-card--press-ghost {
  opacity: 0.42;
  transition: opacity 90ms ease;
}

/* Selection stays full-strength even if a compare path left press-ghost on. */
.player-card--selected.player-card--press-ghost {
  opacity: 1;
}

/*
 * Scrub ghosting lives on the strip class — not :has(.player-card--chart-hover).
 * Hover swaps and window rebinds briefly clear chart-hover; a :has rule would
 * flash peers to full opacity. Mid-scrub opacity is transition:none so remounts
 * stay at a constant ghost level.
 */
.roster-strip--scrub-focus .player-card {
  transition: none;
}

.roster-strip--scrub-focus
  .player-card:not(.player-card--chart-hover):not(.player-card--selected) {
  opacity: 0.42;
}

@media (prefers-reduced-motion: reduce) {
  .player-card--press .player-card__portrait,
  .player-card--press-ghost {
    transition: none;
  }
}

/* Deferred portrait fill — keep the slot sized like a hydrated card. */
.player-card--shell {
  min-height: calc(var(--portrait-slot) + 1.1rem);
}

.player-card:focus {
  outline: none;
}

.player-card:focus-visible {
  outline: 2px solid var(--color-border-strong);
  outline-offset: 2px;
}

.player-card--selected:focus-visible {
  outline: none;
}

.roster-strip--keyboard-nav .player-card:focus-visible:not(.player-card--selected) {
  outline: none;
}

/*
 * One shared frame size for select / focus / last-focus / hover / scrub /
 * chart-hover — in the roster strip, similar/different lists, and chart tips.
 * States differ by fill, outline, and shadow only (no portrait scale).
 */
.player-card--selected,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--chart-hover,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--scrub-linger,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--focused:not(.player-card--selected),
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card):not(:is(.roster-strip--keyboard-nav, .roster-strip--keyboard-chart-browse)) .player-card:hover:not(.player-card--selected),
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--last-focused:not(.player-card--selected):not(.player-card--focused):not(.player-card--chart-hover):not(.player-card--scrub-linger) {
  --selection-scaled: var(--portrait-inner);
  --selection-scale-overflow: 0px;
  --selection-frame-outer: calc(
    var(--portrait-inner) + (2 * var(--selection-matte))
  );
  position: relative;
  z-index: 2;
  flex: 0 0 var(--portrait-slot);
  width: var(--portrait-slot);
  background: transparent;
  border: none;
  outline: none;
  box-shadow: none;
}

.player-card--selected {
  color: var(--color-selection-text);
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--focused:not(.player-card--selected) {
  color: var(--color-chart-hover-text);
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--chart-hover,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--scrub-linger:not(.player-card--selected),
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--focused:not(.player-card--selected),
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card):not(:is(.roster-strip--keyboard-nav, .roster-strip--keyboard-chart-browse)) .player-card:hover:not(.player-card--selected) {
  color: var(--color-chart-hover-text);
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--selected.player-card--chart-hover,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--selected:hover,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--selected.player-card--focused {
  color: var(--color-selection-text);
}

.player-card__avatar {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--portrait-inner);
  height: var(--portrait-inner);
  flex-shrink: 0;
  box-sizing: border-box;
  border: 1px solid rgba(0, 0, 0, 0.12);
  box-shadow: none;
  background: var(--player-team-primary, var(--portrait-bg));
  pointer-events: none;
  border-radius: 4px;
  overflow: hidden;
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--selected .player-card__avatar,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--focused .player-card__avatar,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--chart-hover .player-card__avatar,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--scrub-linger .player-card__avatar,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card):not(:is(.roster-strip--keyboard-nav, .roster-strip--keyboard-chart-browse)) .player-card:hover:not(.player-card--selected) .player-card__avatar {
  border: var(--selection-photo-stroke) solid var(--color-selection-frame);
  border-radius: 6px;
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--focused:not(.player-card--selected) .player-card__avatar,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--chart-hover:not(.player-card--selected) .player-card__avatar,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--scrub-linger:not(.player-card--selected) .player-card__avatar,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card):not(:is(.roster-strip--keyboard-nav, .roster-strip--keyboard-chart-browse)) .player-card:hover:not(.player-card--selected) .player-card__avatar {
  border-color: var(--color-chart-hover-frame);
}

/* Single frame behind portrait + name (shared geometry for every chrome state).
   Center with margin (not transform) so dropping the frame does not leave a
   compositor-layer ghost on the just-deselected card. */
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--selected::before,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--focused::before,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--chart-hover::before,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--scrub-linger::before,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card):not(:is(.roster-strip--keyboard-nav, .roster-strip--keyboard-chart-browse)) .player-card:hover:not(.player-card--selected)::before,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--last-focused:not(.player-card--selected):not(.player-card--focused):not(.player-card--chart-hover):not(.player-card--scrub-linger)::before {
  content: "";
  position: absolute;
  left: 50%;
  width: var(--selection-frame-outer);
  margin-left: calc(var(--selection-frame-outer) / -2);
  top: calc(
    var(--portrait-pad) - var(--selection-scale-overflow) -
      var(--selection-matte)
  );
  bottom: calc(var(--player-card-footer-pad) - var(--selection-matte));
  border-radius: 10px;
  z-index: 0;
  pointer-events: none;
  transform: none;
}

/* Arrow-step: hard-kill frame chrome on non-selected cards (even if :hover
   still matches under the pointer) so deselection cannot flash a grey frame. */
.roster-strip--keyboard-nav .player-card:not(.player-card--selected):not(.player-card--focused):not(.player-card--chart-hover):not(.player-card--scrub-linger):not(.player-card--last-focused)::before {
  content: none !important;
  display: none !important;
  opacity: 0 !important;
  background: none !important;
  box-shadow: none !important;
}

/*
 * LastFocused — where browse/hover/compare last landed after focus leaves the row.
 * Outline only (no fill or shadow). Size comes from the shared frame block above.
 * Do NOT gate on :not(:hover): pointer capture can leave sticky :hover on the
 * peer after compare abort while the pointer is already outside the strip.
 * Real in-list hover clears the last-focused *class* in syncVoiceNavPlayerFocus.
 */
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--last-focused:not(.player-card--selected):not(.player-card--focused):not(.player-card--chart-hover):not(.player-card--scrub-linger) {
  z-index: 1;
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--last-focused:not(.player-card--selected):not(.player-card--focused):not(.player-card--chart-hover):not(.player-card--scrub-linger)::before {
  border: 1px solid #000;
  background: transparent;
  box-shadow: none;
}

/* Scrollbar / list-scrub: hover is the only list chrome — hide leftover outlines. */
.roster-strip--scrub-focus .player-card--last-focused::before {
  content: none !important;
  border: none !important;
  background: none !important;
  box-shadow: none !important;
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--selected::before {
  background: var(--color-selection-fill);
  box-shadow: none;
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--focused:not(.player-card--selected)::before,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--chart-hover::before,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card):not(:is(.roster-strip--keyboard-nav, .roster-strip--keyboard-chart-browse)) .player-card:hover:not(.player-card--selected)::before {
  background: var(--color-chart-hover-fill);
  box-shadow: var(--list-row-hover-shadow);
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--selected.player-card--chart-hover::before,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--selected:hover::before {
  background: var(--color-selection-fill);
  box-shadow: var(--list-row-hover-shadow);
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--scrub-linger::before {
  animation: chart-frame-shadow-fade var(--scrub-linger-ms, 180ms) ease-out forwards;
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--scrub-linger:not(.player-card--selected)::before {
  background: var(--color-chart-hover-fill);
  box-shadow: var(--list-row-hover-shadow);
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--selected.player-card--scrub-linger::before {
  background: var(--color-selection-fill);
  box-shadow: var(--list-row-hover-shadow);
}

.player-card--selected .player-card__meta,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--focused .player-card__meta,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--chart-hover .player-card__meta,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--scrub-linger .player-card__meta,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card):not(:is(.roster-strip--keyboard-nav, .roster-strip--keyboard-chart-browse)) .player-card:hover:not(.player-card--selected) .player-card__meta {
  position: relative;
  z-index: 1;
  /* Label stays on portrait-slot content width so text keeps matte padding
     inside the ::before frame even when the selected card grows neighbor gutters. */
  width: calc(var(--portrait-slot) - 2 * var(--portrait-pad));
  margin-inline: auto;
}

.player-card__avatar--initials {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--color-text-muted);
}

.player-card__team-logo {
  display: block;
  width: 54%;
  height: 54%;
  object-fit: contain;
  filter: grayscale(1);
  opacity: 0.5;
  pointer-events: none;
}

.player-card__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  display: block;
}

.player-card__portrait {
  position: relative;
  width: var(--portrait-inner);
  height: var(--portrait-inner);
  flex-shrink: 0;
}

.player-card__pos-badge {
  position: absolute;
  top: 3px;
  left: 3px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 2.4em;
  height: 1.7em;
  padding: 0.1em 0 0;
  font-size: var(--player-list-name-size);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0;
  color: #fff;
  background: rgba(0, 0, 0, 0.82);
  border-radius: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  z-index: 1;
}

.player-card__meta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.08rem;
  width: 100%;
  min-width: 0;
}

.player-card__name {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.05em;
  width: 100%;
  min-width: 0;
  font-family: var(--font-family);
  font-size: var(--player-list-name-size);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--color-text);
  text-align: left;
}

.player-card__name-first,
.player-card__name-last {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.player-card__name-first {
  font-size: var(--player-list-name-size);
  font-weight: 400;
}

.player-card__name-last {
  font-size: var(--player-list-name-last-size);
  font-weight: 800;
  letter-spacing: -0.02em;
  /* >1 so descenders (g, y, …) clear overflow:hidden used for ellipsis. */
  line-height: 1.2;
  margin-top: -3px;
}

/* Sort-stat under last name, inside the hover/select/last-focused frame. */
.player-card__sort-value {
  display: flex;
  align-items: baseline;
  align-items: last baseline;
  gap: 0.18em;
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 0;
  pointer-events: none;
  color: #000;
  font-size: var(--chart-extremes-size, var(--player-list-name-last-size));
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1;
  text-align: left;
}

.player-card__sort-label {
  flex: 1 1 0;
  min-width: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--player-card-sort-label-lines);
  line-clamp: var(--player-card-sort-label-lines);
  overflow: hidden;
  font-size: var(--hero-chrome-caps-sm-size);
  font-weight: var(--hero-chrome-caps-sm-weight);
  line-height: var(--player-card-sort-label-line-height);
  letter-spacing: var(--hero-chrome-caps-sm-tracking);
  text-transform: uppercase;
  white-space: normal;
  overflow-wrap: break-word;
  word-break: normal;
  /* Stat name stays neutral — only the numeric value carries compare tint. */
  color: #000;
}

.player-card__sort-value[hidden] {
  display: none;
}

.player-card__sort-value--higher {
  color: var(--chart-compare-higher);
}

.player-card__sort-value--lower {
  color: var(--chart-compare-lower);
}

.player-card--selected .player-card__sort-value:not(.player-card__sort-value--higher):not(.player-card__sort-value--lower) {
  color: var(--color-selection-text);
}

.player-card--selected .player-card__sort-label {
  color: var(--color-selection-text);
}

.player-card__rank {
  display: block;
  width: 100%;
  min-width: 0;
  font-size: var(--portrait-label-size);
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.player-card--selected .player-card__name,
.player-card--selected .player-card__rank {
  color: var(--color-selection-text);
}

:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--focused:not(.player-card--selected) .player-card__name,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--focused:not(.player-card--selected) .player-card__rank,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--chart-hover:not(.player-card--selected) .player-card__name,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--chart-hover:not(.player-card--selected) .player-card__rank,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--scrub-linger:not(.player-card--selected) .player-card__name,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--scrub-linger:not(.player-card--selected) .player-card__rank,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card):not(:is(.roster-strip--keyboard-nav, .roster-strip--keyboard-chart-browse)) .player-card:hover:not(.player-card--selected) .player-card__name,
:is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card):not(:is(.roster-strip--keyboard-nav, .roster-strip--keyboard-chart-browse)) .player-card:hover:not(.player-card--selected) .player-card__rank {
  color: var(--color-chart-hover-text);
}

.player-card--selected .player-card__team-logo {
  opacity: 0.85;
  filter: none;
}

.player-hero {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  /* clip (not hidden): purely decorative clipping of overflowing pack
     circles — hidden makes this a real scroll container, so focusing an
     off-to-the-side button (e.g. clicking the Experience dock) triggers the
     browser's native "scroll focused element into view", which yanks
     College sideways since they share this box. clip never scrolls. */
  overflow: clip;
  grid-column: 2;
  grid-row: 1;
  --hero-fade-ms: 220ms;
  /* Comparison portrait fade once the decoded image is ready to show. */
  --hero-peek-reveal-ms: 150ms;
  /* Leave-hover settle for the dual-portrait peek (selected + comparison). */
  --hero-peek-exit-ms: 420ms;
  /* Keep comparison columns fully inside the hero clip — hang below and
     hover-scale shears the name / frame at the viewport bottom. */
  --comparisons-bottom: calc(
    var(--selection-matte) + var(--selection-scale-overflow)
  );
  /* Match College / Experience dock label edges (info pad + dock inset). */
  --hero-cluster-inset-start: 0.25rem;
  --hero-cluster-inset-end: 1.3rem;
  --hero-dock-inset: 6px;
  --comparisons-inline-start: calc(
    var(--hero-cluster-inset-start) + var(--hero-dock-inset)
  );
  --comparisons-inline-end: calc(
    var(--hero-cluster-inset-end) + var(--hero-dock-inset)
  );
  /* Shared with heading / meta so the cutout ceiling tracks live resize
     (vw clamps on type) instead of snapping at MQ breakpoints.
     --hero-name-size / --hero-meta-size live on :root. */
  /* Keep the cutout top ~24px under the meta row: chart-align pad + name +
     meta margin + pill (lh 1.1 + 0.4em pad + 1px borders) + gap.
     Applied as the photo's height budget (not a shared 100% token — a
     percentage in a custom property resolves against whichever property
     consumes it, so width would steal the horizontal %). */
  --hero-photo-chrome-gap: 24px;
  --hero-photo-top-reserve: calc(
    var(--hero-align-to-chart, 0px) + var(--hero-name-size) + 2px +
      (var(--hero-meta-size) * 1.5) + 2px + var(--hero-photo-chrome-gap)
  );
}

/* Open packs intentionally spill left toward the chart column — lift clip so
   bubbles aren’t sheared off by the hero edge / covered by the chart list. */
.player-hero:has(.cluster-bar--open) {
  overflow: visible;
  z-index: 6;
}

.selection-displacement {
  position: fixed;
  z-index: 1000;
  left: 50%;
  bottom: max(1rem, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 0.85rem;
  width: max-content;
  max-width: min(44rem, calc(100vw - 2rem));
  padding: 0.75rem 0.85rem 0.75rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-text);
  color: var(--color-bg);
  box-shadow: 0 0.5rem 1.5rem rgb(0 0 0 / 24%);
  font-size: var(--secondary-label-font-size);
  line-height: 1.35;
}

.selection-displacement[hidden] {
  display: none;
}

.selection-displacement__message {
  min-width: 0;
}

.selection-displacement__undo {
  flex: 0 0 auto;
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 0.4rem 0.75rem;
  background: transparent;
  color: inherit;
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

.selection-displacement__undo:hover {
  background: rgb(255 255 255 / 16%);
}

.selection-displacement__undo:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

.player-hero__photo,
.player-hero__team-logo {
  position: absolute;
  z-index: 1;
  pointer-events: none;
  transition:
    opacity var(--hero-fade-ms) ease,
    transform var(--hero-fade-ms) ease;
}

.player-hero__peek-photo {
  position: absolute;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  transition: none;
}

@keyframes hero-peek-photo-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.player-hero__peek-photo--enter {
  animation: hero-peek-photo-in var(--hero-peek-reveal-ms) ease both;
}

.player-hero__peek-standin {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  color: var(--color-text-inactive);
  opacity: 0;
  transition: transform var(--hero-fade-ms) ease, opacity var(--hero-fade-ms) ease;
}

.player-hero__peek-standin[hidden] {
  display: none;
}

.player-hero__peek-standin svg {
  width: 42%;
  height: auto;
  margin-bottom: 8%;
  opacity: 0.45;
}

.player-hero--peek-exit .player-hero__photo {
  transition:
    opacity var(--hero-peek-exit-ms) ease,
    transform var(--hero-peek-exit-ms) ease;
}

.player-hero--peek-exit .player-hero__peek-photo,
.player-hero--peek-exit .player-hero__peek-standin {
  transition: transform var(--hero-peek-exit-ms) ease, opacity var(--hero-peek-exit-ms) ease;
}

.player-hero__photo,
.player-hero__peek-photo,
.player-hero__peek-standin {
  /* top:auto so the box still sits on the bottom edge (not the top). */
  top: auto;
  right: auto;
  bottom: 0;
  /* Centered between College (left) and Experience (right): left:50% + translateX
     centers around the hero's midpoint regardless of how wide the box gets,
     letting it grow past the column edge symmetrically (clipped by the
     hero's overflow:clip) instead of the old left:0/right:0/margin:auto
     approach, whose auto-margin centering didn't engage for this
     absolutely-positioned *replaced* element — width growth all went to
     one side instead of splitting evenly. */
  left: 50%;
  /* Height fills to the meta+24px line (100% = hero stage height), then
     multiplies by --hero-photo-width-fit so narrower viewports ease down.
     Width comes from aspect-ratio only. */
  height: calc(
    (100% - var(--hero-photo-top-reserve)) * var(--hero-photo-width-fit)
  );
  width: auto;
  max-height: none;
  max-width: none;
  aspect-ratio: var(--hero-photo-aspect);
  margin-inline: 0;
  object-fit: contain;
  object-position: bottom center;
  transform: translateX(calc(-50% + var(--hero-photo-offset-x)));
}

/* Selected player stays in front where shoulders overlap. */
.player-hero__photo {
  z-index: 2;
}

.player-hero--keyboard-pending .player-hero__photo {
  opacity: 0.32;
}

/* Ghost only the comparison thumbnails — keep portrait fill / labels solid. */
.player-comparisons--keyboard-pending .player-card__photo,
.player-comparisons--keyboard-pending .player-card__team-logo {
  opacity: 0.32;
}

.player-hero--peek-left .player-hero__photo {
  transform: translateX(
    calc(-50% + var(--hero-photo-offset-x) + var(--hero-peek-shift))
  );
}

.player-hero--peek-left .player-hero__peek-photo,
.player-hero--peek-left .player-hero__peek-standin {
  opacity: 1;
  transform: translateX(
    calc(-50% + var(--hero-photo-offset-x) - var(--hero-peek-shift))
  );
}

.player-hero--peek-right .player-hero__photo {
  transform: translateX(
    calc(-50% + var(--hero-photo-offset-x) - var(--hero-peek-shift))
  );
}

.player-hero--peek-right .player-hero__peek-photo,
.player-hero--peek-right .player-hero__peek-standin {
  opacity: 1;
  transform: translateX(
    calc(-50% + var(--hero-photo-offset-x) + var(--hero-peek-shift))
  );
}

@keyframes hero-peek-wipe-right {
  from {
    -webkit-mask-position: 100% 0;
    mask-position: 100% 0;
  }
  to {
    -webkit-mask-position: 0 0;
    mask-position: 0 0;
  }
}

@keyframes hero-peek-wipe-left {
  from {
    -webkit-mask-position: 0 0;
    mask-position: 0 0;
  }
  to {
    -webkit-mask-position: 100% 0;
    mask-position: 100% 0;
  }
}

.player-hero--peek-wipe .player-hero__peek-photo {
  -webkit-mask-image: linear-gradient(to right, #000 42%, transparent 58%);
  mask-image: linear-gradient(to right, #000 42%, transparent 58%);
  -webkit-mask-size: 240% 100%;
  mask-size: 240% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  animation: hero-peek-wipe-right var(--hero-peek-wipe-ms) linear forwards;
}

.player-hero--peek-wipe.player-hero--peek-left .player-hero__peek-photo {
  -webkit-mask-image: linear-gradient(to left, #000 42%, transparent 58%);
  mask-image: linear-gradient(to left, #000 42%, transparent 58%);
  animation-name: hero-peek-wipe-left;
}

/* Comparison press: peeked athlete slides into the primary slot; outgoing
   selection fades. Release settles identity; cancel removes this class. */
.player-hero--peek-promote .player-hero__photo,
.player-hero--peek-promote .player-hero__peek-photo {
  transition:
    opacity 280ms ease,
    transform 280ms ease;
}

.player-hero--peek-promote.player-hero--peek-left .player-hero__photo,
.player-hero--peek-promote.player-hero--peek-right .player-hero__photo {
  opacity: 0;
  z-index: 1;
}

.player-hero--peek-promote.player-hero--peek-left .player-hero__peek-photo {
  z-index: 3;
  opacity: 1;
  transform: translateX(
    calc(-50% + var(--hero-photo-offset-x) + var(--hero-peek-shift))
  );
}

.player-hero--peek-promote.player-hero--peek-right .player-hero__peek-photo {
  z-index: 3;
  opacity: 1;
  transform: translateX(
    calc(-50% + var(--hero-photo-offset-x) - var(--hero-peek-shift))
  );
}

/* Legacy press scale — kept for non-promote fallbacks; promote replaces it. */
.player-hero--peek-press.player-hero--peek-left .player-hero__photo,
.player-hero--peek-press.player-hero--peek-right .player-hero__photo {
  opacity: 0.42;
  z-index: 1;
}

.player-hero--peek-press.player-hero--peek-left .player-hero__peek-photo {
  z-index: 2;
  transform: translateX(
      calc(-50% + var(--hero-photo-offset-x) - var(--hero-peek-shift))
    )
    scale(1.045);
}

.player-hero--peek-press.player-hero--peek-right .player-hero__peek-photo {
  z-index: 2;
  transform: translateX(
      calc(-50% + var(--hero-photo-offset-x) + var(--hero-peek-shift))
    )
    scale(1.045);
}

.player-hero__team-logo {
  display: none;
}

.player-comparisons {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}

.player-comparisons__side {
  position: absolute;
  /* See --comparisons-bottom: aligns focus-frame bottom with hero portrait. */
  bottom: var(--comparisons-bottom);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15rem;
  overflow: visible;
  pointer-events: auto;
  /* Cards center the idle portrait inside --portrait-slot; nudge keeps the
     label/row on that portrait column. */
  --comparison-portrait-nudge: calc(
    (var(--portrait-inner) - var(--portrait-slot)) / 2
  );
  /* Exact hovered/selected frame width (same shared size as the player list). */
  --comparison-frame-width: calc(
    var(--portrait-inner) + 2 * var(--selection-matte)
  );
  /* How far the hover frame hangs past each side of --portrait-slot. */
  --comparison-frame-hang: calc(
    (var(--comparison-frame-width) - var(--portrait-slot)) / 2
  );
  /*
   * Frame matte hangs past the card top. Idle keeps that hang as slack above
   * the label; active moves it under the label so the noun clears the frame.
   * Column height stays put because sides are bottom-anchored.
   */
  --comparison-hover-hang: calc(
    var(--selection-matte) - var(--portrait-pad) + 4px
  );
  --comparison-label-slack: var(--comparison-hover-hang);
  width: var(--comparison-frame-width);
}

.player-comparisons__side:has(
  .player-card:is(:hover, .player-card--chart-hover, .player-card--scrub-linger)
) {
  --comparison-label-slack: 0px;
}

.player-comparisons__side--similar {
  /* Shift left so side left = hover-frame left; cards keep their old column. */
  left: calc(
    var(--comparisons-inline-start) + var(--comparison-portrait-nudge) -
      var(--comparison-frame-hang)
  );
}

.player-comparisons__side--different {
  right: calc(
    var(--comparisons-inline-end) + var(--comparison-portrait-nudge) -
      var(--comparison-frame-hang)
  );
  align-items: flex-end;
  text-align: right;
}

.player-comparisons__group {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  width: 100%;
  overflow: visible;
}

.player-comparisons__label {
  display: block;
  /* Slack above (idle) ↔ hang below (hover) — sum stays --comparison-hover-hang. */
  margin: var(--comparison-label-slack, 0px)
    0
    calc(
      var(--comparison-hover-hang, 0px) - var(--comparison-label-slack, 0px)
    );
  padding: 0;
  flex: 0 0 auto;
  min-width: 0;
  width: var(--portrait-slot);
  max-width: 100%;
  box-sizing: border-box;
  line-height: 1;
  color: var(--color-text);
}

.player-comparisons__label-kicker {
  font-size: var(--hero-chrome-caps-size);
  font-weight: 600;
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
  line-height: 1;
  color: var(--hero-chrome-caps-color);
  white-space: nowrap;
}

.player-comparisons__side--similar .player-comparisons__label {
  margin-left: var(--comparison-frame-hang);
  text-align: left;
}

.player-comparisons__side--different .player-comparisons__label {
  margin-right: var(--comparison-frame-hang);
  margin-left: auto;
  text-align: right;
}

.player-comparisons__cards {
  display: flex;
  gap: var(--roster-card-gap, 4px);
  align-items: flex-start;
  width: var(--portrait-slot);
  max-width: 100%;
  margin: 0;
  padding: 0;
  min-height: 0;
  box-sizing: border-box;
}

.player-comparisons__side--similar .player-comparisons__cards {
  margin-left: var(--comparison-frame-hang);
}

.player-comparisons__side--different .player-comparisons__cards {
  margin-right: var(--comparison-frame-hang);
  margin-left: auto;
}

.player-comparisons .player-card {
  flex: 0 0 var(--portrait-slot);
  width: var(--portrait-slot);
  padding-bottom: var(--player-card-footer-pad);
}

/* Pull the name up under the portrait — no roster-strip matte gap here. */
.player-comparisons .player-card__meta {
  position: relative;
  z-index: 1;
  margin-top: 0.25rem;
  gap: 0.1rem;
}

/* Hover/selected chrome must not change the card's layout box here. */
.player-comparisons .player-card--selected,
.player-comparisons .player-card--chart-hover,
.player-comparisons .player-card--scrub-linger,
.player-comparisons .player-card:hover {
  flex: 0 0 var(--portrait-slot);
  width: var(--portrait-slot);
  z-index: 1;
}

.player-hero__info {
  /*
   * Grid (not flex-column) so College and Experience can share one row: College
   * is a normal in-flow item that sizes row 3 from its own content (it has
   * to — the row's start depends on the heading/meta block's height, which
   * varies with name length and text wrapping). Experience is placed in that same
   * row/column span and *then* taken out of flow with position:absolute —
   * per the CSS Grid spec, an absolutely-positioned item with explicit grid
   * placement is positioned relative to that grid area, so `top: 0` lands
   * it exactly flush with wherever row 3 starts. That's what keeps it level
   * with College without any JS measuring anything.
   */
  /* Shared with .cluster-stack's margin-top and .cluster-bar--hairstyle-anchor's
     top so College and Experience land on the same visual row edge. */
  --cluster-row-gap: 1.15rem;
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto auto auto;
  /* .player-hero__info stretches to fill the full hero height (flex:1 1
     auto below), but the 3 rows should pack at the top like the old
     flex-column layout did — without this, "auto" rows share out all the
     leftover vertical space and shove row 3 (College/Experience) way down. */
  align-content: start;
  position: relative;
  /* Above comparison chrome (and peek) so Selected vs Hovered stays readable. */
  z-index: 5;
  min-width: 0;
  flex: 1 1 auto;
  min-height: 0;
  align-self: stretch;
  padding-left: var(--hero-cluster-inset-start, 0.25rem);
  /* Sit the name on the same top edge as the first chart plot (below Overall). */
  padding-top: var(--hero-align-to-chart);
  padding-bottom: 0.5rem;
  pointer-events: none;
  overflow: visible;
}

.player-hero__heading {
  grid-column: 1 / -1;
  grid-row: 1;
  display: flex;
  align-items: center;
  gap: 0.45em;
  min-width: 0;
  font-size: var(--hero-name-size);
  margin-bottom: 0;
  flex-shrink: 0;
  pointer-events: auto;
  transition: opacity var(--hero-fade-ms) ease;
}

.player-hero__meta {
  grid-column: 1 / -1;
  grid-row: 2;
  flex-shrink: 0;
  pointer-events: auto;
  transition: opacity var(--hero-fade-ms) ease;
}

.cluster-bar {
  pointer-events: auto;
  /* Only opacity eases (hero fades). The narrow-viewport College/Experience
     separation nudge (transform, set on .cluster-bar--open below) has no
     transition — it's driven purely by viewport width via clamp()/calc(),
     so it should track a live resize 1:1, not ease toward a
     constantly-moving target (which just looks like lag/jitter mid-drag). */
  transition: opacity var(--hero-fade-ms) ease;
}

.cluster-stack {
  transition: opacity var(--hero-fade-ms) ease;
}

/* Fade name/meta/photos only — similar/different thumbnails stay put while
   the hero content swaps (same as list/chart selection). */
.player-hero--fade-out .player-hero__heading,
.player-hero--fade-out .player-hero__meta,
.player-hero--fade-in .player-hero__heading,
.player-hero--fade-in .player-hero__meta,
.player-hero--fade-out .player-hero__photo,
.player-hero--fade-in .player-hero__photo,
.player-hero--fade-out .player-hero__peek-photo,
.player-hero--fade-in .player-hero__peek-photo,
.player-hero--fade-out .player-hero__peek-standin,
.player-hero--fade-in .player-hero__peek-standin {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .player-hero__heading,
  .player-hero__meta,
  .player-hero__photo,
  .player-hero__peek-photo,
  .cluster-bar {
    transition: none;
  }

  .player-hero--peek-wipe .player-hero__peek-photo,
  .player-hero__peek-photo--enter {
    animation: none;
  }
}

.player-hero__name {
  display: block;
  /* Center with team/college badges (heading align-items: center). */
  align-self: center;
  margin: 0;
  padding: 0;
  min-width: 0;
  flex: 1 1 auto;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--color-text);
  z-index: 1;
  text-transform: none;
}

.player-hero__name-first {
  font-weight: 400;
}

.player-hero__name-last {
  font-weight: 800;
}

/* Selected vs hovered peer in the hero title while comparing.
   Center-align with badges (same as idle) so selected glyphs do not jump
   when peer logos inflate the line to badge height. */
.player-hero__name--compare {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 0.35em;
  row-gap: 0.1em;
}

.player-hero__compare-vs {
  color: var(--color-text-inactive);
  font-weight: 400;
  letter-spacing: 0;
}

.player-hero__compare-hover {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  min-width: 0;
  color: var(--color-bar);
}

.player-hero__compare-hover .player-hero__name-last {
  font-weight: 700;
}

/* Peer logos match heading badges; muted with the greyed name. */
.player-hero__compare-badge {
  flex: 0 0 auto;
  height: 1em;
  width: auto;
  object-fit: contain;
  object-position: center;
  filter: grayscale(1);
  opacity: 0.5;
}

.player-hero__team-badge,
.player-hero__college-badge {
  flex: 0 0 auto;
  align-self: center;
  /* Match the name’s em box so logo + type share top, center, and bottom. */
  height: 1em;
  width: auto;
  object-fit: contain;
  object-position: center;
}

.player-hero__team-badge + .player-hero__college-badge,
.player-hero__compare-badge--team + .player-hero__compare-badge--college {
  margin-inline-start: -0.22em;
}

.player-hero__heading .player-hero__name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 1em;
  line-height: 1;
}

.player-hero__meta {
  --position-pill-font-size: var(--hero-meta-size);
  --hero-meta-data-size: var(--position-pill-font-size);
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0;
  margin-top: 2px;
  font-size: var(--hero-meta-data-size);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1;
  color: #000;
}

.player-hero__meta-grid {
  /* Let each stat participate in the outer flex line so wrapping happens
     between stats instead of moving the entire stats group after the badge. */
  display: contents;
}

.player-hero__meta-row {
  font-size: var(--hero-meta-data-size);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1;
  color: #000;
  white-space: nowrap;
}

.player-hero__meta-row:not(:last-child) {
  --hero-meta-rule-gap: 0.7em;
  position: relative;
  padding-right: var(--hero-meta-rule-gap);
  margin-right: var(--hero-meta-rule-gap);
}

.player-hero__meta-row:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  width: 1px;
  height: 1em;
  background: var(--color-border-strong);
  transform: translateY(-50%);
}

.player-hero__meta b {
  font-size: var(--hero-chrome-caps-size);
  font-weight: 600;
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
  color: var(--hero-chrome-caps-color);
}

.player-hero__filter-pills {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  flex: 0 0 auto;
  gap: 12px 16px;
  --hero-meta-rule-gap: 0.7em;
  position: relative;
  padding-right: var(--hero-meta-rule-gap);
  margin-right: var(--hero-meta-rule-gap);
}

.player-hero__filter-pills::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  width: 1px;
  height: 1em;
  background: var(--color-border-strong);
  transform: translateY(-50%);
}

.position-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 3.25rem;
  max-width: 14rem;
  padding: 0.2em 0.55em;
  border: 1px solid var(--color-border-strong);
  border-radius: 8px;
  background: transparent;
  font: inherit;
  font-size: var(--position-pill-font-size, clamp(1.05rem, 2.2vw, 1.5rem));
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--color-link);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition:
    color 0.18s ease,
    background 0.18s ease,
    border-color 0.18s ease,
    box-shadow 0.18s ease;
}

/* Hover thickens the stroke rather than washing in a fill — an outer ring so
   the extra weight costs no layout. */
.position-pill:hover {
  color: var(--color-text);
  border-color: var(--color-text-muted);
  box-shadow: 0 0 0 1px var(--color-text-muted);
}

.position-pill:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.position-pill--active {
  color: var(--color-nav-text);
  background: var(--color-nav-fill);
  border-color: var(--color-nav-fill);
}

.position-pill--active:hover {
  color: var(--color-nav-text);
  border-color: var(--color-nav-fill);
  background: var(--color-nav-fill);
  box-shadow: 0 0 0 1px var(--color-nav-fill);
}

.hero-filter-pill--disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.player-hero__meta-row b {
  font-size: var(--hero-chrome-caps-size);
  font-weight: 600;
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
  color: var(--hero-chrome-caps-color);
}

.hero-stat-link {
  display: inline;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--color-link);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
  text-underline-offset: 0.15em;
  cursor: pointer;
}

.hero-stat-link:hover {
  color: var(--color-text);
  text-decoration-color: var(--color-text);
}

.hero-stat-link:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.chart-panel {
  display: flex;
  flex-direction: column;
  gap: var(--chart-panel-gap);
  min-height: 0;
  height: 100%;
  width: var(--chart-panel-width);
  flex-shrink: 0;
  align-items: stretch;
  overflow: visible;
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
}

.stats-panel {
  --stats-bg: transparent;
  --stats-surface: transparent;
  --stats-label: #2a2f38;
  --stats-label-secondary: #5a6270;
  --stats-label-tertiary: #8b93a0;
  --stats-separator: rgba(0, 0, 0, 0.1);
  --stats-fill: #f2f3f5;
  --stats-fill-pressed: #e8eaed;
  --stats-accent: #6a9ec4;
  /* Active plot: cool blue well + band. Inactive: neutral gray well. */
  --chart-bg: #ececee;
  --chart-bg-focus: #e8f0f7;
  --chart-border: rgba(0, 0, 0, 0.12);
  --chart-border-focus: #6a9ec4;
  --chart-level: rgba(40, 78, 112, 0.2);
  --chart-level-ambient: rgba(120, 126, 136, 0.15);
  --chart-level-grad: rgba(40, 78, 112, 0.48);
  --chart-bar: #bdbec4;
  --chart-bar-focus: #5a7fa3;
  /* Legacy single-bar --hover (unused by compare path; keep neutral darken). */
  --chart-bar-hover: #6a6e78;
  --chart-bar-hover-ambient: #a5a8af;
  /* Ambient charts remain neutral; focused charts use one blue bar color. */
  --chart-bar-below-ambient: var(--chart-bar);
  --chart-bar-at-or-above: var(--color-link);
  --chart-bar-below: var(--chart-bar-at-or-above);
  /* Okabe-Ito colorblind-safe equivalents of green (higher) and red (lower).
     Higher is a darkened bluish-green (#007a58) for grey-surface text contrast;
     hue stays Okabe–Ito so it remains separable from vermillion under CVD. */
  --chart-compare-higher: #007a58;
  --chart-compare-lower: #d55e00;
  --chart-compare-higher-ambient: #5f9188;
  --chart-compare-lower-ambient: #b98f74;
  /* Compare outside-band: solid RGB stand-ins for bar@0.4 over chart-bg. */
  --chart-bar-ghost: #d4d5da;
  --chart-bar-ghost-focus: #afc3d5;
  --chart-bar-ghost-selected: #949497;
  --chart-bar-ghost-selected-focus: #92969c;
  /* Inspect / passive hover preview bar — Okabe–Ito amber (#F5C710, R 4.0+ default).
     Stays distinct from bluish-green compare-higher, vermillion compare-lower,
     focus blue, black needle, and grey ambient bars under protan/deutan/tritan. */
  --chart-bar-hover-ghost: #f5c710;
  --chart-bar-hover-ghost-focus: #f5c710;
  /* Scrub chrome: solid strokes (no alpha fills on bars). */
  --chart-band-stroke: #5c616c;
  --chart-band-stroke-focus: #577e9c;
  --chart-rail-track: #d8d8da;
  --chart-rail-track-focus: #a3c3db;
  --chart-rail-thumb: #5c616c;
  --chart-rail-thumb-focus: #40586e;
  --chart-rail-thumb-hover: #3a3e46;
  --chart-rail-thumb-focus-hover: #2a3d4f;
  --chart-rail-selected-muted: #71757a;
  /* Vertical rhythm for the accordion list — change this to retune spacing. */
  --stats-panel-row-gap: 2px;
  --stats-panel-pad-x: 12px;
  --stats-panel-pad-y: 8px;
  --stats-panel-pad-top: var(--stats-panel-pad-y);
  --stats-panel-pad-bottom: var(--stats-panel-pad-y);
  display: flex;
  flex-direction: column;
  position: relative;
  flex: 1;
  min-height: 0;
  width: 100%;
  overflow: hidden;
  background: var(--stats-bg);
  color: var(--stats-label);
  font-family: var(--font-family);
  -webkit-font-smoothing: antialiased;
}

.stats-panel__profile-trace {
  position: absolute;
  inset: 0;
  z-index: 3;
  width: 100%;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
}

.stats-panel__profile-trace polyline {
  fill: none;
  stroke: rgba(203, 211, 220, 0.15);
  stroke-width: 1;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

/* Prototype: every stat stays expanded — selection only, no accordion chrome. */
.stats-panel--flat {
  --stats-panel-row-gap: 0;
  /* Side inset = shadow bleed so frame lift paints inside overflow clip. */
  --stats-panel-pad-x: var(--chart-frame-shadow-bleed);
  --stats-panel-pad-y: 6px;
  --stats-panel-pad-top: var(--detail-top-inset, 0px);
  --stats-panel-pad-bottom: var(--stats-panel-pad-y);
  /* Slightly less landscape so plots read taller relative to the roster strip. */
  --flat-chart-aspect: 2.75 / 1;
  overflow: visible;
}

/* Flat: Overall is a static sibling above the scrollable catalog. */
.stats-panel__overall {
  display: none;
  flex: 0 0 auto;
  width: 100%;
  min-width: 0;
}

.stats-panel--flat .stats-panel__overall {
  display: block;
  position: relative;
  z-index: 2;
  box-sizing: border-box;
  width: 100%;
  padding: 0 var(--stats-panel-pad-x) 0;
  background: var(--color-bg);
}

.stats-panel__body {
  display: contents;
}

.stats-panel--flat .stats-panel__body {
  /* Minimap is overlaid in the left bleed; main is full panel width so Overall
     and catalog charts share one content width. */
  position: relative;
  display: block;
  flex: 1;
  min-height: 0;
  min-width: 0;
  padding-inline-start: 0;
}

.stats-panel__main {
  display: contents;
}

.stats-panel--flat .stats-panel__main {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  min-height: 0;
  min-width: 0;
}

.stats-panel__ranked-by {
  flex: 0 0 auto;
  margin: 0;
  padding: 0;
  font-size: var(--hero-chrome-caps-size);
  font-weight: var(--hero-chrome-caps-weight);
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
  color: var(--hero-chrome-caps-color);
  line-height: 1.2;
}

.stats-panel__ranked-by-lead {
  font-weight: var(--hero-chrome-caps-weight);
  color: var(--hero-chrome-caps-color);
}

.stats-panel__ranked-by-stat {
  margin-inline-start: 0.35em;
  /* Size/tracking match list labels; weight/color come from the shared
     active-name rule with .stat-group--focus/.stat-group--browse. */
  font-size: var(--hero-chrome-caps-size);
  line-height: 1;
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
}

.stats-panel__ranked-by-lead[hidden] + .stats-panel__ranked-by-stat {
  margin-inline-start: 0;
}

.stats-panel--flat .stats-panel__ranked-by {
  padding-top: 0;
  padding-bottom: 0;
}

.catalog-minimap {
  display: none;
}

.stats-panel--flat .catalog-minimap {
  display: block;
  position: absolute;
  left: 0;
  /* Height tracks the catalog list only (set in updateCatalogMinimap). */
  top: var(--catalog-minimap-top, 0px);
  bottom: auto;
  height: var(--catalog-minimap-height, 100%);
  z-index: 4;
  width: 14px;
  min-width: 14px;
  cursor: pointer;
  touch-action: none;
  padding: 0;
  box-sizing: border-box;
}

.catalog-minimap:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.catalog-minimap__rail {
  position: relative;
  width: 6px;
  height: 100%;
  margin-inline: auto;
  border-radius: 3px;
  background: #d8d9dd;
}

.catalog-minimap__marker {
  --minimap-t: 0;
  --minimap-thumb: 28px;
  position: absolute;
  left: 50%;
  top: calc(var(--minimap-t) * (100% - var(--minimap-thumb)));
  width: var(--minimap-thumb-thickness);
  height: var(--minimap-thumb);
  border-radius: 999px;
  background: var(--color-text);
  transform: translateX(-50%);
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  transition:
    top 0.12s ease,
    transform 0.12s ease,
    width 0.12s ease;
}

.catalog-minimap__marker:hover {
  width: var(--minimap-thumb-thickness-active);
}

.catalog-minimap--dragging {
  cursor: grabbing;
}

.catalog-minimap--dragging .catalog-minimap__marker {
  width: var(--minimap-thumb-thickness-active);
  cursor: grabbing;
  transition: none;
}

.catalog-minimap--suppress-marker-hover .catalog-minimap__marker,
.catalog-minimap--suppress-marker-hover .catalog-minimap__marker:hover {
  width: var(--minimap-thumb-thickness);
}

.catalog-minimap--empty,
.catalog-minimap--fit {
  visibility: hidden;
  pointer-events: none;
}

.stats-panel--flat .stats-panel__catalog,
.stats-panel--flat .stats-panel__list {
  flex: 1;
  min-height: 0;
  min-width: 0;
  box-sizing: border-box;
  width: 100%;
  /* Top inset lives on the stat definition; catalog sits below Overall.
     Flat catalog uses windowed reorder (no pixel scroll). */
  padding-top: 0;
  /* Same horizontal inset as Overall — equal chart width + shadow bleed. */
  padding-inline: var(--stats-panel-pad-x);
  padding-bottom: var(--stats-panel-pad-bottom);
  overflow-x: hidden;
  overflow-y: hidden;
  overscroll-behavior: none;
}

.stats-panel__stat-def {
  /* Fixed footprint so swapping definitions never reflows the catalog below. */
  flex: 0 0 auto;
  box-sizing: border-box;
  width: 100%;
  margin: 0;
  padding:
    var(--stats-panel-pad-top)
    var(--stats-panel-pad-x)
    0.75rem;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  overflow: hidden;
  border-bottom: 1px solid var(--color-border);
}

.stats-panel__stat-def-body {
  margin: 0;
  flex: 0 0 auto;
  margin-top: 0.4rem;
  max-width: 36ch;
  /* Reserve 3 lines so catalog layout stays put across short/long copy. */
  height: calc(1.45em * 3);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.45;
  color: var(--color-text-muted);
  overflow: hidden;
}

/*
 * Chart straddling the catalog’s lower clip edge: tall dissolve toward the fold
 * so the whole stub reads as fading out (not a thin edge wipe).
 */
.stats-panel--flat .stat-group--catalog-crop-fade {
  -webkit-mask-image: linear-gradient(
    to bottom,
    #000 0%,
    #000 var(--catalog-crop-solid, 18%),
    rgba(0, 0, 0, 0.35) var(--catalog-crop-soft, 48%),
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    #000 0%,
    #000 var(--catalog-crop-solid, 18%),
    rgba(0, 0, 0, 0.35) var(--catalog-crop-soft, 48%),
    transparent 100%
  );
}

/* Chart straddling the catalog’s upper clip edge. */
.stats-panel--flat .stat-group--catalog-crop-fade-top {
  -webkit-mask-image: linear-gradient(
    to top,
    #000 0%,
    #000 var(--catalog-crop-solid, 18%),
    rgba(0, 0, 0, 0.35) var(--catalog-crop-soft, 48%),
    transparent 100%
  );
  mask-image: linear-gradient(
    to top,
    #000 0%,
    #000 var(--catalog-crop-solid, 18%),
    rgba(0, 0, 0, 0.35) var(--catalog-crop-soft, 48%),
    transparent 100%
  );
}

/*
 * Chart above the current window: same cue as bottom crop-fade — a real
 * partial chart under Overall, faded toward the clip edge — so ↑ browse can
 * always see that there’s another chart above until the first one.
 * justify-content:flex-end keeps the chart’s lower edge (adjacent to the
 * window) in the peek band; overflow clips the rest above.
 */
.stats-panel--flat .stat-group--catalog-top-peek {
  --catalog-top-peek-height: 6.5rem;
  --catalog-top-crop-solid: 38%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  flex: 0 0 auto;
  height: var(--catalog-top-peek-height);
  max-height: var(--catalog-top-peek-height);
  min-height: 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
  pointer-events: auto;
  opacity: 1;
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    #000 var(--catalog-top-crop-solid),
    #000 100%
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    #000 var(--catalog-top-crop-solid),
    #000 100%
  );
}

.stats-panel--flat .stat-group--catalog-bottom-peek {
  --catalog-bottom-peek-height: 6.5rem;
  --catalog-bottom-crop-solid: 38%;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  flex: 0 0 auto;
  height: var(--catalog-bottom-peek-height);
  max-height: var(--catalog-bottom-peek-height);
  min-height: 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
  pointer-events: auto;
  opacity: 1;
  -webkit-mask-image: linear-gradient(
    to top,
    transparent 0%,
    #000 var(--catalog-bottom-crop-solid),
    #000 100%
  );
  mask-image: linear-gradient(
    to top,
    transparent 0%,
    #000 var(--catalog-bottom-crop-solid),
    #000 100%
  );
}

.stats-panel--flat .catalog-peek-spacer {
  flex: 0 0 auto;
  height: 6.5rem;
  max-height: 6.5rem;
  min-height: 6.5rem;
  pointer-events: none;
  visibility: hidden;
}

.stats-panel--flat .stat-group--catalog-top-peek .stat-chart__tooltip,
.stats-panel--flat .stat-group--catalog-top-peek .stat-chart__selection-triangle,
.stats-panel--flat .stat-group--catalog-bottom-peek .stat-chart__tooltip,
.stats-panel--flat .stat-group--catalog-bottom-peek .stat-chart__selection-triangle {
  display: none !important;
}

.stats-panel--flat .stat-group--catalog-top-peek .stat-body__chart,
.stats-panel--flat .stat-group--catalog-bottom-peek .stat-body__chart {
  box-shadow: none;
}

.stats-panel--flat .stat-head__icon {
  display: none;
}

.stats-panel--flat .stat-sparkline {
  display: none;
}

.stats-panel--flat .stat-body {
  max-height: none;
  overflow: visible;
}

.stats-panel--flat .stat-head {
  gap: var(--flat-head-gap, 3px);
  /* Idle slack sits above the name so chart↔chart pitch stays put while the
     label rides closer to the frame; collapses when extremes need the gap. */
  padding: calc(var(--flat-head-pad-top, 0px) + var(--chart-label-slack, 0px)) 0 0;
}

.stats-panel--flat .stats-panel__overall > .stat-group .stat-head,
.stats-panel--flat .stats-panel__catalog > .stat-group:first-child .stat-head,
.stats-panel--flat .stats-panel__list > .stat-group:first-child .stat-head {
  padding-top: calc(var(--flat-head-pad-top, 0px) + var(--chart-label-slack, 0px));
}

.stats-panel--flat .stat-head__top {
  position: relative;
  min-height: 0;
  gap: 8px;
}

.stats-panel--flat .stat-head__name {
  /* Match hero all-caps chrome (College, Experience, …). */
  font-size: var(--hero-chrome-caps-size);
  font-weight: var(--hero-chrome-caps-weight);
  line-height: 1;
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
  color: var(--hero-chrome-caps-color);
}


.stats-panel--flat .stat-body__chart {
  position: relative;
  box-sizing: border-box;
  width: 100%;
  height: auto;
  aspect-ratio: var(--flat-chart-aspect);
  margin: var(--chart-top-reserve, 8px) 0 10px;
  overflow: visible;
}

.stats-panel--flat .stat-body__foot {
  display: none !important;
  padding: 0;
}

.stats-panel--flat .stats-panel__profile-trace {
  display: none;
}

.stats-panel--flat .stat-group {
  /*
   * Keep chart↔chart pitch: idle moves the extremes reserve above the label
   * (label closer to frame); hover/focus puts it back between label and chart.
   * Active stack: label → 4px → min/max → 8px → frame.
   */
  --chart-label-to-extremes: 4px;
  --chart-extremes-to-frame: 8px;
  --chart-extremes-size: var(--player-list-name-last-size);
  --chart-top-reserve-idle: 8px;
  --chart-top-reserve-active: calc(
    var(--chart-label-to-extremes) + var(--chart-extremes-size) +
      var(--chart-extremes-to-frame)
  );
  --chart-top-reserve: var(--chart-top-reserve-idle);
  --chart-label-slack: calc(
    var(--chart-top-reserve-active) - var(--chart-top-reserve-idle)
  );
  border: none;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  cursor: pointer;
  overflow: visible;
}

.stats-panel--flat .stat-group--focus,
.stats-panel--flat .stat-group:has(.stat-body__chart:hover),
.stats-panel--flat .stat-group--browse,
.stats-panel--flat .stat-group--extremes-hold {
  --chart-top-reserve: var(--chart-top-reserve-active);
  --chart-label-slack: 0px;
}

.stats-panel--flat .stat-group--browse .stat-body__chart {
  /* Same frame lift as pointer hover — including on the selected chart when
     focus has returned to it, so browse location stays visible. */
  box-shadow: var(--chart-frame-hover-shadow);
}

/* Only one hover lift at a time: mouse frame-hover/fade wins over browse chrome
   on any other chart (typically the selected/ranked one). */
.stats-panel--flat:has(
    .stat-body__chart--frame-hover,
    .stat-body__chart--frame-fade
  )
  .stat-group--browse
  .stat-body__chart:not(.stat-body__chart--frame-hover):not(
    .stat-body__chart--frame-fade
  ) {
  box-shadow: none;
}

/* Catalog carousel step: top collapses away, then the row is moved to the end. */
.stats-panel--flat .stat-group--catalog-exit,
.stats-panel--flat .stat-group--catalog-enter {
  overflow: hidden;
  pointer-events: none;
  flex: 0 0 auto;
  min-height: 0;
  transition:
    height 160ms ease-out,
    opacity 110ms ease;
}

/* Empty landing gap while a crop-faded selection reveals upward. */
.stats-panel--flat .stat-group--catalog-reveal-gap {
  overflow: hidden;
  pointer-events: none;
  flex: 0 0 auto;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: none;
  background: transparent;
  transition: height 150ms ease;
}

.stats-panel--flat .stat-group--pinned {
  /* Overall is outside the scroll pane in flat mode — no sticky underlap. */
  position: static;
  background: var(--color-bg);
  box-shadow: none;
  z-index: auto;
}

.stats-panel--flat .stat-group--pinned::after {
  display: none;
}

.stats-panel--flat .stat-group--focus {
  background: transparent;
  border: none;
  box-shadow: none;
}

/* Selected chart: idle/post-commit has no wash. Wash returns only after the
   pointer leaves selected and later re-hovers / re-browses it. */
.stats-panel--flat:not(.stats-panel--suppress-selected-wash) .stat-group--focus.stat-group--browse,
.stats-panel--flat:not(.stats-panel--suppress-selected-wash) .stat-group--focus:has(.stat-body__chart:hover),
.stats-panel--flat .stat-group--focus.stat-group--extremes-hold {
  background: var(--color-chart-focus-browse-fill);
}


/*
 * Selected vs unselected plot chrome (keep per-stat high→low sort):
 * Active — light blue well, clear blue border, blue value band.
 * Inactive — neutral gray well, quieter border, muted gray band.
 */
.stats-panel--flat .stat-chart--bars {
  position: relative;
  background: var(--chart-bg);
  border: 1px solid var(--chart-border);
  border-radius: 0;
  box-shadow: none;
  /* The plot remains clipped; endpoint values are allowed above the frame. */
  overflow: visible;
  isolation: isolate;
  --plot-inset: 8px;
  height: 100%;
}

.stats-panel--flat .stat-chart__extremes {
  position: absolute;
  /* Hang from the top of the reserve so the label→value gap stays 4px. */
  top: calc(
    -1 * var(--chart-top-reserve, 8px) + var(--chart-label-to-extremes, 4px)
  );
  bottom: auto;
  left: 0;
  right: 0;
  z-index: 9;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  color: #000;
  font-size: var(--chart-extremes-size, var(--player-list-name-last-size));
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1;
  pointer-events: none;
  opacity: 0;
}

.stats-panel--flat .stat-chart__selection-triangle {
  position: absolute;
  bottom: calc(100% + 1px);
  z-index: 10;
  width: 0;
  height: 0;
  margin-left: -5px;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 7px solid var(--stats-label-secondary);
  pointer-events: none;
}

.stats-panel--flat .stat-group--focus .stat-chart__selection-triangle {
  border-top-color: #101014;
}

.stats-panel--flat .stat-chart__selection-triangle[hidden] {
  display: none;
}

.stats-panel--flat .stat-body__chart:hover .stat-chart__extremes,
.stats-panel--flat .stat-group--focus .stat-chart__extremes,
.stats-panel--flat .stat-group--browse .stat-chart__extremes,
.stats-panel--flat .stat-group--extremes-hold .stat-chart__extremes {
  opacity: 1;
}

/* While ↑/↓ owns browse, ignore CSS :hover on other charts so only the
   keyboard browse target reads as focused. Same suppress during player ←/→. */
.stats-panel--flat:is(.stats-panel--keyboard-chart-browse, .stats-panel--player-nav)
  .stat-group:not(.stat-group--browse):has(.stat-body__chart:hover) {
  --chart-top-reserve: var(--chart-top-reserve-idle);
  --chart-label-slack: calc(
    var(--chart-top-reserve-active) - var(--chart-top-reserve-idle)
  );
}

.stats-panel--flat:is(.stats-panel--keyboard-chart-browse, .stats-panel--player-nav)
  .stat-group:not(.stat-group--browse)
  .stat-body__chart:hover
  .stat-chart__extremes {
  opacity: 0;
}

.stats-panel--flat:is(.stats-panel--keyboard-chart-browse, .stats-panel--player-nav)
  .stat-group:not(.stat-group--browse)
  .stat-body__chart:hover {
  box-shadow: none;
}

.stats-panel--flat
  .stat-group:not(.stat-group--focus)
  .stat-body__chart:hover
  .stat-chart__extremes,
.stats-panel--flat
  .stat-group--browse:not(.stat-group--focus)
  .stat-chart__extremes,
.stats-panel--flat
  .stat-group--extremes-hold:not(.stat-group--focus)
  .stat-chart__extremes {
  color: var(--chart-bar);
}

.stats-panel--flat .stat-group--focus .stat-chart--bars {
  background: var(--chart-bg-focus);
  border-color: var(--chart-border-focus);
}

/* Zoomed scrollport: same plot insets as overview so bar pixel heights stay put.
   Close floats outside; rail sits in the existing bottom inset. */
.stats-panel--flat .stat-chart--bars.stat-chart--scrub-window {
  border: 1px solid var(--chart-border-focus);
  background: #dfeaf3;
  box-shadow: none;
  --plot-inset-top: var(--plot-inset);
  --plot-inset-bottom: var(--plot-inset);
  --plot-inset-x: var(--plot-inset);
}

.stats-panel--flat .stat-body__chart[data-scrub-window="1"] {
  /* Slight lift so the zoomed chart separates from idle neighbors. */
  filter: none;
}

.stats-panel--flat .stat-body__chart[data-scrub-window="1"] .stat-chart--bars {
  cursor: grab;
}

/* Level line hidden while scrubbing — threshold is shown via bar tint. */
.stats-panel--flat .stat-chart--bars > .stat-chart__level {
  display: block;
  left: var(--plot-inset);
  right: var(--plot-inset);
  top: auto;
  bottom: calc(var(--plot-inset) + (100% - 2 * var(--plot-inset)) * var(--level-t, 0));
  height: 0;
  background: none;
  border: none;
  border-top: 1px solid var(--chart-band-stroke-focus);
  box-shadow: none;
  z-index: 6;
  pointer-events: none;
  opacity: 0;
}

.stats-panel--flat .stat-chart--scrub-window > .stat-chart__level {
  opacity: 0;
}

.stats-panel--flat .stat-group:not(.stat-group--focus) .stat-chart--bars > .stat-chart__level {
  border-top-color: var(--chart-band-stroke);
}

/* Outer chart frame lift on pointer hover (focus or ambient). */
@keyframes chart-frame-shadow-fade {
  from {
    box-shadow: var(--chart-frame-hover-shadow);
  }
  to {
    box-shadow:
      0 3px 28px rgba(0, 0, 0, 0),
      0 1px 10px rgba(0, 0, 0, 0),
      0 0 0 1px rgba(0, 0, 0, 0);
  }
}

.stats-panel--flat .stat-body__chart--frame-hover {
  box-shadow: var(--chart-frame-hover-shadow);
}

.stats-panel--flat .stat-body__chart--frame-fade {
  animation: chart-frame-shadow-fade var(--scrub-linger-ms, 180ms) ease-out forwards;
}

.stats-panel--flat .stat-chart--bars .stat-chart__plot {
  inset: var(--plot-inset);
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

/* Scrub gutters must win over the uniform inset above — otherwise the rail
   sits on top of the bars. */
.stats-panel--flat .stat-chart--scrub-window .stat-chart__plot {
  top: var(--plot-inset-top);
  right: var(--plot-inset-x);
  bottom: var(--plot-inset-bottom);
  left: var(--plot-inset-x);
  overflow: hidden;
}

/* Scrub ghost overview — unused in Approach B full-width zoom; keep hidden. */
.stats-panel--flat .stat-chart__bars--ghost,
.stats-panel--flat .stat-chart--scrub-window .stat-chart__bars--ghost {
  display: none !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

@keyframes scrub-lens-layer-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes scrub-lens-layer-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

.stats-panel--flat .stat-chart--scrub-window-enter .stat-chart__lens-viewport,
.stats-panel--flat .stat-chart--scrub-window-enter .stat-chart__bars--lens,
.stats-panel--flat .stat-chart--scrub-window-enter .stat-chart__window-selected,
.stats-panel--flat .stat-chart--scrub-window-enter > .stat-chart__window-rail {
  animation: scrub-lens-layer-in var(--scrub-lens-fade-ms, 220ms) ease-out both;
}

.stats-panel--flat .stat-chart--scrub-window-exit .stat-chart__lens-viewport,
.stats-panel--flat .stat-chart--scrub-window-exit .stat-chart__bars--lens,
.stats-panel--flat .stat-chart--scrub-window-exit .stat-chart__window-selected,
.stats-panel--flat .stat-chart--scrub-window-exit > .stat-chart__window-rail {
  animation: scrub-lens-layer-out var(--scrub-lens-fade-ms, 220ms) ease-in both;
}

@media (prefers-reduced-motion: reduce) {
  .stats-panel--flat .stat-chart--scrub-window-enter .stat-chart__lens-viewport,
  .stats-panel--flat .stat-chart--scrub-window-enter .stat-chart__bars--lens,
  .stats-panel--flat .stat-chart--scrub-window-enter .stat-chart__window-selected,
  .stats-panel--flat .stat-chart--scrub-window-enter > .stat-chart__window-rail,
  .stats-panel--flat .stat-chart--scrub-window-exit .stat-chart__lens-viewport,
  .stats-panel--flat .stat-chart--scrub-window-exit .stat-chart__bars--lens,
  .stats-panel--flat .stat-chart--scrub-window-exit .stat-chart__window-selected,
  .stats-panel--flat .stat-chart--scrub-window-exit > .stat-chart__window-rail {
    animation: none;
  }
}

.stats-panel--flat .stat-chart__bars--lens {
  position: relative;
  z-index: 2;
}

.stats-panel--flat .stat-chart__lens-viewport {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  overflow: hidden;
  z-index: 2;
  pointer-events: none;
}

.stats-panel--flat .stat-chart__lens-reticle,
.stats-panel--flat .stat-chart--scrub-window .stat-chart__lens-reticle {
  display: none !important;
}

.stats-panel--flat .stat-chart--scrub-window .stat-chart__bars--lens {
  z-index: 2;
  height: 100%;
}
@property --window-start-t {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

@property --window-span-t {
  syntax: "<number>";
  inherits: true;
  initial-value: 0.2;
}

/* Lens frame — full-bleed around the zoomed scrollport. */
.stats-panel--flat .stat-chart--scrub-window .stat-chart__plot::after {
  content: none;
  display: none;
}

.stats-panel--flat .stat-chart--scrub-window .stat-chart__lens-viewport {
  left: 0;
  right: 0;
  width: 100% !important;
  max-width: 100% !important;
  transform: none;
}

/* Armed hover: same blue frame, no zoomed filmstrip yet. */
.stats-panel--flat .stat-chart--scrub-armed .stat-chart__plot {
  overflow: visible;
}

.stats-panel--flat .stat-chart--scrub-armed .stat-chart__plot::after {
  content: "";
  position: absolute;
  top: -5px;
  bottom: -5px;
  left: var(--window-band-left, 0px);
  width: var(--window-band-width, 16px);
  z-index: 4;
  pointer-events: none;
  box-sizing: border-box;
  background: none;
  border: 1px solid var(--chart-band-stroke-focus);
  opacity: 1;
}

.stats-panel--flat .stat-body__chart--scrub-grab {
  cursor: pointer;
  touch-action: none;
}

.stats-panel--flat .stat-body__chart--scrub-in-lens {
  cursor: grab;
  touch-action: none;
}

.stats-panel--flat .stat-body__chart--scrub-grabbing {
  cursor: grabbing;
  touch-action: none;
  user-select: none;
}

.stats-panel--flat .stat-chart__lens-close {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 8;
  display: none;
  align-items: center;
  justify-content: flex-end;
  width: auto;
  min-width: 0;
  height: auto;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 3px;
  background: transparent;
  color: #3a3e46;
  font: 400 18px/1 system-ui, sans-serif;
  cursor: pointer;
  pointer-events: auto;
  opacity: 0.85;
  transform: none;
  transform-origin: center right;
  white-space: nowrap;
  overflow: visible;
  transition:
    color 120ms ease,
    opacity 120ms ease,
    transform 120ms ease;
  gap: 5px;
}

.stats-panel--flat .stat-chart__lens-close:hover {
  opacity: 1;
  color: #101014;
  background: transparent;
  transform: scale(1.04);
}

.stats-panel--flat .stat-chart__lens-close:active {
  color: #000;
  background: transparent;
  transform: scale(1.02);
}

/* "reset" sits immediately left of the × */
.stats-panel--flat .stat-chart__lens-close::before {
  content: "reset";
  display: inline-block;
  font-family: var(--font-family);
  font-size: 0.846rem; /* was 11px — scales with laptop html size */
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.02em;
  color: inherit;
  transform: translateY(-1px);
}

/* Em-box sits low — shift the glyph up to the name centerline. */
.stats-panel--flat .stat-chart__lens-close-mark {
  display: inline-block;
  font: 400 18px/1 system-ui, sans-serif;
  transform: translateY(-2px);
}

/* Overlay on the label row while zoomed — out of flow so the chart doesn't jump. */
.stats-panel--flat .stat-group:has(.stat-body__chart[data-scrub-window="1"]) .stat-chart__lens-close {
  display: inline-flex;
}

/* Rubber-band while edge auto-scrolling: pointer → lens edge. */
.stat-chart__edge-link {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: visible;
  pointer-events: none;
  z-index: 4500;
}

.stat-chart__edge-link-line {
  stroke: var(--chart-band-stroke-focus, #3b82f6);
  stroke-width: 1.25;
  stroke-linecap: round;
  fill: none;
  opacity: 0.85;
}

.stat-chart__edge-link-rate {
  fill: var(--chart-band-stroke-focus, #3b82f6);
  stroke: var(--chart-band-stroke-focus, #3b82f6);
  stroke-width: 1.5;
  fill-opacity: 0.18;
  pointer-events: none;
}

.stats-panel--flat .stat-group:not(.stat-group--focus) .stat-chart--scrub-window .stat-chart__plot::after {
  border-color: var(--chart-band-stroke);
}

/* Position rail: full cohort track + moving viewport thumb. */
.stats-panel--flat .stat-chart__window-rail {
  position: absolute;
  left: var(--plot-inset);
  right: var(--plot-inset);
  bottom: calc(var(--plot-inset, 8px) - 1px);
  height: 6px;
  z-index: 5;
  pointer-events: none;
  visibility: hidden;
  opacity: 1;
  transform: translateY(2px);
  transition: transform 180ms ease;
  cursor: grab;
}

.stats-panel--flat .stat-chart--scrub-window .stat-chart__window-rail {
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
  height: 6px;
  overflow: visible;
  /* Sit in the shared bottom inset (same plot height as overview). */
  bottom: calc((var(--plot-inset-bottom, var(--plot-inset, 8px)) - 6px) / 2);
  left: var(--plot-inset-x, var(--plot-inset));
  right: var(--plot-inset-x, var(--plot-inset));
  transition:
    transform var(--scrub-lens-fade-ms, 220ms) ease,
    opacity var(--scrub-lens-fade-ms, 220ms) ease;
}

.stats-panel--flat .stat-chart--scrub-window .stat-chart__window-rail-track {
  top: 1px;
  bottom: 1px;
  height: auto;
  background: var(--chart-rail-track);
}

.stats-panel--flat .stat-chart--scrub-window .stat-chart__window-rail-thumb {
  top: 1px;
  bottom: 1px;
  height: auto;
  background: #2f5f8a;
  border-radius: 1px;
  transition:
    top 120ms ease,
    bottom 120ms ease,
    background 120ms ease;
}

/* Enlarge when hovering/dragging the thumb, or when dragging the chart itself. */
.stats-panel--flat .stat-chart--scrub-window .stat-chart__window-rail-thumb:hover,
.stats-panel--flat
  .stat-body__chart[data-scrub-rail-dragging="1"]
  .stat-chart--scrub-window
  .stat-chart__window-rail-thumb,
.stats-panel--flat
  .stat-body__chart[data-scrub-dragging="1"]
  .stat-chart--scrub-window
  .stat-chart__window-rail-thumb {
  top: 0;
  bottom: 0;
}

/* Idle rail on focused charts — hidden; scrollbar only while zoomed/scrubbing. */
.stats-panel--flat .stat-chart--scrub-rail-ready .stat-chart__window-rail,
.stats-panel--flat .stat-group--focus .stat-chart--scrub-rail-ready .stat-chart__window-rail {
  visibility: hidden;
  pointer-events: none;
  opacity: 0;
}

.stats-panel--flat .stat-chart__window-rail-track {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 3px;
  height: 2px;
  border-radius: 1px;
  background: var(--chart-rail-track);
  opacity: 1;
  pointer-events: none;
}

.stats-panel--flat .stat-group--focus .stat-chart__window-rail-track {
  background: var(--chart-rail-track);
}

.stats-panel--flat .stat-chart__window-rail-thumb {
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: calc(var(--window-start-t, 0) * 100%);
  width: max(8px, calc(var(--window-span-t, 0.2) * 100%));
  border-radius: 1px;
  background: var(--chart-rail-thumb);
  opacity: 1;
  pointer-events: auto;
  cursor: grab;
}

.stats-panel--flat .stat-group--focus .stat-chart__window-rail-thumb {
  background: var(--chart-rail-thumb-focus);
}

.stats-panel--flat .stat-chart__window-rail-thumb:hover {
  background: var(--chart-rail-thumb-hover);
}

.stats-panel--flat .stat-group--focus .stat-chart__window-rail-thumb:hover,
.stats-panel--flat .stat-body__chart--scrub-grabbing .stat-chart__window-rail-thumb {
  background: var(--chart-rail-thumb-focus-hover);
}

.stats-panel--flat .stat-chart--scrub-window .stat-chart__window-rail-thumb:hover,
.stats-panel--flat
  .stat-group--focus
  .stat-chart--scrub-window
  .stat-chart__window-rail-thumb:hover,
.stats-panel--flat
  .stat-body__chart--scrub-grabbing
  .stat-chart--scrub-window
  .stat-chart__window-rail-thumb {
  background: #1e4060;
}

.stats-panel--flat .stat-body__chart--scrub-grabbing .stat-chart__window-rail,
.stats-panel--flat .stat-body__chart--scrub-grabbing .stat-chart__window-rail-thumb {
  cursor: grabbing;
}

/* Selected-player rail triangle — hidden for now. */
.stats-panel--flat .stat-chart__window-rail-selected,
.stats-panel--flat .stat-group--focus .stat-chart__window-rail-selected,
.stats-panel--flat .stat-chart__window-rail-selected--in-view,
.stats-panel--flat .stat-chart__window-rail-selected:not(.stat-chart__window-rail-selected--in-view),
.stats-panel--flat .stat-chart--scrub-window .stat-chart__window-rail-selected {
  display: none !important;
}

/*
 * Lens-edge seek carets: which way to pan to reach the selected player
 * when that player sits outside the current window.
 */
.stats-panel--flat .stat-chart--scrub-window[data-selection-seek="start"] .stat-chart__plot::before,
.stats-panel--flat .stat-chart--scrub-window[data-selection-seek="end"] .stat-chart__plot::before {
  content: "";
  position: absolute;
  top: 50%;
  width: 0;
  height: 0;
  z-index: 5;
  pointer-events: none;
  transform: translateY(-50%);
}

.stats-panel--flat .stat-chart--scrub-window[data-selection-seek="start"] .stat-chart__plot::before {
  left: calc(var(--window-band-left, 0px) - 10px);
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-right: 8px solid var(--chart-band-stroke-focus, #3b82f6);
}

.stats-panel--flat .stat-chart--scrub-window[data-selection-seek="end"] .stat-chart__plot::before {
  left: calc(var(--window-band-left, 0px) + var(--window-band-width, 16px) + 2px);
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-left: 8px solid var(--chart-band-stroke-focus, #3b82f6);
}

.stats-panel--flat .stat-chart__bars {
  /* Gap is 0 — JS absolute-positions bars on the device pixel grid. */
  gap: 0;
  justify-content: flex-start;
  /* Keep auto so selected/hover bars can stack above the level band. */
  z-index: auto;
}

.stats-panel--flat .stat-chart--scrub-window .stat-chart__bars--lens {
  z-index: 2;
}

.stats-panel--flat .stat-chart--scrub-window .stat-chart__bars--lens .stat-chart__bar--selected {
  z-index: 5;
}

/* Non-selected lens bars share one solid colour; only the needle is distinct. */
.stats-panel--flat .stat-group--focus .stat-chart--scrub-window .stat-chart__bars--lens
  .stat-chart__bar--at-or-above:not(.stat-chart__bar--selected) {
  background: var(--chart-bar-at-or-above);
}

.stats-panel--flat .stat-group--focus .stat-chart--scrub-window .stat-chart__bars--lens
  .stat-chart__bar--below:not(.stat-chart__bar--selected) {
  background: var(--chart-bar-below);
}

.stats-panel--flat .stat-chart__bar {
  position: relative;
  z-index: 2;
  background: var(--chart-bar);
  opacity: 1;
  flex: 0 0 auto;
  width: 5px;
  min-width: 5px;
  max-width: 5px;
  box-shadow: none;
  outline: none;
}

/* Solo chart: one bar gets a wider presence. Under-capacity multi-bar
   cohorts keep the fixed 5px pitch above (empty plot on the right). */
.stats-panel--flat .stat-chart__bar--solo {
  flex: 0 0 40%;
  width: auto;
  min-width: 0;
  max-width: 8rem;
}

/* Under-capacity cohorts stretch to fill while retaining the normal 1px gap. */
.stats-panel--flat .stat-chart__bars--fill {
  gap: 1px;
}

.stats-panel--flat .stat-chart__bars--fill .stat-chart__bar {
  flex: 1 1 0;
  width: auto;
  min-width: 1px;
  max-width: none;
}

/* Fill cohorts: selected needle keeps equal flex width — only color changes.
   The fixed 5px needle below would otherwise shrink one bar and redistribute
   the strip (reads as a changing bar count when comparing small cohorts). */
.stats-panel--flat .stat-chart__bars--fill .stat-chart__bar--selected {
  flex: 1 1 0;
  width: auto;
  min-width: 1px;
  max-width: none;
}

/* Ambient charts: uniform solid grey; selected needle carries the cut. */
.stats-panel--flat .stat-group:not(.stat-group--focus)
  .stat-chart__bar--at-or-above:not(.stat-chart__bar--selected) {
  background: var(--chart-bar);
}

.stats-panel--flat .stat-group:not(.stat-group--focus)
  .stat-chart__bar--below:not(.stat-chart__bar--selected) {
  background: var(--chart-bar-below-ambient);
}

/* Focused overview: uniform solid blue; selected needle carries the cut. */
.stats-panel--flat .stat-group--focus
  .stat-chart__bar--at-or-above:not(.stat-chart__bar--selected) {
  background: var(--chart-bar-at-or-above);
}

.stats-panel--flat .stat-group--focus
  .stat-chart__bar--below:not(.stat-chart__bar--selected) {
  background: var(--chart-bar-below);
}

.stats-panel--flat .stat-chart:has(.stat-chart__bar--selected) .stat-chart__bar:not(.stat-chart__bar--selected) {
  opacity: 1;
}

/* Ambient charts: black needle for the selected player. */
.stats-panel--flat .stat-chart__bar--selected {
  flex: 0 0 5px;
  width: 5px;
  min-width: 5px;
  max-width: 5px;
  background: #000;
  opacity: 1;
  z-index: 3;
  mix-blend-mode: normal;
}

/* Solo bars keep their stretched sizing even when selected — the fixed
   5px needle width above only applies to packed (fixed-pitch) charts. */
.stats-panel--flat .stat-chart__bar--solo.stat-chart__bar--selected {
  flex: 0 0 40%;
  width: auto;
  min-width: 0;
  max-width: 8rem;
}

/* Focused chart: solid black needle — stronger than muted compare colors. */
.stats-panel--flat .stat-group--focus .stat-chart__bar--selected {
  background: #000;
  z-index: 3;
}

/* Residual single-bar --hover (dig-deeper paths that still stamp it). */
.stats-panel--flat .stat-group:not(.stat-group--focus)
  .stat-chart__bar--hover:not(.stat-chart__bar--selected) {
  background: var(--chart-bar-hover-ambient);
  filter: none;
  opacity: 1;
  z-index: 3;
}

.stats-panel--flat .stat-group--focus .stat-chart__bar--hover:not(.stat-chart__bar--selected) {
  background: var(--chart-bar-hover);
  filter: none;
  opacity: 1;
  z-index: 3;
}

/* Passive hover on the selected chart previews one bar without comparing.
   The tier-qualified selector matches the rank-tier rules' specificity so
   non-selected bars ghost too, not just the selected needle. */
@keyframes ghost-bar-grow {
  from {
    transform: scaleY(0);
  }
  to {
    transform: scaleY(1);
  }
}

.stats-panel--flat .stat-group--focus .stat-chart__bar--hover-ghost:not(.stat-chart__bar--selected),
.stats-panel--flat
  .stat-group--focus
  .stat-chart__bar--hover-ghost:is(.stat-chart__bar--at-or-above, .stat-chart__bar--below):not(
    .stat-chart__bar--selected
  ) {
  background: var(--chart-bar-hover-ghost-focus);
  filter: none;
  opacity: 1;
  z-index: 3;
  transform-origin: bottom center;
  animation: ghost-bar-grow 200ms ease-out both;
}

@media (prefers-reduced-motion: reduce) {
  .stats-panel--flat .stat-chart__bar--hover-ghost:not(.stat-chart__bar--selected) {
    animation: none;
  }
}

.stats-panel--flat .stat-group--focus .stat-chart--scrub-window .stat-chart__bars--lens
  .stat-chart__bar--hover:not(.stat-chart__bar--selected) {
  background: var(--chart-bar-hover);
}

/* Compare hover: ghost outside the selected↔peer band. In-band bars are the
   delta fill (blue on focus, ambient grey elsewhere). Peer also gets a small
   unfilled circle under the outer end of the range. Selected stays black. */
.stats-panel--flat .stat-group:not(.stat-group--focus) .stat-chart--comparing {
  --compare-delta: var(--chart-bar);
}

.stats-panel--flat .stat-group--focus .stat-chart--comparing {
  --compare-delta: var(--chart-bar-at-or-above);
}

/* Comparison bands follow the hovered player's direction from the selection. */
.stats-panel--flat .stat-chart--comparing.stat-chart--compare-higher {
  --compare-delta: var(--chart-compare-higher);
}

.stats-panel--flat .stat-chart--comparing.stat-chart--compare-lower {
  --compare-delta: var(--chart-compare-lower);
}

.stats-panel--flat
  .stat-group:not(.stat-group--focus)
  .stat-chart--comparing.stat-chart--compare-higher {
  --compare-delta: var(--chart-compare-higher-ambient);
}

.stats-panel--flat
  .stat-group:not(.stat-group--focus)
  .stat-chart--comparing.stat-chart--compare-lower {
  --compare-delta: var(--chart-compare-lower-ambient);
}

.stats-panel--flat .stat-group:not(.stat-group--focus)
  .stat-chart--comparing
  .stat-chart__bar:not(.stat-chart__bar--selected):not(.stat-chart__bar--compare-span):not(
    .stat-chart__bar--compare-peer
  ) {
  background: var(--chart-bar-ghost);
  filter: none;
}

.stats-panel--flat .stat-group--focus
  .stat-chart--comparing
  .stat-chart__bar:not(.stat-chart__bar--selected):not(.stat-chart__bar--compare-span):not(
    .stat-chart__bar--compare-peer
  ),
.stats-panel--flat .stat-group--focus
  .stat-chart--comparing
  .stat-chart__bar--at-or-above:not(.stat-chart__bar--selected):not(
    .stat-chart__bar--compare-span
  ):not(.stat-chart__bar--compare-peer),
.stats-panel--flat .stat-group--focus
  .stat-chart--comparing
  .stat-chart__bar--below:not(.stat-chart__bar--selected):not(
    .stat-chart__bar--compare-span
  ):not(.stat-chart__bar--compare-peer) {
  background: var(--chart-bar-ghost-focus);
  filter: none;
}

/* Delta band: solid fill between selected and hovered (incl. peer bar). */
.stats-panel--flat .stat-group:not(.stat-group--focus)
  .stat-chart--comparing
  :is(.stat-chart__bar--compare-span, .stat-chart__bar--compare-peer):not(
    .stat-chart__bar--selected
  ) {
  background: var(--compare-delta);
  filter: none;
}

.stats-panel--flat .stat-group--focus
  .stat-chart--comparing
  :is(
    .stat-chart__bar--compare-span,
    .stat-chart__bar--compare-peer,
    .stat-chart__bar--at-or-above.stat-chart__bar--compare-span,
    .stat-chart__bar--below.stat-chart__bar--compare-span,
    .stat-chart__bar--at-or-above.stat-chart__bar--compare-peer,
    .stat-chart__bar--below.stat-chart__bar--compare-peer
  ):not(.stat-chart__bar--selected) {
  background: var(--compare-delta);
  filter: none;
}

/* Ambient range jumps reveal newly covered bars from the selected needle out.
   The focused chart remains immediate; total stagger is capped in JS. */
@keyframes compare-bar-enter {
  from {
    background-color: var(--chart-bar-ghost);
  }
  to {
    background-color: var(--compare-delta);
  }
}

.stats-panel--flat
  .stat-group:not(.stat-group--focus)
  .stat-chart--comparing
  .stat-chart__bar--compare-enter:not(.stat-chart__bar--selected) {
  animation: compare-bar-enter 36ms ease-out var(--compare-enter-delay, 0ms) both;
}

/* Peer endpoint: color-coded triangle on the same baseline as the selection triangle. */
@keyframes compare-end-in {
  from {
    opacity: 0;
    transform: translateX(-50%) scale(1.5);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) scale(1);
  }
}

.stats-panel--flat .stat-chart__compare-end {
  position: absolute;
  bottom: calc(100% + 1px);
  width: 0;
  height: 0;
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 10;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 7px solid var(--compare-delta);
  animation: none;
}

.stats-panel--flat .stat-chart__compare-end-value {
  --thumb-label-nudge: 0px;
  position: absolute;
  left: 0;
  /* Match .stat-chart__extremes: 8px above the frame. Parent sits 1px above it. */
  bottom: calc(var(--chart-extremes-to-frame, 8px) - 1px);
  transform: translateX(calc(-50% + var(--thumb-label-nudge)));
  color: var(--compare-delta);
  font-size: var(--chart-extremes-size, var(--player-list-name-last-size));
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1;
  white-space: nowrap;
}

.stats-panel--flat .stat-group:not(.stat-group--focus) .stat-chart__compare-end {
  display: none;
}

.stats-panel--flat .stat-group--focus .stat-chart__compare-end {
  transition: none;
}

.stats-panel--flat .stat-chart__compare-end--animate {
  opacity: 1;
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .stats-panel--flat
    .stat-chart--comparing
    .stat-chart__bar--compare-enter:not(.stat-chart__bar--selected) {
    animation: none;
  }

  .stats-panel--flat .stat-chart__compare-end {
    transition: none;
  }

  .stats-panel--flat .stat-chart__compare-end--animate {
    animation: none;
  }
}

/* Selected needle wins — paint immediately on selection. */
.stats-panel--flat .stat-chart--comparing .stat-chart__bar--selected,
.stats-panel--flat .stat-group--focus .stat-chart--comparing .stat-chart__bar--selected {
  background: #000;
  filter: none;
  z-index: 5;
}

.stats-panel__catalog,
.stats-panel__list {
  display: flex;
  flex-direction: column;
  gap: var(--stats-panel-row-gap);
  flex: 1;
  min-height: 0;
  width: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  user-select: none;
  -webkit-user-select: none;
  padding: var(--stats-panel-pad-top) var(--stats-panel-pad-x) var(--stats-panel-pad-bottom);
  background: var(--stats-bg);
}

.stat-group--compare .stat-head__icon {
  display: none;
}

.stat-group--compare .stat-head {
  cursor: default;
}

.stat-group--compare .stat-body {
  display: block;
  max-height: none;
  overflow: visible;
}

.stat-group--pinned {
  position: sticky;
  /* top must stay 0 — a non-zero sticky top shifts Overall down and eats the row gap. */
  top: 0;
  z-index: 2;
  /* Opaque so catalog rows cannot show through while scrolling under an open Overall. */
  background: var(--stats-surface);
  border-bottom: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
  padding-bottom: 0;
  overflow: visible;
}

.stat-group--pinned::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: var(--stats-panel-row-gap);
  background: var(--stats-bg);
  pointer-events: none;
  z-index: 1;
}

.stat-group:not(.stat-group--pinned) {
  scroll-margin-top: calc(
    var(--stats-panel-pinned-height, 0px) + var(--stats-panel-row-gap)
  );
}

.stat-group {
  display: block;
  flex: 0 0 auto;
  width: 100%;
  margin: 0;
  border: 1px solid var(--stats-separator);
  border-radius: var(--radius-panel);
  background: var(--stats-surface);
  overflow: hidden;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  transition:
    background-color 0.12s ease,
    border-color 0.12s ease,
    box-shadow 0.12s ease;
}

/* Author `display: block` above beats the UA [hidden] rule — keep compare
   masking able to drop non-shared stats from the catalog. */
.stat-group[hidden] {
  display: none !important;
}

.stat-group:not(.stat-group--open):not(.stat-group--focus) {
  border-color: rgba(255, 255, 255, 0.06);
}

.stat-group:last-child {
  border-bottom: 1px solid var(--stats-separator);
}

.stats-panel__catalog .stat-group:first-child,
.stats-panel__list .stat-group:first-child {
  border-top: 1px solid var(--stats-separator);
}

.stats-panel__catalog .stat-group:nth-child(2),
.stats-panel__list .stat-group:nth-child(2) {
  border-top: 1px solid var(--stats-separator);
}

.stats-panel--flat .stats-panel__catalog .stat-group:first-child,
.stats-panel--flat .stats-panel__list .stat-group:first-child,
.stats-panel--flat .stats-panel__catalog .stat-group:nth-child(2),
.stats-panel--flat .stats-panel__list .stat-group:nth-child(2),
.stats-panel--flat .stat-group:last-child {
  border: none;
}

/* Selected stat: no grey row wash — index badge + heavy name + plot chrome. */
.stat-group--focus {
  border-color: var(--color-border-strong);
  background: transparent;
  box-shadow: none;
}

.stat-group--focus .stat-head__name {
  color: var(--flat-title-color, var(--color-text));
  /* Keep weight stable so the label doesn't reflow/shift on select. */
  font-weight: var(--flat-title-weight, 400);
}

.stats-panel--flat .stat-group--focus .stat-head__name,
.stats-panel--flat .stat-group--browse .stat-head__name,
.stats-panel__ranked-by-stat {
  /* Shared selected all-caps weight (chart names, cluster type, help tabs). */
  font-weight: var(--hero-chrome-caps-weight-selected);
  color: var(--color-text);
}

.stat-group--focus .stat-chart__plot {
  background: transparent;
}

.stat-group--focus .stat-foot {
  color: #c5cdd8;
}

.stat-group--focus .stat-body__chart {
  border-color: transparent;
}

.stat-group--open {
  overflow: visible;
}

.stat-head {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  background: transparent;
  border: none;
  padding: 12px 14px 13px;
  margin: 0;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  -webkit-tap-highlight-color: transparent;
}

@media (hover: hover) and (pointer: fine) {
  .stat-group:hover {
    background: var(--color-hover-fill);
    border-color: transparent;
    box-shadow: none;
  }

  .stat-group--focus:hover {
    background: transparent;
    border-color: var(--color-border-strong);
    box-shadow: none;
  }

  .stats-panel--flat .stat-group:hover,
  .stats-panel--flat .stat-group--focus:hover {
    background: transparent;
    border: none;
    box-shadow: none;
  }

  /* Selected + hover after commit settle: light row wash. */
  .stats-panel--flat:not(.stats-panel--suppress-selected-wash)
    .stat-group--focus:hover:has(.stat-body__chart:hover),
  .stats-panel--flat:not(.stats-panel--suppress-selected-wash)
    .stat-group--focus.stat-group--browse:hover {
    background: var(--color-chart-focus-browse-fill);
  }
}

.stat-head__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 22px;
}

.stat-head__name {
  margin: 0;
  font-size: var(--flat-title-size, var(--accordion-title-font-size));
  font-weight: var(--flat-title-weight, 400);
  line-height: var(--flat-title-line, 1.2);
  letter-spacing: var(--flat-title-tracking, -0.02em);
  color: var(--flat-title-color, var(--color-text));
  transition: none;
}

.stat-head__icon {
  display: block;
  width: 12px;
  height: 20px;
  position: relative;
  flex-shrink: 0;
}

.stat-head__icon::before,
.stat-head__icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: none;
}

.stat-head__icon::before {
  width: 7px;
  height: 7px;
  border-right: 2px solid var(--stats-label-tertiary);
  border-bottom: 2px solid var(--stats-label-tertiary);
  transform: translate(-70%, -55%) rotate(-45deg);
  transition: none;
}

.stat-head__icon::after {
  display: none;
}

.stat-group--open .stat-head__icon::before {
  transform: translate(-50%, -70%) rotate(45deg);
  border-right-color: var(--stats-label-secondary);
  border-bottom-color: var(--stats-label-secondary);
}

.stat-sparkline {
  display: block;
  position: relative;
  height: 20px;
  margin-right: 4px;
  overflow: visible;
}

.stat-group--open .stat-sparkline {
  display: none;
}

.stat-sparkline .stat-chart {
  height: 100%;
  overflow: visible;
}

.stats-panel--settling .stat-body {
  max-height: 0 !important;
  transition: none;
}

.stats-panel--settling .stat-group--open .stat-body {
  max-height: 220px !important;
  transition: none;
}

.stats-panel--settling .stat-head__icon::before {
  transition: none;
}

.stats-panel--settling .stat-group--open .stat-sparkline {
  display: none;
}

.stat-sparkline__bar {
  flex: 1;
  min-width: 1px;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 0.5px 0.5px 0 0;
}

.stat-sparkline__bar--solo {
  flex: 0 0 6px;
  width: 6px;
  margin-left: auto;
  margin-right: auto;
}

.stat-sparkline:has(.stat-sparkline__bar--solo) {
  justify-content: center;
}

.stat-sparkline__bar--selected {
  min-width: 2px;
  background: var(--stats-accent);
}

.stat-body {
  max-height: 0;
  overflow: hidden;
  background: transparent;
  transition: none;
}

.stat-group--open .stat-body {
  max-height: 220px;
  overflow: visible;
}

.stat-body__foot {
  display: block;
  padding: 0 14px 12px;
}

.stat-body__chart {
  flex: 1;
  min-width: 0;
  height: clamp(78px, var(--chart-height), 120px);
  margin: 0 14px 8px;
  border: none;
  border-radius: 0;
  overflow: visible;
  background: transparent;
  transition: background-color 0.18s ease;
  cursor: pointer;
}

.stats-panel--flat .stat-head__player {
  margin-left: 0;
  margin-right: auto;
  line-height: var(--flat-title-line);
}

.stat-head__player {
  /* Text-level box so baseline matches .stat-head__name.
     overflow:hidden on a flex item uses a synthetic bottom baseline and lifts the name. */
  display: block;
  margin-left: 0;
  margin-right: auto;
  min-width: 0;
  font-size: var(--player-list-name-size);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--color-text);
  white-space: nowrap;
  overflow: visible;
}

.stat-head__player[hidden] {
  display: none !important;
}

.stat-head__player .player-card__name-first,
.stat-head__player .player-card__name-last {
  display: inline;
  max-width: none;
  overflow: visible;
  text-overflow: clip;
  white-space: nowrap;
}

.stat-head__player .player-card__name-first {
  font-size: inherit;
  font-weight: 400;
}

.stat-head__player .player-card__name-last {
  font-size: inherit;
  font-weight: 800;
}

.stat-head__player .player-card__name-first + .player-card__name-last::before {
  content: "\00a0";
}

.stat-head__player--hover {
  color: var(--color-text);
}

.stat-chart__tooltip {
  position: fixed;
  z-index: 4000;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.55em;
  padding: 8px 12px;
  border-radius: 6px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: 0;
  pointer-events: none;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12), 0 1px 3px rgba(0, 0, 0, 0.06);
  white-space: nowrap;
}

.stat-chart__tooltip--affordance {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35em;
  font-size: var(--hero-chrome-caps-size);
  font-weight: 600;
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
  white-space: nowrap;
  line-height: 1.2;
}

.stat-chart__tooltip-row {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  min-width: 0;
}

.stat-chart__tooltip-icon {
  flex: 0 0 auto;
  width: 2em;
  height: 2em;
  color: var(--color-text-muted);
}

.stat-chart__tooltip-row-label {
  min-width: 0;
  color: var(--color-text-muted);
  font-weight: 600;
}

.stat-chart__tooltip-verb {
  color: var(--color-text);
  font-weight: 700;
}

.stat-chart__tooltip--identity {
  flex-direction: column;
  align-items: stretch;
  gap: 0.35em;
}

/* Chart tip as roster list item — card carries identity; chrome wraps affordances. */
.stat-chart__tooltip--card {
  gap: 0.45em;
  padding: 0;
  border: none;
  background: transparent;
  box-shadow: none;
  white-space: normal;
  --chart-compare-higher: #007a58;
  --chart-compare-lower: #d55e00;
}

.stat-chart__tooltip--card .player-card--tooltip {
  position: relative;
  flex: 0 0 auto;
  pointer-events: none;
  cursor: default;
  /* Soft float so the card reads above the chart surface. */
  filter: drop-shadow(0 4px 14px rgba(0, 0, 0, 0.14))
    drop-shadow(0 1px 3px rgba(0, 0, 0, 0.06));
}

.stat-chart__tooltip--card .stat-chart__tooltip-rule,
.stat-chart__tooltip--card .stat-chart__tooltip-hint {
  align-self: stretch;
  margin-inline: 0.35rem;
}

.stat-chart__tooltip--card .stat-chart__tooltip-hint {
  padding: 0.45em 0.65em 0.55em;
  border-radius: 6px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12), 0 1px 3px rgba(0, 0, 0, 0.06);
}

.stat-chart__tooltip--card .stat-chart__tooltip-rule {
  display: none;
}

.stat-chart__tooltip-rule {
  align-self: center;
  width: 42%;
  height: 1px;
  margin-block: 0.05em;
  background: var(--color-border);
}

.stat-chart__tooltip-team {
  flex: 0 0 auto;
  height: 2em;
  width: auto;
  margin-inline-end: 0.4em;
  object-fit: contain;
  object-position: center;
}

.stat-chart__tooltip-identity {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  align-self: flex-start;
  min-width: 0;
}

.stat-chart__tooltip-name {
  white-space: nowrap;
  color: var(--color-text);
  font-weight: 400;
}

.stat-chart__tooltip-name-first {
  font-weight: 400;
}

.stat-chart__tooltip-name-last {
  font-weight: 800;
}

.stat-chart__tooltip-pos {
  flex-shrink: 0;
  margin-inline-start: 0.4em;
}

.stat-chart__tooltip-hint {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35em;
  flex-shrink: 0;
  margin: 0;
  padding: 0;
  border: 0;
  font-size: var(--hero-chrome-caps-size);
  font-weight: 600;
  letter-spacing: var(--hero-chrome-caps-tracking);
  text-transform: uppercase;
  color: var(--color-text-muted);
  white-space: nowrap;
  line-height: 1.2;
}

.stat-chart__tooltip-hint .stat-chart__tooltip-icon {
  width: 2em;
  height: 2em;
}

.stat-chart__tooltip-hint .stat-chart__tooltip-verb {
  font-weight: 700;
  color: var(--color-text);
}

/* List / pointer-following tips — prefer above+right of the cursor. */
.stat-chart__tooltip--cursor {
  transform: translate(40px, 14px);
}

.stat-chart__tooltip--cursor-start {
  transform: translate(calc(-100% - 40px), 14px);
}

.stat-chart__tooltip--cursor.stat-chart__tooltip--cursor-above {
  transform: translate(40px, calc(-100% - 14px));
}

.stat-chart__tooltip--cursor-start.stat-chart__tooltip--cursor-above {
  transform: translate(calc(-100% - 40px), calc(-100% - 14px));
}

/* Chart tips: fixed X outside the plot, Y tracks the mouse (top-aligned). */
.stat-chart__tooltip--docked {
  transform: none;
}

.stat-chart__tooltip[hidden] {
  display: none !important;
}

.stat-chart {
  position: relative;
  width: 100%;
  height: 100%;
  --level-pct: 0%;
  overflow: visible;
}

/* Clipped plot frame: line + level stay inside; markers paint above and can overhang. */
.stat-chart__plot {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: transparent;
  pointer-events: none;
  z-index: 0;
}

/* Player value band — soft fill up to selected height */
.stat-chart__level {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--level-pct);
  background: var(--chart-level);
  box-shadow: none;
  pointer-events: none;
  z-index: 0;
}

.stat-chart__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  overflow: visible;
}

.stat-chart__line {
  fill: none;
  stroke: #b5bdc8;
  stroke-width: 1.3;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  opacity: 0.92;
}

.stat-chart--spark .stat-chart__line {
  stroke: #b5bdc8;
  stroke-width: 0.7;
  opacity: 0.42;
}

.stat-chart__line-focus {
  stroke: #cbd3dc;
  stroke-width: 1;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  opacity: 1;
}

.stat-chart--spark .stat-chart__plot {
  background: transparent;
}

/* Shared marker positioning, with compact and detail visual variants. */
.stat-player-marker {
  --marker-size: 9px;
  --marker-ring: 2px;
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}

.stat-player-marker__guide {
  position: absolute;
  left: var(--marker-left);
  top: 0;
  bottom: 0;
  width: 1px;
  height: auto;
  transform: translateX(-50%);
  background: rgba(255, 255, 255, 0.28);
  pointer-events: none;
}

.stat-player-marker__dot {
  position: absolute;
  left: var(--marker-left);
  bottom: var(--marker-bottom);
  width: var(--marker-size);
  height: var(--marker-size);
  transform: translate(-50%, 50%);
  border-radius: 50%;
  background: var(--stats-label);
  box-shadow: 0 0 0 var(--marker-ring) var(--stats-surface);
  pointer-events: none;
}

.stat-player-marker__dot--interactive {
  pointer-events: auto;
  cursor: pointer;
}

.stat-player-marker--hover {
  --marker-size: 6px;
  --marker-ring: 1.5px;
  z-index: 4;
}

.stat-player-marker--hover .stat-player-marker__guide {
  background: rgba(255, 255, 255, 0.2);
}

.stat-player-marker--hover .stat-player-marker__dot {
  background: rgba(255, 255, 255, 0.55);
  box-shadow: 0 0 0 var(--marker-ring) var(--stats-surface);
}

.stat-chart--spark .stat-chart__level {
  display: none;
}

.stat-chart--bars {
  overflow: hidden;
  background: transparent;
  border: none;
  box-shadow: none;
}

.stat-chart--bars .stat-chart__bars {
  z-index: auto;
}

.stat-chart--bars .stat-chart__level {
  display: none;
}

.stat-chart__bars {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-end;
  gap: 1px;
  width: 100%;
  height: 100%;
  padding: 0;
  box-sizing: border-box;
}

.stat-chart__bars--solo {
  justify-content: center;
}

.stat-chart__bar {
  flex: 1 1 0;
  min-width: 1px;
  background: #bdbec4;
  opacity: 1;
  border-radius: 0;
  box-shadow: none;
  outline: none;
}

.stat-chart:has(.stat-chart__bar--selected) .stat-chart__bar:not(.stat-chart__bar--selected) {
  opacity: 1;
}

.stat-chart__bar--solo {
  flex: 0 0 40%;
  max-width: 8rem;
  opacity: 1;
}

.stat-chart__bar--selected {
  background: #000;
  opacity: 1;
  position: relative;
  z-index: 2;
}

.stat-foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  font-size: var(--supporting-data-font-size);
  line-height: 1.25;
  color: var(--secondary-readable-color);
  padding-bottom: 0;
}

.stat-foot__marker {
  font-weight: 400;
  color: var(--stats-label);
}

/* Mid desktop: tighter cluster only — hero size stays on the root vw curve. */
@media (max-width: 1200px) and (min-width: 721px) {
  .cluster-bar--open {
    width: min(42rem, 72vw);
    min-width: 26rem;
    height: min(38rem, 64vh);
    min-height: 28rem;
  }
}

/*
 * Laptop / MacBook: ~85% browser-zoom density at 100% zoom.
 * Scale rem chrome (html font-size) + portrait px slots — not transform/zoom —
 * so histogram bars keep whole CSS-pixel pitch and stay sharp.
 * List + Similar/Different share --portrait-inner / --portrait-slot.
 */
@media (max-height: 1100px) {
  html {
    /* ~81% of 13px — rem type tokens track this; chart bar px pitch does not. */
    font-size: 10.5px;
  }

  :root {
    --portrait-inner: 107px;
    --portrait-pad: 2px;
    --portrait-slot: 117px;
    /* Hero size stays on the continuous :root dvh/vw curve (no snap). */
  }

  .app {
    --app-pad-top: 24px;
    --app-pad-bottom: 0;
    gap: calc(0.5rem + 24px);
  }

  .player-hero {
    --comparisons-bottom: calc(
      var(--selection-matte) + var(--selection-scale-overflow) + 0.85rem
    );
  }

  .player-hero__info {
    --cluster-row-gap: 0.7rem;
  }

  .cluster-bar--open {
    width: min(42rem, 78vw);
    height: min(34rem, 48vh);
    min-width: 24rem;
    min-height: 16rem;
  }

  .cluster-bar--hairstyle-anchor.cluster-bar--open {
    width: min(20rem, 28vw);
    height: min(24rem, 40vh);
    min-width: 14rem;
    min-height: 14rem;
  }
}

/* Closer to ~80% zoom density on shorter laptop viewports. */
@media (max-height: 900px) {
  html {
    font-size: 10px;
  }

  :root {
    --portrait-inner: 101px;
    --portrait-slot: 110px;
  }

  .cluster-bar--open {
    height: min(30rem, 42vh);
    min-width: 22rem;
    min-height: 14rem;
  }

  .cluster-bar--hairstyle-anchor.cluster-bar--open {
    height: min(20rem, 36vh);
    min-height: 12rem;
  }
}

@media (max-width: 720px) {
  :root {
    --roster-card-gap: 4px;
  }

  body {
    overflow: hidden;
  }

  .app {
    height: 100dvh;
    min-height: 100dvh;
    overflow: hidden;
    padding: 0;
    gap: 0;
    border-left: none;
    display: flex;
    flex-direction: column;
  }

  .content {
    position: sticky;
    top: 0;
    z-index: 6;
    background: var(--color-bg);
    flex-shrink: 0;
  }

  .header {
    gap: 0;
  }

  .header__toolbar {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: 10px 16px;
    border-bottom: 1px solid var(--color-border);
    gap: 8px;
  }

  .header__leading,
  .filters,
  .filter {
    display: flex;
    grid-template-rows: none;
    grid-row: auto;
    grid-column: auto;
  }

  .header__leading {
    flex-direction: row;
    align-items: center;
    gap: 0.35rem;
  }

  .header__chrome-actions {
    grid-row: auto;
    align-self: auto;
  }

  .filters {
    flex-direction: row;
    flex-wrap: wrap;
    width: 100%;
    gap: 8px;
    justify-content: stretch;
    align-items: center;
  }

  .filter {
    position: relative;
    display: block;
  }

  .filter > :not(.filter__label) {
    width: 100%;
  }

  .filter--team,
  .filter--position,
  .filter--search {
    flex: 1 1 0;
    width: auto;
    min-width: 0;
    max-width: none;
  }

  .filter__label {
    font-size: var(--hero-chrome-caps-sm-size);
  }

  .filter-menu__trigger {
    min-width: 0;
    font-size: var(--filter-control-font-size);
    padding: calc(
        var(--filter-inline-label-top) + var(--hero-chrome-caps-sm-size) +
          var(--filter-inline-label-to-value)
      )
      2.15rem var(--filter-value-pad-bottom) var(--filter-control-pad-x);
  }

  .filter-menu__columns {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .filter-menu__column + .filter-menu__column {
    border-left: none;
    border-top: 1px solid var(--color-border);
    padding-left: 0;
    margin-top: 6px;
    padding-top: 6px;
  }

  .roster-strip {
    border-bottom: 1px solid var(--color-border);
    background: var(--color-bg);
    gap: 0;
  }

  .roster-strip .slot-group__strip {
    padding: 0 0 10px;
  }

  .roster-strip .slot-group__viewport {
    border: none;
    background: transparent;
    display: block;
  }

  .roster-strip .slot-group__scrubber {
    display: block;
    min-width: 0;
  }

  .roster-strip .slot-group__track--scroll {
    flex-direction: row;
    align-items: flex-start;
    overflow-x: hidden;
    overflow-y: hidden;
    gap: var(--roster-card-gap);
    padding: calc(var(--selection-matte) + var(--selection-scale-overflow))
      var(--selection-frame-overhang)
      calc(var(--selection-matte) + var(--selection-scale-overflow) + var(--player-card-footer-pad));
    flex: none;
    height: var(--roster-track-height);
    min-height: var(--roster-track-height);
    box-sizing: border-box;
  }

  .roster-strip .slot-group__track--scroll.scroll-pane {
    overflow-x: hidden;
    overflow-y: hidden;
    height: var(--roster-track-height);
    min-height: var(--roster-track-height);
    scrollbar-width: none;
  }

  .roster-strip .slot-group__track--scroll.scroll-pane::-webkit-scrollbar {
    display: none;
  }

  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card {
    flex: 0 0 auto;
    width: var(--portrait-slot);
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: var(--portrait-pad) var(--portrait-pad) var(--player-card-footer-pad);
  }

  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card__portrait,
  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card__avatar {
    width: var(--portrait-inner);
    height: var(--portrait-inner);
    border-radius: 10px;
  }

  /* Keep select/hover/scrub at base portrait size in this breakpoint too. */
  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--selected .player-card__avatar,
  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--chart-hover .player-card__avatar,
  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--scrub-linger .player-card__avatar,
  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card):not(:is(.roster-strip--keyboard-nav, .roster-strip--keyboard-chart-browse)) .player-card:hover:not(.player-card--selected) .player-card__avatar {
    border-radius: 6px;
  }

  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card__meta {
    text-align: center;
    align-items: center;
  }

  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card__name {
    font-size: var(--accordion-title-font-size);
    align-items: center;
    text-align: center;
    max-width: 100%;
  }

  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card__name-first,
  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card__name-last {
    max-width: 100%;
  }

  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card__rank {
    display: none;
  }

  .slot-group__strip {
    padding: 8px 0 10px;
  }

  .slot-group__viewport {
    border: none;
    background: transparent;
  }

  .slot-group__fade {
    display: none;
  }

  .roster-strip .slot-group__fade--left,
  .roster-strip .slot-group__fade--right {
    display: block;
  }

  .slot-group__scrubber {
    display: none;
  }

  .roster-strip .slot-group__scrubber {
    display: block;
  }

  .slot-group__track {
    gap: var(--roster-card-gap);
    padding: calc(var(--selection-matte) + var(--selection-scale-overflow))
      max(16px, var(--selection-frame-overhang))
      calc(var(--selection-matte) + var(--selection-scale-overflow) + var(--player-card-footer-pad));
  }

  .player-card {
    flex: 0 0 auto;
    width: var(--portrait-slot);
    gap: 4px;
  }

  .player-card__portrait,
  .player-card__avatar {
    width: var(--portrait-inner);
    height: var(--portrait-inner);
    border-radius: 10px;
  }

  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--selected .player-card__avatar,
  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--chart-hover .player-card__avatar,
  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card) .player-card--scrub-linger .player-card__avatar,
  :is(.roster-strip, .player-comparisons, .stat-chart__tooltip--card):not(:is(.roster-strip--keyboard-nav, .roster-strip--keyboard-chart-browse)) .player-card:hover:not(.player-card--selected) .player-card__avatar {
    border-radius: 6px;
  }

  .player-card__meta {
    text-align: center;
  }

  .player-card__name {
    font-size: var(--accordion-title-font-size);
    align-items: center;
    text-align: center;
    max-width: 100%;
    white-space: normal;
  }

  .player-card__name-first,
  .player-card__name-last {
    max-width: 100%;
  }

  .player-card__rank {
    display: none;
  }

  .main {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    gap: 0;
    padding-top: 0;
  }

  .detail-column {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
  }

  .stats-compare-overall,
  .stats-compare-focus {
    display: none;
  }

  .player-hero {
    display: grid;
    grid-template-columns: minmax(0, 42%) minmax(0, 1fr);
    align-items: stretch;
    gap: 0;
    height: auto;
    grid-column: auto;
    grid-row: auto;
    padding: 0;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-bg);
    flex-shrink: 0;
    overflow: hidden;
  }

  .player-hero__photo,
  .player-hero__peek-photo,
  .player-hero__team-logo {
    position: relative;
    inset: auto;
    top: auto;
    left: auto;
    right: auto;
    bottom: auto;
    transform: none;
    grid-column: 1;
    grid-row: 1;
    align-self: stretch;
    justify-self: stretch;
    width: 100%;
    height: 100%;
    min-height: 12.5rem;
    max-width: none;
    max-height: none;
    aspect-ratio: auto;
    margin: 0;
    border-radius: 0;
    object-fit: cover;
    object-position: top center;
    background: var(--portrait-bg);
    z-index: 0;
    pointer-events: none;
  }

  /* Side-by-side peek only works with the desktop cutout layout. */
  .player-hero__peek-photo,
  .player-hero--peek-left .player-hero__peek-photo,
  .player-hero--peek-right .player-hero__peek-photo,
  .player-hero__peek-standin,
  .player-hero--peek-left .player-hero__peek-standin,
  .player-hero--peek-right .player-hero__peek-standin {
    display: none !important;
  }

  .player-hero__team-logo {
    display: none;
  }

  .player-comparisons {
    position: relative;
    inset: auto;
    grid-column: 1 / -1;
    grid-row: 3;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
    padding: 0.7rem 0.9rem;
    border-top: 1px solid var(--color-border);
    background: var(--color-surface-raised);
  }

  .player-comparisons__side {
    position: relative;
    inset: auto;
    align-items: stretch;
    gap: 0.5rem;
    width: auto;
  }

  .player-comparisons__side--different {
    align-items: stretch;
    text-align: right;
  }

  .player-comparisons__cards {
    gap: 0.45rem;
  }

  .player-hero__info {
    grid-column: 2;
    grid-row: 1;
    position: relative;
    z-index: 1;
    flex: none;
    min-width: 0;
    height: auto;
    min-height: 0;
    align-self: stretch;
    padding: 12px 14px 12px 12px;
    display: flex;
    flex-direction: column;
    pointer-events: none;
  }

  .cluster-stack,
  .cluster-bar--hairstyle-anchor {
    display: none;
  }

  .player-hero__heading {
    align-items: center;
    gap: 0.4em;
    margin-bottom: 8px;
    font-size: 1.2rem;
    padding: 0;
  }

  .player-hero__name {
    margin: 0;
    padding-top: 0 !important;
    line-height: 1.1;
    font-weight: 700;
    letter-spacing: -0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-transform: none;
  }

  .player-hero__name-first {
    font-weight: 400;
  }

  .player-hero__name-last {
    font-weight: 800;
  }

  .player-hero__meta {
    --position-pill-font-size: 1.1rem;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 0;
    font-size: var(--hero-meta-data-size);
    font-weight: 800;
    letter-spacing: -0.02em;
    color: #000;
  }

  .player-hero__meta-row:not(:last-child),
  .player-hero__filter-pills {
    --hero-meta-rule-gap: 0.55em;
  }

  .player-hero__meta b {
    font-size: var(--hero-chrome-caps-size);
    font-weight: 600;
    letter-spacing: var(--hero-chrome-caps-tracking);
    text-transform: uppercase;
    color: var(--hero-chrome-caps-color);
  }

  .position-pill {
    font-size: var(--position-pill-font-size);
  }

  .stats-sidebar {
    grid-column: auto;
    grid-row: auto;
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    height: auto;
    overflow: hidden;
    width: 100%;
    margin-bottom: 0;
  }

  .chart-panel {
    height: auto;
    overflow: hidden;
    width: 100%;
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }

  .stats-panel {
    height: auto;
    overflow: hidden;
    padding: 0;
    flex: 1;
    min-height: 0;
  }

  .stats-panel__catalog,
  .stats-panel__list {
    -webkit-overflow-scrolling: touch;
  }

  .stat-head__name {
    font-size: var(--accordion-title-font-size);
  }

  .stats-panel--settling .stat-group--open .stat-body {
    max-height: 220px !important;
  }

  .stat-group--open .stat-body {
    max-height: 220px;
  }

  .stat-body__chart {
    height: 78px;
  }
}

@media (max-width: 480px) {
  :root {
    /* Trial: 150% of prior 72/80 — pair with desktop portrait trial above. */
    --portrait-inner: 108px;
    --portrait-slot: 120px;
    --portrait-label-size: 0.55rem;
  }
}

/* Long-press affordance: grows under the pointer, max size at compare engage. */
.hold-press-ring {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 5000;
  width: 0;
  height: 0;
  pointer-events: none;
  transform: translate(var(--hold-x, 0px), var(--hold-y, 0px));
}

.hold-press-ring[hidden] {
  display: none;
}

.hold-press-ring__circle {
  position: absolute;
  left: 0;
  top: 0;
  width: 24px;
  height: 24px;
  margin: -12px 0 0 -12px;
  border-radius: 50%;
  background: rgb(17 17 17 / 12%);
  box-shadow: inset 0 0 0 1.5px rgb(17 17 17 / 40%);
  transform: scale(0.12);
}

.hold-press-ring.is-growing .hold-press-ring__circle {
  animation: hold-press-grow var(--hold-ms, 300ms) linear forwards;
}

@keyframes hold-press-grow {
  from {
    transform: scale(0.12);
  }
  to {
    transform: scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hold-press-ring.is-growing .hold-press-ring__circle {
    animation: none;
    transform: scale(0.35);
  }
}
