:root {
  --bg: #0b0f14;
  --surface: #121820;
  --surface-2: #182028;
  --surface-hover: #1c2530;
  --border: #232e3a;

  --text: #e9eef3;
  --text-dim: #92a0af;
  --text-faint: #5b6b7b;

  --gold: #e8b93f;
  --green: #4cc38a;
  --green-dim: #2f7a56;
  --red: #e2564f;
  --red-dim: #8f3733;
  --blue: #4f8fe2;
  --purple: #9b6fe0;
  --orange: #e8973f;

  /* Position colors -- same palette as the Auction Board, so a player's
     position reads the same at a glance across both apps. */
  --pos-qb: #e2564f;
  --pos-wr: #4f8fe2;
  --pos-rb: #4cc38a;
  --pos-te: #e8973f;
  --pos-k:  #9b6fe0;
  --pos-dst: #a8703f;

  --body: "Segoe UI", "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
  --display: "Bahnschrift", "SF Pro Display", "Segoe UI Semibold", Arial, sans-serif;
  --mono: "SF Mono", "Cascadia Mono", "Consolas", "JetBrains Mono", "Menlo", monospace;
}

html[data-theme="light"] {
  --bg: #f4f6f8;
  --surface: #ffffff;
  --surface-2: #edf0f3;
  --surface-hover: #e2e6eb;
  --border: #d6dce2;

  --text: #1b2430;
  --text-dim: #55606d;
  --text-faint: #8a97a6;

  --green-dim: #1f7a52;
  --red-dim: #8f3733;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--body);
  min-height: 100%;
}

button, input, select, textarea { font-family: inherit; color: inherit; }

a { color: var(--blue); }

.topbar {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 14px 24px;
  background: linear-gradient(180deg, var(--surface) 0%, var(--bg) 100%);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 30;
}

.brand-mark { display: inline-flex; align-items: center; gap: 9px; font-family: var(--display); font-weight: 700; font-size: 18px; letter-spacing: 0.04em; }
.brand-mark-sub { color: var(--gold); }
.brand-logo { width: 40px; height: 40px; border-radius: 9px; display: block; }
.brand-logo-lg { width: 54px; height: 54px; border-radius: 12px; }

.topbar-spacer { flex: 1; }
.topbar-user { color: var(--text-dim); font-size: 13px; margin-right: 14px; }
.topbar-nav-desktop { display: flex; align-items: center; gap: 18px; }

/* Topbar dropdowns (Tools / Config) -- see nav.js. Click-to-open, so the
   menu needs a real stacking context above page content but below the
   settings modal backdrop. */
.nav-dropdown { position: relative; display: inline-flex; }
.nav-caret { font-size: 9px; opacity: 0.8; margin-left: 1px; }
.nav-dropdown-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 60;
  min-width: 190px;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 9px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.4);
}
.nav-dropdown-menu a,
.nav-dropdown-menu button {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.nav-dropdown-menu a:hover,
.nav-dropdown-menu button:hover { background: var(--surface-hover); }
.topbar-nav-mobile-links { display: none; }

.bottom-nav { display: none; }

/* Phones: the six-item desktop nav row was overflowing and clipping, so
   below this width it's replaced entirely by a fixed bottom tab bar with
   just the destinations that matter on a phone (Alerts, Compare,
   Settings) -- everything else (Import, Display, Priority Tracking)
   moves into the Settings sheet instead of fighting for topbar space. */
@media (max-width: 640px) {
  .topbar-nav-desktop { display: none; }
  .topbar-user { display: none; }
  .page { padding-bottom: 84px; }

  .bottom-nav {
    display: flex;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    background: var(--surface);
    border-top: 1px solid var(--border);
    padding: 6px 0 max(6px, env(safe-area-inset-bottom));
    z-index: 40;
  }
  .bottom-nav-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    background: none;
    border: none;
    color: var(--text-dim);
    font-size: 11px;
    padding: 6px 0;
    cursor: pointer;
  }
  .bottom-nav-item.active { color: var(--gold); }
  .bottom-nav-icon { font-size: 19px; line-height: 1; }

  .topbar-nav-mobile-links { display: block; font-size: 13.5px; margin: 10px 0 0; }
}

.page { max-width: 1080px; margin: 0 auto; padding: 24px; }
.page-full { max-width: none; }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px 20px;
  margin-bottom: 18px;
}

.card h2 { margin-top: 0; font-size: 16px; }
a.card { display: block; transition: border-color 0.15s, background 0.15s; }
a.card:hover { border-color: var(--gold); background: var(--surface-2); }
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; }
.card-label { font-family: var(--display); font-weight: 700; font-size: 15px; margin-bottom: 6px; }
.card-body { color: var(--text-dim); font-size: 13.5px; }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 7px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
}
.btn:hover { background: var(--surface-hover); }
.btn-primary { background: var(--gold); border-color: var(--gold); color: #1b1400; }
.btn-primary:hover { background: var(--gold); filter: brightness(1.08); }
.btn-ghost { background: transparent; }
.btn-small { padding: 5px 10px; font-size: 12px; }
.btn-danger { color: var(--red); }

.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th, .table td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--border); }
.table th { color: var(--text-dim); font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: 0.03em; }
.table tr:hover td { background: var(--surface-2); }
.table td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.table-compact th, .table-compact td { padding: 5px 8px; font-size: 12.5px; }
.standings-row-mine td { background: var(--surface-2); font-weight: 700; }

/* ---------- Main page (My View / Summary tabs) ---------- */
.page-tabs { display: flex; gap: 6px; margin-bottom: 16px; }
.page-tab {
  font-family: var(--mono);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  padding: 7px 16px;
  border-radius: 20px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  transition: all 0.15s;
}
.page-tab:hover { border-color: var(--text-faint); color: var(--text); }
.page-tab.active { background: var(--text); color: var(--bg); border-color: var(--text); }

.summary-grid { display: grid; grid-template-columns: 1.3fr 1fr; gap: 16px; align-items: start; }
.summary-col { display: flex; flex-direction: column; gap: 16px; }
@media (max-width: 860px) { .summary-grid { grid-template-columns: 1fr; } }
.scroll-list { max-height: 320px; overflow-y: auto; }
.mini-list-row { padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 13px; }
.mini-list-row:last-child { border-bottom: none; }

.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
}
.badge-green { color: var(--green); border-color: var(--green-dim); }
.badge-red { color: var(--red); border-color: var(--red-dim); }
.badge-warning { color: var(--gold); border-color: var(--gold); }
.badge-critical { color: var(--red); border-color: var(--red); }
.badge-purple { color: var(--purple); border-color: var(--purple); }
.badge-orange { color: var(--orange); border-color: var(--orange); }

/* Sortable table headers (Board page) -- an arrow marks the active sort;
   plain buttons rather than <a> since sorting doesn't change the URL. */
.th-sort { background: none; border: none; padding: 0; margin: 0; font: inherit; color: inherit; text-transform: inherit; letter-spacing: inherit; cursor: pointer; }
.th-sort::after { content: ""; margin-left: 4px; }
.th-sort.sort-asc::after { content: "\25B2"; }
.th-sort.sort-desc::after { content: "\25BC"; }

.alert-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
.alert-row:last-child { border-bottom: none; }
.alert-row .alert-message { flex: 1; font-size: 14px; }
.alert-row .alert-league { color: var(--text-dim); font-size: 12.5px; }

.form-row { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
.form-row label { font-size: 12px; color: var(--text-dim); }
.form-row input, .form-row select {
  padding: 8px 10px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
}
.form-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.form-value { padding: 8px 0 0; font-size: 13.5px; overflow-wrap: anywhere; }

.modal-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,0.55);
  display: flex; align-items: center; justify-content: center; z-index: 50;
}
.modal { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 22px; width: 100%; max-width: 480px; max-height: 85vh; overflow-y: auto; }
.modal-wide { max-width: 900px; }
.modal h3 { margin-top: 0; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
.hidden { display: none !important; }

.empty-state { color: var(--text-faint); padding: 30px 0; text-align: center; }
.text-dim { color: var(--text-dim); }
.error-text { color: var(--red); font-size: 13px; margin-top: 6px; }

.onboarding-step-count { color: var(--text-dim); font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.05em; }
.onboarding-dots { display: flex; gap: 6px; margin: 14px 0 4px; }
.onboarding-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--border); }
.onboarding-dot.active { background: var(--green); }

.login-wrap { display: flex; align-items: center; justify-content: center; min-height: 100vh; }
.login-card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 32px; width: 100%; max-width: 360px; text-align: center; }
.login-card .btn { width: 100%; justify-content: center; margin-top: 18px; }
.login-logo { width: 96px; height: 96px; border-radius: 18px; margin-bottom: 14px; }
.login-card .brand-mark { display: flex; justify-content: center; }

/* Pre-login showcase: the three sibling products, shown for context only --
   these cards are plain divs, never links, since none of them can be opened
   until you've signed in. Accent colors match each product's own topbar
   identity color (gold = Auction Board, blue = DraftBoard, green = this app). */
.showcase-wrap { max-width: 900px; margin: 0 auto; padding: 48px 24px 40px; }
.showcase-head { text-align: center; margin-bottom: 36px; }
.showcase-logo { display: block; width: 88px; height: 88px; margin: 0 auto 16px; border-radius: 14px; border: 1px solid var(--border); }
.showcase-head-sub { color: var(--text-dim); font-size: 14px; margin-top: 10px; }
.showcase-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; margin-bottom: 36px; }
.showcase-card {
  display: flex; flex-direction: column; gap: 10px;
  background: var(--surface); border: 1px solid var(--border); border-top: 3px solid var(--border);
  border-radius: 10px; padding: 20px 18px; cursor: default;
  text-decoration: none; color: inherit;
}
.showcase-card-mark { font-family: var(--display); letter-spacing: 0.06em; font-size: 17px; font-weight: 700; }
.showcase-card-mark .lead { color: var(--text); }
.showcase-card-body { color: var(--text-dim); font-size: 12.5px; line-height: 1.5; flex: 1; }
.showcase-card-go { font-size: 11.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; }
.showcase-card--auction { border-top-color: var(--gold); }
.showcase-card--auction .showcase-card-mark .accent, .showcase-card--auction .showcase-card-go { color: var(--gold); }
.showcase-card--draft { border-top-color: var(--blue); }
.showcase-card--draft .showcase-card-mark .accent, .showcase-card--draft .showcase-card-go { color: var(--blue); }
.showcase-card--tracking { border-top-color: var(--green); }
.showcase-card--tracking .showcase-card-mark .accent { color: var(--green); }

/* Auction/DraftBoard cards link out to the sibling app's own login page
   (fantasytracking.com/login) -- the only way back to those sign-ins once
   you've landed here, since this page's own Google sign-in is FantasyTracking-only. */
.showcase-card--link { cursor: pointer; transition: background 0.15s, transform 0.15s; }
.showcase-card--link:hover { background: var(--surface-hover); transform: translateY(-2px); }
.showcase-card--link:focus-visible { outline: 2px solid var(--text-dim); outline-offset: 2px; }
.login-wrap.login-wrap--showcase { min-height: 0; padding-bottom: 40px; }

.diff-added { color: var(--green); }
.diff-dropped { color: var(--red); text-decoration: line-through; }

/* ---------- Position chips (same look as the Auction Board) ---------- */
.pos-chip {
  display: inline-block;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 3px 7px;
  border-radius: 4px;
  color: #0b0f14;
}
.pos-chip.QB { background: var(--pos-qb); }
.pos-chip.RB { background: var(--pos-rb); }
.pos-chip.WR { background: var(--pos-wr); }
.pos-chip.TE { background: var(--pos-te); }
.pos-chip.K { background: var(--pos-k); }
.pos-chip.DST { background: var(--pos-dst); }
.pos-chip:not(.QB):not(.RB):not(.WR):not(.TE):not(.K):not(.DST) {
  background: var(--border);
  color: var(--text);
}

/* ---------- Rules page ---------- */
.rule-row {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.rule-row .toggle-field { flex: 1; }
.rule-run-result { font-size: 12px; min-width: 160px; }
.rule-description { font-size: 12.5px; color: var(--text-dim); margin: 4px 0 0 26px; line-height: 1.5; }

.severity-legend { display: flex; flex-wrap: wrap; gap: 16px; margin: 10px 0 16px; }
.severity-legend-item { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text-dim); }

.action-plan-row {
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.action-plan-row:last-child { border-bottom: none; }

/* ---------- League page: Roster Composition strip ---------- */
.roster-config-strip { display: flex; flex-wrap: nowrap; gap: 22px; padding-bottom: 2px; }
.roster-config-stat { flex: 0 0 auto; text-align: center; }
.roster-config-stat .stat-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-faint); margin-bottom: 3px; white-space: nowrap;
}
.roster-config-stat .stat-value {
  font-family: var(--mono); font-size: 16px; font-variant-numeric: tabular-nums; color: var(--text);
}

/* ---------- Settings modal ---------- */
.modal-subhead {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-faint);
  margin: 16px 0 10px;
}
.toggle-field { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-dim); cursor: pointer; }

/* ---------- Roster starters/bench (League detail page) ---------- */
.slot-table .slot-label { color: var(--text-dim); font-size: 12px; width: 90px; }
.slot-table .slot-empty { color: var(--text-faint); font-style: italic; }
.section-subhead { font-size: 13px; color: var(--text-dim); margin: 18px 0 8px; text-transform: uppercase; letter-spacing: 0.04em; }
.section-subhead:first-child { margin-top: 0; }

/* ---------- Compare page ---------- */
.owned-in-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.owned-in-chip { font-size: 11px; padding: 2px 7px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-dim); }
.count-multi { color: var(--gold); font-weight: 700; }
.league-picker { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 14px; }
.league-picker label { display: flex; align-items: center; gap: 6px; font-size: 13px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 7px; padding: 6px 10px; cursor: pointer; }

/* ---------- Board page -- filter ribbon and table styled after
   ffb_auction_app's Auction Board (.controls / .pos-tab / .board thead th)
   so the two apps' "browse every player" screens read the same way. ---------- */
.controls-ribbon {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 16px;
  flex-wrap: wrap;
}

.pos-tabs { display: flex; gap: 6px; flex-wrap: wrap; }
.pos-tab {
  font-family: var(--mono);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  padding: 6px 13px;
  border-radius: 20px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  transition: all 0.15s;
}
.pos-tab:hover { border-color: var(--text-faint); color: var(--text); }
.pos-tab.active { background: var(--text); color: var(--bg); border-color: var(--text); }

.board-search-wrap { flex: 1; min-width: 160px; max-width: 320px; }
.board-search {
  width: 100%;
  padding: 8px 13px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 13.5px;
}
.board-search:focus { outline: none; border-color: var(--gold); }
.board-search::placeholder { color: var(--text-faint); }

.board-table thead th {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-faint);
}
.board-table thead th .th-sort:hover { color: var(--text-dim); }
.board-table thead th .th-sort.sort-asc,
.board-table thead th .th-sort.sort-desc { color: var(--gold); }

.player-cell-name { font-weight: 700; color: var(--text); }
.player-cell-bye { font-size: 10.5px; color: var(--text-faint); margin-left: 3px; }

/* Player-name and NFL-team links (shared.js's playerLink/teamLink) --
   deliberately inherit the surrounding text color rather than the usual
   link blue, since nearly every player name in the app is now one of
   these and coloring them all would read as noise. The hover underline is
   what signals they're clickable. */
.entity-link { color: inherit; text-decoration: none; }
.entity-link:hover { text-decoration: underline; text-decoration-color: var(--gold); }

/* ---------- Player / NFL team detail pages ---------- */
.detail-header { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
.detail-header h1 { font-size: 22px; margin: 0; }
.detail-meta { display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: 13px; color: var(--text-dim); margin-bottom: 16px; }
.detail-meta strong { color: var(--text); font-weight: 600; }
.detail-row-mine td { background: var(--surface-2); font-weight: 700; }

/* ---------- Help page ---------- */
.help-list { margin: 6px 0 0; padding-left: 20px; line-height: 1.65; }
.help-list li { margin-bottom: 10px; }
.help-dl { margin: 0; }
.help-dl dt { font-weight: 700; color: var(--text); margin-top: 12px; }
.help-dl dt:first-child { margin-top: 0; }
.help-dl dd { margin: 3px 0 0; color: var(--text-dim); font-size: 13px; line-height: 1.6; }

/* Solid fills rather than the outline-style .badge-* used for alerts/
   severity elsewhere -- at 11px an outline badge reads as one indistinct
   dim pill regardless of hue (purple vs. orange especially), a filled
   background with white text is what actually stays legible at that size. */
.tier-badge {
  display: inline-block;
  min-width: 20px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  text-align: center;
  color: #fff;
}
.tier-purple { background: #9333ea; }
.tier-red { background: #dc2626; }
.tier-orange { background: #ea580c; }
.tier-yellow { background: #ca8a04; color: #1b1400; }
.tier-green { background: #16a34a; }
.tier-badge-btn { border: none; cursor: pointer; }

/* Priority Tracking's "which of my leagues own this" popover, opened by
   clicking a ranked player's Owned tier badge -- positioned next to the
   badge in JS (see priority_tracking.js), closed on outside click. */
.owned-popover {
  position: absolute;
  z-index: 50;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  padding: 6px;
  min-width: 200px;
  max-width: 280px;
}
.owned-popover a {
  display: block;
  padding: 6px 8px;
  border-radius: 6px;
  color: var(--text);
  text-decoration: none;
  font-size: 12.5px;
}
.owned-popover a:hover { background: var(--surface-hover); }
.owned-popover-team { color: var(--text-dim); font-size: 11px; }

/* Priority Queue's "Last 24h" activity indicator -- compact so it fits a
   table cell without widening the column much. */
.activity-cell { font-size: 11.5px; color: var(--text-dim); white-space: nowrap; }
.activity-cell .activity-hit { color: var(--gold); font-weight: 700; }

/* Priority Tracking's ranked list: the name is a link to the player page
   now, so adding to the queue moved onto its own compact button. */
.rank-add-btn { padding: 1px 7px; margin-right: 6px; line-height: 1.4; }

/* Floating feedback "?" button, injected by static/feedback_widget.js on
   every page (see _topbar.html) -- ported from ffb_auction_app's own,
   same look, adapted colors since this app has no -dim variants. */
.feedback-fab {
  position: fixed; right: 20px; bottom: 20px; width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text-dim);
  font-family: var(--display); font-size: 20px; font-weight: 700; cursor: pointer; z-index: 90;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}
.feedback-fab:hover { background: var(--surface-hover); color: var(--gold); border-color: var(--gold); }
.feedback-fab:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* Persistent "Viewing as X" banner while an admin is impersonating (see
   _topbar.html + /api/admin/impersonate) -- deliberately loud (not a
   subtle text-dim note) since it changes what every page shows and must
   never be missed. */
.impersonation-banner {
  background: var(--gold); color: #1b1400; font-size: 13px; font-weight: 600;
  padding: 8px 16px; display: flex; align-items: center; justify-content: center; gap: 10px;
}
.impersonation-banner button {
  background: rgba(0,0,0,0.15); border: 1px solid rgba(0,0,0,0.3); color: inherit;
  border-radius: 5px; padding: 3px 10px; font-size: 12px; font-weight: 700; cursor: pointer;
}
.impersonation-banner button:hover { background: rgba(0,0,0,0.25); }

/* Roster Heatmap: a real CSS grid, not a table -- rows are rank position
   (best at top), columns are "owned in N of your leagues" (fewest at
   left), one colored cell per shown player, everything else blank grid
   space. grid-template-columns/rows and each cell's grid-column/grid-row
   are set inline by roster_heatmap.js since both depend on how many
   leagues the user tracks and how many players are being shown. */
.heatmap-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; margin-bottom: 6px; }
.heatmap-count-field { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-dim); }
.heatmap-count-field input {
  width: 64px; padding: 5px 8px; border-radius: 6px; border: 1px solid var(--border);
  background: var(--surface-2); color: var(--text);
}
.heatmap-legend { display: flex; align-items: center; gap: 6px; font-size: 12px; margin-left: auto; }
.heatmap-legend-swatch { display: inline-block; width: 14px; height: 14px; border-radius: 3px; }
.heatmap-legend-gradient {
  display: inline-block; width: 80px; height: 10px; border-radius: 3px;
  background: linear-gradient(to right, hsl(0,70%,45%), hsl(60,70%,42%), hsl(120,70%,35%));
}

.heatmap-grid {
  display: grid;
  gap: 2px;
  margin-top: 10px;
  min-width: 640px;
}
.heatmap-axis-label {
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-dim); background: var(--surface-2); border-radius: 4px;
}
.heatmap-rank-label {
  display: flex; align-items: center; justify-content: flex-end;
  padding-right: 6px; font-size: 11px; color: var(--text-faint); font-family: var(--mono);
}
.heatmap-cell-empty { background: var(--surface-2); border-radius: 4px; opacity: 0.35; }
.heatmap-cell-player {
  display: flex; flex-direction: column; justify-content: center;
  padding: 3px 8px; border-radius: 4px; color: #fff; font-size: 12px; line-height: 1.3;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  text-decoration: none;
}
.heatmap-cell-player .heatmap-cell-count { font-size: 10.5px; font-weight: 700; opacity: 0.9; }
.heatmap-cell-player:hover { outline: 2px solid var(--text); outline-offset: -2px; }

.heatmap-quadrant-row { border-top: 2px dashed var(--text-faint); }
.heatmap-quadrant-col { border-left: 2px dashed var(--text-faint); }

.heatmap-grid-outer { position: relative; }
.heatmap-quadrant-label {
  position: absolute; font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-faint); background: var(--surface); padding: 2px 7px; border-radius: 4px;
  pointer-events: none; white-space: nowrap;
}

/* Admin reference pages (Version History, How It Works, Tech Stack,
   Database Schema, Data Formats) -- ported from ffb_auction_app's own
   admin-hub-card/flow/schema/vh-* classes, adapted to this app's palette
   (no -dim/-soft variants; solid colors and var(--border) instead). */
.admin-hub-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.admin-hub-card {
  display: block; background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 14px 16px; text-decoration: none; color: inherit;
}
.admin-hub-card[href]:hover { background: var(--surface-hover); border-color: var(--gold); }
.admin-hub-card-title { font-weight: 700; color: var(--text); font-size: 13px; margin-bottom: 4px; }
.admin-hub-card-body { color: var(--text-dim); font-size: 12px; line-height: 1.5; }

/* How It Works */
.flow-phase { margin-bottom: 26px; }
.flow-phase-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.flow-phase-num {
  font-family: var(--mono); font-size: 12px; font-weight: 700; color: var(--bg);
  background: var(--gold); border-radius: 50%; width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.flow-phase-title { font-family: var(--display); font-size: 14px; font-weight: 700; color: var(--text); text-transform: uppercase; letter-spacing: 0.05em; }
.flow-phase-sub { color: var(--text-dim); font-size: 12.5px; margin: 4px 0 14px 32px; max-width: 720px; }
.flow-row { display: flex; flex-wrap: wrap; align-items: stretch; gap: 10px; margin-left: 32px; }
.flow-box {
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 11px 13px;
  flex: 1 1 165px; min-width: 155px; max-width: 220px; display: flex; flex-direction: column; gap: 4px;
}
.flow-box-title { font-weight: 700; color: var(--text); font-size: 12.5px; }
.flow-box-body { color: var(--text-dim); font-size: 11px; line-height: 1.4; flex: 1; }
.flow-box-page {
  align-self: flex-start; margin-top: 2px; font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--gold); background: var(--surface-2); padding: 2px 6px; border-radius: 4px;
}
.flow-down-arrow { margin-left: 32px; color: var(--text-faint); font-size: 20px; line-height: 1; padding: 4px 0; }

/* Database Schema */
.schema-legend { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; font-size: 12px; color: var(--text-dim); margin-bottom: 16px; }
.schema-legend-item { display: flex; align-items: center; gap: 6px; }
.schema-cluster { margin-bottom: 26px; }
.schema-cluster-title {
  font-family: var(--display); font-size: 12.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 10px; padding-bottom: 5px; border-bottom: 1px solid var(--border);
}
.schema-cluster-tables { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-start; }
.schema-table { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; min-width: 220px; max-width: 300px; flex: 1 1 240px; }
.schema-table-head {
  font-family: var(--mono); font-size: 12px; font-weight: 700; color: var(--text); background: var(--surface-2);
  padding: 6px 10px; border-radius: 8px 8px 0 0; border-bottom: 1px solid var(--border);
}
.schema-singleton {
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--gold); background: var(--surface-2);
  padding: 1px 5px; border-radius: 4px; font-weight: 700; margin-left: 4px;
}
.schema-table-note { color: var(--text-faint); font-size: 10.5px; line-height: 1.4; padding: 6px 10px; border-bottom: 1px solid var(--border); }
.schema-cols { width: 100%; border-collapse: collapse; }
.schema-col-row { border-bottom: 1px solid var(--border); }
.schema-col-row:last-child { border-bottom: none; }
.schema-col-badges { width: 50px; padding: 3px 4px 3px 8px; white-space: nowrap; }
.schema-badge { display: inline-block; font-size: 8.5px; font-weight: 700; padding: 1px 4px; border-radius: 3px; margin-right: 2px; }
.schema-badge-pk { background: var(--gold); color: var(--bg); }
.schema-badge-fk { background: var(--surface-2); color: var(--gold); border: 1px solid var(--gold); }
.schema-badge-fk-soft { background: transparent; color: var(--text-faint); border: 1px dashed var(--text-faint); }
.schema-badge-uq { background: transparent; color: var(--text-faint); border: 1px solid var(--border); }
.schema-col-name { font-family: var(--mono); font-size: 11px; color: var(--text); padding: 3px 6px; white-space: nowrap; }
.schema-col-type { font-family: var(--mono); font-size: 9.5px; color: var(--text-faint); padding: 3px 8px 3px 0; text-align: right; white-space: nowrap; }
.schema-fk-target { font-size: 9.5px; color: var(--text-faint); padding: 0 6px 3px; }

/* Version History */
.vh-wrap { display: flex; gap: 0; align-items: flex-start; }
.vh-sidebar { width: 260px; flex-shrink: 0; padding-right: 20px; border-right: 1px solid var(--border); }
.vh-list { display: flex; flex-direction: column; gap: 4px; }
.vh-row { display: flex; align-items: baseline; gap: 8px; padding: 8px 10px; border-radius: 6px; border: 1px solid transparent; cursor: pointer; }
.vh-row:hover { background: var(--surface-hover); }
.vh-row.active { border-color: var(--gold); background: var(--surface-hover); }
.vh-row-version { font-family: var(--mono); font-size: 12px; font-weight: 700; color: var(--gold); flex-shrink: 0; width: 48px; }
.vh-row-title { font-size: 12px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vh-main { flex: 1; min-width: 0; padding: 4px 0 0 24px; max-width: 700px; }
.vh-detail-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 4px; flex-wrap: wrap; }
.vh-detail-version { font-family: var(--mono); font-size: 20px; font-weight: 700; color: var(--text); }
.vh-detail-date { font-size: 12px; color: var(--text-faint); font-family: var(--mono); margin-bottom: 16px; }
.vh-detail-title { font-size: 16px; font-weight: 700; color: var(--text); margin: 0 0 8px; font-family: var(--display); }
.vh-detail-summary { font-size: 13.5px; color: var(--text-dim); line-height: 1.6; margin: 0 0 16px; }
.vh-detail-notes { font-size: 12.5px; color: var(--text-dim); line-height: 1.7; white-space: pre-line; }
.vh-detail-commit { margin-top: 18px; font-family: var(--mono); font-size: 10.5px; color: var(--text-faint); }
@media (max-width: 700px) {
  .vh-wrap { flex-direction: column; }
  .vh-sidebar { width: 100%; border-right: none; border-bottom: 1px solid var(--border); padding: 0 0 14px; }
  .vh-main { padding: 14px 0 0; }
}

/* Site-wide footer -- included on every page (see _footer.html), just a
   link out to the full Privacy Policy rather than repeating the whole
   statement on every page. Sits below the bottom nav on mobile so it
   never overlaps it. */
.site-footer {
  text-align: center; padding: 18px 16px; font-size: 11.5px; color: var(--text-faint);
}
.site-footer a { color: var(--text-faint); text-decoration: underline; }
.site-footer a:hover { color: var(--text-dim); }
@media (max-width: 640px) {
  .site-footer { padding-bottom: 84px; }
}

/* Privacy Policy page */
.privacy-wrap { max-width: 760px; margin: 0 auto; padding: 32px 24px 60px; }
.privacy-wrap h1 { font-size: 20px; margin-bottom: 4px; }
.privacy-wrap .privacy-revised { color: var(--text-faint); font-size: 12px; margin-bottom: 24px; }
.privacy-wrap h2 { font-size: 15px; margin: 28px 0 8px; font-family: var(--display); }
.privacy-wrap p, .privacy-wrap li { color: var(--text-dim); font-size: 13.5px; line-height: 1.65; }
.privacy-wrap ul { margin: 0 0 12px; padding-left: 20px; }
.privacy-wrap li { margin-bottom: 6px; }
.privacy-wrap a { color: var(--gold); }
