/* Player Detail Page — C23 + polish bundle
   Uses tokens.css for all design tokens. Mobile-first, CSS Grid layout. */

:root {
  /* R2E-15: neutral until renderPlayer() reads the real school color and
     overwrites this via style.setProperty (player-detail.js). Was brand
     red, which painted a full-page accent flash on every open before the
     profile request resolved. */
  --school-primary: #6B6B6B;
  --pos-green: #3dba6e;
  --pos-red: #FF5050;
  --pos-flat: #888;
}

/* ── Reset ────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; background: var(--black-bg); color: var(--white-bright); font-family: var(--f-body); font-size: 16px; }
html { color-scheme: dark; }
body { min-height: 100vh; }
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
button { font-family: var(--f-body); }

/* ── Skip link ────────────────────────────────────────────────────────── */
.skip { position: absolute; top: -100px; left: 0; padding: 8px 16px; background: var(--red-primary); color: #fff; z-index: 100; }
.skip:focus { top: 0; }

/* ── Mobile nav ───────────────────────────────────────────────────────── */
.mob-nav-toggle { display: none; }
.mob-nav-burger { display: none; position: fixed; top: 14px; left: 14px; z-index: 200; background: var(--black-card); border: 1px solid var(--red-primary); border-radius: 8px; padding: 6px 8px; cursor: pointer; color: var(--white-bright); }
.mob-nav-scrim { display: none; }

/* ── Page grid ────────────────────────────────────────────────────────── */
.player-page {
  display: grid;
  grid-template-columns: var(--sidebar-w, 0px) minmax(0, 1fr);
  min-height: 100vh;
  max-width: 1440px;
  margin: 0 auto;
}
.player-content {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 0 12px 48px;
  min-width: 0;
}

/* ── Mobile chrome collapse (route-local mirror of the sitewide
   .app .sidebar mobile rule chrome.js injects at the same 880px
   breakpoint) — this page's wrapper is .player-page, not .app, so that
   sitewide rule never matches here and the sidebar column never
   collapsed. Bottom tab bar (injected sitewide, unscoped) already
   covers primary nav at this width, so taking the sidebar off-canvas
   here matches every other route. ─────────────────────────────────── */
@media (max-width: 880px) {
  .player-page {
    grid-template-columns: 1fr;
  }
  /* Specificity, not just !important: chrome.js injects
     `.sidebar.sn--c_sidebar{position:sticky!important}` into a <style> in
     the head at runtime — same specificity as `.player-page .sidebar`,
     but later in document order, so it won the tie and the sidebar stayed
     in flow. It kept its own grid row (100vh) above main#main, which put
     a full blank viewport above the hero on every phone. Qualifying with
     the element + chrome's own class outranks it outright. */
  .player-page .sidebar,
  .player-page aside.sidebar.sn--c_sidebar {
    position: fixed !important;
    left: 0 !important;
    top: 0 !important;
    width: 240px !important;
    height: 100vh !important;
    z-index: 70 !important;
    transform: translateX(-100%) !important;
    transition: transform .25s ease !important;
    display: flex !important;
    flex-direction: column !important;
  }
}

/* ── Hero ─────────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  overflow: hidden;
  padding: 24px 16px 20px;
  background: linear-gradient(135deg, #0d0d0d 0%, color-mix(in srgb, var(--school-primary) 16%, #050505) 50%, #0d0d0d 100%);
  border-bottom: 3px solid var(--school-primary);
  border-radius: 0 0 12px 12px;
}
@keyframes hero-stripe-fadein {
  from { opacity: 0; transform: translateY(-20px); }
  to   { opacity: 0.55; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  @keyframes hero-stripe-fadein {
    from { opacity: 0; }
    to   { opacity: 0.55; }
  }
}

.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(135deg, transparent, transparent 20px, color-mix(in srgb, var(--school-primary) 12%, transparent) 20px, color-mix(in srgb, var(--school-primary) 12%, transparent) 21px);
  pointer-events: none;
  opacity: 0.55;
  animation: hero-stripe-fadein 0.5s ease both;
}
.hero::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 0;
  right: 0;
  height: 36px;
  background: linear-gradient(0deg, var(--black-bg) 0%, transparent 100%);
  pointer-events: none;
}
.hero-inner {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  gap: 16px;
}
.back-link {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--gray-light);
  text-transform: uppercase;
  padding: 8px 0;
  margin-bottom: 8px;
  min-height: 44px;
}
.back-link:hover { color: var(--white-bright); }

.hero-photo, .hero-photo-placeholder {
  width: 120px;
  height: 120px;
  border-radius: 14px;
  background: #111;
  border: 2px solid var(--school-primary);
  flex: 0 0 120px;
  box-shadow: 0 6px 28px color-mix(in srgb, var(--school-primary) 28%, transparent);
}
/* R2E-10: roster portraits run taller than wide with the head in the
   upper third. object-fit:cover with no object-position let a square crop
   land on the source frame's centre, cutting the face off at the
   eyebrows. Anchor the crop to the top so the head stays in frame. */
.hero-photo { object-fit: cover; object-position: center 12%; }
.hero-photo--logo {
  object-fit: contain;
  object-position: center;
  padding: 12px;
  background: #FFFFFF;
}
.hero-photo-placeholder {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  font-family: var(--f-display);
  font-size: 18px;
  color: var(--gray-light);
  padding-bottom: 8px;
  /* Last resort only: neither a headshot nor the current school logo loaded. */
  background-image: url(/assets/sns_shield_v3.png);
  background-size: 60% auto;
  background-position: center 36%;
  background-repeat: no-repeat;
}
.hero-photo-skel {
  width: 120px;
  height: 120px;
  border-radius: 14px;
  flex: 0 0 120px;
}
.hero-info { flex: 1; min-width: 0; }
.hero-eyebrow {
  font-family: var(--f-display);
  font-size: 16px;
  letter-spacing: 0.22em;
  color: var(--school-primary);
  text-transform: uppercase;
  display: block;
  margin-bottom: 4px;
  filter: brightness(1.15);
}
.hero-school {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  min-height: 32px;
  margin-bottom: 7px;
  padding: 4px 10px;
  border: 1px solid rgba(255, 255, 255, 0.68);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.36);
  color: var(--white-bright, #F5F5F5);
  font-family: var(--f-display);
  font-size: clamp(12px, 3.8vw, 16px);
  line-height: 1.2;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .8);
  overflow-wrap: anywhere;
}
a.hero-school:hover { border-color: #FFFFFF; background: rgba(0, 0, 0, .52); }
a.hero-school:focus-visible { outline: 2px solid #FFFFFF; outline-offset: 2px; }
.hero-name {
  font-family: var(--f-display);
  font-size: clamp(26px, 4vw, 52px);
  letter-spacing: 0.04em;
  color: var(--white-bright);
  margin: 0 0 8px;
  line-height: 1;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.5);
}
.hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
  margin-top: 4px;
}
.meta-badge {
  font-size: 16px;
  color: var(--gray-light);
  font-weight: 500;
}
.meta-badge strong { color: var(--white-bright); }
.jersey-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 2px solid var(--school-primary);
  font-family: 'JetBrains Mono', monospace;
  font-size: 16px;
  font-weight: 700;
  color: var(--white-bright);
}

/* Position badges */
.pos-badge {
  display: inline-block;
  padding: 5px 14px;
  border-radius: 6px;
  font-family: var(--f-display);
  font-size: 16px;
  letter-spacing: 0.12em;
}
.pos-QB { background: rgba(255, 107, 0, 0.18); color: #FF8C42; border: 1px solid rgba(255, 107, 0, 0.3); }
.pos-RB { background: rgba(61, 186, 110, 0.15); color: #3dba6e; border: 1px solid rgba(61, 186, 110, 0.3); }
.pos-WR { background: rgba(100, 149, 237, 0.15); color: #6495ED; border: 1px solid rgba(100, 149, 237, 0.3); }
.pos-TE { background: rgba(255,45,45, 0.12); color: #FFFFFF; border: 1px solid rgba(255,45,45, 0.25); }
.pos-K, .pos-P { background: rgba(138, 43, 226, 0.15); color: #BA55D3; border: 1px solid rgba(138, 43, 226, 0.3); }
.pos-DEF, .pos-DL, .pos-LB, .pos-DB { background: rgba(220, 20, 60, 0.15); color: #FF4569; border: 1px solid rgba(220, 20, 60, 0.3); }
.pos-default { background: rgba(255, 26, 26, 0.12); color: var(--red-primary); border: 1px solid rgba(255, 26, 26, 0.25); }

/* ── Cards ────────────────────────────────────────────────────────────── */
.card {
  background: var(--black-card);
  border: 1px solid var(--gray-border);
  border-radius: 12px;
  overflow: hidden;
}
.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--gray-border);
}
.card-eyebrow {
  font-size: 16px;
  font-family: var(--f-display);
  letter-spacing: 0.18em;
  color: var(--school-primary);
  text-transform: uppercase;
  filter: brightness(1.15);
}
.card-title {
  font-family: var(--f-display);
  font-size: 18px;
  letter-spacing: 0.06em;
  color: var(--white-bright);
  margin: 0;
}
.card-body { padding: 20px; }
/* Empty states are written as a lone <p> ("No stats available for this
   season."). The UA's default 1em top/bottom margin added 32px of slack
   to every sparse card on top of the body padding. */
.card-body > p:only-child { margin: 0; }

/* The full profile answers the forward-looking question first. Prior-season
   production remains immediately below as supporting evidence. */
.projection-card {
  border-color: color-mix(in srgb, var(--school-primary) 55%, var(--gray-border));
}
.projection-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.projection-stat {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 12px;
  border: 1px solid var(--gray-border);
  border-radius: 8px;
  background: color-mix(in srgb, var(--school-primary) 9%, #0A0A0A);
}
.projection-stat-label,
.projection-stat-hint {
  font-family: 'JetBrains Mono', monospace;
  overflow-wrap: anywhere;
}
.projection-stat-label {
  color: var(--gray-light);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: .06em;
}
.projection-stat-value {
  margin: 4px 0 2px;
  color: var(--white-bright);
  font-family: var(--f-display);
  font-size: clamp(22px, 8vw, 34px);
  line-height: 1;
  overflow-wrap: anywhere;
}
.projection-stat-hint {
  color: var(--gray-light);
  font-size: 16px;
  line-height: 1.25;
}

/* ── Action buttons ───────────────────────────────────────────────────── */
.player-actions {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 12px;
}
.pl-act-btn {
  min-height: 44px;
  padding: 10px 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--f-body);
  font-size: 16px;
  letter-spacing: 0.06em;
  font-weight: 700;
  color: var(--white-bright);
  background: #111;
  border: 1px solid var(--gray-border);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, transform 0.1s;
}
.pl-act-btn:hover {
  border-color: var(--school-primary);
  background: color-mix(in srgb, var(--school-primary) 8%, #111);
}
.pl-act-btn:active { transform: scale(0.97); }
.pl-act-btn:focus-visible { outline: 2px solid var(--sns-accent, var(--school-primary)); outline-offset: 2px; }

/* ── Fantasy stats ────────────────────────────────────────────────────── */
.fantasy-hero-nums {
  display: flex;
  align-items: baseline;
  gap: 16px;
  margin-bottom: 16px;
}
.fantasy-big {
  font-family: var(--f-display);
  font-size: 48px;
  color: var(--white-bright);
  line-height: 1;
}
.fantasy-sub {
  font-family: 'JetBrains Mono', monospace;
  font-size: 16px;
  color: var(--gray-light);
}
.breakdown-row {
  display: flex;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 16px;
}
.breakdown-row:last-child { border-bottom: none; }
.breakdown-label { color: var(--gray-light); }
.breakdown-calc { font-family: 'JetBrains Mono', monospace; color: var(--gray-light); font-size: 16px; }
.breakdown-pts { font-family: 'JetBrains Mono', monospace; font-weight: 700; color: var(--white-bright); }
.breakdown-pts.negative { color: var(--pos-red); }

/* ── Ownership ────────────────────────────────────────────────────────── */
.ownership-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 16px;
}
.ownership-stat {
  text-align: center;
  padding: 12px;
  background: #111;
  border-radius: 8px;
  border: 1px solid var(--gray-border);
}
.ownership-num {
  font-family: var(--f-display);
  font-size: 36px;
  line-height: 1;
  color: var(--white-bright);
}
.ownership-label {
  font-size: 16px;
  color: var(--gray-light);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-top: 4px;
  overflow-wrap: break-word;
}
.trend-up { color: var(--pos-green); }
.trend-down { color: var(--pos-red); }
.trend-flat { color: var(--pos-flat); }
.sparkline-container { margin-top: 12px; }
.sparkline-container svg { width: 100%; height: 40px; }

/* ── Stat tables ──────────────────────────────────────────────────────── */
/* R2E-12: the table was already `overflow-x: auto` (reachable via a
   sideways drag), but with no visible cue the RESULT column read as
   truncated/broken rather than "scroll for more" — at the default scroll
   offset the header showed a bare "R" and completed games showed no
   result letter at all, which looks like missing data. This is the
   standard CSS-only "scroll shadow" recipe: two solid covers scroll WITH
   the content (background-attachment: local) to hide the shadow once
   you're at that edge, and two shadow gradients stay fixed relative to
   the viewport (background-attachment: scroll) so a shadow only shows on
   the edge that still has more to reveal. No JS, degrades safely if a
   table happens to fit. */
.stat-table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  background:
    linear-gradient(to right, var(--black-card) 30%, rgba(0, 0, 0, 0)) 0 0,
    linear-gradient(to left, var(--black-card) 30%, rgba(0, 0, 0, 0)) 100% 0,
    linear-gradient(to right, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0)) 0 0,
    linear-gradient(to left, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0)) 100% 0;
  background-repeat: no-repeat;
  background-color: var(--black-card);
  background-size: 24px 100%, 24px 100%, 10px 100%, 10px 100%;
  background-attachment: local, local, scroll, scroll;
}
.stat-table-wrap[role="region"] { tabindex: 0; }
.stat-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 16px;
  white-space: nowrap;
}
.stat-table caption { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); }
.stat-table th {
  padding: 10px 12px;
  text-align: right;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--gray-light);
  text-transform: uppercase;
  border-bottom: 1px solid var(--gray-border);
}
.stat-table th:first-child { text-align: left; }
.stat-table td {
  padding: 10px 12px;
  text-align: right;
  font-family: 'JetBrains Mono', monospace;
  font-size: 16px;
  color: var(--white-bright);
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.stat-table td:first-child {
  text-align: left;
  font-family: var(--f-body);
  color: var(--gray-light);
}
.stat-table tr:hover td { background: rgba(255, 255, 255, 0.02); }

/* ── Season selector ──────────────────────────────────────────────────── */
.season-select {
  background: #111;
  border: 1px solid var(--gray-border);
  color: var(--white-bright);
  font-family: 'JetBrains Mono', monospace;
  font-size: 16px;
  padding: 6px 12px;
  border-radius: 6px;
  min-height: 44px;
  cursor: pointer;
}
.season-select:focus-visible { outline: 2px solid var(--school-primary); }

/* ── NIL ──────────────────────────────────────────────────────────────── */
.nil-value-badge {
  font-family: 'JetBrains Mono', monospace;
  font-size: 16px;
  color: var(--pos-green);
  font-weight: 700;
}
.nil-listings-row {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding: 4px 0;
}
.nil-listing-card {
  flex: 0 0 160px;
  background: #111;
  border: 1px solid var(--gray-border);
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  transition: border-color 0.15s;
}
.nil-listing-card:hover { border-color: var(--school-primary); }
.nil-listing-img { width: 100%; height: 100px; object-fit: cover; background: #1a1a1a; }
.nil-listing-info { padding: 8px 10px; }
.nil-listing-title { font-size: 16px; font-weight: 600; margin-bottom: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nil-listing-price { font-family: 'JetBrains Mono', monospace; font-size: 16px; color: var(--pos-green); }

/* ── News ─────────────────────────────────────────────────────────────── */
.news-item {
  display: flex;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.news-item:last-child { border-bottom: none; }
.news-item-body { flex: 1; min-width: 0; }
.news-headline { font-size: 16px; font-weight: 600; margin-bottom: 4px; }
.news-headline a:hover { color: var(--school-primary); }
.news-meta { font-size: 16px; color: var(--gray-light); }
.news-empty { color: var(--gray-light); font-style: italic; }

/* ── Not found ────────────────────────────────────────────────────────── */
.not-found-state {
  text-align: center;
  padding: 80px 20px;
}
.not-found-state h1 {
  font-family: var(--f-display);
  font-size: 36px;
  margin-bottom: 12px;
}
.not-found-state p { color: var(--gray-light); margin-bottom: 24px; }

/* ── Skeletons ────────────────────────────────────────────────────────── */
@keyframes shimmer {
  0% { background-position: -200px 0; }
  100% { background-position: 200px 0; }
}
.skeleton-block, .skeleton-row {
  background: linear-gradient(90deg, #1a1a1a 25%, #222 50%, #1a1a1a 75%);
  background-size: 400px 100%;
  animation: shimmer 1.5s ease-in-out infinite;
  border-radius: 6px;
  min-height: 20px;
}
.skeleton-block { min-height: 40px; }
.skeleton-table { display: flex; flex-direction: column; gap: 8px; }
.skeleton-row { height: 32px; }
@media (prefers-reduced-motion: reduce) {
  .skeleton-block, .skeleton-row { animation: none; background: #1a1a1a; }
}

/* ── Column stacks ────────────────────────────────────────────────────
   The card tiles live in two independent stacks (.pd-col-main and
   .pd-col-rail) rather than in named grid areas. Named areas tied every
   tile to a shared row height, so a sparse card (a freshman with no
   stats) inherited its neighbour's height and rendered a mostly-empty
   box. Two flex stacks let each column pack tight to its own content.
   ─────────────────────────────────────────────────────────────────── */
.pd-col {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

/* The sitewide footer (chrome.js) is appended as a plain child of
   main#main.player-content with no place in the layout of its own, so
   grid auto-placement used to drop it into whichever cell was free.
   Pin it full-width at the true bottom at every breakpoint.
   FOOTER-SELECTOR-SIBLINGS (2026-08-20): flagged by pattern match against
   MESSAGES-FOOTER-SELECTOR (a sibling `#sns-footer` rule on /messages that
   never matched anything live) — re-verified live here and this one is NOT
   the same bug. /players/<slug> is served from apps/web/players/detail.html,
   which is not literally named index.html, so tools/seo-nav-bake.mjs's
   file walk (`name === 'index.html'`) never bakes a static footer into it;
   there is no pre-existing `<footer>` in the served markup to make
   chrome.js's runtime injector bail. Its runtime footer therefore DOES fire
   here and IS created with `id="sns-footer"` as the last child of
   main#main.player-content — confirmed live (360x884, authed,
   /players/cam-ward): `#sns-footer` count 1, parent MAIN.player-content,
   computed grid-column "1 / -1". No fix needed; the `.sns-footer` half of
   this selector is redundant belt-and-braces for the (currently unused)
   baked-footer case, not dead weight to remove. */
.player-content > #sns-footer,
.player-content > .sns-footer {
  grid-column: 1 / -1;
}

/* ── Responsive: tablet (768px+) ──────────────────────────────────────── */
@media (min-width: 768px) {
  .player-content {
    display: grid;
    /* fr, not %: 60% + 40% + gap overflowed the padding box by exactly
       the gap width, pushing the rail past the right gutter and clipping
       its charts. fr resolves after gaps are subtracted. */
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    align-items: start;
    gap: 16px;
    padding: 0 24px 48px;
  }
  .hero { grid-column: 1 / -1; }
  #not-found { grid-column: 1 / -1; }

  .hero-photo, .hero-photo-placeholder, .hero-photo-skel {
    width: 160px; height: 160px; flex: 0 0 160px;
  }
}

/* ── Responsive: desktop (1280px+) ────────────────────────────────────── */
@media (min-width: 1280px) {
  .player-content {
    /* Was a 3-column grid whose first column was permanently empty —
       ~300px of dead space running the full height of the page. The
       column was reserved for a nested .player-actions that is not a
       grid item and never could be. Actions now sit in the hero. */
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
    gap: 20px;
    padding: 0 32px 48px;
  }
  .pd-col { gap: 20px; }

  .hero-photo, .hero-photo-placeholder, .hero-photo-skel {
    width: 200px; height: 200px; flex: 0 0 200px;
  }

  /* Fill the hero's empty right half with the action buttons instead of
     stranding them under the photo. */
  .hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "back  back"
      "inner actions";
    align-items: end;
    column-gap: 24px;
  }
  .hero .back-link { grid-area: back; }
  .hero .hero-inner { grid-area: inner; }
  /* Stacked, not a wide row: a horizontal run of three buttons ate ~450px
     of the hero and forced long names ("Byrum Brown") to wrap. */
  .hero .player-actions {
    grid-area: actions;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    width: 200px;
    margin-top: 0;
  }
}

/* ── Game log season toggle (red pill radiogroup) ─────────────────────
   Ported from the components.css .filter-toggles/.toggle-pill oval
   (components.css isn't loaded on this route). Red active fill per the
   sitewide accent. */
.pd-season-toggle {
  display: flex;
  gap: 4px;
  padding: 3px;
  background: var(--black-soft, #111);
  border: 1px solid var(--gray-border, #2A2A2A);
  border-radius: 999px;
  flex: 0 0 auto;
}
/* 390px: title + toggle can't share one row — let the header wrap. */
#gamelog-section .card-header { flex-wrap: wrap; row-gap: 10px; }
.pd-pill {
  border: none;
  background: transparent;
  color: var(--gray-light, #C2C2C2);
  font-family: var(--f-body);
  font-size: 16px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.04em;
  padding: 8px 16px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.pd-pill:not(.is-active):hover { color: var(--white-bright, #F5F5F5); }
/* R2E-15: this used --border-accent (sitewide brand red, tokens.css) while
   every other accent on the card follows --school-primary — the toggle
   stayed red after the rest of the page had already gone Boise blue. */
.pd-pill.is-active {
  background: var(--school-primary);
  color: #fff;
  box-shadow: 0 0 12px color-mix(in srgb, var(--school-primary) 45%, transparent);
}
.pd-pill:focus-visible {
  outline: 2px solid var(--school-primary);
  outline-offset: 2px;
}

/* ── Game log extras ──────────────────────────────────────────────────── */
.pd-res { font-weight: 700; font-family: 'JetBrains Mono', monospace; }
.pd-res-W { color: var(--pos-green); }
.pd-res-L { color: var(--pos-red); }
.pd-res-T { color: var(--gray-light); }
.pd-sched { color: var(--gray-light); font-family: 'JetBrains Mono', monospace; font-size: 15px; }
.pd-log-note {
  margin: 0 0 12px;
  font-size: 15px;
  color: var(--gray-light);
  font-style: italic;
}
/* R2E-11: separates the played game log from the honestly-labeled
   upcoming-schedule block when a season has both (mid-season) or only
   the latter (preseason). */
.pd-subhead {
  margin: 16px 0 8px;
  font-family: var(--f-display);
  font-size: 14px;
  letter-spacing: 0.14em;
  color: var(--gray-light);
  text-transform: uppercase;
}

/* ── Ownership (real cross-league counts) ─────────────────────────────── */
/* R2E-13: bare `1fr` tracks default to `min-width: auto`, so the widest
   label ("STARTING", display font, wide tracking) forced its track past a
   third of the card and blew the third tile off the right edge.
   `minmax(0, 1fr)` lets every track shrink below its content's intrinsic
   width so the label wraps instead of overflowing. */
.ownership-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* minmax(0,1fr) fixes tracks that CAN wrap, but "STARTING" is a single
   unbreakable word — even wrapped, its min-content alone still ran ~14px
   past a 90px-wide third-tile track at 360px (measured live, R2E-13
   verification). Shrink the 3-up variant's type instead of relying on
   overflow-wrap to break a word mid-letter. */
.ownership-grid--3 .ownership-num { font-size: 26px; }
.ownership-grid--3 .ownership-label { font-size: 12px; letter-spacing: 0.05em; }
.ownership-grid--3 .ownership-stat { padding: 10px 6px; }
.ownership-of {
  font-size: 18px;
  color: var(--gray-light);
  font-family: var(--f-display);
}
.ownership-sub {
  font-size: 15px;
  color: var(--gray-light);
  margin-bottom: 4px;
}
.pd-own-list {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
}
.pd-own-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 16px;
}
.pd-own-list li:last-child { border-bottom: none; }
.pd-own-team { color: var(--white-bright); font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-own-league { color: var(--gray-light); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-own-league a { color: inherit; text-decoration: none; }
.pd-own-league a:hover { color: var(--white-bright); text-decoration: underline; }
.pd-own-starter {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--pos-green);
  border: 1px solid var(--pos-green);
  border-radius: 4px;
  padding: 2px 6px;
}
.pd-own-private {
  margin-top: 10px;
  font-size: 15px;
  color: var(--gray-light);
  font-style: italic;
}

/* ── NIL coming-soon placeholder ──────────────────────────────────────── */
.pd-soon-badge {
  flex: 0 0 auto;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--border-accent, #FF1A1A);
  border: 1px solid var(--border-accent, #FF1A1A);
  border-radius: 999px;
  padding: 4px 10px;
  white-space: nowrap;
}
.pd-soon-copy { color: var(--gray-light); margin: 0; }

/* ── Action button icons (injected by player-actions.js renderButtons()) ── */
.pl-act-ic {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.pl-act-ic svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
}

/* ── Focus indicators ─────────────────────────────────────────────────── */
:focus-visible {
  outline: 2px solid var(--sns-accent, var(--school-primary));
  outline-offset: 2px;
}

/* ── WK0-0814-03: Week 0 game-log rows ────────────────────────────────────
   Games before Thu 2026-09-03 (ET) are Week 0 — no fantasy points. Badge
   after the date, row dimmed slightly. Muted/neutral, not alarm-red. */
.pd-wk0 {
  display: inline-block;
  font: 700 10px/1 var(--f-mono, monospace);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gray-light, #8A8A8A);
  background: rgba(255,255,255,.06);
  border: 1px solid var(--gray-border, #2A2A2A);
  padding: 2px 5px;
  border-radius: 4px;
  vertical-align: 1px;
  white-space: nowrap;
}
tr.pd-wk0-row td { opacity: .62; }
