/*
 * final-drive/styles — the Final Drive board's stylesheet (GET /final-drive).
 *
 * Linked from src/api/final-drive-page.js under a content-hashed URL
 * (src/assets.js), the way the dashboard links dashboard.css. It used to be
 * the page's inline <style>; it moved here verbatim because that page sits on
 * a size ratchet (tests/unit/monolith-budget.test.mjs) that only goes down.
 *
 * Mobile-first for 320 / 768 / 1024 / 1440: one fluid column on a phone,
 * widening to board + league rail at >=1024px. Every text container that
 * holds an API-supplied name carries overflow-wrap, the hero number is
 * clamp(32px, 10.5vw, 68px) so it stays whole at 320px, and every control is
 * >=44px.
 */
*,
*::before,
*::after {
  box-sizing: border-box;
}

:root {
  --bg: #0f0f0f;
  --card: #1a1a1a;
  --sunk: #141414;
  --line: #2a2a2a;
  --line-soft: #232323;
  --muted: #666;
  --sub: #999;
  --text: #fff;
  --green: #00a86b;
  --green-dim: rgba(0, 168, 107, 0.14);
  --red: #e74c3c;
  --red-dim: rgba(231, 76, 60, 0.14);
  --amber: #f39c12;
  --amber-dim: rgba(243, 156, 18, 0.14);
  --gold: #ffd700;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family:
    -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial,
    sans-serif;
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

[hidden] {
  display: none !important;
}

a {
  color: inherit;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--green);
  color: #fff;
  padding: 12px 16px;
  z-index: 60;
  border-radius: 0 0 8px 0;
}
.skip:focus {
  left: 0;
}

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

.wrap {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 14px;
}

/* ---------- top bar ---------------------------------------------------- */

/* The bar itself is the shared shell's (src/views/shell.css — its rules
   were this page's, moved there verbatim). The board's refresh control is
   what is left in the shell's right-hand slot.

   THE FRESHNESS STAMP IS NOT IN THE SLOT. Measured at 320: the slot held
   292px of controls against ~132px of room, so the bar wrapped to 109px
   where every other page's sits at 57px, and removing the Rank button
   changed that by nothing at all. Abbreviating the stamp does not work
   either — the only string that fits is "12s", a number with no noun. So it
   sits on the board instead, right-aligned above it (ch. 15, D-22). */
.freshness {
  display: block;
  text-align: right;
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.btn {
  min-height: 44px;
  min-width: 44px;
  padding: 0 14px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  /* An a.btn is a button, not a link in prose: `a` above only resets colour (D-41). */
  text-decoration: none;
}
.btn:hover {
  background: #222;
  border-color: #3a3a3a;
}
.btn:active {
  transform: scale(0.99);
}
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.btn.ghost {
  background: transparent;
}
.btn.primary {
  background: var(--green);
  border-color: var(--green);
}
.btn.primary:hover {
  background: #00c37c;
}
.btn.icon {
  padding: 0;
  font-size: 18px;
}
.btn.sm {
  min-height: 44px;
  padding: 0 10px;
  font-size: 13px;
}

/* ---------- staleness / status ----------------------------------------- */

.stale {
  background: var(--amber-dim);
  border-bottom: 1px solid var(--amber);
  color: #ffd79a;
  font-size: 13px;
  padding: 8px 14px;
  text-align: center;
}

main {
  padding-bottom: 56px;
}

/* ---------- summary line ----------------------------------------------- */

/* A caption, not pills (ch. 15, D-30). Runs are nowrap and joined by a real
   space; the separator is the FOLLOWING run's ::before so a wrapped line
   never ends on a hanging middot. The escape is '\00b7\00a0' on purpose: a
   CSS hex escape eats one following space, so '\00b7 ' renders with none. */
.summary {
  margin: 8px 0 14px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--sub);
}
.summary .run {
  white-space: nowrap;
}
.summary .run + .run::before {
  content: '\00b7\00a0';
  color: var(--muted);
}
.summary b {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.summary .run.warn,
.summary .run.warn b {
  color: var(--amber);
}

/* ---------- two column shell ------------------------------------------- */

.cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 18px;
}

section.panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px;
  margin-bottom: 16px;
}
.panel > h2 {
  margin: 0 0 12px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}
.panel-head h2 {
  margin: 0;
}

/* Ownership badges, copied EXACTLY from the dashboard's Player Impact
     column so MINE / OPP read as the same token on every screen. */
.ownership-badge {
  display: inline-block;
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  vertical-align: middle;
}
.ownership-mine {
  background: rgba(0, 168, 107, 0.2);
  color: #00a86b;
  border: 1px solid #00a86b;
}
.ownership-opp {
  background: rgba(220, 20, 60, 0.2);
  color: #dc143c;
  border: 1px solid #dc143c;
}
/* Section names carry the dashboard's pill voice: caps, tracked, small. */
.panel-head h2,
#games-h,
.final-kicker,
.lg-status,
.state-badge {
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.panel-head h2,
#games-h {
  font-size: 0.72rem;
  font-weight: 800;
  color: var(--muted);
}

/* ---------- card caption (the headline under the field) ------------- */

.card-caption {
  font-size: 13px;
  color: var(--sub);
  margin-top: 6px;
}
.card-caption b {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* ---------- legs ------------------------------------------------------- */

.legs {
  list-style: none;
  margin: 0;
  padding: 0;
}
.leg {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  padding: 10px 12px;
  background: var(--sunk);
  border-radius: 10px;
  margin-bottom: 8px;
  border-left: 4px solid var(--green);
}
.leg.opp:not(.settled) {
  border-left-style: dashed;
  border-left-color: var(--red);
}
.leg-side {
  flex: 0 0 auto;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: 4px;
  background: var(--green-dim);
  color: var(--green);
  border: 1px solid var(--green);
}
.leg.opp .leg-side {
  background: var(--red-dim);
  color: var(--red);
  border-color: var(--red);
}
.leg-league {
  flex: 1 1 130px;
  min-width: 0;
  font-weight: 600;
  font-size: 14px;
  overflow-wrap: anywhere;
}
.leg-need {
  flex: 0 0 auto;
  font-weight: 700;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}
.leg-need.floor {
  color: var(--green);
}
.leg-need.ceiling {
  color: var(--red);
}
/* Both blocks are D-24. --muted is 3.0:1 on --sunk at 12px (under AA) and
   this line carries the odds, so it moves to --sub. */
.leg-firm {
  flex: 1 1 100%;
  font-size: 12px;
  color: var(--sub);
}
.leg-firm .dot {
  font-size: 10px;
}

/* Neutral: green or red here is the won/lost claim D-24 stopped making. Held
   by :not(.settled) on .leg.opp, not by source order — both are (0,2,0). */
.leg.settled {
  border-left: 4px solid var(--line);
}
.leg-need.settled {
  font-size: 11px;
  color: var(--sub);
}

/* ---------- games ------------------------------------------------------ */

.game {
  margin-bottom: 14px;
}
.game-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  margin-bottom: 10px;
}
.game-status {
  font-size: 13px;
  font-weight: 600;
  color: var(--sub);
}
.game-count {
  font-size: 12px;
  color: var(--muted);
  margin-left: auto;
}
.state-badge {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: 4px;
  border: 1px solid var(--line);
  color: var(--sub);
}
.state-badge.in {
  color: var(--green);
  border-color: var(--green);
}
/* The live marker on a game head: a dot, not an emoji. */
.live-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--red);
  margin-right: 5px;
  vertical-align: 1px;
}
.state-badge.pre {
  color: var(--sub);
}
.state-badge.post {
  color: var(--muted);
}

.pgrid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
}

/* ---------- league rail ------------------------------------------------ */

.lg {
  background: var(--sunk);
  border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 10px;
}
.lg.alive {
  border-left-color: var(--green);
}
.lg.tied {
  border-left-color: var(--amber);
}
.lg.clinched {
  border-left-color: var(--green);
  opacity: 0.62;
}
.lg.eliminated {
  border-left-color: var(--red);
  opacity: 0.52;
}
/* The panel's save flag: text only, no icon. It says which of the three
   things happened (ch. 15, D-22) — a control whose consequence lands
   elsewhere on the page has to say it landed. */
/* The conflict block links here with href="#leagues", and the shell's bar is
   sticky — without this the panel head lands under it. */
#leagues {
  scroll-margin-top: 72px;
}
.rank-status {
  font-size: 12px;
  color: var(--sub);
  text-align: right;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
}
.rank-status.warn {
  color: var(--amber);
}
.rank-status.bad {
  color: var(--red);
}
.rank-hint {
  font-size: 13px;
  color: var(--sub);
  margin: -4px 0 12px;
}
.lg-top {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
/* The same numeral the deleted ranking sheet used, kept verbatim rather than
   inventing a second one. */
.lg-rank {
  flex: 0 0 26px;
  text-align: center;
  font-weight: 800;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
/* The movers get their own line at the bottom of the row at EVERY width. At
   320 the row's content box is ~248px: badge (26) + gaps (16) + two 44px
   movers leaves ~118px for a name that needs ~150px, so sharing the identity
   line would wrap the one line that has to stay scannable. One layout at all
   four widths. */
.lg-move {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  margin-top: 8px;
}
.lg-name {
  font-size: 14px;
  font-weight: 700;
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}
.lg-status {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: 4px;
  border: 1px solid var(--line);
  color: var(--sub);
}
.lg-status.alive {
  color: var(--green);
  border-color: var(--green);
}
.lg-status.clinched {
  color: var(--green);
  border-color: var(--green);
}
.lg-status.eliminated {
  color: var(--red);
  border-color: var(--red);
}
.lg-status.tied {
  color: var(--amber);
  border-color: var(--amber);
}
.lg-sub {
  font-size: 12px;
  color: var(--muted);
  overflow-wrap: anywhere;
}
.lg-score {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 8px;
  font-variant-numeric: tabular-nums;
  margin-top: 6px;
  font-size: 15px;
  font-weight: 700;
}
.lg-score .sep {
  color: var(--muted);
  font-weight: 400;
}
.lg-score .proj {
  font-size: 12px;
  color: var(--muted);
  font-weight: 400;
}
.lg-margin {
  font-size: 12px;
  margin-top: 2px;
}
.lg-margin.up {
  color: var(--green);
}
.lg-margin.down {
  color: var(--red);
}
.lg-margin.flat {
  color: var(--sub);
}
.wp {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}
.wp-bar {
  position: relative;
  flex: 1 1 auto;
  height: 6px;
  border-radius: 3px;
  background: #262626;
  overflow: hidden;
}
.wp-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  background: var(--green);
}
.wp-fill.mid {
  background: var(--amber);
}
.wp-fill.low {
  background: var(--red);
}
.wp-num {
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ---------- final / week result ---------------------------------------- */

.final-head {
  text-align: center;
  padding: 8px 0 4px;
}
.final-kicker {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.final-score {
  font-size: clamp(38px, 13vw, 64px);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  margin: 4px 0;
}
.final-score.sweep {
  color: var(--gold);
}
.final-sub {
  font-size: 14px;
  color: var(--sub);
}
.final-group {
  margin-top: 16px;
}
.final-group h3 {
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.final-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--sunk);
  margin-bottom: 8px;
  border-left: 4px solid var(--line);
}
.final-row.won {
  border-left-color: var(--green);
}
.final-row.lost {
  border-left-color: var(--red);
}
.final-row .mark {
  font-weight: 800;
  font-size: 12px;
  flex: 0 0 auto;
}
.final-row.won .mark {
  color: var(--green);
}
.final-row.lost .mark {
  color: var(--red);
}
.final-row .nm {
  font-weight: 700;
  min-width: 0;
  overflow-wrap: anywhere;
}
.final-row .sc {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

/* ---------- states ----------------------------------------------------- */

.state-box {
  text-align: center;
  padding: 44px 16px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 14px;
  margin-top: 16px;
}
.state-box h2 {
  margin: 0 0 8px;
  font-size: 19px;
}
.state-box p {
  margin: 0 auto 18px;
  color: var(--sub);
  max-width: 46ch;
}
.skel {
  border-radius: 12px;
  background: var(--card);
  border: 1px solid var(--line);
}
.skel-hero {
  height: 260px;
  margin-bottom: 16px;
}
.skel-row {
  height: 74px;
  margin-bottom: 10px;
}
.pulse {
  animation: pulse 1.4s ease-in-out infinite;
}
@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.55;
  }
}
@media (prefers-reduced-motion: reduce) {
  .pulse {
    animation: none;
  }
}

/* ---------- breakpoints ------------------------------------------------ */

@media (min-width: 640px) {
  .pgrid {
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr));
  }
}

@media (min-width: 768px) {
  body {
    font-size: 16px;
  }
  .wrap {
    padding: 0 20px;
  }
  section.panel {
    padding: 18px;
  }
}

@media (min-width: 1024px) {
  .cols {
    grid-template-columns: minmax(0, 1fr) 336px;
    gap: 20px;
    align-items: start;
  }
  .rail {
    position: sticky;
    top: 72px;
  }
  .rail .panel {
    max-height: calc(100vh - 96px);
    overflow-y: auto;
  }
}

@media (min-width: 1440px) {
  .cols {
    grid-template-columns: minmax(0, 1fr) 380px;
  }
}
