/* Hoopers Lists — shared base template chrome (header/footer) + global
   Blacktop+ tokens (docs/color-palette.md). Every public page inherits
   this via templates/base/base.html. landing.css/demo.css pre-date this
   file and keep their own scoped token redeclaration under .landing-page/
   .demo-page (harmless - identical values) rather than being touched here. */

:root {
  --bg: #08080A;
  --bg-raised: #131215;
  --bg-card: #1A181B;
  --border: #2A2520;
  --border-strong: #3D342B;
  --primary: #F26A10;
  --primary-hover: #FF8330;
  --orange-deep: #9C4310;
  --on-primary: #140A03;
  --teal: #2FD3C4;
  --violet: #9B7BFF;
  --lime: #B6E24A;
  --gold: #F5C34B;
  --alert: #FF5A4D;
  --text: #F5F1EC;
  --text-secondary: #B3A99C;
  --text-muted: #7C7266;

  /* ─── Type scale (docs/color-palette.md) ───────────────────────── */
  --font-heading: "Saira Condensed", sans-serif;
  --font-body: "Inter", Arial, sans-serif;
  --font-mono: "JetBrains Mono", monospace;

  /* ─── Spacing scale (4px base grid, docs/color-palette.md) ─────── */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 40px;
  --space-8: 56px;
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
}

main {
  flex: 1;
}

a {
  color: inherit;
}

/* Alpine hides [x-cloak] elements itself once it boots, but the browser
   paints them first - global so every page using x-cloak (not just
   player_profile.css, which redeclares this identically) gets the
   pre-hydration flash suppressed, notably leagues/_public_nav.html's More
   flyout, which renders on every public page. */
[x-cloak] {
  display: none !important;
}

/* ─── Headings (Saira Condensed, uppercase, per docs/color-palette.md) */
h1, h2, h3, h4 {
  font-family: var(--font-heading);
  text-transform: uppercase;
  margin: 0;
}

h1 { font-size: 28px; line-height: 1.1; font-weight: 800; letter-spacing: 0.2px; }
h2 { font-size: 22px; line-height: 1.15; font-weight: 800; }
h3 { font-size: 20px; line-height: 1.15; font-weight: 700; }
h4 { font-size: 16px; line-height: 1.2; font-weight: 700; }

p {
  margin: 0 0 var(--space-3);
  color: var(--text-secondary);
}

.hl-display {
  font-family: var(--font-heading);
  text-transform: uppercase;
  font-size: clamp(34px, 6vw, 56px);
  line-height: 1.03;
  font-weight: 800;
}

.hl-eyebrow {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--primary);
  margin: 0 0 var(--space-2);
}

.hl-body-lg { font-size: 16px; line-height: 1.6; }
.hl-body-sm { font-size: 13px; line-height: 1.5; }
.hl-label { font-size: 12px; line-height: 1.4; font-weight: 500; }
.hl-caption { font-size: 11px; line-height: 1.4; font-weight: 500; color: var(--text-muted); }
.hl-micro {
  font-size: 10px;
  line-height: 1.3;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
}
.hl-stat { font-family: var(--font-mono); font-size: 12px; font-weight: 700; }
.hl-muted { color: var(--text-muted); }

/* ─── Page shell / layout primitives ────────────────────────────── */
.hl-page {
  max-width: 960px;
  margin: 0 auto;
  padding: var(--space-6) clamp(20px, 5vw, 64px);
  width: 100%;
  box-sizing: border-box;
}

.hl-page--narrow {
  max-width: 640px;
}

.hl-section {
  margin-bottom: var(--space-7);
}

.hl-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}

.hl-section-head h2 {
  margin: 0;
}

.hl-link {
  color: var(--primary);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.hl-link:hover {
  color: var(--primary-hover);
}

/* ─── Breadcrumbs (public league pages only - templates/base/
   league_public_base.html's `breadcrumbs` block; not used on the
   landing/demo marketing pages or admin_kit's own trail) ───────────── */
.hl-breadcrumbs {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: var(--space-4);
  font-size: 12px;
  font-weight: 500;
}

.hl-breadcrumbs a {
  color: var(--text-muted);
  text-decoration: none;
}

.hl-breadcrumbs a:hover {
  color: var(--primary);
}

.hl-breadcrumbs-sep {
  color: var(--text-muted);
  opacity: 0.5;
}

.hl-breadcrumbs-current {
  color: var(--text);
  font-weight: 600;
}

/* ─── Card ───────────────────────────────────────────────────────── */
.hl-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: var(--space-5);
}

.hl-card + .hl-card {
  margin-top: var(--space-3);
}

.hl-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-4);
}

/* ─── Buttons ────────────────────────────────────────────────────── */
.hl-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 20px;
  border-radius: 10px;
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
  line-height: 1;
  border: 1px solid transparent;
  cursor: pointer;
}

.hl-btn-primary {
  background: var(--primary);
  color: var(--on-primary);
}

.hl-btn-primary:hover {
  background: var(--primary-hover);
}

.hl-btn-secondary {
  background: var(--bg-card);
  color: var(--text);
  border-color: var(--border-strong);
}

.hl-btn-secondary:hover {
  border-color: var(--primary);
  color: var(--primary);
}

/* ─── Table ──────────────────────────────────────────────────────── */
.hl-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 12px;
}

.hl-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.hl-table th {
  text-align: left;
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
  padding: 10px 14px;
  background: var(--bg-raised);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.hl-table td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
}

.hl-table tbody tr:last-child td {
  border-bottom: none;
}

.hl-table tbody tr {
  transition: background-color 0.15s ease;
}

.hl-table tbody tr:hover,
.hl-table tbody tr:focus-within {
  background: var(--bg-raised);
}

/* ─── Row-as-link tables - opt in per <table> via .hl-table--row-link.
   Without this, a row's hover highlight above implies the WHOLE row is
   clickable when really only one small inline link inside it is (or, on
   some pages, none at all) - dead space everywhere else. This turns the
   row's one designated link (.hl-table-row-link-target, put on whichever
   <a> represents "this row" - the game a schedule row is for, the team a
   standings row is for) into a full-row "stretched link" via ::after, so
   tapping anywhere in the row/card navigates. A row that ALSO has other,
   separate links (e.g. a schedule row's opponent link alongside its game
   link) marks that link's <td> with .hl-table-cell-interactive to keep it
   independently clickable above the overlay - same two-layer pattern
   static/css/players.css established first for the player directory,
   generalized here since the underlying gap recurs across
   standings/schedule/team-detail/etc. A real <a>, not a JS click handler,
   so ctrl/cmd-click, middle-click, and keyboard activation all keep
   working for free.

   Not used by game_detail.css's box score table - that table's first
   column is separately made `position: sticky` for horizontal scroll
   (see game_detail.css), which becomes the nearest positioned ancestor
   for anything inside it and would confine the stretched-link overlay to
   just that column's width instead of the full row; the two techniques
   don't compose on the same cell, so that table keeps just its one
   inline player-name link instead. */
.hl-table--row-link tbody tr:not(.hl-table-group-row) {
  position: relative;
  cursor: pointer;
}

.hl-table--row-link .hl-table-row-link-target::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

.hl-table--row-link .hl-table-cell-interactive {
  position: relative;
  z-index: 2;
}

.hl-table .num {
  font-family: var(--font-mono);
  text-align: right;
  font-variant-numeric: tabular-nums;
  /* th already gets this above - td didn't, so a squeezed table (narrow
     viewport, many columns) could wrap a value like "10-17" onto two
     lines instead of just growing .hl-table-wrap's intended horizontal
     scroll. Numeric data should never wrap. */
  white-space: nowrap;
}

/* ─── Compact modifier - denser rows for long lists (schedule) ──────── */
.hl-table--compact th,
.hl-table--compact td {
  padding: 7px 12px;
}

/* ─── Day-group header row (schedule page groups games by date so the
   date itself isn't repeated on every row) ──────────────────────────── */
.hl-table-group-row td {
  background: var(--bg-raised);
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  padding: 6px 14px;
}

.hl-table-group-row td::before {
  content: none;
}

/* ─── Schedule table - header alignment + content color hierarchy ───── */
.hl-schedule-table th {
  text-align: center;
}

.hl-schedule-table td[data-label="Time"] {
  color: var(--text-secondary);
  font-family: var(--font-mono);
  font-size: 12px;
}

.hl-schedule-table td[data-label="Venue"] {
  color: var(--text-secondary);
}

/* ─── Schedule matchup (team names + winner emphasis) ───────────────── */
.hl-schedule-matchup a {
  white-space: normal;
  display: inline-flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px;
}

.hl-schedule-team {
  font-weight: 700;
}

.hl-schedule-team--win {
  color: var(--text);
  font-weight: 800;
}

.hl-schedule-vs {
  color: var(--text-muted);
  font-weight: 400;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

/* ─── Schedule score (winner's number emphasized, same signal color as
   the "completed" status badge so the two reinforce each other) ─────── */
.hl-schedule-score {
  color: var(--text-muted);
  font-weight: 600;
}

.hl-schedule-score--win {
  color: var(--lime);
  font-weight: 800;
}

.hl-schedule-score-sep {
  color: var(--text-muted);
  margin: 0 2px;
}

.hl-schedule-forfeit-note {
  color: var(--alert);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

/* ─── Pagination ─────────────────────────────────────────────────────── */
.hl-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

.hl-pagination-status {
  font-size: 12px;
  color: var(--text-muted);
  font-family: var(--font-mono);
}

.hl-pagination-disabled {
  opacity: 0.4;
  pointer-events: none;
}

/* ─── Status badges / chips ─────────────────────────────────────── */
.hl-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  white-space: nowrap;
  background: rgba(179, 169, 156, 0.16);
  color: var(--text-secondary);
}

.hl-badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.hl-badge[data-status="scheduled"],
.hl-badge[data-status="upcoming"],
.hl-badge[data-status="pending"] { background: rgba(155, 123, 255, 0.16); color: var(--violet); }

.hl-badge[data-status="in_progress"],
.hl-badge[data-status="active"] { background: rgba(47, 211, 196, 0.16); color: var(--teal); }

.hl-badge[data-status="completed"],
.hl-badge[data-status="paid"],
.hl-badge[data-status="win"] { background: rgba(182, 226, 74, 0.16); color: var(--lime); }

.hl-badge[data-status="forfeited"],
.hl-badge[data-status="cancelled"],
.hl-badge[data-status="overdue"],
.hl-badge[data-status="loss"] { background: rgba(255, 90, 77, 0.16); color: var(--alert); }

.hl-badge[data-status="waived"] { background: rgba(245, 195, 75, 0.16); color: var(--gold); }

/* Position color-coding (paired with .hl-badge--plain below, and
   apps.core.templatetags.badges.position_slug which turns Player's free
   -text position into one of these three curated slugs - anything else
   falls back to the plain neutral badge). */
.hl-badge[data-position="guard"] { background: rgba(47, 211, 196, 0.16); color: var(--teal); }
.hl-badge[data-position="forward"] { background: rgba(182, 226, 74, 0.16); color: var(--lime); }
.hl-badge[data-position="center"] { background: rgba(245, 195, 75, 0.16); color: var(--gold); }

/* Modifier for a chip that labels a plain attribute (e.g. a player's
   position) rather than a live/changing status - drops the leading dot,
   which otherwise reads as a status indicator. */
.hl-badge--plain::before { content: none; }

/* ─── Empty state ────────────────────────────────────────────────── */
.hl-empty {
  text-align: center;
  padding: var(--space-8) var(--space-4);
  color: var(--text-muted);
}

.hl-empty .icon {
  display: block;
  margin: 0 auto var(--space-3);
  opacity: 0.6;
}

.hl-empty p {
  color: var(--text-muted);
  margin: 0 0 var(--space-4);
}

.hl-empty .hl-btn {
  margin-top: var(--space-2);
}

/* ─── Header band (league/team/player identity) ─────────────────── */
.hl-header-band {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
  flex-wrap: wrap;
}

.hl-avatar {
  width: 64px;
  height: 64px;
  border-radius: 14px;
  object-fit: cover;
  background: var(--bg-card);
  border: 1px solid var(--border);
  flex-shrink: 0;
  transition: border-color 0.15s ease;
}

/* Smaller variant for inline use (table rows, list items) - same shape,
   scaled down radius to match. Pair with `.hl-avatar-placeholder` below
   when there's no image to show. */
.hl-avatar--sm {
  width: 36px;
  height: 36px;
  border-radius: 8px;
}

.hl-avatar-placeholder {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text-muted);
  flex-shrink: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
}

/* Colored-initials monogram variant (apps.core.templatetags.badges'
   `initials`/`accent_rotate` filters) shown in place of a logo_url/
   photo_url that hasn't been uploaded - a deterministic rotation through
   the Supporting accents (docs/color-palette.md) so a list of rows reads
   as lively/distinct rather than a wall of identical gray circles. Team
   rows pass an inline `style` for Team.primary_color instead, when set,
   which wins by source order over these attribute rules. */
.hl-avatar-placeholder[data-accent="teal"] { background: rgba(47, 211, 196, 0.16); color: var(--teal); border-color: rgba(47, 211, 196, 0.35); }
.hl-avatar-placeholder[data-accent="violet"] { background: rgba(155, 123, 255, 0.16); color: var(--violet); border-color: rgba(155, 123, 255, 0.35); }
.hl-avatar-placeholder[data-accent="lime"] { background: rgba(182, 226, 74, 0.16); color: var(--lime); border-color: rgba(182, 226, 74, 0.35); }
.hl-avatar-placeholder[data-accent="gold"] { background: rgba(245, 195, 75, 0.16); color: var(--gold); border-color: rgba(245, 195, 75, 0.35); }
.hl-avatar-placeholder[data-accent="coral"] { background: rgba(255, 90, 77, 0.16); color: var(--alert); border-color: rgba(255, 90, 77, 0.35); }

/* Player identity link (avatar + name) used inline in table rows - e.g.
   the league players directory. Name stays the default text color until
   hover, unlike `.hl-link`, since it's the primary cell content rather
   than a secondary "view more" link. */
.hl-player-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
}

.hl-player-link:hover {
  color: var(--primary);
}

.hl-player-link:hover .hl-avatar,
.hl-player-link:hover .hl-avatar--sm {
  border-color: var(--primary);
}

/* ─── Clickable card (season/team cards etc.) ───────────────────── */
.hl-card-link {
  display: block;
  text-decoration: none;
  transition: border-color 0.15s ease;
}

.hl-card-link:hover {
  border-color: var(--primary);
}

.hl-card-link .hl-badge {
  margin-bottom: var(--space-2);
}

.hl-card-link h3 {
  margin-top: var(--space-1);
}

/* ─── Sponsor card ───────────────────────────────────────────────── */
.hl-sponsor-card {
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.hl-sponsor-card:hover {
  border-color: var(--border-strong);
  transform: translateY(-2px);
  box-shadow: 0 12px 28px -16px rgba(0, 0, 0, 0.5);
}

.hl-sponsor-logo-box {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 96px;
  padding: var(--space-4);
  background: var(--bg-raised);
  border-bottom: 1px solid var(--border);
}

.hl-sponsor-logo {
  max-height: 56px;
  max-width: 100%;
  object-fit: contain;
}

.hl-sponsor-logo-placeholder {
  color: var(--text-muted);
}

.hl-sponsor-card-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  flex: 1;
}

.hl-sponsor-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
}

.hl-sponsor-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.hl-sponsor-website-btn {
  margin-top: auto;
  padding: 8px 14px;
  font-size: 13px;
  justify-content: center;
}

.hl-badge[data-tier="gold"] { background: rgba(245, 195, 75, 0.16); color: var(--gold); }
.hl-badge[data-tier="silver"] { background: rgba(179, 169, 156, 0.2); color: var(--text-secondary); }
.hl-badge[data-tier="bronze"] { background: rgba(156, 67, 16, 0.24); color: var(--orange-deep); }

/* ─── Filter tabs (division filters, etc.) ──────────────────────── */
.hl-filter-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.hl-filter-tab {
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  color: var(--text-secondary);
  transition: border-color 0.15s ease, color 0.15s ease;
}

.hl-filter-tab:hover {
  border-color: var(--primary);
  color: var(--text);
}

.hl-filter-tab[aria-current="page"] {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
}

.hl-filter-tab[aria-current="page"]:hover {
  color: var(--on-primary);
}

/* ─── Filter bar (search input + dropdown filters, e.g. the players
   directory) - a plain GET form, no htmx/JS required; the position
   `<select>` auto-submits on change via a template-level `onchange` as
   progressive enhancement, the "Filter" button is the no-JS fallback ─── */
.hl-filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.hl-filter-bar-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--text-muted);
}

.hl-filter-bar-clear {
  align-self: center;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  text-decoration: underline;
}

.hl-filter-bar-clear:hover {
  color: var(--primary);
}

.hl-input,
.hl-select {
  min-width: 200px;
  padding: 9px 12px;
  border-radius: 8px;
  border: 1px solid var(--border-strong);
  background: var(--bg-card);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.2;
}

.hl-input::placeholder {
  color: var(--text-muted);
}

.hl-input:focus,
.hl-select:focus {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
  border-color: var(--primary);
}

/* Narrower variant for a control sitting inline inside a table row (e.g.
   the per-player award-assign form) instead of a standalone filter bar. */
.hl-input--inline,
.hl-select--inline {
  min-width: 0;
  width: auto;
  padding: 6px 8px;
  font-size: 13px;
}

.hl-inline-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

/* ─── Stat tiles (career/season averages) ───────────────────────── */
.hl-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  gap: var(--space-3);
}

.hl-stat-tile {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: var(--space-3);
  text-align: center;
}

.hl-stat-tile .value {
  display: block;
  font-family: var(--font-mono);
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
}

.hl-stat-tile .label {
  display: block;
  margin-top: 2px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}

/* ─── Announcement list ──────────────────────────────────────────── */
.hl-announcement-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.hl-announcement-list li {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* ─── Error pages (404/403/500) ─────────────────────────────────── */
.hl-error-page {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  max-width: 480px;
  min-height: 60vh;
  overflow: hidden;
}

/* Large background numeral watermark - templates/core/_ball_motif.html,
   reused here purely as decoration (context-free, so it's also safe on
   500.html which renders without a request). Sits behind the copy, never
   intercepts clicks/taps. */
.hl-error-page .hl-ball-motif {
  position: absolute;
  top: 50%;
  left: -60px;
  transform: translateY(-50%);
  color: var(--primary);
  opacity: 0.07;
  z-index: 0;
}

.hl-error-page > * {
  position: relative;
  z-index: 1;
}

.hl-error-page .hl-eyebrow {
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 3px;
}

.hl-error-page h1 {
  margin: var(--space-2) 0 var(--space-3);
}

.hl-error-page p {
  margin-bottom: var(--space-5);
}

@media (max-width: 560px) {
  .hl-error-page .hl-ball-motif {
    left: -90px;
  }
}

/* ─── Site header (brand lockup) ─────────────────────────────────── */
.site-header {
  display: flex;
  align-items: center;
  padding: 20px clamp(20px, 5vw, 64px);
  border-bottom: 1px solid var(--border);
}

.site-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
}

.site-brand-name {
  font-family: "Saira Condensed", sans-serif;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  font-size: 17px;
  color: var(--text);
}

.site-brand-name .accent {
  color: var(--primary);
}

/* ─── Beta label ──────────────────────────────────────────────────
   Appended next to every "Hoopers Lists" wordmark instance (site header,
   landing header/mobile-nav/footer, league sidebar nav) while the product
   is in beta - one shared class so removing beta-status later is a single
   edit, not a hunt through each template. Fixed px size (not em-scaled to
   the wordmark it sits beside) so it reads the same small "meta" chip at
   every size the wordmark appears at, from the 12px league sidebar brand
   up to the 22px landing header. Neutral/muted, not accent-colored - it's
   a status label, not a call to action competing with --primary. */
.hl-beta-tag {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  /* Nudged down from dead-center in the brand row - reads more like a
     badge tucked under the wordmark's baseline than a piece of the
     lockup competing with the icon for vertical center. */
  transform: translateY(3px);
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-muted);
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  padding: 2px 5px;
  line-height: 1;
  white-space: nowrap;
}

/* ─── Site footer (tagline) ──────────────────────────────────────── */
.site-footer {
  border-top: 1px solid var(--border);
  padding: 24px clamp(20px, 5vw, 64px) 28px;
}

.site-footer p {
  margin: 0;
  font-size: 12px;
  color: var(--text-muted);
}

.site-footer p + p {
  margin-top: 4px;
}

/* ─── Basketball-seam watermark (templates/core/_ball_motif.html) ────
   Shared default for the reusable motif partial - callers layer their
   own positioning class (e.g. .lh-hero-badge, .hl-league-nav-identity
   -motif) on top; this just sets the baseline color/opacity/pointer-
   events so a bare {% include %} with no extra class still looks right. */
.hl-ball-motif {
  color: var(--text);
  opacity: 0.08;
  pointer-events: none;
}

/* ─── League nav (bottom tab bar on mobile, sidebar on desktop) ─────
   Reusable component - any league-scoped public page can
   {% include "leagues/_public_nav.html" with active="..." %} to get it,
   not just league_home. Mirrors reference/preview/dashboard.html's
   bottom-nav -> sidebar breakpoint (min-width: 900px), rebuilt with this
   project's own .hl-* naming/tokens instead of the mockup's classes. */
.hl-league-nav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  display: flex;
  align-items: stretch;
  gap: 2px;
  padding: 0 6px;
  background: var(--bg-raised);
  border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom, 0);
  box-shadow: 0 -8px 24px -16px rgba(0, 0, 0, 0.6);
}

.hl-league-nav-brand {
  display: none;
}

/* League identity chip (logo/initials + name + season status) - sidebar
   only (≥900px, see media query below). Below that width the bottom tab
   bar has no room for it, and the page's own header/breadcrumbs already
   carry the league's name, so it stays hidden rather than cramped. */
.hl-league-nav-identity {
  display: none;
}

.hl-league-nav-item {
  position: relative;
  box-sizing: border-box;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 56px;
  padding: 8px 4px 10px;
  border-radius: 10px;
  color: var(--text-muted);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.15s ease, background-color 0.15s ease, transform 0.15s ease;
}

.hl-league-nav-item:active {
  color: var(--text);
  transform: scale(0.96);
}

.hl-league-nav-item .icon {
  stroke: currentColor;
}

/* Wraps each nav item's icon (apps.core.templatetags.icons `{% icon %}`)
   so the sidebar variant (media query below) can give it its own tinted
   background chip instead of a flat muted glyph - mirrors
   league_home.css's .lh-glance-icon tiles. Bare/unstyled at mobile
   widths (the bottom tab bar keeps today's plain currentColor icon) so
   this is purely additive there. */
.hl-league-nav-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: transform 0.15s ease;
}

.hl-league-nav-item .label {
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.hl-league-nav-item.active {
  color: var(--primary);
}

.hl-league-nav-item.active .label {
  font-weight: 600;
}

/* Small dot under the active tab's icon (mobile bar only - the desktop
   sidebar gets its own left-edge accent bar instead, see the
   min-width: 900px block). Scales in from nothing so it reads as a
   marker landing on the current tab rather than a static bullet. */
.hl-league-nav-item.active::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 4px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--primary);
  transform: translateX(-50%) scale(0);
}

@media (prefers-reduced-motion: no-preference) {
  .hl-league-nav-item.active .hl-league-nav-icon {
    animation: hl-nav-icon-pop 0.28s cubic-bezier(0.34, 1.56, 0.64, 1);
  }

  .hl-league-nav-item.active::after {
    animation: hl-nav-dot-pop 0.28s 0.05s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hl-league-nav-item.active::after {
    transform: translateX(-50%) scale(1);
  }
}

@keyframes hl-nav-icon-pop {
  from { transform: scale(0.7); }
  to { transform: scale(1); }
}

@keyframes hl-nav-dot-pop {
  from { transform: translateX(-50%) scale(0); }
  to { transform: translateX(-50%) scale(1); }
}

/* "More" toggle + flyout - collapses Schedule/Players out of the mobile
   tab row so it caps at 5 visible slots (League, Leaders, Standings,
   Sponsors, More). Base rules here are the mobile shape; the popover
   positioning lives in the max-width: 899px block below, and the
   min-width: 900px block turns this back into an ordinary pair of sidebar
   rows for desktop, where there's no need to hide anything behind a
   toggle. */
.hl-league-nav-more {
  flex: 1;
  position: relative;
  display: flex;
}

.hl-league-nav-more-toggle {
  flex: 1;
  width: 100%;
  background: none;
  border: none;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.hl-league-nav-more-toggle .hl-league-nav-icon {
  transition: transform 0.2s ease, color 0.15s ease;
}

.hl-league-nav-more-toggle.is-open {
  color: var(--text);
}

.hl-league-nav-more-toggle.is-open .hl-league-nav-icon {
  transform: rotate(90deg);
}

.hl-league-nav-more-panel {
  display: flex;
  flex-direction: column;
}

/* The "back to the platform" row breaks out of the league entirely, so
   it reads as a separate exit rather than one more league page in the
   same list - a hairline divider + extra top space, in both the mobile
   flyout and (once .hl-league-nav-more collapses to display: contents,
   see the min-width: 900px block) the desktop sidebar's plain list.
   Selector is scoped one level down from .hl-league-nav-item's own
   padding rules so it wins on specificity without !important. */
.hl-league-nav-more-panel .hl-league-nav-item.hl-league-nav-more-panel-exit {
  margin-top: 4px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

/* Alpine x-transition hooks for the flyout (see
   leagues/_public_nav.html) - fade + rise on open, reverse on close.
   Durations only apply under prefers-reduced-motion: no-preference so a
   reduced-motion visitor just gets an instant show/hide. */
.hl-nav-more-enter-start,
.hl-nav-more-leave-end {
  opacity: 0;
  transform: translateY(6px) scale(0.97);
}

.hl-nav-more-enter-end,
.hl-nav-more-leave-start {
  opacity: 1;
  transform: translateY(0) scale(1);
}

@media (prefers-reduced-motion: no-preference) {
  .hl-nav-more-enter {
    transition: opacity 0.16s ease, transform 0.16s ease;
  }

  .hl-nav-more-leave {
    transition: opacity 0.12s ease, transform 0.12s ease;
  }
}

/* Page content needs bottom clearance so the fixed tab bar never covers
   the last section - see .hl-league-content below. */
.hl-league-content {
  padding-bottom: 76px;
}

/* templates/base/base.html's global .site-footer is a sibling of <main>
   (.hl-league-shell renders INSIDE <main> - see base.html: <main>{% block
   content %}{% endblock %}</main><footer class="site-footer">...), so the
   footer directly follows <main>, not .hl-league-shell itself - hence
   :has() below rather than a plain adjacent-sibling selector.
   league_public_base.html only overrides site_header, not site_footer, to
   keep the copyright/tagline reachable - .hl-league-nav-brand above is
   display:none below 900px, so without this the footer is the only
   Hoopers Lists branding left on a mobile league page. Below 900px
   .hl-league-nav is position:fixed same as above, so it sits on top of
   whatever is at the true bottom of the page - .hl-league-content already
   reserves clearance for the page content itself, but the footer that
   follows it needs its own, identical reservation or the fixed tab bar
   covers it too. Scoped so only a public league page's footer is
   affected; the landing/marketing footer (<main> has no .hl-league-shell)
   is untouched. */
@media (max-width: 899px) {
  main:has(.hl-league-shell) + .site-footer {
    padding-bottom: 76px;
  }

  /* Popover anchored above the tab bar, right-aligned under the More
     button (the last slot in the row). x-cloak/x-show on the element
     itself (see leagues/_public_nav.html) handle show/hide; this is just
     position + card styling for once it's visible. */
  .hl-league-nav-more-panel {
    position: absolute;
    right: 8px;
    bottom: calc(100% + 10px);
    min-width: 190px;
    gap: 2px;
    background: var(--bg-raised);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 6px;
    box-shadow: 0 12px 32px -12px rgba(0, 0, 0, 0.65);
  }

  /* Rows inside the flyout read as a dropdown menu (icon beside label),
     not the tab bar's icon-over-label layout - same row shape the
     sidebar uses one breakpoint early, since this is already a vertical
     list here. */
  .hl-league-nav-more-panel .hl-league-nav-item {
    flex: none;
    flex-direction: row;
    justify-content: flex-start;
    min-height: 0;
    width: 100%;
    padding: 10px;
    border-radius: 8px;
    gap: 10px;
  }

  /* One plain neutral chip for every flyout icon - no per-item accent
     hue. Color is left to inherit (no `color` set here) so it still
     tracks the row's own state (muted at rest, primary when active). */
  .hl-league-nav-more-panel .hl-league-nav-icon {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: rgba(179, 169, 156, 0.12);
  }

  .hl-league-nav-more-panel .hl-league-nav-icon .icon {
    width: 16px;
    height: 16px;
  }

  .hl-league-nav-more-panel .hl-league-nav-item .label {
    font-size: 13px;
    font-weight: 500;
    white-space: normal;
  }

  /* Row layout has no room for the tab bar's under-icon dot - the
     background tint below is indicator enough here. */
  .hl-league-nav-more-panel .hl-league-nav-item.active::after {
    display: none;
  }

  .hl-league-nav-more-panel .hl-league-nav-item:active {
    background: rgba(245, 241, 236, 0.06);
  }

  .hl-league-nav-more-panel .hl-league-nav-item.active {
    background: rgba(242, 106, 16, 0.12);
    color: var(--primary);
  }
}

@media (min-width: 900px) {
  .hl-league-shell {
    display: grid;
    grid-template-columns: 220px 1fr;
    /* Was --space-6 (32px) - bumped for more breathing room between the
       sidebar and the page content on desktop (user-requested spacing
       pass), same reasoning as the .hl-page mobile padding bump below. */
    gap: var(--space-8);
    align-items: start;
    max-width: 1200px;
    margin: 0 auto;
    padding: var(--space-7) clamp(20px, 4vw, 64px);
  }

  .hl-league-nav {
    position: sticky;
    top: var(--space-5);
    left: auto;
    right: auto;
    bottom: auto;
    z-index: auto;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    background: var(--bg-raised);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: var(--space-4) var(--space-3);
  }

  .hl-league-nav-brand {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 8px;
    margin-bottom: var(--space-3);
    text-decoration: none;
    opacity: 0.7;
  }

  .hl-league-nav-brand-name {
    font-family: var(--font-heading);
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    font-size: 12px;
    color: var(--text);
  }

  .hl-league-nav-brand-name .accent {
    color: var(--primary);
  }

  /* League identity chip - the specific league's own logo/initials +
     name + current season status, so context isn't lost once a visitor
     clicks off League Home into Standings/Schedule/Players (those pages
     only had the generic Hoopers Lists wordmark above before this). */
  .hl-league-nav-identity {
    display: flex;
    align-items: center;
    gap: 10px;
    position: relative;
    overflow: hidden;
    padding: var(--space-2) 8px;
    margin: 0 -8px var(--space-4);
    border-radius: 8px;
    text-decoration: none;
  }

  .hl-league-nav-identity:hover {
    background: rgba(245, 241, 236, 0.04);
  }

  .hl-league-nav-identity-motif {
    position: absolute;
    right: -18px;
    top: -22px;
    color: var(--primary);
  }

  .hl-league-nav-identity-text {
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }

  .hl-league-nav-identity-name {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 13px;
    color: var(--text);
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .hl-league-nav-identity .hl-badge {
    padding: 1px 8px;
    font-size: 9px;
  }

  .hl-league-nav-item {
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border-radius: 8px;
  }

  .hl-league-nav-item .label {
    font-size: 13px;
    font-weight: 500;
  }

  /* One plain neutral chip for every sidebar icon (sidebar only) - no
     per-destination accent hue. `color` is left unset so the glyph
     inherits the row's own state color (muted at rest, primary when
     active, text on hover) instead of a fixed tint. */
  .hl-league-nav-icon {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    background: rgba(179, 169, 156, 0.12);
  }

  .hl-league-nav-icon .icon {
    width: 18px;
    height: 18px;
  }

  .hl-league-nav-item:hover {
    background: rgba(245, 241, 236, 0.04);
    color: var(--text);
    transform: translateX(2px);
  }

  .hl-league-nav-item.active {
    background: rgba(242, 106, 16, 0.12);
    color: var(--primary);
  }

  /* Mobile's active-tab dot (base rules above) gives way to a left-edge
     accent bar here - more legible against a full-width row than a small
     dot would be. */
  .hl-league-nav-item.active::after {
    display: none;
  }

  .hl-league-nav-item.active::before {
    content: "";
    position: absolute;
    left: -13px;
    top: 50%;
    width: 3px;
    height: 60%;
    border-radius: 0 3px 3px 0;
    background: var(--primary);
    transform: translateY(-50%) scaleY(0);
    transform-origin: center;
  }

  @media (prefers-reduced-motion: no-preference) {
    .hl-league-nav-item.active::before {
      animation: hl-nav-bar-grow 0.22s ease forwards;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .hl-league-nav-item.active::before {
      transform: translateY(-50%) scaleY(1);
    }
  }

  @keyframes hl-nav-bar-grow {
    from { transform: translateY(-50%) scaleY(0); }
    to { transform: translateY(-50%) scaleY(1); }
  }

  /* The mobile More toggle/flyout collapses back into two ordinary
     sidebar rows here - there's no space constraint on desktop, so
     nothing should be hidden behind a click. display: contents drops
     .hl-league-nav-more itself from the box tree so its panel's children
     (Schedule/Players) sit directly in .hl-league-nav's own column flow,
     spaced by that column's existing gap instead of a nested box. */
  .hl-league-nav-more {
    display: contents;
  }

  .hl-league-nav-more-toggle {
    display: none;
  }

  .hl-league-nav-more-panel {
    /* leagues/_public_nav.html's x-show sets an inline display: none for
       the closed (mobile-default) state - !important is required to win
       over that inline style so the panel always renders at this
       breakpoint. */
    display: flex !important;
    flex-direction: column;
    gap: 4px;
  }

  .hl-league-content {
    padding-bottom: 0;
  }
}

/* Tablet/large-phone pass (481-899px, below the sidebar breakpoint but
   above the tightened <=480px pass below) - a touch more vertical
   breathing room than the plain .hl-page default, per the user-requested
   mobile spacing pass. */
@media (max-width: 899px) {
  .hl-page {
    padding-top: var(--space-7);
    padding-bottom: var(--space-7);
  }
}

/* ─── Mobile pass (schedule/standings/box scores are the pages most
   likely opened one-handed from a gym sideline - docs/
   ui_content_recommendations.md §11) ─────────────────────────────── */
@media (max-width: 480px) {
  .hl-page {
    padding-top: var(--space-6);
    padding-bottom: var(--space-6);
  }

  .hl-header-band {
    flex-direction: column;
    align-items: flex-start;
  }

  .hl-section-head {
    flex-direction: column;
    align-items: stretch;
  }

  .hl-section-head .hl-btn {
    align-self: flex-start;
  }

  .hl-card-grid {
    grid-template-columns: 1fr;
  }

  .hl-table th,
  .hl-table td {
    padding: 10px;
  }

  .hl-filter-bar {
    flex-direction: column;
    align-items: stretch;
  }

  .hl-input,
  .hl-select {
    min-width: 0;
    width: 100%;
  }
}

/* ─── Stackable table (card layout on narrow screens) ───────────────
   Opt-in via `.hl-table--stack` on `.hl-table` - the schedule page uses
   this since its rows carry 5 columns (date, matchup, venue, status,
   score) that get unreadably cramped in a horizontally-scrolled table
   on a phone. Each `<td>` needs a `data-label` attribute; `<thead>` is
   hidden (not removed, so screen readers relying on table semantics as
   plain text still get the labels via the visible `data-label`
   equivalents rendered per cell). ─────────────────────────────────── */
@media (max-width: 640px) {
  .hl-table--stack thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
    padding: 0;
    margin: -1px;
  }

  .hl-table--stack,
  .hl-table--stack tbody,
  .hl-table--stack tr,
  .hl-table--stack td {
    display: block;
    width: 100%;
    box-sizing: border-box;
  }

  .hl-table--stack tbody tr {
    padding: var(--space-2) var(--space-4);
    border-bottom: 1px solid var(--border);
  }

  .hl-table--stack tbody tr:last-child {
    border-bottom: none;
  }

  .hl-table--stack .hl-table-group-row {
    padding: 0;
  }

  .hl-table--stack .hl-table-group-row td {
    padding: 6px var(--space-4);
  }

  .hl-table--stack .hl-table-group-row td::before {
    content: none;
  }

  /* Label + value stay in normal inline flow (not flex) so a long value
     (full date/time, venue name) wraps onto a second line instead of
     overflowing the card and scrolling the rest of the row out of view. */
  .hl-table--stack td {
    padding: 3px 0;
    border-bottom: none;
    text-align: left;
  }

  .hl-table--stack td::before {
    content: attr(data-label) ": ";
    font-family: var(--font-body);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--text-muted);
  }

  /* A cell with no meaningful column header (e.g. a trailing "view more"
     link column) opts out of the label prefix entirely via data-label=""
     rather than showing a stray ": ". */
  .hl-table--stack td[data-label=""]::before {
    content: none;
  }

  .hl-table--stack .hl-schedule-matchup {
    padding-top: 4px;
    padding-bottom: 4px;
  }

  .hl-table--stack .hl-schedule-matchup::before {
    content: none;
  }

  .hl-table--stack .hl-schedule-team {
    font-family: var(--font-heading);
    font-size: 15px;
  }
}
