/* Barnburner "Ember" identity: the fire mark grown up — ember-black ground,
   a low orange glow rising from the bottom-left, blood-orange primary and a
   softer flame secondary. Archivo Black carries the wordmark, headlines and
   scores; JetBrains Mono does the label/nav/table work; IBM Plex Sans reads
   the body copy. Layout unchanged. */
:root {
  --bar: #0b0806; --bar2: #17110d;
  --bg: #0e0a07; --panel: #1a120b; --panel2: #241a12;
  --text: #f4ece2; --sub: #a2968a; --border: rgba(255, 255, 255, 0.09);
  --line: rgba(255, 255, 255, 0.04);
  /* on-accent ink: everything sitting on a filled ember surface */
  --ink: #150f0a;
  --accent: #e0552b; --accent2: #f0873f; --blue: #f0873f; --blue2: #e0552b;
  --red: #ff4d3d; --gold: #ffb066; --green: #3ddc84; --warn: #e8c34a;
  --danger: #ff4d3d;
  --glow: 0 0 14px rgba(224, 85, 43, 0.28);
  --radius: 16px; --topbar-h: 56px;
  --shadow: 0 6px 24px rgba(20, 16, 12, 0.32);
  /* Archivo Black is a single heavy 400 — it belongs on the wordmark,
     headlines and big numerals only. Small caps labels, nav, tabs and table
     headers get the mono; body copy gets Plex Sans. */
  --display: "Archivo Black", "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --body: "IBM Plex Sans", "Helvetica Neue", Helvetica, Arial, -apple-system, sans-serif;
}
* { box-sizing: border-box; }
/* The UA's [hidden] rule is display:none at the lowest weight, so ANY author
   `display` beats it — form.stack label{display:flex} was leaving hidden
   fields on screen. One global rule instead of patching elements one by one. */
[hidden] { display: none !important; }
body {
  margin: 0; color: var(--text);
  /* the ember bed: heat rising from the bottom-left, a cooler top-right wash */
  background:
    radial-gradient(120% 70% at 12% 104%, rgba(224, 85, 43, 0.13), transparent 62%),
    radial-gradient(900px 480px at 88% -10%, rgba(240, 135, 63, 0.06), transparent 60%),
    var(--bg);
  background-attachment: fixed;
  font: 14px/1.6 var(--body);
}
/* Archivo Black: wordmark, headlines and the numbers people stare at */
h2, .brand, .vs-score, .total, .timer, td.val {
  font-family: var(--display); font-weight: 400;
}
/* JetBrains Mono: every small uppercase label, nav item and table header */
h3, .topnav a, .tabs a, .btn, .verdict, .slot-badge, .plabel, .dyn,
.live-dot, th {
  font-family: var(--mono);
}
a { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; }
h2, h3 { margin: 0 0 8px; font-weight: 700; }
h2 { font-weight: 400; }   /* Archivo Black is 400-only; 700 would synthesise */
h2 { font-size: 1.35em; }
h3 {
  font-size: 0.8em; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--sub); font-weight: 700; margin-bottom: 10px;
}
h3 .total, h3 .plabel { letter-spacing: normal; text-transform: none; }
.sub { color: var(--sub); font-size: 0.87em; }
.hint { color: var(--sub); font-size: 0.85em; margin: 4px 0 12px; }
.empty { text-align: center; padding: 60px 0; }

/* ---- global top bar ---- */
.topbar {
  display: flex; align-items: center; gap: 18px;
  background: rgba(11, 8, 6, 0.85); color: var(--text);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  padding: 0 20px; height: var(--topbar-h);
  position: sticky; top: 0; z-index: 30;
  border-bottom: 1px solid var(--border);
}
.brand {
  color: var(--text); font-weight: 400; font-size: 1.05em;
  letter-spacing: 0.02em; text-decoration: none; white-space: nowrap;
  display: flex; align-items: center; padding: 2px 0;
}
.brand:hover { text-decoration: none; }
.brand-dot { color: var(--accent); }
.brand-mark {
  font-style: normal;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.brand-sub { font-weight: 600; color: var(--sub); margin-left: 4px; }
.topnav { display: flex; gap: 6px; align-items: center; justify-content: center; flex: 1; }
.topnav a {
  display: flex; align-items: center; padding: 6px 14px;
  color: var(--sub); font-weight: 700; font-size: 0.88em; text-decoration: none;
  text-transform: uppercase; letter-spacing: 0.4px;
  border-radius: 999px; border: 1px solid transparent;
  transition: background 0.15s, color 0.15s;
}
.topnav a:hover {
  color: #fff; background: rgba(255, 255, 255, 0.06);
  border-color: var(--border); text-decoration: none;
}
.topnav a.live { color: var(--red); text-shadow: 0 0 12px rgba(255, 77, 61, 0.6); }
.topnav a.on {
  color: var(--ink); background: linear-gradient(90deg, var(--accent), var(--accent2));
  border-color: transparent;
}
.topnav a.on:hover { color: var(--ink); }
.top-user { display: flex; align-items: center; gap: 12px; color: var(--sub); font-size: 0.9em; }
.top-user a { color: var(--sub); }
.top-user a:hover { color: var(--text); text-decoration: none; }
/* logout & stop-impersonating are POSTs now (a GET was forgeable), but they
   still have to read as the plain nav links they've always been */
.navform { display: inline; margin: 0; }
.navform button {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: var(--sub);
}
.navform button:hover { color: var(--text); }
main { max-width: 1100px; margin: 18px auto; padding: 0 20px; }
.flash {
  max-width: 1060px; margin: 12px auto 0; padding: 9px 16px;
  background: rgba(224, 85, 43, 0.12); color: #f6d5c2;
  border: 1px solid rgba(224, 85, 43, 0.45); border-radius: 6px; font-size: 0.92em;
}
.error {
  background: rgba(255, 77, 61, 0.12); color: var(--danger);
  border: 1px solid rgba(255, 77, 61, 0.45);
  padding: 8px 12px; border-radius: 6px; margin: 8px 0;
}

/* ---- cards ---- */
.card {
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 18px 20px; margin-bottom: 16px;
  box-shadow: var(--shadow);
}
.card-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr)); gap: 16px; }
/* Default is stretch: cards in a row match heights, so every gap between boxes
   is the same 16px. Add .grid-start where the two cards are wildly different
   lengths (a long form beside a short one) and the shorter would otherwise be
   padded out with dead space. */
.grid-start { align-items: start; }

/* Home right column: "Join a league" on top, the news feed filling the rest so
   its bottom lands level with the create form in the left column. The article
   list scrolls inside the card rather than pushing the row taller. */
.home-side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.home-side > .card { margin-bottom: 0; }
.home-side > .news-card {
  /* basis 0, not auto: the headline list must not count toward the column's
     natural height, or the news card drives the row and overshoots the create
     form instead of ending level with it. */
  flex: 1 1 0; min-height: 240px; display: flex; flex-direction: column;
}
.news-card > [data-panel-body] { flex: 1; min-height: 0; overflow-y: auto; }
/* .card/.board carry margin-bottom for when they stack on their own; inside a
   grid that margin lands on top of the gap, so row gaps came out 32px against
   16px column gaps. The gap alone spaces the items — but the grid then needs
   its own bottom margin, or it sits flush against whatever follows it. */
.grid > .card, .grid > .board, .cols > .card, .cols > .board { margin-bottom: 0; }
.grid, .cols { margin-bottom: 16px; }
.cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 800px) { .cols { grid-template-columns: 1fr; } }
.board {
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 18px 20px; margin-bottom: 16px;
  box-shadow: var(--shadow);
}

/* ---- data tables: modern list rows, no chrome ---- */
table { width: 100%; border-collapse: collapse; margin: 8px 0; }
th {
  text-align: left; color: var(--sub); font-weight: 700; font-size: 0.7em;
  text-transform: uppercase; letter-spacing: 0.08em;
  background: transparent;
}
th a { color: var(--sub); }
th a.on { color: var(--accent2); }
th, td { padding: 10px 8px; border-bottom: 1px solid var(--line); }
th { padding-top: 4px; padding-bottom: 6px; }
tr:last-child td { border-bottom: none; }
tbody tr:hover td, table tr:hover td { background: rgba(255, 255, 255, 0.03); }
tr.leader td { color: var(--gold); font-weight: 700; }
td.total, .mu-head .total { font-weight: 700; color: var(--accent2); }
tr.leader td.total { color: var(--gold); }

.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%; margin-right: 8px;
  background: hsl(var(--h, 26), 34%, 42%); color: #f4ece2;
  font-size: 0.78em; font-weight: 800; vertical-align: middle; flex: none;
}
.team-cell { display: flex; align-items: center; }

/* ---- buttons & forms ---- */
.btn {
  background: linear-gradient(135deg, var(--accent2), var(--accent)); color: var(--ink);
  border: none; border-radius: 999px;
  padding: 8px 18px; font-weight: 700; letter-spacing: 0.02em;
  cursor: pointer; text-decoration: none;
  display: inline-block; font-size: 0.86em;
}
.btn:hover { filter: brightness(1.12); text-decoration: none; }
.btn.small {
  padding: 4px 12px; font-size: 0.82em;
  background: var(--panel2); color: var(--text); border: 1px solid var(--border);
}
.btn.small:hover { filter: none; background: #2a1f16; border-color: rgba(255, 255, 255, 0.12); }
.btn.danger { background: linear-gradient(135deg, var(--red), #ff2447); color: #fff; border: none; }
.btn.danger:hover { filter: brightness(1.1); }
form.inline { display: inline; }
form.row { display: flex; gap: 8px; }
form.stack { display: flex; flex-direction: column; gap: 10px; max-width: 480px; }
form.stack label { display: flex; flex-direction: column; gap: 4px; color: var(--sub); font-size: 0.9em; font-weight: 600; }
.cfg { display: flex; flex-direction: column; gap: 10px; padding: 12px; background: var(--panel2); border-radius: 8px; }
input, select {
  background: #0b0806; color: var(--text); border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px; padding: 8px 11px; font-size: 0.95em;
}
select option { background: #0b0806; }
input:focus, select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(224, 85, 43, 0.22); }
input.num { width: 60px; }
ul.members { list-style: none; padding: 0; margin: 0 0 12px; }
ul.members li {
  padding: 6px 0; border-bottom: 1px solid var(--line);
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
}

/* ---- draft room ---- */
.narrow { max-width: 420px; margin: 40px auto; }
.draft-clock { display: flex; justify-content: space-between; align-items: center; gap: 18px; flex-wrap: wrap; }
.timer { font-size: 1.6em; font-weight: 400; color: var(--accent2); text-shadow: 0 0 14px rgba(240, 135, 63, 0.5); }
.timer.low { color: var(--danger); text-shadow: 0 0 14px rgba(255, 77, 61, 0.6); }
.pool { max-height: 560px; overflow-y: auto; margin-top: 8px; }
body.my-turn .draft-clock { outline: 2px solid var(--accent2); border-radius: 8px; box-shadow: 0 0 22px rgba(240, 135, 63, 0.32); }
.sport-card h3 { font-size: 1.2em; }

/* ---- headshots: circle bubbles (cover-cropped so faces fill the circle) ---- */
img.headshot {
  width: 40px; height: 40px; flex: none; border-radius: 50%;
  background: radial-gradient(circle at 50% 35%, #2a1f16 0%, #150f0a 100%);
  border: 1px solid var(--border);
  object-fit: cover; object-position: center 18%;
}
img.headshot.big {
  width: 120px; height: 120px; border-width: 2px;
  border-color: var(--accent);
}
.pcell { display: flex; align-items: center; gap: 10px; color: var(--text); font-weight: 600; }
a.pcell:hover { text-decoration: underline; }
.pcell .sub { font-weight: 400; }
.hero { display: flex; align-items: center; gap: 22px; }
.fa { color: var(--green); font-weight: 700; }
.news-item { padding: 8px 0; border-bottom: 1px solid var(--line); }
.news-item:last-child { border-bottom: none; }
.news-item a { font-weight: 700; }
.news-item p { margin: 2px 0 0; }

/* ---- league chrome: header + sticky segmented tab bar ---- */
.league-head { margin: 2px 0 0; display: flex; align-items: baseline;
  gap: 12px; flex-wrap: wrap; }
.league-head h2 { margin-bottom: 0; }
.league-head .sub { margin: 0; }
.tabs {
  display: flex; gap: 4px; flex-wrap: nowrap; margin: 12px -20px 18px;
  padding: 0 20px; overflow-x: auto; scrollbar-width: none;
  background: rgba(11, 8, 6, 0.82);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
  position: sticky; top: var(--topbar-h); z-index: 25;
}
.tabs::-webkit-scrollbar { display: none; }
/* The tab bar goes full-bleed with negative margins, which pushes it past
   main's padding box and gives the whole page a 10px sideways scroll on a
   phone. `clip` rather than `hidden`: hidden would make main a scroll
   container and break the sticky tab bar and topbar. */
main { overflow-x: clip; }
/* On a phone the tab bar always has more tabs than fit. It scrolls, but a
   hard cut at the edge reads as "SCORES & STANDI" — a clipped word, not an
   invitation. Fading the last few pixels says there is more to the right. */
@media (max-width: 700px) {
  .tabs {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent);
  }
}
.tabs a { white-space: nowrap; flex: none; }
.tabs a {
  padding: 13px 15px 11px; color: var(--sub); font-weight: 700; font-size: 0.92em;
  text-decoration: none; border-bottom: 2px solid transparent;
  text-transform: uppercase; letter-spacing: 0.05em;
  transition: color 0.15s;
}
.tabs a:hover { color: var(--text); text-decoration: none; }
.tabs a.on {
  color: var(--text);
  border-image: linear-gradient(90deg, var(--accent), var(--accent2)) 1;
  border-bottom: 2px solid;
}
.tabs a.live { color: var(--red); }

.matchup-card {
  display: block; background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 16px; color: var(--text); text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}
.matchup-card:hover {
  background: var(--panel2); border-color: rgba(255, 255, 255, 0.12); text-decoration: none;
}
.mrow { display: flex; justify-content: space-between; align-items: center; padding: 4px 0; }
.view-link { text-align: right; margin-top: 4px; }
.weeknav { display: flex; gap: 12px; align-items: center; }

.vs-head { display: flex; justify-content: space-around; align-items: center; }
.vs-team { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.vs-team .avatar { width: 46px; height: 46px; font-size: 1.2em; }
.vs-score { font-size: 1.7em; font-weight: 400; color: var(--text); }

.slot-badge {
  display: inline-block; min-width: 36px; text-align: center;
  background: var(--panel2); border: 1px solid var(--border); border-radius: 6px;
  padding: 2px 5px; font-size: 0.72em; font-weight: 500; color: #c9a184;
}

/* ---- matchup page: head-to-head ---- */
.mu-hero {
  display: grid; grid-template-columns: auto 1fr auto 1fr auto;
  align-items: center; gap: 14px;
  background:
    radial-gradient(420px 130px at 18% 0%, rgba(224, 85, 43, .12), transparent 70%),
    radial-gradient(420px 130px at 82% 0%, rgba(240, 135, 63, .08), transparent 70%),
    var(--panel);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 24px 20px 20px; margin-bottom: 16px; box-shadow: var(--shadow);
}
.mu-side { display: flex; align-items: center; gap: 12px; min-width: 0; }
.mu-side.away { flex-direction: row-reverse; text-align: right; }
.mu-side .avatar { width: 58px; height: 58px; font-size: 1.5em; margin: 0; flex: none; }
.mu-side img.avatar { border: 1px solid var(--border); }
.mu-tname { min-width: 0; line-height: 1.3; }
.mu-tname strong { display: block; font-size: 1.05em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mu-tname .sub { font-size: 0.8em; }
.mu-score {
  font-family: var(--display); font-size: 2.4em; font-weight: 400; line-height: 1;
  margin-left: auto; letter-spacing: 0.5px;
  text-shadow: 0 2px 12px rgba(0, 0, 0, .5);
}
.mu-side.away .mu-score { margin-left: 0; margin-right: auto; }
.mu-mid { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.mu-week {
  font-family: var(--mono); font-weight: 500; font-size: 0.74em; color: var(--sub);
  text-transform: uppercase; letter-spacing: 0.08em;
}
.mu-vs {
  font-family: var(--display); font-weight: 400; font-size: 1.05em;
  color: var(--accent2); opacity: .8; letter-spacing: .12em;
}
.mu-count { font-size: .72em; }
.mu-wp-row {
  grid-column: 1 / -1; display: flex; align-items: center; gap: 14px;
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line);
}
.mu-wp-row .wp-bar { flex: 1; height: 8px; border-radius: 999px; overflow: hidden; }
.mu-wp-pct {
  font-family: var(--mono); font-weight: 700; font-size: 1em;
  color: var(--accent2); min-width: 44px;
}
.mu-wp-pct.away { color: var(--sub); text-align: right; }
.mu-card { padding: 8px 0 6px; overflow: hidden; }
.mu-card .mu-head {
  display: grid; grid-template-columns: 1fr 64px 1fr; align-items: center; gap: 8px;
  padding: 6px 20px 10px; border-bottom: 1px solid var(--line);
  color: var(--sub); font-size: 0.7em; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
}
.mu-card .mu-head :last-child { text-align: right; }
.mu-card .mu-head :nth-child(2) { text-align: center; }
.mu-row {
  /* minmax(0, 1fr), not 1fr: a bare fr track has an `auto` minimum and will
     not shrink below its content, so both player cells kept their natural
     width and the away score was clipped off the side of the card. */
  display: grid; grid-template-columns: minmax(0, 1fr) 64px minmax(0, 1fr);
  align-items: center; gap: 8px;
  padding: 0 20px; border-bottom: 1px solid var(--line);
}
.mu-row:last-child { border-bottom: none; }
.mu-row:hover { background: rgba(255, 255, 255, 0.03); }
.mu-slot { text-align: center; }
.mu-slot .slot-badge { min-width: 46px; display: inline-block; text-align: center; }
.mu-row:nth-child(even) { background: rgba(255, 255, 255, .015); }
.mu-p.empty { opacity: .38; }
.mu-p {
  display: flex; align-items: center; gap: 10px; min-width: 0; max-width: 100%;
  padding: 9px 0; color: var(--text); font-weight: 600;
}
.mu-ptcol { flex: none; }
.mu-p:hover { text-decoration: none; }
.mu-p:hover .mu-name { text-decoration: underline; }
.mu-p.a { flex-direction: row-reverse; text-align: right; }
.mu-p .headshot { width: 38px; height: 38px; }
.mu-info { min-width: 0; line-height: 1.35; }
.mu-name { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mu-info .sub { display: block; font-weight: 400; font-size: 0.8em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mu-pts {
  font-family: var(--display); font-weight: 400; font-size: 1.2em;
  margin-left: auto; padding-left: 10px; flex: none;
}
.mu-p.a .mu-pts { margin-left: 0; margin-right: auto; padding-left: 0; padding-right: 8px; }
.mu-p.empty .mu-info { color: var(--sub); font-style: italic; }
.mu-bench { border-top: 1px solid var(--line); }
.mu-bench-h {
  padding: 10px 20px 6px; color: var(--sub); font-size: 0.7em; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
}
.mu-row.bn .mu-p { opacity: 0.6; }
.mu-row.bn .mu-p:hover { opacity: 1; }
@media (max-width: 700px) {
  /* hero: arrows tuck into the top corners, 3-column grid, big scores */
  .mu-hero {
    position: relative; grid-template-columns: 1fr auto 1fr;
    padding: 16px 10px 14px; gap: 6px;
  }
  .mu-arrow {
    position: absolute; top: 10px; z-index: 2; font-size: 1.35rem;
    padding: 6px 13px 8px; border-radius: 12px;
    background: rgba(255, 255, 255, 0.05); border: 1px solid var(--border);
  }
  .mu-arrow.prev { left: 8px; }
  .mu-arrow.next { right: 8px; }
  .mu-side, .mu-side.away { flex-direction: column; text-align: center; gap: 5px; min-width: 0; }
  .mu-side .avatar { width: 40px; height: 40px; font-size: 1.05em; }
  .mu-score { margin: 0 !important; font-size: 2em; }
  .mu-tname { max-width: 100%; }
  .mu-tname strong {
    white-space: normal; font-size: 0.82em; line-height: 1.25;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  }
  .mu-mid { gap: 2px; }
  .mu-vs { font-size: 1em; }
  .mu-wp-row { margin-top: 12px; padding-top: 11px; gap: 10px; }
  .mu-wp-pct { font-size: 0.95em; min-width: 38px; }
  /* ladder: small headshots, tight columns, stacked pts/proj */
  /* Every pixel of chrome here costs the player's name, which is the one
     thing on the row that has to stay readable. Trimming the card gutter,
     the row padding and the slot column roughly doubles what the name gets. */
  .mu-card { margin-left: -10px; margin-right: -10px; border-radius: 0; }

  .mu-row, .mu-card .mu-head {
    grid-template-columns: minmax(0, 1fr) 34px minmax(0, 1fr);
    padding: 0 6px; gap: 3px;
  }
  .mu-card .mu-head { padding: 6px 8px 10px; }
  .mu-p { gap: 5px; padding: 8px 0; }
  .mu-p .headshot { width: 26px; height: 26px; }
  /* kickoff time is a nicety; the name is not. Reclaim its width. */
  .mu-info .ktime { display: none; }
  .mu-name { font-size: 0.85em; }
  .mu-info .sub { font-size: 0.72em; }
  .mu-ptcol { padding-left: 4px; }
  .mu-p.a .mu-ptcol { padding-right: 4px; }
  .mu-pts { font-size: 1em; }
  .mu-proj { font-size: 0.68em; }
  .mu-slot .slot-badge { min-width: 30px; font-size: 0.62em; padding: 3px 1px; }
  .mu-pts { font-size: 0.95em; }
  .mu-ptcol { min-width: 44px; }
}
.slot-badge.bn { color: var(--sub); background: transparent; }
tr.benched td { opacity: 0.55; }
.empty-slot { font-style: italic; }
table.lineup td { vertical-align: middle; }
/* The lineup table had no width rule, so it sized to its content and grew
   wider than the card holding it -- the Drop column and the lock icon sat
   outside the panel, worst on a phone where there is no slack to absorb it.
   Two halves to the fix: cap the table at its container, and let the player
   cell actually shrink. .statline is already nowrap + ellipsis, but an
   ellipsis inside a flex item only engages when the item may shrink below
   its content, which needs min-width:0 -- without it the cell claimed its
   full intrinsic width and the cap had nothing to give. */
table.lineup { width: 100%; table-layout: fixed; }
/* Fixed layout is what actually caps it. A cell's intrinsic width comes from
   its content, and .statline is nowrap, so under auto layout it reported its
   full text width no matter that it also carries overflow:hidden -- width
   100% then had nothing to give and the table overflowed anyway. Under fixed
   layout the columns are set by these rules instead of by the longest line,
   which is also what finally lets the ellipsis engage. Column 2 (Player) is
   left unsized on purpose: it takes whatever the others do not. */
table.lineup tr > :nth-child(1) { width: 56px; }        /* slot badge */
table.lineup tr > :nth-child(2) { width: 100%; }        /* player: the rest */
table.lineup tr > :nth-child(3) { width: 66px; }        /* week points */
table.lineup tr > :nth-child(4) { width: 66px; }        /* projection */
table.lineup tr > :nth-child(5) { width: 72px; }        /* rank */
table.lineup tr > :nth-child(6) { width: 78px; }        /* lock + drop */
/* The chips sit in their own row under the player so they get the table's
   full width rather than one squeezed column -- in a phone's 186px player
   cell they wrapped to three lines and put 55px on every row. The two rows
   are one unit visually, so the player's rule is dropped and the chip row
   carries the separator; otherwise a player is divided from his own chips. */
table.lineup tr.has-lk > td { border-bottom: 0; padding-bottom: 2px; }
table.lineup tr.lk-tr > td { padding: 0 8px 9px 56px; }
/* display:flex, not inline-flex. a.pcell.zapped (the optimal-lineup flash)
   switches it to inline-flex, which sizes to content instead of to the cell —
   so once a manager had used Set optimal lineup, the box score grew straight
   out of the column and painted over the projection and the Drop button. */
table.lineup td .pcell { display: flex; max-width: 100%; min-width: 0; }
table.lineup td .pcell > span { min-width: 0; overflow: hidden; }

.cat-table td { text-align: center; font-weight: 700; }
.cat-table td.winning { color: var(--accent2); }
.cat-table th { text-align: center; }
.this-week { border-color: var(--accent); }
.ptgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px; margin-top: 8px; }
.ptgrid label { display: flex; flex-direction: column; gap: 3px; }

/* auth screens */
.auth-brand { color: var(--text); }
.auth-brand::first-letter { color: var(--accent); }

/* today's real-game opponent next to team abbr */
/* pro-team logo + abbreviation chip. Transparent — logos sit bare on the
   theme. Fixed pixel size so every logo is identical no matter the
   surrounding font size. */
.proteam { display: inline-flex; align-items: center; white-space: nowrap;
  vertical-align: middle; }
.tlogo {
  width: 16px; height: 16px; object-fit: contain; box-sizing: border-box;
  vertical-align: middle; flex: none; margin-left: 5px;
  filter: drop-shadow(0 0 1.5px rgba(255, 255, 255, 0.45));
}
/* slate logos read a touch larger next to the scores */
.sg-team .tlogo { width: 20px; height: 20px; margin-left: 6px; }

.opp { color: var(--green); font-weight: 700; margin-left: 6px; font-size: 1em;
  display: inline-flex; align-items: center; vertical-align: middle; white-space: nowrap; }
.ktime { color: var(--sub); margin-left: 6px; font-size: 1em; white-space: nowrap; }

/* Box-score line under a player. Monospaced so the numbers hold a column as
   they tick, and dimmer than the position row above it — this is the third
   line in the cell and must not compete with the name. Empty until the first
   stat lands: :empty collapses the margin so nothing shifts when it fills. */
.statline {
  display: block; font: 400 0.76em/1.4 var(--mono); color: var(--sub);
  margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.statline:empty { display: none; }
.mu-info .statline { font-size: 0.72em; }
@media (max-width: 700px) {
  /* A box score does not fit in half a phone. On the lineup page let it wrap
     to two lines instead of forcing the table wider than the screen; in a
     head-to-head row there is no width to give it at all, so it steps aside
     and the name and score get the space. */
  .statline {
    white-space: normal; display: -webkit-box; -webkit-line-clamp: 2;
    -webkit-box-orient: vertical; font-size: 0.72em;
  }
  .mu-info .statline { display: none; }
}
@media (max-width: 560px) {
  .statline { font-size: 0.7em; }
  /* On a phone the head-to-head ladder has about 70px per side for text,
     which truncates every name to "C. Skatteb...". The headshot is
     decoration and the name is the information, so the headshot goes and the
     name gets its ~30px back. */
  .mu-p .headshot { display: none; }
  .mu-p { gap: 4px; }
}

/* lineup locks */
.lock { cursor: help; filter: drop-shadow(0 0 6px rgba(245, 196, 81, 0.5)); }

/* injury + bye badges */
.inj {
  display: inline-block; padding: 0 4px; border-radius: 3px; margin-left: 3px;
  font-size: 0.72em; font-weight: 800; vertical-align: 1px;
  color: var(--red); background: rgba(255, 77, 61, 0.14);
  border: 1px solid rgba(255, 77, 61, 0.4);
}
.opp.bye { color: var(--gold); }

/* playoffs */
.plabel {
  display: inline-block; padding: 1px 8px; border-radius: 10px; margin-bottom: 4px;
  font-size: 0.72em; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--gold); background: rgba(245, 196, 81, 0.12);
  border: 1px solid rgba(245, 196, 81, 0.45);
}
.plabel.inline-label { margin: 0 0 0 4px; }
.champ-banner {
  text-align: center;
  border-color: var(--gold);
  box-shadow: 0 0 28px rgba(245, 196, 81, 0.25);
}

/* waivers, trades, activity */
.btn.waiver { background: linear-gradient(135deg, #b8860b, var(--gold)); color: var(--ink); }
.trade-row {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  flex-wrap: wrap; padding: 8px 0; border-bottom: 1px solid var(--line);
}
.trade-row:last-child { border-bottom: none; }
.row { display: inline-flex; gap: 6px; align-items: center; }

/* Ascend rankings movement */
.pr-up { color: var(--green); font-weight: 800; }
.pr-down { color: var(--red); font-weight: 800; }
.awards { display: flex; gap: 22px; flex-wrap: wrap; }

/* trade analyzer */
td.val { font-weight: 800; color: var(--accent2); text-align: right; }
.analyzer .vs-score { color: var(--accent2); }
.verdict {
  padding: 6px 14px; border-radius: 16px; font-weight: 700; text-align: center;
  background: var(--panel2); border: 1px solid var(--border); color: var(--sub);
}
.verdict.fair { color: var(--green); border-color: rgba(224, 85, 43, 0.5); }
.verdict.slight { color: var(--gold); border-color: rgba(245, 196, 81, 0.5); }
.verdict.strong { color: var(--red); border-color: rgba(255, 77, 61, 0.5); }

/* real-league scoreboard strip */
.slate {
  display: flex; gap: 10px; overflow-x: auto; padding: 2px 0 8px;
  scrollbar-width: thin;
}
.slate-game {
  flex: none; min-width: 108px; padding: 7px 10px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  font-family: var(--mono); font-size: 0.86em;
}
.slate-game.in { border-color: rgba(255, 77, 61, 0.55); box-shadow: 0 0 12px rgba(255, 77, 61, 0.18); }
.slate-game.post { opacity: 0.75; }
.sg-row { display: flex; justify-content: space-between; gap: 12px; font-weight: 700; }
.sg-team { display: inline-flex; align-items: center; vertical-align: middle; }
.sg-score { color: var(--accent2); }
.slate-game.in .sg-detail { color: var(--red); }
.sg-detail { color: var(--sub); font-size: 0.82em; margin-top: 2px; white-space: nowrap; }

/* projected points on the waiver board */
td.proj { font-family: var(--mono); font-weight: 700; color: var(--green); }

/* win probability bar */
.wp-bar {
  height: 5px; border-radius: 3px; margin-top: 6px; overflow: hidden;
  /* the trailing side is ash, not red: against Ember's #e0552b a red track
     and an orange fill collapse into one block */
  background: rgba(246, 236, 226, 0.13);
}
.wp-fill {
  height: 100%; border-radius: 3px;
  background: linear-gradient(90deg, var(--accent2), var(--accent));
}
.wp-text { margin-top: 2px; font-size: 0.8em; }

/* lineup alerts */
.alerts { border-color: rgba(245, 196, 81, 0.5); }
.alert-row { padding: 4px 0; border-bottom: 1px solid var(--line); color: var(--gold); }
.alert-row:last-child { border-bottom: none; }

/* league chat */
.chat-log { max-height: 320px; overflow-y: auto; margin-bottom: 10px; }
.chat-msg { padding: 6px 0; border-bottom: 1px solid var(--line); }
.chat-msg:last-child { border-bottom: none; }
.chat-msg.me .chat-user { color: var(--accent2); }
.chat-user { font-weight: 800; margin-right: 6px; }
.chat-time { color: var(--sub); font-size: 0.78em; }
.chat-text { margin-top: 1px; white-space: pre-wrap; word-break: break-word; }
.chat-reacts { margin-top: 3px; display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }
.react {
  background: var(--panel2); border: 1px solid var(--border); border-radius: 10px;
  color: var(--text); padding: 0 7px; font-size: 0.82em; cursor: pointer; line-height: 1.6;
}
.react.mine { border-color: var(--accent); background: rgba(224, 85, 43, 0.18); }
.react-adders { display: none; gap: 4px; }
.chat-msg:hover .react-adders { display: inline-flex; }
.react.add { opacity: 0.55; }
.react.add:hover { opacity: 1; }

/* player week card: matchup rating + betting lines */
.matchup-chip {
  padding: 3px 12px; border-radius: 14px; font-family: var(--mono);
  font-weight: 700; font-size: 0.88em;
  color: hsl(var(--mh), 75%, 60%);
  border: 1px solid hsl(var(--mh), 75%, 45%);
  background: hsla(var(--mh), 75%, 50%, 0.12);
  text-shadow: 0 0 10px hsla(var(--mh), 80%, 60%, 0.4);
}
.week-grid { display: flex; gap: 28px; flex-wrap: wrap; margin: 6px 0; }
.week-stat { display: flex; flex-direction: column; gap: 2px; }
.week-stat strong { font-family: var(--display); font-size: 1.25em; }
table.props { max-width: 380px; }

/* live game indicator */
@keyframes livepulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
.live-dot {
  color: var(--red); font-weight: 700; margin-left: 6px; font-size: 0.9em;
  letter-spacing: 1px; animation: livepulse 1.6s ease-in-out infinite;
  text-shadow: 0 0 10px rgba(255, 77, 61, 0.6);
}

/* dynasty chip */
.dyn {
  display: inline-block; padding: 0 7px; border-radius: 9px; margin-left: 5px;
  font-size: 0.78em; font-weight: 900; letter-spacing: 0.8px; vertical-align: 1px;
  color: var(--ink); background: linear-gradient(135deg, var(--accent2), var(--accent));
}

/* live score updates flash, neon-style */
@keyframes bump { 0% { background: rgba(240, 135, 63, 0.25); } 100% { background: transparent; } }
.bumped { animation: bump 2.5s ease-out; border-radius: 3px; }

/* dark scrollbars for the pool + long tables */
* { scrollbar-color: #2a1f16 transparent; }

@media (max-width: 800px) {
  /* topbar stays one 56px row: quick links scroll instead of wrapping, so the
     sticky tab-bar offset (--topbar-h) keeps holding true */
  .topbar { gap: 10px; padding: 0 12px; }
  .topnav { flex-wrap: nowrap; overflow-x: auto; min-width: 0;
            -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .topnav::-webkit-scrollbar { display: none; }
  .topnav a { padding: 6px 9px; flex: none; }
  .top-user { gap: 8px; flex: none; }
  main { padding: 0 10px; margin: 12px auto; }
  /* league tab bar: single scrolling row, still sticky */
  .tabs { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
          scrollbar-width: none; margin: 10px -10px 14px; padding: 0 10px; }
  .tabs::-webkit-scrollbar { display: none; }
  .tabs a { white-space: nowrap; flex: none; padding: 12px 11px 10px; }
  /* draft room: tighter clock once the columns have stacked */
  .draft-clock { gap: 10px; }
  .dc-left { min-width: 0; }
  .timer.big { font-size: 1.7em; min-width: 90px; }
  .dc-controls { justify-content: flex-start; }
  .pool { max-height: 420px; }
}

/* player-search typeahead */
.suggest-box {
  position: absolute; top: calc(100% + 4px); left: 0; min-width: 300px;
  max-height: 340px; overflow-y: auto; z-index: 60;
  background: var(--panel2); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
}
.suggest-item {
  display: flex; align-items: center; gap: 10px; padding: 7px 12px;
  cursor: pointer; border-bottom: 1px solid var(--line);
}
.suggest-item:last-child { border-bottom: none; }
.suggest-item:hover, .suggest-item.sel { background: rgba(224, 85, 43, 0.15); }
.suggest-item .s-name { flex: 1; line-height: 1.25; }
.suggest-item .s-name .sub { display: block; font-size: 12px; }
.suggest-item .s-tag { font-size: 12px; white-space: nowrap; }
.suggest-item .proj { font-family: var(--mono); font-weight: 700; color: var(--green); }

/* presence + avatars */
.online-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--green); margin-left: 4px; vertical-align: middle;
  box-shadow: 0 0 6px rgba(224, 85, 43, 0.7);
}
.avatar-img {
  width: 28px; height: 28px; border-radius: 50%; object-fit: cover;
  vertical-align: middle;
}
.chat-img {
  max-width: 240px; max-height: 200px; border-radius: 10px;
  display: block; margin-top: 4px;
}

/* Admin HQ stat tiles */
.hq-tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px; margin-bottom: 16px;
}
.hq-tile {
  background: var(--panel2); border: 1px solid var(--border);
  border-radius: 10px; padding: 10px; text-align: center;
}
.hq-tile .hq-n {
  display: block; font-family: var(--display); font-weight: 400;
  font-size: 1.5rem; color: var(--accent2);
}
.hq-tile .sub { font-size: 0.78rem; }

/* floating league-chat drawer */
#chat-fab {
  position: fixed; bottom: 18px; right: 18px; width: 52px; height: 52px;
  border-radius: 50%; border: none; cursor: pointer; z-index: 80;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  font-size: 22px; line-height: 1; color: #fff;
  box-shadow: 0 4px 18px rgba(224, 85, 43, 0.5);
}
#chat-fab:hover { filter: brightness(1.12); }
/* unread pill, shared by the FAB and the League tab (the tab is the only
   indicator the league home page gets — its chat card is inline) */
.chat-unread {
  background: var(--red); color: var(--text); font-family: var(--mono);
  font-size: 11px; font-weight: 700; letter-spacing: 0;
  padding: 1px 6px; border-radius: 10px;
}
#chat-fab .chat-unread { position: absolute; top: -4px; right: -4px; }
.tabs a .chat-unread { margin-left: 6px; }
#chat-drawer {
  position: fixed; bottom: 80px; right: 18px; width: 330px; height: 440px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 14px; z-index: 80; padding: 12px;
  display: flex; flex-direction: column;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
}
#chat-drawer .chat-log { flex: 1; overflow-y: auto; }
#chat-drawer .card-head { margin-bottom: 8px; }
#chat-close {
  background: none; border: none; color: var(--sub); cursor: pointer;
  font-size: 1rem;
}
#chat-close:hover { color: var(--text); }

/* ==== Draft room v2 ==== */

/* ASCEND position palette — tuned for the night-turf chrome: no position
   sits on the turf-green accent or the stadium-gold accent2. Mirrored in
   draft.js POS_COLORS. */
.posc-QB { --pc: #9d7bff; } .posc-RB { --pc: #00d4ff; } .posc-WR { --pc: #4da3ff; }
.posc-TE { --pc: #ff8a3d; } .posc-K { --pc: #f2e33c; } .posc-DEF { --pc: #7f8ea3; }
.posc-DL { --pc: #ff4d6d; } .posc-LB { --pc: #d06bff; } .posc-DB { --pc: #2fd6c0; }
.posc-P { --pc: #00d4ff; } .posc-C { --pc: #f2e33c; }
.posc-1B, .posc-2B, .posc-3B, .posc-SS { --pc: #2fd6c0; }
.posc-OF { --pc: #9d7bff; } .posc-DH, .posc-TWP, .posc-UTIL { --pc: #ff8a3d; }
.posc-PG, .posc-SG { --pc: #00d4ff; } .posc-SF, .posc-PF { --pc: #2fd6c0; }
.posc-G, .posc-F { --pc: #9d7bff; } .posc-GOLF { --pc: #2fd6c0; }
.posc-NA { --pc: #7f8ea3; }
/* combo slots blend the colors of every position they accept */
.posc-FLEX { --pc: #66b8e0;
  --pgrad: linear-gradient(90deg, #00d4ff, #4da3ff, #ff8a3d); }
.posc-SFLX { --pc: #8fa6e0;
  --pgrad: linear-gradient(90deg, #9d7bff, #00d4ff, #4da3ff, #ff8a3d); }
.posc-IDP { --pc: #c46b9f;
  --pgrad: linear-gradient(90deg, #ff4d6d, #d06bff, #2fd6c0); }

/* clock bar */
.dc-left { min-width: 200px; }
.dc-team { font-family: var(--display); font-size: 1.35em; font-weight: 400; line-height: 1.2; }
.dc-team .youre-up { color: var(--green); font-size: 0.65em; text-shadow: 0 0 12px rgba(224, 85, 43, 0.6); }
.timer.big { font-size: 2.3em; letter-spacing: 1px; min-width: 130px; text-align: center; }
@keyframes lowpulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
.timer.big.low { animation: lowpulse 1s ease-in-out infinite; }
.timer.paused { color: var(--gold); font-size: 1.4em; text-shadow: 0 0 14px rgba(245, 196, 81, 0.5); animation: none; }
.dc-controls { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.dc-controls select { padding: 5px 6px; font-size: 0.85em; }
.ad-btn {
  font-family: var(--mono); font-weight: 400; font-size: 0.82em; letter-spacing: 0.5px;
  padding: 5px 14px; border-radius: 14px; cursor: pointer;
  background: var(--panel2); color: var(--sub); border: 1px solid var(--border);
}
.ad-btn:hover { color: var(--text); border-color: var(--accent); }
.ad-btn.on {
  background: linear-gradient(135deg, #16a34a, var(--green)); color: var(--ink);
  border-color: transparent; box-shadow: 0 0 14px rgba(224, 85, 43, 0.4);
}

/* 3-column layout: pool | board | rail */
.draft-cols {
  display: grid; grid-template-columns: minmax(320px, 1.25fr) minmax(0, 1.6fr) 272px;
  gap: 16px; align-items: start;
}
@media (max-width: 1150px) { .draft-cols { grid-template-columns: 1fr 1fr; } .draft-rail { grid-column: 1 / -1; } }
@media (max-width: 800px) { .draft-cols { grid-template-columns: 1fr; } }

/* pool */
.pos-filters { display: flex; gap: 6px; flex-wrap: wrap; margin: 8px 0 2px; }
.pos-pill {
  font-family: var(--mono); font-weight: 700; font-size: 0.78em; letter-spacing: 0.4px;
  padding: 2px 11px; border-radius: 12px; cursor: pointer;
  background: var(--panel2); color: var(--sub); border: 1px solid var(--border);
}
.pos-pill:hover { color: var(--text); border-color: var(--pc, var(--accent)); }
.pos-pill.on { background: var(--pc, var(--accent2)); color: var(--ink); border-color: transparent; font-weight: 800; }
.pool-row {
  display: flex; align-items: center; gap: 10px; padding: 6px 8px 6px 10px;
  border-bottom: 1px solid var(--line); border-left: 3px solid var(--pc, #7988a1);
}
.pool-row:hover { background: rgba(224, 85, 43, 0.06); }
.pool-row .headshot { width: 34px; height: 34px; }
.pr-main { flex: 1; min-width: 0; line-height: 1.25; }
.pr-main .sub { display: block; font-size: 0.8em; }
.pr-nums { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.2; flex: none; }
.pr-proj { font-family: var(--mono); font-weight: 700; color: var(--green); }
.pr-pts { color: var(--sub); font-size: 0.76em; }
.pr-btns { display: flex; gap: 5px; flex: none; }
.qbtn {
  background: var(--panel2); color: var(--text); border: 1px solid var(--border);
  border-radius: 5px; padding: 3px 8px; font-size: 0.78em; font-weight: 700;
  font-family: var(--mono); cursor: pointer; white-space: nowrap;
}
.qbtn:hover:not(:disabled) { border-color: var(--accent); color: #fff; }
.qbtn:disabled { opacity: 0.4; cursor: default; }
.qbtn.draft { background: linear-gradient(135deg, #ff8a2a, #ff5a12); border: none; color: #1a0d05; }
.qbtn.draft:hover:not(:disabled) { filter: brightness(1.15); }

/* draft board grid */
.draft-board { overflow-x: auto; padding-bottom: 6px; scrollbar-width: thin; }
.db-grid { display: grid; gap: 3px; width: max-content; }
.db-th {
  font-family: var(--mono); font-weight: 700; font-size: 0.72em; color: var(--sub);
  text-transform: uppercase; letter-spacing: 0.4px; padding: 4px 4px 6px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.db-th.me { color: var(--accent); text-shadow: 0 0 10px rgba(224, 85, 43, 0.5); }
.db-th.oc { color: var(--accent2); text-shadow: 0 0 10px rgba(240, 135, 63, 0.5); }
.db-a { color: var(--gold); font-size: 0.9em; }
.db-rd {
  font-family: var(--mono); font-weight: 700; font-size: 0.7em; color: var(--sub);
  display: flex; align-items: center; justify-content: center;
}
.dcell {
  position: relative; min-height: 46px; border-radius: 6px; padding: 5px 6px 4px;
  display: flex; flex-direction: column; justify-content: center; overflow: hidden;
}
.dcell.empty { background: var(--panel2); border: 1px solid var(--line); opacity: 0.45; }
.dcell.empty .dc-no { position: static; font-size: 0.72em; color: var(--sub); text-align: center; }
.dcell.filled { background: var(--pgrad, var(--pc, #7f8ea3)); color: var(--ink); }
.dc-name {
  font-family: var(--mono); font-weight: 400; font-size: 0.8em; line-height: 1.15;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dc-sub { font-size: 0.64em; font-weight: 700; opacity: 0.75; white-space: nowrap; }
.dcell.filled .dc-no { position: absolute; top: 1px; right: 4px; font-size: 0.58em; font-weight: 800; opacity: 0.6; }
.dc-auto {
  position: absolute; bottom: 2px; right: 4px; font-size: 0.6em; font-weight: 900;
  background: rgba(7, 12, 9, 0.6); color: #fff; border-radius: 3px; padding: 0 3px;
}
@keyframes curpulse {
  0%, 100% { outline-color: var(--accent2); box-shadow: 0 0 4px rgba(240, 135, 63, 0.3); }
  50% { outline-color: rgba(240, 135, 63, 0.35); box-shadow: 0 0 16px rgba(240, 135, 63, 0.65); }
}
.dcell.cur { outline: 2px solid var(--accent2); opacity: 1; animation: curpulse 1.4s ease-in-out infinite; }

/* right rail: queue, roster, ticker */
.draft-rail { display: flex; flex-direction: column; gap: 0; }
.queue-row {
  display: flex; align-items: center; gap: 8px; padding: 5px 4px 5px 8px;
  border-bottom: 1px solid var(--line); border-left: 3px solid var(--pc, #7988a1);
}
.queue-row .headshot { width: 28px; height: 28px; }
.q-rank { font-family: var(--mono); font-weight: 400; font-size: 0.78em; color: var(--sub); min-width: 14px; text-align: right; }
.q-btns { display: flex; gap: 2px; flex: none; }
.qmini {
  background: var(--panel2); color: var(--sub); border: 1px solid var(--border);
  border-radius: 4px; padding: 1px 4px; font-size: 0.72em; cursor: pointer; line-height: 1.5;
}
.qmini:hover { color: var(--text); border-color: var(--accent); }
.qmini.x:hover { color: var(--red); border-color: var(--red); }
.roster-row { display: flex; align-items: center; gap: 8px; padding: 4px 0; border-bottom: 1px solid var(--line); font-size: 0.9em; }
.roster-row:last-child, .queue-row:last-child { border-bottom: none; }
.roster-row .slot-badge { color: var(--pc, #aeb6cc); border-color: var(--pc, var(--border)); background: transparent; }
.ticker-row { display: flex; align-items: center; gap: 8px; padding: 5px 0; border-bottom: 1px solid var(--line); font-size: 0.86em; line-height: 1.3; }
.ticker-row:last-child { border-bottom: none; }
.ticker-row .headshot { width: 26px; height: 26px; }

/* position-tinted slot badges + the league legend chips (Ascend palette) */
.slot-badge[class*="posc-"] {
  color: var(--pc);
  background: color-mix(in srgb, var(--pc) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--pc) 35%, transparent);
}
.slot-badge.posc-FLEX, .slot-badge.posc-SFLX, .slot-badge.posc-IDP {
  color: var(--text); border: 1px solid rgba(255, 255, 255, .18);
  background: var(--pgrad); background-size: 100% 100%;
  -webkit-background-clip: border-box;
  box-shadow: inset 0 0 0 100px rgba(10, 14, 11, .72);
}
.pos-legend { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 10px; }
.pos-legend span {
  display: inline-flex; align-items: center; gap: 5px; font-size: .78em;
  font-weight: 700; color: var(--sub);
}
.pos-legend i {
  width: 10px; height: 10px; border-radius: 3px;
  background: var(--pgrad, var(--pc));
  display: inline-block;
}

/* matchup win-probability strip */
.mu-winprob { max-width: 560px; margin: -6px auto 14px; }
.mu-wp-labels {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 4px;
}
.mu-wp-labels .sub { font-size: .7em; letter-spacing: .1em; }
.mu-wp-pct { font-family: var(--mono); font-weight: 700; font-size: 1.1em;
             color: var(--accent2); }

/* tap-to-move lineup */
.slot-badge.tappable { cursor: pointer; }
.slot-badge.tappable:hover { outline: 2px solid rgba(255, 255, 255, .25); }
.slot-badge.badge-armed {
  outline: 2px solid var(--accent2);
  box-shadow: 0 0 14px rgba(240, 135, 63, .45);
}
.slot-badge.tgt {
  outline: 2px dashed var(--green);
  cursor: pointer;
  animation: tgt-pulse 1.2s ease-in-out infinite;
}
@keyframes tgt-pulse { 50% { box-shadow: 0 0 12px rgba(224, 85, 43, .5); } }
#move-bar {
  position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%);
  background: var(--panel2); border: 1px solid var(--border); border-radius: 999px;
  padding: 8px 16px; z-index: 90; display: flex; gap: 10px; align-items: center;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .5);
}

/* ✓ confirmation toast — floats in, glows green, fades out */
.flash.ok {
  position: fixed; top: 72px; left: 50%; transform: translateX(-50%);
  z-index: 95; background: rgba(224, 85, 43, .12); color: var(--green);
  border: 1px solid rgba(224, 85, 43, .45); border-radius: 999px;
  padding: 9px 20px; font-weight: 700;
  box-shadow: 0 8px 28px rgba(0, 0, 0, .45), 0 0 18px rgba(224, 85, 43, .25);
  animation: toast-life 2.8s ease forwards;
}
@keyframes toast-life {
  0% { opacity: 0; transform: translate(-50%, -8px); }
  8%, 82% { opacity: 1; transform: translate(-50%, 0); }
  100% { opacity: 0; transform: translate(-50%, -8px); visibility: hidden; }
}

/* live player states: game live → stadium gold, on the field → turf green, red zone → red */
tr.p-live, .mu-p.p-live { background: rgba(240, 135, 63, .05); box-shadow: inset 3px 0 0 var(--accent2); }
tr.p-field, .mu-p.p-field { background: rgba(224, 85, 43, .10); box-shadow: inset 3px 0 0 var(--green); }
tr.p-rz, .mu-p.p-rz {
  background: rgba(255, 77, 61, .12); box-shadow: inset 3px 0 0 var(--red);
  animation: rz-pulse 1.4s ease-in-out infinite;
}
@keyframes rz-pulse { 50% { background: rgba(255, 77, 61, .22); } }
.mu-arrow {
  align-self: center; font-size: 2rem; font-weight: 800; color: var(--sub);
  padding: 0 10px; border-radius: 10px; line-height: 1;
}
.mu-arrow:hover { color: var(--text); background: rgba(255, 255, 255, .05); }

/* player-page live play feed */
.lg-play.me { background: rgba(240, 135, 63, .08); box-shadow: inset 3px 0 0 var(--accent2); border-radius: 6px; }
.lg-play.scored { color: var(--gold); font-weight: 700; }

/* stacked actual-over-projection in the matchup ladder */
.mu-ptcol { display: flex; flex-direction: column; align-items: flex-end;
            margin-left: auto; padding-left: 10px; flex: none; line-height: 1.15; }
.mu-p.a .mu-ptcol { margin-left: 0; margin-right: auto; padding-left: 0;
                    padding-right: 10px; align-items: flex-start; }
.mu-ptcol .mu-pts { margin-left: 0; padding-left: 0; }
.mu-proj { font-size: .72em; color: var(--sub); font-weight: 600; }
.mu-proj.up { color: var(--green); }
.mu-proj.down { color: var(--red); font-weight: 700; }

/* ==================== phone polish (mobile-last) ==================== */

/* touch devices: finger-sized targets, whatever the width */
@media (pointer: coarse) {
  .btn { min-height: 36px; }
  .btn.small {
    min-height: 36px; display: inline-flex; align-items: center;
    justify-content: center;
  }
  table.lineup .slot-badge { min-width: 42px; padding: 9px 5px; }
  /* A phone has 342px of table to spend and the player cell is the only one
     whose content genuinely needs room -- name, team, opponents, kick time
     and the box score all stack in there. Give the fixed columns the least
     that still fits their numbers so the rest goes to the player, otherwise
     that cell wraps to four lines and every row doubles in height. */
  table.lineup tr > :nth-child(1) { width: 46px; }
  table.lineup tr > :nth-child(4) { width: 50px; }
  table.lineup tr > :nth-child(6) { width: 60px; }
  /* Fixed layout gives the player cell a hard width, and .opp is nowrap --
     so an NBA week listing three opponents ran 110px past the cell and
     painted over the Proj column. Let that one list wrap instead of clipping
     the whole line: on an NFL roster this line carries the opponent and the
     kickoff time, which is most of why a manager opens this page on a phone
     in the first place. */
  table.lineup .pcell .sub { display: block; }
  table.lineup .pcell .opp { white-space: normal; }
  .react { padding: 2px 9px; }

  /* A finger is about 9mm across. These were all under 20px tall, which on a
     phone means aiming. The trick throughout is to grow the TAP area without
     growing the mark: padding where the box can afford it, and a transparent
     ::after overlay where it cannot. */
  .topnav a, .topnav button,
  .top-user a, .top-user button { min-height: 34px; display: inline-flex;
                                  align-items: center; }
  th a { display: inline-block; padding: 8px 4px; margin: -8px -4px; }
  .alert-x { min-width: 34px; min-height: 34px; }
  .subtabs button, .tabs a { min-height: 40px; display: inline-flex;
                             align-items: center; }
  .nick-edit { min-width: 32px; min-height: 32px; }
}

@media (max-width: 560px) {
  /* topbar: brand mark + sport emojis + avatar; text falls away */
  .brand { font-size: 1.05em; letter-spacing: 1px; }
  .brand-sub { display: none; }
  .navtxt { display: none; }
  .topnav { gap: 2px; }
  .topnav a { font-size: 1.1em; padding: 6px 8px; }
  .top-user { font-size: 0.85em; gap: 7px; }

  /* chat fab + drawer, safe-area aware */
  #chat-fab {
    width: 48px; height: 48px; font-size: 20px;
    right: 14px; bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  }
  #chat-drawer {
    left: 8px; right: 8px; width: auto;
    height: 60vh; max-height: 72vh;
    bottom: calc(70px + env(safe-area-inset-bottom, 0px));
  }

  /* tap-to-move bar: spans the bottom, clear of the chat fab */
  #move-bar {
    left: 10px; right: 70px; transform: none;
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    flex-wrap: wrap; gap: 6px 10px; justify-content: space-between;
    padding: 8px 14px; border-radius: 18px; font-size: 0.88em;
  }

  /* toast fits the screen */
  .flash.ok {
    max-width: calc(100vw - 24px); width: max-content;
    white-space: normal; text-align: center;
  }
  .flash { margin-left: 10px; margin-right: 10px; }

  /* scoreboard strip: clean edge-swipe, no scrollbar chrome */
  .slate { scrollbar-width: none; }
  .slate::-webkit-scrollbar { display: none; }

  .hq-tiles { grid-template-columns: repeat(2, 1fr); }
  .awards { gap: 10px 18px; }
  .week-grid { gap: 16px; }
}

@media (max-width: 480px) {
  :root { --radius: 14px; }
  .card, .board { padding: 13px 14px; }
  .cols, .grid { gap: 12px; }
  h2 { font-size: 1.15em; }

  /* dense-but-legible tables */
  table { font-size: 13px; }
  th, td { padding: 8px 5px; }
  td .headshot, .pcell .headshot { width: 32px; height: 32px; }
  .pcell { gap: 7px; }
  .m-hide { display: none !important; }

  /* rows of buttons/filters wrap instead of overflowing */
  .row, .card-head .row { flex-wrap: wrap; }
  form.row { flex-wrap: wrap; }
  form.row input:not(.num):not([type="file"]) { flex: 1 1 150px; min-width: 0; }
  .trade-row form.inline.row { flex-wrap: wrap; }
  .weeknav { flex-wrap: wrap; gap: 8px; }

  /* wide admin tables scroll inside the card */
  .tscroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 -14px; padding: 0 14px; }
  .tscroll table { min-width: 680px; }
}

/* clickable team identities on the matchup page */
.mu-tlink { display: flex; align-items: center; gap: 12px; min-width: 0; color: var(--text); }
.mu-side.away .mu-tlink { flex-direction: row-reverse; }
.mu-tlink:hover { text-decoration: none; }
.mu-tlink:hover .mu-tname strong { text-decoration: underline; }
.mu-head a { color: var(--sub); }
.mu-head a:hover { color: var(--text); text-decoration: underline; }

/* dismissible lineup alerts */
.alert-row { display: flex; align-items: center; gap: 8px; }
.alert-x {
  margin-left: auto; background: none; border: none; color: var(--sub);
  cursor: pointer; font-size: 1em; padding: 2px 6px; border-radius: 6px;
}
.alert-x:hover { color: var(--danger); background: rgba(255, 77, 61, .1); }

/* ---- player news (news.py / news.js) ---- */
.news-zap {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; min-height: 22px; margin-left: 4px;
  opacity: .25; filter: grayscale(1); font-size: .95em; text-decoration: none;
}
.news-zap:hover { text-decoration: none; }
a.pcell.zapped { display: inline-flex; vertical-align: middle; }
.news-zap.hot {
  opacity: 1; filter: drop-shadow(0 0 5px rgba(240, 135, 63, .8));
  animation: zap-pulse 1.6s ease-in-out infinite;
}
@keyframes zap-pulse {
  0%, 100% { filter: drop-shadow(0 0 3px rgba(240, 135, 63, .85)); }
  50% { filter: drop-shadow(0 0 9px rgba(255, 200, 60, .95)); }
}
#news-card .news-item .sub { margin-top: 2px; }
#news-card .news-item .news-date { color: var(--sub); white-space: nowrap; }

/* news carousel + blurbs */
.news-slide { min-height: 96px; }
.news-head { font-weight: 700; display: block; }
.news-blurb { color: var(--sub); margin: 4px 0 2px; font-size: .9em; }
.news-dots { display: flex; gap: 6px; margin-top: 8px; }
.news-dot { width: 8px; height: 8px; border-radius: 50%; border: none; cursor: pointer;
            background: rgba(255, 255, 255, .18); padding: 0; }
.news-dot.on { background: var(--accent2); }
/* Carousel dots sit 6px apart, so an invisible 34px hit area per dot would
   just overlap its neighbours and the last one painted would win every tap.
   Space them out and grow the dots themselves instead. Must come after the
   base rule above — same specificity, so order decides. */
@media (pointer: coarse) {
  .news-dots { gap: 16px; padding: 6px 0; }
  .news-dot { width: 12px; height: 12px; }
}
.mu-name .news-zap { margin-left: 3px; font-size: .85em; }

/* betting: player prop cards */
.prop-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 8px; }
.prop-card {
  background: var(--panel2); border: 1px solid var(--border); border-radius: 10px;
  padding: 10px 12px; display: flex; flex-direction: column; gap: 2px; position: relative;
}
.prop-label { font-size: .78em; color: var(--sub); }
.prop-line { font-family: var(--display); font-weight: 400; font-size: 1.35em; color: var(--accent2); }
.prop-ou { display: flex; gap: 4px; margin-top: 2px; }
.prop-ou span { font-size: .62em; font-weight: 700; padding: 1px 6px; border-radius: 4px;
                border: 1px solid var(--border); color: var(--sub); }
.prop-ou .o { color: var(--green); border-color: rgba(224,85,43,.4); }
.prop-ou .u { color: var(--red); border-color: rgba(255,77,61,.4); }

/* live game-detail modal */
.slate-game.clickable { cursor: pointer; }
.slate-game.clickable:hover { outline: 1px solid var(--accent2); }
#game-modal {
  position: fixed; inset: 0; z-index: 100; display: flex;
  align-items: center; justify-content: center; padding: 16px;
  background: rgba(0, 0, 0, .6); backdrop-filter: blur(3px);
}
.gm-box {
  background: var(--panel); border: 1px solid var(--border); border-radius: 16px;
  width: min(460px, 96vw); max-height: 88vh; overflow-y: auto; padding: 20px;
  position: relative; box-shadow: 0 20px 60px rgba(0, 0, 0, .6);
}
.gm-close {
  position: absolute; top: 12px; right: 12px; background: none; border: none;
  color: var(--sub); font-size: 1.1em; cursor: pointer; padding: 4px 8px;
}
.gm-close:hover { color: var(--text); }
.gm-status { text-align: center; font-weight: 700; color: var(--sub);
  text-transform: uppercase; letter-spacing: .06em; font-size: .82em; margin-bottom: 12px; }
.gm-status.rz { color: var(--red); }
.gm-team { display: flex; align-items: center; gap: 10px; padding: 8px 0; }
.gm-team img { width: 34px; height: 34px; object-fit: contain; }
.gm-tname { flex: 1; font-weight: 700; }
.gm-tname .sub { font-weight: 400; margin-left: 6px; font-size: .8em; }
.gm-ball { font-size: .9em; }
.gm-tscore { font-family: var(--display); font-weight: 400; font-size: 1.7em; color: var(--accent2); }
.gm-down { text-align: center; background: var(--panel2); border-radius: 8px;
  padding: 8px; margin: 10px 0; font-weight: 700; }
.gm-lastplay { font-size: .9em; margin: 10px 0; }
.gm-lastplay .sub { display: block; font-size: .82em; }
.gm-scoring { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 10px; }
.gm-score-play { font-size: .88em; padding: 6px 0; border-bottom: 1px solid var(--line);
  position: relative; padding-right: 46px; }
.gm-score-play .sub { display: block; font-size: .82em; }
.gm-running { position: absolute; right: 0; top: 6px; font-family: var(--mono);
  font-weight: 700; color: var(--accent2); }

/* MLB live diamond + count in the game modal */
.gm-bb { display: flex; align-items: center; justify-content: center; gap: 34px;
  background: var(--panel2); border-radius: 12px; padding: 20px 16px; margin: 12px 0; }
.gm-diamond { position: relative; width: 104px; height: 104px; }
.gm-diamond .base {
  position: absolute; width: 26px; height: 26px; background: var(--panel);
  border: 2px solid var(--border); transform: rotate(45deg); border-radius: 3px;
}
.gm-diamond .base.on { background: var(--accent2); border-color: var(--accent2);
  box-shadow: 0 0 16px rgba(240, 135, 63, .7); }
.gm-diamond .second { top: 0; left: 39px; }
.gm-diamond .third { top: 39px; left: 0; }
.gm-diamond .first { top: 39px; right: 0; }
.gm-diamond .home { bottom: 0; left: 41px; background: var(--sub); opacity: .45;
  width: 22px; height: 22px; }
.gm-count { display: flex; flex-direction: column; gap: 12px; }
.gm-bs { font-family: var(--display); font-size: 2em; font-weight: 400; }
.gm-bs .sub, .gm-outs .sub { font-family: var(--body); font-size: .5em; font-weight: 400;
  display: block; margin: 0; color: var(--sub); }
.gm-outs { display: flex; align-items: center; gap: 6px; }
.gm-outs .out { display: inline-block; width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid var(--border); }
.gm-outs .out.on { background: var(--red); border-color: var(--red);
  box-shadow: 0 0 8px rgba(255, 77, 61, .5); }
.gm-ab { font-size: .92em; margin: 8px 0; }
.gm-ab > .sub { display: inline-block; min-width: 20px; font-weight: 700; color: var(--accent2); }

/* LM Tools gear pinned to the far right of the tab bar */
.tabs .tab-gear {
  margin-left: auto; display: inline-flex; align-items: center; gap: 7px;
  padding: 11px 14px 9px;
}
.tabs .tab-gear svg { width: 15px; height: 15px; flex: none; }
@media (max-width: 700px) { .tabs .tab-gear .navtxt { display: none; } }
.sched-wrap { margin-top: 8px; }
.sched-wrap > summary { cursor: pointer; list-style: none; margin: 6px 0; }
.sched-wrap > summary::-webkit-details-marker { display: none; }
.sched-wrap > summary::after { content: " ▾"; color: var(--sub); }
.sched-wrap[open] > summary::after { content: " ▴"; }

/* standings playoff odds + cut line */
.po-odds { font-family: var(--mono); font-weight: 700; }
.cutline { display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent2); margin-left: 5px; vertical-align: middle; }

/* Explainable projections — "why?" breakdown on the This Week card */
.why-toggle { font-size: .72em; margin-left: 8px; color: var(--accent);
  text-decoration: none; font-weight: 600; vertical-align: middle; }
.why-toggle:hover { text-decoration: underline; }
.proj-why { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 10px; }
.proj-why > summary { cursor: pointer; list-style: none; font-weight: 700;
  color: var(--accent); }
.proj-why > summary::-webkit-details-marker { display: none; }
.proj-why > summary .sub { font-weight: 400; }
.why-table { width: 100%; margin: 10px 0 4px; border-collapse: collapse; }
.why-table th { text-align: left; font-weight: 500; color: var(--sub);
  padding: 4px 0; }
.why-table td { text-align: right; font-variant-numeric: tabular-nums;
  padding: 4px 0; }
.why-table tr + tr th, .why-table tr + tr td { border-top: 1px solid var(--border); }
.why-final th, .why-final td { font-weight: 800; color: var(--text); }
/* matchup chips: green smash spot, red tough spot */
.why-smash-spot td { color: var(--green); font-weight: 700; }
.why-tough-matchup td { color: var(--red); font-weight: 700; }

/* taglines */
.brand-tag {
  font-family: var(--body); font-weight: 500; font-style: italic;
  color: var(--sub); font-size: .82em; letter-spacing: .02em; margin-left: 12px;
  padding-left: 12px; border-left: 1px solid var(--border); white-space: nowrap;
}
@media (max-width: 860px) { .brand-tag { display: none; } }

/* athlete nicknames */
.pnick { display: block; font-style: italic; color: var(--accent2);
  font-size: .82em; font-weight: 600; line-height: 1.1; }
.nick-edit { background: none; border: none; color: var(--sub); cursor: pointer;
  font-size: .82em; padding: 0 3px; opacity: .5; }
.nick-edit:hover { opacity: 1; color: var(--accent2); }

/* Barnburner B-mark next to the wordmark in the top bar */
.brand-b { height: 30px; width: auto; margin-right: 8px; vertical-align: middle; }
.brand { display: inline-flex; align-items: center; }
@media (max-width: 560px) { .brand-b { height: 26px; } }


/* ---- player page: career rankings, depth chart, scrollable game log ---- */
.career-strip {
  display: flex; gap: 8px; margin: 2px 0 4px; flex-wrap: wrap;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.career-chip {
  flex: 0 0 auto; min-width: 62px; text-align: center;
  padding: 8px 10px; border-radius: 12px;
  border: 1px solid var(--border); background: var(--panel2);
}
.career-chip .cc-year { display: block; font-size: 0.72em; color: var(--sub); font-weight: 700; }
.career-chip .cc-rank { display: block; font-size: 1.35em; font-weight: 800; line-height: 1.1; }
.career-chip.band-green { border-color: var(--green); background: rgba(61, 220, 132, 0.12); }
.career-chip.band-green .cc-rank { color: var(--green); }
.career-chip.band-yellow { border-color: var(--gold); background: rgba(255, 206, 74, 0.12); }
.career-chip.band-yellow .cc-rank { color: var(--gold); }
.career-chip.band-red { border-color: var(--red); background: rgba(255, 77, 61, 0.12); }
.career-chip.band-red .cc-rank { color: var(--red); }

/* game log — last 5 by default, expandable */
.gamelog-card .glog-extra { display: none; }
.gamelog-card.expanded .glog-extra { display: table-row; }
.glog-toggle {
  margin-top: 10px; width: 100%;
  background: transparent; border: 1px solid var(--line); border-radius: 10px;
  color: var(--accent2); font: inherit; font-weight: 700; letter-spacing: .02em;
  padding: 8px; cursor: pointer;
}
.glog-toggle:hover { border-color: var(--accent); background: rgba(224,85,43,.08); }
.glog-toggle .less { display: none; }
.gamelog-card.expanded .glog-toggle .more { display: none; }
.gamelog-card.expanded .glog-toggle .less { display: inline; }

/* depth chart — full-width, offense | defense+ST, horizontal position columns */
.depth-cols {
  display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: flex-start;
}
/* each unit now owns the full card width, so groups can breathe */
.depth-group { flex: 1 1 180px; min-width: 168px; }
.depth-head { margin: 0 0 4px; letter-spacing: .06em; text-transform: uppercase; }
/* whole cell faintly tinted in the position color; one player per line */
.depth-row {
  display: flex; align-items: baseline; gap: 7px;
  padding: 4px 8px; margin-bottom: 3px; border-radius: 7px;
  white-space: nowrap; color: var(--text);
}
.depth-row[class*="posc-"] {
  background: color-mix(in srgb, var(--pc, transparent) 14%, transparent);
  box-shadow: inset 3px 0 0 color-mix(in srgb, var(--pc, transparent) 80%, transparent);
}
.depth-ord {
  flex: 0 0 16px; text-align: center; font-weight: 800;
  color: var(--sub); font-size: 0.8em;
}
.depth-name {
  flex: 1 1 auto; min-width: 0; font-size: 0.9em;
  overflow: hidden; text-overflow: ellipsis;
}
/* linked names read as part of the chart, not as loud accent links; only the
   players we actually carry get a link, so the underline marks what is clickable */
.depth-name a { color: inherit; }
.depth-name a:hover { color: var(--accent2); text-decoration: underline; }
.depth-num { flex: 0 0 auto; color: var(--sub); font-size: 0.8em; }
.depth-status { flex: 0 0 auto; color: var(--red); font-size: 0.78em; }
.depth-row.depth-me[class*="posc-"] {
  background: rgba(224, 85, 43, 0.16);
  box-shadow: inset 3px 0 0 var(--accent);
}
.depth-row.depth-me .depth-name { color: var(--accent2); font-weight: 700; }
.depth-row.depth-me .depth-ord { color: var(--accent2); }
/* matchup hero: projected totals + win/lose coloring */
.mu-projtot { font-family: var(--mono); font-weight: 700; font-size: .95em;
  color: var(--sub); margin-top: 2px; }
.mu-projtot .sub { font-size: .62em; font-weight: 400; margin-right: 3px; }
.mu-side.winning .mu-score { color: #7CFC00; text-shadow: 0 0 16px rgba(124, 252, 0, .45); }
.mu-side.losing .mu-score { color: var(--red); text-shadow: 0 0 16px rgba(255, 77, 61, .4); }
.mu-side.winning .mu-projtot span:last-child { color: #7CFC00; }
.mu-side.losing .mu-projtot span:last-child { color: var(--red); }

/* scoreboard card: projected total beside the score */
.mrow-scores { display: inline-flex; align-items: baseline; gap: 8px; }
.sb-proj { font-family: var(--mono); font-weight: 700; font-size: .78em; color: var(--sub); }
.sb-proj::before { content: "proj "; font-family: var(--body); font-weight: 400; font-size: .8em; opacity: .7; }

/* team page: the week's score with the projected final under it */
.lineup-tot { display: inline-flex; flex-direction: column; align-items: flex-end;
  line-height: 1.2; }
.lineup-tot .score { font-family: var(--mono); font-weight: 800; font-size: 1.35em; }
.lineup-proj { font-family: var(--mono); font-weight: 700; }
.lineup-proj .total { color: var(--accent2); font-size: 1.1em; }
.lineup-proj .sub { font-family: var(--body); font-weight: 400; }
.lineup-proj .optimal-ok { color: var(--green); }

/* The lineup's Proj column tracks live, reading the way the matchup page
   does: neutral while the projection still stands, green once he is beating
   it, red when he is behind. The flat green it used to wear said nothing —
   every player looked like he was having a good day. */
.lineup td.proj { color: var(--sub); }
.lineup td.proj.up { color: var(--green); }
.lineup td.proj.down { color: var(--red); font-weight: 800; }


/* ---- sub-tabs: in-page panel switching, no reload ----
   Markup: a [data-subtabs] strip of [data-panel="key"] buttons, followed by
   sibling [data-panel-body="key"] sections. base.html drives it. */
.subtabs {
  display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
  margin: 2px 0 14px; padding-bottom: 2px;
}
.subtabs button {
  font-family: var(--mono); font-size: 0.78em; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 8px 15px; border-radius: 999px; cursor: pointer;
  background: transparent; color: var(--sub);
  border: 1px solid var(--border);
  transition: color 0.15s, background 0.15s, border-color 0.15s;
}
.subtabs button:hover { color: var(--text); border-color: rgba(255, 255, 255, 0.16); }
.subtabs button.on {
  background: var(--accent); color: var(--ink); border-color: transparent;
  font-weight: 700;
}
.subtabs .subtabs-note { margin-left: auto; color: var(--sub); font-size: 0.8em; }
@media (max-width: 560px) {
  .subtabs { gap: 4px; }
  .subtabs button { padding: 7px 11px; font-size: 0.72em; letter-spacing: 0.05em; }
  .subtabs .subtabs-note { display: none; }
}

/* a strip nested inside a panel — smaller, and outlined rather than filled, so
   it reads as a level below the tab that is already lit up above it */
.bk-tabs > .subtabs { margin: 0 0 12px; }
.bk-tabs > .subtabs button { padding: 6px 13px; font-size: 0.74em; }
.bk-tabs > .subtabs button.on {
  background: rgba(224, 85, 43, 0.14); color: var(--accent2);
  border-color: rgba(224, 85, 43, 0.5);
}


/* ---- injury status: Q yellow (might play), O / IR red (will not) ---- */
.inj.warn {
  color: var(--warn); background: rgba(232, 195, 74, 0.14);
  border-color: rgba(232, 195, 74, 0.4);
}
.inj.bad {
  color: var(--red); background: rgba(255, 77, 61, 0.14);
  border-color: rgba(255, 77, 61, 0.4);
}
.depth-status.warn { color: var(--warn); }
.depth-status.bad { color: var(--red); }
.depth-status { font-weight: 700; letter-spacing: .02em; }


/* Admin HQ: per-league delete. Narrow so the confirm field doesn't stretch the
   table, and the name must be typed into it before the row can be destroyed. */
.hq-del { display: flex; gap: 6px; align-items: center; flex-wrap: nowrap; }
.hq-del input { width: 130px; min-width: 0; padding: 5px 8px; font-size: 0.85em; }
.hq-del .btn { white-space: nowrap; }


/* ---- page contents: where am I on a long page ----
   For pages that are genuinely one long list (the player pool, a head-to-head
   matchup) where tabbing would hide things people compare side by side. A
   sticky strip names the sections, highlights the one you're looking at, and
   jumps to any of them — so nobody has to scroll to the end to find out what
   is down there. Markup: a [data-pagenav] container whose sections carry
   data-sec="Label"; base.html builds the strip. */
.pagenav {
  position: sticky; top: calc(var(--topbar-h) + 44px); z-index: 20;
  display: flex; align-items: center; gap: 6px; flex-wrap: nowrap;
  margin: 0 -20px 14px; padding: 8px 20px;
  overflow-x: auto; scrollbar-width: none;
  background: rgba(11, 8, 6, 0.9);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}
.pagenav::-webkit-scrollbar { display: none; }
.pagenav a {
  flex: none; white-space: nowrap;
  font: 500 0.74em/1 var(--mono); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--sub); padding: 7px 12px; border-radius: 999px;
  border: 1px solid transparent; transition: color .15s, background .15s;
}
.pagenav a:hover { color: var(--text); text-decoration: none;
                   background: rgba(255, 255, 255, 0.05); }
.pagenav a.here {
  color: var(--ink); background: var(--accent); font-weight: 700;
}
/* how far down the page you are — the answer to "is there much more?" */
.pagenav-bar {
  position: absolute; left: 0; bottom: -1px; height: 2px;
  background: var(--accent2); width: 0; transition: width .12s linear;
}
@media (max-width: 700px) {
  .pagenav { top: var(--topbar-h); }
  .pagenav a { padding: 6px 10px; font-size: 0.68em; letter-spacing: 0.04em; }
}


/* ---- playoff bracket: one column per round, left to right ---- */
.bk-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 6px; }
.bk { display: flex; gap: 14px; align-items: flex-start; min-width: min-content; }
.bk-round { flex: 0 0 200px; display: flex; flex-direction: column; gap: 10px; }
.bk-head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
  font: 500 0.68em/1.3 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  color: var(--sub); padding-bottom: 6px; border-bottom: 1px solid var(--border);
}
.bk-head span { color: #6f6459; letter-spacing: .04em; }
.bk-game {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; overflow: hidden;
}
.bk-game.done { border-color: rgba(255, 255, 255, 0.12); }
.bk-team {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  padding: 9px 11px; font: 400 0.86em/1.2 var(--body); color: var(--sub);
}
.bk-team + .bk-team { border-top: 1px solid var(--line); }
.bk-team .bk-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bk-team .bk-pts { font: 500 0.82em/1 var(--mono); flex: none; }
/* the winner is the only line that gets full contrast */
.bk-team.won { color: var(--text); font-weight: 600; }
.bk-team.won .bk-pts { color: var(--accent2); }
.bk-team.won .bk-name::before { content: "\25B8 "; color: var(--accent); }
@media (max-width: 560px) { .bk-round { flex-basis: 168px; } }


/* projected bracket: no scores yet, so the seed number carries the meaning */
.bk-game.proj .bk-team { color: var(--text); }
.bk-seed {
  display: inline-block; min-width: 17px; margin-right: 7px; padding: 1px 4px;
  border-radius: 3px; text-align: center;
  background: rgba(255, 255, 255, .07); color: var(--sub);
  font: 700 0.72em/1.5 var(--mono);
}
.bk-game.bk-bye { border-style: dashed; opacity: .8; }
.bk-game.bk-bye .bk-pts { color: var(--accent2); font-weight: 700; }
/* the cut line is the thing people scan for */
tr.seed-in td:first-child { color: var(--accent2); font-weight: 700; }

/* "N yet to play" under a matchup score. Grey when the scoreline is settled,
   live-teal while there are still points to come — the difference between a
   final 120 and a 120 with eight men left is the whole story of a matchup. */
.mu-left {
  font-size: .72em; font-weight: 700; letter-spacing: .02em;
  color: var(--accent, #2fd6c0); margin-top: 1px; white-space: nowrap;
}
.mu-side.away .mu-left { text-align: right; }
@media (max-width: 700px) { .mu-left { font-size: .68em; } }
/* the same idea on the scoreboard, where space is tighter */
.sb-left {
  display: block; font-size: .68em; font-weight: 700;
  color: var(--accent, #2fd6c0); white-space: nowrap;
}

/* The bench's own drop target, so a starter can be sent down even when the
   bench is empty and there is no player badge to aim at. Invisible until
   something is armed — it is a target, not furniture. */
.bench-drop {
  margin-left: 8px; opacity: 0; transition: opacity .12s;
  pointer-events: none; font-size: .72em; vertical-align: middle;
}
.bench-drop.tgt { opacity: 1; pointer-events: auto; }

/* ---------------------------------------------------------------------- *
 * Phone vertical budget.
 *
 * On the matchup page half the first screen went to chrome before a single
 * player appeared — and a real iPhone loses another ~140px to Safari's own
 * bars on top of that, so "fits" on paper was still two players in practice.
 *
 * This block lives at the end of the file on purpose: the 560px block above
 * re-declares main, .tabs and .card margins, and anything placed earlier
 * silently loses to it.
 * ---------------------------------------------------------------------- */
@media (max-width: 700px) {
  /* The biggest saving and the easiest to justify: the ladder's header row
     repeats both team names and both scores, which are already in the hero
     immediately above it. */
  .mu-card .mu-head { display: none; }

  main { margin-top: 6px; margin-bottom: 8px; }
  .tabs { margin-top: 4px; margin-bottom: 8px; }
  .league-head { margin-top: 0; }
  .mu-hero { padding: 10px 10px 9px; margin-bottom: 10px; }
  .card { margin-bottom: 10px; }
  details.card { padding: 8px 12px; }
  /* rows: 4px off each one is a whole extra player per screen */
  .mu-p { padding: 6px 0; }
  /* the topbar is permanent chrome on every page — it does not need to be
     56px tall to hold a wordmark and an avatar */
  .topbar { min-height: 46px; }
  .topbar .brand { font-size: 1em; }
  .mu-side .avatar { width: 34px; height: 34px; font-size: 0.95em; }

  /* The league strapline wraps to a second line on longer league names and
     costs more height than it is worth on a phone — the sport and name are
     already in the heading above it. */
  .league-head .lg-meta { display: none; }
  /* card heads stack their title and summary with desktop-sized gaps */
  .card-head { gap: 2px; margin-bottom: 6px; }
  .card-head h3 { margin-bottom: 0; font-size: 0.95em; }
  .card { padding: 11px 13px; }
  .card > .hint:last-child, .card > details:last-child { margin-bottom: 0; }
  .mu-card { padding-top: 2px; padding-bottom: 2px; }
}

/* Week arrows beside the matchup's week label, and the team page's week
   strip. Both walk a season rather than a fixture list, so they sit with the
   label they qualify instead of in the button row. */
.mu-wk {
  color: var(--sub); text-decoration: none; padding: 0 4px;
  font-weight: 700; opacity: 0.65;
}
.mu-wk:hover { color: var(--accent); opacity: 1; text-decoration: none; }
.weeknav { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }

/* A player whose game has kicked off cannot be moved for the rest of the
   week — bench or starting, it makes no difference. The lock icon alone was
   too quiet: you reach for the row before you read the badge. Dim the row and
   put the ember rail down its edge so "untouchable" registers at a glance. */
.locked-row { opacity: 0.72; }
.locked-row td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
.locked-row .pcell span:first-of-type { color: var(--sub); }
.locked-row .slot-badge { filter: saturate(0.4); }
/* nothing on a locked row should look draggable */
.locked-row .slot-badge.tappable { cursor: not-allowed; }

/* A Lock-In chip for a game nobody has played shows a projection, not a
   score. Dim and italic so a guess never reads as a number you have. */
.mu-lock { display: flex; flex-wrap: wrap; gap: 4px; }
/* Lock-In chips. Shared by the Matchup tab and My Team via
   templates/_lock_row.html, so the rules live here rather than inside
   one page's <style> where only that page would pick them up. */
.lkc {
  display: inline-flex; align-items: center; gap: 4px; padding: 1px 6px;
  border: 1px solid var(--line); border-radius: 999px;
  font-size: .72rem; line-height: 1.6; white-space: nowrap;
}
.lkc .d { opacity: .6; }
.lkc .p { font-weight: 700; font-variant-numeric: tabular-nums; }
.lkc.locked { border-color: #f2c94c; background: rgba(242, 201, 76, .13); }
.lkc.lockable { border-color: #2fd6c0; background: rgba(47, 214, 192, .10); }
.lkc.expired { opacity: .38; }
/* He sat this one out. The points are real and they happened — they are just
   not claimable, and a chip that was only dimmed never said so. Struck score
   plus a shut padlock, which reads at a glance and on hover. */
.lkc.ineligible { opacity: .62; border-style: dotted; }
.lkc.ineligible .p { text-decoration: line-through;
                     text-decoration-thickness: from-font; }
.lkc.ineligible .lk-shut { opacity: .85; filter: grayscale(1); }
.lkc.upcoming { border-style: dashed; opacity: .6; }
.lkc.live { border-color: #e2574c; background: rgba(226, 87, 76, .12); }
.lkc button { padding: 0 6px; font-size: .7rem; line-height: 1.5; }
.lkc .p.proj { opacity: 0.65; font-style: italic; }
