/* =========================================================
   CapMVP Roster — design tokens
   ========================================================= */
:root {
  --logo-filter: none;   /* theme blocks below override per dark/light */
  --page-max: 1320px;    /* shared content column — matches the appbar so the
                            logo, salary bar, roster + chart all left-align (M) */
  /* Brand */
  --brand-50:  #e8f3ee;
  --brand-100: #c7e3d2;
  --brand-200: #8ec7a5;
  --brand-300: #5aa97e;
  --brand-400: #2e8a5c;
  --brand-500: #136e44;   /* visor green, primary */
  --brand-600: #0d5836;
  --brand-700: #0a4329;
  --brand-800: #073022;
  --brand-900: #051f17;

  --gold:    #FDB927;     /* LAL accent, used sparingly */
  --purple:  #6f3edb;

  --pos:     #2f9e63;     /* legal / under */
  --warn:    #c98b22;     /* near limit */
  --orange:  #d9722a;     /* apron-zone (above 1st apron) */
  --danger:  #d6584b;     /* illegal / over */
  --info:    #4a8acc;

  --radius-xs: 4px;
  --radius-sm: 6px;
  --radius:    10px;
  --radius-lg: 14px;

  --shadow-sm: 0 1px 2px rgba(0,0,0,0.06);
  --shadow:    0 2px 8px rgba(0,0,0,0.08);
  --shadow-lg: 0 16px 40px rgba(0,0,0,0.20);

  --row-h: 64px; /* table row, comfortable (photos fill it) */
  --danger-dark: color-mix(in oklab, var(--danger), #000 32%);  /* armed destructive-confirm red — derives from each theme's --danger */
}

/* DARK (default) */
/* DARK — "Moody · Emerald" (new locked system, Roster Colours handoff) */
html.dark {
  --bg-app:      #12121e;
  --bg-surface:  #1a1a2a;
  --bg-elevated: #222236;
  --bg-row:      #161626;
  --bg-row-hover:#1f1f33;
  --bg-input:    #0f0f1a;

  --line:        #262638;
  --line-strong: #363650;

  --text:        #e9ebf5;
  --text-dim:    #9da3bd;
  --text-faint:  #666c87;

  /* data colours — per-theme in the new system */
  --pos:         #34c07e;   /* [COLOUR] calmer kelly-mint (was neon #22c55e) */
  --pos-fg:      #06140c;   /* [COLOUR] ink text on a filled green (dark) */
  --warn:        #eab308;
  --orange:      #f97316;
  --danger:      #ef4444;

  --brand:       #3b6fd4;   /* [COLOUR] action blue = logo MVP blue, unified 2026-06-03 (was #2f6fd0) */
  --brand-fg:    #ffffff;
  --brand-soft:  rgba(59, 111, 212, 0.16);
  --brand-line:  rgba(59, 111, 212, 0.42);
  --neutral:     #5a6376;   /* [COLOUR] solid grey for "hold"/neutral decisions (dark) */

  --pos-bg:      rgba(34, 197, 94, 0.16);
  --warn-bg:     rgba(234, 179, 8, 0.18);
  --danger-bg:   rgba(239, 68, 68, 0.16);
  --info-bg:     rgba(74, 138, 204, 0.16);

  /* lift the real team logos a touch on the dark surface (2ways parity) */
  --logo-filter: brightness(1.12) contrast(1.05);
  --brand-blue:  #4299e1;
  --incoming:    #3ec1d5;   /* cyan incoming row */
  --logo-cap:    #0a8060;   /* [COLOUR] v2 heritage emerald, lifted for dark legibility (true #086047 on light) */
  --logo-mvp:    #0a7fc5;   /* [COLOUR] v2 heritage azure */
}

/* LIGHT */
/* LIGHT — "Daylight · Emerald" (new locked system, Roster Colours handoff) */
html.light {
  --bg-app:      #edeff3;
  --bg-surface:  #ffffff;
  --bg-elevated: #ffffff;
  --bg-row:      #f6f7fa;
  --bg-row-hover:#eceef3;
  --bg-input:    #ffffff;

  --line:        #e3e6ec;
  --line-strong: #d0d5df;

  --text:        #191c23;
  --text-dim:    #586070;
  --text-faint:  #8a91a0;

  /* data colours — per-theme in the new system */
  --pos:         #157f43;
  --pos-fg:      #ffffff;   /* [COLOUR] white text on a filled green (light) */
  --warn:        #946410;
  --orange:      #c4611f;
  --danger:      #c83d2f;

  --brand:       #3b6fd4;   /* [COLOUR] action blue = logo MVP blue, unified 2026-06-03 (was #0e6fc0) */
  --brand-fg:    #ffffff;
  --neutral:     #6b7280;   /* [COLOUR] solid grey for "hold"/neutral (light) */
  --brand-soft:  rgba(59, 111, 212, 0.10);
  --brand-line:  rgba(59, 111, 212, 0.32);

  --pos-bg:      rgba(21, 127, 67, 0.14);
  --warn-bg:     rgba(148, 100, 16, 0.16);
  --danger-bg:   rgba(200, 61, 47, 0.13);
  --info-bg:     rgba(74, 138, 204, 0.13);

  /* logos already sit on white in light mode — show them as-is */
  --logo-filter: none;
  --brand-blue:  #1d7fc4;
  --incoming:    #1f97ab;   /* incoming row */
  --logo-cap:    #086047;   /* [COLOUR] v2 heritage emerald */
  --logo-mvp:    #0a7fc5;   /* [COLOUR] v2 heritage azure */
}

/* ---- Palette-compare overrides (dev) — DARK only; light stays Daylight ----
   Driven by Settings → "Palette (dev)" (data-palette="dark-<variant>"). These
   override the html.dark tokens for side-by-side judgement. Once a scheme is
   locked, fold it into html.dark and delete these blocks + the toggle. */
html[data-palette="dark-original"] {
  --bg-app:#0c1014; --bg-surface:#141a21; --bg-elevated:#1a222b; --bg-row:#161d25; --bg-row-hover:#1f2832; --bg-input:#0e141a;
  --line:#232c37; --line-strong:#2f3a48;
  --text:#e7ebef; --text-dim:#99a4b1; --text-faint:#64707d;
  --pos:#2f9e63; --warn:#c98b22; --orange:#d9722a; --danger:#d6584b;
  --brand:#4cc391; --brand-fg:#06120f; --brand-soft:rgba(76,195,145,0.13); --brand-line:rgba(76,195,145,0.35);
  --brand-blue:#4299e1; --incoming:#388bfd; --logo-cap:#4cc391; --logo-mvp:#4299e1;
}
html[data-palette="dark-graphite"] {
  --bg-app:#121214; --bg-surface:#1b1b1e; --bg-elevated:#242428; --bg-row:#171719; --bg-row-hover:#212125; --bg-input:#0f0f11;
  --line:#2a2a2e; --line-strong:#393940;
  --text:#e9eaec; --text-dim:#9da1a8; --text-faint:#6a6e76;
  --pos:#22c55e; --warn:#eab308; --orange:#f97316; --danger:#ef4444;
  --brand:#3aa687; --brand-fg:#06180f; --brand-soft:rgba(58,166,135,0.13); --brand-line:rgba(58,166,135,0.35);
  --brand-blue:#4299e1; --incoming:#3ec1d5; --logo-cap:#10b981; --logo-mvp:#3b82f6;
}
/* Moody panel-separation gradient (dark only): Default (Moody = html.dark) → 5,
   progressively lighter cards + stronger lines. Moody 4 == the old "Moody+".
   Only surfaces/lines differ; accents/text/data inherit html.dark (Moody). */
html[data-palette="dark-moody2"] { --bg-surface:#1c1c2e; --bg-elevated:#25253a; --bg-row:#181828; --bg-row-hover:#222236; --line:#2a2a3f; --line-strong:#3a3a56; }
html[data-palette="dark-moody3"] { --bg-surface:#1e1e31; --bg-elevated:#27273e; --bg-row:#19192a; --bg-row-hover:#242439; --line:#2d2d45; --line-strong:#3c3c59; }
html[data-palette="dark-moody4"] { --bg-surface:#202034; --bg-elevated:#2a2a42; --bg-row:#1b1b2c; --bg-row-hover:#26263c; --line:#30304a; --line-strong:#3e3e5c; }
html[data-palette="dark-moody5"] { --bg-surface:#25253c; --bg-elevated:#31314c; --bg-row:#1f1f30; --bg-row-hover:#2c2c44; --line:#383854; --line-strong:#46466a; }

/* CHARCOAL — neutral near-black dark (de-tinted from Moody navy so the blue
   accent stops sitting in a blue room; Fanspo-style). Surfaces only; accents
   (green --pos, blue --brand, logo) inherit. Locked active dark — see index.html. */
html[data-palette="dark-charcoal"] { --bg-app:#0d0d0f; --bg-surface:#18181b; --bg-elevated:#202024; --bg-row:#131315; --bg-row-hover:#1d1d20; --bg-input:#0b0b0d; --line:#292930; --line-strong:#3a3a42; }

/* NAVY refinement candidates (2026-06-04) — stay in the blue-tint family (owner's
   identity, anti-Fanspo, and a neutral dark reads "too warm/red" to a colour-blind
   eye), but dial Moody 2's loud blue back and/or deepen it. A/B in Settings → Palette. */
html[data-palette="dark-navysoft"] { --bg-app:#121219; --bg-surface:#1c1c27; --bg-elevated:#252532; --bg-row:#181822; --bg-row-hover:#22222e; --bg-input:#0f0f16; --line:#2a2a37; --line-strong:#3a3a4b; }
html[data-palette="dark-navydeep"] { --bg-app:#0e0e17; --bg-surface:#151523; --bg-elevated:#1c1c2c; --bg-row:#12121e; --bg-row-hover:#1a1a29; --bg-input:#0b0b14; --line:#20202f; --line-strong:#2c2c41; }
html[data-palette="dark-deepsoft"] { --bg-app:#0f0f16; --bg-surface:#171722; --bg-elevated:#1e1e2b; --bg-row:#13131d; --bg-row-hover:#1c1c28; --bg-input:#0c0c13; --line:#232330; --line-strong:#303041; }
/* in-between navies (2026-06-04 round 2) — lighter than Navy Deep, bluer than Navy Soft. */
html[data-palette="dark-navybright"]  { --bg-app:#12121b; --bg-surface:#1c1c2a; --bg-elevated:#252535; --bg-row:#181824; --bg-row-hover:#222232; --bg-input:#0f0f18; --line:#2a2a3a; --line-strong:#3a3a50; }
html[data-palette="dark-navymid"]     { --bg-app:#10101a; --bg-surface:#191928; --bg-elevated:#212132; --bg-row:#151522; --bg-row-hover:#1e1e2f; --bg-input:#0d0d16; --line:#252536; --line-strong:#34344b; }
html[data-palette="dark-navymiddeep"] { --bg-app:#0f0f1a; --bg-surface:#171727; --bg-elevated:#1e1e31; --bg-row:#141422; --bg-row-hover:#1c1c2e; --bg-input:#0c0c16; --line:#222235; --line-strong:#303049; }

/* K: light-mode variants — softer than the stark-white Daylight base. Only
   surfaces/lines differ; text/brand/data colours inherit html.light. */
html[data-palette="light-soft"] { --bg-app:#e8eaef; --bg-surface:#f4f6fa; --bg-elevated:#fbfcfe; --bg-row:#eef0f5; --bg-row-hover:#e4e7ee; --line:#dde1e8; --line-strong:#c9cfda; }
html[data-palette="light-warm"] { --bg-app:#f6f5f1; --bg-surface:#fdfcf9; --bg-elevated:#ffffff; --bg-row:#f1efe8; --bg-row-hover:#ebe8df; --line:#e8e5dc; --line-strong:#d6d2c5; }
html[data-palette="light-dim"]  { --bg-app:#d9dde4; --bg-surface:#e7eaf0; --bg-elevated:#f0f2f7; --bg-row:#e1e5ec; --bg-row-hover:#d6dbe4; --line:#cdd3dd; --line-strong:#b8bfcc; }

/* density tweak (set on root) */
html[data-density="compact"]    { --row-h: 52px; }
html[data-density="comfortable"]{ --row-h: 64px; }
html[data-density="roomy"]      { --row-h: 80px; }

/* =========================================================
   base
   ========================================================= */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: 'Inter', -apple-system, system-ui, sans-serif;
  background: var(--bg-app);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: 'cv11', 'ss01';
  min-height: 100vh;
  overflow-x: hidden;   /* never let the page drift left↔right on mobile */
}
.num { font-variant-numeric: tabular-nums; }
button { font-family: inherit; cursor: pointer; }

/* scrollbar */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 6px; border: 2px solid var(--bg-app); }
::-webkit-scrollbar-thumb:hover { background: var(--line-strong); }

/* =========================================================
   layout
   ========================================================= */
.page {
  max-width: 1320px;
  margin: 0 auto;
  padding: 0 28px 80px;
}

/* =========================================================
   top app bar
   ========================================================= */
.appbar {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in oklab, var(--bg-app), transparent 8%);
  backdrop-filter: saturate(140%) blur(12px);
  -webkit-backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.appbar-inner {
  max-width: 1320px; margin: 0 auto;
  padding: 14px 16px;        /* tighter L/R → logo sits further left */
  display: flex; align-items: center; gap: 14px;
  flex-wrap: nowrap;   /* never wrap → header height is constant at every width */
}
/* when narrow, pull the right-side icons (gear/theme) further right and
   the logo further left by trimming the bar's side padding */
@media (max-width: 620px) {
  .appbar-inner { padding-left: 8px; padding-right: 6px; gap: 10px; }
}
.appbar-actions {
  display: flex; align-items: center; gap: 8px;
  flex-shrink: 0;
}
/* #0.5: compact app header is now always on (round 9). Slimmer logo / tool text /
   action icons + tighter vertical padding (round-9 1c: ~25% off the original 14px). */
[data-compact-header] .appbar-inner { padding-top: 8px; padding-bottom: 8px; }
[data-compact-header] .brand-logo   { height: 23px; }
[data-compact-header] .brand-mark   { width: 29px; height: 29px; }
[data-compact-header] .brand-mark svg { width: 20px; height: 20px; }
[data-compact-header] .brand        { font-size: 16px; }
[data-compact-header] .tool-trigger { font-size: 18px; }
[data-compact-header] .icon-btn     { width: 32px; height: 32px; }
[data-compact-header] .icon-btn svg { transform: scale(0.9); }
.brand {
  display: flex; align-items: center; gap: 10px;
  font-weight: 700; font-size: 18px; letter-spacing: -0.01em;
  color: var(--text);
  text-decoration: none;
}
.brand-mark {
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: 8px;
  background: var(--brand-soft);
  color: var(--brand);
}
.brand-mark svg { width: 22px; height: 22px; display: block; }
.brand b { color: var(--brand); font-weight: 800; }
.brand-divider { width: 1px; height: 22px; background: var(--line); margin: 0 4px; }

/* real team logos (2ways approach): raw <img>, theme-lifted in dark */
.team-logo { filter: var(--logo-filter); display: block; }

/* real CapMVP wordmark in the appbar (replaces the old visor mark) */
.brand { padding: 0; display: flex; }
.brand-logo { filter: var(--logo-filter); display: inline-block; line-height: 0; }
.brand-logo svg { height: 100%; width: auto; display: block; }
.brand-logo .cls-1 { fill: var(--logo-cap, #10b981); }   /* "Cap"  [COLOUR rework] */
.brand-logo .cls-2 { fill: var(--logo-mvp, #3b82f6); }   /* "MVP"  [COLOUR rework] */

/* "CapMVP <Tool>" reads as one wordmark. The logo SVG carries the ball
   above the "M", so its glyph baseline is ~3px above the image's bottom
   edge — same gotcha the Calculator solved with items-baseline + a
   manual nudge. Replicate: baseline-align logo & tool text, then lift
   the tool text by --toolname-shift to land on the glyph baseline. */
.wordmark {
  display: flex; align-items: baseline; gap: 5px;
  flex-shrink: 0;
  --toolname-shift: -3px;   /* one knob: more negative = text higher */
}
.tool-menu-wrap { flex-shrink: 0; }
.tool-trigger {
  display: inline-flex; align-items: baseline; gap: 4px;
  padding: 0; margin-left: -1px;
  border: 0; background: transparent;
  color: var(--brand-blue);
  font-weight: 800; font-size: 20px; line-height: 1;
  letter-spacing: -0.01em; white-space: nowrap;
  cursor: pointer;
  transform: translateY(var(--toolname-shift));
}
.tool-trigger:hover { opacity: 0.82; }
.tool-trigger .caret {
  color: var(--brand-blue); opacity: 0.7;
  align-self: center; transform: translateY(1px);
}
.tool-menu {
  position: absolute; top: calc(100% + 6px); left: 0;
  min-width: 168px;
  background: var(--bg-surface);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: var(--shadow-lg);
  padding: 6px;
  z-index: 100;
  display: flex; flex-direction: column; gap: 2px;
}
.tool-menu-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%; height: 32px; padding: 0 8px;
  border: none; background: transparent;
  border-radius: 7px;
  color: var(--text); font-size: 13px; font-weight: 600;
  text-align: left; cursor: pointer;
}
.tool-menu-item:hover { background: var(--bg-row-hover); }
.tool-menu-item.on { color: var(--brand); }
.tool-menu-item .tool-menu-check {
  width: 13px; height: 13px; display: inline-grid; place-items: center;
  color: var(--brand); flex-shrink: 0;
}

/* Calculator tool — embedded real site (iframe), our slim bar on top */
.calc-view { display: flex; flex-direction: column; min-height: 100vh; }
.calc-frame {
  flex: 1 1 auto;
  width: 100%;
  border: 0;
  display: block;
  background: var(--bg-app);
}

/* Team selector reads as part of the header wordmark (2ways-style): the
   team's name in title text with its logo + a subtle caret — not a pill. */
.team-chip {
  display: inline-flex; align-items: center; gap: 7px;
  min-width: 0;
  padding: 2px 6px 2px 4px;
  border: none; background: transparent;
  border-radius: 8px;
  font-weight: 700; font-size: 17px; letter-spacing: -0.01em;
  color: var(--text);
  cursor: pointer;
  transition: background .15s;
}
.team-chip:hover { background: var(--bg-row-hover); }
.team-chip .logo { width: 34px; height: 34px; display: grid; place-items: center; flex-shrink: 0; transform: translateY(1px); }   /* [COLOUR #7] bigger team logo (22→34) */
/* lower just the team NAME (+ caret) so its baseline meets "Roster" — the logo
   stays centred. `--team-name-shift` is the one knob to tune on device. */
.team-chip .team-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transform: translateY(var(--team-name-shift, 2px)); }
.team-chip .caret { color: var(--text-faint); margin-left: 1px; flex-shrink: 0; transform: translateY(var(--team-name-shift, 2px)); }
@media (max-width: 620px) { .team-chip { font-size: 15.5px; gap: 6px; } }

.title-row {
  display: flex; align-items: baseline; gap: 10px;
  margin-left: 2px;
  min-width: 0; overflow: hidden;   /* shrink before forcing a wrap */
}
.title-row .title {
  font-size: 14.5px; font-weight: 600; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tool-pill {
  display: inline-flex; align-items: center; gap: 6px;
  height: 24px; padding: 0 9px;
  border-radius: 999px;
  background: var(--brand-soft);
  color: var(--brand);
  border: 1px solid var(--brand-line);
  font-weight: 600; font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.tool-pill .dot { width: 6px; height: 6px; background: var(--brand); border-radius: 50%; }

.spacer { flex: 1; }

.btn {
  display: inline-flex; align-items: center; gap: 7px;
  height: 36px; padding: 0 13px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--bg-surface);
  color: var(--text);
  font-size: 13.5px; font-weight: 600;
  transition: all .12s ease;
  white-space: nowrap;
}
.btn:hover { background: var(--bg-row-hover); border-color: var(--line-strong); }
.btn svg { width: 15px; height: 15px; }

.btn-primary {
  background: var(--brand);
  color: #fff;
  border-color: transparent;
}
html.dark .btn-primary { color: #fff; }   /* [COLOUR] white on the blue brand (was dark #07140d, a green-era leftover) */
.btn-primary:hover { background: color-mix(in oklab, var(--brand), #000 10%); }   /* darken on hover; lightening dropped white-text contrast on the blue */
.btn-danger { border-color: var(--danger); color: var(--danger); background: var(--bg-surface); }
.btn-danger:hover { background: var(--danger); color: #fff; border-color: var(--danger); }

/* gear "Reset rosters…" entry */
.reset-rosters-btn {
  display: inline-flex; align-items: center; gap: 7px; width: 100%;
  padding: 7px 9px; border: 1px solid var(--line); border-radius: 8px;
  background: transparent; color: var(--text-dim); font: inherit; font-size: 12.5px;
  font-weight: 600; cursor: pointer;
}
.reset-rosters-btn svg { width: 14px; height: 14px; }
.reset-rosters-btn:hover { background: var(--bg-row-hover); border-color: var(--line-strong); color: var(--text); }

/* site-styled palette dropdown (Settings → Palette) — replaces the native select */
.palette-select { position: relative; }
.palette-select-btn {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 7px 9px; border: 1px solid var(--line-strong); border-radius: 8px;
  background: var(--bg-app); color: var(--text); font: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer;
}
.palette-select-btn:hover { border-color: var(--brand-line); }
.palette-select-btn .caret { width: 12px; height: 12px; color: var(--text-faint); transition: transform .15s; }
.palette-select-btn .caret.up { transform: rotate(180deg); }
.palette-select-list {
  margin-top: 5px; display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
  background: var(--bg-elevated);
}
.palette-opt {
  display: block; width: 100%; text-align: left;
  padding: 8px 10px; border: 0; background: transparent;
  color: var(--text); font: inherit; font-size: 12.5px; cursor: pointer;
}
.palette-opt + .palette-opt { border-top: 1px solid var(--line); }
.palette-opt:hover { background: var(--bg-row-hover); }
.palette-opt.on { color: var(--brand); font-weight: 700; }
/* reset confirmation choices — two-step: arm (dark red) then confirm with the ✓ */
.reset-choices { display: flex; flex-direction: column; gap: 10px; }
.reset-choice-row { display: flex; align-items: stretch; gap: 8px; }
.reset-choice { flex: 1; height: auto; flex-direction: column; align-items: flex-start; gap: 2px; padding: 11px 13px; }
.reset-sub { font-size: 11px; font-weight: 500; color: var(--text-dim); }
/* armed (after the first click): our dark red, awaiting the ✓ */
.reset-choice.armed { background: var(--danger-dark); border-color: var(--danger-dark); color: #fff; }
.reset-choice.armed:hover { background: color-mix(in oklab, var(--danger-dark), #000 10%); border-color: var(--danger-dark); }
.reset-choice.armed .reset-sub { color: rgba(255,255,255,0.82); }
.reset-go { flex: 0 0 auto; align-self: stretch; height: auto; min-width: 50px; padding: 0 15px; justify-content: center; background: var(--danger-dark); border-color: var(--danger-dark); color: #fff; }
.reset-go:hover { background: color-mix(in oklab, var(--danger-dark), #000 12%); border-color: var(--danger-dark); color: #fff; }
.reset-go svg { width: 18px; height: 18px; }

.btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--text-dim);
}
.btn-ghost:hover { background: var(--bg-row-hover); color: var(--text); }

.icon-btn {
  width: 36px; height: 36px; padding: 0;
  display: grid; place-items: center;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--bg-surface);
  color: var(--text-dim);
}
.icon-btn:hover { color: var(--text); background: var(--bg-row-hover); }
.icon-btn svg { width: 16px; height: 16px; }

/* =========================================================
   salary bar (top, full width)
   ========================================================= */
.salary-bar-band {
  background: var(--bg-surface);
  border-bottom: 1px solid var(--line);
  overflow: hidden;   /* absolutely-positioned labels can't widen the page */
}
.salary-bar-inner {
  max-width: 1320px; margin: 0 auto;
  padding: 18px 28px 14px;
}
.salary-bar-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}
.sb-head-left { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
/* #7: Apron/Tax toggle + a small faint (i) explaining the difference (replaces the
   wordy "Tax excludes unlikely incentives" note; tooltip carries the full text). */
.sb-bonus-toggle-wrap, .mb-bonus-toggle-wrap { display: flex; align-items: center; gap: 7px; }
.sb-bonus-info { font-size: 12px; line-height: 1; color: var(--text-faint); cursor: help; opacity: 0.8; }
.sb-bonus-info:hover, .sb-bonus-info:focus-visible { opacity: 1; color: var(--text-dim); outline: none; }
.sb-total {
  font-size: 24px; font-weight: 700; letter-spacing: -0.02em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.sb-total .sb-of {
  font-size: 13px; color: var(--text-faint); margin-left: 6px; font-weight: 600;
}
.sb-headline {
  display: inline-flex; gap: 6px;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.sb-headline b { font-weight: 700; }
.sb-mode-toggle {
  display: inline-flex; gap: 3px;
  padding: 3px;
  border-radius: 8px;
  background: var(--bg-row);
  border: 1px solid var(--line);
}
.sb-mode-toggle button {
  height: 26px; padding: 0 12px;
  border: none; background: transparent;
  border-radius: 5px;
  font: inherit;
  font-size: 12px; font-weight: 600;
  color: var(--text-dim);
  cursor: pointer;
  letter-spacing: 0.02em;
  transition: all .12s;
}
.sb-mode-toggle button:hover:not(.on) { color: var(--text); }
.sb-mode-toggle button.on {
  background: var(--neutral);   /* [tweak c] settings toggles = neutral (optional choice), not blue ("do this next") */
  color: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,0.15);
}
html.dark .sb-mode-toggle button.on { color: #07140d; }
.sb-mode-toggle button:disabled { opacity: 0.45; cursor: not-allowed; }
.sb-mode-toggle button:disabled:hover { color: inherit; }
.sb-zero-tick {
  position: absolute; left: 0; top: 18px;
  font-size: 10px; color: var(--text-faint);
  font-weight: 600; letter-spacing: 0.04em;
}
/* generic segmented toggle (apron / cap) — used in salary bar header AND cap strategy */
.mode-toggle {
  display: inline-flex; gap: 4px;
  padding: 3px; border-radius: 999px;
  background: var(--bg-row); border: 1px solid var(--line);
}
.mode-toggle button {
  height: 26px; padding: 0 11px;
  border: none; background: transparent;
  border-radius: 999px;
  font-size: 11.5px; font-weight: 600;
  color: var(--text-dim);
  letter-spacing: 0.02em;
  font-family: inherit;
  cursor: pointer;
  transition: background .15s, color .15s;
}
.mode-toggle button:hover:not(.on) { color: var(--text); }
.mode-toggle button.on {
  background: var(--brand);
  color: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,0.15);
}
html.dark .mode-toggle button.on { color: #07140d; }

.salary-bar-head .mode-toggle button.on {
  background: var(--bg-surface);
  color: var(--text);
}
html.dark .salary-bar-head .mode-toggle button.on { color: var(--text); }

.salary-bar-head .mode-toggle {
  /* same generic mode-toggle — small variant inside salary header */
}

/* === STYLE 1: linear with markers (multi-color zone gradient) === */
.sb-linear {
  position: relative;
  height: 14px;
  overflow: visible;
}
.sb-linear .bar-track {
  position: absolute; inset: 0;
  border-radius: 8px;
  background: var(--bg-row);
}
.sb-linear .bar-fill {
  position: absolute; inset: 0;
  border-radius: 8px;
  transition: clip-path .5s ease;
}
.sb-linear .marker {
  position: absolute; top: -5px; bottom: -5px;
  width: 2px;
  background: color-mix(in oklab, var(--text-dim), transparent 30%);
  border-radius: 1px;
  pointer-events: none;
}
.sb-linear .marker.cap    { background: var(--text-dim); }
.sb-linear .marker.apron1 { background: color-mix(in oklab, var(--text), var(--orange) 35%); }
.sb-linear .marker.apron2 { background: var(--text); }
.sb-linear .marker-label {
  position: absolute; top: 18px;
  font-size: 10.5px; font-weight: 700;
  color: var(--text-faint); letter-spacing: 0.04em;
  transform: translateX(-50%); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.sb-linear .marker-label .val { color: var(--text-dim); font-weight: 500; }

/* hard-cap marker on bar (hard hat icon perched on the tick) */
.sb-linear .bar-hardcap-marker {
  position: absolute; top: -22px;
  transform: translateX(-50%);
  width: 22px; height: 22px;
  display: grid; place-items: center;
  color: var(--warn);
  pointer-events: none;
}
.sb-linear .bar-hardcap-marker svg { width: 20px; height: 20px; }

.sb-linear-row { padding-bottom: 60px; padding-top: 30px; }

/* two stacked bars (0–$125M / $125–$250M) */
.sb-dual { display: flex; flex-direction: column; gap: 44px; padding: 14px 0 58px; }
.sb-row-cap {
  position: absolute; top: 15px;
  font-size: 9.5px; font-weight: 600; color: var(--text-faint);
  font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
}
.sb-row-cap.right { right: 0; }
.sb-row-cap:not(.right) { left: 0; }
.sb-here {
  position: absolute; top: -19px; transform: translateX(-50%);
  pointer-events: none;
}
.sb-here-val {
  font-size: 10px; font-weight: 700; color: var(--text);
  background: var(--bg-surface); padding: 0 4px; border-radius: 3px;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  border: 1px solid var(--line);
}
.sb-dual .marker-label { white-space: nowrap; }
@media (max-width: 600px) {
  .sb-dual { gap: 40px; }
  .sb-dual .marker-label { font-size: 9px; }
  .sb-row-cap { font-size: 9px; }
  .sb-here-val { font-size: 9px; }
}

/* in cap-mode stacked, dim out the apron/tax zones */
.sb-stacked.cap-mode .zone.z-tax,
.sb-stacked.cap-mode .zone.z-a1,
.sb-stacked.cap-mode .zone.z-a2,
.sb-stacked.cap-mode .zone.z-over { opacity: 0.4; }

/* Hard-cap badge in the salary bar header (shown when team is hard-capped) */
.sb-hardcap {
  display: inline-flex; align-items: center; gap: 5px;
  height: 24px; padding: 0 9px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--bg-surface), var(--warn) 18%);
  border: 1px solid color-mix(in oklab, var(--warn), transparent 50%);
  color: var(--warn);
  font-size: 11.5px; font-weight: 700;
  letter-spacing: 0.04em;
}
.sb-hardcap svg { width: 14px; height: 14px; }

/* === STYLE 2: stacked zones (CAP / APRON labels above) === */
.sb-stacked {
  position: relative;
  display: grid; grid-template-rows: auto 32px;
  gap: 6px;
}
.sb-stacked .zones {
  display: grid; grid-template-columns: var(--cap-pct) var(--mid-pct) var(--a1-pct) var(--a2-pct) auto;
  height: 32px;
  border-radius: 8px; overflow: hidden;
  background: var(--bg-row);
  border: 1px solid var(--line);
}
.sb-stacked .zone {
  position: relative;
  display: flex; align-items: center;
  padding: 0 10px;
  border-right: 1px solid var(--bg-app);
  font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-faint);
}
.sb-stacked .zone:last-child { border-right: none; }
.sb-stacked .zone.z-cap  { background: var(--bg-elevated); }
.sb-stacked .zone.z-tax  { background: color-mix(in oklab, var(--bg-elevated), var(--warn) 8%); }
.sb-stacked .zone.z-a1   { background: color-mix(in oklab, var(--bg-elevated), var(--warn) 18%); }
.sb-stacked .zone.z-a2   { background: color-mix(in oklab, var(--bg-elevated), var(--danger) 18%); }
.sb-stacked .zone.z-over { background: color-mix(in oklab, var(--bg-elevated), var(--danger) 35%); }
.sb-stacked .zone .zlbl { color: var(--text-dim); }
.sb-stacked .zone .zval { color: var(--text-faint); margin-left: 7px; font-weight: 500; text-transform: none; letter-spacing: 0; font-size: 10.5px; font-variant-numeric: tabular-nums; }
.sb-stacked .fill-row {
  position: relative; height: 8px;
  background: var(--bg-row); border-radius: 4px; overflow: hidden;
}
.sb-stacked .fill-row .fill {
  position: absolute; inset: 0;
  width: var(--fill-pct);
  background: linear-gradient(90deg,
    var(--pos) 0,
    var(--pos) var(--cap-pct),
    var(--warn) var(--cap-pct),
    var(--orange) calc(var(--cap-pct) + var(--mid-pct) + var(--a1-pct)),
    var(--danger) calc(var(--cap-pct) + var(--mid-pct) + var(--a1-pct) + var(--a2-pct))
  );
  transition: width .5s ease;
}
.sb-stacked .fill-row .fill.over { background: var(--danger); }

/* === STYLE 4: segmented zones (focus on relevant zone) === */
.sb-segmented {
  display: flex; gap: 6px;
}
.sb-segmented .seg {
  flex: 1;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 11px 13px 12px;
  background: var(--bg-elevated);
  position: relative;
  overflow: hidden;
}
.sb-segmented .seg.muted { opacity: 0.55; }
.sb-segmented .seg.active { border-color: var(--brand-line); background: var(--brand-soft); }
.sb-segmented .seg.alert  { border-color: color-mix(in oklab, var(--danger), transparent 60%); background: color-mix(in oklab, var(--bg-elevated), var(--danger) 8%); }
.sb-segmented .seg .label {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--text-faint);
  display: flex; align-items: center; gap: 6px;
}
.sb-segmented .seg .label .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--text-faint);
}
.sb-segmented .seg.active .label { color: var(--brand); }
.sb-segmented .seg.active .label .dot { background: var(--brand); }
.sb-segmented .seg.alert .label { color: var(--danger); }
.sb-segmented .seg.alert .label .dot { background: var(--danger); }
.sb-segmented .seg .amount {
  margin-top: 4px;
  font-size: 18px; font-weight: 700; letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.sb-segmented .seg .sub {
  font-size: 11.5px; color: var(--text-dim);
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}
.sb-segmented .seg .meter {
  position: absolute; left: 0; bottom: 0; height: 3px;
  background: var(--brand);
}
.sb-segmented .seg.alert .meter { background: var(--danger); }

/* salary bar headline + footnote: use mode-aware spotlight */
.sb-linear-spots {
  display: flex; gap: 8px; margin-top: 56px;
  font-size: 10.5px; color: var(--text-faint);
  letter-spacing: 0.05em; text-transform: uppercase;
  font-weight: 700;
}

/* =========================================================
   team picker dropdown
   ========================================================= */
.team-menu {
  /* viewport-pinned (2ways): centred + size-clamped so it can never
     spill off-screen on narrow widths */
  position: fixed;
  top: 58px;
  left: 50%;
  transform: translateX(-50%);
  width: min(640px, 94vw);
  max-height: calc(100vh - 74px);
  overflow-y: auto;
  background: var(--bg-surface);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  box-shadow: var(--shadow-lg);
  z-index: 100;
}
.team-menu-head {
  display: flex; justify-content: space-between;
  padding: 12px 18px 8px;
  font-size: 10.5px; font-weight: 700;
  color: var(--text-faint); letter-spacing: 0.16em;
}
.team-menu-grid {
  padding: 4px 8px 8px;
}
.team-menu-row {
  display: grid;
  grid-template-columns: 1fr 32px 1fr;
  align-items: center;
}
.team-menu-cell {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 10px; border-radius: 7px;        /* #4: bigger touch targets (notice removed) */
  border: none; background: transparent;
  color: var(--text); cursor: pointer;
  font: inherit; font-weight: 600; font-size: 14px;
  text-align: left;
  transition: background .12s, color .12s;
}
.team-menu-cell.east { justify-content: flex-end; text-align: right; }
.team-menu-cell:hover:not(:disabled) { background: var(--bg-row-hover); }
.team-menu-cell.current { color: var(--text-faint); cursor: default; }
.team-menu-cell.current .name { color: var(--text-dim); }
.team-menu-cell.empty { visibility: hidden; }
/* #4: multi-select — a team already in the deal reads as selected (re-tap removes) */
.team-menu-cell.selected { background: var(--brand-soft); border: 1px solid var(--brand-line); }
.team-menu-cell.selected .name { color: var(--brand); }
.team-menu-cell .sel-check { display: inline-grid; place-items: center; width: 16px; height: 16px; color: var(--brand); flex-shrink: 0; }
.team-menu-cell .sel-check svg { width: 14px; height: 14px; }
.team-menu-cell .sel-check.lock { color: var(--text-faint); }   /* managed: locked, not removable */
.team-menu-head .cnt { color: var(--brand); font-weight: 800; letter-spacing: 0; text-transform: none; font-size: 11px; }
.team-menu-cell .logo {
  width: 26px; height: 26px;
  display: inline-grid; place-items: center; flex-shrink: 0;
}
.team-menu-cell .name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.team-menu-cell .curr-tag {
  font-size: 10px; font-weight: 600; color: var(--text-faint);
  text-transform: lowercase; letter-spacing: 0.03em;
}
.team-menu-row .rank {
  text-align: center; font-size: 11px; font-weight: 600;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.team-menu-foot {
  padding: 10px 18px;
  border-top: 1px solid var(--line);
  font-size: 11px; color: var(--text-faint);
  letter-spacing: 0.03em; text-align: center;
}

/* =========================================================
   section cards
   ========================================================= */
.section {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.section-head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.section-head h2 {
  margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -0.005em;
  color: var(--text);
  white-space: nowrap;
}
.section-head .count {
  font-size: 12px; color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.section-head .desc { color: var(--text-dim); font-size: 13px; }
.section-head .right { margin-left: auto; display: flex; gap: 8px; align-items: center; }

/* =========================================================
   step tabs — full-width page chrome, underline indicator
   ========================================================= */
.step-tabs {
  background: var(--bg-surface);
  border-bottom: 1px solid var(--line);
  margin-top: 0;
  position: sticky;
  top: 65px;
  z-index: 40;
}
.step-tabs-inner {
  max-width: 1320px; margin: 0 auto;
  padding: 0 28px;
  display: flex; align-items: stretch;
  gap: 0;
}
.step-tab {
  display: flex; align-items: center; gap: 12px;
  flex: 0 1 auto; min-width: 0;     /* shrink to fit — never overflow at any width */
  padding: 16px 22px;
  border: none; background: transparent;
  color: var(--text-dim);
  font-family: inherit;
  position: relative;
  cursor: pointer;
  transition: color .15s;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.step-tab:hover:not(.active) { color: var(--text); }
.step-tab.active {
  color: var(--text);
  border-bottom-color: var(--text-dim);   /* [COLOUR] neutral, not blue */
}
.step-tab .step-num {
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--bg-row);
  color: var(--text-faint);
  font-size: 13px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
  transition: all .15s;
  border: 1px solid var(--line);
}
.step-tab.active .step-num { background: var(--neutral); color: #fff; border-color: var(--neutral); }  /* [COLOUR] neutral grey, not brand */
.step-tab .step-meta { display: flex; flex-direction: column; gap: 1px; align-items: flex-start; }
.step-tab .step-label { font-size: 14.5px; font-weight: 700; letter-spacing: -0.005em; min-width: 0; overflow-wrap: anywhere; }

/* "done" state — passed step. Tinted (brand-soft) so it's clearly past
   but still part of the same green system. Active is the solid fill;
   done is the soft fill with a check. */
.step-tab.done .step-num {
  background: var(--bg-row);
  border-color: var(--line-strong);
  color: var(--text-dim);
}
.step-tab.done { color: var(--text-dim); }
.step-tab.done .step-label { color: var(--text-dim); }

/* The tab bar must never overflow — clip as a final safety, and on
   mobile stack the number over a wrapping label with tabs sharing the
   width equally so even 4 steps fit on a narrow phone. */
.step-tabs { overflow-x: clip; }
@media (max-width: 720px) {
  /* #3 — mobile step bar (the whole ≤720 mobile range, matching the JS isMobile
     breakpoint — the old 600px cutoff left a 601–720 band where the full-size
     tabs wrapped mid-word). A single tight inline row (number + label), minimal
     padding, smaller text, so it stops dominating the top of the phone. */
  .step-tabs-inner { gap: 0; padding-left: 2px; padding-right: 2px; }
  .step-tab {
    flex: 1 1 0; min-width: 0;
    flex-direction: row; align-items: center; justify-content: center; gap: 4px;
    padding: 4px 2px;
  }
  .step-tab .step-num { width: 16px; height: 16px; font-size: 9px; flex-shrink: 0; }
  .step-tab .step-label {
    font-size: 9.5px; line-height: 1.1; text-align: center;
    white-space: nowrap; letter-spacing: -0.01em;
    overflow: hidden; text-overflow: ellipsis;
  }
}

.step-nav {
  display: flex; align-items: center; gap: 10px;
  margin-top: 36px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
}

/* =========================================================
   strategy cards (cap strategy step)
   ========================================================= */
/* Thin stacked strategy options (compact replacement for the big cards). */
.strategy-rows { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.strategy-row {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 11px 14px; background: var(--bg-surface); border: 1.5px solid var(--line);
  border-radius: 10px; color: var(--text); font: inherit; cursor: pointer;
  transition: border-color .15s, background .15s;
}
.strategy-row:hover { border-color: var(--line-strong); }
.strategy-row.on { border-color: var(--brand); background: color-mix(in oklab, var(--bg-surface), var(--brand) 4%); }
.strategy-row .strategy-mark { width: 18px; height: 18px; }
.strategy-row.on .strategy-mark { background: var(--brand); color: #fff; border-color: var(--brand); }
html.dark .strategy-row.on .strategy-mark { color: #07140d; }
.strategy-row-title { font-weight: 700; font-size: 13.5px; flex-shrink: 0; }
.strategy-row-desc { font-size: 12px; color: var(--text-faint); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.strategy-row.disabled { opacity: 0.5; cursor: not-allowed; }

.strategy-cards {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
  margin-top: 26px;
}
.strategy-card {
  position: relative;
  text-align: left;
  background: var(--bg-surface);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 20px 22px 22px;
  color: var(--text);
  font: inherit;
  cursor: pointer;
  transition: border-color .15s, background .15s, transform .15s;
}
.strategy-card:hover { border-color: var(--line-strong); }
.strategy-card.on {
  border-color: var(--brand);
  background: color-mix(in oklab, var(--bg-surface), var(--brand) 4%);
}
.strategy-card.on .strategy-mark {
  background: var(--brand); color: #fff; border-color: var(--brand);
}
html.dark .strategy-card.on .strategy-mark { color: #07140d; }
.strategy-mark {
  width: 22px; height: 22px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--bg-row);
  border: 1.5px solid var(--line-strong);
  color: transparent;
  flex-shrink: 0;
  transition: all .15s;
}
.strategy-head {
  display: flex; align-items: center; gap: 11px;
  margin-bottom: 8px;
}
.strategy-head h3 {
  margin: 0; font-size: 18px; font-weight: 700;
  letter-spacing: -0.01em;
}
.strategy-head .recommend {
  margin-left: auto;
  font-size: 10px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-dim);
  padding: 3px 8px;
  background: var(--bg-row);
  border-radius: 4px;
  border: 1px solid var(--line);
}
.strategy-card p {
  margin: 0 0 10px;
  font-size: 13.5px; color: var(--text-dim);
  line-height: 1.5;
}
.strategy-card ul {
  margin: 0; padding-left: 18px;
  font-size: 12.5px; color: var(--text-dim);
  line-height: 1.7;
}

.apron-blurb {
  margin-top: 22px;
  padding: 14px 18px;
  background: var(--brand-soft);
  border: 1px solid var(--brand-line);
  border-radius: var(--radius);
  display: flex; align-items: flex-start; gap: 11px;
  font-size: 13.5px; color: var(--text-dim);
  line-height: 1.5;
}
.apron-blurb .ico {
  width: 24px; height: 24px; flex-shrink: 0;
  display: grid; place-items: center;
  background: var(--brand);
  color: #fff;
  border-radius: 50%;
}
html.dark .apron-blurb .ico { color: #07140d; }

/* =========================================================
   Redesign: disabled strategy card, cap gate, FA nudge,
   single Re-sign, cap-room banner, FA sub-heads
   ========================================================= */
.strategy-card.disabled {
  opacity: 0.5; cursor: not-allowed; filter: grayscale(0.4);
}
.strategy-card.disabled:hover { border-color: var(--line); }

.cap-gate-msg {
  font-size: 12.5px; font-weight: 600;
  color: var(--danger);
  background: var(--danger-bg);
  border: 1px solid var(--danger);
  padding: 7px 12px; border-radius: 8px;
  margin-right: 12px;
}

/* Reusable inline alert (2ways-style): flows in the layout, never an
   overlay; coloured left edge + small leading symbol. */
.alert {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 9px 12px;
  border-radius: 6px;
  border-left: 3px solid var(--text-faint);
  background: var(--bg-row);
  font-size: 12.5px; line-height: 1.45; color: var(--text-dim);
}
.alert + .alert { margin-top: 6px; }
.alert-ico { flex-shrink: 0; font-size: 13px; line-height: 1.3; }
.alert-body { flex: 1; min-width: 0; }
.alert-x {
  flex-shrink: 0; border: 0; background: transparent;
  color: var(--text-faint); cursor: pointer; padding: 0;
  width: 18px; height: 18px; display: grid; place-items: center;
}
.alert-x:hover { color: var(--text); }
.alert-x svg { width: 12px; height: 12px; }
.alert-warn  { border-left-color: var(--warn);   background: var(--warn-bg); }
.alert-warn  .alert-ico { color: var(--warn); }
.alert-error { border-left-color: var(--danger); background: var(--danger-bg); }
.alert-error .alert-ico { color: var(--danger); }
.alert-info  { border-left-color: var(--info);   background: var(--info-bg); }
.alert-info  .alert-ico { color: var(--info); }

/* page-level alerts above the roster */
.page-alerts { margin: 4px 0 14px; display: flex; flex-direction: column; }

/* full-width alert banner under an editing FA row (no overlay) */
.fa-alert-row { padding: 0 14px 10px; }
.fa-alert-row .alert { font-size: 11.5px; padding: 8px 10px; }

/* draft pick rename input inside the inline roster editor */
.roster-edit-name {
  width: 100%; max-width: 220px; height: 28px; padding: 0 8px;
  border: 1px solid var(--brand-line); border-radius: 6px;
  background: var(--bg-input); color: var(--text);
  font-size: 13px; font-weight: 600;
}
.roster-edit-name:focus { outline: none; border-color: var(--brand); }

/* draft-pick prospect picker — the photo IS the trigger (always) */
.player-photo-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
.draft-photo-btn {
  position: relative; display: inline-flex; flex-shrink: 0;
  padding: 0; border: 0; background: transparent; cursor: pointer;
}
.draft-photo-btn .player-photo-placeholder.draft-select {
  display: grid; place-items: center; gap: 1px;
  border: 1px dashed var(--pos);
  background: var(--pos-bg); color: var(--pos);   /* [tweak e] adding a rookie = positive → green (was blue neon) */
}
.draft-photo-btn:hover .player-photo-placeholder.draft-select {
  background: color-mix(in oklab, var(--pos) 18%, transparent);
}
.draft-select svg { width: 14px; height: 14px; }
.draft-select-cap { font-size: 8.5px; font-weight: 700; letter-spacing: 0.02em; }
.draft-pick-add {                 /* small "change photo" pencil badge */
  position: absolute; right: -4px; bottom: -4px;
  width: 18px; height: 18px; padding: 0;
  display: grid; place-items: center;
  border-radius: 50%; border: 2px solid var(--bg-surface);
  background: var(--brand); color: #fff;
}
html.dark .draft-pick-add { color: #07140d; }
.draft-pick-add svg { width: 10px; height: 10px; }

/* draft prospect picker */
.prospect-search {
  width: 100%; height: 38px; padding: 0 12px; margin-bottom: 12px;
  border: 1px solid var(--line-strong); border-radius: 9px;
  background: var(--bg-input); color: var(--text); font-size: 14px;
}
.prospect-search:focus { outline: none; border-color: var(--brand); }
.prospect-grid {
  display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  max-height: 56vh; overflow-y: auto;
}
.prospect-card {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; text-align: left; cursor: pointer;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-row); color: var(--text);
}
.prospect-card:hover { border-color: var(--brand-line); background: var(--bg-row-hover); }
.prospect-photo {
  width: 40px; height: 40px; flex-shrink: 0;
  border-radius: 50%; object-fit: cover; object-position: top center;
  background: var(--bg-elevated);
}
.prospect-photo.placeholder {
  display: grid; place-items: center;
  font-size: 12px; font-weight: 700; color: var(--text-faint);
}
.prospect-name { font-size: 13.5px; font-weight: 600; }
.prospect-sub { font-size: 11.5px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.modal-body .empty { padding: 24px; text-align: center; color: var(--text-faint); font-style: italic; }

/* apron single Re-sign — same chrome as a toggle, just one cell */
.decisions.resign-only {
  display: inline-flex; gap: 4px; padding: 3px;
  border-radius: 8px; background: var(--bg-row);
  border: 1px solid var(--line);
}
.decisions.resign-only button {
  height: 28px; padding: 0 16px;
  border: none; background: transparent; border-radius: 5px;
  font-size: 11.5px; font-weight: 600; color: var(--text-dim);
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  cursor: pointer; transition: all .12s;
}
.decisions.resign-only button.on-yes { background: var(--brand); color: #fff; }
html.dark .decisions.resign-only button.on-yes { color: #fff; }   /* white ✓ on blue (was near-black #07140d → didn't match the other ✓ buttons) */
.decisions.resign-only button:hover:not(.on-yes) { background: var(--bg-row-hover); }
.decisions.resign-only.locked button { cursor: not-allowed; }

.cap-room-banner {
  margin: 4px 0 16px;
  padding: 12px 16px;
  border-radius: var(--radius);
  background: var(--brand-soft);
  border: 1px solid var(--brand-line);
  font-size: 14px; color: var(--text-dim);
}
.cap-room-banner b { color: var(--brand); font-size: 18px; font-variant-numeric: tabular-nums; }
.cap-room-banner.over { background: var(--danger-bg); border-color: var(--danger); }
.cap-room-banner.over b { color: var(--danger); }

.fa-subhead {
  margin: 14px 0 6px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-faint);
}
/* inline salary editor in the committed roster (2ways-inspired) */
.roster-actions {
  display: inline-flex; align-items: center; gap: 4px;
  justify-content: flex-end;
  min-width: 56px;          /* fixed slot → nothing shifts row-to-row */
}
.roster-actions .pencil {
  width: 26px; height: 26px; padding: 0;
  display: inline-grid; place-items: center;
  border: 0; background: transparent; border-radius: 6px;
  color: var(--text-faint); cursor: pointer;
}
.roster-actions .pencil:hover { background: var(--bg-row-hover); color: var(--text); }
.roster-actions .pencil.confirm { color: var(--brand); }
.roster-actions .pencil.cancel:hover { color: var(--danger); }
.roster-actions .pencil svg { width: 14px; height: 14px; }
/* keep the slot, just hide controls while another row is editing */
.roster-actions .act-hidden { visibility: hidden; }
tr.dim-while-edit td { opacity: 0.5; }
tr.dim-while-edit .roster-actions { opacity: 1; }
tr.editing-row td { height: auto; background: var(--brand-soft); }

.roster-edit-cell { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.roster-edit-input {
  width: 130px; height: 30px; padding: 0 8px;
  border: 1px solid var(--brand-line);
  border-radius: 7px;
  background: var(--bg-input); color: var(--text);
  font-size: 13px; font-variant-numeric: tabular-nums; text-align: right;
}
.roster-edit-input:focus { outline: none; border-color: var(--brand); }
.dp-edit-disp { display: inline-flex; gap: 3px; }
.dp-edit-disp button {
  height: 24px; padding: 0 7px;
  border: 1px solid var(--line); border-radius: 5px;
  background: transparent; color: var(--text-dim);
  font-size: 10.5px; font-weight: 600; cursor: pointer;
  white-space: nowrap;
}
.dp-edit-disp button.on { background: var(--brand); color: #fff; border-color: var(--brand); }
html.dark .dp-edit-disp button.on { color: #07140d; }

/* =========================================================
   actions row in Build Roster
   ========================================================= */
.actions-row {
  display: flex; align-items: center; gap: 10px;
  margin-top: 26px; margin-bottom: 4px;
}

/* Build Roster: section heading with action buttons aligned on the right */
.committed-head {
  display: flex; align-items: center; gap: 14px;
  margin: 22px 4px 10px;
}
/* Header layout density (gear -> Header layout). Tightens or opens the gap from
   the salary strip down to the roster header + the Sign FA / Trades button room.
   "standard" keeps the base values above. */
/* Only apply the salary-bar spacing when it's a STANDALONE card (over-cap, no
   step bar). When merged with the step bar (cap mode) the gap must stay 0 — the
   merged-card rules own it. :has() targets the standalone case. */
html[data-header-style="tight"] .page-salary:not(:has(+ .page-steptabs)) { margin-bottom: 8px; }
html[data-header-style="tight"] .committed-head { margin-top: 14px; }
html[data-header-style="tight"] .committed-head .actions-right .btn { height: 34px; }
html[data-header-style="roomy"] .page-salary:not(:has(+ .page-steptabs)) { margin-bottom: 22px; }
html[data-header-style="roomy"] .committed-head { margin-top: 34px; }
html[data-header-style="roomy"] .committed-head .actions-right .btn { height: 40px; }
.committed-head h3 {
  margin: 0;
  font-size: 15px; font-weight: 700; letter-spacing: -0.01em;
  color: var(--text);
  display: flex; align-items: baseline; gap: 10px;
}
.committed-head h3 .count {
  font-size: 11px; font-weight: 600;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  background: var(--bg-row);
  padding: 1px 7px;
  border-radius: 4px;
  border: 1px solid var(--line);
}
.committed-head .actions-right {
  margin-left: auto;
  display: inline-flex; gap: 8px;
}
.committed-head .actions-right .btn { height: 32px; font-size: 12.5px; padding: 0 11px; }
.committed-head .actions-right .btn svg { width: 14px; height: 14px; }

/* draft-pick controls inline */
.pick-controls {
  display: inline-flex; gap: 2px;
  margin-left: 4px;
}
.pick-controls .pencil { width: 26px; height: 26px; }
.pick-controls .pencil:disabled { opacity: 0.3; cursor: not-allowed; }

/* min-roster + over-max separators (2ways style) */
.tbl tbody tr.roster-separator td {
  height: 28px;
  padding: 4px 18px;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-faint);
  background: var(--bg-app);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  text-align: left;
}
.tbl tbody tr.roster-separator.over td {
  color: var(--danger);
  background: color-mix(in oklab, var(--bg-app), var(--danger) 5%);
}
.tbl tbody tr.over-max td {
  background: color-mix(in oklab, var(--bg-surface), var(--danger) 4%);
}

/* =========================================================
   section intro
   ========================================================= */
.section-intro {
  margin: 18px 4px 8px;
}
.section-intro h3 {
  margin: 0;
  font-size: 15px; font-weight: 700; letter-spacing: -0.01em;
  color: var(--text);
  display: flex; align-items: baseline; gap: 10px;
}
.section-intro h3 .count {
  font-size: 11px; font-weight: 600;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  background: var(--bg-row);
  padding: 1px 7px;
  border-radius: 4px;
  border: 1px solid var(--line);
}
.section-intro-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px;
}
.section-intro-action { flex-shrink: 0; align-self: center; }
.section-intro-action .btn { height: 30px; padding: 0 12px; font-size: 12.5px; font-weight: 600; }
.section-intro p {
  margin: 3px 0 0;
  font-size: 12.5px; color: var(--text-dim);
  max-width: 92ch;   /* wide enough that the decide-section subtext stays on one line on desktop */
  line-height: 1.45;
}
.section + .section-intro { margin-top: 22px; }
.section { margin-top: 8px; }

/* =========================================================
   roster table
   ========================================================= */
.tbl { width: 100%; border-collapse: collapse; }
.tbl thead th {
  text-align: left;
  font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-faint);
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-surface);
  white-space: nowrap;
}
.tbl thead th.num { text-align: right; }
.tbl tbody tr {
  border-bottom: 1px solid var(--line);
  transition: background .12s;
}
.tbl tbody tr:last-child { border-bottom: none; }
.tbl tbody tr:hover { background: var(--bg-row-hover); }
.tbl tbody tr.editing { background: var(--brand-soft); }
.tbl tbody tr.decided-out { opacity: 0.55; }
.tbl tbody tr.renounced td { opacity: 0.45; }

.tbl td {
  padding: 0 14px;
  height: var(--row-h);
  vertical-align: middle;
  font-size: 13.5px;
}
.tbl td.num { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.tbl td.dim { color: var(--text-dim); }

.player-cell { display: flex; align-items: center; gap: 12px; min-width: 0; }
.player-photo {
  width: var(--row-h);
  height: var(--row-h);
  border-radius: 0;
  background: transparent;
  object-fit: contain;
  object-position: center bottom;
  flex-shrink: 0;
  margin: 0 -2px;          /* let the photo bleed slightly to maximize it */
}
.player-photo-placeholder {
  width: calc(var(--row-h) * 0.9);
  height: calc(var(--row-h) * 0.9);
  border-radius: 4px;
  background: var(--bg-row);
  display: grid; place-items: center;
  color: var(--text-faint); font-size: 12px; font-weight: 700;
  flex-shrink: 0;
}
.player-meta { min-width: 0; }
.player-name {
  font-size: 13.5px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.player-sub {
  font-size: 11.5px; color: var(--text-dim);
  display: flex; align-items: center; flex-wrap: wrap;
  margin-top: 2px;
  gap: 8px;
}
.pos-badge {
  font-size: 10px; font-weight: 700;
  padding: 1px 5px; border-radius: 3px;
  background: var(--bg-row); color: var(--text-dim);
  letter-spacing: 0.02em;
}
/* In the option/FA rows the position is the FIRST thing on the sub line.
   As a padded chip its glyph sits ~5px in from the info-col edge, so the
   sub reads as indented vs. the name and the stacked $ (both at the true
   edge). Render it as plain meta text here so all three lines share one
   left edge. (Step-3 roster keeps the chip — it uses .pos-badge w/o
   .pos-meta.) */
.flex-row .info-col .player-sub .pos-meta {
  padding: 0; background: transparent; border-radius: 0;
  font-size: 11.5px; font-weight: 700; color: var(--text-dim);
}

/* status badges */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  height: 22px; padding: 0 8px;
  border-radius: 5px;
  font-size: 11px; font-weight: 600;
  white-space: nowrap;
  border: 1px solid transparent;
}
.badge .dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.badge.locked   { color: var(--text-dim); background: var(--bg-row); border-color: var(--line); }
.badge.guar     { color: var(--text-dim); background: var(--bg-row); border-color: var(--line); }
.badge.player-opt { color: var(--info);  background: var(--info-bg); }
.badge.team-opt   { color: var(--purple);background: rgba(111,62,219,0.15); }
.badge.non-guar   { color: var(--warn);  background: var(--warn-bg); }
.badge.ufa-bird   { color: var(--pos);   background: var(--pos-bg); }
.badge.ufa-nb     { color: var(--danger);background: var(--danger-bg); }
.badge.rfa        { color: var(--gold);  background: rgba(253,185,39,0.13); }
.badge.draft      { color: var(--info);  background: var(--info-bg); }
.badge.signed     { color: var(--brand); background: var(--brand-soft); }
.badge.optin      { color: var(--info);  background: var(--info-bg); }
.badge.kept       { color: var(--text-dim); background: var(--bg-row); border-color: var(--line); }
.badge.waived     { color: var(--danger); background: var(--danger-bg); }
.badge.renounced  { color: var(--text-faint); background: var(--bg-row); border-color: var(--line); }

/* decision toggles (visible in row) */
.decisions {
  display: inline-flex; gap: 4px;
  padding: 3px;
  border-radius: 8px;
  background: var(--bg-row);
  border: 1px solid var(--line);
}
.decisions.equal {
  display: inline-grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
}
.decisions.equal.two   { width: 200px; max-width: 100%; }
.decisions.equal.three { width: 290px; max-width: 100%; }
.decisions.equal.four  { width: 360px; max-width: 100%; }
.decisions button {
  height: 28px; padding: 0 8px;
  border: none; background: transparent;
  border-radius: 5px;
  font-size: 11.5px; font-weight: 600;
  color: var(--text-dim);
  letter-spacing: 0.01em;
  transition: all .12s;
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  position: relative;
  min-width: 0;     /* allow shrinking inside grid cells */
  overflow: hidden;
}
@media (hover: hover) {
  .decisions button:hover:not(.on-yes):not(.on-no):not(.on-neutral):not(.on-pick) {
    color: var(--text); background: var(--bg-row-hover);
  }
}
/* [COLOUR] decision colours: BLUE chosen ✓ (unified 2026-06-05 — was green --pos in this 3-btn layout but
   --brand blue in the apron resign-only layout, so the SAME button changed colour by mode; owner-caught) /
   oxblood terminal / blue pick / grey neutral. All "✓ chosen" decision buttons now match the blue confirm. */
.decisions button.on-yes  { background: var(--brand);  color: #fff; }
.decisions button.on-no   { background: var(--danger-btn, var(--danger)); color: #fff; }
.decisions button.on-pick { background: var(--brand);  color: #fff; }
/* Hold = neutral but DEFINITIVE: a solid GREY (not text-dim) + white text */
.decisions button.on-neutral { background: var(--neutral); color: #fff; }
.decisions .dec-icon { width: 12px; height: 12px; flex-shrink: 0; }
.decisions .dec-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* During an in-line salary edit: dim the OTHER (non-active) buttons so the
   user understands they're in a confirm/cancel context. Still clickable. */
.decisions.during-edit button:not(.on-yes):not(.on-no):not(.on-neutral):not(.on-pick) {
  opacity: 0.4;
}
.decisions.during-edit button:not(.on-yes):not(.on-no):not(.on-neutral):not(.on-pick):hover {
  opacity: 0.7;
  background: var(--bg-row-hover);
}

/* formula text shown under salary in cap-mode FA rows */
.formula-inline {
  font-size: 10.5px; color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  letter-spacing: 0.01em;
}

/* tiny pencil for non-guar salary override */
.pencil.tiny {
  width: 22px; height: 22px;
  opacity: 0;
  transition: opacity .12s, color .12s, background .12s;
}
.tbl tbody tr:hover .pencil.tiny { opacity: 0.7; }
.pencil.tiny:hover { opacity: 1; }
.pencil.tiny svg { width: 12px; height: 12px; }

/* "Restore" link shown on renounced rows */
.restore-link {
  border: none; background: transparent; padding: 0;
  color: var(--text-dim); font: inherit; font-size: 11.5px; font-weight: 600;   /* [tweak a] calm grey, not neon blue */
  cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
  margin-left: 6px;
}
.restore-link:hover { color: var(--text); }   /* [tweak a] brighten to text on hover */

/* small RFA chip on player meta */
.status-chip {
  display: inline-flex; align-items: center;
  font-size: 9.5px; font-weight: 700;
  padding: 1px 5px; border-radius: 3px;
  letter-spacing: 0.04em; text-transform: uppercase;
}
.status-chip.rfa { color: var(--gold); background: rgba(253,185,39,0.15); }

/* =========================================================
   Flex-based row layout (replaces the old `<table>` rows for
   the decision tables). Columns size to their content — no
   wasted gap between salary and decisions on wide screens.
   ========================================================= */
.section.flex-tbl { padding: 0; }
.flex-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 14px;
  border-bottom: 1px solid var(--line);
  min-height: var(--row-h);
}
.flex-row:last-child { border-bottom: none; }

/* header row */
.flex-row.header {
  background: var(--bg-surface);
  padding-top: 11px; padding-bottom: 11px;
  min-height: 0;
  font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-faint);
  border-bottom: 1px solid var(--line);
}
/* Header has no photo — zero-height width-only spacer aligns columns. */
.flex-row.header .hdr-photo-spacer {
  flex: 0 0 var(--row-h);
  height: 0;
}
.flex-row.header .info-col {
  flex: 1 1 auto;
  padding-top: 0; padding-bottom: 0;
  min-width: 160px; max-width: none;
}
/* #5: match the body salary-col's box (inline-flex, right-aligned) so the
   "2026-27" label sits exactly over the salary numbers below it. */
.flex-row.header .salary-col {
  text-align: right;
  font-weight: 700;
}
/* R15: the salary-column header ("2026-27") doubles as a click-to-sort control —
   tap it to re-rank the roster by salary, highest first. The ↓ hints the sort. */
.flex-row.header .salary-col.salary-sort-hdr { cursor: pointer; user-select: none; transition: color .12s; }
.flex-row.header .salary-col.salary-sort-hdr:hover { color: var(--text); }
.flex-row.header .salary-col.salary-sort-hdr::after { content: " ↓"; opacity: 0.5; font-weight: 700; }
/* #5: flip the arrow when the roster is sorted ascending (lowest first) */
.flex-row.header .salary-col.salary-sort-hdr.asc::after { content: " ↑"; }
/* A: committed rosters render as .cap-row, which put the salary at the row's
   right edge (inside info-col) with no decision toggle. The shared header still
   carries a trailing row-spacer + (empty) decision-col, which strand the
   "2026-27" label ~44px LEFT of the numbers. Drop those vestigial slots so the
   160px salary-col right-aligns "2026-27" directly over the salary column.
   :has(.cap-row) keys on the cap-row layout itself, so decision/status FA tables
   (standard rows + real toggles) are untouched and keep their alignment. */
.roster-tbl:has(.cap-row) .flex-row.header .row-spacer,
.roster-tbl:has(.cap-row) .flex-row.header .decision-col { display: none; }
.flex-row.header .hdr-narrow { display: none; }

/* body row */
.flex-row.body-row:hover { background: var(--bg-row-hover); }
.flex-row.body-row.editing { background: var(--brand-soft); }
.flex-row.body-row.decided-out { opacity: 0.55; }
/* R15: new additions (signed / traded in) sit at the top of the roster, tinted
   green with a left accent — same "fresh arrival" treatment the Trade Machine
   gives incoming rows. .editing wins over this (brand-soft) while being edited. */
.roster-tbl .flex-row.body-row.is-addition:not(.editing) {
  background: color-mix(in oklab, var(--bg-surface), var(--brand) 11%);
  box-shadow: inset 3px 0 0 var(--brand);
}
.roster-tbl .flex-row.body-row.is-addition:not(.editing):hover {
  background: color-mix(in oklab, var(--bg-surface), var(--brand) 17%);
}
/* R15: drag-to-reorder visuals (mirror the Trade Machine's). Rows show a grab
   cursor; the buttons inside keep their own pointer. */
.roster-tbl .flex-row.body-row.cap-row:not(.editing) { cursor: grab; }
.roster-tbl .flex-row.body-row .pencil,
.roster-tbl .flex-row.body-row .cap-status-chip,
.roster-tbl .flex-row.body-row button { cursor: pointer; }
.roster-tbl .sort-ghost { opacity: 0.35; }
.roster-tbl .sort-chosen { background: var(--bg-row-hover); cursor: grabbing; }
.roster-tbl .sort-drag { opacity: 0.95; box-shadow: 0 8px 18px rgba(0,0,0,0.45); border-radius: 8px; }

/* row photo — fixed width, but STRETCHES to the row's full content
   height (taller on mobile where name/sub/salary stack). object-fit
   cover keeps the width fixed and crops the sides → more "zoomed in"
   the taller it gets, never growing the row itself. */
.row-photo {
  width: var(--row-h);
  align-self: stretch;
  height: auto;
  min-height: var(--row-h);
  flex-shrink: 0;
  object-fit: cover;
  object-position: top center;
}
.row-photo.placeholder {
  display: grid; place-items: center;
  border-radius: 4px;
  background: var(--bg-row);
  color: var(--text-faint);
  font-size: 12px; font-weight: 700;
  align-self: center;
  width: calc(var(--row-h) * 0.85);
  height: calc(var(--row-h) * 0.85);
}

/* ===== Committed roster as flex-row cards (matches the Options/draft
   rows): status rides the sub-line, salary sits on the right with the
   pencil beside it, so the action column only needs the buttons' width. */
.roster-tbl .flex-row .decision-col { flex: 0 0 auto; min-width: 0; }
.roster-tbl .flex-row.header .decision-col { min-width: 0; }
.player-sub .badge { height: 18px; padding: 0 7px; font-size: 10px; }
.slot-charge-note { display: block; font-size: 10px; color: var(--text-faint); font-weight: 500; }
/* open roster spots — 2ways-style: shorter, dimmer, tinted, indented,
   small dashed roster-card icon instead of a photo. */
/* shorter + indented (batch 12 #1) */
.open-slot-row { background: var(--bg-elevated); min-height: 17px; gap: 8px; padding-top: 0; padding-bottom: 0; padding-left: 16px; }
/* Lifted surface is the chosen look (the gear option was removed).
   Empty slots: small, low-contrast (text sits close to the row bg), short.
   The name + $0 live in `.cap-line1`, whose `.player-name { overflow:hidden }`
   was clipping the italic last glyph ("Roster Spot 9") — override at higher
   specificity with overflow:visible + right padding. */
.open-slot-row .info-col .cap-line1 .player-name {
  font-style: italic; font-weight: 500; font-size: 10px;
  color: color-mix(in oklab, var(--text-faint), var(--bg-elevated) 45%);
  overflow: visible; text-overflow: clip; padding-right: 7px;
}
.open-slot-row .info-col .cap-line1 .cap-salary,
.open-slot-row .info-col .cap-line1 .cap-salary .money {
  font-weight: 500; font-size: 10px;
  color: color-mix(in oklab, var(--text-faint), var(--bg-elevated) 45%);
}
.open-slot-row .info-col { margin-left: 12px; }
.open-slot-row .row-photo.open-slot-art {
  align-self: center; width: 20px; height: 12px; min-height: 12px;
  border: 1px dashed color-mix(in oklab, var(--line), var(--bg-app) 55%);
  background: transparent; color: var(--text-faint); border-radius: 3px;
}
.open-slot-row .row-photo.open-slot-art svg { width: 11px; height: 11px; }
/* #6: friendly-ghost icon for empty roster spots (CSS mask, recoloured), matching
   the optional roster-spot ghost's colour (--text-faint). */
.open-slot-row .row-photo.open-slot-art .slot-ghost-icon {
  display: block; width: 12px; height: 11px;
  background-color: var(--text-faint);   /* match the optional roster-spot ghost */
  -webkit-mask: url(assets/friendly-ghost-svgrepo-com.svg) center / contain no-repeat;
  mask: url(assets/friendly-ghost-svgrepo-com.svg) center / contain no-repeat;
}
/* Minimum roster spots: readable (bigger text + more contrast) but VERY short
   rows — kill nearly all the vertical space (#1). The row was ~33px tall mostly
   from the info-col; force the row + info-col to hug the single text line. */
.open-slot-row { min-height: 0; height: 22px; padding-top: 0; padding-bottom: 0; gap: 8px; align-items: center; overflow: hidden; }
.open-slot-row .info-col { gap: 0; min-height: 0; justify-content: center; }
.open-slot-row .info-col .cap-line1 { line-height: 1.1; }
.open-slot-row .row-photo.open-slot-art { width: 22px; height: 12px; min-height: 12px; }
.open-slot-row .info-col .cap-line1 .player-name,
.open-slot-row .info-col .cap-line1 .cap-salary,
.open-slot-row .info-col .cap-line1 .cap-salary .money {
  font-size: 11px; line-height: 1.15;
  /* lift contrast vs the elevated row bg (was mixed 45% toward bg) */
  color: var(--text-dim);
}
.roster-zone-head.minimum { padding: 6px 12px 2px; font-size: 10px; }

/* cap-sheet zone sub-headers (Hold for trade / Minimum roster spots /
   Renounced) inside the same Cap-Hits sheet. */
.roster-zone-head {
  display: flex; align-items: center; gap: 8px;
  padding: 14px 12px 6px; font-size: 11.5px; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-dim);
}
.roster-zone-head .count { font-size: 11px; color: var(--text-faint); }
.roster-zone-head.renounced { color: var(--text-faint); }

/* renounced rows — compact, like 2ways "removed from roster" (#7);
   dimmed until the row is being edited (#4 / batch 10). */
.renounced-row { padding-top: 4px; padding-bottom: 4px; opacity: 0.55; }
.renounced-row.editing { opacity: 1; }
.renounced-row .row-photo { width: 40px; min-height: 40px; align-self: center; }
.renounced-row .player-name { font-size: 12.5px; }

/* ===== Dead-money tier — waived players, below the active rows and above the
   open-slot ghosts. Smaller than an active row (~44px) but bigger than the
   22px ghosts; indented; a muted --danger left accent (mirror of .is-addition).
   The salary cell shows the REAL dead money (the guaranteed amount that stuck),
   never $0 — that's the whole point of the corrected model. Tokens only so it
   reads in light + both dark themes. --dead-desat is the one-line grayscale dial. */
.roster-zone-head.dead-money { color: var(--text-dim); }
.roster-zone-head.dead-money .count { color: var(--text-faint); }

/* Waive / buy out / stretch — the "Dead money" section button + the panel. */
.roster-zone-head.dead-money { display: flex; align-items: center; gap: 8px; }
.waive-add {
  margin-left: auto; font-size: 10.5px; font-weight: 700; letter-spacing: 0.01em;
  padding: 3px 10px; border-radius: 7px; cursor: pointer;
  border: 1px solid var(--line-strong); background: var(--bg-elevated); color: var(--text-dim);
}
.waive-add:hover { border-color: var(--danger); color: var(--text); }
.wp-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.55); z-index: 300; display: grid; place-items: center; }
.wp-panel {
  background: var(--bg-surface); border: 1px solid var(--line-strong); border-radius: 14px;
  box-shadow: var(--shadow-lg); width: 360px; max-width: 92vw; padding: 16px;
  display: flex; flex-direction: column; gap: 12px; font-size: 13px; color: var(--text);
}
.wp-head { display: flex; align-items: center; justify-content: space-between; }
.wp-head b { font-size: 14.5px; }
.wp-x { border: 0; background: transparent; color: var(--text-faint); font-size: 16px; cursor: pointer; line-height: 1; }
.wp-x:hover { color: var(--text); }
.wp-field { display: flex; flex-direction: column; gap: 4px; }
.wp-field > span { font-size: 11px; font-weight: 600; color: var(--text-dim); }
.wp-field select, .wp-field input {
  height: 32px; padding: 0 8px; border-radius: 8px; box-sizing: border-box; width: 100%;
  border: 1px solid var(--line); background: var(--bg-elevated); color: var(--text); font: inherit;
}
.wp-seg { display: flex; gap: 4px; background: var(--bg-elevated); border-radius: 9px; padding: 3px; }
.wp-seg button { flex: 1; height: 28px; border: 0; border-radius: 6px; background: transparent; color: var(--text-dim); font: inherit; font-weight: 600; cursor: pointer; }
.wp-seg button.on { background: var(--bg-surface); color: var(--text); box-shadow: 0 1px 3px rgba(0,0,0,0.2); }
/* Player picklist (taller rows + super-zoom head crop, like the outgoing-trade chips) */
.wp-picklist { display: flex; flex-direction: column; gap: 2px; max-height: 236px; overflow-y: auto; border: 1px solid var(--line); border-radius: 9px; padding: 4px; background: var(--bg-elevated); }
.wp-pick { display: flex; align-items: center; gap: 10px; min-height: 44px; flex-shrink: 0; padding: 0 8px; border: 0; border-radius: 7px; background: transparent; color: var(--text); font: inherit; cursor: pointer; text-align: left; }
.wp-pick:hover { background: var(--bg-surface); }
.wp-pick.on { background: color-mix(in oklab, var(--danger), transparent 82%); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--danger), transparent 55%); }
.wp-pick-photo { position: relative; width: 34px; height: 34px; border-radius: 8px; overflow: hidden; background: var(--bg-surface); display: inline-grid; place-items: center; flex-shrink: 0; }
.wp-pick-photo::before { content: attr(data-init); font-size: 10px; font-weight: 700; color: var(--text-faint); }
.wp-pick-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 8%; transform: scale(1.5); transform-origin: 50% 8%; }
.wp-pick-name { flex: 1; min-width: 0; font-weight: 600; font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wp-pick-sal { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.15; font-variant-numeric: tabular-nums; color: var(--text); font-size: 12.5px; flex-shrink: 0; }
.wp-pick-yrs { font-size: 10px; color: var(--text-faint); font-weight: 500; }
.wp-elect { display: flex; align-items: center; gap: 8px; }
.wp-elect-lbl { font-size: 11px; font-weight: 600; color: var(--text-dim); white-space: nowrap; }
.wp-elect .wp-seg { flex: 1; }
.wp-seg.wp-seg-sm button { height: 24px; font-size: 11px; }
.wp-len { font-size: 13px; color: var(--text); }
.wp-len-note { color: var(--text-faint); font-size: 11px; }
.wp-stretch { display: flex; flex-direction: column; gap: 6px; font-size: 12.5px; color: var(--text-dim); }
.wp-check { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.wp-line b { color: var(--text); }
.wp-warn { color: var(--danger); font-size: 12px; }
/* #6: stretch is a toggle (under both Waive and Buy out), not a third mode */
.wp-toggle { display: flex; align-items: flex-start; gap: 9px; padding: 6px 2px 2px; cursor: pointer; font-size: 13px; color: var(--text); }
.wp-toggle input { margin-top: 2px; flex-shrink: 0; }
.wp-toggle-txt { display: flex; flex-direction: column; gap: 1px; }
.wp-toggle-sub { font-size: 11px; color: var(--text-faint); font-weight: 400; }
.wp-ok { color: var(--pos); font-size: 11.5px; }   /* [COLOUR] on-system green (was hardcoded #4caf82) */
.wp-summary { border-top: 1px solid var(--line); padding-top: 10px; font-size: 13px; display: flex; flex-direction: column; gap: 3px; }
.wp-sum-line { display: flex; justify-content: space-between; align-items: baseline; }
.wp-sum-line b { color: var(--text); }
.wp-dead { color: var(--danger); }
.wp-summary b { color: var(--text); }
.wp-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 2px; }

/* Waiver guardrail — the nudge + "do it anyway" acknowledgement shown before a
   team books avoidable dead money (waive panel = A · decide menu = B). */
.waiver-guard {
  margin: 4px 0 2px;
  padding: 9px 11px;
  border: 1px solid color-mix(in oklab, var(--danger), transparent 55%);
  background: color-mix(in oklab, var(--danger), transparent 88%);
  border-radius: 10px;
  display: flex; flex-direction: column; gap: 8px;
}
.waiver-guard-msg { display: flex; gap: 8px; align-items: flex-start; font-size: 12px; line-height: 1.45; color: var(--text); }
.waiver-guard .wg-ico { flex-shrink: 0; }
.waiver-guard-ack { display: flex; gap: 8px; align-items: center; font-size: 12px; font-weight: 600; cursor: pointer; color: var(--text); }
.waiver-guard-ack input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--brand); flex-shrink: 0; }
.waiver-guard.acked { opacity: 0.65; }
.wp-cancel, .wp-go { height: 32px; padding: 0 14px; border-radius: 8px; font: inherit; font-weight: 600; cursor: pointer; }
.wp-cancel { border: 1px solid var(--line); background: transparent; color: var(--text-dim); }
.wp-go { border: 0; background: var(--danger-btn, var(--danger)); color: #fff; }   /* [COLOUR] terminal-action red (oxblood), matching the decide-menu Waive */
.wp-go:disabled { opacity: 0.5; cursor: not-allowed; }

.dead-row {
  --dead-desat: 1;
  min-height: 62px; height: auto;
  padding-left: 8px;                  /* align with active rows — no indent (colour distinguishes the zone) */
  gap: 8px; align-items: center;
  background: color-mix(in oklab, var(--bg-elevated), var(--danger) 6%);
  opacity: 0.92;                      /* dimmer than active, brighter than ghosts */   /* [tweak d] left accent bar removed */
}
.dead-row:hover { background: color-mix(in oklab, var(--bg-elevated), var(--danger) 11%); }
.dead-row .info-col { gap: 3px; justify-content: center; margin-left: 0; }
.dead-row .cap-line1 .player-name { font-size: 12.5px; color: var(--text-faint) !important; font-weight: 600; }   /* lower-contrast name on a tombstone */
.dead-row .cap-salary .money { color: var(--text-dim); font-weight: 700; }
.dead-row .player-sub { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.dead-row .dead-tag {
  font-size: 10px; font-weight: 700; letter-spacing: 0.03em;
  text-transform: uppercase; color: var(--danger);
}
.dead-row .dead-meta { font-size: 10px; color: var(--text-faint); }
.dead-row .restore-link { margin-left: 2px; }

/* ----- the TOMBSTONE outline framing the reused face crop ----- */
.dead-row .dead-art {
  width: calc(var(--row-h) * 0.92);
  min-height: 0; align-self: center;
  background: transparent; border: none;
  display: grid; place-items: end start;   /* grave sits on its base; LEFT-aligned to match active photos (no indent) */
}
/* Headstone modeled on the reference SVGs: a tall ROUNDED-TOP stone in muted
   blue-grey, on a wide square base, with a dark, low-key grass strip. The head is
   a SMALL faint engraving in the upper third (not a full framed photo). No 3D side. */
.tombstone { position: relative; display: block; width: 50px; height: 56px; }
.tombstone .photo {                   /* THE STONE — muted blue-grey, full arch top */
  position: absolute; left: 50%; top: 0; transform: translateX(-50%);
  width: 38px; height: 43px;
  border-radius: 19px 19px 4px 4px;   /* radius ≈ half width → semicircular top */
  overflow: hidden;
  background: color-mix(in oklab, #6f8087, var(--bg-row) 32%);
  border: 1px solid color-mix(in oklab, #4f5c5f, var(--bg-row) 25%);
  display: grid; place-items: center;
  color: var(--text-faint); font-weight: 700; font-size: 10px;
  z-index: 2;
}
.tombstone .photo img {               /* head FILLS the stone (previous zoom, a touch smaller) */
  width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 8%;
  transform: scale(1.35); transform-origin: 50% 8%;
  filter: grayscale(1) contrast(0.85);
  opacity: 0.55;
}
.tombstone::after {                   /* wide square base plinth */
  content: ""; position: absolute; left: 50%; bottom: 7px; transform: translateX(-50%);
  width: 48px; height: 8px;
  background: color-mix(in oklab, #55666c, var(--bg-row) 28%);
  border: 1px solid color-mix(in oklab, #465255, var(--bg-row) 22%);
  border-radius: 2px; z-index: 1;
}
.tombstone::before {                  /* dark, desaturated, low-opacity grass tufts */
  content: ""; position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  width: 52px; height: 8px;
  background: #3a4a35;
  filter: saturate(0.45);
  opacity: 0.5;
  clip-path: polygon(0% 100%, 0% 55%, 8% 26%, 16% 58%, 25% 18%, 34% 58%, 43% 30%, 50% 15%, 57% 30%, 66% 58%, 75% 18%, 84% 58%, 92% 28%, 100% 55%, 100% 100%);
  z-index: 3;
}
/* (multi-tombstone shrink rules removed — tombstones keep a CONSTANT size regardless of
   how many dead-money players, so waiving a 2nd one no longer resizes/moves the heads.
   The old rules targeted `.tombstone .photo`, which on the SVG stone is the head overlay.) */

/* ── SVG headstone art (Display settings ▸ Tombstone: Stone A / Stone B) ───────
   The chosen SVG draws the whole stone + base + grass, so the CSS-drawn pieces
   are dropped and the player's head is overlaid (same fill-zoom, a touch smaller)
   on the stone face. The head's top/width is tuned PER STONE (positions are
   first-pass estimates — eyeball + nudge). */
html[data-deadart="svg14"] .tombstone,
html[data-deadart="svg15"] .tombstone {
  height: 58px;   /* per-SVG width below matches each portrait crop's aspect */
  background-repeat: no-repeat; background-position: center bottom; background-size: contain;
}
html[data-deadart="svg15"] .tombstone { width: 42px; background-image: url("assets/tomb-15.svg?v=210"); }  /* 307×421 crop */
html[data-deadart="svg14"] .tombstone { width: 45px; background-image: url("assets/tomb-14.svg?v=210"); }  /* 381×491 crop */
/* SVG already has the stone/base/grass — remove the CSS-drawn ones */
html[data-deadart="svg14"] .tombstone::before, html[data-deadart="svg14"] .tombstone::after,
html[data-deadart="svg15"] .tombstone::before, html[data-deadart="svg15"] .tombstone::after { content: none; }
/* the head, overlaid on the stone face (positions are eyeball-tunable per stone) */
html[data-deadart="svg14"] .tombstone .photo,
html[data-deadart="svg15"] .tombstone .photo {
  position: absolute; left: 50%; transform: translateX(-50%);
  background: transparent; border: 0; border-radius: 8px 8px 3px 3px;
  overflow: hidden; place-items: center; z-index: 2;
}
html[data-deadart="svg15"] .tombstone .photo { top: 20%; width: 52%; height: 26%; }
/* Stone B's FACE is offset right (the dark left line at top is the angled 3D side,
   not part of the face), so shift the head right to centre on the face. */
html[data-deadart="svg14"] .tombstone .photo { top: 28%; left: 53.5%; width: 80%; height: 52%; }
html[data-deadart="svg14"] .tombstone .photo img,
html[data-deadart="svg15"] .tombstone .photo img {
  width: 100%; height: 100%; aspect-ratio: auto; margin: 0;
  object-fit: cover; object-position: 50% 8%;
  transform: scale(1.3); transform-origin: 50% 8%;
  border-radius: 0; filter: grayscale(1) contrast(0.9); opacity: 0.7; mix-blend-mode: normal;
}

/* ----- partial-guarantee hint in the Decision table ----- */
/* Now lives in the decision-col (right side, above the Keep/Waive toggle) so it no
   longer clutters/misaligns the salary cell. Right-aligned + a little space below. */
.decision-col .pg-hint { text-align: right; margin: 0 0 3px; margin-top: 0; }
/* Partial-guarantee cost as a right-aligned sub-line under the DecideRow salary. */
.cap-salary .pg-hint.pg-sub { text-align: right; margin: 1px 0 0; white-space: nowrap; }
.pg-hint {
  display: block; margin-top: 2px;
  font-size: 10px; font-weight: 600; color: var(--text-faint);
}

/* ----- optional (15th) open slot → ghost silhouette instead of the dashed +.
   The plain empty minimum spots keep .open-slot-art exactly as-is. ----- */
.open-slot-row.optional .row-photo.ghost-art {
  border: none; background: transparent; color: var(--text-faint);
  width: 22px; height: 16px; min-height: 0; align-self: center; opacity: 0.5;
  display: grid; place-items: center;
}
.open-slot-row.optional .row-photo.ghost-art svg { width: 14px; height: 16px; }

/* in-place FA editor on the Cap Moves cap sheet (#4) */
.cap-fa-editor { margin-top: 8px; }
.cap-fa-editor .cap-moves-actions { margin-top: 0; }

/* committed-row millions editor (#2): a touch wider than the cap-holds one */
.roster-medit { display: inline-flex; }
.roster-medit input { width: 72px; }

/* ===== Cap-sheet row layout (batch 10): salary top-right on the name
   line; a single clickable status chip on line 2. ===== */
.cap-row .info-col { gap: 6px; justify-content: center; }
.cap-line1 { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; width: 100%; }
.cap-line1 .player-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cap-line1 .cap-salary { flex-shrink: 0; font-variant-numeric: tabular-nums; font-weight: 600; font-size: 13.5px; white-space: nowrap; }
/* cap-hold/option reference when it rides the name line (no-years editor) —
   keep the value small, matching the ref-row treatment. */
.cap-line1 .cap-locked { flex-shrink: 0; }
.cap-line1 .cap-locked .money { font-size: 11px; }
.cap-line1 .cap-salary .counts-note { display: none; }
.cap-line2 { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; min-height: 24px; }
/* #2: the contract-years label rides this (chip) line, pushed right by space-between,
   so it no longer makes cap-line1 two lines tall and shove the status chip down.
   #3: cursor:help hints the hover tooltip that decodes P/T/PG/NG. */
.cap-line2 .cap-yrs { flex-shrink: 0; cursor: help; }
.cap-note { font-size: 10.5px; color: var(--text-faint); flex-shrink: 0; white-space: nowrap; }
.cap-edit-controls { display: inline-flex; gap: 8px; align-items: center; }
/* status chip = the edit trigger (combines old badge + pencil) */
.cap-status-chip {
  display: inline-flex; align-items: center; gap: 5px;
  border: 1px solid var(--line); background: var(--bg-row);
  color: var(--text-dim); border-radius: 6px; padding: 3px 9px;
  font: inherit; font-size: 11px; font-weight: 600; cursor: pointer;
  max-width: 100%; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cap-status-chip svg { width: 12px; height: 12px; flex-shrink: 0; opacity: 0.7; }
.cap-status-chip:hover:not(.static) { color: var(--text); border-color: var(--brand-line); }
.cap-status-chip.on { border-color: var(--brand); color: var(--brand); }
.cap-status-chip.static { cursor: default; }
/* a row's pencil is locked (dimmed, no-op) while another row's editor has
   unsaved changes — finish that edit (✓/✗) first. */
.cap-status-chip.locked { opacity: 0.4; cursor: not-allowed; }
.cap-status-chip.locked:hover { color: var(--text-dim); border-color: var(--line); }
.cap-status-chip.static svg { display: none; }
.cap-status-chip.signed { color: var(--brand); border-color: var(--brand-line); background: var(--brand-soft); }
/* a1: trade-acquired players read "Traded" in the TM's incoming cyan, so they're
   distinct from hand-signed (green) additions. Static (no pencil) — edit in TM. */
.cap-status-chip.traded { color: var(--incoming); border-color: color-mix(in oklab, var(--incoming) 45%, var(--line)); background: color-mix(in oklab, var(--incoming) 13%, transparent); }
/* opted-in / exercised: an active, editable decision — coloured so it reads as
   clickable, not like the gray static "Guaranteed" chip. */
.cap-status-chip.optin { color: var(--text-dim); border-color: var(--line); background: var(--pos-bg); }   /* [COLOUR] subtle green box, grey text (was blue neon) */
.cap-status-chip.renounced { color: var(--text-faint); }
.open-slot-row.cap-row .cap-line1 { align-items: center; }

/* ===== Cap-sheet in-place editor (batch 11) ===== */
/* locked reference figure (Cap hold / Option) shown left-labelled */
.cap-locked { display: inline-flex; align-items: baseline; gap: 6px; flex-shrink: 0; }
.cap-lbl { font-size: 10px; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; color: var(--text-faint); }
.cap-locked .money, .money.dim { color: var(--text-faint); }
/* line 2 reference row: compact Cap hold (left) + Salary box (right),
   spanning the full info-col width; wraps on very narrow screens. */
.cap-ref-row { display: flex; width: 100%; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; row-gap: 4px; }
/* Cap hold is just a reference figure — keep it small (batch 14d #1). */
.cap-ref-row .cap-locked .money { font-size: 11px; }
/* Salary label + box (+ inline ✓/✗); wraps so the ✓/✗ drop below the box
   rather than overflow on a narrow phone. */
.cap-edit-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.cap-opt-toggle { width: 160px; max-width: 100%; }
.cap-moves-actions.is-disabled { opacity: 0.4; pointer-events: none; }

/* batch 14 — editing row = column: top block (photo + controls) then a
   full-width advice bar with larger ✓/✗ running under the photo too. */
.cap-row.editing { background: var(--brand-soft); flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 6px; }
.cap-row .cap-moves-actions { margin-top: 6px; }
.cap-row .cap-moves-actions .decisions.equal.three button { padding-top: 7px; padding-bottom: 7px; }
/* in the in-place editor the segmented control spans full width so it shares
   the reference row's right edge (scoped to the .resign-edit grid — not the
   Cap Holds idle page). Targets .three/.four explicitly so it outranks the
   fixed-width rules (.cap-moves-actions .decisions.equal.three/.four) later. */
.resign-edit .cap-moves-actions { width: 100%; }
.resign-edit .cap-moves-actions .decisions.equal.three,
.resign-edit .cap-moves-actions .decisions.equal.four { width: 100%; }

/* ===== Option-player decision control: "Opt in" + a thin divider + the
   Sign/Hold/Renounce "opt-out" trio. 4 EQUAL buttons (each flex:1): the
   trio wrapper is display:contents so the buttons flow flat; the separator
   is a REAL flex element (never clipped) drawn as the divider line. ===== */
.resign-edit .optgrp { display: flex; width: 100%; gap: 4px; align-items: stretch; }
.optgrp > button, .optgrp-trio > button { flex: 1; min-width: 0; box-sizing: border-box; }
.optgrp-trio { display: contents; }
.optgrp-sep {
  flex: 0 0 1px; width: 1px; align-self: stretch;
  margin: 3px 2px; background: var(--line-strong); border-radius: 1px;
}
.cap-advice-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 1px 0 0; border-top: none; }
.cap-advice-bar .cap-advice { flex: 1; min-width: 0; margin-top: 0; min-height: 0; font-size: 11px; }
.cap-edit-confirm { display: inline-flex; gap: 14px; flex-shrink: 0; padding-right: 4px; }
/* ✓/✗ as real bordered buttons (batch 14b #1b): confirm tinted green,
   cancel a neutral outline with a red glyph. Full-size button; the slim bar
   padding (above) keeps the strip short. */
.cap-advice-bar .pencil { width: 34px; height: 34px; border-color: var(--line); background: var(--bg-row); }
.cap-advice-bar .pencil.confirm { border-color: var(--brand-line); background: var(--brand-soft); color: var(--brand); }
.cap-advice-bar .pencil.confirm:hover { background: var(--brand); color: #07140d; }
.cap-advice-bar .pencil.cancel { color: var(--danger); }
.cap-advice-bar .pencil.cancel:hover { border-color: var(--danger); background: var(--bg-row-hover); }

/* renounced: single line — chip sits where the $ was; brighten on edit */
.renounced-row .cap-line1 .cap-status-chip { flex-shrink: 0; }

.roster-sep {
  padding: 7px 12px; font-size: 11px; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--danger);
  background: var(--bg-row); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.over-max .row-photo, .over-max .player-name { opacity: 0.7; }

/* draft-pick photo as a row-photo-sized picker button */
.flex-row .row-photo-btn {
  align-self: stretch; flex-shrink: 0;
  padding: 0; border: none; background: none; cursor: pointer;
  position: relative; display: inline-flex;
}
.row-photo.placeholder.draft-select {
  border: 1px dashed var(--line-strong); background: transparent;
  color: var(--text-dim); gap: 1px;   /* #5: neutral (was bright green); blue accent on hover */
}
.row-photo-btn:hover .row-photo.placeholder.draft-select {
  border-color: var(--brand-line); background: var(--brand-soft); color: var(--brand);
}
.row-photo.placeholder.draft-select svg { width: 14px; height: 14px; }

/* ===== Cap Moves: per-FA final-salary entry + advisory ===== */
.cap-moves-tbl .info-col { min-width: 200px; }
/* Photo fills the whole row (like the Options-page rows). Row height is
   driven by the compact content, so it stays short in both states. */
.cap-moves-row .row-photo { border-radius: 6px; }
.salary-edit.inline-final {
  display: inline-flex; align-items: center; gap: 2px;
  border: 1px solid var(--line); border-radius: 6px;
  padding: 2px 8px; background: var(--bg-app);
}
.salary-edit.inline-final input {
  width: 92px; border: none; background: transparent; color: var(--text);
  font: inherit; font-weight: 700; font-variant-numeric: tabular-nums; text-align: right;
}
.salary-edit.inline-final input:focus { outline: none; }
.salary-edit.inline-final .pre { color: var(--text-faint); }
/* locked box: the salary the pending decision implies (not editable). */
.salary-edit.inline-final.is-locked { opacity: 0.55; }
.salary-edit.inline-final input:disabled { color: var(--text-dim); cursor: not-allowed; }
/* block child of the info column — must NOT use `flex: 1 1 180px` here
   (in a column that resolves to a 180px-tall box and balloons the row).
   Reserve room for the longest advisory so the box doesn't jump in
   height as the message changes while typing (#4). */
.cap-advice { display: block; font-size: 11px; line-height: 1.35; margin-top: 4px; min-height: 2.6em; }
.signed-amt { color: var(--brand); }
.cap-advice.info  { color: var(--text-dim); }
.cap-advice.warn  { color: var(--warn); }
.cap-advice.error { color: var(--danger); }
.hold-meta { color: var(--text-faint); }
/* signed FA line + the "counts X / re-sign Y" dual figure (#3) */
.cap-signed-line { font-size: 12px; color: var(--text); margin-top: 4px; }
.cap-signed-line .counts-note { color: var(--text-faint); font-weight: 500; }
.counts-note { display: block; font-size: 10.5px; color: var(--text-faint); font-weight: 500; }
.salary-col .counts-note { text-align: right; }

/* Cap-salary becomes a small flex column so the contract-yrs sub-line lands
   under the money number in Cap Moves rows (Build/Final use salary-col which
   is already block-stacked). */
.cap-salary { display: inline-flex; flex-direction: column; align-items: flex-end; }
.cap-salary .contract-yrs { font-size: 10.5px; }
/* renounced sub-header inside the same Free-agents box (2ways-style demote) */
.cap-renounced-head {
  padding: 9px 12px 6px; font-size: 11px; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-faint);
  border-top: 1px solid var(--line); margin-top: 2px;
}
.cap-moves-actions { margin-top: 8px; }
.cap-moves-actions .decisions.equal.three { width: 330px; max-width: 100%; }
.cap-moves-actions .decisions.equal.four  { width: 360px; max-width: 100%; }
@media (max-width: 600px) {
  .cap-moves-actions .decisions.equal.three,
  .cap-moves-actions .decisions.equal.four { width: 100%; }
  /* cap-holds rows must NOT inherit the apron FA editing wrap (which
     reflows columns) — keep photo + info side-by-side while editing. */
  .cap-moves-tbl .flex-row.body-row.editing { flex-wrap: nowrap; }
}

/* (Room MLE explainer box removed — #4. The Room MLE still appears in the
   Exceptions panel; the cap-holds page no longer carries the collapsible box.) */

/* Mobile (#9): edit-action buttons (reset/trash/✓/✗ + pencils) bigger
   and better spaced; committed-roster controls stay inline on the right
   (the editing-wrap only applies to the apron FA table). */
@media (max-width: 600px) {
  .roster-actions { gap: 10px; }
  .roster-actions .pencil { width: 34px; height: 34px; }
  .roster-actions .pencil svg { width: 17px; height: 17px; }
  .roster-tbl:not(.cap-moves-tbl) .flex-row.body-row.editing { flex-wrap: nowrap; }
  .roster-tbl:not(.cap-moves-tbl) .flex-row.body-row.editing .decision-col { flex-basis: auto; }
}

/* info column — basis 320 so header and body align consistently; names
   are nowrap (no ellipsis) — if a name exceeds 320 it'll visually run
   into the salary column rather than truncate. Most names fit well. */
.flex-row .info-col {
  flex: 1 1 auto;          /* GROW to eat slack — no elastic void in the middle */
  min-width: 160px;
  display: flex;
  flex-direction: column;
  align-items: flex-start; /* name / sub / stacked-salary share one left edge */
  gap: 3px;                /* even rhythm between the (up to) 3 stacked lines */
  padding: 8px 0;
}
.flex-row .info-col .player-name {
  font-size: 13.5px; font-weight: 600; color: var(--text);
  white-space: nowrap;
}
/* position rides the name line (all widths); the duplicate sub badge
   is hidden so it shows exactly once, right of the name. */
.player-name .pos-name {
  display: inline-block; margin-left: 7px;
  font-size: 10px; font-weight: 700; color: var(--text-dim);
  background: var(--bg-row); padding: 1px 5px; border-radius: 3px;
  vertical-align: middle;
}
.flex-row .info-col .player-sub .pos-meta { display: none; }
.flex-row .info-col .player-sub {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px;
  font-size: 11.5px; color: var(--text-dim);
}
.flex-row .salary-inline {
  display: none;
  align-items: center; gap: 8px;
  padding-top: 0;          /* spacing comes from info-col's uniform gap */
  font-variant-numeric: tabular-nums;
  font-size: 13px; font-weight: 600;
}

/* salary column — FIXED width so $-values right-align across rows AND match
   the header's '2026-27' label position. */
.flex-row .salary-col {
  flex: 0 0 160px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: 13.5px;
  white-space: nowrap;
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
}
/* #4: vertically centre the salary block to the row so it lines up with the
   centred name + status badge in the info column (committed roster). */
.roster-tbl .flex-row .salary-col { align-self: stretch; justify-content: center; }

/* spacer — a small FIXED gutter between salary and the decision toggle.
   (info-col grows to absorb slack instead, so there's no big void and
   the layout survives much narrower before anything stacks.) */
.flex-row .row-spacer { flex: 0 0 16px; min-width: 16px; }

/* decision column — FIXED basis so the 'Decision' header lines up over the
   toggle, AND non-shrinking so the toggle's button text never gets clipped.
   When the row gets too tight, info-col absorbs the squeeze. At the
   extreme-narrow breakpoint (≤ 420px), decisions wrap to a new line. */
.flex-row .decision-col {
  flex: 0 0 200px;
  display: flex; align-items: center; justify-content: flex-end;
  text-align: right;
}
/* status-tbl ('Already on contract'): badge is much narrower than a toggle */
.flex-tbl.status-tbl .flex-row .decision-col { flex-basis: 120px; }
/* 3-button FA tables (UFA / RFA): match the 290px three-toggle width */
.flex-tbl.three-btn .flex-row .decision-col { flex-basis: 290px; }
/* apron free agents show ONE "Re-sign" button — don't reserve the 3-button
   width or it strands the button far-right with a big empty gap. */
.flex-tbl.one-btn .flex-row .decision-col { flex-basis: 116px; }
/* header label centered OVER the toggle: pin a box the exact width of
   the toggle to the right edge (same place the toggle sits) and centre
   the text in it — robust regardless of the columns to its left. */
.flex-row.header .decision-col { justify-content: flex-end; text-align: center; }
/* The label box IS the toggle's box (both resolve to the decision
   column's content width) and centres its text — so "DECISION" sits
   exactly over the toggle at every breakpoint. No hardcoded width that
   can desync when the toggle shrinks (max-width:100%) on mobile. */
.flex-row.header .hdr-dec { display: block; width: 100%; text-align: center; }

/* salary + tiny pencil */
.flex-row .salary-col .money,
.flex-row .salary-inline .money {
  display: inline-flex; align-items: center; gap: 6px;
}

.signed-tag {
  font-size: 11px; color: var(--brand); font-weight: 500;
  font-variant-numeric: tabular-nums;
}
/* Round 10 #0a: contract years remaining, sits as its own line under the salary
   (e.g. "2+1T Years"). Block so it stacks below the money cell. */
.contract-yrs {
  display: block;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  margin-top: 1px;
}
.override-tag {
  font-size: 10.5px; color: var(--text-faint); font-weight: 500;
}

/* Money component — render both, CSS chooses based on width. */
.money-compact { display: none; }

/* salary edit wrap */
.salary-edit-wrap {
  display: inline-flex; flex-direction: column;
  align-items: flex-end; gap: 5px;
  min-width: 180px;
}
.salary-edit-wrap.compact { min-width: 0; align-items: flex-start; }
.salary-edit-foot {
  display: inline-flex;
  align-items: center; gap: 4px;
  font-size: 11px; color: var(--text-faint);
}
/* final-year P/T option segmented control (Sign-FA modal) + multi-year total */
.opt-seg { display: inline-flex; gap: 4px; }
.opt-seg button {
  height: 22px; padding: 0 9px;
  border: 1px solid var(--line); border-radius: 4px;
  background: transparent; color: var(--text-dim);
  font-weight: 600; font-size: 11px; font-family: inherit; cursor: pointer;
}
.opt-seg button:hover:not(.on) { color: var(--text); border-color: var(--brand-line); }
.opt-seg button.on { background: var(--brand); color: #fff; border-color: var(--brand); }
html.dark .opt-seg button.on { color: #07140d; }
.contract-total { font-size: 11px; color: var(--text-faint); margin-top: 4px;
  font-variant-numeric: tabular-nums; }

/* G1 (a): signing-legality flags in the Sign-FA modal. Block = danger, warn = amber. */
.sign-legality { display: flex; flex-direction: column; gap: 5px; margin-top: 2px; }
.sl-row { display: flex; align-items: flex-start; gap: 7px; font-size: 12px; font-weight: 600; line-height: 1.4; padding: 7px 9px; border-radius: 7px; }
.sl-row .sl-ic { flex-shrink: 0; }
.sl-row.block { color: var(--danger); background: color-mix(in srgb, var(--danger) 13%, transparent); border: 1px solid color-mix(in srgb, var(--danger) 34%, transparent); }
.sl-row.warn  { color: var(--warn);   background: color-mix(in srgb, var(--warn) 13%, transparent);   border: 1px solid color-mix(in srgb, var(--warn) 32%, transparent); }

/* i (backlog): Sign-FA free-agent search (combobox over other teams' UFA/RFA). */
.form-row.fa-search { position: relative; }
.fa-badge { font-size: 9px; font-weight: 800; letter-spacing: .03em; padding: 1px 6px; border-radius: 999px; margin-left: 7px; vertical-align: middle; }
.fa-badge.ufa { color: var(--pos-text, var(--pos)); background: color-mix(in srgb, var(--pos) 16%, transparent); }
.fa-badge.rfa { color: var(--warn); background: color-mix(in srgb, var(--warn) 16%, transparent); }
.fa-list { position: absolute; top: 100%; left: 0; right: 0; z-index: 30; margin-top: 4px; background: var(--bg-elevated); border: 1px solid var(--line-strong); border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.32); max-height: 244px; overflow-y: auto; }
.fa-opt { display: flex; justify-content: space-between; align-items: center; gap: 10px; width: 100%; padding: 8px 11px; background: transparent; border: 0; border-bottom: 1px solid var(--line); cursor: pointer; text-align: left; font: inherit; }
.fa-opt:last-child { border-bottom: 0; }
.fa-opt:hover { background: var(--bg-row-hover); }
.fa-opt-name { font-size: 13px; font-weight: 700; color: var(--text); }
.fa-opt-meta { font-size: 11px; font-weight: 700; color: var(--text-faint); white-space: nowrap; }
.fa-opt-meta .ufa { color: var(--pos-text, var(--pos)); }
.fa-opt-meta .rfa { color: var(--warn); }
.fa-match-note { font-size: 11px; color: var(--warn); margin-top: 5px; font-weight: 600; }
.fa-match-note b { font-weight: 800; }

/* ============================================================
   G3 (e) — Snapshot modal + the shareable "changes" card (captured by html2canvas).
   ============================================================ */
.snapshot-modal { width: min(980px, 96vw); max-width: 980px; }
.snap-controls { display: flex; align-items: center; gap: 10px; padding: 10px 16px 0; }
.snap-msg { font-size: 11.5px; color: var(--text-dim); font-weight: 600; }
.snap-stage {
  padding: 14px; margin: 10px 16px; max-height: 60vh; overflow: auto;
  display: flex; justify-content: center;
  background: var(--bg-app); border-radius: 10px; border: 1px solid var(--line);
}
/* The card is the capture target — solid, self-contained. */
.snap-card {
  background: linear-gradient(160deg, var(--bg-surface), var(--bg-elevated));
  border: 1px solid var(--line-strong); border-radius: 16px;
  padding: 22px 24px; color: var(--text);
  font-variant-numeric: tabular-nums; box-sizing: border-box;
  align-self: flex-start; flex-shrink: 0;   /* keep true export size; the stage scrolls if narrow */
}
.snap-card.portrait  { width: 560px; }
.snap-card.landscape { width: 920px; }
.snap-card-head { display: flex; align-items: center; gap: 12px; padding-bottom: 14px; border-bottom: 1px solid var(--line); }
.snap-card-head .logo, .snap-card-head svg { flex-shrink: 0; }
.snap-card-title { flex: 1; min-width: 0; }
.snap-team { font-size: 20px; font-weight: 800; letter-spacing: -0.01em; }
.snap-sub { font-size: 11.5px; color: var(--text-faint); font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; margin-top: 2px; }
.snap-brand { font-size: 15px; font-weight: 700; color: var(--text-dim); letter-spacing: -0.02em; }
.snap-brand b { color: var(--brand); }
.snap-empty { padding: 30px 8px; text-align: center; color: var(--text-faint); font-size: 13px; }
.snap-groups { display: grid; grid-template-columns: 1fr; gap: 14px; padding-top: 16px; }
.snap-card.landscape .snap-groups { grid-template-columns: 1fr 1fr; gap: 14px 28px; }
.snap-group { break-inside: avoid; }
.snap-group-h {
  display: flex; align-items: center; gap: 8px;
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--brand); padding-bottom: 6px; margin-bottom: 2px; border-bottom: 1px solid var(--line);
}
.snap-group-h span { background: rgba(255,255,255,0.10); color: var(--brand); border-radius: 999px; padding: 0 7px; font-size: 10px; }
.snap-row { display: flex; align-items: baseline; gap: 8px; padding: 4px 0; font-size: 13px; }
.snap-row .nm { font-weight: 700; color: var(--text); }
.snap-row .meta { margin-left: auto; color: var(--text-dim); font-size: 12px; font-weight: 600; white-space: nowrap; }
.snap-card-foot {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  margin-top: 18px; padding-top: 12px; border-top: 1px solid var(--line);
  font-size: 13px; color: var(--text-dim);
}
.snap-card-foot b { color: var(--text); font-weight: 800; }
.snap-card-foot .pos { color: var(--pos-text, var(--pos)); font-weight: 700; }
.snap-card-foot .neg { color: var(--danger); font-weight: 700; }
/* Fixed-width total so the dollar figure can't shift the raise stepper as it
   changes (the % control stays put). Wide enough for "$248.0M". */
.ct-amt { display: inline-block; min-width: 5em; }

/* contract raise controls (gear → Contract raises: single / per-year) */
.raise-stepper { display: inline-flex; align-items: center; gap: 4px; vertical-align: middle; }
.raise-stepper button {
  width: 18px; height: 18px; padding: 0; line-height: 1;
  border: 1px solid var(--line); border-radius: 4px; background: transparent;
  color: var(--text-dim); font: inherit; font-weight: 700; cursor: pointer;
}
.raise-stepper button:disabled { opacity: 0.35; cursor: not-allowed; }
.raise-stepper button:hover:not(:disabled) { color: var(--text); border-color: var(--brand-line); }
.raise-val { min-width: 36px; text-align: center; color: var(--text); font-weight: 600; }
.raise-peryear { display: flex; flex-direction: column; gap: 4px; margin-top: 5px; }

/* Apron re-sign editor uses a 2-col grid [photo | content] so the per-year
   list lines up EXACTLY with the info column (no guessed margin), while the
   photo only spans the top row (doesn't stretch down into the list). */
.cap-row.editing.resign-edit {
  display: grid; grid-template-columns: var(--row-h) 1fr;
  column-gap: 14px; row-gap: 3px; align-items: start;
}
@media (max-width: 600px) { .cap-row.editing.resign-edit { grid-template-columns: 62px 1fr; } }
.resign-edit > .row-photo { grid-column: 1; grid-row: 1; width: 100%; align-self: stretch; }
.resign-edit > .info-col { grid-column: 2; grid-row: 1; padding-top: 3px; }
/* the mobile gutter rule (.flex-row .info-col { margin-left:6px }) shifts the
   info-col content 6px right of its grid column, but the per-year list (same
   column) has no such margin — zero it here so they line up at all widths. */
.cap-row.editing.resign-edit > .info-col { margin-left: 0; }
.resign-edit > .raise-peryear { grid-column: 2; grid-row: 2; margin-top: 0; }
/* Single-year (no per-year/Years row): the ✓/✗ bar sits flush under the buttons
   (row 2, row-gap negated) — no empty band above it. cap-grid overrides below. */
.resign-edit > .cap-advice-bar { grid-column: 1 / -1; grid-row: 2; }
.resign-edit:not(.cap-grid) > .cap-advice-bar { margin-top: -3px; }
/* Cap Moves only (.cap-grid): the Years bar gets its OWN row below the photo
   (so the photo spans only down to the decision buttons), with "Years" in the
   photo column and the buttons/total aligned to the info column. Per-year and
   the bottom bar shift down a row. */
.resign-edit > .contract-bar {
  grid-column: 1 / -1; grid-row: 2;
  display: grid; grid-template-columns: var(--row-h) 1fr; column-gap: 14px; align-items: start;
}
@media (max-width: 600px) { .resign-edit > .contract-bar { grid-template-columns: 62px 1fr; } }
.contract-bar > .resign-hdr { grid-column: 1; padding-top: 9px; }
.contract-bar-main { grid-column: 2; min-width: 0; }
.contract-bar-main .resign-field { margin-top: 0; }
.resign-edit.cap-grid > .raise-peryear { grid-row: 3; }
.resign-edit.cap-grid > .cap-advice-bar { grid-row: 4; }
.raise-py-row { display: flex; align-items: center; gap: 8px; font-size: 11px; }
.raise-py-row .resign-hdr { flex: 0 0 32px; }
.raise-py-amt { margin-left: auto; color: var(--text-faint); font-variant-numeric: tabular-nums; }
/* per-year expand/collapse toggle on the total line */
.py-toggle {
  margin-left: 6px; padding: 1px 6px; border: 1px solid var(--line);
  border-radius: 4px; background: transparent; color: var(--text-dim);
  font: inherit; font-size: 10.5px; font-weight: 600; cursor: pointer;
}
.py-toggle:hover { color: var(--text); border-color: var(--brand-line); }

/* apron re-sign editor (batch 20): full-width Years segmented control with a
   header above + Total below; Final-year Option shares the bottom bar w/ ✓/✗. */
.resign-hdr { font-size: 10px; font-weight: 700; letter-spacing: 0.03em;
  text-transform: uppercase; color: var(--text-faint); }
.resign-field { display: flex; flex-direction: column; gap: 5px; width: 100%; margin-top: 6px; }
.resign-years { width: 100%; }
/* option bar mirrors the outer editor grid: OPTION label in the photo column,
   the None/Player/Team control + ✓/✗ in the info column (lined up with Years). */
.resign-bar { display: grid; grid-template-columns: var(--row-h) 1fr; column-gap: 14px; align-items: center; }
@media (max-width: 600px) { .resign-bar { grid-template-columns: 62px 1fr; } }
.resign-bar > .resign-hdr { grid-column: 1; }
.resign-bar-main { grid-column: 2; display: flex; align-items: center; justify-content: space-between; gap: 12px; min-width: 0; }
/* When there's no Option row (1-year), ✓/✗ sit inline beside the salary box
   (no bottom bar). The salary header rides just left of the box. */
.cap-edit-line .salary-hdr { flex-shrink: 0; }
.cap-edit-line .cap-edit-confirm { gap: 8px; margin-left: 4px; }
.cap-edit-line .cap-edit-confirm .pencil { width: 30px; height: 30px; border-color: var(--line); background: var(--bg-row); }
.cap-edit-line .cap-edit-confirm .pencil.confirm { border-color: var(--brand-line); background: var(--brand-soft); color: var(--brand); }
.cap-edit-line .cap-edit-confirm .pencil.confirm:hover { background: var(--brand); color: #07140d; }
.cap-edit-line .cap-edit-confirm .pencil.cancel { color: var(--danger); }
.cap-edit-line .cap-edit-confirm .pencil.cancel:hover { border-color: var(--danger); background: var(--bg-row-hover); }
.resign-opt { width: 240px; max-width: 100%; }
/* 1-year deal can't carry a final-year option — greyed/locked to None. */
.resign-opt button:disabled, .opt-seg button:disabled { opacity: 0.4; cursor: not-allowed; }
/* breathing room above the decision buttons when no advice line sits above them. */
.cap-moves-actions.gap-top { margin-top: 14px; }

/* #3/#4 — Wide roster editor (≥601px): the photo spans the FULL panel height
   (object-fit:cover keeps the head, top-aligned), the col-1 labels (Years /
   Option — kept for the mobile stacked view) drop away, and the segmented
   controls size to a sensible max instead of stretching the whole column
   (Years especially doesn't need to be that long). */
@media (min-width: 601px) {
  .resign-edit > .row-photo { grid-row: 1 / -1; }
  .resign-edit > .contract-bar > .resign-hdr,
  .resign-edit > .resign-bar > .resign-hdr { display: none; }
  /* #1 — the Years selector and the decision/opt-in·signed·opt-out row share ONE
     max-width so they line up as equal-size controls (was years 320 vs the decision
     row 480–624, a visible mismatch; owner asked to make them the same size). The
     .three/.four selectors are needed to out-specify `.cap-moves-actions
     .decisions.equal.three { max-width:100% }` (line ~2148), which otherwise wins. */
  .resign-edit .cap-moves-actions .decisions.equal.three,
  .resign-edit .cap-moves-actions .decisions.equal.four,
  .resign-edit .cap-moves-actions .optgrp,
  .resign-edit .resign-years { max-width: 360px; }
  /* #2 — the per-year list matches that same column width, so the $ amounts sit
     right-aligned within ~360px (under the Years control) instead of being pushed
     out to the far panel edge. */
  .resign-edit .raise-peryear { max-width: 360px; }
}

/* dim other rows while one is editing */
.section.flex-tbl.has-edit .flex-row.other-editing .decision-col,
.section.flex-tbl.has-edit .flex-row.other-editing .pencil.tiny {
  opacity: 0.35; pointer-events: none;
}

/* during-edit dim of OTHER buttons inside the SAME row */
.decisions.during-edit button:not(.on-yes):not(.on-no):not(.on-neutral):not(.on-pick) { opacity: 0.4; }
.decisions.during-edit button:not(.on-yes):not(.on-no):not(.on-neutral):not(.on-pick):hover { opacity: 0.7; background: var(--bg-row-hover); }

/* lock state — when this row is locked (another row editing) */
.decisions.locked button { cursor: not-allowed; }

/* =========================================================
   Responsive — flex-based, content-driven
   ========================================================= */
@media (max-width: 1000px) {
  .page { padding: 0 18px 80px; }
  .salary-bar-inner { padding: 14px 18px 12px; }
  .step-tabs-inner { padding: 0 18px; }
  .flex-row { gap: 12px; padding: 8px 12px; }
  .flex-row .info-col .player-sub .max-meta { display: none; }
}

/* < 680: switch full dollar value to compact ($M); KEEP the salary col */
@media (max-width: 680px) {
  .money-full { display: none; }
  .money-compact { display: inline; }
  .flex-row .salary-col { flex-basis: 110px; }
}

/* ≤ 720: STACK SALARY INLINE — salary moves under the player's name; the
   dedicated salary column disappears. Decisions STAY on the right; info-col
   shrinks to make room for them. */
@media (max-width: 600px) {
  /* salary collapses into the info column under the player's name */
  .flex-row .salary-col { display: none; }
  .flex-row .salary-inline {
    display: inline-flex;
    align-items: center; gap: 8px;
    padding-top: 0;
    font-variant-numeric: tabular-nums;
    font-size: 13px; font-weight: 600;
  }
  .flex-row .row-spacer { min-width: 4px; }
  /* header swap: PLAYER → 2026-27 (since the column now contains the salary) */
  .flex-row.header .salary-col { display: none; }
  .flex-row.header .hdr-wide   { display: none; }
  .flex-row.header .hdr-narrow { display: inline; }
  /* let info-col shrink freely so the decision column always fits */
  .flex-row .info-col { min-width: 0; }

  /* While a row is editing, drop the action/decision column to its own
     full-width line below. Otherwise the inline editor's foot (Years +
     ✓ / ✗) overflows under the decision-col button, which paints on top
     and swallows the taps — making the ✓ / ✗ feel dead. */
  .flex-row.body-row.editing { flex-wrap: wrap; row-gap: 8px; }
  .flex-row.body-row.editing .decision-col {
    flex-basis: 100%; justify-content: flex-end;
    align-self: auto; padding-bottom: 0;
  }
}

/* ≤ 560 — mobile: full-bleed (no outer padding), position on the name
   line, decisions stay on the right but sit lower so a long (wrapping)
   name flows above them. DECISION header kept, centered over them. */
@media (max-width: 560px) {
  /* #2 — full bleed: no outer page padding, content to the edge.
     Keep a small inner pad so text isn't glued to the card border. */
  .page { padding-left: 0; padding-right: 0; }
  .salary-bar-inner { padding-left: 10px; padding-right: 10px; }
  .step-tabs-inner { padding-left: 10px; padding-right: 10px; }
  .flex-row { padding-left: 8px; padding-right: 8px; gap: 9px; }
  .section-intro { margin-left: 6px; margin-right: 6px; }
  .section { border-radius: 0; border-left: none; border-right: none; }

  /* let the name wrap so it can flow above the lowered toggle */
  .flex-row .info-col .player-name { white-space: normal; }

  /* #1 — name takes the room and wraps; the toggle stays right but
     drops to the bottom of the row so it's never covered. */
  .flex-row .info-col { flex: 1 1 auto; min-width: 0; }
  /* keep the toggle FULL size (no mobile shrink) — just drop it to the
     bottom of the row so the wrapping name sits above it. */
  .flex-row .decision-col { align-self: flex-end; padding-bottom: 5px; }
  .flex-row.header .decision-col { align-self: auto; padding-bottom: 0; }

  /* Reclaim horizontal room so the position chip stays on the NAME
     line: tighter gutter + photo + a narrower decision track. Buttons
     keep full height/padding — only the pill is less wide. The header
     label is width:100% so it stays centred over the (narrower) toggle.
     Very long names may still wrap; the chip then rides the name's
     last word (intentional), never alone on its own line. */
  .flex-row .row-photo { width: 62px; }
  .flex-row .info-col { margin-left: 6px; }
  .flex-row .row-spacer { flex: 0 0 4px; min-width: 4px; }
  .flex-row .decision-col { flex-basis: 150px; }
  .flex-tbl.three-btn .flex-row .decision-col { flex-basis: 210px; }
  .flex-row.body-row .decision-col { padding-right: 6px; }
  .flex-row.header .decision-col { padding-right: 6px; }
  /* compact the chip a hair so borderline names tip onto one line */
  .player-name .pos-name { margin-left: 5px; padding: 1px 4px; }
}

/* row actions: pencil + ghost slot */
.row-actions {
  display: inline-flex; align-items: center; gap: 6px;
  justify-content: flex-end;
  min-width: 0;
}
.pencil {
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border-radius: 6px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-faint);
  transition: all .12s;
  flex-shrink: 0;
}
.pencil:hover { color: var(--brand); border-color: var(--line); background: var(--bg-row); }
.pencil svg { width: 14px; height: 14px; }
.pencil.ghost { opacity: 0; pointer-events: none; }
.tbl tbody tr:hover .pencil.ghost { opacity: 0.35; }
.pencil.cancel { color: var(--danger); }
.pencil.confirm { color: var(--brand); }

/* edit input */
.salary-edit {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--bg-input);
  border: 1px solid var(--brand-line);
  border-radius: 6px;
  padding: 0 8px; height: 30px;
  font-size: 13px;
}
.salary-edit .pre { color: var(--text-faint); }
.salary-edit input {
  width: 110px;
  background: transparent;
  border: none; outline: none;
  font: inherit;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text);
  text-align: right;
}
.salary-edit input::-webkit-outer-spin-button,
.salary-edit input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.years-edit {
  display: inline-flex; gap: 2px; align-items: center;
  padding: 2px 6px;
  background: var(--bg-input);
  border: 1px solid var(--line);
  border-radius: 5px;
  font-size: 11.5px; color: var(--text-dim);
}
.years-edit input { width: 22px; background: transparent; border: none; outline: none; font: inherit; color: var(--text); text-align: center; }

/* hold formula hint */
.formula {
  font-size: 10.5px; color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  display: inline-block;
  max-width: 140px;
  line-height: 1.35;
}

/* ghost / open spot row */
.tbl tbody tr.ghost-row td {
  height: 44px;
  color: var(--text-faint);
  font-size: 12px;
  background: var(--bg-app);
  border-top: 1px dashed var(--line-strong);
  border-bottom: 1px dashed var(--line-strong);
}
.tbl tbody tr.ghost-row .player-cell { gap: 12px; }
.tbl tbody tr.ghost-row .open-slot {
  width: calc(var(--row-h) * 0.92);
  height: calc(var(--row-h) * 0.92);
  border-radius: 0;
  border: 1.5px dashed var(--line-strong);
  display: grid; place-items: center; color: var(--text-faint);
}

/* New open-slot rows — more visible than plain ghost. */
.tbl tbody tr.open-slot-row {
  background: color-mix(in oklab, var(--bg-app), var(--brand) 2%);
}
.tbl tbody tr.open-slot-row td {
  border-top: 1px dashed var(--brand-line);
  border-bottom: 1px dashed var(--brand-line);
  height: calc(var(--row-h) * 0.85);
}
.tbl tbody tr.open-slot-row.optional { background: var(--bg-app); }
.tbl tbody tr.open-slot-row.optional td {
  border-color: var(--line-strong);
  opacity: 0.85;
}
.tbl tbody tr.open-slot-row .open-slot-art {
  width: calc(var(--row-h) * 0.7);
  height: calc(var(--row-h) * 0.7);
  border-radius: 8px;
  border: 1.5px dashed var(--brand-line);
  background: var(--brand-soft);
  color: var(--brand);
  display: grid; place-items: center;
}
.tbl tbody tr.open-slot-row.optional .open-slot-art {
  border-color: var(--line-strong);
  background: var(--bg-row);
  color: var(--text-faint);
}
.tbl tbody tr.open-slot-row .open-slot-name {
  font-size: 13px; font-weight: 600;
  color: var(--text-dim);
  display: inline-flex; align-items: center; gap: 8px;
}
.tbl tbody tr.open-slot-row .optional-tag {
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-faint);
  background: var(--bg-row);
  border: 1px solid var(--line);
  padding: 1px 6px; border-radius: 3px;
}

/* inline-editable pick name */
.player-name-edit {
  display: inline-flex; align-items: center; gap: 6px;
  border: none; background: transparent; padding: 0;
  color: var(--text); font: inherit;
  font-size: 13.5px; font-weight: 600;
  cursor: pointer;
  border-radius: 4px;
  transition: background .12s;
}
.player-name-edit:hover { background: var(--bg-row-hover); padding: 0 4px; }
.player-name-edit .edit-hint {
  width: 12px; height: 12px;
  color: var(--text-faint);
  opacity: 0;
  transition: opacity .12s;
}
.player-name-edit:hover .edit-hint { opacity: 1; }
.inline-edit {
  background: var(--bg-input);
  border: 1px solid var(--brand-line);
  border-radius: 5px;
  padding: 4px 8px;
  font: inherit;
  font-size: 13.5px; font-weight: 600;
  color: var(--text);
  outline: none;
  width: 160px;
}

/* Pick # field on draft pick rows */
.pick-num-wrap {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; color: var(--text-dim);
}
.pick-num-input {
  width: 48px; height: 22px;
  padding: 0 6px;
  background: var(--bg-input);
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text);
  outline: none;
  text-align: center;
  -moz-appearance: textfield;
}
.pick-num-input::-webkit-outer-spin-button,
.pick-num-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.pick-num-input:focus { border-color: var(--brand-line); }

/* table footer */
.tbl-foot {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 18px;
  border-top: 1px solid var(--line);
  background: var(--bg-row);
  font-size: 12.5px; color: var(--text-dim);
}
.tbl-foot .total-num { color: var(--text); font-weight: 700; font-size: 14px; font-variant-numeric: tabular-nums; margin-left: 4px; }

/* =========================================================
   panels (Trade machine, modals)
   ========================================================= */
.scrim {
  position: fixed; inset: 0; z-index: 100;
  background: color-mix(in oklab, #000, transparent 35%);
  backdrop-filter: blur(4px);
  display: grid; place-items: center;
  padding: 24px;
  animation: fade .15s ease;
}
@keyframes fade { from { opacity: 0; } }

.modal {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  width: 100%;
  max-width: 560px;
  overflow: hidden;
  animation: pop .18s ease;
}
@keyframes pop { from { opacity: 0; transform: translateY(8px) scale(0.98); } }
.modal.wide { max-width: 1180px; max-height: 90vh; display: flex; flex-direction: column; }
.modal-head {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
}
.modal-head h3 { margin: 0; font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.modal-head .desc { color: var(--text-dim); font-size: 13px; }
.modal-body { padding: 20px; flex: 1; min-height: 0; overflow-y: auto; }
.modal-foot {
  padding: 12px 20px; border-top: 1px solid var(--line);
  display: flex; justify-content: flex-end; gap: 8px;
  background: var(--bg-row);
}

.form-row { display: flex; flex-direction: column; gap: 5px; margin-bottom: 14px; }
.form-row label { font-size: 12px; font-weight: 600; color: var(--text-dim); letter-spacing: 0.02em; }
.form-row input, .form-row select {
  background: var(--bg-input); border: 1px solid var(--line);
  border-radius: 7px; padding: 9px 11px;
  font: inherit; color: var(--text);
  font-variant-numeric: tabular-nums;
  outline: none;
  transition: border-color .12s;
}
.form-row input:focus, .form-row select:focus { border-color: var(--brand-line); }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

/* one-world #14, Phase 5a — pending (un-applied) draft-trade banner on the roster page */
.pending-trade-banner { display: flex; align-items: center; gap: 12px; margin: 0 0 14px; padding: 9px 13px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg-row, rgba(127,127,127,.06)); }
.pending-trade-banner .ptb-icon { display: inline-flex; width: 24px; height: 24px; align-items: center; justify-content: center; flex: none; color: var(--text-faint, #8a93a0); }
.pending-trade-banner .ptb-icon svg { width: 17px; height: 17px; }
.pending-trade-banner .ptb-body { flex: 1 1 auto; min-width: 0; }
.pending-trade-banner .ptb-head { font-size: 11px; font-weight: 700; letter-spacing: .02em; display: flex; align-items: center; gap: 8px; margin-bottom: 6px; color: var(--text); }
.pending-trade-banner .ptb-tag { font-size: 10.5px; font-weight: 500; color: var(--text-faint); }
.pending-trade-banner .ptb-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.pending-trade-banner .ptb-chip { font-size: 11px; line-height: 1.55; padding: 1px 9px; border-radius: 999px; border: 1px solid var(--line); white-space: nowrap; color: var(--text); }
.pending-trade-banner .ptb-chip.out { border-color: rgba(224,85,107,.45); color: #e0556b; }
.pending-trade-banner .ptb-chip.in  { border-color: rgba(76,195,145,.45); color: #2fa872; }
.pending-trade-banner .ptb-chip b { font-weight: 700; }
.pending-trade-banner .ptb-hint { font-size: 11px; color: var(--text-faint, #889); flex: none; }
/* [tweak d] banner actions: Resume (open TM) · Discard (clear draft) · Hide (dismiss) */
.pending-trade-banner .ptb-actions { display: flex; align-items: center; gap: 6px; flex: none; }
.pending-trade-banner .ptb-btn { height: 26px; padding: 0 10px; border-radius: 7px; border: 1px solid var(--line); background: var(--bg-surface); color: var(--text-dim); font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer; white-space: nowrap; transition: all .12s; }
.pending-trade-banner .ptb-btn:hover { color: var(--text); border-color: var(--line-strong); }
.pending-trade-banner .ptb-btn.resume { background: var(--brand); border-color: transparent; color: var(--brand-fg, #fff); }
.pending-trade-banner .ptb-btn.resume:hover { background: color-mix(in oklab, var(--brand), #000 10%); color: var(--brand-fg, #fff); }
.pending-trade-banner .ptb-btn.discard:hover { color: #fff; background: var(--danger-btn, var(--danger)); border-color: transparent; }
.pending-trade-banner .ptb-btn.hide { padding: 0 8px; }
@media (max-width: 760px) { .pending-trade-banner .ptb-btn.resume { padding: 0 8px; } }

/* (Old TradeMachineModal CSS removed here — the modal is retired. Its dead
   .tm-list / .tm-row / .tm-tabs / .tm-tab / .tm-cash* / .tm-verdict* /
   .tm-picker* rules collided with the new full-bleed Trade Machine, whose
   CSS is appended at the end of this file under .tm-app.) */

/* =========================================================
   misc
   ========================================================= */
.toast {
  position: fixed; bottom: 28px; left: 50%; transform: translateX(-50%);
  padding: 10px 14px;
  background: var(--text); color: var(--bg-surface);
  border-radius: 8px;
  font-size: 13px; font-weight: 600;
  z-index: 200;
  box-shadow: var(--shadow-lg);
  animation: pop .15s ease;
}

.empty {
  padding: 26px; text-align: center;
  color: var(--text-faint); font-size: 13px;
}

.kbd {
  display: inline-flex; align-items: center;
  padding: 1px 5px; border-radius: 4px;
  background: var(--bg-row); border: 1px solid var(--line);
  font-size: 10.5px; font-family: ui-monospace, monospace;
  color: var(--text-dim);
}

/* tweak panel customization */
.team-skin-strip {
  display: block;
  height: 3px;
  background: linear-gradient(90deg,
    var(--skin-1, var(--gold)) 0%, var(--skin-2, var(--purple)) 100%);
  opacity: 0;
  transition: opacity .25s;
}
html[data-team-skin="a"] .team-skin-strip,
html[data-team-skin="b"] .team-skin-strip { opacity: 1; }
/* skin A/B re-point the brand accent at the active team's colour
   (vars set per-team on <html> by app.jsx) */
html[data-team-skin="a"],
html[data-team-skin="b"] {
  --brand:      var(--skin-accent, var(--gold));
  --brand-soft: var(--skin-accent-soft, rgba(253,185,39,0.13));
  --brand-line: var(--skin-accent-line, rgba(253,185,39,0.35));
}

/* small responsive */
@media (max-width: 900px) {
  /* one team at a time: tab bar + only the active column */
  .tm-tabs {
    display: flex; flex-wrap: wrap; gap: 6px;
    padding: 12px 18px 0;
  }
  .tm { overflow-x: visible; padding-top: 12px; }
  .tm-column { flex: 1 1 100%; }
  .tm-column:not(.active) { display: none; }
  .tm-column.pinned { position: static; box-shadow: none; }
  .tm-add-slot { display: none; }   /* add via the "+ Team" tab instead */
  .sb-segmented { flex-direction: column; }
}
/* at small widths drop the subtitle so the bar stays one line (constant
   height) without overflowing — brand, team chip and actions remain. */
@media (max-width: 620px) {
  .title-row { display: none; }
}


/* ============================================================
   MOBILE SALARY BAR (design handoff, batch 43) — appended from
   design_handoff_mobile_salary_bar/mobile-bar.css. Tokens used
   (--pos/--warn/--danger/--brand-blue/--text-faint/etc.) are all
   defined in the :root blocks above.
   ============================================================ */
/* ============================================================
   Mobile salary bar — extracted from styles.css

   This block contains all CSS for:
     • The slim top strip (.salary-bar-band.mobile-bar-band, .mb-*)
     • The sticky compact strip (.mobile-sticky-strip, .ms-*)
     • The bottom thermometer card (.mobile-thermo-card, .mt-*)

   Depends on these CSS custom properties defined elsewhere in
   styles.css — bring them across or map to your own tokens:
     --bg-app, --bg-surface, --bg-row, --bg-elevated
     --text, --text-dim, --text-faint
     --line
     --brand, --brand-blue, --brand-soft
     --pos, --warn, --orange, --danger
   ============================================================ */

/* ============================================================
   MOBILE SALARY-BAR — slim text-first strip with border meters.
   Top border meter: blue, fills 0 → cap.
   Bottom border meter: green/yellow/red zones for the apron range.
   A single white vertical tick at the committed position spans both
   bars (they share one dollar axis).
   ============================================================ */

.salary-bar-band.mobile-bar-band {
  position: relative;
  padding: 0;
  overflow: hidden;
}

/* === Border meters === */
.mb-meter {
  position: absolute;
  left: 0; right: 0;
  height: 6px;            /* P: taller so the fill is actually visible (was 4px) */
  pointer-events: none;
  z-index: 1;
  overflow: hidden;
}
.mb-meter-top    { top: 0; }
.mb-meter-bottom { bottom: 0; }
/* P: a clearly-visible track so an empty / low meter reads as an intentional
   bar rather than a stray "glitch" hairline. */
.mb-meter-track {
  position: absolute; inset: 0;
  background: color-mix(in oklab, var(--bg-row), var(--text) 12%);
  opacity: 1;
}
.mb-meter-fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  transition: width 0.4s ease;
}

/* === Border-meter additions (Roster Colours handoff) ===
   .mb-meter-over = the red "over the ceiling" overtake that charges in from
   the left ON TOP of the team-colour fill (TOP meter). .mb-meter-tick = the
   faint white 1px notches marking the tax line + 1st apron (BOTTOM meter). */
.mb-meter-over {
  z-index: 2;
}
.mb-meter-tick {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: rgba(255, 255, 255, 0.32);
  z-index: 3;
  pointer-events: none;
}

/* ============================================================
   Desktop layout (Roster Colours handoff — desktop-layout.css)
     • Desktop salary bar reuses the mobile meter strip, full-width
     • Two-column page: roster (left) + vertical chart (right)
     • Salary strip pinned (sticky) at top; chart pinned in right column
   Scoped to desktop (min-width:721px) so mobile is untouched.
   ============================================================ */
/* Chunk 2 — "Decide these first" section (general; shows on mobile + desktop) */
.decide-meta { font-size: 11px; color: var(--text-faint); margin-left: 8px; }
/* Small muted type tag after the name (Player option / Team option / Non-guaranteed);
   the $ renders right-aligned at normal salary size via .cap-salary. */
.decide-tag { font-size: 11px; color: var(--text-faint); margin-left: 8px; font-weight: 500; }
/* Decide row — vertical cascade with the photo over the choice levels and a
   full-width confirm bar at the bottom (deal/advice text + ✓), mirroring the
   roster editor. Grid: [photo | content]; the foot spans both columns; the
   re-sign editor flows into its own row under the content (photo stops at the
   choices). */
.flex-row.decide-row {
  --dphoto: 68px;
  display: grid; grid-template-columns: var(--dphoto) 1fr;
  column-gap: 14px; row-gap: 3px; align-items: start;
}
@media (max-width: 600px) { .flex-row.decide-row { --dphoto: 60px; } }
/* Two photo sizes only — idle fills the single-choice row; the moment you start
   working the player (first click → .is-active) it jumps to one fixed taller
   size and STAYS there (no growing as more option levels appear). */
.decide-row > .row-photo { grid-column: 1; grid-row: 1; width: 100%; align-self: stretch; }
.decide-row.is-active > .row-photo { align-self: start; height: 112px; }
.decide-row > .info-col { grid-column: 2; grid-row: 1; margin-left: 0; gap: 6px; }
.decide-row > .decide-resign { grid-column: 2; }
.decide-row > .decide-foot { grid-column: 1 / -1; }
.decide-controls { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin-top: 6px; }
.decide-controls .decisions { width: 300px; max-width: 100%; }
.decide-resign { display: flex; flex-direction: column; gap: 6px; width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg-elevated); }
.decide-resign-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* full-width confirm bar: contextual sentence + ✓ at the end */
.decide-foot { display: flex; align-items: flex-start; gap: 12px; padding: 10px 0 12px calc(var(--dphoto) + 14px); margin-top: 5px; border-top: 1px solid var(--line); }
.decide-foot-text { flex: 1; min-width: 0; font-size: 12px; color: var(--text-dim); }
.decide-foot .pencil { width: 34px; height: 34px; border-color: var(--line); background: var(--bg-row); flex-shrink: 0; }
.decide-foot .pencil.confirm { border-color: var(--check-blue-line); background: var(--check-blue-soft); color: var(--check-blue); }
.decide-foot .pencil.confirm:hover { background: var(--check-blue); color: #fff; }
.decide-foot .pencil:disabled { opacity: 0.4; cursor: not-allowed; }

/* Confirm (✓) buttons in the decide/strategy editors: salary-bar blue (matches
   the committed-total blue), and the check glyph nudged up 1px so it reads as
   optically centered (the SVG's low vertex made it sit low). */
:root { --check-blue: var(--brand-blue); --check-blue-soft: color-mix(in oklab, var(--brand-blue), transparent 88%); --check-blue-line: color-mix(in oklab, var(--brand-blue), transparent 62%); }
/* (no transform needed — the Check icon is optically centered in its own
   viewBox now, so it stays centered at every zoom/DPI.) */
.mode-decide-foot .pencil { width: 34px; height: 34px; border-color: var(--line); background: var(--bg-row); }
.mode-decide-foot .pencil.confirm { border-color: var(--check-blue-line); background: var(--check-blue-soft); color: var(--check-blue); }
.mode-decide-foot .pencil.confirm:hover { background: var(--check-blue); color: #fff; border-color: var(--check-blue); }

/* Right-column "Exceptions available" panel — sits atop the side panel so the
   payroll chart drops down to line up with the roster (the alignment fix). */
.exceptions-card { background: var(--bg-surface); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; margin-bottom: 14px; }
.exc-head { font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 8px; }
.exc-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 4px 0; font-size: 12.5px; }
.exc-name { color: var(--text-dim); }
.exc-amt { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text); }
.exc-empty { font-size: 12px; color: var(--text-faint); }

/* #3 toggle 2: Sign FA / Trades moved into the right panel (above the chart). */
/* Sign FA / Trades sit just above the Exceptions card (small gap). Buttons
   match the "Over-the-cap team" chip height (28px) so the controls feel uniform. */
.side-actions { display: flex; gap: 8px; margin-bottom: 10px; }
.side-actions .btn { flex: 1; height: 28px; font-size: 12px; padding: 0 11px; }
.side-actions .btn svg { width: 13px; height: 13px; }
/* #3: team strategy info card (right panel) — matches the Exceptions card look,
   sits above it, lines up box-to-box with the on-page Cap-strategy box. */
.strat-info-card { background: var(--bg-surface); border: 1px solid var(--brand-line); border-radius: 12px; padding: 12px 14px; margin-bottom: 14px; }
.strat-info-p { margin: 0; font-size: 12px; line-height: 1.45; color: var(--text-dim); }
.strat-info-sub { margin: 8px 0 0; font-size: 10px; color: var(--text-faint); font-style: italic; }

/* On-page per-team strategy chip + its dropdown. */
.committed-head-left { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; min-width: 0; }
/* Collapsed cap-strategy row (once a strategy is set): a small label + the chip,
   sitting at the top where the full editor was. Clicking the chip re-opens it. */
.strat-collapsed { display: flex; align-items: center; gap: 10px; margin: 0 2px 8px; }
.strat-collapsed-label { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; color: var(--text); }
.mode-chip-wrap { position: relative; }
/* A soft branded accent so it reads as the team's strategy control (stands out
   a bit, not loud). */
.mode-chip { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 11px; border: 1px solid var(--brand-line); border-radius: 8px; background: var(--brand-soft); color: var(--brand); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.mode-chip:hover, .mode-chip.open { border-color: var(--brand); }
.mode-chip-caret { font-size: 10px; opacity: 0.7; margin-left: 1px; }
.mode-chip-backdrop { position: fixed; inset: 0; z-index: 40; }
/* Opens leftward — right edge stays pinned to the chip's right edge. Wider now
   that it carries the full strategy-options look (#4b/c). */
.mode-chip-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 50; width: 380px; max-width: 86vw; background: var(--bg-surface); border: 1px solid var(--line-strong); box-shadow: var(--shadow-lg); }
/* The dropdown reuses .mode-decide-box internals (head + .strategy-rows + foot);
   no bespoke button styling needed — it inherits the canonical look. */

/* "Decide these first" category subheadings (D-1): split the section into
   Player options / Team options / Non-guaranteed, each a small subhead above
   its rows. */
.decide-cat { margin-top: 2px; }
.decide-cat + .decide-cat { margin-top: 10px; }
/* #3 — bump the subheading contrast (was --text-faint, too dim): use --text-dim. */
.decide-cat-head { display: flex; align-items: baseline; gap: 7px; padding: 0 2px 3px; font-size: 10px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-dim); }
.decide-cat-head .count { font-size: 10px; font-weight: 600; color: var(--text-faint); }
/* D-2 strategy decision box (option iii look): one self-contained card with a
   title, the two stacked strategy options (cap-space first), and a ✓ footer.
   No profile-pic slot. */
.mode-decide-box { background: var(--bg-surface); border: 1px solid var(--brand-line); border-radius: 12px; padding: 12px 14px; margin: 2px 0 14px; }
.mode-decide-head { display: flex; align-items: baseline; gap: 8px; font-size: 13.5px; font-weight: 700; color: var(--text); margin-bottom: 10px; }
.mode-decide-box .strategy-rows { margin-top: 0; }
.mode-decide-foot { display: flex; align-items: center; margin-top: 10px; }
.link-btn { background: none; border: none; color: var(--text); font-size: 11.5px; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; padding: 2px 0; }
.link-btn .dim { color: var(--text-faint); }

@media (min-width: 721px) {

  /* ---- desktop salary strip: reuse the mobile meter band full-width ---- */
  .desktop-salary {
    position: sticky;
    top: 0;                      /* pin below the appbar */
    z-index: 30;
    background: var(--bg-app);
  }
  .desktop-salary .salary-bar-band.mobile-bar-band {
    max-width: var(--page-max, 1100px);
    margin: 0 auto;
    border-bottom: 1px solid var(--line);
  }
  /* the strip's inner 3-slot text can breathe more on desktop — but cap its
     width + centre it so the committed total isn't stranded at the far-left
     edge with huge gaps to the apron lines (#1). */
  .desktop-salary .mb-inner { padding: 13px 16px 14px; }   /* left-align salary content with the logo (M.2) */
  .desktop-salary .mb-slot-committed .mb-slot-amount { font-size: 24px; }

  /* ---- salary bar atop the roster COLUMN (both modes) ----
     Lives INSIDE .page-main, so it spans exactly the roster column width (B):
     the "white box" mock the owner wanted. The right panel (col 2) top-aligns
     with it via the grid's shared start line. */
  /* #5a — salary bar + step bar read as ONE card: the salary bar rounds only
     its TOP corners, the step bar only its BOTTOM, no gap between, single outer
     border. (When there are no step tabs — over-cap — the salary bar rounds all
     four corners via the :last-child rule below.) */
  .page-salary { margin: 0; }
  .page-salary .salary-bar-band.mobile-bar-band {
    max-width: none; margin: 0;
    border: 1px solid var(--line); border-bottom: none;
    border-radius: 12px 12px 0 0;
  }
  .page-salary .mb-inner { padding: 13px 16px 14px; }
  .page-salary .mb-slot-committed .mb-slot-amount { font-size: 24px; }
  /* Over-cap (no step bar): salary bar is the whole card → round all corners +
     restore its bottom border + the spacing to the roster below. */
  .page-main > .page-salary:not(:has(+ .page-steptabs)) .salary-bar-band.mobile-bar-band {
    border-bottom: 1px solid var(--line); border-radius: 12px;
  }
  .page-main > .page-salary:not(:has(+ .page-steptabs)) { margin-bottom: 14px; }

  /* Cap-mode step bar (#5a/#5b): the lower half of the merged card — shares the
     outer border, rounds only its bottom, sits flush under the salary bar with a
     thin divider. Much shorter than before (≤⅔ the salary bar): trimmed tab
     padding + smaller num/label. */
  .page-steptabs { margin: 0 0 14px; }
  .page-steptabs .step-tabs {
    position: static; top: auto;
    border: 1px solid var(--line); border-top: 1px solid var(--line);
    border-radius: 0 0 12px 12px; overflow: hidden;
    background: var(--bg-elevated);
  }
  /* Equal columns on desktop too (was left-packed): each tab takes an equal
     share of the bar's width, matching the mobile distribution. */
  .page-steptabs .step-tabs-inner { max-width: none; padding: 0 4px; }
  .page-steptabs .step-tab { flex: 1 1 0; }
  /* "mid" (default) — splits the difference between the old "mini" and "Numbers":
     a single inline number+label line (never stacks → never grows when narrow),
     centered, sized between the two. */
  .page-steptabs .step-tab,
  html[data-stepbar="mid"] .page-steptabs .step-tab { flex-direction: row; align-items: center; justify-content: center; padding: 5px 12px; gap: 7px; }
  html[data-stepbar="mid"] .page-steptabs .step-tab .step-num { width: 18px; height: 18px; font-size: 10px; }
  html[data-stepbar="mid"] .page-steptabs .step-tab .step-label { font-size: 12px; text-align: left; }
  /* "left" — single left-aligned line, number then label, no stacking even when
     narrow. Overrides the stacked media rule below via higher specificity. */
  html[data-stepbar="left"] .page-steptabs .step-tab { flex-direction: row; align-items: center; justify-content: flex-start; padding: 5px 12px; gap: 7px; }
  html[data-stepbar="left"] .page-steptabs .step-tab .step-num { width: 18px; height: 18px; font-size: 10px; }
  html[data-stepbar="left"] .page-steptabs .step-tab .step-label { font-size: 11.5px; text-align: left; }

  /* ---- two-column page: roster left, chart right ---- */
  main.page.has-sidepanel {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 0 26px;                /* column gap only; vertical rhythm via margins */
    max-width: var(--page-max, 1100px);
    margin: 0 auto;
    padding: 18px 16px 80px;   /* match the appbar's 16px L/R; top gives the shared start line (M.1) */
    align-items: start;
  }
  /* A page-level alert spans both columns; the salary bar/step tabs now live
     inside .page-main (col 1), so the right panel still top-aligns with the
     column's first element. */
  main.page.has-sidepanel > .page-alerts { grid-column: 1 / -1; margin: 0 0 14px; }
  main.page.has-sidepanel > .page-main   { grid-column: 1; }
  main.page.has-sidepanel > .page-side   { grid-column: 2; }
  /* Desktop: Sign FA / Trades live in the right panel — hide the duplicate set
     in any content-column header (Roster, Cap Hits). Mobile keeps them inline
     (no right panel there). */
  main.page.has-sidepanel .committed-head .actions-right { display: none; }
  /* The aside lines its blocks up with left landmarks via JS (usePageSideAlign);
     no top margin on the aside itself. */
  main.page.has-sidepanel > .page-side { margin-top: 0; }
  /* #3 toggle 1 (Bars width = Full): the salary bar + step tabs span BOTH
     columns as their own top row; the merged-card rounding still applies. */
  main.page.has-sidepanel > .page-bars-full { grid-column: 1 / -1; margin: 0 0 14px; }
  .page-bars-full .page-salary { margin: 0; }
  .page-bars-full .page-steptabs { margin: 0; }
  /* Zero the first element's top margin so col 1 and the right panel start clean. */
  main.page.has-sidepanel > .page-main > :first-child { margin-top: 0; }
  .page-main { min-width: 0; }   /* let the roster table shrink, never overflow */

  /* Right panel scrolls with the content (not sticky) — stays anchored to its
     spot like the left-hand panels, per the owner's ask. */
  .page-side {
    align-self: start;
  }
  /* the bottom thermometer (built for mobile end-of-page) becomes a compact
     side-panel card with a small centred header */
  .page-side .mobile-thermo-card {
    /* M.1: no top margin — the grid's padding-top sets the shared start line,
       so the chart top aligns with the roster's first heading on every step. */
    margin: 0;
    width: 100%;
  }
  /* B: on committed steps (Build/Final) the first heading is the "Roster N" +
     Sign FA/Trades controls bar (.committed-head, ~42px tall); the actual roster
     TABLE starts below it. Drop the chart by that bar's height so it sits level
     with the table itself, not the controls. :has() scopes this to committed
     steps only — the Options step (section-intro first) keeps margin 0 (M.1). */
  /* The right panel's first card (Exceptions) now top-aligns with the roster via
     the grid rows above — no manual offset needed. The chart sits below the
     Exceptions card (which carries its own 14px bottom margin). */
  .page-side .mobile-thermo-card { margin-top: 0; }
  .page-side .mt-head { text-align: center; }
  .page-side .mt-title { display: block; }
  .page-side .mt-bigNum { font-size: 19px; }   /* small + centred above the graph */
  /* #4.2: taller graph so the chart doesn't read stumpy next to the long roster */
  .page-side .mt-graph { height: 480px; max-width: none; }
}

/* keep the side panel out of the way on smaller desktops if needed */
@media (min-width: 721px) and (max-width: 980px) {
  main.page.has-sidepanel { grid-template-columns: minmax(0,1fr) 280px; gap: 18px; }
}

/* Owner ask: keep a SINGLE column until ~960px so the two columns aren't squished.
   Only the column COUNT changes here — every other desktop style (from the 721px
   block) still applies, so 721–959px stays a clean stacked desktop layout (the side
   panel drops below the roster instead of cramming a narrow column beside it). */
@media (min-width: 721px) and (max-width: 959px) {
  main.page.has-sidepanel { grid-template-columns: minmax(0, 1fr); }
  main.page.has-sidepanel > .page-main,
  main.page.has-sidepanel > .page-side { grid-column: 1; }
}

/* #2 — In the two-column zone the roster column gets narrow and the 4 horizontal
   step tabs wrap mid-word ("Opt ions"). Switch to the compact STACKED format
   (number over a centred, non-wrapping label) early — well before the
   single-column breakpoint — so the labels never break. */
@media (min-width: 960px) and (max-width: 1080px) {
  /* In the narrow two-column zone, tighten the single-line step tabs so all four
     fit without wrapping (both styles stay single-line — never stack). */
  .page-steptabs .step-tab { padding: 4px 6px !important; gap: 5px !important; }
  .page-steptabs .step-tab .step-label { font-size: 10.5px !important; }
}


/* === Inner content === */
.mb-inner {
  position: relative;
  padding: 11px 12px 12px;
  z-index: 3;
}

/* === APRON view: three slots, sorted by value === */
.mb-text-apron {
  display: grid;
  grid-template-columns: 1fr 1.25fr 1fr;
  gap: 6px;
  /* #13b — align the NUMBER baselines (bottom of digits / "M"), not the box bottom
     (which is the $ descender). baseline lets the bigger committed figure's $ overhang. */
  align-items: baseline;
}
/* #4c — "All" lines = committed + tax + 1st + 2nd apron = 4 slots. */
html[data-headerlines="all"] .mb-text-apron { grid-template-columns: 1fr 1fr 1fr 1fr; }
html[data-headerlines="all"] .mobile-compact-strip { grid-template-columns: 1fr 1fr 1fr 1fr; }
.mb-slot {
  min-width: 0;
  display: flex; flex-direction: column;
  font-variant-numeric: tabular-nums;
}
/* Slot position by index — first child left-aligned, last right-aligned,
   middle center. Works for any of the 6 possible orderings of {committed,
   apron1, apron2} since CSS doesn't need to know which slot is which. */
.mb-text-apron .mb-slot { align-items: center; text-align: center; }   /* #13a — every column centred */

/* Amount-first format (2ways-style): big number on top, small label below */
.mb-slot-amount {
  font-size: 14.5px;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.01em;
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
}
.mb-slot-amount .caret {
  font-size: 9px;
  line-height: 1;
  position: relative; top: -1px;
}
.mb-slot-line.pos    .mb-slot-amount { color: var(--pos-text); }  /* [#2][D] under any line → brighter green */
.mb-slot-line.danger .mb-slot-amount { color: var(--danger); }   /* [#2] over any line → red */

.mb-slot-committed .mb-slot-amount {
  font-size: 21px;
  letter-spacing: -0.02em;
}
.mb-slot-label {
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-faint);
  margin-top: 2px;
  white-space: nowrap;
}

/* === CAP view: same height, "Cap Commitment" center, side text === */
.mb-text-cap {
  display: grid;
  grid-template-columns: 1fr 1.25fr 1fr;
  gap: 6px;
  align-items: end;
}
.mb-cap-side {
  min-width: 0;
  display: flex; flex-direction: column;
  font-variant-numeric: tabular-nums;
}
.mb-cap-side-left  { align-items: center; text-align: center; }   /* #13a — centred */
.mb-cap-side-right { align-items: center; text-align: center; }   /* #13a — centred */
.mb-cap-side-amount {
  font-size: 14.5px;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.01em;
}
.mb-cap-side-left .mb-cap-side-amount  { color: var(--pos-text); }  /* [D] brighter green */
.mb-cap-side-right .mb-cap-side-amount { color: var(--danger); }
.mb-cap-side-label {
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-faint);
  margin-top: 2px;
  white-space: nowrap;
}
.mb-cap-center {
  text-align: center;
  display: flex; flex-direction: column;
  align-items: center;
  font-variant-numeric: tabular-nums;
}
.mb-cap-amount {
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.mb-cap-label {
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-faint);
  margin-top: 2px;
  white-space: nowrap;
}


/* ============================================================
   STICKY COMPACT STRIP — one-line, same idiom, $XXXM format
   ============================================================ */
.mobile-sticky-strip {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: color-mix(in oklab, var(--bg-surface), transparent 6%);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 4px 10px rgba(0,0,0,0.12);
  transform: translateY(-100%);
  transition: transform 0.22s ease;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
}
.mobile-sticky-strip.on {
  transform: translateY(0);
  pointer-events: auto;
}
.ms-divider {
  width: 1px; align-self: stretch;
  background: var(--line);
  margin: 0 2px;
}
.ms-part {
  display: inline-flex; align-items: baseline;
  gap: 4px;
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
}
.ms-part b { font-weight: 800; }
.ms-part .caret {
  font-size: 9px;
  position: relative; top: -1px;
  margin-right: 1px;
}
.ms-part.committed b { font-size: 14px; letter-spacing: -0.01em; }
.ms-part.pos    { color: var(--pos); }
.ms-part.warn   { color: var(--warn); }
.ms-part.danger { color: var(--danger); }
.ms-faint { color: var(--text-faint); font-weight: 500; }

/* Hide the secondary delta on extra-narrow phones */
@media (max-width: 360px) {
  .mobile-sticky-strip .ms-part:nth-of-type(3) { display: none; }
  .mobile-sticky-strip .ms-divider:nth-of-type(2) { display: none; }
}


/* ============================================================
   BOTTOM THERMOMETER — 2ways-style with broken axis.
   Column is composed of independent regions (floor / main / over-2A)
   separated by physical gaps where the card background shows through.
   ============================================================ */
.mobile-thermo-card {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px 14px 18px;
  margin: 18px 12px 10px;
  scroll-margin-top: 12px;
}
.mt-head {
  display: flex; flex-direction: column;
  align-items: center; text-align: center;
  margin-bottom: 26px;
}
.mt-title {
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-faint);
  margin: 0;
}
.mt-bigNum {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -0.025em;
  color: var(--text);
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}

/* Cap mode: small "Including holds / Payroll only" toggle */
.cap-view-tabs {
  display: inline-flex;
  margin: 0 auto 14px;
  padding: 2px;
  background: var(--bg-row);
  border: 1px solid var(--line);
  border-radius: 6px;
  align-self: center;
  justify-self: center;
}
.mobile-thermo-card.cap { display: flex; flex-direction: column; }
.cap-view-tabs button {
  height: 26px;
  padding: 0 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  background: transparent;
  border: none; color: var(--text-faint);
  border-radius: 4px;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.cap-view-tabs button.on { background: var(--bg-elevated); color: var(--text); }

.mt-body { display: flex; justify-content: center; }
.mt-graph {
  position: relative;
  width: 100%; max-width: 360px;
  height: 380px;
  display: grid;
  grid-template-columns: 1fr 64px 1fr;
  gap: 14px;
  align-items: stretch;
}
.mt-graph.cap-graph { height: 280px; }

/* Center column container — holds region pills + threshold lines + here marker.
   No overflow:hidden so threshold lines can extend into the side rails. */
.mt-col {
  position: relative;
  grid-column: 2;
  background: transparent;
}
/* Legacy alias — the original full-height track is replaced by per-region pills. */
.mt-col-track { display: none; }

/* Per-region pill container: rounded corners, overflow:hidden so the
   color segments inside get clipped to the pill shape. The card
   background shows through the gaps BETWEEN region pills — that's
   the "axis break". Track color is slightly lighter than the card's
   bg-row so unfilled regions read as a distinct surface. */
.mt-region {
  position: absolute;
  left: 0; right: 0;
  background: color-mix(in oklab, var(--bg-row), var(--text) 8%);
  border: 1px solid color-mix(in oklab, var(--line), var(--text) 12%);
  border-radius: 10px;
  overflow: hidden;
  z-index: 0;
  transition: bottom 0.4s ease, height 0.4s ease;
}
/* an empty region (e.g. the over-2A pill when payroll is well below it) shows
   no box — keeps the reserved layout space but drops the stray empty pill */
.mt-region.is-empty { background: transparent; }   /* [#5b] keep the segment OUTLINE when empty */

/* Color fill segments — positioned RELATIVE to the parent .mt-region.
   Take the full width of the region pill; the region's overflow:hidden
   gives them the rounded top/bottom corners. */
.mt-col-seg {
  position: absolute;
  left: 0; right: 0;
  transition: bottom 0.4s ease, height 0.4s ease;
}

/* Threshold dashed lines — z-index ABOVE segments so they stay visible
   when the fill rises past them. Drawn as white-ish dashes with a
   subtle dark shadow so they contrast on both light and dark fills. */
.mt-th {
  position: absolute;
  left: -10px; right: -10px;
  z-index: 3;
  pointer-events: none;
  transition: bottom 0.4s ease;
}
.mt-th-rule {
  border-top: 1.5px dashed rgba(255, 255, 255, 0.75);
  width: 100%;
  filter: drop-shadow(0 0.5px 0 rgba(0,0,0,0.55));
}
/* Per-threshold accent: a faint tint to distinguish them from each
   other when needed. Kept subtle so the white still dominates. */
.mt-th-cap    .mt-th-rule { border-top-color: rgba(255, 255, 255, 0.80); }
.mt-th-tax    .mt-th-rule { border-top-color: rgba(255, 255, 255, 0.65); }
.mt-th-apron1 .mt-th-rule { border-top-color: rgba(255, 255, 255, 0.80); }
.mt-th-apron2 .mt-th-rule { border-top-color: rgba(255, 255, 255, 0.85); }

/* "Here" / committed marker */
.mt-here {
  position: absolute;
  left: -4px; right: -4px;
  z-index: 4;
  pointer-events: none;
  transition: bottom 0.4s ease;
}
.mt-here-cap {
  position: absolute;
  left: 0; right: 0;
  top: -2.5px;
  height: 5px;
  background: var(--text);
  border-radius: 3px;
  box-shadow: 0 0 0 2px var(--bg-surface), 0 2px 6px rgba(0,0,0,0.3);
}

/* === Side rails === */
.mt-rail {
  position: relative;
  font-variant-numeric: tabular-nums;
}
.mt-rail-left  { grid-column: 1; }
.mt-rail-right { grid-column: 3; }

/* Rail item — vertically centered on the threshold's y via translateY(50%).
   Both rails now share the same two-line structure (number on top,
   descriptor below), so the numbers on left and right land at the same
   y above the dashed line and the names at the same y below it. */
.mt-rail-item {
  position: absolute;
  transform: translateY(50%);
  line-height: 1.15;
}
.mt-rail-left  .mt-rail-item { right: 4px; text-align: right; }
.mt-rail-right .mt-rail-item { left:  4px; text-align: left;  }

.mt-rail-num {
  font-size: 13px;
  font-weight: 800;
  white-space: nowrap;
}
.mt-rail-num b { font-weight: 800; }
.mt-rail-name {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--text-faint);
  white-space: nowrap;
  margin-top: 1px;
}
.mt-rail-item.over    .mt-rail-num { color: var(--danger); }
.mt-rail-item.below   .mt-rail-num { color: var(--pos-text); }  /* [D] brighter green */
.mt-rail-item.neutral .mt-rail-num { color: var(--text-faint); }
/* [#4] Right rail = reference VALUES (cap / tax / apron lines) → muted grey, same as
   the Min Floor; the LEFT rail keeps the live red/green delta. */
.mt-rail-right .mt-rail-num { color: var(--text-dim); font-weight: 700; opacity: 0.9; }

/* Min Floor row — slightly demoted in weight, no left counterpart */
.mt-rail-item.mt-rail-floor .mt-rail-num {
  color: var(--text-dim);
  font-weight: 700;
  opacity: 0.9;
}
.mt-rail-item.mt-rail-floor .mt-rail-name {
  opacity: 0.85;
}

/* Legacy aliases kept for any straggler markup — both rails now use
   .mt-rail-num as the primary value class. */
.mt-rail-val,
.mt-rail-delta { /* deprecated — see .mt-rail-num */ }

/* ============================================================
   R4 finance display — luxury-tax bill stat + salary-floor badge
   (mobile thermometer head + desktop salary-bar header).
   ============================================================ */
.mt-stat { display: inline-flex; align-items: baseline; gap: 5px; margin-top: 5px; }
.mt-stat-num { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; color: var(--warn); font-variant-numeric: tabular-nums; }
.mt-stat-label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-faint); }
.sb-stat { display: inline-flex; gap: 6px; align-items: baseline; font-size: 13px; font-variant-numeric: tabular-nums; }
.sb-stat b { font-weight: 700; color: var(--warn); }
.sb-stat span { color: var(--text-faint); }
.mt-floor-badge, .sb-floor-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px;
  background: rgba(229, 62, 62, 0.14);
  border: 1px solid rgba(229, 62, 62, 0.40);
  color: var(--danger, #e53e3e);
  font-size: 11px; font-weight: 700; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.mt-floor-badge { margin-top: 7px; }
.sb-floor-badge { margin-left: 8px; align-self: center; }

/* ============================================================
   MOBILE TOP STACK (batch 44) — header + salary bar + step tabs pin
   together as ONE sticky unit (salary directly above the tabs). This
   replaces the old free-floating `position:fixed` compact strip that
   landed above the header. On scroll the salary bar collapses to a
   one-liner and the step tabs shrink to titles-only.
   ============================================================ */
.mobile-topstack { position: sticky; top: 0; z-index: 50; }
/* Only the wrapper pins. The header keeps the HIGHEST z within the stack so
   the open team menu (position:fixed, but trapped in the appbar's
   backdrop-filter stacking context) paints OVER the salary bar + tabs below
   it — otherwise those later siblings cover it. */
.mobile-topstack > .appbar { position: relative; z-index: 5; top: auto; }
.mobile-topstack > .step-tabs { position: relative; z-index: 1; top: auto; }

/* i1 fix — give the salary band its own surface so it doesn't blend
   into the bg-surface header above and step tabs below. */
.salary-bar-band.mobile-bar-band {
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--line);
}

/* compact one-line salary strip (scrolled state). Q2: same left/center/right
   distribution as the full top strip (committed centered, deltas flanking) via
   a 3-column grid. Q3: a touch larger than the first pass so it isn't cramped. */
.mobile-compact-strip {
  display: grid;
  grid-template-columns: 1fr 1.25fr 1fr;
  align-items: center;
  gap: 6px;
  padding: 0 14px;
  height: 48px;   /* FIXED so cap & apron sticky strips are always identical height */
  min-height: 0;
  box-sizing: border-box;
  overflow: hidden;
  font-variant-numeric: tabular-nums;
}
/* Round 9: compact strip is always the 2-line "big-bar smaller" format — amount
   over a tiny uppercase label, each cell centered in its third (no edge-hugging). */
.mcs-cell {
  min-width: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 0; text-align: center; white-space: nowrap;
  justify-self: center;
}
.mcs-cell .num { font-size: 14px; font-weight: 800; line-height: 1.1; }
.mcs-cell.committed .num { font-size: 16.5px; letter-spacing: -0.01em; }
.mcs-cell.pos    .num { color: var(--pos-text); }  /* [D] brighter green */
.mcs-cell.warn   .num { color: var(--warn); }
.mcs-cell.danger .num { color: var(--danger); }
.mcs-lbl {
  font-size: 8.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--text-faint); margin-top: 1px;
}
/* [#2] compact-strip labels neutralised — the coloured number already carries the zone. */
@media (max-width: 360px) {
  .mobile-compact-strip { gap: 4px; padding: 0 10px; }
  .mcs-cell.committed .num { font-size: 15px; }
  .mcs-cell .num { font-size: 12.5px; }
}

/* #4 — mobile salary-bar sizing (full top strip + compact sticky strip).
   4a: shrink the labels RELATIVE to the numbers (numbers unchanged) — full strip.
   4b: shrink the apron/threshold numbers (both strips), mindful of 4a so the
       labels under them shrink further still. The committed total is untouched. */
@media (max-width: 720px) {
  /* --- Full top strip --- */
  /* All sub-labels the SAME (smaller) size; the committed total number stays
     big, the three threshold numbers share one (smaller) size. (#2) */
  .mobile-topstack .salary-bar-band .mb-slot-label { font-size: 8px; letter-spacing: 0.05em; }
  .mobile-topstack .salary-bar-band .mb-slot-line .mb-slot-amount { font-size: 12px; }
  /* every column centered in its own track (the last "2nd apron" no longer
     right-hugs). */
  .mobile-topstack .mb-text-apron .mb-slot { align-items: center !important; text-align: center !important; }
  /* #1 — align the DIGIT bottoms (not just the glyph boxes). line-height:1 drops
     the per-size half-leading below the digits, so with the grid's align-items:end
     every amount's baseline/digit-bottom lands on the same line regardless of font
     size (the big payroll number no longer floats a hair above the small ones). */
  .mobile-topstack .mb-text-apron .mb-slot-amount { line-height: 1; }

  /* --- Compact / sticky strip --- */
  /* #2 — numbers stay vertically CENTERED at their own sizes (payroll bigger,
     thresholds smaller) — do NOT bottom-pin them. The only goal is that all the
     sub-LABELS sit on one shared line: give every number the SAME line-box
     height so the label beneath each starts at the same Y (the payroll label was
     ~2px low; this splits the difference and levels them). */
  .mobile-compact-strip { align-items: center; }
  .mobile-compact-strip .mcs-cell { justify-content: center; }
  .mobile-compact-strip .mcs-cell .num { font-size: 12px; line-height: 20px; }
  .mobile-compact-strip .mcs-cell.committed .num { font-size: 16.5px; line-height: 20px; }
  .mobile-compact-strip .mcs-lbl { font-size: 8px; line-height: 1; margin-top: 0; }
}
/* Superscript ordinal in the "short" line-label test variant (1ˢᵗ / 2ⁿᵈ). */
.mb-slot-label .ord, .mcs-lbl .ord { font-size: 0.58em; vertical-align: 0.28em; line-height: 0; }

/* shrunk step tabs (scrolled state): small number to the LEFT of the title,
   the (number + label) cluster centred within each tab column — mirrors the
   full-size header. (Batch 44 hid the number; batch 47 brings it back small.) */
.step-tabs.compact .step-num { width: 17px; height: 17px; font-size: 10px; }
.step-tabs.compact .step-tab { padding-top: 11px; padding-bottom: 11px; }
@media (max-width: 600px) {
  .step-tabs.compact .step-tab {
    flex-direction: row; align-items: center; justify-content: center;
    gap: 5px; padding: 11px 4px;
  }
  .step-tabs.compact .step-label { font-size: 13px; white-space: nowrap; }
}

/* Next button while over the cap — stays tappable (fires the toast) but
   reads as not-ready. The persistent red banner is gone. */
.step-nav .btn-primary.is-blocked { opacity: 0.5; }

/* toast is tap-to-dismiss */
.toast { cursor: pointer; }


/* ============================================================
   TRADE MACHINE (full-bleed view) — appended from the design
   handoff tm-styles.css. The original :root tokens + a few global
   rules (html/body overflow, scrollbar, img.logo) were SCOPED to
   .tm-app here so they cannot leak into the rest of the site.
   Everything else is already .tm-* namespaced.
   ============================================================ */
.tm-fullscreen { position: fixed; inset: 0; z-index: 1000; }
/* =========================================================
   Trade Machine — design tokens & shell (v2)
   Compact, content-first. No fat rails, no fat tray.
   ========================================================= */
.tm-app {
  /* Theme tokens are INHERITED from the site's :root / html.dark / html.light
     (styles.css top) so the Trade Machine matches the main app and follows
     light/dark automatically. Only Trade-Machine-specific tokens live here. */
  --bg-strip:      var(--bg-app);   /* team strip / nav strips = deepest surface */

  /* Primary action color — vivid web-standard blue (stands out far better than
     the muted brand green for "do this" buttons: Apply / Add team). */
  --tm-action:      #2563eb;
  --tm-action-hi:   #1d4ed8;
  --tm-action-soft: rgba(37,99,235,0.16);
  --tm-action-line: rgba(37,99,235,0.55);
  --tm-action-text: #5b9be0;        /* readable blue text on the soft tint */

  /* Floating elements (verdict popover, player drawer) want more lift than the
     site's subtle shadows. */
  --shadow:        0 8px 24px rgba(0,0,0,0.4);
  --shadow-lg:     0 24px 64px rgba(0,0,0,0.55);

  /* layout dimensions (Trade-Machine shell/column geometry) */
  --topbar-h:      44px;
  --strip-h:       54px;
  --col-head-h:    44px;
  --col-tabs-h:    34px;
  --col-foot-h:    32px;
}

*, *::before, *::after { box-sizing: border-box; }
button { font-family: inherit; cursor: pointer; }
.num { font-variant-numeric: tabular-nums; }

.tm-app ::-webkit-scrollbar { width: 8px; height: 8px; }
.tm-app ::-webkit-scrollbar-thumb { background: var(--line); border-radius: 6px; }
.tm-app ::-webkit-scrollbar-thumb:hover { background: var(--line-strong); }

.tm-app img.logo, .tm-app .logo-img { filter: var(--logo-filter); display: block; }

/* =========================================================
   APP WRAPPER + MOBILE-PREVIEW FRAME
   ========================================================= */
.tm-app {
  height: 100vh;
  height: 100dvh;   /* #1: match the VISIBLE viewport (address bar) so inner panels can scroll */
  width: 100%;
  display: grid;
  grid-template-rows: 1fr;
  overflow: hidden;
  position: relative;
}
.tm-app.mobile {
  background:
    radial-gradient(800px 600px at 50% 50%, #0d1218, #06090c);
  display: grid;
  place-items: center;
  padding: 18px;
}
.tm-app.mobile .tm-shell {
  width: 390px; height: 844px;
  border-radius: 38px;
  border: 1px solid #2a3543;
  box-shadow:
    0 0 0 8px #0a0d12,
    0 0 0 9px #2a3543,
    0 30px 80px rgba(0,0,0,0.6);
  overflow: hidden;
  position: relative;
}
.tm-app.mobile .tm-shell::before {
  content: ""; position: absolute; top: 0; left: 50%;
  transform: translateX(-50%);
  width: 124px; height: 30px;
  background: #06090c;
  border-radius: 0 0 18px 18px;
  z-index: 100;
}
/* Hide scrollbars in tight strips (still scrollable on touch/wheel) */
.tm-col-gets::-webkit-scrollbar,
.tm-tabs::-webkit-scrollbar,
.tm-strip::-webkit-scrollbar { height: 0 !important; display: none; }
.tm-col-gets, .tm-tabs, .tm-strip { scrollbar-width: none; }

/* Mobile preview close button — fix positioning so it's not behind notch */
.tm-app.mobile {
  background:
    radial-gradient(800px 600px at 50% 50%, #0d1218, #06090c);
  display: grid;
  place-items: center;
  padding: 18px;
}
.tm-app .mobile-toggle {
  position: absolute; top: 14px; left: 14px;
  z-index: 200;
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 12px;
  background: var(--bg-elevated); border: 1px solid var(--line);
  color: var(--text); border-radius: 99px;
  font-size: 11.5px; font-weight: 700;
  cursor: pointer;
}
.tm-app .mobile-toggle:hover { border-color: var(--line-strong); }
.tm-app .mobile-toggle svg { width: 12px; height: 12px; }

/* =========================================================
   SHELL
   ========================================================= */
.tm-shell {
  height: 100%;
  min-height: 0;
  overflow: hidden;
  display: grid;
  grid-template-rows: var(--topbar-h) auto 1fr;
  /* The shell is a single-column grid; without an explicit column track it
     sizes to content max-content. On mobile the board (display:block,
     overflow-x:hidden) reports its content's full width (~440px) as min-content,
     so the lone column track grew past the 390px shell and the columns/rows ran
     off the right edge ("outgoing players overlap the border"). Clamp the track
     to the shell width so content fits and reflows instead of overflowing. */
  grid-template-columns: minmax(0, 1fr);
  background: var(--bg-app);
  container-type: inline-size;
  container-name: shell;
  position: relative;
}
/* #9 autohide REMOVED (scroll-mechanics handoff): the .chrome-down class is no
   longer applied, so the top verdict bar + team strip stay in normal flow. Each
   column already pins its header via .tm-col's auto/auto/1fr grid (only
   .tm-col-scroll scrolls), so no sticky/translate chrome is needed. */
.tm-top, .tm-strip { min-height: 0; }
.tm-strip { display: none; }
@container shell (max-width: 720px) {
  .tm-strip { display: flex; height: var(--strip-h); }
}
@media (max-width: 720px) {
  .tm-app:not(.mobile) .tm-strip { display: flex; height: var(--strip-h); }
}

/* =========================================================
   TOP BAR
   ========================================================= */
.tm-top {
  display: flex; align-items: center; gap: 10px;
  padding: 0 12px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-surface);   /* themed — was a hardcoded dark gradient (E) */
  position: relative; z-index: 30;
  min-height: 0;
}
.tm-top .divider { width: 1px; height: 22px; background: var(--line); }
.tm-back {
  display: inline-flex; align-items: center; gap: 5px;
  height: 28px; padding: 0 9px 0 6px;
  background: transparent; border: 1px solid var(--line);
  color: var(--text-dim); font-size: 12px; font-weight: 600;
  border-radius: 7px;
  transition: all .12s;
}
.tm-back:hover { color: var(--text); background: var(--bg-row-hover); border-color: var(--line-strong); }
.tm-back svg { width: 13px; height: 13px; }

.tm-crumb {
  display: inline-flex; align-items: baseline; gap: 7px;
  font-weight: 800; font-size: 15px; letter-spacing: -0.01em;
}
.tm-crumb .b1 { color: var(--text); }
.tm-crumb .b1 b { color: var(--brand); font-weight: 800; }
.tm-crumb .sep { color: var(--text-faint); font-weight: 400; font-size: 12px; }
.tm-crumb .b2 { color: var(--brand-blue); }
/* E: top bar now uses the base wordmark (logo + tool menu) + a "Trades" label
   where the main header's team selector sits. */
.tm-top .tm-wordmark { display: inline-flex; align-items: center; gap: 8px; --toolname-shift: 3px; }  /* O.1: the CapMVP artwork sits LOW in its 0-383 viewBox (caps y95, baseline y322), so box-centering floats the tool text above it. Push "Roster" down so its baseline lands on the logo's visible baseline — matches the main header's logo↔toolname relationship (Roster bottom = logo bottom +1). */
.tm-trades { font-size: 17px; font-weight: 700; color: var(--text-dim); letter-spacing: -0.01em; transform: translateY(3px); }  /* O.1: drop "Trades" onto the same baseline as "Roster"/logo (see .tm-wordmark above). */

.tm-top .spacer { flex: 1; }

/* Verdict pill in top-right */
/* [COLOUR] verdict pill (V3) — solid 3-state, constant width, no dot. */
.tm-top-verdict {
  display: inline-flex; align-items: center; gap: 7px;
  height: 28px; padding: 0 10px 0 11px; box-sizing: border-box;
  background: var(--neutral); border: 1px solid transparent; color: #fff;   /* filled GREY = Available */
  border-radius: 99px;
  cursor: pointer;
  transition: all .12s;
  /* matches the Teams pill — 28px, vertically centred; the label reserves the longest
     word's width so the pill never resizes between Available / Apply / Blocked. */
}
.tm-top-verdict:hover { filter: brightness(1.08); }
.tm-top-verdict.legal   { background: var(--pos);    border-color: transparent; }   /* GREEN = Apply (legal) */
.tm-top-verdict.illegal { background: var(--danger-btn, #6d1622); border-color: transparent; }  /* Blocked = oxblood */
.tm-top-verdict .lbl {
  font-size: 11px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
  color: #fff; min-width: 76px; text-align: center;   /* reserve longest-word width → constant pill size */
}
.tm-top-verdict .recap {
  display: inline-flex; align-items: center; gap: 3px;
  height: 22px; padding: 0 8px;
  background: var(--bg-elevated); border-radius: 99px;
  color: var(--text-dim); font-size: 11px; font-weight: 600;
}
.tm-top-verdict .recap b { color: var(--text); font-variant-numeric: tabular-nums; }
.tm-top-verdict .caret { width: 10px; height: 10px; color: rgba(255,255,255,0.85); margin-right: 0; }

/* Top-bar Add team — desktop only (hidden when strip shows) */
.tm-pillbtn.add-team-top {
  display: inline-flex;
  background: var(--tm-action);
  border: 1px solid var(--tm-action);
  color: #fff;
  font-weight: 700;
}
.tm-pillbtn.add-team-top:hover:not(:disabled) {
  background: var(--tm-action-hi); border-color: var(--tm-action-hi);
}
.tm-pillbtn.add-team-top svg { width: 14px; height: 14px; }
/* [A4] once teams are added it's an EDIT control ("Teams"), no longer the next step → neutral.
   ("Add team" with <2 teams stays blue = the actual next step.) */
.tm-pillbtn.add-team-top.is-edit {
  background: var(--bg-surface); border-color: var(--line-strong); color: var(--text);
}
.tm-pillbtn.add-team-top.is-edit:hover:not(:disabled) {
  background: var(--bg-row-hover); border-color: var(--line-strong);
}
@container shell (max-width: 720px) {
  .tm-pillbtn.add-team-top { display: none; }
}
@media (max-width: 720px) {
  .tm-app:not(.mobile) .tm-pillbtn.add-team-top { display: none; }
}
.tm-pillbtn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 10px;
  background: var(--bg-surface);
  border: 1px solid var(--line);
  color: var(--text);
  font-weight: 600; font-size: 12px;
  border-radius: 7px;
  transition: all .12s;
}
.tm-pillbtn:hover:not(:disabled) { background: var(--bg-row-hover); border-color: var(--line-strong); }
.tm-pillbtn:disabled { opacity: 0.45; cursor: not-allowed; }
.tm-pillbtn.primary {
  background: var(--tm-action); color: #fff; border-color: transparent;
  font-weight: 700;
}
.tm-pillbtn.primary:hover:not(:disabled) { background: var(--tm-action-hi); border-color: transparent; }
.tm-pillbtn.primary:disabled {
  background: var(--bg-elevated); color: var(--text-faint);
  border: 1px dashed var(--line-strong);
}
.tm-pillbtn.ghost { background: transparent; color: var(--text-dim); border-color: transparent; }
.tm-pillbtn.ghost:hover { background: var(--bg-row-hover); color: var(--text); }
.tm-pillbtn svg { width: 13px; height: 13px; }
.tm-iconbtn {
  display: inline-grid; place-items: center;
  width: 28px; height: 28px;
  background: transparent; border: 1px solid var(--line);
  border-radius: 7px;
  color: var(--text-dim);
}
.tm-iconbtn:hover { color: var(--text); border-color: var(--line-strong); background: var(--bg-row-hover); }
.tm-iconbtn.on { color: var(--brand); border-color: var(--brand-line); background: var(--brand-soft); }
.tm-iconbtn svg { width: 14px; height: 14px; }

/* Verdict popover */
.tm-verdict-pop {
  position: absolute;
  top: calc(var(--topbar-h) + 4px); right: 12px;
  width: 360px;
  background: var(--bg-elevated);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: var(--shadow-lg);
  z-index: 250;
  max-height: 70vh; overflow: auto;
  animation: fadeDown .14s ease;
}
@keyframes fadeDown {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.tm-verdict-pop .hd {
  padding: 12px 14px 8px;
  border-bottom: 1px solid var(--line);
}
.tm-verdict-pop .hd h2 {
  margin: 6px 0 4px; font-size: 16px; font-weight: 800; letter-spacing: -0.01em;
}
.tm-verdict-pop .hd .sub { font-size: 12.5px; color: var(--text-dim); line-height: 1.45; }
.tm-verdict-pop .body { padding: 8px 14px 12px; display: flex; flex-direction: column; gap: 12px; }
.tm-verdict-pop .side .hd2 {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; font-weight: 700;
}
.tm-verdict-pop .side .hd2 img { width: 20px; height: 20px; }
.tm-verdict-pop .side .vmark { margin-left: auto; }
.tm-verdict-pop .side .vmark.ok { color: var(--pos); }
.tm-verdict-pop .side .vmark.bad { color: var(--danger); }
.tm-verdict-pop .side .line {
  padding-left: 28px; font-size: 11.5px; line-height: 1.5; color: var(--text-dim);
  margin-top: 3px;
}
.tm-verdict-pop .side .line.bad  { color: var(--danger); }
.tm-verdict-pop .side .line.warn { color: var(--warn); }
.tm-verdict-pop .side .line .num { color: var(--text); font-weight: 700; }
.tm-verdict-pop .ft {
  padding: 10px 14px; border-top: 1px solid var(--line);
  display: flex; gap: 8px;
}
.tm-verdict-pop .ft .tm-pillbtn { flex: 1; justify-content: center; height: 32px; }

/* ============================================================
   TEAM STRIP — mobile-only (hidden on desktop via container query)
   Replaced on desktop by the column headers themselves.
   ============================================================ */
.tm-strip {
  align-items: center;
  padding: 0 0 0 10px;
  gap: 6px;
  /* #7 (muted): flat lifted surface + a single quiet hairline — no shadow/glow. */
  border-bottom: 1px solid var(--line);
  background: var(--bg-surface);
  overflow-x: auto;
  overflow-y: hidden;
  position: relative; z-index: 20;
  min-height: 0;
}
.tm-strip-scroll {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 6px;
  /* #5/#6: spread teams across the available width for bigger touch targets;
     when there are too many to fit, this naturally falls back to scrolling. */
  justify-content: space-evenly;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  padding-right: 6px;
}
.tm-strip-scroll::-webkit-scrollbar { display: none; }
.tm-strip-team {
  display: grid;
  grid-template-columns: 26px auto auto;
  align-items: center;
  column-gap: 7px;
  height: 44px;                 /* #6: bigger touch target on phone */
  padding: 0 12px 0 9px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text);
  border-radius: 9px;
  flex-shrink: 0;
  cursor: pointer;
  position: relative;
  transition: all .12s;
}
.tm-strip-team:hover { background: var(--bg-row-hover); }
/* #7 (muted): subtle active state — no glow, no underline. */
.tm-strip-team.active {
  background: var(--bg-elevated);
  border-color: var(--line-strong);
}
.tm-strip-team .logo { width: 26px; height: 26px; display: grid; place-items: center; }
.tm-strip-team .logo img { width: 100%; height: 100%; object-fit: contain; }
.tm-strip-team .nm {
  font-weight: 800; font-size: 12.5px; letter-spacing: -0.01em;
  line-height: 1.1;
}
.tm-strip-team .nm small {
  display: block; font-size: 10px; font-weight: 600;
  color: var(--text-dim); font-variant-numeric: tabular-nums;
  letter-spacing: 0;
}
.tm-strip-team .pip {
  width: 12px; height: 12px; border-radius: 50%;   /* B — bigger for colourblind legibility (was 7px) */
  background: var(--brand); margin-left: 2px;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.35);          /* crisp edge so the colour reads against any chip bg */
}
/* (strip team ✕ removed — remove a team from its column header instead) */
/* #6: picker-close affordance — the add button flips to a BLUE check while adding */
.tm-strip-add.done, .tm-pillbtn.add-team-top.done {
  background: var(--tm-action); border-color: var(--tm-action); color: #fff;
}
/* compact mode: just logo when many teams */
.tm-strip.compact .tm-strip-team:not(.active) {
  grid-template-columns: 26px;
  padding: 0 6px;
}
.tm-strip.compact .tm-strip-team:not(.active) .nm,
.tm-strip.compact .tm-strip-team:not(.active) .pip { display: none; }

.tm-strip-add {
  position: sticky; right: 6px;
  display: grid; place-items: center;
  width: 34px; height: 34px;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  flex-shrink: 0;
  color: var(--text-dim);
  margin-left: 6px;
  cursor: pointer;
  border-radius: 10px;   /* #6: clean rounded button, not a full-height square */
}
.tm-strip-add:hover:not(:disabled) { color: var(--brand); background: var(--brand-soft); }
.tm-strip-add:disabled { opacity: 0.4; cursor: not-allowed; }
.tm-strip-add svg { width: 16px; height: 16px; }

/* status pill (small) */
.cap-pip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; color: var(--text-dim);
  white-space: nowrap;
}
.cap-pip .dot { width: 6px; height: 6px; border-radius: 50%; }

/* =========================================================
   BOARD — columns side-by-side
   ========================================================= */
.tm-board {
  display: flex; flex-direction: row;
  overflow-x: auto;
  overflow-y: hidden;
  min-height: 0;
  scroll-snap-type: x proximity;
  position: relative;
}
/* B: WIDTH-based columns (not count-based). Each team card targets ~360px,
   shrinks to no less than ~304px — then the board scrolls horizontally rather
   than cramming — and grows up to ~440px when only a couple of teams are shown. */
.tm-board > .tm-col {
  flex: 1 1 450px;
  min-width: 400px;
  max-width: 500px;
  scroll-snap-align: start;
}
/* N.1: a lone team fills the whole board until there's room for a 2nd column. */
.tm-board.single > .tm-col { max-width: none; }
/* A: the add-team picker is an OVERLAY in front of the columns — NOT a board
   column — so the team count never affects it and it never affects the columns.
   Uses the same lifted surface (--bg-surface) as the main-app team menu. */
.tm-board > .tm-addcol {
  position: absolute; top: 0; right: 0; bottom: 0;
  z-index: 40;
  flex: none;
  width: min(440px, 94%);
  background: var(--bg-surface);
  box-shadow: -16px 0 30px -10px rgba(0,0,0,0.55);
  overflow: auto;
}
@media (min-width: 721px) {
  .tm-app:not(.mobile) .tm-board { gap: 14px; }
}

/* per-team column */
.tm-col {
  display: grid;
  /* #6: cap header + outgoing pinned; the tabs live INSIDE the scroll region so they
     scroll away with the list (one 1fr scroller). */
  grid-template-rows: auto auto 1fr;
  min-width: 0;
  border-right: 1px solid var(--line);
  background: var(--bg-app);
  min-height: 0;
  overflow: hidden;
  position: relative;
}
.tm-col:last-of-type { border-right: 0; }
.tm-col.pinned {
  background: linear-gradient(180deg, rgba(76,195,145,0.04), transparent 30%);
}
.tm-col-accent {
  height: 3px;
  background: var(--team-primary, var(--brand));
  position: absolute; top: 0; left: 0; right: 0;
  z-index: 2;
}
.tm-col-accent::after {
  content: ""; position: absolute; inset: 0; left: auto; width: 55%;
  background: linear-gradient(90deg, transparent, var(--team-secondary, transparent));
  opacity: 0.85;
}

.tm-col-head {
  display: grid;
  grid-template-columns: auto 1fr;   /* logo(+name) · cap-grid */
  align-items: center;
  gap: 9px;                  /* V3 (merge miss): tighter — give the 4-number salary bar more room */
  padding: 7px 9px;
  /* #6: lift the header onto the surface (kills the ugly black --bg-app behind the
     cap numbers) so it reads as one cohesive bar with the outgoing strip below. */
  background: var(--bg-surface);
  border-bottom: 1px solid var(--line);
  min-width: 0;
}
/* Round 8 (#2): lean & payroll header variants (gear: Team header). Less gap to the logo. */
.tm-col-head.hs-lean, .tm-col-head.hs-payroll { gap: 10px; }
/* Lean — apron line (left) + OUT/IN/NET + legal mark (right). */
.lean-head { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 10px; min-width: 0; }
.lean-apr { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.lean-apr-sal { font-size: 13px; font-weight: 800; color: var(--text); white-space: nowrap; }
.lean-apr-sal i { font-style: normal; color: var(--text-faint); font-size: 8.5px; letter-spacing: .05em; text-transform: uppercase; margin-right: 5px; }
.lean-apr-sp { display: flex; gap: 8px; font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums; }
.lean-apr-sp .pos { color: var(--pos); }
.lean-apr-sp .neg { color: var(--danger); }
.lean-apr-sp sup { font-size: 7px; font-weight: 800; }
.lean-totals { display: flex; align-items: center; gap: 8px; font-variant-numeric: tabular-nums; }
.lean-totals > span { display: inline-flex; align-items: baseline; gap: 3px; font-size: 11px; font-weight: 800; color: var(--text); }
.lean-totals i { font-style: normal; color: var(--text-faint); font-size: 8px; letter-spacing: .05em; text-transform: uppercase; }
.lean-totals .net.over  { color: var(--danger); }
.lean-totals .net.under { color: var(--pos); }
/* Payroll — compact team-coloured meter with the total sliding by the aprons + net. */
.ph { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ph-bar { position: relative; height: 8px; border-radius: 99px; overflow: hidden; background: var(--bg-elevated); }
.ph-zone { position: absolute; top: 0; bottom: 0; opacity: 0.22; }
.ph-zone.z-cap { left: 0; background: var(--brand-blue); }
.ph-zone.z-a1  { background: var(--warn); }
.ph-zone.z-a2  { background: var(--danger); }
.ph-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 99px;
           background: linear-gradient(90deg, var(--team-primary, var(--brand)), var(--team-secondary, var(--brand))); }
.ph-tick { position: absolute; top: -1px; bottom: -1px; width: 1px; background: rgba(255,255,255,0.55); }
.ph-labels { position: relative; height: 24px; min-width: 0; }
.ph-tot { position: absolute; top: 0; transform: translateX(-50%); font-size: 11px; font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ph-mark { position: absolute; bottom: 0; transform: translateX(-50%); font-size: 8px; font-weight: 700; color: var(--text-faint); }
.ph-mark.end { right: 0; left: auto; transform: none; }
.ph-net { display: flex; align-items: center; gap: 6px; font-size: 10px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--text-dim); }
.ph-net.over  { color: var(--danger); }
.ph-net.under { color: var(--pos); }
/* Round 9 (#3) — Mobile-bar header style: render the main-site mobile top strip
   inside the column header (uses MobileBarMeters + MobileBarText globals).
   Round 10 #0.5b: drop the inner bg/border so it blends with the column header
   (no more "bar within a bar" with two light tracks). */
.tm-col-head.hs-mobilebar .ident { min-width: 0; }
.tm-mb { position: relative; overflow: hidden; min-width: 0; background: transparent; }
.tm-mb .mb-inner { padding: 6px 2px; }
/* The meters' empty TRACK is what reads as a "second bar" — hide it inside the
   TM, leave only the filled portion so it looks like a single thin progress hair. */
.tm-mb .mb-meter-track { background: transparent; }
/* Round 11 — "header within a header" fix: promote the mobile-bar meters from the
   ident-column inner box up to the col-head's outer top/bottom edges. The meters
   themselves become the cap-head's visual boundaries (no more inset gradient
   beneath the strip border + a separate col-head border-bottom = two parallel bars). */
.tm-col-head.hs-mobilebar { position: relative; overflow: hidden; border-bottom: 0;
  padding-top: 13px; padding-bottom: 13px; }
.tm-col-head.hs-mobilebar .tm-mb { position: static; overflow: visible; }
/* The strip already has a 1px border-bottom; offsetting the top meter by 1px
   absorbs it so we see ONE bar at the outer edge instead of strip-border + gap +
   gradient. The col-head's own bottom border is removed above so the bottom meter
   sits flush against the OUTGOING strip header below. */
.tm-col-head.hs-mobilebar .mb-meter-top    { top: -1px; }
.tm-col-head.hs-mobilebar .mb-meter-bottom { bottom: 0; }
/* #2: cap / tax / apron salary + space — one row, 3 columns (Cap | Tax | Apron) with dividers.
   Cap/Tax right-align so the salary "M" sits over the space "M"; Apron is centered over 1ˢᵗ/2ⁿᵈ. */
.tm-cap-grid { min-width: 0; }
.tm-cap-grid.stacked { display: grid; grid-template-columns: 1fr 1fr auto; gap: 0; font-variant-numeric: tabular-nums; }
.tm-cap-grid.stacked .cc { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; padding: 0 9px; border-left: 1px solid var(--line); }
.tm-cap-grid.stacked .cc:first-child { padding-left: 0; border-left: 0; }
.tm-cap-grid.stacked .cc.apr { align-items: center; }
.tm-cap-grid.stacked .cc .top { font-size: 11px; font-weight: 800; color: var(--text); white-space: nowrap; }
.tm-cap-grid.stacked .cc .top i { font-style: normal; color: var(--text-faint); font-size: 8.5px; letter-spacing: 0.05em; text-transform: uppercase; margin-right: 4px; }
.tm-cap-grid.stacked .cc .bot { font-size: 10px; font-weight: 700; white-space: nowrap; }
.tm-cap-grid.stacked .cc .bot.pos { color: var(--pos); }
.tm-cap-grid.stacked .cc .bot.neg { color: var(--danger); }
.tm-cap-grid.stacked .cc .bot.apr { display: flex; gap: 8px; }
.tm-cap-grid.stacked .cc .bot.apr .pos { color: var(--pos); }
.tm-cap-grid.stacked .cc .bot.apr .neg { color: var(--danger); }
.tm-cap-grid.stacked .cc .bot sup { font-size: 7px; font-weight: 800; }
.tm-col-head .logo { width: 28px; height: 28px; display: grid; place-items: center; align-self: center; justify-self: center; }   /* V3 #4 — smaller logo so the salary bar gets more room */
.tm-col-head .logo img { width: 100%; height: 100%; object-fit: contain; }
/* V3 (C): single-column on mobile — the team is already highlighted in the strip above, so the
   column-header logo is redundant; drop it for more salary-bar width (and collapse the header
   grid so the bar doesn't fall into the empty logo column). Was missing from the merge. */
@media (max-width: 720px) {
  .tm-board.single .tm-col-head .logo { display: none; }
  .tm-board.single .tm-col-head { grid-template-columns: 1fr auto; }
}
.tm-app.mobile .tm-board.single .tm-col-head .logo { display: none; }
.tm-app.mobile .tm-board.single .tm-col-head { grid-template-columns: 1fr auto; }
.tm-col-head .ident { min-width: 0; }
.tm-col-head .name {
  font-weight: 800; font-size: 15px; letter-spacing: -0.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  line-height: 1.1;
  display: flex; align-items: center; gap: 7px;
}
.tm-col-head .name .team-nm { flex: 0 1 auto; }
/* #5: trade totals + status pip on the name line (small, never grows the bar) */
.tm-col-head .hdr-totals {
  margin-left: auto; flex-shrink: 0;
  display: flex; align-items: center; gap: 8px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0;
  color: var(--text); font-variant-numeric: tabular-nums;
}
.tm-col-head .hdr-totals i { font-style: normal; color: var(--text-faint); font-weight: 800; font-size: 8.5px; letter-spacing: 0.06em; margin-right: 3px; }
.tm-col-head .hdr-totals .net.over  { color: var(--danger); }
.tm-col-head .hdr-totals .net.under { color: var(--pos); }
/* compact (c): NET over IN, right-aligned; the OUTGOING total lines up beneath them */
.tm-col-head .hdr-totals.compact .stack {
  display: flex; flex-direction: column; align-items: flex-end;
  line-height: 1.25; gap: 0;
}
/* #1B: the 'full' header toggle reads as a right-aligned column, not a row */
.tm-col-head .hdr-totals.full {
  flex-direction: column; align-items: flex-end; gap: 0; line-height: 1.25;
}
/* #5b: legal/blocked mark instead of a dot */
.tm-col-head .hdr-mark { display: inline-grid; place-items: center; width: 16px; height: 16px; flex-shrink: 0; }
.tm-col-head .hdr-mark svg { width: 14px; height: 14px; }
.tm-col-head .hdr-mark.legal   { color: var(--pos); }
.tm-col-head .hdr-mark.illegal { color: var(--danger); }
.tm-col-head .hdr-mark.idle    { color: var(--text-faint); font-weight: 800; }
/* match the OUTGOING strip total to the header NET/IN size so they read as one column */
.tm-col-out-h .total { font-size: 10.5px; }
.tm-col-head .name .codetag {
  font-size: 10px; font-weight: 800; letter-spacing: 0.06em;
  padding: 1px 5px; border-radius: 4px;
  color: var(--text-dim); background: var(--bg-elevated);
  border: 1px solid var(--line);
}
.tm-col-head .meta {
  display: flex; align-items: center; gap: 6px;
  font-size: 10.5px; color: var(--text-dim); margin-top: 4px;
  flex-wrap: wrap;
  min-width: 0;
}
.tm-col-head .meta .tile {
  display: inline-flex; align-items: baseline; gap: 4px;
  padding: 2px 6px; border-radius: 5px;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  font-size: 10.5px;
  white-space: nowrap;
  flex-shrink: 0;
}
.tm-col-head .meta .tile .lab {
  font-size: 9px; letter-spacing: 0.08em; font-weight: 700;
  color: var(--text-faint); text-transform: uppercase;
  white-space: nowrap;
}
.tm-col-head .meta .tile .val {
  font-weight: 800; font-variant-numeric: tabular-nums;
  color: var(--text);
  white-space: nowrap;
}
.tm-col-head .meta .tile.pos .val  { color: var(--pos); }
.tm-col-head .meta .tile.neg .val  { color: var(--danger); }
.tm-col-head .meta .tile.warn .val { color: var(--warn); }
.tm-col-head .x {
  width: 24px; height: 24px;
  border: 1px solid var(--line); background: var(--bg-surface);
  border-radius: 6px; display: grid; place-items: center;
  color: var(--text-faint);
}
.tm-col-head .x:hover { color: var(--danger); border-color: var(--danger); }
.tm-col-head .x svg { width: 12px; height: 12px; }

/* Gets strip (compact horizontal incoming) — DEPRECATED, kept for fallback */
.tm-col-gets {
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(76,195,145,0.07), transparent);
  padding: 6px 12px;
  display: flex; align-items: center; gap: 6px;
  overflow-x: auto;
  min-height: 0;
}
.tm-col-gets .label {
  font-size: 9.5px; letter-spacing: 0.1em; font-weight: 800;
  color: var(--brand); text-transform: uppercase;
  flex-shrink: 0;
}
.tm-col-gets:empty { display: none; }

/* ============================================================
   OUTGOING STRIP — collapsible (Fanspo-inspired)
   ============================================================ */
.tm-col-out {
  border-bottom: 1px solid var(--line);
  background: none;          /* neutral by default — it's a passive "what's leaving" zone, not an alarm */
  min-height: 0;
  overflow: hidden;
  transition: background .15s;
}
/* always-visible empty state: compact + faint, no caret */
.tm-col-out.is-empty { background: none; }
.tm-col-out.is-empty .tm-col-out-h { cursor: default; padding-top: 6px; padding-bottom: 6px; }
.tm-col-out-h .hint { color: var(--text-faint); font-size: 10px; font-weight: 600; letter-spacing: 0; text-transform: none; }
/* needs-route: an asset has an unconfirmed auto-destination → amber nudge */
.tm-col-out.needs-route .lab { color: var(--warn); }
.tm-col-out-h .route-flag {
  font-size: 10px; padding: 1px 6px; border-radius: 99px; letter-spacing: 0;
  background: color-mix(in oklab, var(--warn), transparent 84%);
  color: var(--warn); font-weight: 800;
}
.tm-col-out-h {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 12px;
  font-size: 10.5px; font-weight: 800;
  color: var(--text-dim); letter-spacing: 0.06em;
  cursor: pointer;
  user-select: none;
  background: var(--bg-surface);            /* #4: the heading text sits on a header background */
  border-bottom: 1px solid var(--line);
}
.tm-col-out-h .lab {
  text-transform: uppercase;
  color: var(--text-dim);              /* grey, not red */
  font-size: 9.5px;
  letter-spacing: 0.1em;
}
.tm-col-out-h .total {
  color: var(--text); font-weight: 800;
  font-variant-numeric: tabular-nums;
  font-size: 12px; letter-spacing: 0;
}
.tm-col-out-h .count {
  font-size: 10px; padding: 1px 5px; border-radius: 99px;
  background: var(--bg-elevated); color: var(--text-dim);
  font-weight: 800; letter-spacing: 0;
}
.tm-col-out-h .caret {
  width: 12px; height: 12px; color: var(--text-faint);
  transition: transform .15s;
  margin-left: auto;
}
.tm-col-out.open .tm-col-out-h .caret { transform: rotate(180deg); }
.tm-col-out-body {
  display: flex; flex-wrap: wrap; gap: 5px;
  /* Equal top + bottom padding so the outgoing chips sit vertically CENTERED in
     the box — padding-top was 0, which pinned them to the top border. */
  padding: 8px 12px;
}
.tm-col-out.collapsed .tm-col-out-body { display: none; }
/* #1A: OUT · IN · NET inline on the OUTGOING header line (small) */
/* Round 10 #0.5c: single OUT total on the outgoing header — IN/NET moved to the
   column header (mobile-bar net label), so the strip just shows what's leaving. */
.tm-out-total {
  display: inline-flex; align-items: baseline; gap: 3px;
  font-size: 10.5px; font-weight: 800; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.tm-out-total i { font-style: normal; font-size: 8px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); font-weight: 800; }

.tm-out-chip {
  display: inline-flex; align-items: center; gap: 4px;
  height: 34px; padding: 0 4px 0 0;     /* no left pad → avatar flush; tight right */
  background: var(--bg-elevated);
  border: 1px solid color-mix(in oklab, var(--danger), transparent 62%);
  border-radius: 10px;
  overflow: hidden;                      /* the chip's rounded box clips the avatar */
  font-size: 12px; font-weight: 700;
  color: var(--text);
}
.tm-out-chip .photo {
  /* flush to the chip's left, fills the full chip height; the chip's rounded
     corners (overflow:hidden above) clip the avatar — corners blend, no gap. */
  width: 32px !important; height: auto !important; align-self: stretch;
  border-radius: 0;
  overflow: hidden; background: transparent;
  display: grid; place-items: center;
  font-size: 9px; font-weight: 800; color: var(--text-dim);
}
.tm-out-chip .photo img { width: 100%; height: 100%; object-fit: cover; }
.tm-out-chip .ico {
  width: 20px; height: 20px; border-radius: 5px;
  background: var(--bg-row); color: var(--text-dim);
  display: grid; place-items: center;
  font-size: 9.5px; font-weight: 800;
}
.tm-out-chip .amt {
  color: var(--text-dim); font-variant-numeric: tabular-nums; font-weight: 700;
  font-size: 11px;
}
.tm-out-chip .arr { color: var(--text-faint); font-size: 10.5px; }
.tm-out-chip .dest {
  display: inline-flex; align-items: center; gap: 3px;
  color: var(--text);
  font-size: 10px; font-weight: 800;
  letter-spacing: 0.02em;
}
.tm-out-chip .dest .ddot { width: 6px; height: 6px; border-radius: 50%; }
.tm-out-chip .rm {
  width: 16px; height: 18px;
  border: 0; background: transparent; color: var(--text-faint);
  border-radius: 4px;
  display: grid; place-items: center;
  margin-right: -2px; margin-left: -7px;   /* hug the (non-tappable) dollar */
}
.tm-out-chip .amt { margin-left: -2px; }     /* halve chevron→dollar gap */
.tm-out-chip .rm:hover { color: var(--danger); background: rgba(238,91,79,0.1); }
.tm-out-chip .rm svg { width: 11px; height: 11px; }

/* Tabs */
.tm-tabs {
  display: flex; align-items: center;
  border-bottom: 1px solid var(--line);
  padding: 0 6px;
  background: var(--bg-surface);
  overflow-x: auto;
  min-height: 0;
  flex: 0 0 auto;   /* #6: a flex item in .tm-col-scroll — keep height, scroll away with the list */
}
/* #6: the single column scroller — holds the tabs + the active panel, so the tabs
   scroll past like the first roster row (only the cap header + outgoing stay pinned). */
.tm-col-scroll {
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.tm-col-panels { display: flex; flex-direction: column; min-height: 0; }
.tm-tab {
  position: relative;
  flex: 1;                       /* #16: equal zones, never rearrange as counts appear */
  padding: 8px 10px;
  background: transparent; border: 0;
  color: var(--text-dim);
  font-size: 11.5px; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  white-space: nowrap;
}
.tm-tab svg { width: 13px; height: 13px; }
.tm-tab:hover { color: var(--text); }
.tm-tab.on { color: var(--text); }
.tm-tab.on::after {
  content: ""; position: absolute; left: 10px; right: 10px; bottom: -1px;
  height: 2px; background: var(--text-dim); border-radius: 2px 2px 0 0;   /* [#5] neutral underline, not blue */
}
.tm-tab .count {
  position: absolute; top: 4px; right: 8px;   /* #16: doesn't shift the centered label */
  font-size: 9.5px; padding: 1px 5px; border-radius: 99px;
  background: var(--bg-elevated); color: var(--text-faint);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.tm-tab.on .count { color: var(--text); background: var(--bg-elevated); }   /* [#5] neutral, not blue */

/* List — #6: no longer the scroller (the parent .tm-col-scroll scrolls); just lays out rows. */
.tm-list {
  overflow: visible;
  padding: 4px 6px 8px 4px;
  display: flex; flex-direction: column; gap: 1px;
  min-height: 0;
}

/* =========================================================
   PLAYER ROW — primary interactive element
   ========================================================= */
.tm-row {
  display: grid;
  /* [photo] [body] [salary/yrs] [origin-team logo] */
  grid-template-columns: 52px minmax(0, 1fr) auto auto;
  column-gap: 9px;
  padding: 0 6px 0 4px;          /* #8: no vertical padding — the photo fills the row height */
  min-height: 50px;              /* #8: ~ main-site Tight density (52px) */
  border-radius: 8px;
  border: 1px solid transparent;
  cursor: pointer;
  user-select: none;
  position: relative;
  align-items: center;
  flex-shrink: 0;   /* rows are flex items in .tm-list — never compress below content
                       (an explicit min-height would otherwise let flexbox shrink the
                       expanded editing row and clip the inline editor) */
}
/* #1: originating-team logo, full row height, far right, divider off the salary/yrs */
.tm-row .tm-row-org {
  align-self: stretch;
  display: flex; align-items: center; justify-content: center;
  padding-left: 3px; margin-left: 0;
  border-left: 1px solid var(--line);
}
.tm-row .tm-row-org .logo-img { width: 38px !important; height: 38px !important; display: block; }
.tm-row:hover {
  background: var(--bg-row-hover);
  border-color: var(--line);
}
.tm-row.selected {
  background: var(--danger-bg);
  border-color: color-mix(in oklab, var(--danger), transparent 62%);
}
/* Incoming player row variant (Fanspo-style: inline in roster) */
.tm-row.incoming {
  background: color-mix(in oklab, var(--bg-surface), var(--incoming) 12%);
  border-color: transparent;
}
/* hover goes BLUER (more --incoming), not brighter, so it never reads as a hover state */
.tm-row.incoming:hover {
  background: color-mix(in oklab, var(--bg-surface), var(--incoming) 19%);
  border-color: color-mix(in oklab, var(--incoming), transparent 55%);
}
.tm-row .arrow-in {
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--incoming);
  display: inline-grid; place-items: center;
  color: #fff; flex-shrink: 0;
}
.tm-row .arrow-in svg { width: 9px; height: 9px; }
.tm-row .from-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 5px 1px 4px;
  border-radius: 4px;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  font-size: 9.5px; font-weight: 800; letter-spacing: 0.04em;
  color: var(--text-dim);
}
.tm-row .from-badge .dot { width: 6px; height: 6px; border-radius: 50%; }

/* Subtle row shading for roster (banded bg) */
/* rows are lifted cards in the exact main-site roster colour (--bg-surface),
   sitting on the dark column (--bg-app) — the dark-bg/light-card contrast is
   what makes the main site read crisp (a flat mid background looked dull). */
.tm-list .tm-row:not(.selected):not(.incoming):not(:hover) {
  background: var(--bg-surface);
}
.tm-list .tm-row:hover:not(.selected):not(.incoming) {
  background: var(--bg-row-hover);
  border-color: var(--line);
}
.tm-list .tm-row {
  border-radius: 8px;
}
.tm-list { gap: 3px; }

.tm-row .photo {
  /* #2c: roster-style — square-ish photo that fills the FULL row height,
     top-anchored, cropping the sides if too wide (like the Build Roster page).
     Wider box brings the head/ears out toward the borders. !important beats
     PlayerAvatar's inline width/height so the photo can stretch + widen. */
  width: 52px !important; align-self: stretch; min-height: 50px; height: auto !important;
  border-radius: 5px;
  background: transparent;   /* show the row bg behind the player */
  overflow: hidden;
  display: grid; place-items: center;
  font-size: 10.5px; font-weight: 700; color: var(--text-dim);
}
.tm-row .photo img { width: 100%; height: 100%; object-fit: cover; }
.tm-row .body { min-width: 0; }
.tm-row .nameline {
  display: flex; align-items: center; gap: 6px;
  min-width: 0;
}
.tm-row .name {
  font-weight: 700; font-size: 13.5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0;
  letter-spacing: -0.005em;
}
.tm-row.selected .name { color: var(--text); }
.tm-row .check {
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--danger);
  display: inline-grid; place-items: center;
  color: #fff; flex-shrink: 0;
}
.tm-row .check svg { width: 9px; height: 9px; }
.tm-row.incoming-side .check { background: var(--info); }
.tm-row .tag {
  font-size: 9px; font-weight: 800; letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 1px 4px; border-radius: 3px;
  background: var(--bg-elevated); color: var(--text-dim);
  border: 1px solid var(--line);
  flex-shrink: 0;
  white-space: nowrap;
}
.tm-row .tag.ntc {
  color: var(--danger); border-color: color-mix(in oklab, var(--danger), transparent 65%);
  background: var(--danger-bg);
}
.tm-row .tag.option {
  /* [A6] option TYPE label is reference info → neutral (the blue pencil carries the action cue). */
  color: var(--text-dim); border-color: var(--line);
  background: transparent;
}
.tm-row .tag.bonus {
  color: var(--warn); border-color: rgba(217,160,79,0.3);
  background: var(--warn-bg);
}
.tm-row .tag.bird {
  color: var(--brand); border-color: var(--brand-line);
  background: var(--brand-soft);
}
/* Re-signed (signed) player: the player INFO is greyed to signal "can't trade
   directly", while the "Signed" chip stays clear + clickable to flip to Sign &
   Trade. (one-world #14 — S&T → roster) */
.tm-row.resigned { cursor: default; }
.tm-row.resigned .name,
.tm-row.resigned .salary,
.tm-row.resigned .yrs-left { color: var(--text-faint); }
.tm-row.resigned .photo img { filter: grayscale(0.55); opacity: 0.72; }
.tm-row.resigned:hover { background: var(--bg-elevated); }
.tm-row .tag.signed-chip {
  display: inline-flex; align-items: center; gap: 2px; cursor: pointer;
  color: var(--text-dim);
  border-color: color-mix(in oklab, var(--line), var(--text-faint) 25%);
  background: color-mix(in oklab, var(--bg-elevated), var(--text-faint) 12%);
}
.tm-row .tag.signed-chip:hover { border-color: var(--danger); color: var(--text); }
.tm-row .tag.signed-chip .pen { width: 8px; height: 8px; opacity: 0.65; margin-left: 1px; }
/* B re-use guard: a player acquired in an applied trade — locked from being re-traded. */
.tm-row .tag.locked-tag { background: var(--bg-row); color: var(--text-faint); border: 1px solid var(--line); cursor: not-allowed; }
.tm-row .subline {
  font-size: 11px; color: var(--text-dim);
  margin-top: 1px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tm-row .right {
  display: flex; flex-direction: column;
  align-items: flex-end; gap: 2px;
  flex-shrink: 0;
}
.tm-row .salary {
  font-size: 13px; font-weight: 800;
  color: var(--text); font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.tm-row .salary-sub {
  display: none;
}
.tm-row .destpill {
  margin-top: 2px;
}
.tm-row.locked { opacity: 0.5; cursor: not-allowed; }
.tm-row .lockico {
  position: absolute; right: 6px; top: 6px;
  color: var(--text-faint);
}
.tm-row .lockico svg { width: 12px; height: 12px; }

/* Action bar (when selected & multi) — appears as a subtle 2nd row */
.tm-row .actionbar {
  grid-column: 1 / -1;
  margin: 4px -2px -2px;
  padding: 3px 4px 0;
  border-top: 1px dashed rgba(238,91,79,0.25);
  display: none;
  align-items: center; gap: 6px;
  min-height: 22px;
}
.tm-row.selected.show-actions .actionbar { display: flex; }
.tm-row.incoming-side .actionbar { border-top-color: rgba(91,155,224,0.25); }
.tm-row .actionbar .lab {
  font-size: 9px; letter-spacing: 0.08em; font-weight: 800;
  color: var(--text-faint); text-transform: uppercase;
}
.tm-row .actionbar .spacer { flex: 1; }
.tm-row .actionbar .iconbtn {
  display: inline-grid; place-items: center;
  width: 20px; height: 20px;
  background: transparent; border: 0;
  border-radius: 4px; color: var(--text-faint);
}
.tm-row .actionbar .iconbtn:hover { color: var(--text); background: var(--bg-row); }
.tm-row .actionbar .iconbtn.danger:hover { color: var(--danger); background: rgba(238,91,79,0.1); }
.tm-row .actionbar .iconbtn svg { width: 11px; height: 11px; }
.tm-row .actionbar .tagopt {
  display: inline-flex; align-items: center; gap: 4px;
  height: 20px; padding: 0 7px;
  background: transparent; border: 1px solid var(--line);
  color: var(--text-dim); font-size: 10px; font-weight: 700;
  border-radius: 5px;
}
.tm-row .actionbar .tagopt.on {
  background: var(--warn-bg); border-color: rgba(217,160,79,0.3); color: var(--warn);
}

/* Pick variant */
.tm-row.pick .photo {
  border-radius: 7px;
  font-size: 10px; font-weight: 800; line-height: 1;
  flex-direction: column;
}
.tm-row.pick.this  .photo { background: var(--brand-soft);  color: var(--brand);  border: 1px solid var(--brand-line); }
.tm-row.pick.swap  .photo { background: var(--info-bg);     color: var(--info);   border: 1px solid rgba(91,155,224,0.3); }
.tm-row.pick.residual .photo { background: var(--warn-bg);  color: var(--warn);   border: 1px solid rgba(217,160,79,0.3); }
.tm-row.pick .photo small { font-size: 8px; font-weight: 700; opacity: 0.7; }

/* List section header */
.list-section {
  padding: 10px 8px 4px;
  font-size: 9.5px; letter-spacing: 0.1em;
  font-weight: 800; text-transform: uppercase;
  color: var(--text-faint);
  display: flex; align-items: center; gap: 8px;
}
.list-section.warn { color: var(--warn); }
.list-section.brand { color: var(--brand); }
.list-section .sep { flex: 1; height: 1px; background: var(--line); }

/* =========================================================
   DESTINATION PILL (compact, in-row) + popover
   ========================================================= */
.tm-dest {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 7px 2px 5px;
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: 6px;
  font-size: 10.5px; font-weight: 800;
  color: var(--text); letter-spacing: 0.02em;
  cursor: pointer;
  flex-shrink: 0;
}
.tm-dest:hover { border-color: var(--brand-line); }
.tm-dest .dot {
  width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.1);
}
.tm-dest .caret { width: 8px; height: 8px; color: var(--text-faint); }
.tm-dest.locked { cursor: default; }
.tm-dest.locked:hover { border-color: var(--line); }
.tm-dest.locked .caret { display: none; }
/* #1c/#5: logo-only destination pill — no background/border, big logo, the
   chevron overlaid at the bottom so the box stays short AND narrow. */
.tm-dest.logo-only {
  background: transparent !important; border: 0 !important; padding: 0;
  display: inline-flex; align-items: center; gap: 0;
}
.tm-dest.logo-only:hover { background: transparent; }
.tm-dest.logo-only .logo-img { display: block; }
.tm-dest.logo-only:hover .logo-img { filter: brightness(1.25); }
/* tentative: auto-defaulted destination the user hasn't confirmed yet (multi-team).
   Dashed amber ring around the logo until they pick/dismiss the menu. */
.tm-dest.logo-only.tentative {
  outline: 1.5px dashed var(--warn);
  outline-offset: 1px;
  border-radius: 6px;
  animation: tm-tentative-pulse 1.6s ease-in-out infinite;
}
@keyframes tm-tentative-pulse { 0%,100% { outline-color: color-mix(in oklab, var(--warn), transparent 35%); } 50% { outline-color: var(--warn); } }
.tm-dest.logo-only .caret {
  position: static; width: 8px; height: 8px; color: var(--text-faint); flex-shrink: 0;
  margin-left: -1px;   /* tuck the chevron close to the logo */
}
.tm-dest.logo-only .qmark { color: var(--text-faint); font-weight: 800; }

.tm-pop {
  position: fixed;
  background: var(--bg-elevated);
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  padding: 5px;
  box-shadow: var(--shadow-lg);
  z-index: 1300;   /* portaled to <body>; must sit above .tm-fullscreen (1000) */
  display: flex; flex-direction: column; gap: 2px;
  min-width: 170px;
}
.tm-pop-item {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 10px; border-radius: 6px; min-height: 40px;   /* #9: more room to breathe */
  background: transparent; border: 0; color: var(--text);
  text-align: left; font-size: 12px; font-weight: 600;
  width: 100%;
}
.tm-pop-item:hover:not(:disabled) { background: var(--bg-row-hover); }
.tm-pop-item.on { color: var(--brand); }
.tm-pop-item img { width: 26px; height: 26px; }
.tm-pop-item:disabled { opacity: 0.35; cursor: not-allowed; }

/* =========================================================
   COLUMN FOOTER — compact per-team summary
   ========================================================= */
.tm-col-foot {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 0 12px;
  border-top: 1px solid var(--line);
  background: linear-gradient(0deg, #0a1015, var(--bg-surface));
  font-size: 11px;
  min-width: 0;
}
.tm-col-foot .totals {
  display: flex; align-items: center; gap: 10px;
  color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tm-col-foot .totals .lab {
  font-size: 9.5px; letter-spacing: 0.08em; font-weight: 800;
  color: var(--text-faint); text-transform: uppercase; margin-right: 3px;
}
.tm-col-foot .totals b { color: var(--text); font-weight: 800; font-variant-numeric: tabular-nums; }
.tm-col-foot .totals .net { color: var(--text); font-variant-numeric: tabular-nums; }
.tm-col-foot .totals .net.over { color: var(--danger); }
.tm-col-foot .totals .net.under { color: var(--brand); }
.tm-col-foot .status {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.05em;
  color: var(--text-faint);
}
.tm-col-foot .status.legal   { color: var(--pos); }
.tm-col-foot .status.illegal { color: var(--danger); }
.tm-col-foot .status .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* =========================================================
   ADD-TEAM COLUMN
   ========================================================= */
.tm-addcol {
  display: flex; flex-direction: column;
  min-width: 0;
  background:
    linear-gradient(180deg, rgba(76,195,145,0.05), transparent 60%),
    var(--bg-surface);
  border-right: 1px solid var(--line);
  border-left: 1px dashed var(--line-strong);
}
.tm-addcol-h { padding: 10px 14px 8px; border-bottom: 1px solid var(--line); }
.tm-addcol-h h3 { margin: 0; font-size: 13.5px; font-weight: 700; color: var(--text); }
.tm-addcol-h p  { margin: 3px 0 0; font-size: 11.5px; color: var(--text-dim); }

.tm-picker {
  flex: 1; overflow: auto; padding: 6px;
  display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
  align-content: start;
}
.tm-picker-h {
  grid-column: span 2;
  display: grid; grid-template-columns: 1fr 1fr;
  font-size: 9px; letter-spacing: 0.1em; font-weight: 800;
  color: var(--text-faint); text-transform: uppercase;
  padding: 4px 8px 4px;
}
.tm-picker-h span:nth-child(2) { text-align: right; }
.tm-picker-cell {
  display: flex; align-items: center; gap: 7px;
  padding: 6px 8px; border-radius: 7px;
  background: transparent; border: 1px solid transparent;
  font-size: 12px; font-weight: 600; color: var(--text);
  text-align: left;
}
.tm-picker-cell.east { flex-direction: row-reverse; text-align: right; }
.tm-picker-cell:hover:not(:disabled) {
  background: var(--bg-row-hover); border-color: var(--line);
}
.tm-picker-cell:disabled { opacity: 0.3; cursor: not-allowed; }
.tm-picker-cell .logo { width: 22px; height: 22px; flex-shrink: 0; }
.tm-picker-cell .logo img { width: 100%; height: 100%; object-fit: contain; }

/* =========================================================
   CASH PANEL (compact)
   ========================================================= */
.tm-cash {
  padding: 14px;
  display: flex; flex-direction: column; gap: 14px;
}
/* #6: season cash summary (received / sent / remaining allowed) */
.tm-cash-summary {
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-elevated);
}
.tm-cash-summary span { display: flex; flex-direction: column; gap: 2px; }
.tm-cash-summary i { font-style: normal; font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-faint); font-weight: 800; }
.tm-cash-summary b { font-size: 14px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--text); }
.tm-cash-summary span.none b { color: var(--danger); }
.tm-cash-box {
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px;
}
.tm-cash-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.tm-cash-row .lbl { color: var(--text-dim); font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }
.tm-cash-input-wrap {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 8px;
  margin-top: 8px;
}
.tm-cash-input {
  background: var(--bg-input); border: 1px solid var(--line);
  color: var(--text); font: inherit; font-weight: 800;
  font-variant-numeric: tabular-nums;
  font-size: 22px;
  padding: 6px 10px;
  border-radius: 7px;
  width: 100%; min-width: 0;
}
.tm-cash-input:focus { outline: none; border-color: var(--brand); }
.tm-cash-suffix { color: var(--text-faint); font-weight: 800; font-size: 14px; }
.tm-cash-meter {
  height: 7px; background: var(--bg-input); border-radius: 99px;
  position: relative; overflow: hidden; margin-top: 8px;
}
.tm-cash-meter .ledger { position: absolute; left: 0; top: 0; bottom: 0; background: var(--text-faint); opacity: 0.6; }
.tm-cash-meter .now    { position: absolute; top: 0; bottom: 0; background: var(--brand); }
.tm-cash-meter.over .now { background: var(--danger); }
.tm-cash-meta { margin-top: 6px; font-size: 11px; color: var(--text-dim); display: flex; justify-content: space-between; }
.tm-cash-meta b { color: var(--text); font-variant-numeric: tabular-nums; }
.tm-cash-meta .over { color: var(--danger); }
.tm-cash-quick { display: flex; gap: 5px; margin-top: 8px; flex-wrap: wrap; }
.tm-cash-quick button {
  height: 26px; padding: 0 9px;
  background: var(--bg-surface); border: 1px solid var(--line);
  color: var(--text-dim); font: inherit; font-size: 11px; font-weight: 600;
  border-radius: 6px;
}
.tm-cash-quick button:hover { color: var(--text); border-color: var(--line-strong); }
.tm-cash-dest {
  display: flex; align-items: center; gap: 8px;
  margin-top: 10px;
  font-size: 11.5px; color: var(--text-dim);
}

/* TPE list */
.tm-tpe { padding: 8px; display: flex; flex-direction: column; gap: 6px; }
.tm-tpe-row {
  display: grid; grid-template-columns: 32px 1fr auto;
  gap: 10px; align-items: center;
  padding: 8px 10px;
  background: var(--bg-row); border: 1px solid var(--line);
  border-radius: 9px;
  cursor: pointer;
}
.tm-tpe-row:hover { border-color: var(--line-strong); background: var(--bg-row-hover); }
.tm-tpe-row.on { border-color: var(--info); background: rgba(91,155,224,0.08); }
.tm-tpe-row .ico {
  width: 32px; height: 32px; border-radius: 7px;
  background: var(--info-bg); color: var(--info);
  display: grid; place-items: center;
  font-weight: 800; font-size: 14px;
}
.tm-tpe-row .name { font-weight: 700; font-size: 13px; }
.tm-tpe-row .meta { font-size: 11px; color: var(--text-dim); margin-top: 2px; }
.tm-tpe-row .amt { font-weight: 800; font-variant-numeric: tabular-nums; }
.tm-tpe-empty {
  text-align: center; padding: 24px 14px;
  color: var(--text-faint); font-size: 12px; line-height: 1.5;
}

/* =========================================================
   R14.A — Sortable.js drag-to-reorder visual states.
   Long-press on touch (200ms) starts drag; quick tap toggles the row.
   ========================================================= */
.tm-list .sort-ghost {
  opacity: 0.35;
  background: var(--bg-row-hover);
}
.tm-list .sort-chosen {
  background: var(--bg-row-hover);
  cursor: grabbing;
}
.tm-list .sort-drag {
  opacity: 0.92;
  box-shadow: 0 8px 18px rgba(0,0,0,0.45);
  background: var(--bg-elevated);
  border-radius: 8px;
}
/* Soft drag handle hint on hover (cursor only — keeps row click intact). */
.tm-list .tm-row[data-name] { cursor: grab; }
.tm-list .tm-row[data-name]:active { cursor: grabbing; }
.tm-list .tm-row.editing[data-name],
.tm-list .tm-row.locked[data-name] { cursor: pointer; }

/* R12.B — Scenario chip + switcher menu (gated by SHOW_SCENARIOS_TOGGLE
   + tweaks.scenariosEnabled). Chip is the trigger; menu drops below it. */
.tm-pillbtn.scenario-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 10px;
  background: var(--bg-elevated); border: 1px solid var(--line);
  color: var(--text); border-radius: 999px;
  font: inherit; font-size: 11.5px; font-weight: 700; cursor: pointer;
  max-width: 160px;
}
.tm-pillbtn.scenario-chip.on { background: var(--brand-soft); border-color: var(--brand-line); color: var(--brand); }
.tm-pillbtn.scenario-chip .lbl {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 110px;
}
.tm-scenario-menu {
  position: absolute; top: 56px; right: 12px;
  width: 280px; max-width: calc(100vw - 24px);
  max-height: calc(100dvh - 80px);
  background: var(--bg-elevated);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: var(--shadow-lg);
  z-index: 350;
  padding: 10px;
  display: flex; flex-direction: column; gap: 8px;
  overflow-y: auto;
}
.tm-scenario-menu .tm-sm-h {
  display: flex; justify-content: space-between; align-items: center;
}
.tm-scenario-menu .tm-sm-h b {
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  font-weight: 800; color: var(--text-faint);
}
.tm-scenario-menu .tm-sm-x {
  background: transparent; border: 0; color: var(--text-faint);
  cursor: pointer; width: 22px; height: 22px; display: grid; place-items: center;
  border-radius: 4px;
}
.tm-scenario-menu .tm-sm-x:hover { color: var(--text); background: var(--bg-row-hover); }
.tm-scenario-menu .tm-sm-list { display: flex; flex-direction: column; gap: 4px; }
.tm-scenario-menu .tm-sm-row {
  display: flex; align-items: stretch; gap: 4px;
  border-radius: 7px;
  background: var(--bg-row);
}
.tm-scenario-menu .tm-sm-row.active { background: color-mix(in srgb, var(--pos) 12%, var(--bg-row)); border: 1px solid var(--pos); }
.tm-scenario-menu .tm-sm-load {
  flex: 1; display: flex; align-items: center; gap: 4px;
  padding: 8px 10px;
  background: transparent; border: 0; color: var(--text);
  text-align: left; font: inherit; font-size: 12.5px; font-weight: 700;
  cursor: pointer; border-radius: 7px;
  min-width: 0;
}
.tm-scenario-menu .tm-sm-load:hover { background: var(--bg-row-hover); }
.tm-scenario-menu .tm-sm-name {
  flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tm-scenario-menu .tm-sm-meta {
  font-size: 10px; color: var(--text-faint); font-weight: 600;
  letter-spacing: 0.04em;
}
.tm-scenario-menu .tm-sm-act {
  background: transparent; border: 0; color: var(--text-dim); cursor: pointer;
  padding: 0 6px; display: grid; place-items: center;
}
.tm-scenario-menu .tm-sm-act:hover { color: var(--text); }
.tm-scenario-menu .tm-sm-act.danger:hover { color: var(--danger); }
.tm-scenario-menu .tm-sm-foot {
  display: flex; gap: 6px;
  padding-top: 6px; border-top: 1px solid var(--line);
}
.tm-scenario-menu .tm-sm-foot .tm-pillbtn {
  flex: 1; font-size: 11px; padding: 6px 8px;
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
}

/* R13.B — OPTIONS PANEL: TPEs + MLEs + cap-room under one tab. */
.tm-options { padding: 6px 8px 12px; display: flex; flex-direction: column; gap: 10px; }
.tm-opt-sect { display: flex; flex-direction: column; gap: 6px; }
.tm-opt-sect h5 {
  margin: 4px 2px 2px;
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  font-weight: 800; color: var(--text-faint);
  display: inline-flex; align-items: center; gap: 6px;
}
.tm-opt-count {
  display: inline-grid; place-items: center;
  min-width: 16px; height: 16px;
  padding: 0 4px;
  background: var(--bg-elevated); color: var(--text-dim);
  border-radius: 8px;
  font-size: 10px; font-weight: 800;
}
.tm-opt-row {
  display: grid; grid-template-columns: 24px 1fr auto;
  align-items: center; gap: 8px;
  padding: 8px 10px;
  background: var(--bg-row);
  border: 1px solid var(--line);
  border-radius: 8px;
  cursor: pointer;
}
.tm-opt-row:hover { background: var(--bg-row-hover); }
.tm-opt-row.info  { cursor: default; background: var(--bg-elevated); }
.tm-opt-row.on    { background: color-mix(in srgb, var(--info) 12%, var(--bg-row)); border-color: var(--info); }
.tm-opt-ico {
  display: grid; place-items: center;
  width: 24px; height: 24px;
  color: var(--text-faint);
  border-radius: 6px;
  background: var(--bg-elevated);
}
.tm-opt-info { min-width: 0; }
.tm-opt-name { font-size: 12.5px; font-weight: 800; color: var(--text); line-height: 1.3; }
.tm-opt-meta { font-size: 10.5px; color: var(--text-faint); font-weight: 600; line-height: 1.4; margin-top: 1px; }
.tm-opt-act { color: var(--text-dim); }
.tm-opt-empty {
  padding: 12px 14px;
  background: var(--bg-row); border: 1px dashed var(--line);
  border-radius: 8px;
  font-size: 11.5px; color: var(--text-dim); line-height: 1.5;
}
.tm-opt-empty.warn { border-color: var(--warn); color: var(--warn); }
.tm-opt-empty-sub { font-size: 10.5px; color: var(--text-faint); margin-top: 4px; }

/* R12 — trade-acquired addition badge in the main-site additions table.
   Replaces the X remove button so the user can't half-undo a trade. */
.from-trade-badge {
  display: inline-flex; align-items: center;
  padding: 2px 8px; border-radius: 999px;
  background: var(--brand-soft); color: var(--brand);
  border: 1px solid var(--brand-line);
  font-size: 10px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
  cursor: help;
}

/* =========================================================
   CASH PANEL v2 — R14 rebuild: vertical layout.
   Two stacked blocks (Send, Receive), each with: header (label + total/limit),
   meter, then per-row controls. No more crammed 5-column grid.
   ========================================================= */
.tm-cash-v2 {
  display: flex; flex-direction: column; gap: 10px;
  padding: 4px 6px 10px;
  font-variant-numeric: tabular-nums;
}
.tcv-block {
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  display: flex; flex-direction: column; gap: 8px;
}
.tcv-block.over { border-color: var(--danger); }
.tcv-h { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.tcv-lbl { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; font-weight: 800; color: var(--text-faint); }
.tcv-total { font-size: 16px; font-weight: 800; color: var(--text); }
.tcv-total .tcv-of { font-size: 10.5px; font-weight: 600; color: var(--text-faint); margin-left: 4px; }
.tcv-total.over { color: var(--danger); }
.tcv-meter { height: 4px; border-radius: 99px; background: var(--bg-row); overflow: hidden; }
.tcv-meter-fill { height: 100%; background: var(--brand); transition: width .25s ease; }
.tcv-meter-fill.recv { background: var(--info); }
.tcv-block.over .tcv-meter-fill { background: var(--danger); }
.tcv-row {
  display: flex; align-items: center; gap: 10px;
  min-height: 32px;
}
.tcv-row-lbl { font-size: 11.5px; font-weight: 700; color: var(--text-dim); min-width: 80px; }
.tcv-val { font-size: 13px; font-weight: 700; color: var(--text); }
.tcv-in {
  flex: 1; display: inline-flex; align-items: center;
  background: var(--bg-row);
  border: 1px solid var(--line-strong);
  border-radius: 7px;
  padding: 4px 8px;
  max-width: 140px;
}
.tcv-in .pre { color: var(--text-faint); font-size: 12px; margin-right: 4px; }
.tcv-in .suf { color: var(--text-faint); font-size: 12px; margin-left: 4px; }
.tcv-in .num {
  flex: 1; min-width: 0; width: 100%;
  background: transparent; border: 0; color: var(--text);
  font-size: 14px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right; padding: 2px 0;
  outline: none;
}
.tcv-quick { gap: 6px; flex-wrap: wrap; }
.tcv-quick button {
  padding: 4px 10px;
  background: var(--bg-row); border: 1px solid var(--line);
  color: var(--text-dim); border-radius: 999px;
  font: inherit; font-size: 11px; font-weight: 700; cursor: pointer;
}
.tcv-quick button:hover { background: var(--bg-row-hover); color: var(--text); }
.tcv-quick button.on { background: var(--brand); color: #052b1d; border-color: var(--brand); }
.tcv-quick button.clear { background: transparent; color: var(--text-faint); border-color: var(--line); }
.tcv-dest { gap: 8px; }
.tcv-warn { font-size: 10.5px; color: var(--warn); font-weight: 700; }
.tcv-foot { font-size: 10.5px; color: var(--text-faint); }
.tcv-foot b { color: var(--text-dim); font-weight: 700; }
.tcv-cba { font-size: 10.5px; color: var(--text-faint); line-height: 1.5; padding: 0 2px; }
.tcv-cba b { color: var(--text-dim); font-weight: 700; }

/* j (backlog): per-season cash BREAKDOWN — Limit / Prior / Proposing / Left.
   Itemizes the headline total so the four numbers the owner asked for are explicit. */
.tcv-bd { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.tcv-bd-c {
  display: flex; flex-direction: column; gap: 2px;
  padding: 5px 7px; min-width: 0;
  background: var(--bg-row); border: 1px solid var(--line); border-radius: 7px;
}
.tcv-bd-c i {
  font-style: normal; font-size: 9px; font-weight: 800;
  letter-spacing: 0.02em; text-transform: uppercase; color: var(--text-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tcv-bd-c b { font-size: 12.5px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
.tcv-bd-c b.now { color: var(--brand); }
.tcv-bd-c.none b { color: var(--danger); }

/* I: external section heading above each cash block + footer summary line. */
.tcv-group { display: flex; flex-direction: column; gap: 5px; }
.tcv-ext-h {
  font-size: 11px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-dim); padding-left: 2px;
}
.tcv-h-foot { border-top: 1px solid var(--line); padding-top: 8px; margin-top: 2px; }

/* ============================================================
   B/C/H — applied-trades / undo window + header opener
   ============================================================ */
.th-open-btn { position: relative; }
/* Neutral count, NOT a notification: applied trades are informational (nothing to
   clear/confirm), so no brand/blue alert colour — a muted grey count chip. */
.th-badge { position: absolute; top: -4px; right: -4px; min-width: 13px; height: 13px; padding: 0 3px; border-radius: 4px; background: var(--bg-elevated); color: var(--text-dim); border: 1px solid var(--line-strong); font-size: 9px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
.th-empty { color: var(--text-faint); font-style: italic; padding: 22px 6px; text-align: center; }
.th-card { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin-bottom: 10px; background: var(--bg-elevated); }
.th-card.focus { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-line); }
.th-card-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.th-teams { font-weight: 800; font-size: 14px; color: var(--text); letter-spacing: 0.02em; }
.th-latest { font-size: 9px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em; color: var(--brand); border: 1px solid var(--brand-line); border-radius: 999px; padding: 1px 7px; }
.th-undo { color: var(--danger); border-color: var(--line-strong); white-space: nowrap; }
.th-undo:hover { background: var(--danger); border-color: var(--danger); color: #fff; }
.th-slots { display: flex; flex-direction: column; gap: 6px; }
.th-slot { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.th-slot-team { min-width: 120px; font-size: 12px; font-weight: 700; color: var(--text-dim); }
.th-slot-team .th-code { color: var(--text-faint); font-weight: 800; font-size: 10px; margin-left: 3px; }
.th-arrow { font-size: 10px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.04em; }
.th-slot-assets { display: flex; flex-wrap: wrap; gap: 5px; flex: 1; }
.th-chip { font-size: 11px; font-weight: 700; background: var(--bg-row); border: 1px solid var(--line); border-radius: 6px; padding: 2px 7px; color: var(--text); }
.th-chip.th-none { color: var(--text-faint); border-style: dashed; font-style: italic; }
.btn.th-share { color: var(--text-dim); }
.btn.th-share:hover { color: var(--text); border-color: var(--line-strong); }

/* ============================================================
   Trade snapshot card (ts-*) — the competition-winning layout.
   Fixed dark palette (not theme vars) so the shared PNG is
   consistent + html2canvas-stable. Card per team; SENDS compact
   rows, GETS cards; Net Salary = player salaries only.
   ============================================================ */
.snapshot-modal.ts-modal { width: min(1180px, 95vw); max-width: none; }
.ts-scroll { width: 100%; overflow: auto; padding: 2px; }
.ts-card { width: 1080px; margin: 0 auto; position: relative; overflow: hidden; border-radius: 20px; border: 1px solid #2b313d; color: #e7ebf2;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: radial-gradient(1200px 360px at 50% -150px, rgba(61,220,132,.06), transparent 60%), linear-gradient(180deg,#1d222b,#161a21); }
.ts-top { display: flex; align-items: center; justify-content: space-between; padding: 9px 24px; border-bottom: 1px solid #2b313d; background: linear-gradient(180deg, rgba(255,255,255,.03), transparent); }
.ts-brand { display: flex; align-items: baseline; font-size: 21px; font-weight: 800; letter-spacing: -.02em; }
.ts-brand .cap { color: #aeb6c4; font-weight: 600; } .ts-brand .mvp { color: #3ddc84; font-weight: 900; }
.ts-tag { font-size: 10.5px; color: #6c7686; letter-spacing: .18em; text-transform: uppercase; font-weight: 700; padding-left: 13px; margin-left: 11px; border-left: 1px solid #2b313d; align-self: center; }
.ts-topright { display: flex; align-items: center; gap: 13px; }
.ts-deal { font-size: 13px; font-weight: 800; color: #e7ebf2; } .ts-deal .n { color: #3ddc84; }
.ts-season { font-size: 12.5px; font-weight: 800; color: #e7ebf2; background: #222732; border: 1px solid #2b313d; border-radius: 999px; padding: 5px 13px; }
.ts-grid { display: grid; gap: 13px; padding: 14px; }
.ts-grid.cols-2 { grid-template-columns: repeat(2,1fr); }
.ts-grid.cols-3 { grid-template-columns: repeat(3,1fr); }
.ts-grid.cols-4 { grid-template-columns: repeat(4,1fr); }
.ts-tcard { background: #1b1f27; border: 1px solid #2b313d; border-radius: 16px; overflow: hidden; display: flex; flex-direction: column; box-shadow: 0 6px 18px rgba(0,0,0,.35); }
.ts-thead { position: relative; padding: 8px 13px; display: flex; align-items: center; gap: 11px; border-bottom: 1px solid #2b313d; }
.ts-chip { width: 38px; height: 38px; border-radius: 11px; display: flex; align-items: center; justify-content: center; font-size: 13.5px; font-weight: 900; color: #fff; background: rgba(0,0,0,.28); border: 1px solid rgba(255,255,255,.22); flex-shrink: 0; }
.ts-tname { font-size: 16px; font-weight: 800; color: #fff; line-height: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 2px rgba(0,0,0,.45); }
.ts-sec { padding: 9px 12px 3px; } .ts-sec + .ts-sec { border-top: 1px dashed #2b313d; }
.ts-sechead { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; }
.ts-arrow { width: 17px; height: 17px; border-radius: 5px; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 900; flex-shrink: 0; }
.ts-arrow.out { background: rgba(239,90,111,.15); color: #ef5a6f; border: 1px solid rgba(239,90,111,.45); }
.ts-arrow.in { background: rgba(52,211,153,.13); color: #34d399; border: 1px solid rgba(52,211,153,.45); }
.ts-sectitle { font-size: 10.5px; font-weight: 800; letter-spacing: .13em; text-transform: uppercase; }
.ts-sechead.out .ts-sectitle { color: #ef5a6f; } .ts-sechead.in .ts-sectitle { color: #34d399; }
.ts-seccount { margin-left: auto; font-size: 10px; font-weight: 700; color: #6c7686; }
.ts-noassets { color: #6c7686; font-size: 12px; padding: 0 2px 8px; }
.ts-ini { display: flex; align-items: center; justify-content: center; font-weight: 800; color: #fff; flex-shrink: 0; border: 1px solid rgba(255,255,255,.14); }
.ts-ini.sm { width: 25px; height: 25px; border-radius: 50%; font-size: 9px; }
.ts-ini.lg { width: 34px; height: 34px; border-radius: 50%; font-size: 12px; }
.ts-ini.pick { background: linear-gradient(180deg,#3a4150,#2a303b); color: #3ddc84; border-radius: 7px; }
.ts-ini.lg.pick, .ts-ini.lg.cash { border-radius: 10px; font-size: 16px; }
.ts-ini.cash { background: linear-gradient(180deg,#2f3d33,#243029); color: #34d399; border-radius: 7px; }
.ts-pos { font-size: 9.5px; font-weight: 800; letter-spacing: .05em; color: #aeb6c4; background: rgba(255,255,255,.06); border: 1px solid #2b313d; border-radius: 5px; padding: 1px 5px; flex-shrink: 0; }
.ts-dest { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 800; letter-spacing: .04em; color: #6c7686; flex-shrink: 0; }
.ts-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.ts-sm { display: flex; align-items: center; gap: 8px; padding: 5px 11px 5px 8px; margin-bottom: 5px; border-radius: 9px; background: #222732; border: 1px solid #2b313d; border-left: 3px solid #ef5a6f; }
.ts-sm-name { font-size: 12.5px; font-weight: 700; color: #e7ebf2; line-height: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 150px; }
.ts-sm-amt { margin-left: auto; padding-left: 8px; font-size: 12.5px; font-weight: 800; color: #e7ebf2; font-variant-numeric: tabular-nums; flex-shrink: 0; }
.ts-asset { display: flex; align-items: center; gap: 10px; padding: 8px 10px; margin-bottom: 6px; border-radius: 11px; background: #222732; border: 1px solid #2b313d; border-left: 3px solid #34d399; }
.ts-asset-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.ts-asset-name { font-size: 14px; font-weight: 700; color: #e7ebf2; line-height: 1.1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-asset-meta { display: flex; align-items: center; gap: 7px; }
.ts-asset-amt { font-size: 14px; font-weight: 800; color: #34d399; font-variant-numeric: tabular-nums; flex-shrink: 0; }
.ts-asset-amt.pick { color: #6c7686; font-weight: 700; font-size: 11px; }
.ts-foot { margin-top: auto; display: flex; align-items: center; justify-content: space-between; padding: 6px 13px; border-top: 1px solid #2b313d; background: linear-gradient(180deg, rgba(0,0,0,.12), rgba(0,0,0,.28)); }
.ts-foot-label { font-size: 9.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: #6c7686; }
.ts-foot-val { display: flex; align-items: baseline; gap: 6px; font-size: 14px; font-weight: 800; font-variant-numeric: tabular-nums; }
.ts-foot-val.pos { color: #34d399; } .ts-foot-val.neg { color: #ef5a6f; }
.ts-foot-val .sub { font-size: 9.5px; font-weight: 700; color: #6c7686; letter-spacing: .04em; text-transform: uppercase; }

/* =========================================================
   PICKS GRID — R11.A: 7-year × 2-round matrix view.
   ========================================================= */
.tm-picks-grid {
  padding: 6px 8px 10px;
  display: flex; flex-direction: column;
  font-variant-numeric: tabular-nums;
}
.tm-picks-grid .pg-head,
.tm-picks-grid .pg-row {
  display: grid;
  grid-template-columns: 56px 1fr 1fr;
  align-items: center;
  gap: 6px;
}
.tm-picks-grid .pg-head {
  padding: 4px 4px 6px;
  border-bottom: 1px solid var(--line);
  color: var(--text-faint);
  font-size: 10px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
}
.tm-picks-grid .pg-yr-h { color: var(--text-faint); }
.tm-picks-grid .pg-rd-h { text-align: center; color: var(--text-faint); }
.tm-picks-grid .pg-row {
  padding: 5px 4px;
  border-bottom: 1px solid var(--line);
  min-height: 38px;
}
.tm-picks-grid .pg-row:last-of-type { border-bottom: 0; }
.tm-picks-grid .pg-row.is-this {
  background: color-mix(in srgb, var(--brand) 6%, transparent);
  border-radius: 6px;
  margin: 1px 0;
}
.tm-picks-grid .pg-yr {
  font-weight: 800; font-size: 12px; color: var(--text);
  padding-left: 4px;
}
.tm-picks-grid .pg-cell {
  display: flex; flex-wrap: wrap; gap: 4px;
  align-items: center; justify-content: center;
  min-height: 28px;
}
.tm-picks-grid .pg-empty {
  color: var(--text-faint); font-size: 14px; font-weight: 600;
  opacity: 0.45;
}
.tm-picks-grid .pg-pick {
  position: relative;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 8px;
  background: var(--bg-row);
  border: 1px solid var(--line);
  border-radius: 7px;
  font-size: 11.5px; font-weight: 700; color: var(--text);
  cursor: pointer;
  min-height: 26px;
  white-space: nowrap;
  transition: background .12s, border-color .12s;
}
.tm-picks-grid .pg-pick:hover {
  background: var(--bg-row-hover);
  border-color: var(--line-strong);
}
.tm-picks-grid .pg-pick.selected {
  background: color-mix(in srgb, var(--pos) 20%, var(--bg-row));
  border-color: var(--pos);
  color: var(--text);
}
.tm-picks-grid .pg-pick.cond { font-style: italic; }
.tm-picks-grid .pg-pick.swap .pg-pick-lbl::after { content: " ⇄"; font-size: 10px; color: var(--warn); margin-left: 2px; }
/* k (backlog): protected/conditional pick — amber accent so it reads apart from a clean own pick. */
.tm-picks-grid .pg-pick.prot:not(.selected) { border-color: color-mix(in srgb, var(--warn) 45%, var(--line)); }
.tm-picks-grid .pg-pick.prot:not(.selected) .pg-pick-lbl { color: var(--warn); }
.tm-picks-grid .pg-info {
  display: inline-grid; place-items: center;
  width: 16px; height: 16px;
  border-radius: 50%;
  color: var(--text-dim);
  font-size: 11px;
  cursor: pointer;
}
.tm-picks-grid .pg-info:hover { color: var(--info); }
.tm-picks-grid .pg-check {
  display: inline-grid; place-items: center;
  color: var(--pos);
  margin-left: 1px;
}
/* R14 — pick detail card: slides up from column bottom on tap, with the
   full RealGM ledger description + an explicit Add/Remove from trade button. */
.tm-picks-grid .pg-card-backdrop {
  position: absolute; inset: var(--col-head-h, 0) 0 0 0;
  background: color-mix(in srgb, #000 50%, transparent);
  z-index: 55;
  animation: tmCdFade .14s ease;
}
.tm-picks-grid .pg-card {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  background: var(--bg-elevated);
  border-top: 1px solid var(--line-strong);
  z-index: 60;
  padding: 14px 14px 12px;
  display: flex; flex-direction: column; gap: 10px;
  box-shadow: 0 -8px 20px rgba(0,0,0,0.35);
  animation: tmCdSlide .22s ease;
  max-height: 70%;
  overflow-y: auto;
}
.tm-picks-grid .pg-card-h {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 8px;
}
.tm-picks-grid .pg-card-title {
  font-size: 14px; font-weight: 800; color: var(--text); letter-spacing: -0.01em;
}
.tm-picks-grid .pg-card-sub {
  font-size: 11.5px; color: var(--text-faint); font-weight: 600; margin-top: 2px;
}
.tm-picks-grid .pg-card-x {
  width: 28px; height: 28px;
  background: var(--bg-row); border: 1px solid var(--line);
  color: var(--text-dim); cursor: pointer;
  display: grid; place-items: center;
  border-radius: 6px;
}
.tm-picks-grid .pg-card-body {
  font-size: 12px; color: var(--text-dim); line-height: 1.55;
  padding: 2px 0;
}
/* k (backlog): per-pick condition line in the detail card (tags + descriptor) over the full ledger. */
.tm-picks-grid .pg-card-cond { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.tm-picks-grid .pg-card-cond b { font-size: 12.5px; font-weight: 800; color: var(--text); }
.tm-picks-grid .pg-card-ledger { font-size: 11.5px; color: var(--text-faint); line-height: 1.5; }
.tm-picks-grid .pg-card-foot {
  display: flex; align-items: center; gap: 8px;
  padding-top: 4px; border-top: 1px dashed var(--line);
  flex-wrap: wrap;
}
.tm-picks-grid .pg-card-dest {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--text-dim);
}
.tm-picks-grid .pg-card-foot .tm-pillbtn { height: 32px; }

/* =========================================================
   PLAYER DETAIL DRAWER (slides up from bottom of column)
   ========================================================= */
.tm-drawer {
  position: absolute;
  inset: var(--col-head-h) 0 var(--col-foot-h) 0;
  background: var(--bg-elevated);
  border-top: 1px solid var(--line);
  z-index: 60;
  display: flex; flex-direction: column;
  animation: slideUp .18s ease;
}
@keyframes slideUp {
  from { transform: translateY(8px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
.tm-drawer-h {
  display: grid;
  grid-template-columns: 44px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
}
.tm-drawer-h .photo { width: 44px; height: 44px; border-radius: 50%; overflow: hidden; background: var(--bg-row); }
.tm-drawer-h .photo img { width: 100%; height: 100%; object-fit: cover; }
.tm-drawer-h .name { font-weight: 800; font-size: 16px; letter-spacing: -0.01em; }
.tm-drawer-h .meta { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.tm-drawer-h .close {
  width: 28px; height: 28px;
  background: transparent; border: 1px solid var(--line);
  border-radius: 7px; color: var(--text-dim);
  display: grid; place-items: center;
}
.tm-drawer-h .close:hover { color: var(--text); border-color: var(--line-strong); }
.tm-drawer-body {
  flex: 1; overflow-y: auto;
  padding: 12px;
  display: flex; flex-direction: column; gap: 14px;
}
.tm-drawer-sect h5 {
  margin: 0 0 6px;
  font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase;
  font-weight: 800; color: var(--text-faint);
}
.tm-drawer-years {
  display: grid; grid-template-columns: 1fr auto auto;
  gap: 6px 12px;
  font-size: 12.5px;
}
.tm-drawer-years .yr { color: var(--text-dim); font-weight: 600; }
.tm-drawer-years .amt { font-weight: 800; font-variant-numeric: tabular-nums; text-align: right; }
.tm-drawer-years .stat { color: var(--text-faint); font-size: 11px; }
.tm-drawer-years .total {
  grid-column: 1 / -1;
  display: grid; grid-template-columns: 1fr auto;
  margin-top: 6px; padding-top: 8px; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--text-dim);
}
.tm-drawer-years .total b { color: var(--text); font-variant-numeric: tabular-nums; font-weight: 800; }
.tm-drawer-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  background: var(--bg-row); border: 1px solid var(--line); border-radius: 8px;
}
.tm-drawer-row .lbl { color: var(--text-dim); font-size: 12px; }
.tm-drawer-row .val { color: var(--text); font-weight: 700; font-size: 12.5px; }
.tm-toggle {
  width: 38px; height: 22px;
  background: var(--bg-input);
  border: 1px solid var(--line);
  border-radius: 99px;
  position: relative; cursor: pointer;
  flex-shrink: 0;
}
.tm-toggle::after {
  content: ""; position: absolute; top: 1px; left: 1px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--text-dim);
  transition: all .15s;
}
.tm-toggle.on { background: var(--brand-soft); border-color: var(--brand-line); }
.tm-toggle.on::after { left: 17px; background: var(--brand); }

.tm-drawer-foot {
  padding: 10px 12px;
  border-top: 1px solid var(--line);
  display: flex; gap: 8px;
}
.tm-drawer-foot .tm-pillbtn { flex: 1; justify-content: center; height: 34px; }

/* =========================================================
   ADD-TEAM COLUMN (already declared above; min-width override)
   ========================================================= */

/* =========================================================
   TWEAKS PANEL
   ========================================================= */
.tweaks {
  position: fixed;
  right: 12px; bottom: 12px;
  width: 280px;
  max-width: calc(100vw - 24px);
  /* R12.0 gear-overflow fix: cap to visible viewport (dvh excludes mobile address
     bar) so the panel can never grow off-screen, and scroll content within. */
  max-height: calc(100dvh - 24px);
  background: var(--bg-elevated);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: var(--shadow-lg);
  z-index: 400;
  padding: 12px;
  display: flex; flex-direction: column; gap: 12px;
  font-size: 12.5px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.tweaks h4 {
  margin: 0; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  font-weight: 800; color: var(--text-faint);
}
.tw-row { display: flex; flex-direction: column; gap: 6px; }
.tw-row label { font-size: 11.5px; color: var(--text-dim); font-weight: 600; }
.tw-seg {
  display: grid; gap: 4px;
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 3px;
}
.tw-seg button {
  padding: 6px 8px;
  background: transparent; border: 0; color: var(--text-dim);
  font: inherit; font-size: 11.5px; font-weight: 600;
  border-radius: 6px;
}
.tw-seg button.on { background: var(--brand); color: #052b1d; }
.tweaks-close {
  /* R12.0 gear-overflow fix: sticky (not absolute) so it stays pinned at the
     top of the visible panel area while content scrolls below it. */
  position: sticky;
  top: 0; align-self: flex-end;
  width: 26px; height: 26px;
  background: var(--bg-elevated); border: 1px solid var(--line); color: var(--text);
  display: grid; place-items: center; border-radius: 6px;
  z-index: 5;
  cursor: pointer;
  margin: -4px -4px 0 0;
}
.tweaks-close:hover { color: var(--text); background: var(--bg-row-hover); }
.tw-select {
  padding: 6px 8px; background: var(--bg-surface);
  color: var(--text); border: 1px solid var(--line);
  border-radius: 6px; font-size: 12.5px; font-family: inherit;
}

/* Toast */
.toast {
  position: fixed; bottom: 14px; left: 50%;
  transform: translateX(-50%);
  background: var(--bg-elevated);
  border: 1px solid var(--brand-line);
  color: var(--text);
  padding: 10px 14px; border-radius: 10px;
  box-shadow: var(--shadow-lg);
  z-index: 500;
  font-size: 13px; font-weight: 600;
  display: flex; align-items: center; gap: 8px;
  animation: toastIn .18s ease;
}
.toast svg { width: 16px; height: 16px; color: var(--brand); }
@keyframes toastIn {
  from { opacity: 0; transform: translate(-50%, 6px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* =========================================================
   CONTAINER QUERIES — true mobile layout when shell is narrow
   ========================================================= */
@container shell (max-width: 720px) {
  .tm-shell { --topbar-h: 44px; --strip-h: 50px; }
  /* Hide non-essential top-bar bits */
  .tm-top .crumb-sep, .tm-top .crumb-b1 { display: none; }
  .tm-top .save-btn { display: none; }
  .tm-top .clear-btn { display: none; }
  .tm-top { gap: 6px; padding: 0 8px; }
  .tm-back .lbl { display: none; }
  .tm-back { padding: 0 7px; }
  .tm-top-verdict .recap { display: none; }   /* #2: keep Legal/Blocked/Ready label visible on mobile */
  .tm-top-verdict { padding: 0 6px; gap: 4px; }
  .tm-pillbtn.apply-btn { padding: 0 9px; }
  .tm-crumb { font-size: 13px; white-space: nowrap; }
  .tm-crumb .b2 { font-size: 13px; }

  /* Board: only active column */
  .tm-board { display: block; overflow-x: hidden; }
  .tm-board .tm-col, .tm-board .tm-addcol { display: none; }
  .tm-board .tm-col.active {
    display: grid; width: 100%; min-width: 0; height: 100%;
  }
  .tm-board .tm-addcol.active { display: flex; width: 100%; height: 100%; }   /* #11: scrolls internally */

  /* Player row: hide full salary subline; tighten (#1: no vertical pad — photo fills height) */
  .tm-row { padding: 0 6px; column-gap: 8px; }
  .tm-row .actionbar { margin: 4px 0 -1px; padding: 3px 0 0; }
  .tm-row .salary-sub { display: none; }
  .tm-row .salary { font-size: 12.5px; }
  .tm-row .subline { font-size: 10px; }
  .tm-row .name { font-size: 12.5px; }
  .tm-row .tag { font-size: 8.5px; padding: 1px 3px; }
  .tm-list { padding: 4px 4px 8px; }
  /* Outgoing strip: tighter */
  .tm-col-out-h { padding: 6px 10px; }
  .tm-col-out-body { padding: 6px 10px; }   /* equal top/bottom → chips centered (was top:0) */
  .tm-out-chip { font-size: 11px; height: 24px; }
  /* stacked chips are two rows — don't crush them to the inline single-row height */
  .tm-out-chip.stacked { height: auto; min-height: 34px; }
  /* Column header tighter; tiles stack */
  .tm-col-head { padding: 6px 10px; gap: 8px; grid-template-columns: 28px 1fr auto; }
  .tm-col-head .logo { width: 28px; height: 28px; }
  .tm-col-head .name { font-size: 13.5px; }
  .tm-col-head .meta { font-size: 10px; gap: 4px; }
  .tm-col-head .meta .tile { padding: 1px 5px; }
  /* Column footer */
  .tm-col-foot { padding: 0 10px; font-size: 10.5px; }
  .tm-col-foot .totals { gap: 8px; }
  .tm-col-foot .totals .lab { font-size: 9px; }

  /* Gets strip more compact */
  .tm-col-gets { padding: 5px 8px; gap: 5px; }
  .tm-col-gets .chip { font-size: 10.5px; height: 20px; padding: 0 6px 0 4px; }
  .tm-col-gets .chip .photo { width: 14px; height: 14px; }

  /* Tabs more compact */
  .tm-tab { padding: 7px 8px; font-size: 11px; }
  .tm-tab span { display: inline; }

  /* Strip teams more compact */
  .tm-strip { padding: 0 8px; }
  .tm-strip-team { padding: 0 8px 0 6px; height: 36px; }
  .tm-strip-team .nm { font-size: 12px; }
  .tm-strip-team .nm small { font-size: 10px; }
  .tm-strip-add { font-size: 11px; padding: 0 8px; }
  .tm-strip-add svg { width: 12px; height: 12px; }
  .tm-strip-add .lbl { display: none; }

  /* Column header tighter */
  .tm-col-head { padding: 5px 10px; gap: 8px; grid-template-columns: 28px 1fr auto; }
  .tm-col-head .logo { width: 28px; height: 28px; }
  .tm-col-head .name { font-size: 13.5px; }
  .tm-col-head .meta { font-size: 10.5px; }

  /* Column footer */
  .tm-col-foot { padding: 0 10px; font-size: 10.5px; }
  .tm-col-foot .totals { gap: 8px; }
  .tm-col-foot .totals .lab { font-size: 9px; }
}

/* On real mobile viewport too (when not in mobile-preview) */
@media (max-width: 720px) {
  .tm-app:not(.mobile) .tm-board { display: block; overflow-x: hidden; }
  .tm-app:not(.mobile) .tm-board .tm-col,
  .tm-app:not(.mobile) .tm-board .tm-addcol { display: none; }
  .tm-app:not(.mobile) .tm-board .tm-col.active {
    display: grid; width: 100%; min-width: 0; height: 100%;
  }
  .tm-app:not(.mobile) .tm-board .tm-addcol.active { display: flex; width: 100%; height: 100%; }
  .tm-app:not(.mobile) .tm-row .salary-sub { display: none; }
  .tm-app:not(.mobile) .tm-back .lbl { display: none; }
  .tm-app:not(.mobile) .tm-top .save-btn,
  .tm-app:not(.mobile) .tm-top .clear-btn { display: none; }
}


/* ============================================================
   Trade Machine — integration layout fixes
   The prototype's grids use explicit track sizing but rely on
   auto-placement, so any `display:none` child shifts the remaining
   items into the wrong tracks. (The prototype's demo always seeded
   outgoing items, so it never hit the empty cases.) Keep the
   would-be-hidden children in flow at zero size instead.
   ============================================================ */
/* shell: the mobile team-strip is display:none on desktop → pin the board
   to the flexible last row so it doesn't fall into the `auto` row. */
.tm-app .tm-board { grid-row: 3 / 4; }
/* column: the empty Outgoing strip must stay a 0-height grid item so the
   list keeps the 1fr track (otherwise the footer absorbs it). */
.tm-app .tm-col-out.empty {
  display: block; height: 0; min-height: 0;
  padding: 0; border: 0; overflow: hidden;
}

/* ============================================================
   Trade Machine — row layout + headshot zoom (feedback batch)
   ============================================================ */
/* Item 10: zoom the 260x190 NBA headshots into the face via CSS crop
   (anchored top-center so the head/face fills the round avatar). */
.tm-app .photo { overflow: hidden; }
/* Photos are always zoomed now (toggle removed). Row photos fill the row
   height (set on .tm-row .photo below); chip photos crop the head fuller and
   are clipped by the chip's rounded box (#8/#9). */
.tm-row .photo img {
  /* middle-ground zoom — head + a bit of shoulder, crop kept high, fills the box */
  object-fit: cover; object-position: 50% 8%; transform: scale(1.3); transform-origin: 50% 8%;
}
.tm-out-chip .photo img {
  /* #3D: nudge the head left (object-position-x ↑) + fill a touch more so there's
     less empty space to the left of the face. */
  object-fit: cover; object-position: 57% 6%; transform: scale(1.55); transform-origin: 57% 6%;
}
.tm-out-chip .nm { max-width: 94px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-left: -4px; }
/* Item 11: the status box ("Player Opt") is a clickable pen → opens the editor. */
.tm-row .tag.tag-edit { cursor: pointer; display: inline-flex; align-items: center; gap: 3px; font-family: inherit; line-height: 1; }
.tm-row .tag.tag-edit .pen { width: 9px; height: 9px; opacity: 0.75; }
.tm-row .tag.tag-edit:hover { color: var(--tm-action-text); border-color: var(--tm-action-line); }
/* Items 12/14: "years left" sits under the salary; dest pill sits under name. */
.tm-row .yrs-left {
  font-size: 10px; color: var(--text-faint);
  font-variant-numeric: tabular-nums; margin-top: 1px;
}
.tm-row .subline.destline { margin-top: 3px; }
.tm-row .rowpen {
  display: inline-grid; place-items: center; width: 22px; height: 22px;
  background: transparent; border: 0; color: var(--text-faint);
  border-radius: 5px; margin-top: 2px;
}
.tm-row .rowpen:hover { color: var(--text); background: var(--bg-row-hover); }

/* #7: the main-site TeamMenu reused inline in the Trade Machine add-team column
   — strip its viewport-fixed overlay positioning so it lays out in the column. */
/* #1a: the add-col is the scroll container — make touch scrolling reliable from anywhere */
.tm-addcol { overflow-y: auto; min-height: 0; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; touch-action: pan-y; }
.tm-addcol .team-menu {
  position: static; transform: none; top: auto; left: auto;
  width: 100%; max-width: none; max-height: none;
  box-shadow: none; border: 0; border-radius: 0;
  background: transparent;
  overflow: visible;   /* #5: the .tm-addcol is the sole scroller — no inner scroll race */
}
.tm-addcol .team-menu-foot { border: 0; }
/* #4: the add-team column has vertical room — spread the rows out for easier taps,
   especially on phone (the old header/footer notices are gone). */
.tm-addcol .team-menu-grid { padding: 8px 10px 12px; }
.tm-addcol .team-menu-cell { padding: 13px 12px; }
.tm-addcol .team-menu-head { padding-top: 8px; }

/* #5/#6: inline-expand editor — the row grows to reveal the option/contract
   controls in place of the old full-page drawer. */
.tm-row.editing {
  background: var(--bg-elevated); border-color: var(--line-strong);
  align-items: start;
}
/* (editor photo no longer stretches full height — reverted; redesign deferred) */
.row-editor {
  grid-column: 1 / -1;
  margin-top: 8px; padding-top: 8px;
  border-top: 1px dashed var(--line);
  display: flex; flex-direction: column; gap: 8px;
}
/* actions sit on a row with the description to their right (top-right), just under the name */
.row-editor .re-top { display: flex; align-items: center; gap: 12px; justify-content: space-between; flex-wrap: wrap; }
.row-editor .re-desc { font-size: 11px; color: var(--text-faint); font-weight: 600; text-align: right; }
.row-editor .re-desc.warn { color: var(--warn); }
.re-seg { display: flex; border: 1px solid var(--line); border-radius: 7px; overflow: hidden; }
.re-seg button {
  flex: 1; padding: 6px 8px; border: 0; background: transparent;
  color: var(--text-dim); font: inherit; font-size: 11.5px; font-weight: 700; cursor: pointer;
}
.re-seg button + button { border-left: 1px solid var(--line); }
.re-seg button.on { background: var(--tm-action-soft); color: var(--tm-action-text); }
.re-tag { font-size: 11px; color: var(--text-faint); font-weight: 600; }
.re-tag.warn { color: var(--warn); }
.re-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.re-field { display: inline-flex; align-items: center; gap: 6px; }
.re-lbl { font-size: 10px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-faint); }
.re-salbox {
  display: inline-flex; align-items: center; gap: 2px;
  border: 1px solid var(--line); border-radius: 6px; background: var(--bg-input); padding: 2px 6px;
}
.re-salbox .pre, .re-salbox .suf { color: var(--text-faint); font-size: 11px; }
.re-salbox input {
  width: 52px; border: 0; background: transparent; color: var(--text);
  font: inherit; font-size: 13px; font-weight: 700; text-align: right; outline: none;
}
.re-years { display: inline-flex; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; }
.re-years button {
  width: 26px; padding: 3px 0; border: 0; background: transparent;
  color: var(--text-dim); font: inherit; font-size: 12px; font-weight: 700; cursor: pointer;
}
.re-years button + button { border-left: 1px solid var(--line); }
.re-years button.on { background: var(--tm-action); color: #fff; }
.re-raise {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); border-radius: 6px; padding: 2px 6px;
}
.re-raise button {
  width: 18px; height: 18px; border: 0; background: var(--bg-row-hover);
  color: var(--text); border-radius: 4px; font-weight: 800; cursor: pointer; line-height: 1;
}
.re-raise b { font-size: 12px; min-width: 26px; text-align: center; font-variant-numeric: tabular-nums; }
.re-total { font-size: 11px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.re-consent { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--text-dim); cursor: pointer; }
.re-foot { display: flex; gap: 8px; justify-content: flex-end; margin-top: 2px; }
.re-foot .tm-pillbtn { height: 30px; }
/* #5: top-level action buttons (Opt in · S&T · Sign · Renounce · Hold) */
.re-actions { display: flex; gap: 4px; flex-wrap: wrap; }
.re-actions button {
  flex: 1 1 auto; min-width: 50px; padding: 5px 8px;
  border: 1px solid var(--line); background: var(--bg-surface);
  color: var(--text-dim); border-radius: 6px;
  font: inherit; font-size: 11px; font-weight: 700; cursor: pointer; white-space: nowrap;
}
.re-actions button:hover:not(.on) { color: var(--text); border-color: var(--line-strong); }
.re-actions button.on { background: var(--tm-action); color: #fff; border-color: var(--tm-action); }
/* R13.A — Renounce/Hold dimmed when team isn't cap-space (CBA: no effect). */
.re-actions button.out-of-scope { opacity: 0.45; }
.re-actions button.out-of-scope.on { opacity: 0.8; }

/* =========================================================
   R11.C — Inline v2 editor: photo stretches ~2× taller via grid-row
   span; actions + contract controls sit beside the stretched photo
   in row 2. Cleaner separation, less visual jump than v1's full-width
   block below the row.
   ========================================================= */
.tm-row.editing.edit-inline-v2 {
  grid-template-rows: auto auto;
  align-items: start;
}
.tm-row.editing.edit-inline-v2 > .photo {
  grid-row: 1 / 3;
  /* taller crop window — let it stretch to the row's full height */
  height: 100% !important;
  min-height: 80px !important;
  max-height: 130px;
  width: 52px !important;
  align-self: stretch;
}
.tm-row.editing.edit-inline-v2 .row-editor.re-inline-v2 {
  grid-column: 2 / -1;
  grid-row: 2;
  margin-top: 6px; padding-top: 6px;
  border-top: 1px dashed var(--line);
}
/* tighten the row-editor for inline-v2 since it shares the row with the stretched photo */
.tm-row.editing.edit-inline-v2 .row-editor.re-inline-v2 .re-top { gap: 8px; }
.tm-row.editing.edit-inline-v2 .row-editor.re-inline-v2 .re-controls { gap: 10px; }

/* =========================================================
   R11.C — Column drawer: slide-up panel anchored to col-scroll
   bottom. Larger canvas, no row-height shift. Backdrop dims the
   column's list.
   ========================================================= */
.tm-col-drawer-backdrop {
  position: absolute;
  inset: var(--col-head-h, 0) 0 0 0;
  background: color-mix(in srgb, #000 55%, transparent);
  z-index: 55;
  animation: tmCdFade .14s ease;
}
.tm-col-drawer {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  background: var(--bg-elevated);
  border-top: 1px solid var(--line-strong);
  z-index: 60;
  padding: 14px 14px 12px;
  display: flex; flex-direction: column; gap: 12px;
  box-shadow: 0 -8px 20px rgba(0,0,0,0.35);
  animation: tmCdSlide .22s ease;
  max-height: 70%;
  overflow-y: auto;
}
@keyframes tmCdFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes tmCdSlide { from { transform: translateY(100%); } to { transform: translateY(0); } }
.tm-cd-close {
  position: absolute; top: 8px; right: 8px;
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--bg-row); border: 1px solid var(--line);
  color: var(--text-dim); cursor: pointer;
  display: grid; place-items: center;
  z-index: 1;
}
.tm-cd-head {
  display: grid; grid-template-columns: 96px 1fr; gap: 14px; align-items: start;
}
.tm-cd-photo {
  width: 96px; height: 112px;
  border-radius: 9px;
  overflow: hidden;
  background: var(--bg-row);
  display: grid; place-items: center;
}
.tm-cd-photo .photo, .tm-cd-photo .photo img { width: 100% !important; height: 100% !important; object-fit: cover; object-position: 50% 14%; }
.tm-cd-info { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.tm-cd-name { font-size: 16px; font-weight: 800; color: var(--text); letter-spacing: -0.01em; }
.tm-cd-meta { font-size: 11.5px; color: var(--text-faint); font-weight: 600; }
.tm-cd-actions { display: flex; flex-wrap: wrap; gap: 4px; }
.tm-cd-actions button {
  flex: 0 1 auto; padding: 5px 10px;
  border: 1px solid var(--line); background: var(--bg-surface);
  color: var(--text-dim); border-radius: 6px;
  font: inherit; font-size: 11.5px; font-weight: 700; cursor: pointer; white-space: nowrap;
}
.tm-cd-actions button:hover:not(.on) { color: var(--text); border-color: var(--line-strong); }
.tm-cd-actions button.on { background: var(--tm-action); color: #fff; border-color: var(--tm-action); }
.tm-cd-desc {
  font-size: 11.5px; color: var(--text-faint); font-weight: 600; line-height: 1.4;
  padding-top: 2px;
}
.tm-cd-desc.warn { color: var(--warn); }
.tm-cd-controls {
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px;
  padding-top: 4px; border-top: 1px dashed var(--line);
}
.tm-cd-field { display: inline-flex; align-items: center; gap: 7px; }
.tm-cd-field label {
  font-size: 10px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--text-faint);
}
.tm-cd-salbox {
  display: inline-flex; align-items: center; gap: 2px;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--bg-input, var(--bg-row)); padding: 3px 7px;
}
.tm-cd-salbox .pre, .tm-cd-salbox .suf { color: var(--text-faint); font-size: 11px; }
.tm-cd-salbox input {
  width: 56px; border: 0; background: transparent; color: var(--text);
  font: inherit; font-size: 13px; font-weight: 700; text-align: right; outline: none;
}
.tm-cd-years { display: inline-flex; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; }
.tm-cd-years button {
  width: 28px; padding: 4px 0; border: 0; background: transparent;
  color: var(--text-dim); font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer;
}
.tm-cd-years button + button { border-left: 1px solid var(--line); }
.tm-cd-years button.on { background: var(--tm-action); color: #fff; }
.tm-cd-raise {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--line); border-radius: 6px; padding: 3px 7px;
}
.tm-cd-raise button {
  width: 20px; height: 20px; border: 0; background: var(--bg-row-hover);
  color: var(--text); border-radius: 4px; font-weight: 800; cursor: pointer; line-height: 1;
}
.tm-cd-raise b { font-size: 12.5px; min-width: 28px; text-align: center; font-variant-numeric: tabular-nums; }
.tm-cd-total { font-size: 12px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.tm-cd-foot { display: flex; gap: 8px; justify-content: flex-end; }
.tm-cd-foot .tm-pillbtn { height: 32px; }

/* #1/#2: columns stay dark (--bg-app, the main-site PAGE colour) in every mode;
   the rows are the lifted --bg-surface cards (set above). Mixed (default) +
   Solid just drop the neon dot-glows so surfaces read solid; Neon keeps glows. */
.tm-app.surface-mixed .tm-top-verdict .dot, .tm-app.surface-mixed .tm-col-foot .status .dot,
.tm-app.surface-solid .tm-top-verdict .dot, .tm-app.surface-solid .tm-col-foot .status .dot {
  box-shadow: none !important;
}
/* Solid only: also flatten the team accent bar. */
.tm-app.surface-solid .tm-col-accent { opacity: 0.5; height: 2px; }
.tm-app.surface-solid .tm-col-accent::after { display: none; }
.tm-app.surface-solid .tm-top-verdict .dot,
.tm-app.surface-solid .tm-col-foot .status .dot { box-shadow: none !important; }
.tm-app.surface-solid .tm-row.selected {
  background: color-mix(in oklab, var(--danger), var(--bg-surface) 85%);
  border-color: color-mix(in oklab, var(--danger), transparent 55%);
}
.tm-app.surface-solid .tm-row.incoming {
  background: color-mix(in oklab, var(--bg-surface), var(--incoming) 14%);
  border-color: color-mix(in oklab, var(--incoming), transparent 60%);
}
.tm-app.surface-solid .tm-list .tm-row:not(.selected):not(.incoming):not(:hover) { background: var(--bg-surface); }

/* #1: calm the TOP zone (header bar / OUTGOING strip / incoming rows) in Mixed
   (default) + Solid — the gradients + blue/red washes read too neon. Keep a
   clean SOLID team bar; flatten the strip; make incoming a subtle tint. Neon
   mode keeps the full glowy treatment. */
/* (Mixed keeps the SAME neon team bar as Neon — no accent flatten here.) */
.tm-app.surface-mixed .tm-col-out,
.tm-app.surface-solid .tm-col-out { background: none; }                  /* drop the red gradient wash */
.tm-app.surface-mixed .tm-out-chip,
.tm-app.surface-solid .tm-out-chip { border-color: var(--line); }        /* neutral chip border */
.tm-app.surface-mixed .tm-row.incoming {
  background: color-mix(in oklab, var(--bg-surface), var(--incoming) 12%);
  border-color: transparent;
}
.tm-app.surface-mixed .tm-row.incoming:hover,
.tm-app.surface-solid .tm-row.incoming:hover { border-color: color-mix(in oklab, var(--incoming), transparent 55%); }
/* Incoming rows use the locked cyan (--incoming). The old per-colour inc-* dev
   options + the "Incoming color" dropdown were removed (palette: cyan won). */

/* ============================================================
   Outgoing chip — STACKED layout (experimental gear toggle).
   Salary under the name (with decimals), bigger team logo, room between the
   chevron + remove. Box height stays the same — name/salary fonts shrink.
   Stacked+ swaps the ✕ for an "Undo trade" button.
   ============================================================ */
.tm-out-chip.stacked { gap: 6px; padding: 0 6px 0 0; }
.tm-out-chip.stacked .chip-mid {
  display: flex; flex-direction: column; justify-content: center;
  min-width: 0; line-height: 1.1; gap: 1px; margin-left: -2px;
}
.tm-out-chip.stacked .chip-mid .nm {
  font-size: 11.5px; font-weight: 700; max-width: 96px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin: 0;
}
.tm-out-chip.stacked .chip-mid .amt {
  font-size: 9.5px; font-weight: 700; color: var(--text-dim); margin: 0;
}
.tm-out-chip.stacked .tm-dest.logo-only { margin-left: 2px; }
.tm-out-chip.stacked .rm { margin-left: 5px; }   /* room between chevron + remove */
/* Stacked 3–8: small logo + salary share the bottom row. */
.tm-out-chip .chip-botrow { display: flex; align-items: center; gap: 3px; }
.tm-out-chip .chip-botrow .tm-dest.logo-only { margin-left: 0; }
.tm-out-chip .chip-botrow .amt { font-size: 9.5px; font-weight: 700; color: var(--text-dim); }
.tm-dest.logo-only.sm .caret { width: 7px; height: 7px; margin-left: -2px; }
/* Stacked 7/8: name + one-click ✕ on the top row (✕ pushed right, away from the
   bottom-row team logo to avoid accidental removes). */
.tm-out-chip .chip-toprow { display: flex; align-items: center; gap: 6px; }
.tm-out-chip .chip-toprow .rm { width: 16px; height: 16px; margin: 0 0 0 auto; }
.tm-out-chip .chip-toprow .rm svg { width: 10px; height: 10px; }
/* Stacked 11: full-height team logo sits flush between the player photo and the
   stacked name/$ text (no chevron). */
.tm-dest.logo-only.fullh { align-self: stretch; height: auto; padding: 0; margin: 0; display: inline-flex; align-items: center; }
.tm-dest.logo-only.fullh .logo-img { height: 28px !important; width: 28px !important; }
.tm-out-chip.stacked11 { gap: 4px; padding: 0 6px 0 0; }
.tm-out-chip.stacked11 .tm-dest.logo-only.fullh { margin-left: 1px; }
.tm-out-chip.stacked11 .chip-mid { margin-left: 1px; }
.tm-out-chip.stacked11 .rm { margin-left: 3px; }
/* Dropdown "Undo trade" item (remove path for the no-✕ chip variants). */
.tm-pop-item.undo { border-top: 1px solid var(--line); margin-top: 4px; color: var(--text-dim); }
.tm-pop-item.undo:hover { background: var(--danger-bg); color: var(--danger); }

/* ============================================================
   [COLOUR] V3 design-system locked tokens (ported from Roster V3 → V4, phase 0).
   data-attr overrides on <html> select the locked scheme (set in index.html
   before paint). Placed at EOF so these beat the palette-compare blocks AND any
   earlier per-selector rule (e.g. the --photo-ext editing-row height). UI
   consumers (decision polarity, de-neon, checkmark centering) land in later phases.
   ============================================================ */
/* LOGO colourway — swaps ONLY the two wordmark tokens (--logo-cap / --logo-mvp). */
html[data-logo="heritage"]            { --logo-cap:#0a8060; --logo-mvp:#0a7fc5; }
html.light[data-logo="heritage"]      { --logo-cap:#086047; --logo-mvp:#0a7fc5; }
html[data-logo="classic"]             { --logo-cap:var(--logo-red); --logo-mvp:#0a7fc5; }
html.light[data-logo="classic"]       { --logo-cap:var(--logo-red); --logo-mvp:#0a7fc5; }
html[data-logo="classic-bright"]      { --logo-cap:var(--logo-red); --logo-mvp:#2f8fd0; }
html.light[data-logo="classic-bright"]{ --logo-cap:var(--logo-red); --logo-mvp:#2f72d6; }
html[data-logo="classic-indigo"]      { --logo-cap:var(--logo-red); --logo-mvp:#3b6fd4; }
html.light[data-logo="classic-indigo"]{ --logo-cap:var(--logo-red); --logo-mvp:#2a55b8; }
/* KELLY-INDIGO (active) — green "Cap"/hat #107A41 (= Sign FA / --pos) + blue "MVP" #3b6fd4 (= action --brand). Unified brand pair, 2026-06-03. */
html[data-logo="kelly-indigo"]        { --logo-cap:#107A41; --logo-mvp:#3b6fd4; }
html.light[data-logo="kelly-indigo"]  { --logo-cap:#107A41; --logo-mvp:#3b6fd4; }

/* GREEN (--pos) selector. All filled buttons use white text → --pos-fg forced white. */
html[data-pos] { --pos-fg: #ffffff; }
html[data-pos="kelly"]    { --pos: #107A41; }
html[data-pos="forest"]   { --pos: #15824a; }
html[data-pos="emerald"]  { --pos: #1a8f50; }
html[data-pos="mint"]     { --pos: #34c07e; }

/* LOGO-RED selector — drives --logo-red, consumed by the classic* logo blocks. */
html { --logo-red: #d8344f; }
html[data-logored="capmvp"]  { --logo-red: #d8344f; }
html[data-logored="nba"]     { --logo-red: #c8102e; }
html[data-logored="espn"]    { --logo-red: #da020e; }
html[data-logored="scarlet"] { --logo-red: #e0162b; }

/* Numbers: chart floor (0→cap) + hero payroll. Payroll is WHITE; blue freed for actions. */
html { --chart-floor: var(--logo-mvp, #3b6fd4); }
html { --payroll-num: var(--text); }
/* brighter green for small NUMBER text on the dark bar (deep --pos reads too dark tiny). */
html { --pos-text: #1a8f50; }   /* [tweak b] a hair brighter than kelly --pos (legible on dark), calmer than the old mint #34c07e */
html.light { --pos-text: var(--pos); }

/* Terminal-action red (.on-no buttons). Danger TEXT stays on the legible --danger. */
html { --danger-btn: var(--danger); }
html[data-dangerred="coral"]   { --danger-btn: var(--danger); }
html[data-dangerred="nba"]     { --danger-btn: #c8102e; }
html[data-dangerred="crimson"] { --danger-btn: #ad1626; }
html[data-dangerred="wine"]    { --danger-btn: #8c1d2b; }
html[data-dangerred="oxblood"] { --danger-btn: #6d1622; }

/* Reversible-decline red token — kept for the Palette Lab (opt-out is NEUTRAL now). */
html { --letred: #ad1626; }

/* Profile photo EXTENDED height when a row's editor is open (locked 1.8×). */
html { --photo-ext: 1.8; }
.decide-row.is-active > .row-photo,
.flex-row.body-row.editing > .row-photo { height: calc(var(--row-h) * var(--photo-ext)); min-height: calc(var(--row-h) * var(--photo-ext)); }

/* Neutral ("Hold") colour. */
html[data-neutral="slate"]  { --neutral: #5a6376; }
html[data-neutral="grey"]   { --neutral: #6b7280; }
html[data-neutral="warm"]   { --neutral: #6b6a72; }
html[data-neutral="steel"]  { --neutral: #566173; }

/* Apron-line reference numbers ($209.1M etc) — white / grey / blue. */
html { --apron-num: var(--text); }
html[data-apronnum="white"] { --apron-num: var(--text); }
html[data-apronnum="grey"]  { --apron-num: var(--text-dim); }
html[data-apronnum="blue"]  { --apron-num: var(--brand-blue, #4299e1); }

/* ============================================================
   [COLOUR] phase 1b — de-neon the cap-strategy selector (ported from V3).
   Selected row/card, collapsed chip + info boxes wore saturated --brand (now
   blue) borders/tints (a glowing edge). Make them NEUTRAL; only the round ✓ check
   stays blue. EOF placement so these beat the earlier per-selector brand rules.
   ============================================================ */
.strategy-row.on, .strategy-card.on { border-color: var(--line-strong); background: var(--bg-elevated); }
.strategy-row:hover, .strategy-card:hover { border-color: var(--line-strong); }
.strategy-row.on .strategy-mark, .strategy-card.on .strategy-mark { background: var(--brand); border-color: var(--brand); color: #fff; }
.mode-chip { border-color: var(--line-strong); background: var(--bg-elevated); color: var(--text); }
.mode-chip:hover, .mode-chip.open { border-color: var(--text-faint); background: var(--bg-row-hover); }
.mode-chip-caret { color: var(--text-faint); }
.mode-decide-box, .strat-info-card { border-color: var(--line); }
.apron-blurb { background: var(--bg-elevated); border-color: var(--line); }
.apron-blurb .ico { background: var(--neutral); color: #fff; }

/* ============================================================
   [COLOUR] phase 1b — contrast cleanup after --brand became BLUE (ported from V3):
   selected fills are blue → white text (not the old dark-green ink); small blue
   glyphs route to --brand-blue; positive STATUS → green; confirm checks SOLID.
   ============================================================ */
html.dark .sb-mode-toggle button.on,
html.dark .mode-toggle button.on,
html.dark .step-tab.active .step-num,
html.dark .strategy-row.on .strategy-mark,
html.dark .strategy-card.on .strategy-mark,
html.dark .dp-edit-disp button.on,
html.dark .opt-seg button.on,
html.dark .apron-blurb .ico { color: #fff; }
.cap-advice-bar .pencil.confirm:hover,
.cap-edit-line .cap-edit-confirm .pencil.confirm:hover { color: #fff; }
/* small confirm/edit glyphs + links: brand fill-blue too dim as text on dark → --brand-blue */
.pencil.confirm, .roster-actions .pencil.confirm { color: var(--brand-blue); }   /* [tweak a] restore-link dropped from this group → stays calm grey */
/* positive STATUS chip (was green-on-green neon) → subtle green box, grey text, plain border */
.cap-status-chip.signed { color: var(--text-dim); border-color: var(--line); background: var(--pos-bg); }
.flex-row.body-row.is-addition { background: color-mix(in oklab, var(--bg-surface), var(--pos) 11%); box-shadow: inset 3px 0 0 var(--pos); }
/* confirm-checks: SOLID blue at rest */
.decide-foot .pencil.confirm, .mode-decide-foot .pencil.confirm { border-color: var(--brand-blue); background: var(--brand-blue); color: #fff; }
/* #3 — the in-editor ✓ (signing confirm) was a SOFT pill (brand-soft bg, blue check)
   that only filled on hover, so it didn't match the solid "Decide these first" ✓.
   Make every editor confirm solid-blue/white at rest too — one consistent ✓ style
   everywhere. The ✗ stays the site's bordered danger-icon cancel (subtler than ✓). */
.cap-advice-bar .pencil.confirm,
.cap-edit-line .cap-edit-confirm .pencil.confirm {
  border-color: var(--brand-blue); background: var(--brand-blue); color: #fff;
}

/* ============================================================
   [COLOUR] phase 1c — value pickers + checkmark centring (ported from V3).
   ============================================================ */
/* Value pickers (Years / Option type) = quiet NEUTRAL raised pill (a value choice,
   not pos/neg/action). */
.resign-years button.on-pick, .resign-opt button.on-pick,
.decisions.resign-years button.on-pick { background: var(--line-strong); color: var(--text); border-color: transparent; }
/* Checkmark / X vertical centring on every pencil + decision glyph (paired with the
   retuned Icon.Check polyline 20 7 9.5 17.5 4 12). */
.pencil { padding: 0; }
.pencil svg, .pencil .dec-icon,
.cap-edit-confirm .pencil svg, .cap-advice-bar .pencil svg, .decide-foot .pencil svg,
.decisions button .dec-icon { display: block; position: static; top: auto; transform: none; margin: 0; }

/* ============================================================
   [COLOUR] phase 4 — main-page action buttons by MEANING (ported from V3):
   Sign FA = GREEN (adding a player is positive) · Trades = BLUE (action).
   Both .side-actions and .actions-right list them in [Sign FA, Trades] order.
   ============================================================ */
.side-actions .btn:first-child,
.actions-right .btn:first-child {
  background: var(--pos); border-color: transparent; color: #fff;
}
.side-actions .btn:first-child:hover,
.actions-right .btn:first-child:hover {
  background: color-mix(in oklab, var(--pos), #000 10%); border-color: transparent; color: #fff;
}
.side-actions .btn:nth-child(2),
.actions-right .btn:nth-child(2) {
  background: var(--brand); border-color: transparent; color: var(--brand-fg, #fff);
}
.side-actions .btn:nth-child(2):hover,
.actions-right .btn:nth-child(2):hover {
  background: color-mix(in oklab, var(--brand), #000 10%); border-color: transparent; color: var(--brand-fg, #fff);
}

/* ============================================================
   CapMVP picks — timeline + ticket card (TmPicksPanel / TmPickCard).
   Our picks-variant surface ported into the trade machine, themed off V4's
   LIVE vars so it follows theme / palette / team-skin. Every class is namespaced
   `tmp-` to avoid collisions with existing trade-machine styles. The card is
   portaled to <body>, so position:fixed centring is immune to transformed
   ancestors.
   ============================================================ */
.tmp-wrap{padding:4px 2px 10px}
.tmp-sec{margin-top:12px}
.tmp-sec:first-child{margin-top:2px}
.tmp-sec-h{display:flex;align-items:center;gap:7px;font-size:11px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--text);border-bottom:1.5px solid var(--line-strong);padding-bottom:6px;margin-bottom:7px}
.tmp-sec-h .tmp-sq{width:9px;height:9px;border-radius:2px;background:var(--info)}
.tmp-sec-h .tmp-cnt{margin-left:auto;font-weight:600;font-size:10px;color:var(--text-faint);text-transform:none;letter-spacing:0}
.tmp-cols2{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.tmp-subh{margin-bottom:4px}
.tmp-subh div{font-size:9px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint)}
.tmp-yr-row{display:grid;grid-template-columns:30px 1fr;gap:9px;position:relative;padding-bottom:9px}
.tmp-yr-row::before{content:"";position:absolute;left:5px;top:7px;bottom:-3px;width:1.5px;background:var(--line-strong)}
.tmp-yr-row.last::before{display:none}
.tmp-yr{font-weight:800;font-size:11.5px;color:var(--text-faint);position:relative;padding-left:15px}
.tmp-yr::before{content:"";position:absolute;left:0;top:2px;width:10px;height:10px;border-radius:50%;background:var(--info);border:2px solid var(--bg-app)}
.tmp-subc{min-height:6px;min-width:0}
.tmp-dash{color:var(--text-faint);font-size:12px;padding-left:3px}
/* token */
.tmp-tok{display:flex;flex-wrap:wrap;align-items:center;gap:5px;width:100%;text-align:left;background:var(--bg-surface);border:1px solid var(--line);border-radius:8px;padding:5px 7px;margin-bottom:5px;cursor:pointer;color:inherit;font:inherit}
.tmp-tok:hover{border-color:var(--brand)}
.tmp-tok.cond{border-style:dashed}
.tmp-tok.sel{border-color:var(--brand);box-shadow:inset 0 0 0 1px var(--brand)}
.tmp-tok.pending{background:color-mix(in oklab,var(--info),transparent 90%);border-color:color-mix(in oklab,var(--info),transparent 45%)}
.tmp-idr{display:flex;align-items:center;gap:4px;min-width:0}
.tmp-lg{display:inline-flex;flex:none}
.tmp-lg img{border-radius:3px}
.tmp-cd{font-weight:800;font-size:11.5px;letter-spacing:.02em}
.tmp-chint{font-size:10px;font-weight:700;color:var(--info);white-space:nowrap}
.tmp-pl{font-size:8.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--text-faint)}
.tmp-bdg{font-size:9px;font-weight:800;line-height:1.35;padding:1.5px 5px;border-radius:5px;border:1px solid var(--line-strong);color:var(--text-dim)}
.tmp-bdg.b-pos{color:var(--pos);border-color:var(--pos)}
.tmp-bdg.b-neg{color:var(--danger);border-color:var(--danger);border-style:dashed}
.tmp-bdg.b-neu{color:var(--text-dim)}
.tmp-tok-chk{margin-left:auto;color:var(--brand);font-weight:800;font-size:12px}
.tmp-pending-from{margin-left:auto;display:inline-flex;align-items:center;opacity:.9}
.tmp-pending-from img{border-radius:3px}
/* detail card (portaled to <body>) */
.tmp-scrim{position:fixed;inset:0;background:rgba(4,7,10,.55);z-index:1200}
.tmp-card{position:fixed;left:0;right:0;bottom:0;max-width:460px;margin:0 auto;background:var(--bg-surface);border-top:1px solid var(--line-strong);border-radius:14px 14px 0 0;z-index:1201;max-height:80vh;overflow:auto;animation:tmpUp .2s cubic-bezier(.3,.8,.3,1)}
@keyframes tmpUp{from{transform:translateY(100%)}to{transform:translateY(0)}}
.tmp-ch{display:flex;align-items:center;gap:9px;padding:13px 14px 6px}
.tmp-clg{display:inline-flex;flex:none}
.tmp-clg img{border-radius:4px}
.tmp-ti{font-weight:800;font-size:14px}
.tmp-su{font-size:11px;color:var(--text-faint)}
.tmp-x{margin-left:auto;border:0;background:var(--bg-elevated);color:var(--text-dim);width:28px;height:28px;border-radius:8px;font-size:17px;cursor:pointer;flex:none;line-height:1}
.tmp-cbody{padding:2px 14px 14px}
.tmp-cfull{font-size:13.5px;line-height:1.55}
.tmp-swapcard{margin-top:11px;border:1px solid var(--line-strong);border-radius:10px;padding:8px 11px}
.tmp-swapcard.pos{border-color:color-mix(in oklab,var(--pos),transparent 50%);background:color-mix(in oklab,var(--pos),transparent 90%)}
.tmp-swapcard.neg{border-color:color-mix(in oklab,var(--danger),transparent 50%);background:color-mix(in oklab,var(--danger),transparent 90%);border-style:dashed}
.tmp-sw-h{display:flex;align-items:center;gap:6px;font-size:10px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;margin-bottom:4px}
.tmp-swapcard.pos .tmp-sw-h{color:var(--pos)}
.tmp-swapcard.neg .tmp-sw-h{color:var(--danger)}
.tmp-swlg{display:inline-flex;flex:none}
.tmp-swlg img{border-radius:3px}
.tmp-sw-t{}
.tmp-swcd{margin-left:auto;font-weight:800;font-size:11px;color:var(--text-dim);letter-spacing:.02em}
.tmp-sw-b{font-size:12.5px;line-height:1.45;color:var(--text);margin-top:2px}
.tmp-otab{width:100%;border-collapse:collapse;margin:6px 0 2px}
.tmp-otab td{border:1px solid var(--line-strong);padding:7px 8px;text-align:center;font-weight:700;font-size:12.5px}
.tmp-otab .tmp-oh{text-align:left;color:var(--text-dim);font-weight:800;font-size:11.5px;white-space:nowrap;background:var(--bg-elevated)}
.tmp-otab .tmp-ow{color:var(--pos);background:color-mix(in oklab,var(--pos),transparent 88%)}
.tmp-otab .tmp-od{color:var(--text-faint)}
.tmp-chev{margin-top:12px;border:0;background:transparent;color:var(--brand);font:inherit;font-size:12.5px;font-weight:800;cursor:pointer;padding:5px 0;display:flex;align-items:center;gap:7px}
.tmp-chev .tmp-cv{display:inline-block;transition:transform .15s;font-size:10px}
.tmp-chev.open .tmp-cv{transform:rotate(90deg)}
.tmp-chev:hover{filter:brightness(1.15)}
.tmp-wf{margin-top:11px;border-top:1px solid var(--line-strong);padding-top:9px}
.tmp-wr{display:flex;align-items:center;gap:9px;margin-bottom:6px}
.tmp-wr .tmp-wl{font-size:12px;font-weight:700;flex:1 1 auto;min-width:0}
.tmp-seg{display:inline-flex;border:1px solid var(--line-strong);border-radius:7px;overflow:hidden;flex:none}
.tmp-seg button{border:0;background:transparent;color:var(--text-faint);font:inherit;font-size:11px;font-weight:700;padding:3px 10px;min-width:46px;cursor:pointer}
.tmp-seg button.on{background:var(--brand);color:#fff}
.tmp-vd{margin-top:8px;font-size:12.5px;font-weight:800}
.tmp-vd.g{color:var(--pos)}
.tmp-vd.d{color:var(--danger)}
.tmp-vd.u{color:var(--text-faint)}
.tmp-wr.moot{opacity:.5}
.tmp-wr.moot .tmp-seg{display:none}
.tmp-wr.moot.forced{opacity:1}
.tmp-mlbl{font-size:11px;font-weight:800;color:var(--text-faint);flex:none;white-space:nowrap}
.tmp-mlbl.f{color:var(--info)}
.tmp-add{margin-top:12px;width:100%;border:1px solid var(--line-strong);background:var(--bg-elevated);color:var(--text);font:inherit;font-size:12.5px;font-weight:800;border-radius:9px;padding:9px;cursor:pointer}
.tmp-add.on{background:var(--brand);border-color:var(--brand);color:#fff}
.tmp-dest{display:flex;align-items:center;gap:8px;margin-top:10px;font-size:11px;color:var(--text-dim);font-weight:700}
/* inline destination selector (left of a reduced-width Add button) */
.tmp-addrow{display:flex;align-items:stretch;gap:8px;margin-top:12px}
.tmp-addrow .tmp-add{margin-top:0;flex:1 1 auto}
.tmp-destsel{display:inline-flex;align-items:center;gap:5px;flex:none;border:1px solid var(--line-strong);background:var(--bg-elevated);border-radius:9px;padding:6px 11px;cursor:default;color:var(--text)}
.tmp-destsel.changer{cursor:pointer}
.tmp-destsel.changer:hover{border-color:var(--brand)}
.tmp-destsel img{border-radius:3px}
.tmp-destcaret{font-size:13px;font-weight:800;color:var(--text-dim);line-height:1}
/* trade mechanics — build a protection / swap on the card */
.tmp-mech{margin-top:14px;border-top:1px solid var(--line-strong);padding-top:11px}
.tmp-mech-h{font-size:9px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--text-faint);margin-bottom:8px}
.tmp-legacy{display:inline-block;font-size:11px;font-weight:700;color:var(--text-dim);background:var(--bg-elevated);border:1px solid var(--line-strong);border-radius:7px;padding:6px 10px}
.tmp-built{display:flex;align-items:center;gap:8px;font-size:12px;font-weight:800;color:var(--text);background:var(--bg-elevated);border:1px solid var(--line-strong);border-radius:8px;padding:6px 10px;margin-bottom:8px}
.tmp-mech-x{margin-left:auto;border:1px solid var(--line-strong);background:transparent;color:var(--text-dim);font:inherit;font-size:10px;font-weight:800;border-radius:6px;padding:3px 8px;cursor:pointer}
.tmp-mech-x:hover{border-color:var(--danger);color:var(--danger)}
.tmp-mech-btns{display:flex;gap:8px}
.tmp-mech-btn{flex:1;border:1px solid var(--line-strong);background:var(--bg-elevated);color:var(--text);font:inherit;font-size:12px;font-weight:800;border-radius:8px;padding:8px;cursor:pointer}
.tmp-mech-btn:hover{border-color:var(--brand)}
.tmp-mech-btn.on{background:var(--brand);border-color:var(--brand);color:#fff}
.tmp-build{margin-top:9px;border:1px solid var(--line-strong);border-radius:9px;padding:10px}
.tmp-build-lbl{font-size:11px;font-weight:700;color:var(--text-dim);margin-bottom:6px}
.tmp-presets{display:flex;flex-wrap:wrap;gap:6px}
.tmp-preset{border:1px solid var(--line-strong);background:var(--bg-surface);color:var(--text);font:inherit;font-size:12px;font-weight:800;border-radius:7px;padding:6px 11px;cursor:pointer}
.tmp-preset:hover:not(:disabled){border-color:var(--brand)}
.tmp-preset.banned{opacity:.4;cursor:not-allowed;text-decoration:line-through;border-style:dashed}
.tmp-preset-block{display:inline-flex;align-items:center;font-size:10px;font-weight:800;letter-spacing:.02em;color:var(--text-faint);border:1px dashed var(--line-strong);border-radius:7px;padding:6px 9px;opacity:.8}
.tmp-teamsel{width:100%;font:inherit;font-size:12px;font-weight:700;color:var(--text);background:var(--bg-surface);border:1px solid var(--line-strong);border-radius:7px;padding:7px 9px;cursor:pointer;margin-bottom:2px}
.tmp-teamsel:hover{border-color:var(--brand)}
.tmp-swtarget{display:flex;align-items:center;gap:6px;margin:8px 0 2px;padding:7px 9px;border:1px solid var(--line-strong);border-radius:8px;background:var(--bg-elevated)}
.tmp-swtarget-team{margin-left:auto;display:inline-flex;align-items:center;gap:5px;font-size:10px;font-weight:800;color:var(--text-dim);white-space:nowrap}
.tmp-swtarget-team img{border-radius:3px}
.tmp-stepien{margin:2px 0 10px;font-size:11px;font-weight:700;color:var(--warn);background:var(--warn-bg);border:1px solid color-mix(in oklab,var(--warn),transparent 55%);border-radius:8px;padding:7px 10px;line-height:1.4}
.tmp-incoming{margin:2px 0 12px;padding:8px 9px;border:1px solid var(--line-strong);border-radius:9px;background:var(--bg-elevated)}
.tmp-incoming-h{font-size:9px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--incoming, var(--info));margin-bottom:6px}
/* protection slider */
.tmp-slabels{display:flex;justify-content:space-between;gap:10px;font-size:11.5px;color:var(--text-dim);margin-bottom:7px}
.tmp-slabels .r{text-align:right}
.tmp-slabels b{font-weight:800}
.tmp-slabels .l b{color:var(--pos)}
.tmp-slabels .r b{color:var(--brand)}
.tmp-slider{width:100%;margin:2px 0 4px;accent-color:var(--brand);cursor:pointer}
.tmp-sticks{display:flex;justify-content:space-between;font-size:9px;font-weight:700;color:var(--text-faint);margin-bottom:10px}
.tmp-sticks .blk{color:var(--warn);cursor:help}
.tmp-mech-err{margin-top:8px;font-size:11px;font-weight:700;color:var(--danger);background:var(--danger-bg);border:1px solid color-mix(in oklab,var(--danger),transparent 55%);border-radius:7px;padding:6px 9px}
.tmp-mech-hint{margin-top:8px;font-size:10px;color:var(--text-faint);line-height:1.4}
.tmp-swrow{display:flex;align-items:center;gap:10px;margin-top:9px}
.tmp-swrow .tmp-build-lbl{margin-bottom:0;flex:1}
.tmp-build .tmp-destsel{margin-top:2px}
.tmp-build .tmp-add{margin-top:11px}
.tmp-tok.built{border-color:var(--brand)}
.tmp-legacy.tmp-mir{color:var(--info);border-color:color-mix(in oklab,var(--info),transparent 50%);background:color-mix(in oklab,var(--info),transparent 88%)}
@media (min-width:600px){
 .tmp-card{top:50%;left:50%;right:auto;bottom:auto;width:460px;max-width:calc(100vw - 48px);border:1px solid var(--line-strong);border-radius:14px;max-height:84vh;transform:translate(-50%,-50%);animation:tmpPop .16s ease}
 @keyframes tmpPop{from{transform:translate(-50%,-50%) scale(.97);opacity:0}to{transform:translate(-50%,-50%) scale(1);opacity:1}}
}
