/* Datalva design system — extracted from templates/base.html 2026-09-10.
   Every page's CSS variables, shared components and table/chart styling.
   Page-specific rules stay in that page's own template. */
:root {
  /* ── Brand palette (docs/design.md §8) ─────────────────────────── */
  --blue:        #137DC5;   /* primary blue: headings, primary UI       */
  --blue-2:      #2199EA;   /* secondary blue: accents, hover, interact  */
  --ink:         #111111;   /* dark text                                 */
  --gray-light:  #EEEEEE;   /* light gray: page + table backgrounds      */
  --white:       #FFFFFF;
  --border-gray: #D4D4D4;   /* borders / dividers                        */

  /* ── Semantic tokens ──────────────────────────────────────── */
  --bg:        var(--gray-light);
  --surface:   var(--white);
  --text:      var(--ink);
  --text-dim:  #5A5A5A;
  --border:    var(--border-gray);
  --heading:   var(--blue);
  --accent:    var(--blue-2);
  --radius:    8px;
  --shadow:    0 1px 3px rgba(17,17,17,.10);

  /* ── Legacy aliases (per-page inline styles still resolve) ── */
  --gold:       var(--blue);
  --gold-light: var(--blue);
  --gold-mid:   var(--blue-2);
  --navy-dark:  var(--white);
  --navy-mid:   #DCEBF8;
  --navy-black: var(--gray-light);
  --navy-hover: #F3F7FB;

  /* ── Position colours — distinct but palette-integrated ───── */
  --pos-g-bg:   #D6EAF8;  --pos-g-text: #0E5E96;   /* Guard  – blue  */
  --pos-f-bg:   #D8F0DE;  --pos-f-text: #1E7E34;   /* Forward – green */
  --pos-c-bg:   #FBE7CE;  --pos-c-text: #B5670B;   /* Center – amber  */
  --pos-hc-bg:  #E4E4E4;  --pos-hc-text: #4A4A4A;  /* Head coach – gray */

  /* ── Subcategory colours ──────────────────────────────────────
     Each of the three subcategories within a position gets its own colour,
     but all three stay inside that position's family (Guards blue, Forwards
     green, Centers orange) so the position is still readable at a glance and
     the subcategory refines it rather than competing with it. Ordered dark →
     mid → light, matching the order the labels are declared in
     db/schema.py::SUBCATEGORIES, so the Nth button always gets the Nth shade
     and a vocabulary change needs no CSS edit. */
  --sub-g-1-bg: #0E5E96;  --sub-g-1-text: #FFFFFF;   /* Guards – deep blue    */
  --sub-g-2-bg: #57A5D8;  --sub-g-2-text: #06304F;   /* Guards – mid blue     */
  --sub-g-3-bg: #CDE6F7;  --sub-g-3-text: #0B4A78;   /* Guards – pale blue    */
  --sub-f-1-bg: #1B6B32;  --sub-f-1-text: #FFFFFF;   /* Forwards – deep green */
  --sub-f-2-bg: #5EAE72;  --sub-f-2-text: #0C3517;   /* Forwards – mid green  */
  --sub-f-3-bg: #D3EDDA;  --sub-f-3-text: #1B6B32;   /* Forwards – pale green */
  --sub-c-1-bg: #A85B08;  --sub-c-1-text: #FFFFFF;   /* Centers – deep orange */
  --sub-c-2-bg: #E5943C;  --sub-c-2-text: #3D2103;   /* Centers – mid orange  */
  --sub-c-3-bg: #FBE3C6;  --sub-c-3-text: #A85B08;   /* Centers – pale orange */

  /* ── Player unit classification badges (docs/design.md §2) ─────── */
  --unit-first-bg:   #137DC5;  --unit-first-text:  #FFFFFF;
  --unit-second-bg:  #DCEBF8;  --unit-second-text: #0E5E96;
  --unit-dotan-bg:   #F1E1C6;  --unit-dotan-text:  #8A5A12;

  /* ── Teams board status vocabulary ─────────────────────────────
     Readiness (manual traffic light), "planned, not synced" (amber) and the
     player-search marker. Each owns its colour family; nothing else borrows
     them. `-strong` is the dot/edge, `-bg` the header wash, `-line` its rule,
     `-text` a label on that wash (all ≥4.5:1 on their own -bg). */
  --ready-red-strong:    #C0392B;  --ready-red-bg:    #FCEEEC;
  --ready-red-line:      #E7BDB7;  --ready-red-text:  #8E2A20;
  --ready-yellow-strong: #C9971F;  --ready-yellow-bg: #FDF6E3;
  --ready-yellow-line:   #E3D096;  --ready-yellow-text: #735912;
  --ready-green-strong:  #2E8B47;  --ready-green-bg:  #ECF7F0;
  --ready-green-line:    #B4DCC0;  --ready-green-text:  #1B6B33;
  --star-gold:   #F5C518;  /* a starred team's star (Teams boards) */
  --star-gold-line: #E3C25A;  /* a starred team's card edge, under its gold wash */
  --bench-half:  #0F766E;   /* teal: a bench player scoring half (Teams boards) */
  --plan-bg:     #FFF6DC;  --plan-line: #E0B84A;  --plan-text: #7A5F14;
  --search-hit:  #FFEB3B;
  --danger-text: #A5342F;
  --hover-bg:    #E8F3FB;
  --focus-ring:  0 0 0 2px var(--surface), 0 0 0 4px var(--accent);
}

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

html, body {
  min-height: 100vh;
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
}

/* ── Top bar ─────────────────────────────────────────────────── */
.topbar {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 6px 28px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 100;
  box-shadow: 0 1px 4px rgba(17,17,17,.05);
}
.topbar a.logo-link { display: flex; align-items: center; text-decoration: none; }
.topbar img.logo-icon { height: 42px; width: 42px; object-fit: contain; }
.topbar a.page-title {
  font-size: 1rem;
  font-weight: 700;
  color: var(--heading);
  letter-spacing: .03em;
  text-transform: uppercase;
  text-decoration: none;
}
.topbar a.page-title:hover { color: var(--blue); }

/* ── Competition theme ─────────────────────────────────────────
   A page about one competition wears its colour: EuroLeague orange, EuroCup
   blue (body.theme-*, set by api/pages.py::_page_context for themed pages
   only). Each theme fills the same four slots — the colour itself, a strong
   shade for text/chips (≥4.5:1 on white), a pale page wash and a border
   line — so components read `--comp*` and never name a competition. */
.theme-euroleague {
  --comp:        #EE7A1F;
  --comp-strong: #B4530A;
  --comp-bg:     #FFF4EA;
  --comp-line:   #F3BE8F;
}
.theme-eurocup {
  --comp:        #137DC5;
  --comp-strong: #0E5E96;
  --comp-bg:     #EDF5FC;
  --comp-line:   #A6CDEB;
}
body.theme-euroleague, body.theme-eurocup { --bg: var(--comp-bg); background: var(--bg); }
.theme-euroleague .topbar, .theme-eurocup .topbar { border-bottom: 3px solid var(--comp); }
.theme-euroleague .card, .theme-eurocup .card { border-color: var(--comp-line); }
.comp-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  text-decoration: none;
  cursor: pointer;
  transition: filter .15s, transform .12s;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--comp-strong);
  color: var(--white);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.comp-chip:hover { filter: brightness(1.15); transform: translateY(-1px); }
.comp-chip:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.comp-chip-swap { font-size: .8rem; opacity: .8; }
/* ── Season selector ─────────────────────────────────────────── */
.season-picker { position: relative; flex-shrink: 0; }
.season-toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: inherit;
  padding: 5px 10px 5px 11px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color .15s, background .15s;
}
.season-toggle:hover:not(:disabled) { border-color: var(--accent); background: #E8F3FB; }
.season-toggle:disabled { cursor: default; color: inherit; }
.season-toggle .season-current { font-size: .78rem; font-weight: 700; }
.season-toggle .season-caret { color: var(--text-dim); transition: transform .15s; }
.season-toggle[aria-expanded="true"] .season-caret { transform: rotate(180deg); }
.season-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 120;
  min-width: 100%;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 6px 18px rgba(17,17,17,.16);
  padding: 5px;
}
.season-menu[hidden] { display: none; }
.season-opt {
  font-family: inherit;
  font-size: .8rem;
  font-weight: 700;
  padding: 6px 11px;
  border-radius: 5px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  white-space: nowrap;
  text-align: left;
  transition: all .15s;
}
.season-opt:hover { background: #E8F3FB; color: var(--blue); }
.season-opt.active { background: var(--blue); border-color: var(--blue); color: #fff; }
.season-opt .no-data-dot {
  display: inline-block;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: #D08A0C;
  margin-left: 5px;
  vertical-align: middle;
}

/* Banner shown when the chosen season has not been scraped yet. */
.season-empty {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid #E8C88A;
  border-left: 3px solid #D08A0C;
  background: #FDF6E7;
  border-radius: 6px;
  padding: 11px 14px;
  margin-bottom: 18px;
  font-size: .82rem;
  color: #7A5310;
}
.season-empty strong { color: #5C3E0B; }
.season-empty .switch {
  margin-left: auto;
  flex-shrink: 0;
  font-family: inherit;
  font-size: .76rem;
  font-weight: 700;
  padding: 5px 12px;
  border-radius: 4px;
  border: 1px solid #D08A0C;
  background: transparent;
  color: #7A5310;
  cursor: pointer;
}
.season-empty .switch:hover { background: #D08A0C; color: #fff; }

/* ── Login widget ─────────────────────────────────────────────── */
.auth-widget {
  position: relative;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}
.auth-label {
  font-size: .78rem;
  font-weight: 700;
  color: var(--text-dim);
  white-space: nowrap;
}
.auth-label.logged-in { color: var(--blue); }
.auth-btn {
  font-family: inherit;
  font-size: .72rem;
  font-weight: 700;
  padding: 5px 12px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-dim);
  cursor: pointer;
  white-space: nowrap;
  transition: all .15s;
}
.auth-btn:hover { background: #E8F3FB; color: var(--blue); border-color: var(--accent); }
.auth-btn.logged-in { color: var(--blue); border-color: var(--blue); background: var(--navy-mid); }
.auth-bubble {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 120;
  width: 230px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 6px 18px rgba(17,17,17,.16);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* Author rules always beat the UA stylesheet's [hidden]{display:none} at equal
   specificity, so the plain class rule above alone left a "hidden" bubble
   visible — this re-wins the fight on specificity instead. */
.auth-bubble[hidden] { display: none; }
.auth-field { display: flex; flex-direction: column; gap: 4px; }
.auth-field label {
  font-size: .66rem;
  font-weight: 700;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: .05em;
}
.auth-field input {
  font-family: inherit;
  font-size: .82rem;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
}
.auth-field input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(33,153,234,.18);
}
.auth-submit {
  font-family: inherit;
  font-size: .8rem;
  font-weight: 700;
  padding: 7px 10px;
  border-radius: 5px;
  border: 1px solid var(--blue);
  background: var(--blue);
  color: #fff;
  cursor: pointer;
  transition: background .15s;
}
.auth-submit:hover { background: var(--blue-2); border-color: var(--blue-2); }
.auth-submit:disabled { opacity: .6; cursor: default; }
.auth-msg { font-size: .72rem; color: var(--text-dim); min-height: 14px; }
.auth-msg.error { color: #A5342F; }
.auth-msg.success { color: #186A2C; }

/* ── Main content ─────────────────────────────────────────────── */
.content { padding: 28px 32px; max-width: 1600px; margin: 0 auto; }

/* ── Cards / panels ──────────────────────────────────────────── */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px 24px;
  box-shadow: var(--shadow);
}

/* ── Filter bar ──────────────────────────────────────────────── */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  align-items: flex-end;
  padding: 16px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 20px;
  box-shadow: var(--shadow);
}
.filter-group { display: flex; flex-direction: column; gap: 6px; min-width: 120px; }
.filter-group label {
  font-size: .72rem;
  font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: .05em;
}
.filter-group .value-display {
  font-size: .8rem;
  color: var(--blue);
  font-weight: 700;
}

/* noUiSlider theme override */
.noUi-target {
  background: var(--border);
  border: none;
  box-shadow: none;
  height: 4px;
  margin-top: 4px;
}
.noUi-connect { background: var(--blue); }
.noUi-handle {
  width: 16px !important; height: 16px !important;
  top: -6px !important;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--blue);
  box-shadow: 0 1px 4px rgba(17,17,17,.25);
  cursor: pointer;
}
.noUi-handle::before, .noUi-handle::after { display: none; }

/* Toggle buttons */
.toggle-group { display: flex; gap: 4px; }
.toggle-btn {
  background: var(--white);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: .78rem;
  font-weight: 600;
  padding: 5px 12px;
  border-radius: 4px;
  cursor: pointer;
  transition: all .15s;
  font-family: inherit;
}
.toggle-btn:hover { background: #E8F3FB; color: var(--blue); border-color: var(--accent); }
.toggle-btn.active {
  background: var(--blue);
  border-color: var(--blue);
  color: #fff;
}

/* ── Team selector boxes ─────────────────────────────────────── */
.team-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 8px;
}
.btn-team {
  background: var(--white);
  border: 1px solid var(--border);
  border-left: 3px solid var(--tc, var(--border));
  color: var(--text-dim);
  font-size: .78rem;
  font-weight: 700;
  padding: 7px 10px 7px 8px;
  border-radius: 5px;
  cursor: pointer;
  transition: all .15s;
  font-family: inherit;
  letter-spacing: .04em;
  min-width: 44px;
  text-align: center;
}
.btn-team:hover {
  background: color-mix(in srgb, var(--tc, #137DC5) 12%, #ffffff);
  border-left-color: var(--tc, var(--accent));
  color: var(--text);
}
.btn-team.active {
  background: color-mix(in srgb, var(--tc, #137DC5) 18%, #ffffff);
  border-color: var(--blue);
  border-left-color: var(--tc, var(--blue));
  color: var(--text);
}

/* ── Player selector boxes ───────────────────────────────────── */
.player-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}
.btn-player {
  background: var(--white);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: .72rem;
  font-weight: 600;
  padding: 6px 10px;
  border-radius: 5px;
  cursor: pointer;
  transition: all .15s;
  font-family: inherit;
  width: 130px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: left;
}
.btn-player:hover { background: #E8F3FB; color: var(--text); }
.btn-player.active {
  background: var(--navy-mid);
  border-color: var(--blue);
  color: var(--blue);
}

/* Selected player chips */
.chip-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.chip {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--navy-mid);
  border: 1px solid var(--accent);
  color: var(--blue);
  font-size: .75rem;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 20px;
}
.chip-remove {
  cursor: pointer;
  color: var(--text-dim);
  font-size: .85rem;
  line-height: 1;
  transition: color .1s;
}
.chip-remove:hover { color: #c0392b; }

/* ── Data tables — professional / Excel-like (docs/design.md §1, §6) ── */
/* The wrapper is the scroll container in BOTH axes. That is what makes the
   sticky header below work: `position: sticky` resolves against the nearest
   scrollable ancestor, and a wrapper with `overflow-x: auto` is already one
   (overflow-y computes to auto alongside it), so a header stuck to the viewport
   is not achievable from inside it. Capping the height instead gives every long
   table its own scroll region with the header pinned at the top of it.
   Override per page with --table-max-h where a table should never scroll. */
.table-wrap {
  overflow: auto;
  max-height: var(--table-max-h, calc(100vh - 140px));
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
  box-shadow: var(--shadow);
}
table.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .82rem;
  background: var(--surface);
}
table.data-table thead th {
  background: var(--blue);
  color: #fff;
  font-weight: 700;
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  padding: 10px 12px;
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  border: 1px solid #0E6AAC;
  transition: background .15s;
}
table.data-table thead th:hover { background: var(--accent); }
/* Floating header: stays visible while the table body scrolls under it.
   `border-collapse: collapse` drops the cell borders on a sticky row, so the
   grid lines are redrawn as insets — otherwise the header loses its outline the
   moment it detaches. The solid --blue background is what stops rows showing
   through. */
table.data-table thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  box-shadow: inset 0 1px 0 #0E6AAC, inset 0 -1px 0 #0E6AAC;
}
/* grouped tables: sorting would detach rows from their group headers */
table.data-table.no-sort thead th { cursor: default; }
table.data-table.no-sort thead th:hover { background: var(--blue); }
table.data-table thead th.sorted-asc::after  { content: ' \2191'; color: #fff; }
table.data-table thead th.sorted-desc::after { content: ' \2193'; color: #fff; }
table.data-table tbody tr { transition: background .1s; }
table.data-table tbody tr:nth-child(even) { background: #F7F9FB; }
table.data-table tbody tr:hover { background: var(--navy-mid); }
table.data-table tbody td {
  padding: 9px 12px;
  color: var(--text);
  white-space: nowrap;
  text-align: center;
  border: 1px solid var(--border);
}
table.data-table tbody td.num { text-align: center; font-variant-numeric: tabular-nums; }
/* Group header rows (opponents / duo pages) — prominent (docs/design.md §1) */
table.data-table .group-header td {
  background: var(--gray-light);
  color: var(--blue);
  font-weight: 700;
  font-size: .92rem;
  border-top: 2px solid var(--blue);
}

/* Position badges — prominent (docs/design.md §1, §3) */
.pos-badge {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 4px;
  font-size: .78rem;
  font-weight: 800;
  letter-spacing: .05em;
}
.pos-G { background: var(--pos-g-bg); color: var(--pos-g-text); }
.pos-F { background: var(--pos-f-bg); color: var(--pos-f-text); }
.pos-C { background: var(--pos-c-bg); color: var(--pos-c-text); }
.pos-HC { background: var(--pos-hc-bg); color: var(--pos-hc-text); }
/* Whole-cell position colouring. The badge alone is easy to miss when scanning a
   dense table, so the player cell itself carries the position colour. A cell
   background paints over the row's zebra/hover background, so the tint survives
   both; the left rule keeps the boundary legible where two positions adjoin. */
td.pos-cell {
  font-weight: 600;
  border-left-width: 3px;
  border-left-style: solid;
}
/* Specificity note: `table.data-table tbody td` sets colour and
   `table.data-table .group-header td` sets both colour and background, so these
   rules are qualified with tbody to outrank them. A bare `.result-W` loses to
   the group-header rule and the cell silently renders grey. */
table.data-table tbody td.pos-cell-G, table.sub-table tbody td.pos-cell-G
  { background: var(--pos-g-bg); color: var(--pos-g-text); border-left-color: var(--pos-g-text); }
table.data-table tbody td.pos-cell-F, table.sub-table tbody td.pos-cell-F
  { background: var(--pos-f-bg); color: var(--pos-f-text); border-left-color: var(--pos-f-text); }
table.data-table tbody td.pos-cell-C, table.sub-table tbody td.pos-cell-C
  { background: var(--pos-c-bg); color: var(--pos-c-text); border-left-color: var(--pos-c-text); }
table.data-table tbody td.pos-cell-HC, table.sub-table tbody td.pos-cell-HC
  { background: var(--pos-hc-bg); color: var(--pos-hc-text); border-left-color: var(--pos-hc-text); }
/* Unknown position: no colour rather than a misleading one. */
table.data-table tbody td.pos-cell-none, table.sub-table tbody td.pos-cell-none
  { background: var(--surface); color: var(--text-dim); }
table.data-table tbody tr:hover > td.pos-cell-G { background: color-mix(in srgb, var(--pos-g-bg) 78%, #000000 6%); }
table.data-table tbody tr:hover > td.pos-cell-F { background: color-mix(in srgb, var(--pos-f-bg) 78%, #000000 6%); }
table.data-table tbody tr:hover > td.pos-cell-C { background: color-mix(in srgb, var(--pos-c-bg) 78%, #000000 6%); }

/* Game result — green win / red loss, readable rather than shouty */
td.result-cell { font-weight: 700; font-variant-numeric: tabular-nums; }
table.data-table tbody td.result-W, table.sub-table tbody td.result-W
  { background: #D6F0DC; color: #186A2C; }
table.data-table tbody td.result-L, table.sub-table tbody td.result-L
  { background: #FADBD8; color: #A5342F; }
table.data-table tbody tr:hover > td.result-W { background: #C6E9CF; }
table.data-table tbody tr:hover > td.result-L { background: #F6CBC7; }
/* Same semantics for a bare W/L letter cell. */
.wl-badge {
  display: inline-block;
  min-width: 20px;
  padding: 1px 6px;
  border-radius: 4px;
  font-weight: 800;
  font-size: .74rem;
}
.wl-W { background: #186A2C; color: #fff; }
.wl-L { background: #A5342F; color: #fff; }

/* Position subcategory — secondary info next to the main G/F/C badge.
   Plain text where the subcategory isn't known to the palette (a tag from an
   older vocabulary, say); a coloured chip in the position's own family where
   it is, via .sub-chip below. */
.pos-detail {
  display: inline-block;
  margin-left: 5px;
  font-size: .72rem;
  font-weight: 500;
  color: var(--text-dim);
  vertical-align: middle;
}

/* Subcategory chip — one shade per subcategory, all within the position's
   colour family (see the --sub-* variables). `.sub-G-1` is "the first Guard
   subcategory", indexed off db/schema.py::SUBCATEGORIES, so nothing here
   names a label and a rename is a server-side change only. */
.sub-chip {
  display: inline-block;
  padding: 2px 7px;
  margin-left: 4px;
  border-radius: 4px;
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .02em;
  white-space: nowrap;
  vertical-align: middle;
}
.sub-G-1 { background: var(--sub-g-1-bg); color: var(--sub-g-1-text); }
.sub-G-2 { background: var(--sub-g-2-bg); color: var(--sub-g-2-text); }
.sub-G-3 { background: var(--sub-g-3-bg); color: var(--sub-g-3-text); }
.sub-F-1 { background: var(--sub-f-1-bg); color: var(--sub-f-1-text); }
.sub-F-2 { background: var(--sub-f-2-bg); color: var(--sub-f-2-text); }
.sub-F-3 { background: var(--sub-f-3-bg); color: var(--sub-f-3-text); }
.sub-C-1 { background: var(--sub-c-1-bg); color: var(--sub-c-1-text); }
.sub-C-2 { background: var(--sub-c-2-bg); color: var(--sub-c-2-text); }
.sub-C-3 { background: var(--sub-c-3-bg); color: var(--sub-c-3-text); }

/* Player unit classification badges (docs/design.md §2) */
.unit-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .03em;
  white-space: nowrap;
}
.unit-first  { background: var(--unit-first-bg);  color: var(--unit-first-text); }
.unit-second { background: var(--unit-second-bg); color: var(--unit-second-text); }
.unit-dotan  { background: var(--unit-dotan-bg);  color: var(--unit-dotan-text); }

/* Heat map cells — light theme (green = high, red = low) */
.heat-red   { background: #F6D2D2; color: #A5342F; }
.heat-hi    { background: #FBE3CE; color: #9A5A0E; }
.heat-mid   { background: #ECECEC; color: #444; }
.heat-lo    { background: #E2F3E6; color: #2E7D46; }
.heat-green { background: #C9E8D0; color: #1E7E34; }

/* ── Side-by-side ranked sub-tables (PIR comparison pages) ───── */
.sub-tables-grid { display: grid; gap: 12px; }
.sub-tables-grid.cols-4 { grid-template-columns: repeat(4, 1fr); }
.sub-tables-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 1100px) {
  .sub-tables-grid.cols-4 { grid-template-columns: repeat(2, 1fr); }
  .sub-tables-grid.cols-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .sub-tables-grid.cols-4,
  .sub-tables-grid.cols-3 { grid-template-columns: 1fr; }
}
.sub-table-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
}
.sub-table-card h4 {
  font-size: .72rem;
  font-weight: 700;
  color: var(--blue);
  text-transform: uppercase;
  letter-spacing: .06em;
  padding: 8px 10px 6px;
  background: var(--gray-light);
  border-bottom: 1px solid var(--border);
  text-align: center;
}
.sub-table-card .table-wrap { border: none; border-radius: 0; box-shadow: none; }
table.sub-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .78rem;
}
table.sub-table thead th {
  background: var(--blue);
  color: #fff;
  font-weight: 700;
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  padding: 7px 8px;
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  border: 1px solid #0E6AAC;
  transition: background .15s;
}
table.sub-table thead th:hover { background: var(--accent); }
table.sub-table thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  box-shadow: inset 0 1px 0 #0E6AAC, inset 0 -1px 0 #0E6AAC;
}
table.sub-table thead th.sorted-asc::after  { content: ' \2191'; color: #fff; }
table.sub-table thead th.sorted-desc::after { content: ' \2193'; color: #fff; }
table.sub-table tbody tr { transition: background .1s; }
table.sub-table tbody tr:hover { background: var(--navy-mid); }
table.sub-table tbody td {
  padding: 5px 8px;
  color: var(--text);
  white-space: nowrap;
  text-align: center;
  border: 1px solid var(--border);
}
table.sub-table tbody td.num {
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.section-block { margin-bottom: 28px; }
.filter-slider-wrap { width: 180px; }

/* ── Player autocomplete (static/js/player_pool.js) ──────────── */
.ac-wrap { position: relative; }
.ac-input {
  width: 100%;
  font-family: inherit;
  font-size: .8rem;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
}
.ac-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(33,153,234,.18);
}
.ac-input::placeholder { color: #6E6E6E; }   /* 4.9:1 on white */
.ac-menu {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  z-index: 60;
  max-height: 260px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 5px;
  box-shadow: 0 6px 18px rgba(17,17,17,.16);
}
.ac-item {
  display: grid;
  grid-template-columns: 26px 1fr auto auto;
  align-items: center;
  gap: 8px;
  padding: 6px 9px;
  cursor: pointer;
  font-size: .78rem;
  border-bottom: 1px solid #F0F0F0;
}
.ac-item:last-child { border-bottom: none; }
.ac-item:hover, .ac-item.ac-active { background: #E8F3FB; }
.ac-pos {
  text-align: center;
  font-weight: 800;
  font-size: .66rem;
  border-radius: 3px;
  padding: 1px 0;
}
.ac-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ac-team { color: var(--text-dim); font-size: .72rem; font-weight: 600; }
.ac-inactive { color: var(--text-dim); font-size: .66rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.ac-price {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--blue);
  min-width: 32px;
  text-align: right;
}
.ac-empty { padding: 10px; color: var(--text-dim); font-size: .78rem; text-align: center; }

/* ── Charts ──────────────────────────────────────────────────── */
.charts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
  gap: 18px;
  margin-top: 20px;
}
.chart-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px;
  box-shadow: var(--shadow);
}
.chart-card h4 {
  font-size: .78rem;
  font-weight: 700;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: .05em;
  margin-bottom: 10px;
}
.chart-card canvas { max-height: 220px; }

/* ── Section headings ────────────────────────────────────────── */
h2.section-title {
  font-size: .85rem;
  font-weight: 800;
  color: var(--blue);
  text-transform: uppercase;
  letter-spacing: .06em;
  margin-bottom: 12px;
}

/* ── Empty / loading states ──────────────────────────────────── */
.empty-state {
  text-align: center;
  padding: 48px 20px;
  color: var(--text-dim);
  font-size: .9rem;
}
.spinner {
  display: inline-block;
  width: 22px; height: 22px;
  border: 2px solid var(--border);
  border-top-color: var(--blue);
  border-radius: 50%;
  animation: spin .6s linear infinite;
  vertical-align: middle;
  margin-right: 8px;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Toasts (showToast in base.js) ───────────────────────────── */
#toast-host {
  position: fixed;
  left: 50%; bottom: 16px;
  transform: translateX(-50%);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: max-content;
  max-width: min(420px, calc(100vw - 32px));
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
  box-shadow: 0 4px 14px rgba(17,17,17,.18);
  font-size: .85rem;
}
.toast-ok { border-color: #2F8A3D; background: #DDF2E4; color: #17602A; }
.toast-error { border-color: #C0392B; background: #FBE4E1; color: #8E2418; }
.toast-text { flex: 1; white-space: pre-wrap; word-break: break-word; }
.toast-close {
  border: 0; background: none; color: inherit;
  font-size: 1.2rem; line-height: 1; cursor: pointer; padding: 0 2px;
}

/* ── Responsive ──────────────────────────────────────────────── */
@media (max-width: 640px) {
  .content { padding: 16px; }
  .topbar { padding: 8px 16px; }
  .charts-grid { grid-template-columns: 1fr; }
}
/* A phone can't fit logo + two-line title + season + name + Logout on one
   row: the Logout button was pushed 12px past the screen edge. The name is
   the one thing already implied by being logged in. */
@media (max-width: 480px) {
  .topbar { gap: 10px; }
  .topbar img.logo-icon { height: 34px; width: 34px; }
  .auth-label { display: none; }
}
