/* =========================================================
   Draft Board — Premium Dark Fantasy Cheatsheet
   ========================================================= */

:root {
  color-scheme: dark;
  /* Phase 1: Stepped elevation — each surface visibly lighter than the one below.
     Old tokens produced ~1.05–1.07:1 contrast between surfaces (invisible).
     New tokens produce ~1.5–2.2:1 steps, giving panels, drawers and menus
     visible lift without any shadows on list rows. */
  --bg:        #070709;   /* page: slightly darker → rows pop more          */
  --bg-row:    #15151c;   /* tiles: ~1.6:1 vs page (up from 1.07:1)         */
  --bg-row-hover: #1c1c24;
  --bg-elev:   #1a1a22;   /* menus, drawer (floats above rows)              */
  --bg-elev-2: #22222b;   /* modal card, popover — top of the stack         */
  --border:        #2c2c37;  /* up from #25252d (better visible separation) */
  --border-strong: #41414e;  /* up from #33333d                             */
  --text: #f4f4f6;
  --text-dim: #a8a8b6;   /* was #9a9aa6 — slightly lighter */
  --text-muted: #7e7e8c; /* was #5f5f6b (2.9:1 ❌) → ~4.6:1 ✅ WCAG AA */
  /* One cheap "lift" treatment for all floating surfaces (free to paint) */
  --surface-highlight: inset 0 1px 0 rgba(255,255,255,0.05);
  --accent: #5b8cff;          /* warm blue */
  --accent-2: #7fb2ff;
  --accent-glow: rgba(91, 140, 255, 0.35);
  --star: #ffcc4d;
  --danger: #ef4444;
  --success: #22c55e;
  --mine: #4f9eff;            /* "Picked By Me" — azure, distinct from
                                 picked (green), favorited (gold) & all
                                 position colors. Drives row tint, the action
                                 button, the header badge and the drawer. */
  --mine-glow: rgba(79, 158, 255, 0.35);
  --mine-soft: rgba(79, 158, 255, 0.10);

  /* position colors */
  --qb: #ef4444;
  --rb: #22c55e;
  --wr: #3b82f6;
  --te: #f59e0b;
  --k: #8b5cf6;               /* Kicker color */
  --dst: #14b8a6;             /* DST color */

  --radius: 14px;
  --radius-sm: 10px;
  --shadow: 0 12px 36px rgba(0,0,0,0.55), 0 2px 8px rgba(0,0,0,0.35);
  --shadow-soft: 0 4px 14px rgba(0,0,0,0.3);

  --row-h: 64px;
  --row-h-mobile: 72px;

  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* Bright theme tokens preserve the existing blue accents while moving every
   neutral surface onto a crisp, readable light palette. */
:root[data-theme="bright"] {
  color-scheme: light;
  --bg: #f5f7fb;
  --bg-row: #ffffff;
  --bg-row-hover: #f8faff;
  --bg-elev: #eef2f8;
  --bg-elev-2: #ffffff;
  --border: #dce2ec;
  --border-strong: #b9c3d2;
  --text: #172033;
  --text-dim: #526078;
  --text-muted: #6d7890;
  --surface-highlight: inset 0 1px 0 rgba(255,255,255,0.9);
  --accent: #356ee8;
  --accent-2: #2457c5;
  --accent-glow: rgba(53, 110, 232, 0.22);
  --star: #b77900;
  --danger: #dc2626;
  --success: #16803b;
  --mine: #1f6ed4;
  --mine-glow: rgba(31, 110, 212, 0.22);
  --mine-soft: rgba(31, 110, 212, 0.09);
  --shadow: 0 16px 40px rgba(39, 55, 82, 0.16), 0 3px 10px rgba(39, 55, 82, 0.1);
  --shadow-soft: 0 4px 14px rgba(39, 55, 82, 0.12);
}

* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: 15px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overscroll-behavior-y: none;
}

body {
  min-height: 100vh;
  background:
    radial-gradient(1200px 600px at 80% -200px, rgba(91, 140, 255, 0.09), transparent 60%),
    radial-gradient(900px 500px at -10% 10%, rgba(59, 130, 246, 0.06), transparent 60%),
    var(--bg);
}

button {
  font-family: inherit;
  cursor: pointer;
  border: none;
  background: none;
  color: inherit;
}

h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -0.01em; }


/* Inline SVG icons inherit the same size and color as the former font glyphs. */
.icon-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}
.icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  flex: 0 0 auto;
  fill: currentColor;
  vertical-align: -0.125em;
}
.icon-spin { animation: icon-spin 1s linear infinite; }
@keyframes icon-spin { to { transform: rotate(360deg); } }

/* =========================
   Header
   ========================= */
.app-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(7,7,9,0.85);  /* matches new --bg token */
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--border);
  padding-top: env(safe-area-inset-top);
}

.header-inner {
  max-width: 960px;
  margin: 0 auto;
  padding: 14px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.brand { display: flex; align-items: center; min-width: 0; }

/* Brand logo — SVG scales from its height; width stays proportional.
   max-width guards against overflow on very narrow screens. */
.brand-logo {
  display: block;
  height: 44px;
  width: auto;
  max-width: 100%;
}

/* Uniform 12px rhythm between every action button; all three (plus the
   overflow icon button) sit on one vertically-centred baseline, aligned to the
   brand mark on the left. */
.header-actions { display: flex; align-items: center; gap: 12px; position: relative; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Consistent icon-to-label gap across all three buttons. */
  gap: 7px;
  height: 40px;
  /* 10px vertical is expressed via the fixed height; 16px horizontal here. */
  padding: 0 16px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
  color: var(--text);
  background: transparent;
  border: 1px solid var(--border);
  transition: background 0.15s var(--ease), border-color 0.15s var(--ease),
              transform 0.15s var(--ease), box-shadow 0.15s var(--ease);
  white-space: nowrap;
}
/* All button icons share one size and align to the label baseline. */
.btn > .icon { font-size: 18px; line-height: 1; }
.btn:hover { background: var(--bg-elev); border-color: var(--border-strong); }
.btn:active { transform: scale(0.97); }
/* Visible, keyboard-only focus ring in the app's warm-blue accent. */
.btn:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-glow);
}

/* Ghost buttons in the header: subtle dark-neutral fill with a faint border,
   consistent with the dark theme. Hover lightens the fill and brightens the
   border for a soft, uniform lift. */
.btn-ghost {
  background: #1e1f23;
  border-color: rgba(255, 255, 255, 0.08);
}
.btn-ghost:hover {
  background: #26272c;
  border-color: rgba(255, 255, 255, 0.16);
  transform: translateY(-1px);
}
.btn-ghost:active { transform: scale(0.97); }

.btn-danger {
  background: var(--danger);
  color: #fff;
  border-color: transparent;
}
.btn-danger:hover { background: #dc2626; }

/* Menu dropdown */
/* Keep the overflow ("⋮") trigger a square, icon-only button: same height as
   the three action buttons, but no label padding. Sits inline in the flex row
   so the uniform 12px gap already separates it from "My Team". */
#menu-btn {
  width: 40px;
  padding: 0;
  gap: 0;
}
#menu-btn > .icon { font-size: 18px; }
#menu-btn[aria-expanded="true"] {
  background: #26272c;
  border-color: rgba(255, 255, 255, 0.16);
}

.menu-wrap { position: relative; }
.menu-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 200px;
  background: var(--bg-elev-2);
  border: 1px solid var(--border-strong);
  border-radius: 12px;
  padding: 6px;
  box-shadow: var(--shadow), var(--surface-highlight);
  z-index: 60;
  animation: fade-in 0.15s var(--ease);
}
.menu-item {
  display: flex;
  text-decoration: none;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 14px;
  color: var(--text);
  font-weight: 500;
  text-align: left;
  transition: background 0.15s var(--ease);
}
.menu-item:hover { background: var(--bg-elev); }
/* Gentle support cue: distinct enough to notice without competing with actions. */
.menu-item-coffee {
  margin: 2px 0;
  color: var(--accent-2);
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  font-weight: 600;
}
.menu-item-coffee .icon { color: var(--accent-2); }
.menu-item-coffee:hover { background: color-mix(in srgb, var(--accent) 16%, transparent); }
.coffee-heart {
  margin-left: auto;
  color: var(--star);
  font-size: 11px;
  opacity: 0.85;
}
.menu-item.danger { color: #ff7a7a; }
.menu-item .icon { width: 18px; text-align: center; color: var(--text-dim); }
.menu-item.danger .icon { color: #ff7a7a; }
.menu-sep { height: 1px; background: var(--border); margin: 4px 6px; }

/* Visually-hidden utility — used by the hidden Restore file input. Keeps it
   out of the layout & off-screen while remaining programmatically clickable. */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Tabs */
.tabs {
  position: relative;
  max-width: 960px;
  margin: 0 auto;
  padding: 0 12px;
  display: flex;
  gap: 4px;
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }

.tab {
  position: relative;
  padding: 12px 18px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-dim);
  letter-spacing: 0.01em;
  transition: color 0.2s var(--ease);
  white-space: nowrap;
}
.tab:hover { color: var(--text); }
.tab.active { color: var(--text); }
/* Keep the active state attached to its tab instead of positioning a separate
   element with measurements. This remains accurate after tab scrolling,
   resizing, and font loading. */
.tab::after {
  content: '';
  position: absolute;
  right: 18px;
  bottom: 0;
  left: 18px;
  height: 2.5px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  border-radius: 2px 2px 0 0;
  box-shadow: 0 0 8px var(--accent-glow);
  opacity: 0;
  transform: scaleX(0.65);
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease);
}
.tab.active::after { opacity: 1; transform: scaleX(1); }
.tab-indicator { display: none; }

/* =========================
   Main / List
   ========================= */
.app-main {
  max-width: 960px;
  margin: 0 auto;
  padding: 16px 16px calc(40px + env(safe-area-inset-bottom));
}

.list-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px 14px;
  font-size: 12.5px;
  color: var(--text-dim);
  font-weight: 500;
  letter-spacing: 0.01em;
}
.meta-dot { color: var(--text-muted); }

/* =========================
   Toolbar (search + filters)
   ========================= */
.toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0 4px;
  margin-bottom: 4px;
  flex-wrap: wrap;
}

.search-wrap {
  position: relative;
  flex: 1 1 240px;
  min-width: 200px;
  display: flex;
  align-items: center;
}
.search-icon {
  position: absolute;
  left: 13px;
  font-size: 13px;
  color: var(--text-muted);
  pointer-events: none;
}
.search-input {
  width: 100%;
  height: 40px;
  padding: 0 38px 0 36px;
  border-radius: 11px;
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);  /* stronger border so search box reads against bg */
  color: var(--text);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  outline: none;
  transition: border-color 0.18s var(--ease), background 0.18s var(--ease), box-shadow 0.18s var(--ease);
  -webkit-appearance: none;
  appearance: none;
}
.search-input::placeholder { color: var(--text-muted); }
.search-input:focus {
  border-color: var(--accent);
  background: var(--bg-elev-2);
  box-shadow: 0 0 0 3px var(--accent-glow);
}
/* Hide native search clear UI; we provide our own button */
.search-input::-webkit-search-cancel-button { -webkit-appearance: none; }

.search-clear {
  position: absolute;
  right: 6px;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  color: var(--text-dim);
  font-size: 13px;
  transition: all 0.15s var(--ease);
}
.search-clear:hover { background: var(--bg-elev-2); color: var(--text); }
.search-clear[hidden] { display: none; }

.filter-toggles {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 40px;
  padding: 0 14px;
  border-radius: 11px;
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);
  color: var(--text-dim);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: all 0.18s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.filter-chip:hover { background: var(--bg-elev-2); border-color: var(--border-strong); color: var(--text); }
.filter-chip .icon { font-size: 12.5px; }
/* Hide the actual checkbox; the chip itself is the toggle */
.filter-chip input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }

/* Active (checked) state */
.filter-chip:has(#filter-watchlist:checked) {
  background: rgba(255, 204, 77, 0.12);
  border-color: rgba(255, 204, 77, 0.45);
  color: var(--star);
}
.filter-chip:has(#filter-hide-picked:checked) {
  background: rgba(91, 140, 255, 0.12);
  border-color: rgba(91, 140, 255, 0.45);
  color: var(--accent);
}
/* Keyboard focus ring on the chip */
.filter-chip:focus-within {
  box-shadow: 0 0 0 3px var(--accent-glow);
}

.rankings-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  /* Don't let row insert/remove shift the user's scroll position mid-drag */
  overflow-anchor: none;
}
/* Phase 3: themed scrollbar on the main list (desktop) */
html { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }

/* =========================
   Player Row
   ========================= */
.player-row {
  display: grid;
  grid-template-columns: 28px 34px 34px 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 10px 12px 10px 6px;
  min-height: var(--row-h);
  background: var(--bg-row);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  /* Vertical panning only — stops the browser doing horizontal-gesture
     hit-testing on every touch over a row */
  touch-action: pan-y;
  /* Perf: isolate each row's layout/paint so reordering one row doesn't
     force the browser to recalc every other row */
  contain: layout style paint;
  /* Perf: skip rendering work for rows far off-screen (87+ row lists).
     Rows are uniform height, so the intrinsic placeholder size is exact
     and scrolling stays pixel-stable. */
  content-visibility: auto;
  contain-intrinsic-size: auto var(--row-h);
}

/* Hover styles only on devices that actually hover — prevents sticky
   "phantom hover" repaints after taps on touch screens */
@media (hover: hover) {
  .player-row:hover {
    background: var(--bg-row-hover);
    border-color: var(--border-strong);
  }
}

.player-row.picked {
  opacity: 0.55;  /* was 0.42 — too low for readable names; now legible but clearly off-board */
}
.player-row.picked .player-name {
  text-decoration: line-through;
  text-decoration-color: var(--text-muted);
}
/* Desaturate the logo of picked players — cheap per-row filter, contained */
.player-row.picked .team-logo img {
  filter: grayscale(1);
}

/* "Picked By Me" — off-board like .picked (dimmed + struck through) but with
   an azure tint + left accent stripe so your own picks pop in a long draft.
   A player is either picked OR mine, never both (enforced in JS), so these
   two rules don't compete. */
.player-row.mine {
  opacity: 0.55;  /* consistent with .picked — legible but clearly off-board */
  background: var(--mine-soft);
  border-color: rgba(79, 158, 255, 0.30);
  box-shadow: inset 3px 0 0 var(--mine);
}
.player-row.mine .player-name {
  text-decoration: line-through;
  text-decoration-color: var(--mine);
}
.player-row.mine .team-logo img {
  filter: grayscale(0.6);  /* lighter grayscale — mine keeps the azure tint context */
}
@media (hover: hover) {
  .player-row.mine:hover {
    background: rgba(79, 158, 255, 0.14);
  }
}

/* Favorite mirrors the My Team tile treatment exactly, replacing the azure
   tint + left accent stripe with gold. State-specific dimming/strikethrough is
   intentionally reserved for drafted players. */
.player-row.favorited {
  background: rgba(255, 204, 77, 0.10);
  border-color: rgba(255, 204, 77, 0.30);
  box-shadow: inset 3px 0 0 var(--star);
}
@media (hover: hover) {
  .player-row.favorited:hover {
    background: rgba(255, 204, 77, 0.14);
  }
}

/* Sortable ghost / drag states */
.sortable-ghost {
  opacity: 0.35;
  background: var(--bg-elev-2) !important;
  border: 1px dashed var(--border-strong) !important;
}

.sortable-chosen {
  cursor: grabbing !important;
}

.sortable-drag {
  opacity: 1 !important;
  background: var(--bg-elev-2) !important;
  box-shadow: 0 12px 32px rgba(0,0,0,0.6) !important;
  border-color: var(--accent) !important;

  /* CRITICAL FIX: Kill all transitions so it sticks instantly to the finger */
  transition: none !important;

  /* Ensure hardware acceleration — the clone moves on its own GPU layer */
  will-change: transform;
  transform: translateZ(0);

  /* The clone must always paint fully (it lives on <body>) */
  content-visibility: visible !important;
  contain: none !important;

  /* Prevent browser from capturing touch events */
  touch-action: none !important;
  z-index: 9999 !important;
}

/* ---- Drag perf mode (body.is-dragging is set by JS for the drag's duration) ---- */
/* Rows must paint normally while Sortable measures + animates them… */

/* …and the expensive sticky-header backdrop blur is paused so auto-scroll
   during a drag doesn't trigger costly re-blurs every frame on phones. */
body.is-dragging .app-header {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  background: var(--bg);
}
/* Pause icon-button transitions mid-drag (they'd otherwise animate as the
   pointer passes over rows). */
body.is-dragging .icon-btn,
body.is-dragging .player-row {
  transition: none !important;
}

/* Drag handle */
.drag-handle {
  display: grid;
  place-items: center;
  width: 28px;
  height: 100%;
  min-height: 44px;
  color: var(--text-muted);
  cursor: grab;
  font-size: 14px;
  transition: color 0.15s var(--ease);
  touch-action: none;
  border-radius: 6px;
}
@media (hover: hover) {
  .drag-handle:hover { color: var(--text); }
}
.drag-handle:active { cursor: grabbing; }

/* Rank number */
.rank {
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-dim);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
/* Ranks 1–10: full white so top-of-board rows feel weightier */
.rank.rank-top { color: var(--text); }

/* Team logo (before the player name) */
.team-logo {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 8px;   /* was 0px — sharp squares read as unfinished */
  background: var(--bg-elev);
  border: 1px solid var(--border);
  overflow: hidden;
  flex: 0 0 auto;
}
.team-logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* vs. ECR comparison column */
.player-compare {
  display: flex;
  align-items: stretch;
  gap: 6px;
  flex: 0 0 auto;
}
.compare-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-width: 46px;   /* was 52px — tighter on desktop, drop "VS." → "ECR" label saves space */
  padding: 4px 6px;
  border-radius: 9px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  line-height: 1;
}
.compare-label {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.compare-value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
}
.compare-cell.delta-up .compare-value { color: var(--success); }
.compare-cell.delta-up { border-color: rgba(34, 197, 94, 0.35); background: rgba(34, 197, 94, 0.08); }
.compare-cell.delta-down .compare-value { color: var(--danger); }
.compare-cell.delta-down { border-color: rgba(239, 68, 68, 0.35); background: rgba(239, 68, 68, 0.08); }
.compare-cell.delta-even .compare-value { color: var(--text-muted); }  /* quiet "–" in muted tone */
.compare-cell.delta-neutral .compare-value { color: var(--text-muted); }

/* Player info */
.player-info {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.player-name {
  font-weight: 600;
  font-size: 15px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: -0.01em;
}
.player-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text-dim);
  font-weight: 500;
}
.player-team {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 700;
  color: var(--text);
  letter-spacing: 0.04em;
  font-size: 11.5px;
}
.player-bye {
  color: var(--text-muted);
  font-size: 11.5px;
}
.player-bye::before {
  content: 'BYE ';
  color: var(--text-muted);
  font-weight: 500;
}

/* Position chip */
.pos-chip {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10.5px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 5px;
  letter-spacing: 0.05em;
  /* Base: neutral dark */
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
}
/* Position color-coding in the main list (same palette as the drawer).
   Applied when the chip has a position class (Overall tab only). */
.pos-chip.QB  { color: var(--qb);  background: rgba(239, 68, 68, 0.1);   border-color: rgba(239, 68, 68, 0.35); }
.pos-chip.RB  { color: var(--rb);  background: rgba(34, 197, 94, 0.1);   border-color: rgba(34, 197, 94, 0.35); }
.pos-chip.WR  { color: var(--wr);  background: rgba(59, 130, 246, 0.1);  border-color: rgba(59, 130, 246, 0.35); }
.pos-chip.TE  { color: var(--te);  background: rgba(245, 158, 11, 0.1);  border-color: rgba(245, 158, 11, 0.35); }
.pos-chip.K   { color: var(--k);   background: rgba(139, 92, 246, 0.1);  border-color: rgba(139, 92, 246, 0.35); }
.pos-chip.DST { color: var(--dst); background: rgba(20, 184, 166, 0.1);  border-color: rgba(20, 184, 166, 0.35); }

/* =========================
   Injury indicator (Sleeper)
   ========================= */
/* Name row is now a single-line container — the injury badge has moved to
   the meta line so the full width is available for the player name. */
.player-name-row {
  display: flex;
  align-items: center;
  min-width: 0;
}
.player-name-row .player-name { flex: 0 1 auto; }

/* Severity color tokens for injuries:
   warn = Questionable / day-to-day (amber)
   bad  = Doubtful (deep orange)
   out  = Out / IR / PUP / Suspended (red) */
:root {
  --inj-warn: #f5a623;
  --inj-bad:  #ff7a45;
  --inj-out:  #ef4444;
}

/* =========================
   Injury status chip (redesigned)
   A clean, modern status indicator: a small severity "signal" dot followed by
   the short designation code, on a subtly tinted glassy pill. The dot carries
   the severity colour at a glance; "out"-level severities gently pulse to draw
   the eye. Replaces the old busy medical-kit-icon + text look.
   ========================= */
.injury-badge {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 18px;
  padding: 0 7px 0 6px;
  border-radius: 5px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
  cursor: pointer;
  border: 1px solid transparent;
  transition: transform 0.12s var(--ease), filter 0.12s var(--ease), background 0.12s var(--ease);
  -webkit-tap-highlight-color: transparent;
  white-space: nowrap;
}
/* Only render the badge for players who actually carry a designation. The JS
   sets `hidden` on healthy players, but `display: inline-flex` above outranks
   the UA `[hidden] { display: none }` rule — so we must restore it explicitly,
   otherwise every healthy player shows an empty chip. */
.injury-badge[hidden] { display: none; }
.injury-badge:active { transform: scale(0.94); }
@media (hover: hover) {
  .injury-badge:hover { filter: brightness(1.12); }
}

/* Severity signal dot — the core of the new look. A crisp filled dot with a
   soft matching glow ring, so severity is legible even at a glance. */
.injury-badge-dot {
  width: 6px;
  height: 6px;
  flex: 0 0 6px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 22%, transparent);
}

.injury-badge-text { line-height: 1; }

.injury-badge.sev-warn {
  color: var(--inj-warn);
  background: rgba(245, 166, 35, 0.12);
  border-color: rgba(245, 166, 35, 0.34);
}
.injury-badge.sev-bad {
  color: var(--inj-bad);
  background: rgba(255, 122, 69, 0.13);
  border-color: rgba(255, 122, 69, 0.36);
}
.injury-badge.sev-out {
  color: var(--inj-out);
  background: rgba(239, 68, 68, 0.14);
  border-color: rgba(239, 68, 68, 0.4);
}

/* Draw the eye to the most serious designations with a gentle pulse on the
   signal dot (respecting reduced-motion via the global override below). */
.injury-badge.sev-out .injury-badge-dot {
  animation: inj-dot-pulse 1.8s var(--ease) infinite;
}
@keyframes inj-dot-pulse {
  0%, 100% { box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 30%, transparent); }
  50%      { box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 0%, transparent); }
}

/* Header "Injuries" button — subtle accent when it carries no special state;
   spins while fetching. The wrapper keeps the native cooldown tooltip hoverable
   even while the actual button is disabled. */
.injury-btn-wrap { display: inline-flex; }
.injury-btn.is-loading { opacity: 0.7; cursor: progress; }
.injury-btn.is-cooldown { opacity: 0.55; cursor: not-allowed; }
.injury-btn:disabled:hover { background: transparent; border-color: transparent; }

/* =========================
   Injury detail popover
   ========================= */
.injury-pop {
  position: fixed;
  z-index: 1200;
  width: min(280px, calc(100vw - 24px));
  background: var(--bg-elev-2);
  border: 1px solid var(--border-strong);
  border-radius: 12px;
  box-shadow: var(--shadow), var(--surface-highlight);
  padding: 12px 13px 11px;
  animation: inj-pop-in 0.14s var(--ease);
  border-top-width: 3px;
}
@keyframes inj-pop-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.injury-pop.sev-warn { border-top-color: var(--inj-warn); }
.injury-pop.sev-bad  { border-top-color: var(--inj-bad); }
.injury-pop.sev-out  { border-top-color: var(--inj-out); }

.injury-pop-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}
.injury-pop-status {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.injury-pop.sev-warn .injury-pop-status { color: var(--inj-warn); }
.injury-pop.sev-bad  .injury-pop-status { color: var(--inj-bad); }
.injury-pop.sev-out  .injury-pop-status { color: var(--inj-out); }
.injury-pop-close {
  display: grid;
  place-items: center;
  width: 24px; height: 24px;
  border-radius: 7px;
  color: var(--text-muted);
  flex: 0 0 auto;
}
@media (hover: hover) {
  .injury-pop-close:hover { background: var(--bg-elev); color: var(--text); }
}
.injury-pop-name {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 6px;
}
.injury-pop-body {
  font-size: 12.5px;
  color: var(--text-dim);
  font-weight: 500;
  margin-bottom: 4px;
}
.injury-pop-notes {
  font-size: 12.5px;
  color: var(--text);
  line-height: 1.45;
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}
.injury-pop-foot {
  font-size: 10.5px;
  color: var(--text-muted);
  margin-top: 9px;
  letter-spacing: 0.01em;
}

/* Actions */
.player-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}
.icon-btn {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 9px;
  color: var(--text-muted);
  transition: all 0.15s var(--ease);
  font-size: 15px;
}
@media (hover: hover) {
  .icon-btn:hover { background: var(--bg-elev-2); color: var(--text); }
}
.icon-btn:active { transform: scale(0.92); }

.icon-btn.star.active {
  color: var(--star);
  background: rgba(255, 204, 77, 0.1);
}
.icon-btn.pick.active {
  color: var(--success);
  background: rgba(34, 197, 94, 0.12);
}
/* "Draft to my team" button — azure to match the .mine row treatment. */
.icon-btn.mine-btn.active {
  color: var(--mine);
  background: var(--mine-soft);
}

/* =========================
   Tier Break Row
   ========================= */
.tier-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  margin: 8px 0 2px;
  background: linear-gradient(90deg, rgba(91, 140, 255, 0.14), rgba(91, 140, 255, 0.03));
  border: 1px solid rgba(91, 140, 255, 0.4);  /* was 0.25 — more presence */
  border-radius: var(--radius-sm);
  min-height: 44px;
  touch-action: pan-y;
  -webkit-tap-highlight-color: transparent;
}
.tier-row .drag-handle { color: var(--accent); }
.tier-label {
  flex: 1;
  font-size: 12.5px;  /* was 12px — slightly bigger as tier anchors */
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  background: transparent;
  border: none;
  outline: none;
  padding: 4px 0;
  font-family: inherit;
}
.tier-label:focus {
  background: rgba(0,0,0,0.25);
  border-radius: 6px;
  padding: 4px 8px;
}
.tier-row .icon-btn { color: var(--accent); }
.tier-row .icon-btn:hover { background: rgba(91, 140, 255, 0.15); color: var(--accent); }

/* =========================
   My Team — header badge + meta
   ========================= */
/* Header button stays a quiet ghost button; the badge is the live signal. */
.my-team-btn { position: relative; }
/* Count badge: a small, integrated pill sitting inline after the label with a
   consistent left margin. Refined azure — a softer translucent fill with a
   crisp accent-coloured numeral, so it reads as part of the button rather than
   a bolted-on sticker. */
.my-team-badge {
  display: inline-grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  margin-left: 8px;
  border-radius: 999px;
  background: rgba(79, 158, 255, 0.18);
  border: 1px solid rgba(79, 158, 255, 0.35);
  color: var(--mine);
  font-size: 11.5px;
  font-weight: 700;
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
/* The badge is toggled via the `hidden` attribute in JS; restore the UA rule
   the `display: inline-grid` above would otherwise override (so it never
   flashes a "0" for an empty roster). */
.my-team-badge[hidden] { display: none; }
.my-team-btn[aria-expanded="true"] {
  color: var(--mine);
  border-color: rgba(79, 158, 255, 0.45);
  background: var(--mine-soft);
}
/* Keep the azure focus ring for My Team consistent with its accent, while the
   generic .btn:focus-visible (orange) covers Injuries / Add Tier / overflow. */
.my-team-btn:focus-visible {
  border-color: rgba(79, 158, 255, 0.6);
  box-shadow: 0 0 0 3px var(--mine-glow);
}

/* Meta line entry for My Team count (only shows when non-zero). */
.meta-myteam { color: var(--mine); font-weight: 600; }

/* =========================
   My Team — drawer
   ========================= */
.team-drawer {
  position: fixed;
  inset: 0;
  z-index: 90;              /* below modal (100) & toast (200), above header */
}
.team-drawer[hidden] { display: none; }

.team-backdrop {
  position: absolute;
  inset: 0;
  /* Phase 4: removed backdrop-filter blur — biggest mobile GPU paint win.
     Deeper dim (0.65) compensates by making the modal contrast higher. */
  background: rgba(0,0,0,0.65);
  opacity: 0;
  transition: opacity 0.28s var(--ease);
}
.team-drawer.open .team-backdrop { opacity: 1; }

.team-panel {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: 400px;
  max-width: 92vw;
  display: flex;
  flex-direction: column;
  /* Phase 1: two elevation steps above the page so it clearly floats */
  background: var(--bg-elev);
  border-left: 1px solid var(--border-strong);
  box-shadow: -20px 0 60px rgba(0,0,0,0.65), var(--surface-highlight);
  /* Slide-in: starts off-screen to the right, eased into place. */
  transform: translateX(100%);
  transition: transform 0.3s var(--ease);
  /* Respect the device notch / status bar on mobile. */
  padding-top: env(safe-area-inset-top);
}
.team-drawer.open .team-panel { transform: translateX(0); }

.team-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
  flex: 0 0 auto;
}
.team-title-wrap { display: flex; align-items: center; gap: 12px; min-width: 0; }
.team-title-icon {
  width: 38px; height: 38px;
  border-radius: 11px;
  display: grid; place-items: center;
  background: var(--mine-soft);
  border: 1px solid rgba(79, 158, 255, 0.35);
  color: var(--mine);
  font-size: 16px;
  flex: 0 0 auto;
}
.team-header h2 { font-size: 17px; letter-spacing: -0.01em; line-height: 1.1; }
.team-summary {
  display: block;
  font-size: 11.5px;
  color: var(--text-dim);
  font-weight: 500;
  letter-spacing: 0.02em;
  margin-top: 2px;
}
.team-close { width: 38px; height: 38px; font-size: 17px; flex: 0 0 auto; }

.team-body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 12px 16px calc(24px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 16px;
  /* Phase 3: themed scrollbar so default grey doesn't break the dark theme */
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
.team-body::-webkit-scrollbar { width: 6px; }
.team-body::-webkit-scrollbar-track { background: transparent; }
.team-body::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }

/* Position group */
.team-group { display: flex; flex-direction: column; gap: 6px; }
.team-group-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 4px 8px;
}
.team-group-pos {
  /* reuses .pos-chip; color it with the position palette */
  background: var(--bg-elev-2);
}
.team-group-pos.QB  { color: var(--qb);  border-color: rgba(239,68,68,0.4); }
.team-group-pos.RB  { color: var(--rb);  border-color: rgba(34,197,94,0.4); }
.team-group-pos.WR  { color: var(--wr);  border-color: rgba(59,130,246,0.4); }
.team-group-pos.TE  { color: var(--te);  border-color: rgba(245,158,11,0.4); }
.team-group-pos.K   { color: var(--k);   border-color: rgba(139,92,246,0.4); }
.team-group-pos.DST { color: var(--dst); border-color: rgba(20,184,166,0.4); }
.team-group-label {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.team-group-count {
  margin-left: auto;
  min-width: 22px;
  text-align: center;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Roster row — steps up to --bg-elev-2 so rows read against the drawer (--bg-elev) */
.team-row {
  display: grid;
  grid-template-columns: 28px 34px minmax(0, 1fr) 36px;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  border-left: 3px solid var(--mine);
  animation: fade-in 0.18s var(--ease);
}
.team-row-rank {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-muted);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.team-row-logo {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 8px;  /* matches main list team-logo */
  overflow: hidden;
}
.team-row-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
.team-row-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.team-row-name {
  font-weight: 600;
  font-size: 14.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: -0.01em;
}
.team-row-meta { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--text-dim); }
.team-row-remove { width: 36px; height: 36px; font-size: 14px; color: var(--text-muted); }
.team-row-remove:hover { color: var(--danger); background: rgba(239, 68, 68, 0.1); }

/* Empty roster */
.team-empty {
  margin: 40px 20px;
  text-align: center;
  color: var(--text-dim);
}
.team-empty .icon { font-size: 34px; margin-bottom: 12px; color: var(--mine); opacity: 0.7; }
.team-empty p { font-size: 15px; font-weight: 600; margin: 0 0 6px; color: var(--text); }
.team-empty span { font-size: 12.5px; color: var(--text-dim); }
.team-empty span .icon { font-size: 11px; color: var(--mine); margin: 0 2px; }

/* =========================
   Modal
   ========================= */
.modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 20px;
}
.modal[hidden] { display: none; }
.modal-backdrop {
  position: absolute;
  inset: 0;
  /* Phase 4: removed backdrop-filter blur — eliminates expensive full-screen GPU paint.
     Deeper dim (0.72) gives the modal more perceived contrast vs the page. */
  background: rgba(0,0,0,0.72);
  animation: fade-in 0.2s var(--ease);
}
.modal-card {
  position: relative;
  width: 100%;
  max-width: 420px;
  /* Phase 1: modal sits at elevation-2 (two steps above page) so it clearly floats */
  background: var(--bg-elev-2);
  border: 1px solid var(--border-strong);
  border-radius: 16px;
  padding: 22px;
  box-shadow: var(--shadow), var(--surface-highlight);
  animation: pop-in 0.22s var(--ease);
}
.modal-card h2 { font-size: 18px; margin-bottom: 8px; }
.modal-card p { color: var(--text-dim); font-size: 14px; margin: 0 0 18px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }

/* =========================
   Toast
   ========================= */
.toast {
  position: fixed;
  bottom: calc(24px + env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: var(--bg-elev-2);
  color: var(--text);
  padding: 12px 18px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  font-size: 13px;
  font-weight: 600;
  box-shadow: var(--shadow);
  opacity: 0;
  transition: all 0.25s var(--ease);
  z-index: 200;
  pointer-events: none;
  max-width: 90vw;
}
.toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* =========================
   Empty state
   ========================= */
.empty-state {
  padding: 60px 20px;
  text-align: center;
  color: var(--text-dim);
}
.empty-state .icon { font-size: 38px; margin-bottom: 10px; color: var(--text-muted); }
.empty-state p { font-size: 14px; margin: 0; }

/* =========================
   Animations
   ========================= */
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes pop-in {
  from { opacity: 0; transform: scale(0.95) translateY(8px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}

/* =========================
   Context menu (mobile — wires up the existing #context-menu markup)
   Positioned dynamically near the tap point via JS.
   ========================= */
.context-menu-backdrop {
  position: fixed;
  inset: 0;
  z-index: 800;
  background: transparent;  /* transparent — just a tap-dismiss layer */
}
.context-menu-backdrop[hidden] { display: none; }

.context-menu {
  position: fixed;
  z-index: 810;
  min-width: 210px;
  /* Slightly lifted, lighter surface so the menu reads as clearly floating
     above the row it belongs to. A soft accent-tinted top edge ties it into
     the app's warm-blue theme without shouting. */
  background:
    linear-gradient(180deg, rgba(255,255,255,0.035), transparent 60%),
    var(--bg-elev-2);
  border: 1px solid var(--border-strong);
  border-radius: 14px;
  padding: 7px;
  box-shadow:
    0 18px 44px rgba(0,0,0,0.62),
    0 2px 10px rgba(0,0,0,0.4),
    var(--surface-highlight);
  animation: ctx-pop-in 0.15s var(--ease);
  transform-origin: top right;
}
.context-menu[hidden] { display: none; }

@keyframes ctx-pop-in {
  from { opacity: 0; transform: translateY(-6px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.context-menu-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 11px 12px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  text-align: left;
  transition: background 0.13s var(--ease), color 0.13s var(--ease);
}
.context-menu-item + .context-menu-item { margin-top: 2px; }

/* Each row leads with a small tinted glyph tile so the two actions are
   instantly distinguishable and colour-coded to match their inline states. */
.context-menu-item .icon {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  border-radius: 9px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 14px;
  transition: color 0.13s var(--ease), background 0.13s var(--ease), border-color 0.13s var(--ease);
}

.context-menu-item:hover,
.context-menu-item:active { background: var(--bg-elev); }
.context-menu-item:hover .icon { color: var(--text); }

/* Active (already-applied) state — tint the glyph tile with the action's colour
   so it matches the corresponding row treatment (gold favorite / azure mine). */
.context-menu-item[data-ctx-action="favorite"].ctx-active .icon {
  color: var(--star);
  background: rgba(255, 204, 77, 0.12);
  border-color: rgba(255, 204, 77, 0.4);
}
.context-menu-item[data-ctx-action="mine"].ctx-active .icon {
  color: var(--mine);
  background: var(--mine-soft);
  border-color: rgba(79, 158, 255, 0.4);
}

/* =========================
   Responsive
   ========================= */
@media (max-width: 640px) {
  body { font-size: 14.5px; }

  /* ================================================================
     Phase A — Mobile Header Compaction
     Shrinks every header element so the top bar reads as designed for
     a phone, not a scaled-down desktop. Net gain: ~14–18px vertical,
     and one extra player row becomes visible.
     ================================================================ */

  /* Tighter inner padding: 8px 12px instead of 10px 14px */
  .header-inner { padding: 8px 12px; }

  /* Brand logo: shrink to keep the compact mobile header height */
  .brand-logo { height: 32px; }

  /* Icon-only header buttons: 36px squares, tighter gap */
  .btn-label { display: none; }
  .header-actions { gap: 6px; }
  .header-actions .btn {
    width: 36px;
    height: 36px;
    padding: 0;
    gap: 0;
    border-radius: 9px;
    /* Extend tap area to 44px with an invisible ::after — no paint cost */
    position: relative;
  }
  .header-actions .btn::after {
    content: '';
    position: absolute;
    inset: -4px;
  }
  .header-actions .btn > .icon { font-size: 15px; }

  /* My Team may still carry a count pill, so let it grow past the square */
  .header-actions .my-team-btn { width: auto; padding: 0 10px; gap: 6px; }

  /* Smaller count badge to sit flush with the 36px button */
  .my-team-badge {
    margin-left: 4px;
    min-width: 17px;
    height: 17px;
    padding: 0 5px;
    font-size: 10.5px;
  }

  /* Hide "Add Tier" from the header on mobile — moved into the ⋯ overflow menu.
     It's a prep-time action, not a live-draft action. Header becomes:
     brand · Injuries · My Team · ⋯  (three elements, designed-for-phone feel). */
  #add-tier-btn { display: none; }

  /* ================================================================
     Tabs: tighter padding + right-fade so DST isn't clipped
     ================================================================ */
  .tabs {
    padding: 0 8px;
    /* Right-edge fade signals horizontal scrollability */
    -webkit-mask-image: linear-gradient(90deg, #000 82%, transparent 100%);
    mask-image: linear-gradient(90deg, #000 82%, transparent 100%);
  }

  /* Phase D: slightly tighter tab padding + indicator stays within its label inset */
  .tab { padding: 8px 13px; font-size: 13px; }
  .tab::after { right: 13px; left: 13px; }

  /* Lighter header blur on phones — backdrop-filters re-run every scroll frame */
  .app-header {
    background: rgba(7,7,9,0.94);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
  }

  /* Phase D: unify app-main top padding to 8px — one spacing grid for the whole page */
  .app-main { padding: 8px 10px 60px; }

  /* Phase D: Toolbar — match the new header scale */
  .toolbar { gap: 8px; }
  .search-wrap { flex: 1 1 100%; min-width: 100%; }
  .filter-toggles { flex: 1 1 100%; }
  .search-input { height: 36px; border-radius: 10px; }
  .filter-chip { flex: 1 1 0; justify-content: center; height: 36px; padding: 0 10px; border-radius: 10px; }

  /* Phase D: list-meta line — tertiary info, reduce size */
  .list-meta { font-size: 11.5px; padding: 4px 8px 10px; }

  /* ================================================================
     Phase B — Injury badge now lives in .player-meta.
     On mobile, shrink it to sit flush with the 10.5px meta text.
     Also disable the sev-out pulse (30+ infinite animations on IR
     players is the one non-free thing — removing it on mobile is a
     small paint win).
     ================================================================ */
  .injury-badge {
    height: 15px;
    padding: 0 5px;
    font-size: 9px;
    border-radius: 4px;
    gap: 4px;
  }
  .injury-badge-dot {
    width: 5px;
    height: 5px;
    flex: 0 0 5px;
  }
  /* Disable the infinite pulse on mobile — paint win */
  .injury-badge.sev-out .injury-badge-dot {
    animation: none;
  }

  /* ================================================================
     Phase C — Row Density & Name-Truncation Pass
     Target: ~52px row height, name column gains ~45–55px so full NFL
     names fit untruncated at 360px.

     Layout:  [handle][rank][logo]  Player Name        ECR ±N   [✓][⋯]
                                    RB · ATL · BYE 11 · ●Q
     ================================================================ */
  .player-row {
    /* Tighter grid: 20px handle, 24px rank, 28px logo */
    grid-template-columns: 20px 24px 28px minmax(0, 1fr) auto auto;
    grid-template-rows: 1fr;
    align-items: center;
    gap: 5px;
    padding: 0 7px 0 2px;
    min-height: 52px;
    border-radius: 9px;
    /* Sync content-visibility intrinsic size */
    contain-intrinsic-size: auto 52px;
  }

  /* Drag handle: 20px wide, keep 44px min tap area */
  .drag-handle { width: 20px; height: 100%; min-height: 44px; font-size: 12px; }

  /* Rank: 24px column, 11.5px mono — 3 digits still fit in JetBrains Mono */
  .rank { font-size: 11.5px; }

  /* Team logo: keep 28px as visual anchor; drop border to a 1px inset —
     one less contrast edge, calmer rows */
  .team-logo {
    width: 28px;
    height: 28px;
    border-radius: 6px;
    flex: 0 0 28px;
    border-color: transparent;
    box-shadow: inset 0 0 0 1px var(--border);
  }

  /* Player info: tighter stack */
  .player-info { gap: 1px; min-width: 0; }

  /* Player name: 13.5px with tighter tracking — Inter stays crisp */
  .player-name { font-size: 13.5px; letter-spacing: -0.015em; }

  /* Meta line: 10.5px — badge sits here now, same size as meta text */
  .player-meta { font-size: 10.5px; gap: 4px; }
  .player-bye  { font-size: 10.5px; }

  /* Compare: compact ECR pill — with the label hidden, the pill is
     oversized for a 2-char value; tighten it */
  .player-compare {
    flex: 0 0 auto;
    gap: 0;
  }
  .compare-cell {
    min-width: 34px;
    padding: 2px 5px;
    gap: 2px;
  }
  .compare-label { display: none; }
  .compare-value { font-size: 11.5px; }

  /* Phase D: ECR neutral/even pill — transparent bg so green/red pops more */
  .compare-cell.delta-even,
  .compare-cell.delta-neutral {
    background: transparent;
    border-color: transparent;
  }

  /* Actions: 34px buttons with extended tap area via ::after */
  .player-actions {
    flex-direction: row;
    gap: 2px;
    flex: 0 0 auto;
  }
  .icon-btn {
    width: 34px;
    height: 34px;
    font-size: 14px;
    position: relative;
  }
  .icon-btn::after {
    content: '';
    position: absolute;
    inset: -4px;
  }

  /* Hide favorite (★) & mine on mobile — they live in the context menu */
  .icon-btn.star,
  .icon-btn.mine-btn {
    display: none;
  }

  /* Show the ⋯ context menu trigger (mobile-only) */
  .icon-btn.ctx-btn {
    display: grid;
  }

  /* Drawer is a near full-screen sheet on phones */
  .team-panel { width: 100%; max-width: 100%; }
  .team-row { grid-template-columns: 24px 32px minmax(0, 1fr) 34px; gap: 9px; }
  .team-row-logo { width: 32px; height: 32px; }
}

/* When the drawer is open, lock the background so the page doesn't scroll
   behind the sheet. Only at/below desktop widths (where the backdrop covers
   the viewport) — avoids a desktop scrollbar gutter shift. */
@media (max-width: 640px) {
  body.team-open { overflow: hidden; }
}

@media (max-width: 380px) {
  .player-row {
    grid-template-columns: 18px 22px 26px minmax(0, 1fr) auto auto;
    gap: 4px;
    padding: 0 6px 0 2px;
  }
  .drag-handle { width: 18px; }
  .team-logo { width: 26px; height: 26px; }
  .pos-chip { font-size: 10px; padding: 2px 5px; }
  .player-meta { gap: 3px; font-size: 10px; }
  .icon-btn { width: 32px; height: 32px; font-size: 14px; }
}

/* The ⋯ context-menu trigger only makes sense on mobile where the mine/pick
   buttons are hidden. On desktop all three actions are always visible inline. */
@media (min-width: 641px) {
  .icon-btn.ctx-btn { display: none; }
}

/* "Add Tier" is hidden from the overflow menu on desktop (it has its own
   header button). On mobile the header button is hidden and this menu item
   is shown instead — see Phase A. */
.menu-item-mobile-only { display: none; }
.menu-sep-mobile-only  { display: none; }
@media (max-width: 640px) {
  .menu-item-mobile-only { display: flex; }
  .menu-sep-mobile-only  { display: block; }
}

/* Reduce motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* =========================
   Player-info tap affordance
   Non-DST rows show a subtle chevron after the player name + pointer cursor
   so users know the name/meta block is tappable to open the Player Card.
   DST rows do NOT get this — no card data exists for them.
   ========================= */
.player-row:not([data-position="DST"]) .player-info {
  cursor: pointer;
}
/* Subtle chevron hint on the name — CSS-only, zero DOM nodes. */
.player-row:not([data-position="DST"]) .player-name::after {
  content: ' ›';
  font-size: 11px;
  color: var(--text-muted);
  opacity: 0;
  margin-left: 3px;
  transition: opacity 0.15s var(--ease);
  vertical-align: middle;
}
@media (hover: hover) {
  .player-row:not([data-position="DST"]) .player-info:hover .player-name::after {
    opacity: 1;
  }
}
/* On touch devices / mobile: always show a faint chevron so the affordance
   is discoverable without hover. */
@media (hover: none) {
  .player-row:not([data-position="DST"]) .player-name::after {
    opacity: 0.45;
  }
}

/* =========================
   Player Card — v2 redesign
   Editorial, data-forward profile: hairline rules instead of boxed tiles,
   a refined type scale with tabular numerals, and calm, even spacing.
   Bottom-sheet on mobile (≤640px), centered card above.
   ========================= */

/* Backdrop — slightly deeper dim + blur for focus */
.card-backdrop {
  position: fixed;
  inset: 0;
  z-index: 85;
  background: rgba(2, 2, 4, 0.7);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 0.28s var(--ease);
}
.card-backdrop[hidden] { display: none; }
body.card-open .card-backdrop { opacity: 1; }

/* The card itself */
.player-card {
  position: fixed;
  z-index: 86;
  background: linear-gradient(180deg, #191921 0%, #14141b 100%);
  border: 1px solid var(--border-strong);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 4px 16px rgba(0, 0, 0, 0.4),
              inset 0 1px 0 rgba(255, 255, 255, 0.04);
  display: flex;
  flex-direction: column;
  overflow: hidden;

  /* Desktop: centered card */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.97);
  width: min(440px, calc(100vw - 32px));
  max-height: min(680px, calc(100vh - 80px));
  border-radius: 16px;
  opacity: 0;
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
.player-card[hidden] { display: none; }
.player-card.open {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

/* Close button — quiet ghost circle, top-right */
.card-close {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 2;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.07);
  font-size: 13px;
  transition: color 0.15s var(--ease), background 0.15s var(--ease);
}
.card-close:hover { color: var(--text); background: rgba(255, 255, 255, 0.1); }

/* ---- Header ----
   Headshot in a soft ring; name set large and tight; identity line
   (logo · team · pos · number) reads as one quiet metadata row. */
.card-header {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 24px 24px 18px;
  flex: 0 0 auto;
}

.card-headshot-wrap {
  flex: 0 0 64px;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  overflow: hidden;
  background: radial-gradient(circle at 50% 30%, #23232d, #17171f);
  border: 1px solid var(--border-strong);
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.03);
}
.card-headshot {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Team-logo fallback: contain, with breathing room */
.card-headshot.card-headshot-fallback {
  object-fit: contain;
  padding: 12px;
}

.card-header-info {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-right: 30px; /* clear the close button */
}
.card-name {
  font-size: 20px;
  font-weight: 750;
  letter-spacing: -0.025em;
  line-height: 1.15;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card-header-meta-row {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}
.card-team-logo {
  width: 18px;
  height: 18px;
  object-fit: contain;
  flex: 0 0 18px;
}
.card-header-meta {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.09em;
  color: var(--text-dim);
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- Rank strip → three-up stat block ----
   Big tabular numerals over small uppercase captions, separated by
   hairlines — the classic broadcast lower-third treatment. */
.card-rank-strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.014);
  flex: 0 0 auto;
}
.card-rank-item {
  display: flex;
  flex-direction: column-reverse; /* value above label in source order */
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 12px 8px 11px;
  min-width: 0;
}
.card-rank-item + .card-rank-item { border-left: 1px solid var(--border); }
.card-rank-item strong {
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
  line-height: 1;
}
.card-rank-label {
  font-size: 9px;
  font-weight: 650;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.card-rank-divider { display: none; }

/* ---- Section layout ---- */
.card-dc-panel,
.card-inj-panel {
  padding: 16px 24px;
  border-bottom: 1px solid var(--border);
  flex: 0 0 auto;
}
.card-dc-panel[hidden],
.card-inj-panel[hidden],
.card-bio-strip[hidden] { display: none; }

.card-section-title {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 10px;
}

/* ---- Depth chart ----
   One quiet ruled list: no per-row boxes. The selected player is marked
   with an accent bar + tinted row instead of a heavy outlined card. */
.card-dc-list {
  list-style: none;
  margin: 0 -10px;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.card-dc-list[hidden] { display: none; }

.card-dc-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 10px;
  border-radius: 8px;
  font-size: 13.5px;
  line-height: 1.3;
}
.card-dc-item + .card-dc-item { margin-top: 1px; }
.card-dc-item.card-dc-self {
  background: linear-gradient(90deg, rgba(91, 140, 255, 0.10), rgba(91, 140, 255, 0.03));
  font-weight: 650;
}
.card-dc-item.card-dc-self::before {
  content: '';
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 3px;
  border-radius: 2px;
  background: var(--accent);
}
.card-dc-rank {
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-muted);
  min-width: 18px;
  text-align: center;
}
.card-dc-self .card-dc-rank { color: var(--accent); font-weight: 800; }
.card-dc-name {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text-dim);
}
.card-dc-self .card-dc-name { color: var(--text); }

/* Rank badge for the player's own row — e.g. "RB1" */
.card-dc-badge {
  margin-left: auto;
  flex: 0 0 auto;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  font-weight: 750;
  letter-spacing: 0.08em;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(91, 140, 255, 0.14);
  border: 1px solid rgba(91, 140, 255, 0.32);
  color: var(--accent-2);
}

/* Slot tag shown on every WR row — e.g. "LWR1", "SWR2". */
.card-dc-slot {
  margin-left: auto;
  flex: 0 0 auto;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  font-weight: 650;
  letter-spacing: 0.08em;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--border);
  color: var(--text-muted);
}
.card-dc-slot.card-dc-slot-self {
  background: rgba(91, 140, 255, 0.14);
  border-color: rgba(91, 140, 255, 0.32);
  color: var(--accent-2);
  font-weight: 750;
}

.card-dc-empty {
  font-size: 12.5px;
  color: var(--text-muted);
  padding: 2px 0;
}
.card-dc-empty[hidden] { display: none; }

/* ---- Injury panel ---- */
.card-inj-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.card-inj-status {
  font-size: 10.5px;
  font-weight: 750;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 999px;
  padding: 3px 10px;
  background: rgba(255, 255, 255, 0.05);
}
.card-inj-status.sev-warn {
  color: var(--inj-warn);
  background: rgba(245, 166, 35, 0.1);
  border: 1px solid rgba(245, 166, 35, 0.3);
}
.card-inj-status.sev-bad {
  color: var(--inj-bad);
  background: rgba(255, 122, 69, 0.11);
  border: 1px solid rgba(255, 122, 69, 0.32);
}
.card-inj-status.sev-out {
  color: var(--inj-out);
  background: rgba(239, 68, 68, 0.12);
  border: 1px solid rgba(239, 68, 68, 0.36);
}
.card-inj-body {
  font-size: 12.5px;
  color: var(--text-dim);
  font-weight: 500;
}
.card-inj-body[hidden], .card-inj-notes[hidden] { display: none; }
.card-inj-notes {
  font-size: 12.5px;
  color: var(--text-dim);
  line-height: 1.5;
  margin-top: 8px;
}

/* ---- Bio strip ----
   One ruled row, five equal-rhythm cells split by hairlines — no boxes.
   College is text, not a number, so it renders in Inter at a size that
   wraps to two tidy lines instead of inflating its cell. */
.card-bio-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr)) minmax(0, 1.9fr);
  align-items: stretch;
  padding: 0 24px;
  border-bottom: 1px solid var(--border);
  flex: 0 0 auto;
}
.card-bio-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 0;
  padding: 14px 6px 13px;
}
.card-bio-item + .card-bio-item { border-left: 1px solid var(--border); }
.card-bio-label {
  font-size: 9px;
  font-weight: 650;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.card-bio-value {
  max-width: 100%;
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 13.5px;
  font-weight: 650;
  color: var(--text);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.15;
}
.card-bio-college .card-bio-value {
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0;
  display: -webkit-box;
  white-space: normal;
  overflow-wrap: normal;
  word-break: normal;
  hyphens: auto;
  line-height: 1.3;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

/* ---- Footer ---- */
.card-foot {
  padding: 12px 24px 16px;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  text-align: center;
  flex: 0 0 auto;
}

/* =====================
   Mobile: bottom-sheet
   ===================== */
@media (max-width: 640px) {
  .player-card {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    transform: translateY(100%);
    width: 100%;
    max-width: 100%;
    max-height: 88vh;
    border-radius: 20px 20px 0 0;
    border-bottom: none;
    padding-bottom: env(safe-area-inset-bottom);
    opacity: 1; /* opacity is managed via transform on mobile */
  }
  .player-card.open {
    transform: translateY(0);
    opacity: 1;
  }

  /* Pull-handle hint at the top of the sheet */
  .player-card::before {
    content: '';
    display: block;
    width: 36px;
    height: 4px;
    border-radius: 2px;
    background: var(--border-strong);
    margin: 10px auto 0;
    flex: 0 0 auto;
    position: sticky;
    top: 0;
  }

  .card-header { padding: 16px 20px 14px; gap: 14px; }
  .card-headshot-wrap { width: 56px; height: 56px; flex: 0 0 56px; }
  .card-name { font-size: 18px; }
  .card-dc-panel,
  .card-inj-panel { padding: 14px 20px; }
  .card-bio-strip { padding: 0 20px; }
  .card-foot { padding: 11px 20px 14px; }
  .card-close { top: 16px; right: 16px; }

  .card-rank-item { padding: 11px 6px 10px; }
  .card-rank-item strong { font-size: 16px; }
  .card-rank-label { font-size: 8.5px; letter-spacing: 0.1em; }

  /* Bio keeps the same ruled single-row rhythm; cells simply compress. */
  .card-bio-item { padding: 12px 4px 11px; }
  .card-bio-value { font-size: 12.5px; }
  .card-bio-college .card-bio-value { font-size: 11px; }
}

/* Lock background scroll when the card is open (mobile). */
@media (max-width: 640px) {
  body.card-open { overflow: hidden; }
}

/* =========================
   Bright theme surface refinements
   ========================= */
:root[data-theme="bright"] body {
  background:
    radial-gradient(1200px 600px at 80% -200px, rgba(53, 110, 232, 0.12), transparent 60%),
    radial-gradient(900px 500px at -10% 10%, rgba(99, 148, 255, 0.09), transparent 60%),
    var(--bg);
}
:root[data-theme="bright"] .app-header { background: rgba(245, 247, 251, 0.88); }
:root[data-theme="bright"] .brand-logo { filter: brightness(0) saturate(100%) invert(12%) sepia(16%) saturate(1427%) hue-rotate(182deg) brightness(93%); }
:root[data-theme="bright"] .btn-ghost { background: #ffffff; border-color: var(--border); }
:root[data-theme="bright"] .btn-ghost:hover,
:root[data-theme="bright"] #menu-btn[aria-expanded="true"] { background: #e8edf6; border-color: var(--border-strong); }
:root[data-theme="bright"] .menu-item.danger,
:root[data-theme="bright"] .menu-item.danger .icon { color: #c62828; }
:root[data-theme="bright"] .team-backdrop { background: rgba(30, 41, 59, 0.4); }
:root[data-theme="bright"] .team-panel { box-shadow: -20px 0 60px rgba(39, 55, 82, 0.2), var(--surface-highlight); }
:root[data-theme="bright"] .modal-backdrop { background: rgba(30, 41, 59, 0.48); }
:root[data-theme="bright"] .context-menu {
  background: linear-gradient(180deg, rgba(53,110,232,0.04), transparent 60%), var(--bg-elev-2);
  box-shadow: var(--shadow), var(--surface-highlight);
}
:root[data-theme="bright"] .card-backdrop { background: rgba(30, 41, 59, 0.48); }
:root[data-theme="bright"] .player-card {
  background: linear-gradient(180deg, #ffffff 0%, #f6f8fc 100%);
  box-shadow: var(--shadow), var(--surface-highlight);
}
:root[data-theme="bright"] .card-close {
  background: rgba(23, 32, 51, 0.05);
  border-color: rgba(23, 32, 51, 0.1);
}
:root[data-theme="bright"] .card-close:hover { background: rgba(23, 32, 51, 0.1); }
:root[data-theme="bright"] .card-headshot-wrap {
  background: radial-gradient(circle at 50% 30%, #ffffff, #e7ebf3);
  box-shadow: 0 0 0 3px rgba(23, 32, 51, 0.04);
}
:root[data-theme="bright"] .card-rank-strip,
:root[data-theme="bright"] .card-dc-slot,
:root[data-theme="bright"] .card-inj-status { background: rgba(23, 32, 51, 0.025); }

@media (max-width: 640px) {
  :root[data-theme="bright"] .app-header { background: rgba(245, 247, 251, 0.95); }
}
