/* Game detail page (templates/games/game_detail.html) - page-specific
   classes layered on static/css/base.css's shared .hl-* components and
   tokens, same pattern as league_home.css/stat_leaders.css/
   player_profile.css. Covers the matchup hero (incl. each team's W-L
   record pill), the game-leaders strip, the Team Stats comparison bars,
   and the box-score section head/badges/totals row that
   templates/games/_box_score_table.html renders. */

/* ─── Hero (matchup masthead) ─────────────────────────────────────────
   Same gradient-card + radial-glow treatment as league_home.css's
   .lh-masthead, adapted to a two-team scoreboard layout instead of a
   single identity block. */
.gd-hero {
  position: relative;
  overflow: hidden;
  background: linear-gradient(165deg, var(--bg-card) 0%, var(--bg-raised) 100%);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: var(--space-5) var(--space-6);
  margin-bottom: var(--space-5);
}

.gd-hero-glow {
  position: absolute;
  top: -90px;
  left: 50%;
  transform: translateX(-50%);
  width: 340px;
  height: 220px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--primary-rgb), 0.16), transparent 70%);
  pointer-events: none;
}

.gd-hero-top {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  margin-bottom: var(--space-5);
  text-align: center;
}

.gd-hero-meta {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
}

.gd-hero-dot {
  margin: 0 6px;
  opacity: 0.5;
}

/* ─── Matchup (team / score / team) ──────────────────────────────────── */
.gd-matchup {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-3);
}

.gd-team {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  padding: var(--space-2);
  border-radius: 12px;
  text-decoration: none;
  transition: background-color 0.15s ease;
}

.gd-team:hover {
  background: rgba(245, 241, 236, 0.04);
}

.gd-team-avatar {
  width: 64px;
  height: 64px;
  border-radius: 16px;
  font-size: 22px;
}

.gd-team-name {
  max-width: 100%;
  overflow: hidden;
  font-family: var(--font-heading);
  font-size: clamp(14px, 3vw, 18px);
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text);
  transition: color 0.15s ease;
}

.gd-team:hover .gd-team-name {
  color: var(--primary);
}

.gd-team-score {
  font-family: var(--font-mono);
  font-size: clamp(32px, 7vw, 46px);
  font-weight: 800;
  line-height: 1;
  color: var(--text-secondary);
}

.gd-team--win .gd-team-score {
  color: var(--lime);
}

.gd-team-record {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
}

.gd-matchup-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 0 var(--space-2);
}

.gd-final-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.gd-vs {
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: 700;
  color: var(--text-muted);
}

/* The status badge up top already says "Cancelled" - this just keeps the
   matchup itself from reading identically to a normal upcoming game (same
   plain "VS" divider previously covered both cases). */
.gd-matchup--cancelled {
  opacity: 0.55;
}

.gd-matchup--cancelled .gd-final-label {
  color: var(--alert);
}

.gd-score-sep {
  font-family: var(--font-mono);
  font-size: clamp(24px, 5vw, 34px);
  font-weight: 300;
  color: var(--border-strong);
}

.gd-forfeit-note {
  position: relative;
  margin: var(--space-4) 0 0;
  text-align: center;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--alert);
}

.gd-notes {
  margin: 0;
  white-space: pre-line;
}

/* ─── Game leaders strip ─────────────────────────────────────────────
   Was a grid of separate bordered tiles, one per category (top accent
   bar, same shape league_home.css's .lh-leader-tile used to be) - that
   tile shape was rebuilt as a hairline ledger there in Phase 0 of the
   site-wide Playbook conversion (direct user feedback: read as a generic
   "AI stat card" grid), so this strip - up to 5 categories instead of 3,
   an even denser case for the same problem - gets the same rebuild.
   Category color now lives on a chip (`leader.label` is already the
   short "PTS"/"REB"/... form - apps/games/views.py's
   _LEADER_CATEGORIES) instead of a top bar. */
.gd-leaders-panel {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
}

.gd-leader-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  text-decoration: none;
  color: inherit;
  border-top: 1px solid var(--border);
  transition: background 0.15s ease;
}

.gd-leader-row:first-child {
  border-top: none;
}

.gd-leader-row:hover {
  background: var(--bg-raised);
}

.gd-leader-row[data-category="points"] { --tile-accent: var(--alert); }
.gd-leader-row[data-category="rebounds"] { --tile-accent: var(--violet); }
.gd-leader-row[data-category="assists"] { --tile-accent: var(--teal); }
.gd-leader-row[data-category="steals"] { --tile-accent: var(--lime); }
.gd-leader-row[data-category="blocks"] { --tile-accent: var(--gold); }

.gd-leader-chip {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.3px;
  background: color-mix(in srgb, var(--tile-accent, var(--primary)) 16%, transparent);
  color: var(--tile-accent, var(--primary));
  transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.gd-leader-row:hover .gd-leader-chip {
  transform: scale(1.08) rotate(-4deg);
}

.gd-leader-info {
  flex: 1;
  min-width: 0;
}

.gd-leader-name {
  display: block;
  max-width: 100%;
  overflow: hidden;
  font-size: 14px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text);
}

.gd-leader-team {
  display: block;
  margin-top: 2px;
  font-size: 11.5px;
  color: var(--text-muted);
}

.gd-leader-value {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 22px;
  font-weight: 700;
  line-height: 1.15;
  color: var(--text);
}

/* ─── Team Stats comparison card ─────────────────────────────────────
   Mirrored bar-chart rows (away team's bar grows right-to-left toward
   center, home team's grows left-to-right away from center) - reads at a
   glance which side leads each category without another plain table of
   numbers, the way a broadcast "team stats" graphic does. Bar color
   defaults to the away/home accent pair below; a team's own
   `primary_color` (set via inline `--bar-color`, same convention as the
   hero avatar/box-score-head monograms) wins when present. */
.gd-compare-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.gd-compare-teams {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border);
  font-family: var(--font-heading);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.gd-compare-row {
  display: grid;
  grid-template-columns: 40px 1fr 40px;
  align-items: center;
  gap: var(--space-2);
}

.gd-compare-value {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
}

.gd-compare-value--away {
  text-align: left;
}

.gd-compare-value--home {
  text-align: right;
}

.gd-compare-bars {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 8px;
}

.gd-compare-bar {
  --bar-color: var(--violet);
  height: 6px;
  border-radius: 999px;
  background: var(--bg-raised);
  overflow: hidden;
  display: flex;
}

.gd-compare-bar--home {
  --bar-color: var(--teal);
  justify-content: flex-start;
}

.gd-compare-bar--away {
  justify-content: flex-end;
}

.gd-compare-bar span {
  display: block;
  height: 100%;
  min-width: 2px;
  border-radius: 999px;
  background: var(--bar-color);
  transition: width 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

.gd-compare-label {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  color: var(--text-muted);
}

/* ─── Game Awards card (Best Player of the Game + DD/TD callouts) ────
   On-the-fly, display-only badges (apps.games.views._game_awards) - never
   stored, never a real Award/AwardRecipient. Best Player of the Game gets
   the gold trophy treatment; double/triple-double rows reuse the same
   .gd-stat-badge chip the box score table's inline badge already uses
   (data-tier="double"/"triple"), just as the leading marker in a full row
   here instead of a small inline suffix next to a name. */
.gd-awards-card {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.gd-award-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-2);
  text-decoration: none;
  border-radius: 10px;
  transition: background 0.15s ease;
}

a.gd-award-row:hover {
  background: var(--bg-raised);
}

.gd-award-row + .gd-award-row {
  border-top: 1px solid var(--border);
}

.gd-award-icon {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 32px;
  border-radius: 999px;
}

.gd-award-row--bpg .gd-award-icon {
  color: var(--gold);
  background: rgba(245, 195, 75, 0.16);
}

.gd-award-row .gd-stat-badge.gd-award-icon {
  margin-left: 0;
}

.gd-award-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  margin-right: auto;
}

.gd-award-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.gd-award-name {
  overflow: hidden;
  font-size: 14px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text);
}

.gd-award-row:hover .gd-award-name {
  color: var(--primary);
}

.gd-award-team {
  font-size: 11px;
  color: var(--text-muted);
}

.gd-award-line {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  white-space: nowrap;
}

/* ─── Box score section head (team identity + shooting splits) ──────── */
.gd-box-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.gd-box-team {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}


.gd-box-splits {
  display: flex;
  gap: var(--space-4);
}

.gd-split {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  min-width: 42px;
}

.gd-split .value {
  font-family: var(--font-mono);
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
}

.gd-split .label {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ─── Stat badge chip (double-double / triple-double) - outlined rather
   than filled, currentColor border so the two tiers below only need to
   set one color property each. ────────────────────────────────────── */
.gd-stat-badge {
  display: inline-flex;
  align-items: center;
  margin-left: 6px;
  padding: 1px 4px;
  border: 1px solid currentColor;
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: middle;
}

.gd-stat-badge[data-tier="double"] { color: var(--teal); }
.gd-stat-badge[data-tier="triple"] { color: var(--gold); }

/* Team's game-high scorer gets a subtle left accent on their row - same
   "the one number worth a glance" idea as stat_leaders.css's gold-rank
   emphasis, applied to the box score instead of a leaderboard. No
   `position: relative` of its own here - the sticky-column rule below
   already makes `.gd-box-table td:first-child` a positioned element,
   which is just as valid a containing block for this ::before as
   `relative` would be. */
.gd-table-leader td:nth-child(2)::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 3px;
  background: var(--primary);
}

.gd-totals-row td {
  background: var(--bg-raised);
  border-top: 1px solid var(--border-strong);
  border-bottom: none;
  font-weight: 700;
  color: var(--text);
}

.gd-totals-row td:nth-child(2) {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Header cells centered (Player included) - a scannable, evenly-spaced
   header row reads more like a real broadcast box score than the
   left-aligned default every other .hl-table on the site uses; scoped to
   this table only via .gd-box-table rather than touched in base.css,
   since e.g. the schedule/standings tables still want their left-aligned
   header default. */
.gd-box-table th,
.gd-box-table td,
.gd-box-table .num {
  text-align: center;
  font-family: var(--font-mono);
  letter-spacing: 0.05em;
}

/* Perf hint for box-score-sort.js's FLIP transform below - rows only pay
   for their own compositor layer while a sort is actually in flight. */
.gd-box-table tbody tr {
  will-change: transform;
}

/* Sortable column headers (static/js/box-score-sort.js toggles
   aria-sort/data-sort-dir on click, with a FLIP transform so rows glide
   into their new position instead of jumping) - every stat column except
   Player, which stays in its original roster order rather than being
   sortable itself. The ↕ glyph sits at low opacity on every sortable
   header as a standing "you can click this" affordance, then lights up
   solid + orange as ↑/↓ on whichever column is actually driving the
   current order. */
.gd-box-table th[data-sort] {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

.gd-box-table th[data-sort]:hover,
.gd-box-table th[data-sort]:focus-visible {
  color: var(--text);
}

.gd-box-table th[data-sort]::after {
  content: "\2195";
  display: inline-block;
  width: 8px;
  margin-left: 3px;
  font-size: 9px;
  opacity: 0.4;
}

.gd-box-table th[data-sort][aria-sort="ascending"]::after {
  content: "\2191";
  opacity: 1;
  color: var(--primary);
}

.gd-box-table th[data-sort][aria-sort="descending"]::after {
  content: "\2193";
  opacity: 1;
  color: var(--primary);
}

/* Player name + double-double/triple-double badge stay on one line -
   .gd-stat-badge is already nowrap internally, but without this the <td>
   itself could still break the line BETWEEN the name link and the badge
   once the table gets squeezed, dropping the badge onto its own row
   under the name instead of the table just scrolling wider (the
   intended behavior of .hl-table-wrap's overflow-x: auto). */
.gd-box-table td:nth-child(2) {
  white-space: nowrap;
}

/* ─── Sticky Player column - this table deliberately stays a real,
   horizontally-scrollable table on phones rather than switching to
   stacked cards (see .gd-scroll-hint below), so swiping right to see
   FG/3PT/FT would otherwise scroll the Player column out of view too -
   the one column you need to keep in sight to know whose stat line
   you're looking at. A sticky cell paints in its own layer above
   whatever scrolls underneath it, so (unlike a plain cell, which is
   transparent and lets its <tr>'s background show through) it needs an
   explicit background per row state, or it goes see-through against the
   columns sliding past behind it. Not combined with base.css's
   .hl-table--row-link (see that file's comment) - `position: sticky`
   here would become the containing block for anything inside this cell,
   confining a stretched-link overlay to just this column's width instead
   of the full row. */
.gd-box-table th:nth-child(2),
.gd-box-table td:nth-child(2) {
  position: sticky;
  left: 0;
}

.gd-box-table th:nth-child(2) {
  z-index: 3;
}

.gd-box-table td:nth-child(2) {
  z-index: 2;
  background: var(--bg-card);
}

.gd-box-table tbody tr:hover td:nth-child(2),
.gd-box-table tbody tr:focus-within td:nth-child(2) {
  background: var(--bg-raised);
}

.gd-box-table .gd-totals-row td:nth-child(2) {
  background: var(--bg-raised);
}

.gd-scroll-hint {
  display: none;
  margin: calc(var(--space-3) * -1) 0 var(--space-4);
  font-size: 11px;
  color: var(--text-muted);
}

/* static/js/scroll-table-hint.js toggles this based on whether either
   box score table's .hl-table-wrap actually overflows (a long team/player
   name can force real overflow above 640px; a short one may not overflow
   even below it) - a fixed breakpoint only approximated that. */
.gd-scroll-hint[data-visible] {
  display: block;
}

/* No-JS fallback: same 640px breakpoint base.css's .hl-table--stack uses
   for its own responsive table handling - the box score stays a real
   (scrollable) table rather than switching to stacked cards at this
   width, since stacking 12 stat columns per player would read worse than
   a table a visitor can swipe through, but the hint makes that swipe
   discoverable instead of the row just quietly cutting off. Without JS,
   there's no way to measure real overflow, so this falls back to the old
   width-based guess. */
.no-js .gd-scroll-hint {
  display: none;
}

@media (max-width: 640px) {
  .no-js .gd-scroll-hint {
    display: block;
  }
}

/* ─── Small-screen tightening (phones) ───────────────────────────────── */
@media (max-width: 480px) {
  .gd-hero {
    padding: var(--space-4);
  }

  /* The 3-column team/center/team grid gets too tight for two full team
     names plus a large score once the hero itself is this narrow - each
     side becomes a compact horizontal row (avatar + name + score) with
     the divider collapsing to a thin "Final"/"VS" band between them,
     matching how a scoreboard app lays out on a phone rather than
     squeezing the desktop layout down. */
  .gd-matchup {
    grid-template-columns: 1fr;
    gap: 6px;
  }

  .gd-team {
    flex-direction: row;
    justify-content: flex-start;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    background: var(--bg-raised);
    border-radius: 10px;
  }

  .gd-team-avatar {
    width: 40px;
    height: 40px;
    font-size: 14px;
    border-radius: 10px;
  }

  .gd-team-name {
    flex: 1;
    min-width: 0;
    text-align: left;
    font-size: 15px;
  }

  .gd-team-score {
    font-size: 24px;
  }

  .gd-matchup-center {
    flex-direction: row;
    justify-content: center;
    gap: 6px;
    padding: 2px 0;
  }

  .gd-score-sep {
    display: none;
  }

  .gd-leader-row {
    padding: var(--space-2) var(--space-3);
  }

  /* Team Stats card - compact for phones: tighter card padding and row
     spacing, thinner bars, smaller labels/values, and team names that
     truncate instead of wrapping, so all nine rows fit on roughly one
     screen without losing the bar comparison. */
  .gd-compare-card {
    gap: 6px;
    padding: var(--space-3);
  }

  .gd-compare-teams {
    gap: var(--space-2);
    padding-bottom: var(--space-2);
    font-size: 11px;
  }

  .gd-compare-team {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .gd-compare-team:last-child {
    text-align: right;
  }

  .gd-compare-row {
    grid-template-columns: 32px 1fr 32px;
    gap: 4px;
  }

  .gd-compare-value {
    font-size: 11px;
  }

  .gd-compare-bars {
    gap: 6px;
  }

  .gd-compare-bar {
    height: 4px;
  }

  .gd-compare-label {
    min-width: 52px;
    font-size: 8px;
  }

  .gd-compare-note {
    margin-top: 2px;
    font-size: 10px;
    line-height: 1.3;
  }

  .gd-box-head {
    align-items: flex-start;
    flex-direction: column;
  }

  .gd-box-splits {
    gap: var(--space-3);
  }
}

.gd-compare-note {
  margin: 0.75rem 0 0;
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--hl-text-muted, #6b7280);
  text-align: center;
}

/* Shooting cell - made-attempted as the primary (sortable) figure, the
   percentage beneath in muted text; same split team_analytics.css's
   .ta-fg/.ta-fg-detail use for its FG% column. */
.gd-shot {
  display: block;
  font-weight: 700;
  color: var(--text);
}

.gd-shot-pct {
  display: block;
  margin-top: 1px;
  font-size: 10px;
  color: var(--text-muted);
}

/* ─── Box score: compact, left-aligned Player column ─────────────────────
   Overrides the table-wide centering above for the sticky Player cell only.
   The name is capped and ellipsized (full name in the link's title
   attribute, and the profile link is one tap away) so one long name can't
   widen the sticky column and eat the space the stat columns need. The
   DD/TD badge sits after the name and never shrinks. */
.gd-box-table th:nth-child(2),
.gd-box-table td:nth-child(2) {
  padding-left: var(--space-3);
  padding-right: var(--space-2);
}

.gd-box-table td:nth-child(2) {
  text-align: left;
}

.gd-box-table th {
  text-align: center;
}

.gd-box-table th:first-child,
.gd-box-table td:first-child {
  width: 1%;
  padding-left: var(--space-3);
  padding-right: var(--space-2);
}

.gd-player-cell {
  display: flex;
  align-items: center;
  gap: 6px;
  max-width: 220px;
  transition: max-width 0.2s ease;
}

/* static/js/scroll-table-hint.js adds .is-scrolled to the wrapper once the
   table is scrolled sideways - full name at rest, compact cap while
   scrolled. */
.gd-box-wrap.is-scrolled .gd-player-cell {
  max-width: 150px;
}

.gd-player-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gd-player-cell .gd-stat-badge {
  flex: none;
}

@media (max-width: 480px) {
  .gd-box-wrap.is-scrolled .gd-player-cell {
    max-width: 104px;
  }

  .gd-box-table th:nth-child(2),
  .gd-box-table td:nth-child(2) {
    padding-left: var(--space-2);
    padding-right: 6px;
  }

  /* Soft edge on the sticky column so it reads as floating over the
     stat columns scrolling beneath it. */
  .gd-box-table td:nth-child(2),
  .gd-box-table th:nth-child(2) {
    box-shadow: 1px 0 0 var(--border);
  }
}

/* ─── Box score: slimmer, themed horizontal scrollbar ────────────────────
   Thin rounded thumb using the site's border tokens (accent on hover),
   with momentum scrolling and contained overscroll so a sideways swipe
   doesn't trigger browser back-navigation. */
.gd-box-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
  padding-bottom: 4px;
}

.gd-box-wrap::-webkit-scrollbar {
  height: 8px;
}

.gd-box-wrap::-webkit-scrollbar-track {
  background: var(--bg-raised);
  border-radius: 999px;
}

.gd-box-wrap::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 999px;
}

.gd-box-wrap::-webkit-scrollbar-thumb:hover {
  background: var(--primary);
}
