/* ==========================================================================
   FSN — The Funboy Sports Network
   Design system v2 — "Broadcast"

   Still light, still built on TSN's structure and weight, but no longer a
   spreadsheet with a red stripe on it. What changed:
     · franchise identity — 14 colours + generated crests, used everywhere
     · surfaces with real depth instead of 1px grey boxes
     · tables that read as standings, not as cells (no zebra, hairlines,
       sticky paper headers, team edge, mono figures, live filter toolbar)
     · a display / serif / mono type system so prose, headlines and data
       each look like themselves
   ========================================================================== */

:root {
  /* brand ------------------------------------------------------------ */
  --fsn-red:        #d40026;
  --fsn-red-dark:   #a80020;
  --fsn-red-ink:    #8d001b;
  --fsn-red-wash:   #fdf0f2;

  /* surfaces & ink --------------------------------------------------- */
  --ink:            #14161a;
  --ink-2:          #3c4148;
  --paper:          #ffffff;
  --paper-2:        #f2f3f5;
  --paper-3:        #e7e9ed;
  --canvas:         #eef0f3;
  --black:          #0b0c0e;
  --black-2:        #16181c;
  --black-3:        #24272d;
  --gray-rule:      #e4e6ea;
  --gray-rule-2:    #c9ced6;
  --gray-text:      #626873;

  /* elevation -------------------------------------------------------- */
  --sh-1: 0 1px 2px rgba(16,20,28,.05), 0 1px 1px rgba(16,20,28,.04);
  --sh-2: 0 2px 4px rgba(16,20,28,.06), 0 4px 12px rgba(16,20,28,.07);
  --sh-3: 0 8px 24px rgba(16,20,28,.12), 0 2px 6px rgba(16,20,28,.07);

  /* data viz — validated against #ffffff ----------------------------- */
  /* v5.5: the default series was magenta, sitting next to a brand red and a
     blue magnitude ramp — three colour systems on one page, which is the
     "77 off-palette marks" the last audit left open. The default series is
     now step 5 of the same ramp every grade, tier and carry-over bar uses, so
     a bar on the Trade Desk and a bar on the keeper board mean the same
     thing. --series-2 stays as the genuine second category. */
  --series-1:       #2264ab;
  --series-2:       #8a5a00;
  --grid:           #e6e8ec;
  --track:          #e9ebef;

  /* sequential ramp, one hue, light → dark (magnitude) */
  --seq-1: #dbe7f6; --seq-2: #b3cdec; --seq-3: #7fabde;
  /* step 4 was #4a86cd: white on it is 3.76:1, and this ramp carries
     10px bold chip labels, so 4.5:1 is the bar. Darkened until white
     clears it; lightness stays monotone and every adjacent gap is
     still ≥ 0.06. */
  --seq-4: #3d76b8; --seq-5: #2264ab; --seq-6: #123f70;

  /* status — always shipped with a label, never colour alone --------- */
  --good:           #17663a;
  --good-wash:      #e7f4ec;
  --warn:           #8a5a00;
  --warn-wash:      #fdf3e0;
  --bad:            #a3202c;
  --bad-wash:       #fdeef0;

  /* medals ----------------------------------------------------------- */
  --gold:           #b8860b;
  --silver:         #6f757e;
  --bronze:         #96552a;

  /* type ------------------------------------------------------------- */
  --cond: "Archivo Narrow", "Roboto Condensed", "Arial Narrow", system-ui, sans-serif;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --serif: "Source Serif 4", Georgia, "Times New Roman", serif;
  --mono: "Roboto Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* metrics ---------------------------------------------------------- */
  --wrap: 1280px;
  --gutter: 20px;
  --radius: 6px;
  --radius-sm: 4px;

  /* the neutral fallback for anything not inside a [data-team] scope lives in
     the generated identity block below, so there is one source for it */
}

/* ------------------------------------------------------- franchise colours
   Identity, never the sole encoding: every crest carries the club's own art,
   every row carries the club's name, and every chart mark carries a direct
   label, so a reader who cannot separate two hues still reads the row
   correctly. That matters more here than it used to: the two closest inks in
   the set — Derek's Leafs navy and Matt's indigo — sit ΔE76 14.4 apart, which
   is comfortable but is not the 30-plus a hue wheel hands you for free.
   fsn.js stamps data-team onto GM links, chips and table rows from their
   href, so these apply site-wide without a single page being rewritten. */
/* >>> FSN CLUB IDENTITY — GENERATED BY tools/apply_identity.py
 *
 * Fourteen clubs, each colour sampled from that club's own artwork rather
 * than picked off a hue wheel, and each crest the club's real logo masked to
 * a circle with a rim in its own ink. Every ink clears 4.5:1 on white as an
 * 8-bit value, so it is safe as text, as a rule, and as a row's leading edge.
 *
 * Two vocabularies, one source: --club/--club-wash/--club-crest are the pack's
 * names, --team/--team-wash alias them so every rule already written against
 * --team keeps working. Keyed by the GM key fsn.js stamps AND the club slug.
 *
 * DO NOT HAND-EDIT. Regenerate with tools/apply_identity.py.
 */

:root {
  --club: #4a5058; --club-wash: #f1f2f4; --club-crest: none;
  --team: var(--club); --team-wash: var(--club-wash);
}
[data-team] { --team: var(--club); --team-wash: var(--club-wash); }

/* Beaches Bandits — Troy — the neon coral raccoon -- the only colour in it (10.54:1 on white, from the club's Yahoo logo) */
[data-team="troy"],
[data-team="beaches-bandits"] {
  --club: #772003;
  --club-wash: #f9ede9;
  --club-signature: #fc9b7b;
  --club-crest: url("clubs/crests/beaches-bandits-crest-192.png");
  --club-logo: url("clubs/logos/beaches-bandits-256.png");
}

/* Bros Before Ahos — David — Aho crimson (6.9:1 on white, drawn for FSN) */
[data-team="david"],
[data-team="bros-before-ahos"] {
  --club: #b3122f;
  --club-wash: #f9e9ec;
  --club-signature: #b3122f;
  --club-crest: url("clubs/crests/bros-before-ahos-crest-192.png");
  --club-logo: url("clubs/logos/bros-before-ahos-256.png");
}

/* Caufield Of Dreams — Marcus — the cornfield (10.53:1 on white, from the club's Yahoo logo) */
[data-team="marcus"],
[data-team="caufield-of-dreams"] {
  --club: #543a17;
  --club-wash: #f9f2e9;
  --club-signature: #aa742e;
  --club-crest: url("clubs/crests/caufield-of-dreams-crest-192.png");
  --club-logo: url("clubs/logos/caufield-of-dreams-256.png");
}

/* Domo Arigato Mr. Roboto — Matt — indigo (10.74:1 on white, drawn for FSN) */
[data-team="matt"],
[data-team="domo-arigato-mr-roboto"] {
  --club: #3b2e8c;
  --club-wash: #eceaf8;
  --club-signature: #3b2e8c;
  --club-crest: url("clubs/crests/domo-arigato-mr-roboto-crest-192.png");
  --club-logo: url("clubs/logos/domo-arigato-mr-roboto-256.png");
}

/* Dusty Gooch — Dylan — the sky behind the shot (6.02:1 on white, from the club's Yahoo logo) */
[data-team="dylan"],
[data-team="dusty-gooch"] {
  --club: #004ff9;
  --club-wash: #e9eef9;
  --club-signature: #004ff9;
  --club-crest: url("clubs/crests/dusty-gooch-crest-192.png");
  --club-logo: url("clubs/logos/dusty-gooch-256.png");
}

/* Faulk Me — Atul — the deep red of the scarf (12.21:1 on white, from the club's Yahoo logo) */
[data-team="atul"],
[data-team="faulk-me"] {
  --club: #6b1119;
  --club-wash: #f9e9eb;
  --club-signature: #6b1119;
  --club-crest: url("clubs/crests/faulk-me-crest-192.png");
  --club-logo: url("clubs/logos/faulk-me-256.png");
}

/* Hobgoblin Ale — Alex — label gold (4.51:1 on white, from the club's Yahoo logo) */
[data-team="alex"],
[data-team="hobgoblin-ale"] {
  --club: #a76828;
  --club-wash: #f9f1e9;
  --club-signature: #e2b587;
  --club-crest: url("clubs/crests/hobgoblin-ale-crest-192.png");
  --club-logo: url("clubs/logos/hobgoblin-ale-256.png");
}

/* Legia Brosawa — Artur — Oilers orange (4.51:1 on white, from the club's Yahoo logo) */
[data-team="artur"],
[data-team="legia-brosawa"] {
  --club: #c2562b;
  --club-wash: #f9eee9;
  --club-signature: #d66f45;
  --club-crest: url("clubs/crests/legia-brosawa-crest-192.png");
  --club-logo: url("clubs/logos/legia-brosawa-256.png");
}

/* Let's Tuch About Sex — Derek — the Leafs sweater -- not a skin tone off the face (10.35:1 on white, from the club's Yahoo logo) */
[data-team="derek"],
[data-team="lets-tuch-about-sex"] {
  --club: #0333a6;
  --club-wash: #e9eef9;
  --club-signature: #0333a6;
  --club-crest: url("clubs/crests/lets-tuch-about-sex-crest-192.png");
  --club-logo: url("clubs/logos/lets-tuch-about-sex-256.png");
}

/* My Team is Mostly Ass — Chris — magenta (6.81:1 on white, drawn for FSN) */
[data-team="chris"],
[data-team="my-team-is-mostly-ass"] {
  --club: #a81c74;
  --club-wash: #f9e9f3;
  --club-signature: #a81c74;
  --club-crest: url("clubs/crests/my-team-is-mostly-ass-crest-192.png");
  --club-logo: url("clubs/logos/my-team-is-mostly-ass-256.png");
}

/* Quintin's Team — Quintin — teal (5.99:1 on white, drawn for FSN) */
[data-team="quintin"],
[data-team="quintins-team"] {
  --club: #0e6e75;
  --club-wash: #e9f8f9;
  --club-signature: #0e6e75;
  --club-crest: url("clubs/crests/quintins-team-crest-192.png");
  --club-logo: url("clubs/logos/quintins-team-256.png");
}

/* Roswell UFOs — Anthony — badge field (4.51:1 on white, from the club's Yahoo logo) */
[data-team="anthony"],
[data-team="roswell-ufos"] {
  --club: #dc3a16;
  --club-wash: #f9ece9;
  --club-signature: #ea502e;
  --club-crest: url("clubs/crests/roswell-ufos-crest-192.png");
  --club-logo: url("clubs/logos/roswell-ufos-256.png");
}

/* Stu Where's Makar? — James — the sky the panel sits in (4.5:1 on white, from the club's Yahoo logo) */
[data-team="james"],
[data-team="stu-wheres-makar"] {
  --club: #0073ec;
  --club-wash: #e9f1f9;
  --club-signature: #60adff;
  --club-crest: url("clubs/crests/stu-wheres-makar-crest-192.png");
  --club-logo: url("clubs/logos/stu-wheres-makar-256.png");
}

/* The Buds — Aaron — a leaf, green (7.0:1 on white, drawn for FSN) */
[data-team="aaron"],
[data-team="the-buds"] {
  --club: #14663f;
  --club-wash: #e9f9f1;
  --club-signature: #14663f;
  --club-crest: url("clubs/crests/the-buds-crest-192.png");
  --club-logo: url("clubs/logos/the-buds-256.png");
}

/* Former GMs kept the record but never a club logo. They keep the monogram,
   on neutral ink, which is now the only place the old shield shape survives. */
[data-team="adam"], [data-team="jamie"], [data-team="johnny"],
[data-team="myles"], [data-team="phil"], [data-team="rolando"],
[data-team="legacy"] { --club: #5c626b; --club-wash: #f1f2f4; --club-crest: none; }

/* <<< FSN CLUB IDENTITY — END GENERATED BLOCK */

/* ---------------------------------------------------------------- reset */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}
body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font: 400 16px/1.55 var(--sans);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; }
a { color: inherit; }
h1, h2, h3, h4, h5 { margin: 0; font-family: var(--cond); font-weight: 700;
  letter-spacing: .005em; line-height: 1.06; }
p { margin: 0 0 1em; }
ul, ol { margin: 0 0 1em; padding-left: 1.25em; }
table { border-collapse: collapse; width: 100%; }
button { font: inherit; }
:focus-visible { outline: 3px solid var(--fsn-red); outline-offset: 2px; border-radius: 2px; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--fsn-red); color: #fff; padding: 10px 16px; font-weight: 700;
}
.skip-link:focus { left: 0; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); }

/* ================================================================== chrome */

/* utility bar */
.utility {
  background: var(--black); color: #a7abb3;
  font: 600 11.5px/1 var(--sans); letter-spacing: .06em; text-transform: uppercase;
}
.utility .wrap { display: flex; align-items: center; gap: 18px; height: 30px;
  overflow-x: auto; white-space: nowrap; scrollbar-width: none; }
.utility .wrap::-webkit-scrollbar { display: none; }
.utility a { color: #a7abb3; text-decoration: none; }
.utility a:hover { color: #fff; }
.utility .spacer { margin-left: auto; }

/* masthead */
.masthead { background: var(--black);
  background-image: radial-gradient(120% 180% at 8% -40%, #23262c 0%, transparent 62%); }
.masthead .wrap {
  display: flex; align-items: center; gap: 16px;
  padding-top: 15px; padding-bottom: 15px;
}
.logo { display: inline-flex; align-items: stretch; text-decoration: none; }
.logo-mark {
  background: var(--fsn-red); color: #fff;
  font-family: var(--cond); font-weight: 700; font-size: 34px; line-height: 1;
  letter-spacing: .04em; padding: 9px 13px 7px;
  border-radius: var(--radius-sm);
  box-shadow: inset 0 -3px 0 rgba(0,0,0,.22);
}
.logo-word {
  display: flex; flex-direction: column; justify-content: center;
  padding-left: 13px; color: #fff;
}
.logo-word b {
  font-family: var(--cond); font-size: 15.5px; letter-spacing: .17em;
  text-transform: uppercase; font-weight: 700;
}
.logo-word span { font-size: 11.5px; color: #8f949c; letter-spacing: .04em; }
.masthead .est {
  margin-left: auto; color: #757a83; font-size: 11.5px; letter-spacing: .11em;
  text-transform: uppercase;
}

/* main nav */
.mainnav { background: var(--black-2); position: sticky; top: 0; z-index: 40;
  border-bottom: 3px solid var(--fsn-red); }
.mainnav .wrap { display: flex; align-items: stretch; gap: 0; }
.mainnav a {
  position: relative; color: #dfe1e5; text-decoration: none; padding: 13px 15px 11px;
  font-family: var(--cond); font-weight: 700; font-size: 15px;
  letter-spacing: .08em; text-transform: uppercase;
  border-bottom: 3px solid transparent; margin-bottom: -3px; white-space: nowrap;
  transition: background .12s ease, color .12s ease;
}
.mainnav a:hover { background: #23262b; color: #fff; }
.mainnav a[aria-current="page"] { border-bottom-color: var(--fsn-red); color: #fff;
  background: #1d2025; }
.navtoggle { display: none; }

/* ticker — a scoreboard strip, not a list of cells */
.ticker { background: var(--paper); border-bottom: 1px solid var(--gray-rule);
  max-width: 100vw; box-shadow: var(--sh-1); position: relative; z-index: 30; }
.ticker ul {
  display: flex; gap: 0; margin: 0; padding: 0; list-style: none;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none; max-width: 100%;
}
.ticker ul::-webkit-scrollbar { display: none; }
.ticker li {
  flex: 0 0 auto; border-right: 1px solid var(--gray-rule);
  font-size: 13.5px; white-space: nowrap;
}
.ticker li:first-child { border-left: 1px solid var(--gray-rule); }
.ticker a, .ticker > ul > li > span {
  display: block; padding: 8px 20px 9px; text-decoration: none;
  border-top: 3px solid transparent; transition: background .12s;
}
.ticker a:hover { background: var(--paper-2); border-top-color: var(--fsn-red); }
.ticker b {
  display: block; font: 700 9.5px/1.5 var(--sans); letter-spacing: .13em;
  text-transform: uppercase; color: var(--gray-text);
}
.ticker a > :not(b), .ticker li { font-variant-numeric: tabular-nums; }
.ticker a { font-weight: 600; }

/* ================================================================== layout */
main { display: block; padding: 26px 0 44px; }

.page-head { margin-bottom: 18px; }
.page-head .kicker {
  display: inline-flex; align-items: center; gap: 8px;
  font: 700 10.5px/1 var(--sans); letter-spacing: .16em; text-transform: uppercase;
  color: var(--fsn-red); margin-bottom: 8px;
}
.page-head .kicker::before {
  content: ""; width: 22px; height: 3px; background: var(--fsn-red); display: block;
}
.page-head h1 { font-size: clamp(28px, 3.6vw, 40px); text-transform: uppercase;
  letter-spacing: -.005em; }
.page-head .standfirst {
  margin-top: 7px; font-family: var(--serif); font-size: 15.5px; line-height: 1.42;
  color: var(--ink-2); max-width: 64ch;
}

.section-head {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  border-bottom: 2px solid var(--ink);
}
.section-head h2 {
  font-size: clamp(19px, 2.6vw, 25px); text-transform: uppercase;
  display: flex; align-items: baseline; gap: 10px;
}
.section-head h2::before {
  content: ""; width: 9px; height: 9px; background: var(--fsn-red);
  border-radius: 2px; flex: 0 0 auto; align-self: center;
}
.section-head .sub { font-size: 13.5px; color: var(--gray-text); }
.section-head .note { margin-left: auto; font-size: 12.5px; color: var(--gray-text); }

.grid { display: grid; gap: 16px; }
.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.layout-rail { display: grid; gap: 26px; grid-template-columns: minmax(0,1fr) 330px; }

.card {
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1);
}

/* ============================================================== franchise */

/* Crest — a CSS-drawn shield. No image files, scales anywhere, takes its
   colour from the nearest [data-team] scope. */
/* The crest is now the club's own artwork, circular, rimmed in its own ink.
   The monogram stays in the markup underneath it and is what shows through
   when a club has no art — the six former GMs — so the slot never renders
   empty and screen readers still get a name. The four shield silhouettes are
   retired: they existed to stop a wall of fourteen identical shields reading
   as one shape, and fourteen distinct logos solve that better than four
   generated outlines ever did. */
.crest {
  --size: 34px;
  width: var(--size); height: var(--size);
  flex: 0 0 auto; position: relative;
  background: var(--club);
  border-radius: 50%;
  display: grid; place-items: center;
  color: #fff; font: 700 calc(var(--size) * .40)/1 var(--cond);
  letter-spacing: .02em; text-transform: uppercase;
  text-shadow: 0 1px 1px rgba(0,0,0,.22);
}
/* the artwork. `background-image: none` when --club-crest is none, which is
   exactly what lets the monogram beneath show through for a legacy GM. */
.crest::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: var(--club-crest) center / cover no-repeat;
}
.crest::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: 2;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.13), 0 1px 2px rgba(16,20,28,.14);
}
.crest > span { position: relative; }
.crest.lg { --size: 60px; }
.crest.xl { --size: 84px; }
.crest.sm { --size: 26px; }   /* real artwork needs a little more room than a monogram did */

/* GMChip */
.gmchip { display: inline-flex; align-items: center; gap: 9px; text-decoration: none;
  vertical-align: middle; }
.gmchip .dot, .gmchip .crest { flex: 0 0 auto; }
.gmchip .dot {
  width: 26px; height: 26px; border-radius: var(--radius-sm); background: var(--team);
  color: #fff; font: 700 12px/26px var(--cond); text-align: center;
  letter-spacing: .04em;
}
.gmchip b { font-weight: 650; }
.gmchip:hover b { text-decoration: underline; text-decoration-color: var(--team);
  text-underline-offset: 2px; }
.gmchip .team { color: var(--gray-text); font-size: 13px; }

/* a compact inline chip: coloured dot + name, for use inside prose & cells */
.tm {
  display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
  font-weight: 600; white-space: nowrap;
}
.tm::before {
  content: ""; width: 9px; height: 9px; border-radius: 2px;
  background: var(--team); flex: 0 0 auto;
}
.tm:hover { text-decoration: underline; text-decoration-color: var(--team);
  text-underline-offset: 2px; }

/* franchise banner — the top of a team page */
.franchise-hero {
  position: relative; overflow: hidden; border-radius: var(--radius);
  background: var(--team); color: #fff; box-shadow: var(--sh-2);
  margin-bottom: 18px;
}
.franchise-hero::before {
  content: ""; position: absolute; inset: 0;
  /* the fourteen inks now span 4.5:1 to 12.2:1 on white, so the banner has to
     hold white text on Hobgoblin's label gold as well as on Faulk Me's oxblood.
     A floor of darkening across the whole panel, not just the left edge. */
  background:
    linear-gradient(105deg, rgba(0,0,0,.34), rgba(0,0,0,.12) 58%),
    repeating-linear-gradient(115deg, rgba(255,255,255,.07) 0 3px, transparent 3px 34px);
}
.franchise-hero .inner {
  position: relative; display: flex; align-items: center; gap: 20px;
  padding: 18px 24px 17px; flex-wrap: wrap;
}
.franchise-hero .kicker {
  font: 700 11px/1 var(--sans); letter-spacing: .16em; text-transform: uppercase;
  color: rgba(255,255,255,.82); margin-bottom: 9px;
}
.franchise-hero h1 { font-size: clamp(28px, 3.8vw, 42px); text-transform: uppercase;
  color: #fff; }
.franchise-hero .line {
  margin-top: 9px; font-family: var(--mono); font-size: 14px; letter-spacing: .02em;
  color: rgba(255,255,255,.94); font-variant-numeric: tabular-nums;
}
.franchise-hero .line a { color: #fff; }
.franchise-hero .badges { margin-top: 13px; }
.franchise-hero .badge { background: rgba(255,255,255,.15); border-color: rgba(255,255,255,.3);
  color: #fff; }
.franchise-hero .who { min-width: 0; flex: 1 1 320px; }
.franchise-hero .standfirst { margin: 8px 0 0; font-family: var(--serif);
  font-size: 15px; line-height: 1.45; color: rgba(255,255,255,.9); max-width: 66ch; }
.franchise-hero .rankblock {
  margin-left: auto; text-align: right; flex: 0 0 auto;
  padding-left: 22px; border-left: 1px solid rgba(255,255,255,.22);
}
.franchise-hero .rankblock .lbl {
  display: block; font: 700 10.5px/1 var(--sans); letter-spacing: .15em;
  text-transform: uppercase; color: rgba(255,255,255,.72);
}
.franchise-hero .rankblock .num {
  display: block; font-family: var(--cond); font-weight: 700; font-size: 44px;
  line-height: 1; margin-top: 5px; font-variant-numeric: tabular-nums;
}
.franchise-hero .rankblock .stars { color: #ffd76a; display: block; margin-top: 8px; }
/* On the banner the field is already the team colour, so the crest inverts:
   a white shield carrying the monogram in the club's hue. */
.franchise-hero .crest {
  background: rgba(255,255,255,.92); color: var(--club); text-shadow: none;
  filter: drop-shadow(0 6px 16px rgba(0,0,0,.32));
}
.franchise-hero .crest::before {
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.5);
}
/* the club's full logo, sunk into the banner as its watermark */
.franchise-hero::after {
  content: ""; position: absolute; top: 50%; right: -46px;
  width: 300px; height: 300px; transform: translateY(-50%);
  background: var(--club-logo) center / contain no-repeat;
  opacity: .12; pointer-events: none;
  mix-blend-mode: luminosity;
}
@media (max-width: 900px) { .franchise-hero::after { display: none; } }

/* a franchise page tints its own furniture */
html[data-team] .tile::before { background: var(--team); }
html[data-team] .section-head h2::before { background: var(--team); }
html[data-team] .rail h2 { box-shadow: inset 0 -3px 0 var(--team); }

/* ============================================================== components */

/* StatTile */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(152px, 1fr)); }
.tile {
  position: relative; background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1); overflow: hidden;
}
.tile::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 4px;
  background: var(--fsn-red);
}
.tile[data-team]::before { background: var(--team); }
.tile .label {
  font: 700 10.5px/1.3 var(--sans); letter-spacing: .13em;
  text-transform: uppercase; color: var(--gray-text);
}
.tile .value {
  font-family: var(--cond); font-weight: 700; line-height: 1.02;
  margin: 6px 0 3px; font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}
.tile .value.sm { font-size: 27px; }
.tile .context { font-size: 12.5px; color: var(--gray-text); line-height: 1.42; }
.tile .spark { margin-top: 9px; display: block; }

/* StoryCard */
.story {
  display: block; background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); text-decoration: none; overflow: hidden;
  box-shadow: var(--sh-1);
  transition: box-shadow .15s ease, transform .15s ease, border-color .15s ease;
}
.story:hover { box-shadow: var(--sh-2); transform: translateY(-2px);
  border-color: var(--gray-rule-2); }
.story .body { padding: 15px 16px 17px; }
.story .eyebrow {
  font: 700 10.5px/1 var(--sans); letter-spacing: .13em; text-transform: uppercase;
  color: var(--fsn-red); margin-bottom: 8px;
}
.story h3 { font-size: 20px; }
.story:hover h3 { text-decoration: underline; text-underline-offset: 2px; }
.story p { margin: 8px 0 0; font-size: 14.5px; color: var(--ink-2);
  font-family: var(--serif); line-height: 1.48; }

/* hero */
.hero {
  position: relative; background: var(--black); color: #fff;
  border-radius: var(--radius); overflow: hidden; box-shadow: var(--sh-2);
  min-height: 330px; display: flex; align-items: flex-end;
  text-decoration: none;
}
.hero .art { position: absolute; inset: 0; opacity: .55; }
.hero .body {
  position: relative; padding: 30px 28px 26px;
  background: linear-gradient(to top, rgba(0,0,0,.94) 22%, rgba(0,0,0,0));
  width: 100%;
}
.hero .eyebrow {
  display: inline-block; background: var(--fsn-red); color: #fff;
  font: 700 10.5px/1 var(--sans); letter-spacing: .13em; text-transform: uppercase;
  padding: 6px 9px; margin-bottom: 12px; border-radius: 2px;
}
.hero h2 { font-size: clamp(28px, 4.6vw, 46px); text-transform: uppercase; }
.hero p { margin: 10px 0 0; font-size: 16px; color: #d3d6db; max-width: 62ch;
  font-family: var(--serif); line-height: 1.5; }
.hero:hover h2 { text-decoration: underline; text-underline-offset: 3px; }

/* headline rail */
.rail { background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1); overflow: hidden; }
.rail + .rail { margin-top: 16px; }
.rail h2 {
  font-size: 15.5px; text-transform: uppercase; letter-spacing: .06em;
  padding: 12px 16px; background: var(--black-2); color: #fff;
}
.rail ul { list-style: none; margin: 0; padding: 0; }
.rail li { border-bottom: 1px solid var(--gray-rule); }
.rail li:last-child { border-bottom: 0; }
.rail a { display: block; padding: 12px 16px; text-decoration: none; font-size: 14.5px;
  font-weight: 550; border-left: 3px solid transparent; transition: background .12s; }
.rail a:hover { background: var(--paper-2); border-left-color: var(--fsn-red); }
.rail li[data-team] a:hover { border-left-color: var(--team); }
.rail .meta { display: block; font-size: 12px; color: var(--gray-text); font-weight: 400;
  margin-top: 4px; line-height: 1.4; }
.rail .card-pad { padding: 16px; }

/* ------------------------------------------------------------- DataTable
   The spreadsheet tell was zebra striping plus a hard black header row.
   Both are gone: hairline rules, a paper header that sticks, tabular mono
   figures, and a team-coloured leading edge on hover. */
:is(.card, .card-pad, details.collapse > .inner, .grid > div) > table.data {
  display: block; overflow-x: auto; max-width: 100%;
}
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--gray-rule); border-radius: var(--radius);
  background: var(--paper); box-shadow: var(--sh-1); }
table.data { font-size: 14.5px; min-width: 100%; }
table.data caption { text-align: left; padding: 12px 16px; font-size: 12.5px;
  color: var(--gray-text); }
table.data th, table.data td { text-align: left; border-bottom: 1px solid var(--gray-rule);
  white-space: nowrap;
}
table.data thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--paper-2); color: var(--ink-2);
  border-bottom: 2px solid var(--ink);
  font: 700 10.5px/1.3 var(--sans); letter-spacing: .11em; text-transform: uppercase;
  padding-top: 10px; padding-bottom: 10px;
}
table.data tbody tr { transition: background .1s ease; }
table.data tbody tr:hover { background: var(--team-wash, var(--paper-2)); }
table.data tbody tr:last-child td { border-bottom: 0; }
/* First cell carries row identity — and, where the row belongs to a
   franchise, its colour. This is the single change that stops a long table
   reading as a block of cells. */
table.data tbody td:first-child { font-weight: 600; box-shadow: inset 3px 0 0 transparent; }
table.data tbody tr[data-team] td:first-child { box-shadow: inset 3px 0 0 var(--team); }
table.data tbody td:first-child { padding-left: 15px; }
/* crest in the identity cell, for tables that ask for one */
table.data td .crest { vertical-align: -7px; margin-right: 9px; }
/* numerals in the body are mono for column alignment; the header label above
   them is a label, not a figure, so it stays in the UI face. */
table.data td.num { text-align: right;
  font-variant-numeric: tabular-nums; font-family: var(--mono); font-size: 13.5px; }
table.data th.num { text-align: right;
  font-variant-numeric: tabular-nums; font-family: var(--sans); font-size: 13.5px; }
table.data td.wrap-cell { white-space: normal; min-width: 260px; font-family: var(--serif);
  font-size: 15px; line-height: 1.45; }
table.data a { text-decoration: none; font-weight: 550; }
table.data a:hover { text-decoration: underline; text-underline-offset: 2px; }
table.data tr.interruption td {
  background: var(--paper-2); color: var(--gray-text); font-weight: 600;
  text-align: center; letter-spacing: .06em; font-size: 11.5px;
  text-transform: uppercase; padding: 7px 14px;
}
table.data tr.is-hidden { display: none; }
/* rank column */
table.data td.rank { font-family: var(--mono); color: var(--gray-text); font-size: 12.5px;
  width: 1%; }
/* medal rows */
table.data tr.gold  td:first-child { box-shadow: inset 3px 0 0 var(--gold); }
table.data tr.silver td:first-child { box-shadow: inset 3px 0 0 var(--silver); }
table.data tr.bronze td:first-child { box-shadow: inset 3px 0 0 var(--bronze); }
/* compact density */
table.data.compact th, table.data.compact td { padding: 6px 12px; font-size: 13.5px; }

th[aria-sort] { cursor: pointer; user-select: none; }
th[aria-sort]:hover { background: var(--paper-3); }
th[aria-sort]::after { content: " ↕"; opacity: .35; font-size: 11px; }
th[aria-sort="ascending"]::after { content: " ↑"; opacity: 1; color: var(--fsn-red); }
th[aria-sort="descending"]::after { content: " ↓"; opacity: 1; color: var(--fsn-red); }

/* table toolbar — filter + count + density, injected by fsn.js */
.tbl-tools {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 10px;
}
.tbl-tools .fld { position: relative; flex: 0 1 300px; min-width: 190px; }
.tbl-tools .fld::before {
  content: "⌕"; position: absolute; left: 11px; top: 50%; transform: translateY(-52%);
  color: var(--gray-text); font-size: 16px; pointer-events: none;
}
.tbl-tools input {
  width: 100%; padding: 8px 11px 8px 30px; font: 400 13.5px var(--sans);
  border: 1px solid var(--gray-rule-2); border-radius: var(--radius-sm);
  background: var(--paper); color: var(--ink);
}
.tbl-tools input:focus { border-color: var(--fsn-red); outline: none;
  box-shadow: 0 0 0 3px var(--fsn-red-wash); }
.tbl-tools .n { font: 600 12px var(--mono); color: var(--gray-text);
  font-variant-numeric: tabular-nums; }
.tbl-tools .grow { margin-left: auto; }
.tbl-tools button {
  border: 1px solid var(--gray-rule-2); background: var(--paper); color: var(--ink-2);
  border-radius: var(--radius-sm); padding: 7px 11px; cursor: pointer;
  font: 600 11.5px var(--sans); letter-spacing: .06em; text-transform: uppercase;
}
.tbl-tools button:hover { background: var(--paper-2); }
.tbl-tools button[aria-pressed="true"] { background: var(--ink); color: #fff;
  border-color: var(--ink); }
.tbl-empty { padding: 22px 16px; text-align: center; color: var(--gray-text);
  font-size: 14px; }

/* BarRow */
.barrow { display: grid;
  grid-template-columns: minmax(0, var(--barlabel, 138px)) minmax(0, 1fr) auto;
  gap: 11px; align-items: center; padding: 4px 0; }
.barrow .k { font-size: 13.5px; color: var(--ink-2); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.barrow .k a { text-decoration: none; font-weight: 550; }
.barrow .k a:hover { text-decoration: underline; }
.barrow .bar { min-width: 0; }
.barrow .v { font-size: 13px; font-variant-numeric: tabular-nums; font-weight: 600;
  text-align: right; min-width: 3.6em; font-family: var(--mono); }
.barrow.is-self .k { font-weight: 700; color: var(--ink); }
.bar-track { background: var(--track); border-radius: var(--radius-sm); height: 14px; }
.bar-fill { fill: var(--series-1); }
.bar-fill-2 { fill: var(--series-2); }
/* A card scoped to one franchise paints its own bars; a comparison row that
   names a different GM wins over it, so "against the field" becomes a
   league-coloured ranking rather than fourteen identical crimson bars. */
.card[data-team] .bar-fill, .story[data-team] .bar-fill,
.bars-teamed .bar-fill { fill: var(--team); }
.barrow[data-team] .bar-fill { fill: var(--team); }

/* StarStrip / trophy timeline */
.stars { font-size: 15px; letter-spacing: .12em; color: var(--gold); white-space: nowrap; }
.trophy-timeline { display: flex; gap: 4px; flex-wrap: wrap; }
.trophy-timeline .yr {
  display: inline-flex; flex-direction: column; align-items: center; gap: 2px;
  min-width: 32px; font-size: 15px; line-height: 1.2; padding: 5px 2px 4px;
  border-radius: var(--radius-sm); background: var(--paper-2);
}
.trophy-timeline .yr small { font-size: 9.5px; color: var(--gray-text);
  letter-spacing: .03em; font-family: var(--mono); }
.trophy-timeline .yr.none { opacity: .42; background: transparent; }

/* Badge */
.badges { display: flex; flex-wrap: wrap; gap: 7px; }
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--gray-rule-2); border-radius: 999px;
  padding: 4px 12px 4px 9px; font-size: 12.5px; background: var(--paper);
  font-weight: 550;
}
.badge .em { font-size: 14px; }
.pill {
  display: inline-block; padding: 3px 9px; border-radius: 999px;
  font: 700 10.5px/1.6 var(--sans); letter-spacing: .08em; text-transform: uppercase;
  white-space: nowrap;
}
.pill.ok { background: var(--good-wash); color: var(--good); }
.pill.act { background: var(--bad-wash); color: var(--bad); }
.pill.warn { background: var(--warn-wash); color: var(--warn); }
.pill.neutral { background: var(--paper-3); color: var(--ink-2); }
.pill.team { background: var(--team-wash); color: var(--team); }

/* CollapsibleSection */
details.collapse {
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); margin: 14px 0; box-shadow: var(--sh-1);
}
details.collapse > summary {
  cursor: pointer; padding: 13px 16px; list-style: none;
  font-family: var(--cond); font-weight: 700; font-size: 16px;
  text-transform: uppercase; letter-spacing: .06em;
  display: flex; align-items: center; gap: 10px;
}
details.collapse > summary::-webkit-details-marker { display: none; }
details.collapse > summary:hover { background: var(--paper-2); border-radius: var(--radius); }
details.collapse > summary::after {
  content: "▸"; margin-left: auto; color: var(--fsn-red); transition: transform .15s;
}
details.collapse[open] > summary::after { transform: rotate(90deg); }
details.collapse[open] > summary { border-bottom: 1px solid var(--gray-rule);
  border-radius: var(--radius) var(--radius) 0 0; }
details.collapse > summary .count {
  background: var(--paper-3); color: var(--ink-2); border-radius: 999px;
  padding: 2px 10px; font: 600 11px/1.6 var(--sans); letter-spacing: .04em;
}
details.collapse > .inner { padding: 16px; }

/* lore / pull quotes */
.lore {
  border-left: 4px solid var(--team, var(--fsn-red));
  background: var(--team-wash, var(--fsn-red-wash));
  padding: 14px 18px; border-radius: 0 var(--radius) var(--radius) 0;
  font-family: var(--serif); font-size: 17px; line-height: 1.55; color: var(--ink-2);
}
.callout {
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-left: 4px solid var(--fsn-red); border-radius: var(--radius);
  padding: 14px 16px; margin: 14px 0; font-size: 14.5px; box-shadow: var(--sh-1);
}
.callout b { display: block; font-family: var(--cond); text-transform: uppercase;
  letter-spacing: .06em; font-size: 15px; margin-bottom: 4px; }

.prose { font-family: var(--serif); font-size: 17.5px; line-height: 1.62;
  color: var(--ink-2); max-width: 68ch; }
.prose strong, .prose b { color: var(--ink); }

.meta-line { font-size: 12.5px; color: var(--gray-text); }
/* The label column is clamped, never `max-content`: a definition list is fed
   user-written terms, and one long one (a 70-character citation, on FBAHL)
   consumed all 1192px and collapsed every value to a 0px column. */
.kv { display: grid;
  grid-template-columns: minmax(0, clamp(120px, 30%, 260px)) minmax(0, 1fr);
  gap: 6px 16px; font-size: 14px; }
.kv dt { color: var(--gray-text); overflow-wrap: anywhere; }
.kv dd { margin: 0; min-width: 0; overflow-wrap: anywhere; font-weight: 550; }

/* search island */
.search { position: relative; }
.search input {
  width: 100%; padding: 10px 13px; font-size: 14.5px; border-radius: var(--radius-sm);
  border: 1px solid var(--gray-rule-2); background: #fff; color: var(--ink);
}
.search input:focus { border-color: var(--fsn-red); outline: none;
  box-shadow: 0 0 0 3px var(--fsn-red-wash); }
.search-results {
  position: absolute; z-index: 50; left: 0; right: 0; top: calc(100% + 5px);
  background: #fff; border: 1px solid var(--gray-rule-2);
  border-radius: var(--radius); max-height: 340px; overflow-y: auto;
  box-shadow: var(--sh-3);
}
.search-results a { display: block; padding: 10px 13px; text-decoration: none;
  border-bottom: 1px solid var(--gray-rule); font-size: 14px; }
.search-results a:last-child { border-bottom: 0; }
.search-results a:hover, .search-results a.active { background: var(--paper-2); }
.search-results .k {
  float: right; font: 700 9.5px/1.6 var(--sans); letter-spacing: .1em;
  text-transform: uppercase; color: var(--fsn-red);
}
.search-results .x { display: block; font-size: 12px; color: var(--gray-text); }
.search-empty { padding: 13px; font-size: 13px; color: var(--gray-text); }

/* filters row */
.filters { display: flex; flex-wrap: wrap; gap: 9px; align-items: center;
  margin-bottom: 14px; padding: 12px 14px; background: var(--paper);
  border: 1px solid var(--gray-rule); border-radius: var(--radius);
  box-shadow: var(--sh-1); }
.filters select, .filters input[type="search"],
.pb-selects select {
  padding: 8px 11px; font-size: 13.5px; border: 1px solid var(--gray-rule-2);
  border-radius: var(--radius-sm); background: #fff; color: var(--ink);
}
.filters select:focus, .filters input:focus, .pb-selects select:focus {
  border-color: var(--fsn-red);
  outline: none; box-shadow: 0 0 0 3px var(--fsn-red-wash); }
.filters .count { margin-left: auto; font-size: 12.5px; color: var(--gray-text);
  font-family: var(--mono); }
.filters button {
  border: 1px solid var(--gray-rule-2); background: var(--paper); color: var(--ink-2);
  border-radius: var(--radius-sm); padding: 8px 12px; cursor: pointer;
  font: 600 12px var(--sans);
}
.filters button:hover { background: var(--paper-2); }

/* charts */
figure.chart { margin: 0; }
figure.chart figcaption { font-size: 12.5px; color: var(--gray-text); margin-top: 10px; }
.chart-note { font-size: 12px; color: var(--gray-text); }
.chart-title { font: 700 12px/1.3 var(--sans); letter-spacing: .11em;
  text-transform: uppercase; color: var(--ink-2); margin-bottom: 12px; }
.legend { display: flex; gap: 15px; flex-wrap: wrap; font-size: 12.5px;
  color: var(--ink-2); margin-bottom: 10px; }
.legend .sw { display: inline-block; width: 11px; height: 11px; border-radius: 2px;
  margin-right: 6px; vertical-align: -1px; }
.axis text { font: 11px var(--mono); fill: var(--gray-text); }
.axis line, .axis path { stroke: var(--grid); }
.gridline { stroke: var(--grid); stroke-width: 1; }
[data-tip] { cursor: default; }
svg .bar-fill { transition: opacity .12s; }
svg:hover .bar-fill { opacity: .82; }
svg .bar-fill:hover { opacity: 1; }

/* chart tooltip */
.viz-tip {
  position: fixed; z-index: 90; pointer-events: none; opacity: 0;
  background: var(--black); color: #fff; padding: 7px 10px;
  border-radius: var(--radius-sm); font: 500 12.5px var(--sans);
  box-shadow: var(--sh-3); transition: opacity .1s; max-width: 260px;
}
.viz-tip b { font-family: var(--mono); font-weight: 700; }
.viz-tip.on { opacity: 1; }

/* heat cell — for season/GM matrices */
.heat { font-variant-numeric: tabular-nums; text-align: center;
  font-family: var(--mono); font-size: 12.5px; }

/* trade ledger rows */
.deal { border-bottom: 1px solid var(--gray-rule); padding: 15px 0; }
.deal:last-child { border-bottom: 0; }
.deal .when { font-size: 11.5px; color: var(--gray-text); letter-spacing: .07em;
  text-transform: uppercase; font-family: var(--mono); }
.deal .sides { display: grid; gap: 12px; grid-template-columns: 1fr 1fr; margin-top: 8px;
  position: relative; }
.deal .side {
  background: var(--paper-2); border-radius: var(--radius); padding: 12px 14px;
  border-left: 3px solid var(--team, var(--gray-rule-2));
}
.deal .side b { font-family: var(--cond); font-size: 16.5px; text-transform: uppercase;
  letter-spacing: .03em; display: block; }
.deal .side .gets { font-size: 13.5px; color: var(--ink-2); margin-top: 5px;
  line-height: 1.5; }
.deal .side .gets a { text-decoration: none; border-bottom: 1px solid var(--gray-rule-2); }
.deal .side .gets a:hover { border-bottom-color: var(--fsn-red); }

/* footer */
footer.site {
  background: var(--black); color: #90959d; margin-top: 48px;
  padding: 34px 0 28px; font-size: 13.5px;
  border-top: 3px solid var(--fsn-red);
}
footer.site .cols { display: grid; gap: 26px;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
footer.site h3 {
  color: #fff; font-size: 13px; letter-spacing: .13em; text-transform: uppercase;
  margin-bottom: 11px;
}
footer.site ul { list-style: none; margin: 0; padding: 0; }
footer.site li { margin-bottom: 6px; }
footer.site a { color: #90959d; text-decoration: none; }
footer.site a:hover { color: #fff; text-decoration: underline; }
footer.site .colophon {
  border-top: 1px solid #26272b; margin-top: 26px; padding-top: 18px;
  font-size: 12.5px; color: #6e727a;
}

/* ============================================================== responsive */
@media (max-width: 1060px) {
  .layout-rail { grid-template-columns: minmax(0, 1fr); }
  .cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .cols-2, .cols-3, .cols-4 { grid-template-columns: minmax(0, 1fr); }
  .deal .sides { grid-template-columns: minmax(0, 1fr); }
  .masthead .est { display: none; }
  main { padding: 18px 0 34px; }

  .navtoggle {
    display: inline-flex; align-items: center; gap: 8px; background: none;
    border: 0; color: #fff; padding: 12px 0; cursor: pointer;
    font-family: var(--cond); font-weight: 700; font-size: 15px;
    letter-spacing: .08em; text-transform: uppercase;
  }
  .mainnav .wrap { flex-direction: column; align-items: stretch; }
  .mainnav .navlinks { display: none; flex-direction: column; padding-bottom: 8px; }
  .mainnav .navlinks.open { display: flex; }
  .mainnav a { padding: 12px 0; border-bottom: 1px solid #26272b; margin: 0; }
  .mainnav a[aria-current="page"] { border-bottom-color: var(--fsn-red); }

  /* tables become cards — and stop being tables, so the table layout
     algorithm can no longer impose a min-content width wider than the screen */
  table.data.stackable { display: block; width: 100%; min-width: 0; max-width: 100%; }
  table.data.stackable tbody, table.data.stackable caption { display: block; }
  table.data.stackable thead { display: none; }
  table.data.stackable tbody tr {
    display: block; padding: 12px 14px; margin-bottom: 10px;
    background: var(--paper); border: 1px solid var(--gray-rule);
    border-left: 4px solid var(--team, var(--gray-rule-2));
    border-radius: var(--radius); box-shadow: var(--sh-1);
  }
  table.data.stackable tbody tr:hover { background: var(--paper); }
  table.data.stackable td {
    display: flex; gap: 12px; border: 0; padding: 3px 0; white-space: normal;
    text-align: left; min-width: 0; overflow-wrap: anywhere; box-shadow: none !important;
  }
  table.data.stackable td:first-child {
    font-family: var(--cond); font-weight: 700; font-size: 18px;
    text-transform: uppercase; padding-bottom: 8px; margin-bottom: 6px;
    border-bottom: 1px solid var(--gray-rule);
  }
  table.data.stackable td:first-child::before { display: none; }
  table.data.stackable td::before {
    content: attr(data-label); flex: 0 0 42%; color: var(--gray-text);
    font: 700 10px/1.7 var(--sans); letter-spacing: .09em; text-transform: uppercase;
  }
  table.data.stackable td.num { text-align: left; justify-content: flex-start; }
  table.data.stackable tr.interruption { text-align: center; }
  .table-scroll:has(> table.data.stackable) { border: 0; background: none;
    box-shadow: none; overflow: visible; }

  .barrow { grid-template-columns: 100px 1fr auto; }
  .page-head h1 { font-size: clamp(30px, 9vw, 40px); }
  .franchise-hero .inner { padding: 20px; gap: 16px; }
  .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tile .value { font-size: 32px; }
}

@media print {
  .mainnav, .ticker, .utility, footer.site, .filters, .tbl-tools { display: none; }
  body { background: #fff; }
  .card, .tile, .table-scroll { box-shadow: none; }
  details.collapse > .inner { display: block !important; }
}

@media (forced-colors: active) {
  .crest { forced-color-adjust: none; border: 1px solid CanvasText; }
  .tile::before, .section-head h2::before { forced-color-adjust: none; }
}

/* ------------------------------------------------------------ notes board
   Seven identical bordered callouts in a grid read as spreadsheet cells.
   Same seven notes, set as newspaper briefs: balanced columns, a rule over
   each item, and no phantom empty cells on the last row. */
.notes-board {
  columns: 3; column-gap: 30px; margin-bottom: 6px;
}
.note-item {
  break-inside: avoid; -webkit-column-break-inside: avoid;
  border-top: 2px solid var(--ink);
}
.note-item .t {
  display: block; font: 700 10.5px/1.4 var(--sans); letter-spacing: .14em;
  text-transform: uppercase; color: var(--fsn-red); margin-bottom: 5px;
}
.note-item p { margin: 0; font-family: var(--serif);
  line-height: 1.45; color: var(--ink-2); }
.note-item p a { font-weight: 600; }
@media (max-width: 1060px) { .notes-board { columns: 2; } }
@media (max-width: 620px)  { .notes-board { columns: 1; } }

/* a bar inside a table cell */
table.data td.barcell { min-width: 120px; padding-top: 0; padding-bottom: 0; }
table.data td.barcell .bar { display: block; width: 110px; }
@media (max-width: 900px) {
  table.data.stackable td.barcell .bar { width: 100%; }
}

/* identity cell: crest and name on one line */
table.data td:first-child {
  display: table-cell;
}
table.data[data-crests] tbody td:first-child > .crest { float: left; margin-top: 1px; }
table.data[data-crests] tbody td:first-child {
  overflow: hidden; min-width: 170px;
}
/* a row that belongs to a club paints its own bars */
table.data tbody tr[data-team] .bar-fill { fill: var(--team); }

/* ------------------------------------------------------------- key dates */
.datestrip {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.date-card {
  display: block; text-decoration: none; background: var(--paper);
  border: 1px solid var(--gray-rule); border-radius: var(--radius);
  border-top: 3px solid var(--fsn-red);
  box-shadow: var(--sh-1); transition: box-shadow .15s, transform .15s;
}
.date-card:hover { box-shadow: var(--sh-2); transform: translateY(-2px); }
.date-card .d {
  display: block; font: 700 11px/1 var(--mono); letter-spacing: .1em;
  text-transform: uppercase; color: var(--fsn-red); margin-bottom: 7px;
}
.date-card .l { display: block; font-family: var(--cond); font-weight: 700;
  font-size: 18px; line-height: 1.15; text-transform: uppercase; }
.date-card .x { display: block; margin-top: 6px; font-size: 12.5px;
  color: var(--gray-text); line-height: 1.4; }

/* The home hero stretches to match the headline rail beside it, so the
   two columns end level instead of leaving a slab of empty page. */
.layout-rail > .rail-main { display: flex; flex-direction: column; }
.layout-rail > .rail-main > .hero { flex: 1 1 auto; }
.layout-rail > .rail-main > .section-head:first-of-type { margin-top: 26px; }
@media (max-width: 1060px) { .layout-rail > .rail-main > .hero { min-height: 300px; } }

/* --------------------------------------------------------- trading matrix
   Magnitude, so: one hue, light to dark, six steps. The count is printed in
   every cell, so the colour is reinforcement rather than the only encoding. */
.matrix-card { padding: 0; overflow: hidden; }
.matrix-legend {
  display: flex; align-items: center; gap: 4px; padding: 14px 16px 12px;
  font: 500 11.5px var(--mono); color: var(--gray-text);
}
.matrix-legend .sw { width: 26px; height: 11px; border-radius: 2px; }
.matrix-legend span:first-child { margin-right: 6px; }
.matrix-legend span:last-child { margin-left: 6px; }
.matrix-scroll { border: 0; border-radius: 0; box-shadow: none; }
table.matrix { font-size: 13px; }
table.matrix th { padding: 0; border: 0; }
table.matrix td { padding: 0; }   /* the cell border is set with the fill below */
table.matrix thead th {
  background: var(--paper); border-bottom: 2px solid var(--ink);
  vertical-align: bottom; height: 92px; padding: 0 0 8px;
  font: 700 11px/1 var(--sans); letter-spacing: .04em; text-transform: none;
}
table.matrix thead th .vlabel {
  display: inline-block; writing-mode: vertical-rl; transform: rotate(180deg);
  white-space: nowrap; color: var(--team, var(--ink-2));
}
table.matrix thead th:first-child {
  width: 172px; min-width: 172px;
  writing-mode: horizontal-tb; text-align: left; padding-left: 16px;
  letter-spacing: .11em; text-transform: uppercase; color: var(--gray-text);
}
table.matrix tbody th[scope="row"] {
  width: 172px; min-width: 172px;
  background: var(--paper); text-align: left; padding: 0 14px 0 16px;
  border-right: 2px solid var(--gray-rule); position: sticky; left: 0; z-index: 1;
  box-shadow: inset 3px 0 0 var(--team);
}
table.matrix tbody th a {
  display: flex; align-items: center; gap: 8px; text-decoration: none;
  font: 700 13px var(--sans); padding: 3px 0; white-space: nowrap;
}
table.matrix tbody th a:hover span:last-child { text-decoration: underline; }
table.matrix tbody tr:hover th[scope="row"] { background: var(--team-wash); }
table.matrix td {
  width: auto; min-width: 42px; height: 38px; text-align: center; font-family: var(--mono);
  font-size: 12.5px; font-variant-numeric: tabular-nums;
  border: 1px solid var(--paper);            /* 2px surface gap between fills */
}
table.matrix td.self { background: repeating-linear-gradient(45deg,
  var(--paper-2) 0 4px, var(--paper) 4px 8px); }
table.matrix td.tot { font-weight: 700; background: var(--paper-2);
  border-left: 2px solid var(--gray-rule); }
table.matrix thead th.tot { writing-mode: horizontal-tb; text-align: center;
  letter-spacing: .08em; text-transform: uppercase; color: var(--gray-text); }
table.matrix td.s0 { background: var(--paper); color: transparent; }
table.matrix td.s1 { background: var(--seq-1); color: #16324e; }
table.matrix td.s2 { background: var(--seq-2); color: #16324e; }
table.matrix td.s3 { background: var(--seq-3); color: #0f2a44; }
table.matrix td.s4 { background: var(--seq-4); color: #fff; }
table.matrix td.s5 { background: var(--seq-5); color: #fff; }
table.matrix td.s6 { background: var(--seq-6); color: #fff; }
.matrix-legend .s1{background:var(--seq-1)} .matrix-legend .s2{background:var(--seq-2)}
.matrix-legend .s3{background:var(--seq-3)} .matrix-legend .s4{background:var(--seq-4)}
.matrix-legend .s5{background:var(--seq-5)} .matrix-legend .s6{background:var(--seq-6)}
table.matrix td:hover { outline: 2px solid var(--ink); outline-offset: -2px; }

/* a crest on each side of a deal card */
.deal .side .club { display: flex; align-items: center; gap: 9px; }
.deal .side .club b { display: block; }

/* former GMs sit after the active clubs, marked rather than hidden */
table.matrix tbody tr.former th[scope="row"] { color: var(--gray-text); }
table.matrix tbody tr.former th a em {
  font: 600 9.5px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase;
  color: var(--gray-text); font-style: normal; margin-left: 2px;
}
table.matrix tbody tr:first-of-type.former th,
table.matrix tbody tr.former:not(.former + tr.former) td,
table.matrix tbody tr.former:not(.former + tr.former) th { border-top: 2px solid var(--gray-rule-2); }
table.matrix th.former .vlabel, table.matrix td.former { opacity: .92; }
table.matrix thead th.former { border-left: 1px solid var(--gray-rule); }

/* inline club chip inside a table cell */
table.data td a.tm { font-weight: 600; }
table.data td a.tm::before { width: 8px; height: 8px; }

/* the GM wall's card grid: keep the club name from forcing the page wide */
@media (max-width: 900px) {
  .gmchip { min-width: 0; }
  .gmchip b, .gmchip .team { overflow: hidden; text-overflow: ellipsis; }
  .card > div[style*="display:flex"] { min-width: 0; flex-wrap: wrap; }
  .trophy-timeline .yr { min-width: 28px; }
}

@media (max-width: 900px) {
  /* a stacked cell that lists several clubs must be allowed to wrap */
  table.data.stackable td { flex-wrap: wrap; }
  table.data.stackable td > * { min-width: 0; max-width: 100%; }
  .tm { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
}

/* ==========================================================================
   v3 — page-level information architecture
   ========================================================================== */

:root { --nav-h: 50px; }

/* ------------------------------------------------------------ section tabs */
.pagetabs {
  position: sticky; top: var(--nav-h); z-index: 35;
  display: flex; align-items: stretch; gap: 10px;
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1);
  margin: 0 0 22px; padding: 0 6px 0 0;
}
.pagetabs-strip {
  display: flex; align-items: stretch; gap: 0; flex: 1 1 auto;
  overflow-x: auto; scrollbar-width: none; scroll-behavior: smooth;
  -webkit-mask-image: none; mask-image: none;
}
.pagetabs-strip::-webkit-scrollbar { display: none; }
/* A strip only a little too wide wraps instead of scrolling: every tab stays
   visible, which is worth one extra row. Wider than that and it keeps
   scrolling, with the arrows below doing the work. */
.pagetabs.is-wrapped { align-items: flex-start; }
.pagetabs.is-wrapped .pagetabs-strip {
  flex-wrap: wrap; overflow-x: visible;
  -webkit-mask-image: none; mask-image: none;
}
.pagetabs-arrow {
  flex: 0 0 auto; align-self: stretch; width: 26px; padding: 0;
  border: 0; background: var(--paper); color: var(--gray-text);
  font: 400 19px/1 var(--sans); cursor: pointer;
  transition: color .12s, background .12s;
}
.pagetabs-arrow:hover:not(:disabled) { color: var(--ink); background: var(--paper-2); }
/* Dim, don't remove: an arrow that disappears at the end of the strip changes
   the strip's width mid-scroll, and the tab you just revealed slides back out. */
.pagetabs-arrow:disabled { opacity: .22; pointer-events: none; }
.pagetabs:not(.is-scrollable) .pagetabs-arrow,
.pagetabs.is-wrapped .pagetabs-arrow { display: none; }
.pagetabs-arrow--prev { border-right: 1px solid var(--gray-rule); }
.pagetabs-arrow--next { border-left: 1px solid var(--gray-rule); }

/* On a 375px phone the strip was 148px wide — one and a half tabs — because a
   26px arrow, another 26px arrow and a 93px "Show all" button were taking two
   thirds of the bar before the tabs got a look in. The strip takes its own
   row; the arrows go (a 335px strip scrolls fine by touch) and Show all sits
   under it. This is also what made the layout gate report the selected tab as
   off screen: with 148px to work in, returning to Overview left it scrolled
   past. */
@media (max-width: 620px) {
  .pagetabs { flex-wrap: wrap; row-gap: 4px; }
  .pagetabs .pagetabs-strip { flex: 1 1 100%; order: 1; }
  .pagetabs .pagetabs-arrow { display: none; }
  .pagetabs .pagetabs-all { order: 2; margin-left: auto; }
}
.pagetab {
  flex: 0 0 auto; border: 0; background: none; cursor: pointer;
  padding: 13px 16px 11px; color: var(--gray-text);
  font-family: var(--cond); font-weight: 700; font-size: 14.5px;
  letter-spacing: .07em; text-transform: uppercase; white-space: nowrap;
  border-bottom: 3px solid transparent; transition: color .12s, background .12s;
}
.pagetab:hover { color: var(--ink); background: var(--paper-2); }
.pagetab[aria-selected="true"] {
  color: var(--ink); border-bottom-color: var(--fsn-red);
}
html[data-team] .pagetab[aria-selected="true"] { border-bottom-color: var(--team); }
.pagetabs-all {
  flex: 0 0 auto; align-self: center; margin-left: 4px;
  border: 1px solid var(--gray-rule-2); background: var(--paper);
  color: var(--ink-2); border-radius: 999px; padding: 6px 13px; cursor: pointer;
  font: 600 11px var(--sans); letter-spacing: .08em; text-transform: uppercase;
}
.pagetabs-all:hover { background: var(--paper-2); }
.pagetabs.is-all .pagetabs-all { background: var(--ink); color: #fff; border-color: var(--ink); }
.pagetabs.is-all .pagetab[aria-selected="false"] { opacity: .55; }

.pane { scroll-margin-top: calc(var(--nav-h) + 70px); }
/* when every pane is open, each one needs its own separation again */
.pagetabs.is-all ~ .pane + .pane > .section-head:first-child { margin-top: 34px; }

/* ---------------------------------------------------------- master–detail */
.md-body {
  display: grid; gap: 18px; grid-template-columns: minmax(280px, 360px) minmax(0, 1fr);
  align-items: start;
}
.md-list {
  position: sticky; top: calc(var(--nav-h) + 64px);
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1); overflow: hidden;
}
.md-list-inner {
  max-height: min(70vh, 720px); overflow-y: auto; overscroll-behavior: contain;
}
.md-item {
  display: block; width: 100%; text-align: left; cursor: pointer;
  border: 0; border-bottom: 1px solid var(--gray-rule);
  border-left: 3px solid transparent;
  background: var(--paper); padding: 10px 13px 11px; font: inherit;
  transition: background .1s;
}
.md-item:last-child { border-bottom: 0; }
.md-item:hover { background: var(--team-wash, var(--paper-2)); }
.md-item .t {
  display: block; font: 700 14px/1.25 var(--sans); color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.md-item .m {
  display: block; margin-top: 3px; font: 400 11.5px/1.35 var(--mono);
  color: var(--gray-text); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap;
}
.md-item .g {
  display: inline-block; margin-top: 6px; padding: 1px 8px; border-radius: 999px;
  background: var(--team-wash, var(--paper-3)); color: var(--team, var(--ink-2));
  font: 700 10px/1.7 var(--sans); letter-spacing: .07em; text-transform: uppercase;
}
.md-item.is-current {
  background: var(--team-wash, var(--paper-2));
  border-left-color: var(--team, var(--fsn-red));
}
.md-item.is-current .t { color: var(--ink); }
.md-item[hidden] { display: none; }
.md-empty { padding: 20px 14px; text-align: center; font-size: 13.5px;
  color: var(--gray-text); }

.md-detail {
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1); padding: 18px;
  min-height: 240px;
}
.md-detail > [data-row] { display: none; }
.md-detail > [data-row].is-current { display: block; }
.md-detail .md-back { display: none; }
/* the row's own disclosure chrome is redundant once it is the whole panel */
.md-detail [data-md-chrome="off"] > summary { display: none; }
.md-detail details.collapse { border: 0; box-shadow: none; margin: 0; }
.md-detail details.collapse > .inner { padding: 0; }
.md-detail .deal { border-bottom: 0; padding-top: 0; }

@media (max-width: 900px) {
  .md-body { grid-template-columns: minmax(0, 1fr); }
  .md-list { position: static; }
  .md-list-inner { max-height: 58vh; }
  /* the detail slides over the list rather than pushing it off the screen */
  .md-detail {
    position: fixed; inset: 0; z-index: 60; border-radius: 0; border: 0;
    overflow-y: auto; padding: 14px 16px 28px;
    transform: translateX(100%); transition: transform .2s ease;
  }
  .is-md.has-selection .md-detail { transform: translateX(0); }
  .md-detail .md-back {
    display: inline-flex; align-items: center; gap: 6px; position: sticky; top: 0;
    margin: -14px -16px 12px; width: calc(100% + 32px);
    background: var(--paper); border: 0; border-bottom: 1px solid var(--gray-rule);
    padding: 13px 16px; cursor: pointer; color: var(--ink);
    font: 700 12px var(--sans); letter-spacing: .07em; text-transform: uppercase;
  }
}

/* --------------------------------------------------------- windowed table */
.table-scroll.is-windowed {
  max-height: min(66vh, 680px); overflow-y: auto; overscroll-behavior: contain;
}
.table-scroll.is-windowed table.data thead th { top: 0; }
.table-scroll.is-windowed::after {
  content: ""; position: sticky; bottom: 0; display: block; height: 22px;
  margin-top: -22px; pointer-events: none;
  background: linear-gradient(to top, var(--paper), transparent);
}

@media print {
  .pagetabs { display: none; }
  .pane { display: block !important; }
  .md-body { display: block; }
  .md-list { display: none; }
  .md-detail > [data-row] { display: block !important; }
  .table-scroll.is-windowed { max-height: none; overflow: visible; }
}

/* the tab strip scrolls when it overflows — say so with a fade, and keep the
   Show-all control clear of the last tab. The default (no mask) is declared on
   .pagetabs-strip itself; only the is-scrollable states belong here. */
.pagetabs.is-scrollable .pagetabs-strip {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
          mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
}
.pagetabs.is-scrollable.at-end .pagetabs-strip {
  -webkit-mask-image: none; mask-image: none;
}

/* ------------------------------------------------------------- rule lists
   The workbook shipped every rule bullet as a one-cell table. They are a
   list, and they read like one. */
ul.rules { list-style: none; margin: 10px 0 18px; padding: 0; }
ul.rules > li.rule {
  position: relative; padding: 7px 0 7px 22px; font-size: 15.5px;
  line-height: 1.55; color: var(--ink-2);
  border-bottom: 1px solid var(--gray-rule);
}
ul.rules > li.rule:last-child { border-bottom: 0; }
ul.rules > li.rule::before {
  content: ""; position: absolute; left: 4px; top: 15px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--fsn-red);
}
ul.rules > li.rule .k {
  display: block; font: 700 10.5px/1.5 var(--sans); letter-spacing: .11em;
  text-transform: uppercase; color: var(--gray-text);
}
ul.rules > li.rule a { font-weight: 600; }

/* the Rule Book: each tabbed section is its own sheet of paper */
main .layout-rail > div > .pane {
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1); padding: 4px 18px 18px;
}
main .layout-rail > div > .pane > .section-head:first-child { margin-top: 18px; }

/* ==========================================================================
   v4 — one bar of chrome, one page banner

   Eight bands above the first line of content became four. The utility bar,
   the masthead and the nav were three dark strips carrying four pieces of
   the same standing metadata; they are one bar now. The page title and the
   KPI tiles were two bands with no hierarchy between them; they are one
   banner, with the headline number beside the title.
   ========================================================================== */

/* One row, and the whole bar is what sticks.

   The previous version split this into an identity row and a sticky nav row.
   That was a bug, not a layout: `position: sticky` is scoped to the element's
   own parent box, and the nav's parent was a 99px header — so the nav stuck
   for 99px and then scrolled away with it. It appeared on load and vanished on
   the first scroll. The nine rooms fit beside the wordmark because the
   wordmark gives way first: strapline, then season line, then wordmark. */
.topbar {
  position: sticky; top: 0; z-index: 50;
  background: var(--black);
  background-image: radial-gradient(120% 240% at 6% -60%, #24272e 0%, transparent 60%);
  border-bottom: 3px solid var(--fsn-red);
}
.topbar > .wrap {
  display: flex; align-items: stretch; gap: 0;
  min-height: 58px;
}
.topbar .logo { align-self: center; padding: 6px 0; flex: 0 0 auto; }
.topbar .logo-mark { font-size: 23px; padding: 6px 9px 4px; }
.topbar .logo-word { padding-left: 10px; }
.topbar .logo-word span { font-size: 10.5px; color: #82868e; }
.topbar .mainnav {
  position: static; background: none; border: 0;
  display: flex; align-items: stretch; flex: 1 1 auto; min-width: 0;
  margin-left: 18px;
}
.topbar .mainnav a { min-height: 58px; }
.topbar .navlinks {
  display: flex; align-items: stretch; overflow-x: auto; scrollbar-width: none;
}
.topbar .navlinks::-webkit-scrollbar { display: none; }
.topbar .mainnav a {
  display: flex; align-items: center;
  border-bottom: 3px solid transparent; margin-bottom: -3px;
  font-size: 14px;
}
/* The season line is chrome, and the bar's width is not free: the wrap caps
   at 1280, so every pixel it takes comes out of the nine rooms. Retired from
   the bar — the season is on the home hero, the ticker and the footer. */
.topbar-meta { display: none; }

/* ------------------------------------------------------------ page banner */
.page-banner {
  display: grid; gap: 0 30px; align-items: end;
  grid-template-columns: minmax(0, 1fr) auto;
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1);
  padding: 16px 22px 0; margin-bottom: 18px;
  border-top: 3px solid var(--fsn-red);
}
html[data-team] .page-banner { border-top-color: var(--team); }
.page-banner .pb-main { min-width: 0; padding-bottom: 15px; }
.page-banner .kicker {
  display: inline-flex; align-items: center; gap: 8px;
  font: 700 10.5px/1 var(--sans); letter-spacing: .16em; text-transform: uppercase;
  color: var(--fsn-red); margin-bottom: 8px;
}
.page-banner .kicker::before {
  content: ""; width: 20px; height: 3px; background: currentColor; display: block;
}
/* v5.6: the masthead was eating 280-360px before a reader reached anything
   they came for — on Keeper Central it was more than a third of the first
   screen. Same information, roughly two thirds the height. */
.page-banner h1 {
  font-size: clamp(27px, 3.4vw, 38px); text-transform: uppercase;
  letter-spacing: -.005em;
}
.page-banner .standfirst {
  margin: 7px 0 0; font-family: var(--serif); font-size: 15.5px; line-height: 1.42;
  color: var(--ink-2); max-width: 66ch;
}

/* the headline number, beside the title rather than in a box of its own */
.page-banner .pb-hero {
  text-align: right; padding-bottom: 15px; flex: 0 0 auto;
  border-left: 1px solid var(--gray-rule); padding-left: 26px;
}
.page-banner .pb-hero .v {
  display: block; font-family: var(--cond); font-weight: 700;
  font-size: clamp(34px, 4vw, 46px); line-height: .95;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.page-banner .pb-hero .v.sm { font-size: clamp(24px, 2.8vw, 32px); }
.page-banner .pb-hero .l {
  display: block; margin-top: 6px;
  font: 700 10.5px/1.3 var(--sans); letter-spacing: .14em;
  text-transform: uppercase; color: var(--fsn-red);
}
.page-banner .pb-hero .c {
  display: block; margin-top: 4px; font-size: 12px; color: var(--gray-text);
  max-width: 22ch; margin-left: auto;
}

/* the rest: one quiet row, hairline-separated, no boxes and no red bars */
.page-banner .pb-stats {
  grid-column: 1 / -1; display: flex; flex-wrap: wrap;
  border-top: 1px solid var(--gray-rule);
  margin: 0 -24px; padding: 0 24px;
}
.page-banner .pb-stats .s {
  flex: 1 1 0; min-width: 128px; padding: 12px 18px 14px 0;
  border-right: 1px solid var(--gray-rule); margin-right: 18px;
}
.page-banner .pb-stats .s:last-child { border-right: 0; margin-right: 0; }
.page-banner .pb-stats .v {
  display: block; font-family: var(--cond); font-weight: 700; font-size: 26px;
  line-height: 1; font-variant-numeric: tabular-nums;
}
.page-banner .pb-stats .l {
  display: block; margin-top: 5px;
  font: 700 9.5px/1.3 var(--sans); letter-spacing: .13em;
  text-transform: uppercase; color: var(--gray-text);
}
.page-banner .pb-stats .c {
  display: block; margin-top: 3px; font-size: 11.5px; color: var(--gray-text);
  line-height: 1.35;
}

@media (max-width: 900px) {
  .page-banner { grid-template-columns: minmax(0, 1fr); padding: 18px 18px 0; }
  .page-banner .pb-hero {
    text-align: left; border-left: 0; padding-left: 0; padding-bottom: 16px;
    border-top: 1px solid var(--gray-rule); padding-top: 14px;
  }
  .page-banner .pb-hero .c { margin-left: 0; }
  .page-banner .pb-stats { }
  .page-banner .pb-stats .s { flex: 1 1 40%; }
}
@media (max-width: 900px) {
  .topbar > .wrap { min-height: 0; padding-top: 8px; padding-bottom: 8px;
    flex-wrap: wrap; }
  .topbar .logo { padding: 0; }
  .topbar-meta { display: none; }
  .topbar .mainnav { flex: 1 1 100%; margin-left: 0; }
  .topbar .navlinks { display: none; flex-direction: column; width: 100%;
    padding: 4px 0 8px; }
  .topbar .navlinks.open { display: flex; }
  .topbar .mainnav a { min-height: 0; }
  .topbar .navtoggle { margin-left: auto; align-self: center; }
  .page-banner h1 { font-size: clamp(24px, 7vw, 31px); }
}

/* The identity row trims in this order as it narrows: the strapline first,
   then the season line, then the wordmark. The nav has its own row and no
   longer competes for any of it. */
.topbar .wrap { gap: 16px; }
.topbar .logo-word { justify-content: center; white-space: nowrap; }
.topbar .logo-word b { font-size: 12px; letter-spacing: .10em; }
.topbar .mainnav a { letter-spacing: .06em; }

/* The bar has to hold a mark, a wordmark, nine rooms and the season line
   inside 1240px. Measured: the rooms need 840px at this padding, and the
   wordmark gives up its strapline at 1400 and itself at 1120 to pay for it. */
.topbar .mainnav a { padding: 0 9px; }
.topbar .navitem:first-child > a { padding-left: 0; }
.topbar-meta { font-size: 10px; letter-spacing: .1em; }

/* 760–1100px: the wordmark is already gone; tighten the nav so nine items
   still fit rather than clipping the last one. */
@media (max-width: 1100px) {
  .topbar .mainnav a { padding: 0 8px; font-size: 13.5px; }
  /* the disclosure is a real box now, so it costs real width — 25px × seven
     rooms. Trim it here rather than let the strip start scrolling 100px
     earlier than it used to. */
  .topbar .navmore { width: 13px; padding-right: 4px; }
  .topbar .mainnav .navitem.has-menu > a { padding-right: 2px; }
}

/* THE FADE MUST NOT BE A MASK ON .navlinks.
   This was the nav bug, and it had nothing to do with the JS. A non-none
   mask-image makes an element a containing block for its fixed-position
   descendants (CSS Masking §, same clause as transform and filter). The
   dropdown panels are `position: fixed` and live inside .navlinks — so the
   moment the mask applied they stopped being laid out against the viewport
   and started being laid out, and then CLIPPED, by .navlinks, which is an
   `overflow-x: auto` scroll container 58px tall.
   The mask was written as `:not(:hover)` → none, meaning it switched ON at
   the exact moment a pointer entered the bar: hover a room, and the panel
   that opened was clipped out of existence by the element you were hovering.
   The panel reported display:block, visibility:visible, opacity:1 and a
   620x569 rect the whole time, which is why three rounds of checks that
   asked "is it open?" all passed while nothing was ever on screen.
   The fade is now a sibling overlay on .mainnav — .mainnav is position:
   relative, which is a containing block for ABSOLUTE descendants only, so
   the fixed panels stay bound to the viewport. */
.topbar .mainnav { position: relative; }
/* (v5.9: the 901-1000px band rule that used to draw this fade is retired —
   the fade is now driven by measurement, at the foot of this file, because
   the band where the strip overflows moved when the search button arrived
   and will move again with any font substitution.) */
/* Trim order as the bar narrows: the strapline first, then the season line,
   then the wordmark. The nav never scrolls on a desktop. */
@media (max-width: 1400px) { .topbar .logo-word span { display: none; } }
@media (max-width: 1220px) { .topbar .logo-word { display: none; } }
@media (max-width: 1220px) { .topbar .mainnav { margin-left: 14px; } }
/* (the :hover mask override that went with the deleted mask is gone too — it
   was the trigger, not the cure) */

/* On a phone the stat row wraps, and a per-item right border then draws a
   stray rule at the edge of each row. Use a hairline grid instead. */
@media (max-width: 900px) {
  .page-banner .pb-stats {
    display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
    background: var(--gray-rule); border-top: 1px solid var(--gray-rule);
    margin: 0 -18px; padding: 0;
  }
  .page-banner .pb-stats .s {
    background: var(--paper); border: 0; margin: 0;
    padding: 12px 18px 14px; min-width: 0;
  }
  .page-banner .pb-stats .s:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

/* ==========================================================================
   v5 — the cockpit

   Every card is a clone of markup already in one of the page's sections,
   trimmed to a few rows, with a link through to the whole thing.
   ========================================================================== */
/* THE COCKPIT BOARD — one authoritative block. Everything that sizes or aligns
   the board lives here; add to this rule, never append a second `.glance {}`.
   (Responsive overrides stay in their media queries at the foot of the file.)
   - 12 columns: cards carry `--span` / `data-role`, so the track count must be
     fixed. `auto-fit` computed a different count per container width, which is
     what stranded cards in half-empty rows.
   - `dense`: lets a 4-span card backfill a gap a 12-span card left behind.
   - `stretch`: cards in a row share a height, so their footer links line up.
     A chart card that cannot fill a two-row slot is demoted to a one-row
     `feature` in fsn.js rather than stretching around its SVG. */
.glance {
  display: grid;
  gap: 13px;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-auto-flow: dense;
  align-items: stretch;
}
.glance-card {
  --span: 1;
  grid-column: span var(--span);
  display: flex; flex-direction: column;
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1); overflow: hidden;
}
.glance-card > h3 { letter-spacing: .11em; text-transform: uppercase; border-bottom: 1px solid var(--gray-rule);
  color: var(--ink);
}
.glance-body { flex: 1 1 auto; min-width: 0; }
.glance-body > .table-scroll {
  border: 0; border-radius: 0; box-shadow: none; max-height: none;
}
.glance-body table.data thead th { position: static; }
.glance-body table.data tbody tr:last-child td { border-bottom: 0; }
.glance-body .glance-cards { display: grid; gap: 1px; background: var(--gray-rule); }
.glance-body .glance-cards > * {
  border: 0; border-radius: 0; box-shadow: none; margin: 0;
}
.glance-body > .card, .glance-body > .lore, .glance-body > .callout {
  border: 0; border-radius: 0; box-shadow: none; margin: 0;
}

/* a master–detail excerpt: the newest few entries, straight into the list */
.glance-list { display: block; }
.glance-item {
  display: block; text-decoration: none;
  border-bottom: 1px solid var(--gray-rule);
  border-left: 3px solid var(--team, transparent);
  transition: background .1s;
}
.glance-item:last-child { border-bottom: 0; }
.glance-item:hover { background: var(--team-wash, var(--paper-2)); }
.glance-item .t {
  display: block; font: 650 13.5px/1.3 var(--sans); color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.glance-item .m {
  display: block; margin-top: 2px; font: 400 11.5px/1.35 var(--mono);
  color: var(--gray-text);
}

.glance-more {
  display: block; border-top: 1px solid var(--gray-rule);
  background: var(--paper-2); text-decoration: none;
  font: 700 11px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase;
  color: var(--fsn-red);
}
html[data-team] .glance-more { color: var(--team); }

@media (max-width: 900px) {
  .glance { grid-template-columns: minmax(0, 1fr); }
  .glance-card { --span: 1 !important; }
}
@media print { .glance { display: none; } }

/* a verbatim-quote column has a 260px floor for readability in a full-width
   table; inside a glance card it has to give */
.glance-body table.data td.wrap-cell { min-width: 150px; font-size: 13px; }

/* A chart card would otherwise pin its small SVG to the top of a card
   stretched to a tall neighbour. Let it fill and centre instead. */
.glance-body { display: flex; flex-direction: column; }
.glance-body > * { min-width: 0; }
.glance-chart { flex: 1 1 auto; display: flex; align-items: center; }
.glance-chart > svg, .glance-chart figure { width: 100%; }
.glance-chart svg { width: 100%; height: auto; max-height: 260px; }
.glance-bars { flex: 1 1 auto; }
.glance-body > .table-scroll, .glance-body .glance-list { flex: 0 0 auto; }

/* A glance table is narrower than the one it excerpts, so it scrolls. Say so
   with a fade rather than letting a column look chopped off. */
.glance-card { position: relative; }
.glance-body > .table-scroll.is-cut { position: relative; }
/* player names in a glance bar chart need more room than club names do */
.glance-body .glance-bars .barrow { --barlabel: 168px; }

/* ==========================================================================
   v5.1 — cockpit polish

   The v5 overview had the right bones — cloned excerpts, one card per
   section — but every card carried the same weight and the same chrome.
   This layer gives the cockpit hierarchy and life:
     · the Overview head reads as a broadcast segment, not a generic h2
     · cards lift on hover; the footer link travels
     · chart cards run wide by default (the JS now spans them 2) and drop
       their inherited caption chrome
     · table excerpts breathe — row hover, no dead last-row rule
     · panes fade in when a tab lands
   All of it degrades to the v5 look with styles off or motion reduced.
   ========================================================================== */

/* --- the segment head ---------------------------------------------------- */
.section-head#overview { border-bottom-color: var(--fsn-red); }
html[data-team] .section-head#overview { border-bottom-color: var(--team); }
.section-head#overview h2 { display: flex; align-items: center; gap: 10px; }
.section-head#overview h2::before {
  content: ""; width: 11px; height: 11px; border-radius: 2px;
  background: var(--fsn-red); box-shadow: 0 0 0 3px var(--fsn-red-wash);
}
html[data-team] .section-head#overview h2::before {
  background: var(--team); box-shadow: 0 0 0 3px var(--team-wash);
}
.section-head#overview .sub {
  font-family: var(--mono); letter-spacing: .04em;
}

/* --- the cards ----------------------------------------------------------- */

.glance-card {
  transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease;
}
.glance-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--sh-2);
  border-color: var(--gray-rule-2);
}
/* every card header carries its accent, not only on franchise pages */
.glance-card > h3 {
  box-shadow: inset 3px 0 0 var(--fsn-red);
  background: linear-gradient(to bottom, var(--paper), var(--paper-2));
}
html[data-team] .glance-card > h3 { box-shadow: inset 3px 0 0 var(--team); }

/* --- footer link: the arrow travels -------------------------------------- */
.glance-more {
  position: relative;
  transition: background .14s ease, padding-left .14s ease, color .14s ease;
}
.glance-card:hover .glance-more { background: var(--paper-3); }
.glance-more:hover {
  background: var(--fsn-red-wash) !important;
}
html[data-team] .glance-more:hover { background: var(--team-wash) !important; }

/* --- table excerpts ------------------------------------------------------ */
.glance-body table.data tbody tr { transition: background .1s; }
.glance-body table.data tbody tr:hover { background: var(--team-wash, var(--paper-2)); }
.glance-body table.data thead th { letter-spacing: .08em;
  background: var(--paper); border-bottom: 1px solid var(--gray-rule-2);
}

/* --- chart cards --------------------------------------------------------- */
/* An SVG cannot grow past its own aspect ratio, so a chart card stretched to a
   tall neighbour puts white space inside its own border.
   `align-self: start` was the first answer to that, and it was the wrong one
   twice over. It moved the white space OUT of the card and onto the page — a
   216px hole under the Trade Desk chart, which is what a reader actually
   notices — and, because the card then measured exactly as tall as its
   content, it silently defeated the demotion pass in fsn.js, whose whole job
   is to catch a lead card that cannot fill its slot (it tests
   height − natural > 80, and start-alignment guarantees that difference is 0).
   The card stretches again. Slack inside a border reads as padding; the same
   slack outside one reads as a broken page. The real cure is the row itself
   adding up, which is authored per board. */
.glance-card--chart .glance-body { justify-content: center; }
.glance-body .glance-chart svg {
  display: block; width: 100%; height: auto; max-height: 230px;
}

/* --- bar excerpts get the same air as the chart -------------------------- */

/* --- master–detail excerpt: metadata aligns as a column ------------------ */
.glance-item .m { font-variant-numeric: tabular-nums; }

/* --- panes land softly --------------------------------------------------- */
@keyframes fsn-pane-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
.pane:not([hidden]) { animation: fsn-pane-in .18s ease-out; }
.pagetabs.is-all ~ .pane:not([hidden]) { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .glance-card, .glance-more { transition: none; }
  .glance-card:hover { transform: none; }
  .pane:not([hidden]) { animation: none; }
}

/* ==========================================================================
   v5.2 — composition, not tiles

   The audit finding: every container on the site was repeat(auto-fit, 1fr) —
   the overview, the tiles, the notes, the room cards. Equal tracks make
   every fact the same size, and a page of same-sized facts has no story.
   This layer replaces the equal-track overview with a 12-column cockpit
   (lead instrument + rails + gauges) and gives the home page's uniform
   walls a first-among-equals in each module.
   ========================================================================== */

/* --- the cockpit board ----------------------------------------------------
   The 12-column track and its gap now live in the single `.glance` rule in the
   v5 block above. Only the per-role spans belong here. */
.glance-card[data-role]        { grid-column: span 4; }
.glance-card[data-role="half"] { grid-column: span 6; }
.glance-card[data-role="wide"] { grid-column: span 12; }
.glance-card[data-role="rail"] { grid-column: span 4; }
/* One row, not two. The two-row span assumed a lead card would have a stack of
   two rail cards beside it; no board on the site is built that way, so what it
   actually did was open a phantom half-height row that only the lead reached
   into — leaving its single row-mate 88px short on the FBAHL board and
   216px short on the Trade Desk. A lead is now simply the wide, heavier card
   in an ordinary row, and every card in that row ends level. */
.glance-card[data-role="lead"] {
  grid-column: span 8;
  border-color: var(--gray-rule-2);
  box-shadow: var(--sh-2);
}
.glance-card[data-role="lead"] > h3 { letter-spacing: .12em;
}
.glance-card[data-role="lead"] .glance-chart svg { max-height: 320px; }
.glance-card[data-role="lead"] .glance-body table.data { font-size: 14px; }
/* rails run tighter than gauges — they sit beside the lead */
.glance-card[data-role="rail"] .glance-body table.data { font-size: 13px; }

@media (max-width: 1060px) {
  .glance-card[data-role]        { grid-column: span 6; }
  .glance-card[data-role="lead"],
  .glance-card[data-role="wide"] { grid-column: span 12; }
  .glance-card[data-role="lead"] { grid-row: auto; }
}
@media (max-width: 900px) {
  .glance-card[data-role] { grid-column: span 12; }
}

/* --- home: State of the League / The Format — one dial leads --------------
   The span is the emphasis, but it costs a slot: `auto-fit` computes the
   column count from container width, so five tiles with a 2-span first need
   six columns and only get five in the 884px rail — stranding the last tile
   on a row of its own. Pin the track count to (tiles + 1) per module rather
   than letting the container decide. */
.tiles--state  { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.tiles--format { grid-template-columns: repeat(7, minmax(0, 1fr)); }
.tiles--state .tile:first-child,
.tiles--format .tile:first-child {
  grid-column: span 2;
  border-top: 3px solid var(--fsn-red);
  background: linear-gradient(to bottom, var(--paper), var(--fsn-red-wash));
}
.tiles--state .tile:first-child .label,
.tiles--format .tile:first-child .label { color: var(--fsn-red); }

/* --- home: Around the league — the champ leads the board ------------------ */
.notes--featured {
  columns: auto; column-gap: normal;
  display: grid; gap: 0 30px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-flow: dense;
}
.notes--featured .note-item:first-child {
  grid-row: span 2;
  border-top: 3px solid var(--fsn-red);
  padding-right: 18px;
}
.notes--featured .note-item:first-child .t { font-size: 12px; }
.notes--featured .note-item:first-child p { line-height: 1.5; color: var(--ink);
}
/* Seven briefs in three columns with the lead one spanning two rows is eight
   cells in a nine-cell grid, and the ninth showed as a hole under the
   right-hand column — the one ragged corner on the page. The closing brief
   takes the width instead. At two columns the eight cells already divide
   exactly, so the rule is scoped above that breakpoint. */
@media (min-width: 1061px) {
  .notes--featured .note-item:last-child { grid-column: span 2; }
}
@media (max-width: 1060px) {
  .notes--featured { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .notes--featured { grid-template-columns: minmax(0, 1fr); }
  .notes--featured .note-item:first-child { grid-row: auto; }
}

/* --- home: Where to go — three wings, not nine tiles ---------------------- */
.rooms .story:nth-child(-n+3)              { border-top: 3px solid var(--fsn-red); }
.rooms .story:nth-child(n+4):nth-child(-n+6) { border-top: 3px solid var(--series-2); }
.rooms .story:nth-child(n+7)               { border-top: 3px solid var(--gray-rule-2); }
.rooms .story:nth-child(n+4):nth-child(-n+6) .eyebrow { color: var(--series-2); }
.rooms .story:nth-child(n+7) .eyebrow      { color: var(--gray-text); }

/* --- home: Key dates — the next deadline leads ---------------------------- */
.dates--next .date-card:first-child {
  grid-column: span 2;
  background: linear-gradient(to bottom, var(--paper), var(--fsn-red-wash));
}
.dates--next .date-card:first-child .d { font-size: 17px; font-weight: 700; }
@media (max-width: 620px) {
  .tiles--state .tile:first-child,
  .tiles--format .tile:first-child,
  .dates--next .date-card:first-child { grid-column: 1 / -1; }
}

/* ==========================================================================
   v5.3 — density and one voice

   Three fixes from the review of the live boards:
   1. Leads that could not fill their slot now either bring more data
      (row budgets by role, set in JS) or give the slot back (the JS
      demotes an underfilled lead to this single-row "feature").
   2. A sitewide density pass — the broadcast look survives at ~80% of the
      old padding, and the ledger, standings and boards show visibly more
      per screen.
   3. One voice across pages: every table, tile, card footer and section
      head uses the same rhythm, so no page reads as its own site.
   ========================================================================== */

/* --- the demoted lead ----------------------------------------------------- */
.glance-card[data-role="feature"] {
  grid-column: span 8;
  border-color: var(--gray-rule-2); box-shadow: var(--sh-2);
}
.glance-card[data-role="feature"] > h3 {
  font-size: 14px; padding: 12px 16px 11px; letter-spacing: .12em;
}
@media (max-width: 1060px) { .glance-card[data-role="feature"] { grid-column: span 12; } }

/* --- density: the cockpit ------------------------------------------------- */
.glance-card > h3 { padding: 10px 14px 9px; font-size: 12.5px; }
.glance-card[data-role="lead"] > h3 { font-size: 14px; padding: 12px 16px 11px; }
.glance-body table.data { font-size: 13px; }
.glance-body table.data th, .glance-body table.data td { padding: 6px 12px; }
.glance-body table.data thead th { font-size: 10.5px; }
.glance-card[data-role="rail"] .glance-body table.data th,
.glance-card[data-role="rail"] .glance-body table.data td { padding: 5px 10px; }
.glance-body .glance-bars { padding: 10px 14px; }
.glance-body .glance-bars .barrow { padding: 3px 0; }
.glance-body .glance-chart { padding: 12px 14px 6px; }
.glance-body > .card { padding: 11px 14px; }
.glance-item { padding: 7px 14px 8px; }
.glance-more { padding: 8px 14px; font-size: 10.5px; }
.glance-more:hover { padding-left: 21px; }

/* --- density: everywhere -------------------------------------------------- */
.section-head { margin: 28px 0 12px; padding-bottom: 7px; }
.pane > .section-head:first-child { margin-top: 2px; }
table.data th, table.data td { padding: 8px 12px; }
.card-pad { padding: 15px; }
.tiles { gap: 10px; }
.tile { padding: 12px 14px 13px; }
.tile .value { font-size: 38px; }
.tiles--state .tile:first-child .value,
.tiles--format .tile:first-child .value { font-size: 50px; }
.datestrip { gap: 10px; }
.date-card { padding: 11px 13px 12px; }
.note-item { padding: 9px 0 12px; }
.note-item p { font-size: 14.5px; }
.notes--featured .note-item:first-child p { font-size: 17.5px; }

/* --- one voice ------------------------------------------------------------ */
/* every excerpt table hides its sort affordances and tool row, not just some */
.glance-body .tbl-tools { display: none; }
/* kv blocks cloned into cards keep the card's rhythm */
.glance-body dl.kv { margin: 0; }
/* the overview head matches the banner's kicker rhythm on every page */
.section-head#overview h2 { letter-spacing: .02em; }
.section-head#overview .sub { font-size: 11.5px; }

@media (max-width: 900px) {
  .glance { gap: 11px; }
  table.data th, table.data td { padding: 7px 10px; }
}


/* ==========================================================================
   v5.4 — a table that scrolls says so

   Silent clipping was the worst of the three options in the audit: a card
   that cut `LAST TITLE` off its All-Time Standings looked identical to one
   that never had the column, and `COMPLETED` was sliced mid-word on the
   Draft. The site already had this idiom — the page-tab strip fades at the
   edge it can scroll toward — so tables use it too, plus a line that names
   how many columns are still out there. Nothing is removed; it just stops
   pretending the table ended at the card wall.
   ========================================================================== */
.table-scroll.is-cut:not(.at-end):not(.at-start) {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 26px,
                        #000 calc(100% - 30px), transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 26px,
                        #000 calc(100% - 30px), transparent 100%);
}
.table-scroll.is-cut.at-start:not(.at-end) {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 30px), transparent);
          mask-image: linear-gradient(to right, #000 calc(100% - 30px), transparent);
}
.table-scroll.is-cut.at-end:not(.at-start) {
  -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 26px), transparent);
          mask-image: linear-gradient(to left, #000 calc(100% - 26px), transparent);
}
.table-scroll.is-cut:focus-visible { outline: 2px solid var(--fsn-red); outline-offset: 2px; }

.scroll-note {
  margin: 5px 2px 0; text-align: right;
  font: 600 10.5px/1.4 var(--sans); letter-spacing: .09em;
  text-transform: uppercase; color: var(--gray-text);
  transition: opacity .18s;
}
.scroll-note[hidden] { display: none; }
.glance-body .scroll-note { margin: 4px 12px 8px; font-size: 10px; }

/* --------------------------------------------------------- the keeper board
   Fourteen clubs, one collapsible depth chart each, header row first. The
   slot marker is a chip rather than a bare suffix so `· P` stops reading as
   punctuation, and the golden prospect gets the one colour it has earned. */
.keeper-boards { display: grid; gap: 8px; }
.keeper-club > summary .count { margin-left: auto; }
.keeper-club .meta-line { margin: 10px 2px; }
.keeper-club table.data td { white-space: nowrap; }
.keeper-club table.data td:empty::after { content: "·"; color: var(--gray-rule-2); }
.slot {
  display: inline-block; vertical-align: 1px;
  font: 700 9.5px/1.5 var(--sans); letter-spacing: .09em;
  color: var(--gray-text); border: 1px solid var(--gray-rule-2);
  border-radius: 3px; padding: 0 4px;
}
.slot:not(:empty) { text-transform: uppercase; }
td:has(> .slot) { color: var(--ink-2); }

/* ------------------------------------------------------------ award tables
   K-6: the Trophy Case is four sibling tables with identical columns, and each
   was sizing its own — `AWARD` 192px in one, 169px in the next — so the column
   rules zig-zagged down the page. A shared colgroup and a fixed layout make
   the four read as one board. */
table.awards { table-layout: fixed; }
table.awards td, table.awards th { white-space: normal; }
table.awards td:first-child, table.awards th:first-child { white-space: nowrap; }

/* K-6, part two: these sub-headings were the only headings on the site with no
   marker of any kind, so they read as sitting *below* the table header row
   they introduce. Same red mark as every other heading, one size down. */
h3.sub-head {
  display: flex; align-items: baseline; gap: 9px;
  margin: 26px 0 10px; padding-bottom: 6px;
  border-bottom: 1px solid var(--gray-rule-2);
  font: 700 13px/1.2 var(--cond); letter-spacing: .1em; text-transform: uppercase;
}
h3.sub-head::before {
  content: ""; width: 7px; height: 7px; background: var(--fsn-red);
  border-radius: 2px; flex: 0 0 auto; align-self: center;
}
html[data-team] h3.sub-head::before { background: var(--team); }

/* ---------------------------------------------------------------- GM cards
   L-7: the badge block between the bars and the closing line runs from 0 to
   109px depending on how much hardware a GM owns, so three cards side by side
   put their last paragraph at three different heights. The cards are already
   equal height — push the paragraph to the floor of each. */
.gm-card { display: flex; flex-direction: column; }
.gm-summary {
  margin: 14px 0 0; margin-top: auto; padding-top: 10px;
  border-top: 1px solid var(--gray-rule);
  font-size: 13.5px; color: var(--ink-2);
}

/* ================================================================ styleguide
   before/after comparison, for proposals that need a human decision */
.ba { margin: 22px 0 30px; }
.ba-grid { display: grid; gap: 16px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 900px) { .ba-grid { grid-template-columns: minmax(0, 1fr); } }
.ba-cell {
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1); padding: 14px 16px 16px;
  min-width: 0;
}
.ba-tag {
  display: inline-block; margin-bottom: 10px; padding: 3px 9px; border-radius: 999px;
  font: 700 10px/1.4 var(--sans); letter-spacing: .1em; text-transform: uppercase;
}
.ba-tag--before { background: var(--paper-3); color: var(--gray-text); }
.ba-tag--after  { background: var(--fsn-red-wash); color: var(--fsn-red-ink); }
.swatches { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); margin: 12px 0 6px; }
.swatch { min-width: 0; }
.swatch .chip { display: block; height: 42px; border-radius: var(--radius-sm); border: 1px solid var(--gray-rule); }
.swatch code { display: block; font-size: 12px; margin-top: 5px; }
.idot { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 7px; vertical-align: 0; }
.hero-stat { font: 700 15px/1.4 var(--sans); margin: 4px 0 10px; color: var(--ink); }
.hero-stat b { font-family: var(--cond); font-size: 30px; vertical-align: -3px; margin: 0 3px; }
.demo-matrix td { border: 1px solid var(--paper); text-align: center; font-family: var(--mono); font-size: 12px; }

/* ==========================================================================
   v5.5 — the nav menus
   --------------------------------------------------------------------------
   Nine rooms across the top, each one now a doorway rather than a single
   destination. The panels are positioned by JS in the fixed layer, for two
   reasons that CSS alone cannot solve: the strip is a scroll container at
   narrow widths (a positioned child would be clipped by it), and the wide
   club panel has to be pushed back inside the viewport when its room sits
   near the right edge. Without JS every top-level link still works and no
   panel ever opens — that is the fallback, not a broken state.
   ========================================================================== */

.navitem { display: flex; align-items: stretch; position: relative; }
.topbar .mainnav .navitem.has-menu > a { padding-right: 3px; }

.navcaret {
  width: 0; height: 0; margin-top: 1px;
  border-left: 3px solid transparent; border-right: 3px solid transparent;
  border-top: 3.5px solid currentColor; opacity: .5;
  transition: transform .14s ease, opacity .14s ease;
}

/* The disclosure. It is a box of its own beside the link — NOT an overlay on
   it. The two halves highlight together so the room still reads as one thing,
   but the word is always a link and the arrow is always the menu. */
.navmore {
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto; width: 18px; padding: 0 7px 0 0;
  background: none; border: 0; cursor: pointer; color: #dfe1e5;
  border-bottom: 3px solid transparent; margin-bottom: -3px;
  transition: background .12s ease, color .12s ease;
}
.navitem.has-menu:hover > a, .navitem.has-menu:hover > .navmore,
.navitem.is-open > a, .navitem.is-open > .navmore {
  background: #23262b; color: #fff;
}
.navitem.is-open .navcaret { transform: rotate(180deg); opacity: 1; }
.navmore:focus-visible { outline: 2px solid var(--fsn-red); outline-offset: -3px; }

/* ------------------------------------------------------------- the panels */
.navmenu {
  position: fixed; z-index: 60; min-width: 246px; max-width: 320px;
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--gray-rule); border-top: 3px solid var(--fsn-red);
  border-radius: 0 0 var(--radius) var(--radius);
  box-shadow: var(--sh-3);
  padding: 7px; display: none;
}
.navitem.is-open > .navmenu { display: block; animation: fsn-menu-in .13s ease-out; }
@keyframes fsn-menu-in { from { opacity: 0; transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) { .navitem.is-open > .navmenu { animation: none; } }

/* The strip's links are condensed, uppercase and tracked out — inside a panel
   that is a paragraph of small print, so every one of those inherited
   properties has to be put back. */
.navmenu a {
  font-family: var(--sans); font-weight: 400; letter-spacing: 0;
  text-transform: none; white-space: normal;
  border-bottom: 0; margin: 0; padding: 0; background: none;
  transition: background .1s ease;
}
/* .topbar .mainnav a is a flex container (it centres the label against a
   62px bar). Inside a panel the link is a two-line block, so the display has
   to be reasserted at equal-or-greater specificity — a bare `display:block`
   loses, and the label and its note end up side by side. */
.topbar .navmenu > a, .navmenu > a {
  display: block; padding: 6px 10px 7px; border-radius: var(--radius-sm);
  text-decoration: none; color: var(--ink); min-height: 0;
}
.navmenu > a b { display: block; font: 600 14px/1.3 var(--sans); color: var(--ink); }
.navmenu > a span {
  display: block; color: var(--gray-text); font-size: 12px; margin-top: 0;
  font-weight: 400;
}
.navmenu > a:hover, .navmenu > a:focus-visible {
  background: var(--fsn-red-wash); color: var(--ink);
}
.navmenu > a:hover b { color: var(--fsn-red-ink); }

/* ------------------------------------------------- the club panel (GMs) */
.navmenu--wide { min-width: 560px; max-width: 620px; padding: 12px 12px 8px; }
.navcols { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 18px; }
.navcol-h {
  display: block; font: 700 10.5px/1 var(--cond); letter-spacing: .13em;
  text-transform: uppercase; color: var(--gray-text);
  padding: 2px 8px 7px; border-bottom: 1px solid var(--gray-rule); margin-bottom: 5px;
}
.navcol-h i { font-style: normal; color: var(--gray-rule-2); letter-spacing: .06em; }

.topbar .navclub, .navclub {
  display: flex; align-items: center; gap: 9px;
  padding: 4px 8px; border-radius: var(--radius-sm);
  text-decoration: none; color: var(--ink);
}
.navclub .crest { --size: 24px; }
.navclub .nc-t { min-width: 0; }
.navclub b {
  display: block; font: 650 13.5px/1.3 var(--sans); color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.navclub .nc-t > span {
  display: block; color: var(--gray-text); font: 400 11.5px/1.3 var(--sans);
}
.navclub:hover, .navclub:focus-visible { background: var(--club-wash); }
.navclub:hover b { color: var(--club); }

.navmenu-foot {
  display: flex; align-items: center; gap: 10px 16px; flex-wrap: nowrap;
  margin-top: 8px; padding: 9px 8px 2px; border-top: 1px solid var(--gray-rule);
}
.navmenu .nf-lead {
  font: 700 11.5px/1 var(--cond); letter-spacing: .11em; text-transform: uppercase;
  color: var(--fsn-red-ink); text-decoration: none; white-space: nowrap;
}
.navmenu .nf-lead:hover { text-decoration: underline; }
.nf-legacy {
  display: flex; align-items: center; gap: 4px 10px; flex-wrap: wrap;
  margin-left: auto; min-width: 0;
}
.nf-legacy i {
  font: 700 9.5px/1 var(--cond); letter-spacing: .12em; text-transform: uppercase;
  font-style: normal; color: var(--gray-rule-2);
}
.navmenu .nf-legacy a {
  color: var(--gray-text); text-decoration: none;
  font: 400 12px/1 var(--sans); white-space: nowrap;
}
.navmenu .nf-legacy a:hover { color: var(--fsn-red-ink); text-decoration: underline; }

/* The strip stays a scroll container — nine rooms do not fit between 760 and
   1000px and scrolling is the honest answer there. The panels are unaffected:
   a position:fixed box is laid out against the viewport, so an ancestor's
   overflow never clips it. (.topbar is sticky, and sticky does not create a
   containing block for fixed descendants — if that ever changes to transform
   or filter, these panels will start disappearing.) */

/* ------------------------------------------------------ phones: accordion */
@media (max-width: 900px) {
  .topbar .navlinks { display: none; }
  .topbar .navlinks.open { display: flex; }
  .navitem { display: block; }
  .topbar .mainnav .navitem > a {
    display: flex; padding: 11px 0; border-bottom: 1px solid #26272b;
  }
  /* stacked rows: here the row is full width and the label sits at the left,
     so a 44px tap target pinned to the right edge overlaps nothing. */
  /* .topbar-scoped, because the 1100px trim above is .topbar .navmore and
     would otherwise leave the phone with a 13px tap target. */
  .topbar .navmore, .navmore {
    position: absolute; right: 0; top: 0; height: 45px; width: 44px;
    padding: 0; justify-content: center;
  }
  .navitem.has-menu:hover > a { background: none; }
  .navcaret { border-left-width: 4px; border-right-width: 4px;
              border-top-width: 5px; opacity: .75; }
  .navmenu {
    position: static; display: none; min-width: 0; max-width: none;
    border: 0; border-radius: 0; box-shadow: none;
    background: #111318; padding: 4px 0 8px;
  }
  .navitem.is-open > .navmenu { display: block; animation: none; }
  .navmenu > a, .navclub { color: #dfe2e6; padding: 9px 12px; }
  .navmenu > a b { color: #fff; font-size: 13.5px; }
  .navmenu > a span, .navclub .nc-t > span { color: #8a9098; }
  .navmenu > a:hover, .navmenu > a:focus-visible,
  .navclub:hover, .navclub:focus-visible { background: #1b1e24; }
  .navmenu > a:hover b { color: #fff; }
  .navclub b { color: #fff; }
  .navclub:hover b { color: #fff; }
  .navmenu--wide { padding: 4px 0 8px; }
  .navcols { grid-template-columns: 1fr; gap: 0; }
  .navcol-h { color: #8a9098; border-bottom-color: #26272b; padding: 10px 12px 6px; }
  .navmenu-foot { border-top-color: #26272b; padding: 10px 12px 2px; }
  .nf-lead { color: #ff7d90; }
  .nf-legacy a { color: #8a9098; }
}

/* ==========================================================================
   v5.5 — the keeper archive
   --------------------------------------------------------------------------
   Everything on /keepers/history/. The magnitude marks all use the one
   sequential ramp already in the tokens (--seq-1..6, one hue, monotone
   lightness) rather than the workbook's block glyphs, which carried no scale
   and could not be read at a glance. Green/red appears in exactly one place —
   the season board, where the top three and the bottom three of a ranked
   column genuinely are good news and bad news.
   ========================================================================== */

/* the inline magnitude bar: track, fill, and the number that must survive
   whether or not the bar renders */
.kh-bar { display: inline-flex; align-items: center; gap: 8px; }
.kh-bar svg { display: block; flex: 0 0 auto; }
.kh-bar b { font: 600 12.5px/1 var(--mono); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.kh-first { color: var(--gray-text); font-size: 12.5px; font-style: italic; }
td.barcell { white-space: nowrap; }

.kh-lbl {
  font: 700 10.5px/1 var(--cond); letter-spacing: .11em; text-transform: uppercase;
  color: var(--gray-text); align-self: center;
}
.kh-h3 {
  font: 700 15px/1.2 var(--cond); letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink); margin: 26px 0 11px; padding-bottom: 7px;
  border-bottom: 2px solid var(--gray-rule);
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
}
.kh-h3 span {
  font: 400 13px/1.3 var(--serif); letter-spacing: 0; text-transform: none;
  color: var(--gray-text);
}
.kh-sum { margin: 0 0 10px; }
.kh-sum .sep { margin: 0 8px; color: var(--gray-rule-2); }

.cardhead {
  margin: 0; padding: 11px 15px 10px;
  font: 700 12px/1 var(--cond); letter-spacing: .11em; text-transform: uppercase;
  color: var(--ink); border-bottom: 1px solid var(--gray-rule);
}

/* the slot a keeper fills, as a chip rather than a bare word */
.slotpill {
  display: inline-block; padding: 2px 7px; border-radius: 999px;
  font: 700 10px/1.5 var(--sans); letter-spacing: .07em; text-transform: uppercase;
  background: var(--paper-3); color: var(--ink-2);
}
.slotpill.slot-keeper  { background: #e8eef7; color: #1c4a80; }
.slotpill.slot-rookie  { background: var(--warn-wash); color: var(--warn); }
.slotpill.slot-prospect{ background: var(--good-wash); color: var(--good); }

/* ⑥ — the two count columns read as a pair, so they are marked as one */
.kh-year td.held { color: var(--good); font-weight: 600; }
.kh-year td.new  { color: var(--bad);  font-weight: 600; }

/* ⑦ — one nine-column chart per GM */
.kh-carry .kh-spark { padding-top: 6px; padding-bottom: 2px; }
.kh-carry .kh-spark svg { display: block; }
.kh-carry tr.is-former td:first-child { color: var(--gray-text); }
.kh-carry tr.is-former .kh-spark { opacity: .8; }

/* ⑧ — the ranked board. Fourteen rows of names is a lot of grid, so the
   season columns get mono figures and the two bands get a wash apiece. */
.kh-board { font-size: 13px; }
.kh-board th[scope="row"] {
  text-align: left; font: 700 12px/1 var(--cond); letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-2); white-space: nowrap;
  background: var(--paper); position: sticky; left: 0; z-index: 1;
  border-right: 1px solid var(--gray-rule);
}
.kh-board tr.kh-top th[scope="row"], .kh-board tr.kh-top td { background: var(--good-wash); }
.kh-board tr.kh-bot th[scope="row"], .kh-board tr.kh-bot td { background: var(--bad-wash); }
.kh-board tr.kh-top td a { color: var(--good); font-weight: 650; }
.kh-board tr.kh-bot td a { color: var(--bad);  font-weight: 650; }
.kh-board td { white-space: nowrap; }
.kh-board .kh-cup { font-size: 12px; filter: saturate(.9); }

@media (max-width: 700px) {
  .kh-board { font-size: 12px; }
  .kh-h3 { margin-top: 20px; }
}

/* ---------------------------------------------------- the compact hero
   The full hero is a 330px poster and earns that on a page whose lead story
   is the whole point. Where a hero is a signpost rather than the news — the
   link out of Keeper Central into the archive, the ruling on the home page
   once the page has other work to do — it runs a third the height, keeps the
   red eyebrow, and drops the display-size headline. */
/* No align-self here. The rail is a column flex container, so align-self acts
   on the CROSS axis — it made the hero 614px wide inside an 884px column and
   left a 270px hole beside it, which read as "a big gap between the breaking
   news sections". Height is already handled by min-height:0. */
.hero--sm { min-height: 0; }
.hero--sm .body { padding: 20px 24px 19px; background: none; }
.hero--sm h2 { font-size: clamp(21px, 2.6vw, 27px); }
.hero--sm p { font-size: 14.5px; margin-top: 7px; max-width: 78ch; }
.hero--sm .eyebrow { margin-bottom: 9px; padding: 5px 8px; font-size: 10px; }
.hero--sm .art { opacity: .38; }

/* a tile that is also a link */
a.tile { text-decoration: none; color: inherit; transition: background .12s ease,
  box-shadow .12s ease; }
a.tile:hover { background: var(--fsn-red-wash); box-shadow: var(--sh-2); }
a.tile:hover .label { color: var(--fsn-red-ink); }

/* ---------------------------------------------------- keeper board tiers
   A grade is ordinal, so it is drawn ordinally: one hue, darkening as it
   climbs. The letter never leaves — colour is the second channel, never the
   only one. Text on steps 5 and 6 flips to white to keep 4.5:1. */
.gradechip {
  display: inline-block; min-width: 34px; text-align: center;
  padding: 3px 8px 2px; border-radius: var(--radius-sm);
  font: 700 13px/1.35 var(--cond); letter-spacing: .06em;
}
.gradechip.gt-1 { background: var(--seq-1); color: #123f70; }
.gradechip.gt-2 { background: var(--seq-2); color: #123f70; }
.gradechip.gt-3 { background: var(--seq-3); color: #0d3057; }
.gradechip.gt-4 { background: var(--seq-4); color: #fff; }
.gradechip.gt-5 { background: var(--seq-5); color: #fff; }
.gradechip.gt-6 { background: var(--seq-6); color: #fff; }

.tierkey {
  display: flex; align-items: center; gap: 6px 14px; flex-wrap: wrap;
  margin: 12px 0 18px; padding: 9px 12px;
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius);
}
.tierkey .tk-l {
  font: 700 10px/1 var(--cond); letter-spacing: .13em; text-transform: uppercase;
  color: var(--gray-text); margin-right: 2px;
}
.tierkey .tk { display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--ink-2); }
.tierkey .tk i { width: 20px; height: 12px; border-radius: 3px; display: block; }
.tierkey .tk i.gt-1 { background: var(--seq-1); } .tierkey .tk i.gt-2 { background: var(--seq-2); }
.tierkey .tk i.gt-3 { background: var(--seq-3); } .tierkey .tk i.gt-4 { background: var(--seq-4); }
.tierkey .tk i.gt-5 { background: var(--seq-5); } .tierkey .tk i.gt-6 { background: var(--seq-6); }

/* the slot tag that follows a name on a depth chart. Four kinds, four
   meanings — a flex body, a rookie slot, a farmhand, and the one golden
   prospect a club may declare. */
.slottag {
  display: inline-block; margin-left: 5px; padding: 1px 5px;
  border-radius: 3px; vertical-align: 1px;
  font: 700 9.5px/1.5 var(--sans); letter-spacing: .06em;
}
.slottag.st-flx  { background: #e8eef7; color: #1c4a80; }
.slottag.st-rk   { background: var(--warn-wash); color: var(--warn); }
.slottag.st-p    { background: var(--good-wash); color: var(--good); }
.slottag.st-gold { background: #fbf0d8; color: #7a5a06; }

.keeper-grid td { vertical-align: top; }
.keeper-grid td:empty::after { content: "·"; color: var(--gray-rule); }
.keeper-club > summary .crest { --size: 22px; margin-right: 8px; vertical-align: -6px; }
.keeper-club .meta-line .sep { margin: 0 8px; color: var(--gray-rule-2); }
.poschip {
  font: 600 11px/1 var(--mono); color: var(--gray-text);
  background: var(--paper-2); border-radius: 3px; padding: 3px 5px; margin-left: 4px;
}

/* ---------------------------------------------------------- hidden rows
   At <=760px .stackable turns every row into a flex card, and `display:flex`
   on `tbody tr` beats the user-agent's `[hidden] { display: none }`. Every
   filter on the site therefore did nothing visible on a phone: the draft
   board still showed all 266 picks with the count underneath insisting 19.
   The rows were carrying the attribute the whole time; only the rule was
   missing. Both selectors are needed — the UA rule is weaker than either. */
[hidden] { display: none !important; }
table.data tbody tr[hidden],
table.data.stackable tbody tr[hidden] { display: none !important; }

/* …but a tab pane is only hidden because the tab layer is showing one at a
   time on screen. Printing has always flattened the tabs and printed the whole
   page; the !important above out-ranked that rule by arriving 1,000 lines
   later, so Save-as-PDF started emitting one tab and dropping the other 99% of
   the page. .pane[hidden] out-specifies [hidden] and puts it back. Filtered-out
   rows stay hidden in print, which is correct — they are not on the page the
   reader is looking at. */
@media print {
  .pane[hidden], .md-detail > [data-row][hidden] { display: block !important; }
}

/* ------------------------------------------------------- filter toolbars
   A filter people cannot see is a filter that looks broken. The draft board's
   two dropdowns had visually-hidden labels, so the only thing on screen was
   the word "Every pick" — which reads as a heading, not a control. */
.filters { align-items: center; }
.filters .f-lbl {
  font: 700 10.5px/1 var(--cond); letter-spacing: .11em; text-transform: uppercase;
  color: var(--gray-text);
}
.filters select, .filters input[type="search"], .pb-selects select { min-height: 34px; }

/* ------------------------------------------------------------ draft grid
   Nineteen rounds by fourteen slots. The point of drawing it is the shape,
   so picking a GM dims the rest rather than filtering them away — the holes
   in a club's row are the story. */
.draft-grid { font-size: 12.5px; }
.draft-grid td.is-traded { background: var(--fsn-red-wash); color: var(--fsn-red-ink);
  font-weight: 600; }
/* the scope may be the table itself or a wrapper around it, so both */
.draft-grid.is-highlighting td[data-owner],
.is-highlighting .draft-grid td[data-owner] {
  opacity: .3; transition: opacity .14s ease, background .14s ease;
}
.draft-grid.is-highlighting td.is-lit,
.is-highlighting .draft-grid td.is-lit {
  opacity: 1; background: var(--seq-5); color: #fff; font-weight: 650;
}
.draft-grid.is-highlighting td.is-lit.is-traded,
.is-highlighting .draft-grid td.is-lit.is-traded {
  background: var(--fsn-red); color: #fff;
}
.draft-grid.is-highlighting tbody tr:has(td.is-lit) td:first-child,
.is-highlighting .draft-grid tbody tr:has(td.is-lit) td:first-child { opacity: 1; }
[data-highlight-count] { font-variant-numeric: tabular-nums; }
.gridkey { display: flex; align-items: center; gap: 6px 18px; flex-wrap: wrap;
  margin: 9px 0 12px; }
.gridkey .gk { width: 16px; height: 12px; border-radius: 3px; display: inline-block;
  margin-right: -12px; }
.gridkey .gk-own   { background: var(--seq-5); }
.gridkey .gk-got   { background: var(--fsn-red); }
.gridkey .gk-plain { background: var(--paper-3); border: 1px solid var(--gray-rule); }

/* ==========================================================================
   v5.5 — the FBAHL board
   The eligibility verdicts used to sit in .wrap-cell, which is a serif prose
   cell — correct for the fine print of a trade, wrong for a row of flags, and
   the reason the Big Board read as a different site to the rankings above it.
   ========================================================================== */
.qcell { white-space: normal; min-width: 190px; line-height: 1.9; }
.qchip {
  display: inline-block; padding: 2px 7px; border-radius: 999px;
  font: 700 10px/1.5 var(--sans); letter-spacing: .05em; text-transform: uppercase;
  background: var(--paper-3); color: var(--ink-2); white-space: nowrap;
}
.qchip.q-pro      { background: #e8eef7; color: #1c4a80; }
.qchip.q-rk       { background: var(--warn-wash); color: var(--warn); }
.qchip.q-gold     { background: #f6e2a8; color: #6b4c00; }
.qchip.q-goldlite { background: #fbf0d8; color: #7a5a06; }
.qchip.q-out      { background: var(--bad-wash);  color: var(--bad); }
.qchip.q-warn     { background: var(--warn-wash); color: var(--warn); }

.tierchip {
  display: inline-block; padding: 2px 7px; border-radius: 3px;
  font: 700 10px/1.5 var(--sans); letter-spacing: .06em;
}
.tierchip.dt-1 { background: var(--seq-1); color: #123f70; }
.tierchip.dt-2 { background: var(--seq-2); color: #123f70; }
.tierchip.dt-3 { background: var(--seq-3); color: #0d3057; }
.tierchip.dt-4 { background: var(--seq-4); color: #fff; }
.tierchip.dt-5 { background: var(--seq-5); color: #fff; }
.tierchip.dt-6 { background: var(--seq-6); color: #fff; }

.muted { color: var(--gray-text); font-size: 12px; }
.testcell {
  white-space: normal; min-width: 300px; max-width: 460px;
  font: 400 12px/1.45 var(--mono); color: var(--gray-text);
}
.pool-table { font-size: 13.5px; }
.pool-table tr[data-state="out"]  td:first-child { box-shadow: inset 3px 0 0 var(--bad); }
.pool-table tr[data-state="gold"] td:first-child { box-shadow: inset 3px 0 0 #b8860b; }
.pool-table tr[data-state="warn"] td:first-child { box-shadow: inset 3px 0 0 var(--warn); }
.tiles--pool { margin-bottom: 14px; }
.ofcap { color: var(--gray-rule-2); font-weight: 400; }
.testcell { min-width: 240px; max-width: 360px; font-size: 11.5px; }

/* ==========================================================================
   v5.5 — the front page
   ========================================================================== */

/* the search band: the archive's front door, above the news rather than
   third item down a sidebar */
.searchband {
  display: flex; align-items: center; gap: 18px 26px; flex-wrap: wrap;
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-top: 3px solid var(--fsn-red); border-radius: var(--radius);
  box-shadow: var(--sh-1); padding: 15px 20px; margin-bottom: 18px;
}
.searchband .sb-t { min-width: 0; }
.searchband .sb-t h2 {
  margin: 0; font: 700 15px/1.1 var(--cond); letter-spacing: .09em;
  text-transform: uppercase;
}
.searchband .sb-t h2::before { content: none; }
.searchband .sb-t p { margin: 3px 0 0; font-size: 12.5px; color: var(--gray-text); }
.searchband .search { flex: 1 1 340px; position: relative; }
.searchband input { width: 100%; font-size: 15px; padding: 11px 14px; }

/* ------------------------------------------------------- the conferences */
.conferences { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.confcol {
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1); overflow: hidden;
}
.conf-h {
  display: flex; align-items: baseline; gap: 10px;
  padding: 11px 16px; background: var(--black-2); color: #fff;
}
.conf-h b { font: 700 15px/1 var(--cond); letter-spacing: .12em; text-transform: uppercase; }
.conf-h span { margin-left: auto; font-size: 11.5px; color: #9aa0a8; }

.clubrow {
  display: grid; align-items: center; gap: 12px;
  grid-template-columns: 34px minmax(0, 1fr) auto auto;
  padding: 10px 16px; text-decoration: none; color: inherit;
  border-bottom: 1px solid var(--gray-rule);
  border-left: 3px solid transparent;
  transition: background .12s ease, border-color .12s ease;
}
.clubrow:last-child { border-bottom: 0; }
.clubrow:hover { background: var(--club-wash); border-left-color: var(--club); }
.clubrow .cr-t { min-width: 0; }
.clubrow .cr-t b {
  display: block; font: 650 15px/1.25 var(--sans);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.clubrow:hover .cr-t b { color: var(--club); }
.clubrow .cr-gm { display: block; font-size: 12px; color: var(--gray-text); }
.clubrow .cr-rec {
  text-align: right; font: 600 13.5px/1.2 var(--mono);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.clubrow .cr-rec span { display: block; font: 400 11px/1.4 var(--sans);
  color: var(--gray-text); }
.clubrow .cr-hw { min-width: 46px; text-align: right; }
.banners { font-size: 13px; letter-spacing: -1px; white-space: nowrap; }
.banners.none { color: var(--gray-rule-2); letter-spacing: 0; }

@media (max-width: 820px) { .conferences { grid-template-columns: 1fr; } }

/* -------------------------------------------------------- the trade card
   One deal, drawn as a deal: who receives what, and where each piece came
   from. The old block put five trades on the front page as running prose and
   pushed everything else below the fold. */
.tradecard {
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-2); overflow: hidden;
}
.tc-top {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  padding: 13px 18px; background: var(--fsn-red); color: #fff;
  border-bottom: 3px solid var(--gold);
}
.tc-top b { font: 700 19px/1 var(--cond); letter-spacing: .1em; text-transform: uppercase; }
.tc-top span { margin-left: auto; font: 600 11px/1 var(--sans); letter-spacing: .12em;
  text-transform: uppercase; color: rgba(255,255,255,.86); }

.tc-side { border-top: 1px solid var(--gray-rule); }
.tc-side:first-of-type { border-top: 0; }
.tc-head {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 18px; background: var(--club-wash);
  border-left: 4px solid var(--club);
}
.tc-head .tc-club { min-width: 0; }
.tc-head .tc-club b {
  display: block; font: 700 17px/1.15 var(--cond); letter-spacing: .07em;
  text-transform: uppercase; color: var(--club);
}
.tc-head .tc-club > span { font-size: 12px; color: var(--gray-text); }
.tc-head .tc-club > span::after { content: " \2014 receives"; color: var(--gray-rule-2); }
.tc-count {
  margin-left: auto; padding: 4px 10px; border-radius: 999px;
  background: rgba(255,255,255,.72); color: var(--club);
  font: 700 10.5px/1.4 var(--sans); letter-spacing: .09em; text-transform: uppercase;
  white-space: nowrap;
}
.tc-row {
  display: flex; align-items: center; gap: 14px;
  padding: 9px 18px 9px 22px; border-top: 1px solid var(--gray-rule);
}
.tc-a { min-width: 0; }
.tc-a b { display: block; font: 650 15px/1.25 var(--sans); }
.tc-a .tc-sub { display: block; font-size: 12px; color: var(--gray-text); }
.tc-a .tc-from { display: block; font-size: 12px; color: var(--gray-text); margin-top: 1px; }
.tc-a .tc-from a { color: var(--club); font-weight: 600; text-decoration: none; }
.tc-a .tc-from a:hover { text-decoration: underline; }
.tc-kind {
  margin-left: auto; flex: 0 0 auto; padding: 3px 9px; border-radius: 999px;
  font: 700 10px/1.5 var(--sans); letter-spacing: .07em; text-transform: uppercase;
  white-space: nowrap;
}
.tc-kind.tc-pick { background: #e8eef7; color: #1c4a80; }
.tc-kind.tc-pro  { background: #fbf0d8; color: #7a5a06; }
.tc-foot {
  display: block; padding: 11px 18px; background: var(--paper-2);
  border-top: 1px solid var(--gray-rule);
  font: 700 11px/1 var(--cond); letter-spacing: .11em; text-transform: uppercase;
  color: var(--fsn-red-ink); text-decoration: none;
}
.tc-foot:hover { background: var(--fsn-red-wash); }
@media (max-width: 560px) {
  .tc-row { flex-wrap: wrap; gap: 6px; }
  .tc-kind { margin-left: 0; }
}

/* ==========================================================================
   v5.5 — the GM wall
   Fourteen identical white cards told you nothing at a glance, so each panel
   now opens with its own club: the crest at 60px on the club's ink, with the
   full logo sunk in behind it. Seven clubs per conference is an awkward
   number for a grid, so the conference leader takes a double-width panel and
   every row of three fills.
   ========================================================================== */
/* Fourteen clubs, fourteen identical panels. An earlier version gave the
   conference leader a full-width panel so seven would fill a three-column
   row; equal billing is worth more than a flush bottom edge, and a ragged
   last row reads as the end of a group, not as a missing club. */
.gmgrid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px; margin-bottom: 26px;
}
@media (max-width: 1060px) { .gmgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px)  { .gmgrid { grid-template-columns: minmax(0, 1fr); } }

.gm-panel {
  display: flex; flex-direction: column;
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1); overflow: hidden;
  transition: box-shadow .14s ease, transform .14s ease;
}
.gm-panel:hover { box-shadow: var(--sh-3); }

/* the small hero */
.gp-hero {
  position: relative; display: flex; align-items: center; gap: 14px;
  padding: 15px 18px; background: var(--club); color: #fff;
  text-decoration: none; overflow: hidden;
}
.gp-hero::before {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(105deg, rgba(0,0,0,.34), rgba(0,0,0,.10) 62%),
    repeating-linear-gradient(115deg, rgba(255,255,255,.07) 0 3px, transparent 3px 34px);
}
.gp-hero::after {
  content: ""; position: absolute; top: 50%; right: -34px;
  width: 150px; height: 150px; transform: translateY(-50%);
  background: var(--club-logo) center / contain no-repeat;
  opacity: .13; mix-blend-mode: luminosity; pointer-events: none;
}
.gp-hero .crest {
  position: relative; z-index: 1;
  background: rgba(255,255,255,.94); color: var(--club); text-shadow: none;
  filter: drop-shadow(0 4px 10px rgba(0,0,0,.3));
}
.gp-hero .crest::before { box-shadow: inset 0 0 0 2px rgba(255,255,255,.5); }
.gp-id { position: relative; z-index: 1; min-width: 0; }
.gp-id h3 {
  margin: 0; font: 700 20px/1.1 var(--cond); letter-spacing: .05em;
  text-transform: uppercase; color: #fff;
}
.gp-gm { font-size: 13px; color: rgba(255,255,255,.88); letter-spacing: .03em; }
.gp-hero:hover .gp-id h3 { text-decoration: underline; text-underline-offset: 3px; }
.gp-rank {
  position: relative; z-index: 1; margin-left: auto; text-align: right; flex: 0 0 auto;
  padding-left: 14px; border-left: 1px solid rgba(255,255,255,.24);
}
.gp-rank i {
  display: block; font: 700 26px/1 var(--cond); font-style: normal;
  font-variant-numeric: tabular-nums;
}
.gp-rank > span {
  display: block; font: 700 8.5px/1 var(--sans); letter-spacing: .14em;
  text-transform: uppercase; color: rgba(255,255,255,.7); margin-top: 4px;
}

.gp-body { display: flex; flex-direction: column; flex: 1 1 auto; padding: 14px 18px 15px; }
.gp-line { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.gp-line b { font: 600 15px/1 var(--mono); font-variant-numeric: tabular-nums; }
.gp-line > span { font: 600 13px/1 var(--mono); color: var(--gray-text); }
.gp-line .banners { margin-left: auto; font-size: 14px; }
.gp-line .banners.none {
  font: 400 11.5px/1 var(--sans); color: var(--gray-rule-2); letter-spacing: 0;
}

.gp-metrics { display: flex; gap: 20px; margin: 12px 0 2px; flex-wrap: wrap; }
.gpm { display: flex; align-items: center; gap: 8px; }
.gpm .k {
  font: 700 9.5px/1 var(--cond); letter-spacing: .13em; text-transform: uppercase;
  color: var(--gray-text);
}
.gpm b { font: 600 13px/1 var(--mono); font-variant-numeric: tabular-nums; }
.gpm .mini { display: block; }

.gp-grades { display: flex; gap: 8px; margin: 13px 0 11px; flex-wrap: wrap; }
.gg {
  display: flex; align-items: center; gap: 7px; padding: 6px 10px 6px 7px;
  background: var(--paper-2); border-radius: var(--radius-sm); min-width: 0;
}
.gg > span {
  font: 700 9.5px/1.35 var(--cond); letter-spacing: .11em; text-transform: uppercase;
  color: var(--ink-2);
}
.gg > span i {
  display: block; font: 400 10px/1.3 var(--sans); letter-spacing: 0;
  text-transform: none; color: var(--gray-text);
}
.gg-n > b {
  display: block; min-width: 30px; text-align: center;
  font: 700 15px/1.35 var(--cond); color: var(--ink);
}

.gp-lore {
  margin: 0 0 12px; font-family: var(--serif); font-size: 13.5px; line-height: 1.5;
  color: var(--ink-2); flex: 1 1 auto;
}
.gp-foot {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding-top: 10px; border-top: 1px solid var(--gray-rule);
}
.gp-desk { font-size: 11.5px; color: var(--gray-text); min-width: 0; }
.gp-case {
  margin-left: auto; flex: 0 0 auto; font-size: 14px; letter-spacing: 1px;
  text-decoration: none; padding: 2px 7px; border-radius: 999px;
  background: var(--paper-2);
}
.gp-case:hover { background: var(--fsn-red-wash); }

.legacy-card {
  display: flex; align-items: center; gap: 11px; text-decoration: none; color: inherit;
}
.legacy-card h3 { margin: 0; font-size: 15px; font-weight: 650; }
.legacy-card > span:last-child { font-size: 12px; color: var(--gray-text); display: block; }

/* ==========================================================================
   v5.5 — the trophy case
   A four-column table of awards read as a spreadsheet of prizes. A trophy is
   an object, so it is drawn as one: a glyph, a holder, and the reason. Each
   section that decides an award now carries its own small wall.
   ========================================================================== */
.tw-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 10px;
}
.tw-grid--full { grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); }

.trophy {
  display: flex; gap: 11px; padding: 12px 14px;
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1);
  border-left: 3px solid var(--gold);
}
.trophy .tr-em { font-size: 20px; line-height: 1.1; flex: 0 0 auto; }
.trophy .tr-b { min-width: 0; }
.trophy b {
  display: block; font: 700 13px/1.25 var(--cond); letter-spacing: .08em;
  text-transform: uppercase;
}
.trophy .tr-who { display: block; font: 600 13.5px/1.35 var(--sans); margin-top: 3px; }
.trophy .tr-who a { text-decoration: none; color: var(--club); }
.trophy .tr-who a:hover { text-decoration: underline; }
.trophy .tw-nobody { color: var(--gray-text); font-weight: 400; }
.trophy .tr-why  { display: block; font-size: 12px; color: var(--ink-2); margin-top: 3px; }
.trophy .tr-crit {
  display: block; font: 400 11.5px/1.4 var(--serif); color: var(--gray-text);
  margin-top: 6px; padding-top: 6px; border-top: 1px dotted var(--gray-rule);
}
.trophy--sm { padding: 10px 12px; }
.trophy--sm .tr-em { font-size: 17px; }
.trophy--sm .tr-why { display: none; }

/* the per-section wall */
.trophywall {
  background: var(--paper-2); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); padding: 13px 15px 15px; margin: 4px 0 24px;
}
.tw-head {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin-bottom: 11px;
}
.tw-head .tw-cup { font-size: 15px; }
.tw-head b {
  font: 700 13px/1 var(--cond); letter-spacing: .12em; text-transform: uppercase;
}
.tw-head > span { font-size: 12.5px; color: var(--gray-text); }
.tw-head a {
  margin-left: auto; font: 700 10.5px/1 var(--cond); letter-spacing: .11em;
  text-transform: uppercase; color: var(--fsn-red-ink); text-decoration: none;
  white-space: nowrap;
}
.tw-head a:hover { text-decoration: underline; }

/* the full case */
.tc-leaders {
  display: flex; align-items: center; gap: 10px 14px; flex-wrap: wrap;
  padding: 12px 15px; margin-bottom: 16px;
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-top: 3px solid var(--gold); border-radius: var(--radius);
  box-shadow: var(--sh-1);
}
.tcl-l {
  font: 700 10.5px/1 var(--cond); letter-spacing: .13em; text-transform: uppercase;
  color: var(--gray-text);
}
.tc-lead {
  display: inline-flex; align-items: center; gap: 8px; text-decoration: none;
  color: inherit; padding: 4px 10px 4px 5px; border-radius: 999px;
  background: var(--club-wash);
}
.tc-lead:hover { box-shadow: inset 0 0 0 1px var(--club); }
.tc-lead b { font: 650 14px/1 var(--sans); color: var(--club); }
.tc-lead > span { font: 600 11.5px/1 var(--mono); color: var(--gray-text); }

.tc-group { margin-bottom: 20px; }
.tcg-head {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding-bottom: 8px; margin-bottom: 11px; border-bottom: 2px solid var(--gray-rule);
}
.tcg-head b {
  font: 700 15px/1 var(--cond); letter-spacing: .1em; text-transform: uppercase;
}
.tcg-head > span { font-size: 12.5px; color: var(--gray-text); }
.tcg-head a {
  font: 700 10.5px/1 var(--cond); letter-spacing: .1em; text-transform: uppercase;
  color: var(--fsn-red-ink); text-decoration: none;
}
.tcg-head a:hover { text-decoration: underline; }
.tcg-head i {
  margin-left: auto; font: 600 11px/1 var(--mono); font-style: normal;
  color: var(--gray-text);
}

/* ------------------------------------------------------ blockbuster cards
   Two columns of cards whose footers floated wherever the longest asset list
   left them. The card is a column, the deal grows, the footer sits on the
   floor — so a row reads as a row. */
.grid.cols-2 > .card--deal, .card--deal { display: flex; flex-direction: column; }
.card--deal .deal { flex: 1 1 auto; }
.card--deal .bb-foot { margin-top: auto; padding-top: 12px; margin-bottom: 0;
  border-top: 1px solid var(--gray-rule); }
.bb-head {
  display: flex; align-items: baseline; gap: 10px;
  padding-bottom: 10px; margin-bottom: 12px; border-bottom: 2px solid var(--gray-rule);
}
.bb-head b { font: 700 24px/1 var(--cond); }
.bb-head .bb-count { margin-left: auto; }
.card--deal .sides { align-items: stretch; }
.card--deal .side { display: flex; flex-direction: column; }

/* ---------------------------------------------------------- GM cockpit
   Eight tiles rather than four. At 1240px that is two rows of four; the
   minmax floor stops a long keeper name from squeezing the row to nothing. */
.tiles--cockpit { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.tiles--cockpit .value.sm { font-size: 19px; line-height: 1.25; }
.tiles--cockpit .value a { text-decoration: none; color: inherit;
  border-bottom: 2px solid var(--team, var(--fsn-red)); }
.tiles--cockpit .value a:hover { color: var(--team, var(--fsn-red-ink)); }
.tiles--cockpit .value .unit {
  font: 700 14px/1 var(--cond); color: var(--gray-text); margin-left: 3px;
  letter-spacing: .06em; text-transform: uppercase;
}
.tiles--cockpit .context { line-height: 1.45; }

/* A grid item's min-width is auto, so a <details> whose summary cannot wrap
   sets the floor for the whole column — which is how a 375px phone ended up
   with a 414px page once the club summaries gained a crest and a grade pill.
   The track is explicitly minmax(0,1fr) and the summary wraps. */
.keeper-boards { grid-template-columns: minmax(0, 1fr); }
.keeper-club { min-width: 0; }
.keeper-club > summary { flex-wrap: wrap; row-gap: 4px; }
.keeper-club > summary b { min-width: 0; }
@media (max-width: 560px) {
  .keeper-club > summary .count { margin-left: 0; }
  .keeper-club .meta-line { display: flex; flex-wrap: wrap; align-items: center;
    gap: 4px 0; }
  .keeper-club .meta-line .sep { margin: 0 6px; }
}

/* On a phone the club name and the all-time rank fight for the same 335px,
   and a long name runs under the number. The rank drops to a chip on the
   line below rather than shrinking the club to nothing. */
@media (max-width: 560px) {
  .gp-hero { flex-wrap: wrap; row-gap: 8px; padding: 13px 15px; }
  .gp-id { flex: 1 1 100%; order: 2; }
  .gp-hero .crest { order: 1; }
  .gp-hero .crest { --size: 44px; }
  .gp-rank {
    order: 1; margin-left: auto; padding-left: 0; border-left: 0;
    display: flex; align-items: baseline; gap: 6px;
  }
  .gp-rank i { font-size: 22px; }
  .gp-rank > span { margin-top: 0; }
  .gp-id h3 { font-size: 21px; }
}

/* a filter that matches nothing has to say so rather than leave a blank page */
.filter-empty {
  margin: 14px 0 4px; padding: 16px 18px;
  background: var(--paper); border: 1px dashed var(--gray-rule-2);
  border-radius: var(--radius);
  font-family: var(--serif); font-size: 14.5px; color: var(--ink-2);
}

/* a section whose content is reference rather than a working surface: the
   heading stays in the page and in the tab strip, the table folds away */
details.collapse.fold { margin-bottom: 20px; }
details.collapse.fold > summary { background: var(--paper-2); }
details.collapse.fold[open] > summary { border-bottom: 1px solid var(--gray-rule); }

/* ==========================================================================
   v5.6 — the prospect pool
   The pool is the page's working surface: 121 names a GM checks a ruling
   against. So the search is the first thing and the biggest, the five
   standings are chips rather than a dropdown (all five visible at once), and
   the test that produced a ruling sits under the ruling instead of in a ninth
   column that ran off the right edge.
   ========================================================================== */
.poolbar {
  display: grid; gap: 12px 18px; align-items: center;
  grid-template-columns: minmax(280px, 1.15fr) auto;
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-top: 3px solid var(--fsn-red); border-radius: var(--radius);
  box-shadow: var(--sh-1); padding: 14px 16px; margin-bottom: 14px;
}
.pb-search { position: relative; display: flex; align-items: center; gap: 12px; }
.pb-search input {
  flex: 1 1 auto; width: 100%; font-size: 16px; padding: 12px 14px;
  border: 1px solid var(--gray-rule-2); border-radius: var(--radius);
}
.pb-search input:focus { outline: 2px solid var(--fsn-red); outline-offset: 1px; }
.poolbar .count { margin-left: 0; font-size: 13px; color: var(--gray-text);
  font-family: var(--mono); }
.pb-search .count { white-space: nowrap; font-variant-numeric: tabular-nums; }
.pb-chips { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.pb-selects {
  grid-column: 1 / -1; display: flex; align-items: center; gap: 8px 14px;
  flex-wrap: wrap; padding-top: 12px; border-top: 1px solid var(--gray-rule);
}
.fchip {
  border: 1px solid var(--gray-rule-2); background: var(--paper);
  border-radius: 999px; padding: 7px 13px; cursor: pointer; color: var(--ink-2);
  font: 600 12.5px/1 var(--sans); white-space: nowrap;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.fchip:hover { border-color: var(--fsn-red); color: var(--fsn-red-ink); }
.fchip.is-on {
  background: var(--black-2); border-color: var(--black-2); color: #fff;
}
.fchip:focus-visible { outline: 2px solid var(--fsn-red); outline-offset: 2px; }
@media (max-width: 900px) {
  .poolbar { grid-template-columns: minmax(0, 1fr); }
  .pb-chips { justify-content: flex-start; }
}

/* the ruling column: chips, then the reason in the site's mono */
.pool-table .qcell { min-width: 340px; white-space: normal; line-height: 1.75; }
.qwhy {
  display: block; margin-top: 5px;
  font: 400 11.5px/1.5 var(--mono); color: var(--gray-text);
  white-space: normal;
}
.pool-table { font-size: 14px; }
.pool-table td { padding-top: 11px; padding-bottom: 11px; }
.pool-table thead th { z-index: 3; }
.filter-empty-row td {
  padding: 22px 18px; text-align: center;
  font-family: var(--serif); font-size: 14.5px; color: var(--ink-2);
  background: var(--paper-2);
}

/* ==========================================================================
   v5.6 — the latest deal, compact
   Three rows instead of twelve: the club's colour does the grouping, and the
   assets are chips that separate picks from players at a glance.
   ========================================================================== */
.deal-card {
  display: block; text-decoration: none; color: inherit;
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-2); overflow: hidden;
  transition: box-shadow .14s ease;
}
.deal-card:hover { box-shadow: var(--sh-3); }
.dc-top {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  padding: 11px 16px; background: var(--fsn-red); color: #fff;
  border-bottom: 2px solid var(--gold);
}
.dc-top b {
  font: 700 16px/1 var(--cond); letter-spacing: .11em; text-transform: uppercase;
}
.dc-meta {
  margin-left: auto; font: 600 10.5px/1 var(--sans); letter-spacing: .1em;
  text-transform: uppercase; color: rgba(255,255,255,.85); white-space: nowrap;
}
.dl-row {
  display: grid; align-items: start; gap: 4px 11px;
  grid-template-columns: 26px minmax(96px, auto) minmax(0, 1fr);
  padding: 11px 16px; border-top: 1px solid var(--gray-rule);
  border-left: 3px solid var(--club);
}
.dl-row:first-of-type { border-top: 0; }
.deal-card:hover .dl-row { background: var(--club-wash); }
.dl-club { min-width: 0; padding-top: 1px; }
.dl-club b {
  display: block; font: 700 13px/1.2 var(--cond); letter-spacing: .07em;
  text-transform: uppercase; color: var(--club);
}
.dl-club > span { font-size: 11px; color: var(--gray-text); }
.dl-gets { display: flex; flex-wrap: wrap; gap: 5px; }
.dl-pick, .dl-pro {
  display: inline-flex; align-items: baseline; gap: 4px;
  padding: 3px 8px; border-radius: 4px; white-space: nowrap;
  font: 650 12px/1.35 var(--sans);
}
.dl-pick { background: #e8eef7; color: #1c4a80; }
.dl-pick i {
  font-style: normal; font: 700 9px/1 var(--sans); letter-spacing: .06em;
  opacity: .7;
}
.dl-pro { background: #fbf0d8; color: #6b4c00; }
.dc-foot {
  display: block; padding: 9px 16px; background: var(--paper-2);
  border-top: 1px solid var(--gray-rule);
  font: 700 10.5px/1 var(--cond); letter-spacing: .11em; text-transform: uppercase;
  color: var(--fsn-red-ink);
}
.deal-card:hover .dc-foot { background: var(--fsn-red-wash); }
@media (max-width: 520px) {
  .dl-row { grid-template-columns: 26px minmax(0, 1fr); }
  .dl-gets { grid-column: 1 / -1; }
}

/* ==========================================================================
   v5.6 — the GM cockpit
   Ten tiles in one strip. A tile with more to say opens rather than growing:
   native <details>, so it is keyboard reachable and needs no script, and the
   strip keeps one height whether nothing or everything is open.
   ========================================================================== */
/* ==========================================================================
   THE FRANCHISE HUB — the top of a GM page.

   Two tiers. THIS SEASON is the working state and reads as an instrument
   panel: five divided cells and, when the club owes the league something, one
   line in the league's own words. THE PANELS are the archive: three equal
   cards, each led by the single number that card is about.

   The old strip put "first keeper list, 2018-19" at the top of a man's own
   page and his outstanding obligation two thirds of the way down, behind a
   tab. This is the same eleven facts with the order of importance inverted.
   ========================================================================== */
.cockpit { display: flex; flex-direction: column; gap: 20px; }

/* ------------------------------------------------------------ this season */
.ck-now { min-width: 0; }
.ckgroup-h {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin: 0 0 10px; padding-bottom: 7px;
  border-bottom: 2px solid var(--ink);
}
.ckgroup-h b {
  font: 700 13px/1 var(--cond); letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink);
}
.ckgroup-h > span { font-size: 12px; color: var(--gray-text);
  font-family: var(--mono); }
.ckgroup-h a {
  margin-left: auto; font: 700 10px/1 var(--cond); letter-spacing: .1em;
  text-transform: uppercase; color: var(--fsn-red-ink); text-decoration: none;
  white-space: nowrap;
}
.ckgroup-h a:hover { text-decoration: underline; }

.nowbar {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-top: 3px solid var(--team, var(--fsn-red));
  border-radius: var(--radius); box-shadow: var(--sh-1); overflow: hidden;
}
.nowcell { padding: 14px 18px 15px; min-width: 0; position: relative; }
.nowcell + .nowcell { border-left: 1px solid var(--gray-rule); }
.nowcell .label {
  display: block; font: 700 9.5px/1 var(--cond); letter-spacing: .14em;
  text-transform: uppercase; color: var(--gray-text);
}
.nowcell .value {
  display: block; font-family: var(--cond); font-weight: 700; font-size: 30px;
  line-height: 1.06; margin-top: 6px; font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.nowcell .context {
  display: block; font-size: 12px; color: var(--gray-text); line-height: 1.45;
  margin-top: 6px;
}
.nowcell .context a { color: inherit; text-decoration: none;
  border-bottom: 1px solid var(--gray-rule-2); }
.nowcell .context a:hover { color: var(--team, var(--fsn-red-ink)); }
/* the state tick sits inside the value so the word stays the value */
.nowcell .tick {
  display: inline-block; margin-right: 7px; font-size: 21px; line-height: 1;
  vertical-align: 1px;
}
.nowcell.is-ok .tick   { color: var(--ok-ink, #1c7a4a); }
.nowcell.is-warn .tick { color: var(--fsn-red); }
.nowcell.is-warn::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--fsn-red);
}
/* only a problem gets a stripe. A green rule down the left of the buy-in cell
   made "you have paid" look like a category of thing, which it is not — the
   only cell worth marking is one that needs the GM to do something. */

/* the one line that says whether this club owes the league anything */
.ck-action {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin: 10px 0 0; padding: 11px 16px 12px;
  background: var(--fsn-red-wash); border: 1px solid var(--gray-rule);
  border-left: 3px solid var(--fsn-red); border-radius: var(--radius);
  font-size: 13.5px; line-height: 1.5; color: var(--ink-2);
}
.ck-action.is-clear {
  background: var(--paper-2); border-left-color: var(--gray-rule-2);
}
.ck-action b { color: var(--ink); font-weight: 700; }
.ck-action .pill { flex: 0 0 auto; }
.ck-action > a {
  margin-left: auto; font: 700 10px/1 var(--cond); letter-spacing: .1em;
  text-transform: uppercase; color: var(--fsn-red-ink); text-decoration: none;
  white-space: nowrap;
}
.ck-action > a:hover { text-decoration: underline; }

/* ---------------------------------------------------------- the panels */
.ckpanels {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px; align-items: stretch;
}
.ckpanel {
  display: flex; flex-direction: column; min-width: 0;
  background: var(--paper); border: 1px solid var(--gray-rule);
  border-radius: var(--radius); box-shadow: var(--sh-1); overflow: hidden;
}
.ckpanel > h3 {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin: 0; padding: 11px 16px 10px;
  border-bottom: 1px solid var(--gray-rule); background: var(--paper-2);
}
.ckpanel > h3::before { content: none; }
.ckpanel > h3 b {
  font: 700 11.5px/1 var(--cond); letter-spacing: .13em;
  text-transform: uppercase; color: var(--ink);
}
.ckpanel > h3 span {
  margin-left: auto; font: 400 11px/1 var(--mono); color: var(--gray-text);
  white-space: nowrap;
}
/* the lead number: one per panel, and it is the only large thing in it */
.ckp-lead {
  display: flex; align-items: baseline; gap: 9px;
  padding: 13px 16px 12px; border-bottom: 1px solid var(--gray-rule);
}
.ckp-lead > b {
  font-family: var(--cond); font-weight: 700; font-size: 38px; line-height: .96;
  font-variant-numeric: tabular-nums; color: var(--ink);
}
.ckp-lead .gradechip { font-size: 21px; padding: 3px 10px 2px; }
.ckp-lead > span {
  font-size: 12px; color: var(--gray-text); line-height: 1.35;
}
.ckp-dl { margin: 0; padding: 4px 16px 6px; flex: 1 1 auto; }
.ckp-dl dt {
  font: 700 9.5px/1.5 var(--cond); letter-spacing: .11em;
  text-transform: uppercase; color: var(--gray-text); margin-top: 11px;
}
.ckp-dl dt:first-of-type { margin-top: 8px; }
.ckp-dl dd { margin: 2px 0 0; font-size: 13px; line-height: 1.5; color: var(--ink-2); }
.ckp-dl dd .muted { color: var(--gray-text); }
.ckp-dl dd a { color: inherit; text-decoration: none;
  border-bottom: 1px solid var(--gray-rule-2); }
.ckp-dl dd a:hover { color: var(--team, var(--fsn-red-ink));
  border-bottom-color: var(--team, var(--fsn-red)); }
.ckp-dl .gradechip { font-size: 12px; padding: 1px 6px; vertical-align: 1px; }
.co-line { display: block; }
.co-line b { font-family: var(--cond); font-size: 16px; }
.ckp-more {
  display: block; margin-top: auto; padding: 10px 16px 11px;
  border-top: 1px solid var(--gray-rule); background: var(--paper-2);
  font: 700 10px/1 var(--cond); letter-spacing: .11em; text-transform: uppercase;
  color: var(--fsn-red-ink); text-decoration: none;
}
.ckp-more:hover { background: var(--fsn-red-wash); text-decoration: underline; }

/* the carry-over sparkline, inline in its row rather than behind a caret */
.ckp-dl .tspark {
  display: flex; align-items: flex-end; gap: 2px; height: 22px; margin-top: 6px;
}

/* ------------------------------------------------------------ responsive */
@media (max-width: 1100px) {
  .ckpanels { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ckpanel:last-child { grid-column: span 2; }
}
@media (max-width: 1000px) {
  .nowbar { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .nowcell:nth-child(3n + 1) { border-left: 0; }
  .nowcell:nth-child(n + 4) { border-top: 1px solid var(--gray-rule); }
  .nowcell:nth-child(n + 4)::before { display: none; }
}
@media (max-width: 720px) {
  .nowbar { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .nowcell { padding: 12px 14px 13px; }
  .nowcell .value { font-size: 26px; }
  .nowcell:nth-child(n) { border-left: 1px solid var(--gray-rule); }
  .nowcell:nth-child(2n + 1) { border-left: 0; }
  .nowcell:nth-child(n + 3) { border-top: 1px solid var(--gray-rule); }
  .ckpanels { grid-template-columns: minmax(0, 1fr); }
  .ckpanel:last-child { grid-column: auto; }
  .ck-action { flex-direction: column; align-items: flex-start; gap: 6px; }
  .ck-action > a { margin-left: 0; }
}

.tiles--cockpit {
  grid-template-columns: repeat(auto-fit, minmax(228px, 1fr));
  gap: 12px; align-items: start;
}
.tiles--cockpit .tile { padding: 0; }
.tiles--cockpit .tile > .label,
.tiles--cockpit summary > .label {
  display: block; font: 700 9.5px/1 var(--cond); letter-spacing: .13em;
  text-transform: uppercase; color: var(--gray-text);
}
.tiles--cockpit .tile > .value,
.tiles--cockpit summary > .value {
  display: block; font-family: var(--cond); font-weight: 700; font-size: 34px;
  line-height: 1.04; margin-top: 6px; font-variant-numeric: tabular-nums;
}
.tiles--cockpit .value.sm { font-size: 20px; line-height: 1.22; }
.tiles--cockpit .value a { text-decoration: none; color: inherit;
  border-bottom: 2px solid var(--team, var(--fsn-red)); }
.tiles--cockpit .value .unit {
  font: 700 13px/1 var(--cond); color: var(--gray-text); margin-left: 3px;
  letter-spacing: .06em; text-transform: uppercase;
}
.tiles--cockpit .tile > .context,
.tiles--cockpit summary > .context {
  display: block; font-size: 12px; color: var(--gray-text); line-height: 1.4;
  margin-top: 5px;
}
.tiles--cockpit > .tile { padding: 13px 15px 14px; }
.tiles--cockpit a.tile:hover { background: var(--fsn-red-wash); }

/* The disclosure opens over the strip, not through it. Expanding in flow
   makes the whole grid row as tall as the open tile and leaves four empty
   boxes beside it; as a popover the strip is the same height whether nothing
   or something is open, which is the point of a cockpit. */
.tile--more { padding: 0; position: relative; overflow: visible; }
/* 36, not 6: the page's tab strip is sticky at z-index 35, and the lower band
   of the cockpit sits directly above it — a panel opened there was painted
   behind the strip and lost its first two rows. Still under the topbar (50)
   and the nav panels (60). */
.tiles--cockpit .tile--more[open] { z-index: 36; }
.tile--more > summary {
  list-style: none; cursor: pointer; padding: 13px 34px 14px 15px;
  position: relative;
}
.tile--more > summary::-webkit-details-marker { display: none; }
.tile--more > summary::after {
  content: ""; position: absolute; right: 14px; top: 17px;
  width: 7px; height: 7px; border-right: 2px solid var(--gray-rule-2);
  border-bottom: 2px solid var(--gray-rule-2); transform: rotate(45deg);
  transition: transform .15s ease, border-color .15s ease;
}
.tile--more[open] > summary::after {
  transform: rotate(-135deg); border-color: var(--team, var(--fsn-red));
}
.tile--more > summary:hover::after { border-color: var(--team, var(--fsn-red)); }
.tile--more > summary:focus-visible { outline: 2px solid var(--fsn-red);
  outline-offset: -2px; }
.tile--more[open] > summary { background: var(--paper-2); }
.tile-body {
  position: absolute; top: calc(100% + 1px); left: -1px;
  min-width: calc(100% + 2px); width: max-content; max-width: 330px;
  padding: 12px 15px 13px; background: var(--paper);
  border: 1px solid var(--gray-rule); border-top: 2px solid var(--team, var(--fsn-red));
  border-radius: 0 0 var(--radius) var(--radius); box-shadow: var(--sh-3);
  animation: fsn-menu-in .13s ease-out;
}
/* The edge case is handled in script, not by nth-child: the column count
   changes with the viewport, so "every fifth tile is the right-hand one" is
   true at 1280 and false at 1060, where a panel then hung 64px off the page. */
@media (prefers-reduced-motion: reduce) { .tile-body { animation: none; } }
.tile-dl { margin: 0; }
.tile-dl dt {
  font: 700 9.5px/1.5 var(--cond); letter-spacing: .1em; text-transform: uppercase;
  color: var(--gray-text); margin-top: 8px;
}
.tile-dl dt:first-child { margin-top: 0; }
.tile-dl dd { margin: 1px 0 0; font-size: 12.5px; line-height: 1.45; }
.tile-dl dd a { text-decoration: none; border-bottom: 1px solid var(--gray-rule-2); }
.tile-dl dd a:hover { border-bottom-color: var(--team, var(--fsn-red)); }
.tile-go {
  display: block; margin-top: 10px; padding-top: 9px;
  border-top: 1px solid var(--gray-rule);
  font: 700 10px/1 var(--cond); letter-spacing: .1em; text-transform: uppercase;
  color: var(--fsn-red-ink); text-decoration: none;
}
.tile-go:hover { text-decoration: underline; }

/* the carry-over sparkline inside its panel */
.tspark { display: flex; align-items: flex-end; gap: 3px; height: 34px;
  margin-bottom: 10px; }
.tspark-b {
  flex: 1 1 0; height: var(--h); min-height: 3px; border-radius: 2px 2px 0 0;
  background: var(--team, var(--seq-5)); opacity: .85;
}

/* ==========================================================================
   FSN v5.9 — the bar, the panels, the boards.
   ========================================================================== */

/* -------------------------------------------------------------- the mark
   The wordmark tile was a red square with "FSN" typeset into it. It is now
   the real logo, which already carries its own red, so the tile's background
   and inset shadow come off — otherwise the mark sits on a red-on-red slab.
   The image is given an explicit height and `width:auto` because the intrinsic
   file is 374x120: without it the flex row hands it 374px and the nine rooms
   lose a third of the bar. */
.logo-mark { background: none; box-shadow: none; padding: 0; border-radius: 0;
  display: flex; align-items: center; }
/* width:auto with an explicit height, because the file is 374x120 and a flex
   row would otherwise hand the mark 374px — a third of the bar. The bar
   height is set so the mark costs about what the old red "FSN" tile did
   (~56px): the nine rooms have no spare width to give it. */
.logo-mark img { display: block; height: 30px; width: auto; }
.topbar .logo-mark img { height: 21px; }
.masthead .logo-mark img { height: 38px; }
@media (max-width: 900px) { .topbar .logo-mark img { height: 20px; } }

/* ------------------------------------------------------- nav-bar search
   The home page opens on a full search band; the moment it scrolls off, the
   only way back to it was the footer. The bar now carries the same island in
   its top-right corner, collapsed to a 34px disclosure so it costs the nine
   rooms almost nothing.

   On the home page the button is held back until the reader has actually
   scrolled past the band (script adds .is-armed) — two search boxes on screen
   at once is a puzzle, not a convenience. Every other page arms it at load. */
.navsearch { display: flex; align-items: center; flex: 0 0 auto;
  position: relative; margin-left: 6px; }
.navsearch-btn {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; border-radius: var(--radius-sm);
  border: 1px solid #33373f; background: #1b1e23; color: #cfd3d9;
  cursor: pointer; transition: background .12s ease, color .12s ease,
    border-color .12s ease, opacity .16s ease, visibility .16s ease;
}
.navsearch-btn:hover { background: #2a2e35; color: #fff; border-color: #4a4f58; }
.navsearch-btn:focus-visible { outline: 2px solid var(--fsn-red); outline-offset: 2px; }
.navsearch-btn[aria-expanded="true"] {
  background: var(--fsn-red); border-color: var(--fsn-red); color: #fff; }
/* held back until armed — visibility, not display, so the box keeps its
   width and the nine rooms do not reflow the instant you scroll */
.navsearch:not(.is-armed) .navsearch-btn { opacity: 0; visibility: hidden; }

.navsearch-panel {
  position: absolute; top: calc(100% + 9px); right: 0; z-index: 60;
  width: min(400px, calc(100vw - 28px));
  background: var(--paper); border: 1px solid var(--gray-rule-2);
  border-top: 3px solid var(--fsn-red);
  border-radius: var(--radius); box-shadow: var(--sh-3); padding: 11px;
}
.navsearch-panel[hidden] { display: none; }
.navsearch-panel .search-results { left: 11px; right: 11px; }

@media (max-width: 900px) {
  /* The phone bar wraps: logo · search · Menu on row one, the room list on
     row two. The order is explicit because .mainnav is the 100%-wide item —
     without it the search box lands underneath the room list. */
  .navsearch { margin-left: auto; margin-right: 10px; order: 1; }
  .topbar .navtoggle { order: 2; margin-left: 0; }
  .topbar .mainnav { order: 3; }
  .navsearch-panel { position: fixed; top: var(--nav-h, 58px); right: 8px; left: 8px;
    width: auto; }
}

/* ---------------------------------------------- the panels, folded (v5.9)
   v5.8 argued that eleven facts do not need folding. Read on a real screen
   the three panels are 380px of dense definition list each, and the numbers
   that actually answer "how am I doing" — the win rate, the deal count, the
   two grades — are buried in the middle of it.

   Each panel now opens on its lead figure and its single most load-bearing
   row (the record, the assets in and out, the farm grade) and folds the rest
   behind a summary that names what is inside, so the fold is a decision
   rather than a shrug. The <details> element does the work: no JS, keyboard
   operable, and Ctrl+F / print still reach the folded rows because
   `.pane details` is force-opened for printing further up this file. */
/* The head list takes the slack so the three folds line up along the bottom
   of the row. (Not `margin-top:auto` on the fold: .ckp-more already claims an
   auto margin, and two of them in one column split the free space between
   them, which left the fold hovering in the middle of the panel.) */
.ckp-dl--head { padding-bottom: 10px; flex: 1 1 auto; }
.ckp-dl--head dt:first-of-type { margin-top: 8px; }

.ckp-fold { border-top: 1px solid var(--gray-rule); flex: 0 0 auto; }
.ckp-fold > summary {
  cursor: pointer; list-style: none; display: flex; align-items: center;
  gap: 9px; padding: 9px 16px 10px;
  font: 500 11.5px/1.35 var(--sans); color: var(--gray-text);
}
.ckp-fold > summary::-webkit-details-marker { display: none; }
.ckp-fold > summary:hover { background: var(--paper-2); color: var(--ink-2); }
.ckp-fold > summary:focus-visible { outline: 2px solid var(--fsn-red);
  outline-offset: -2px; }
.ckp-fold > summary::after {
  content: "▸"; margin-left: auto; color: var(--fsn-red);
  transition: transform .15s ease; flex: 0 0 auto;
}
.ckp-fold[open] > summary::after { transform: rotate(90deg); }
.ckp-fold[open] > summary { border-bottom: 1px solid var(--gray-rule);
  background: var(--paper-2); color: var(--ink-2); }
.ckp-fold > summary .count {
  flex: 0 0 auto; background: var(--paper-3); color: var(--ink-2);
  border-radius: 999px; padding: 1px 8px;
  font: 600 10px/1.7 var(--sans); letter-spacing: .04em;
}
.ckp-fold > .ckp-dl { padding-bottom: 12px; }
@media print { .ckp-fold > .ckp-dl { display: block !important; } }

/* ------------------------------------------- paying for the search button
   The bar was tuned in v5.8 to hold a mark, a wordmark and nine rooms inside
   1280px with nothing to spare. v5.9 adds a real logo and a search
   disclosure, and both cost width the rooms do not have — measured, the
   strip ran 105px past its edge and clipped "Stories" clean off with no
   sign that anything was missing.

   The width is bought back rather than borrowed: the mark is sized to the
   old tile above, the disclosure is 30px, the rooms give up 2px of padding
   each side, and the wordmark now steps aside at 1320 rather than 1220. What
   is left over is handled honestly by the fade below, which is now driven by
   measurement instead of a media query — so if a font substitution makes the
   rooms wider than they were measured at, the strip *looks* scrollable
   instead of quietly ending. */
.topbar .mainnav { margin-left: 12px; }
.topbar .mainnav a { padding: 0 7px; }
.topbar .logo-word b { letter-spacing: .06em; }
@media (max-width: 1320px) { .topbar .logo-word { display: none; } }
@media (max-width: 1320px) { .topbar .mainnav { margin-left: 10px; } }

/* The fade is a sibling overlay on .mainnav, never a mask on .navlinks —
   see the v5.8 note above; a mask makes .navlinks a containing block for the
   fixed dropdown panels and clips every one of them out of existence. */
.topbar .mainnav.is-scrollable::after {
  content: ""; position: absolute; right: 0; top: 0; bottom: 0; width: 26px;
  background: linear-gradient(to right, transparent, var(--black));
  pointer-events: none; z-index: 1;
}
.topbar .mainnav.is-scrollable.at-end::after { opacity: 0; }
/* The wrap's 16px flex gap was doing the same job as .mainnav's margin-left,
   twice over — 32px of it, between the logo and the rooms and again between
   the rooms and the search. One spacing mechanism, stated once. */
.topbar > .wrap { gap: 0; }

/* ------------------------------------ overview cards that carry a section
   Most glance cards are excerpts. A few are the section itself — the FBAHL
   pool is the whole reason people open that page, and reading it meant
   scrolling past two other boards into a tab. Those cards get a filter and
   a scrolling body under a sticky header. */
.glance-search {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px; border-bottom: 1px solid var(--gray-rule);
  background: var(--paper-2);
}
.glance-search input {
  flex: 1 1 auto; min-width: 0;
  padding: 7px 11px; font-size: 13.5px; border-radius: var(--radius-sm);
  border: 1px solid var(--gray-rule-2); background: #fff; color: var(--ink);
}
.glance-search input:focus { border-color: var(--fsn-red); outline: none;
  box-shadow: 0 0 0 3px var(--fsn-red-wash); }
.glance-search .n {
  flex: 0 0 auto; font: 600 11px/1 var(--mono); color: var(--gray-text);
  white-space: nowrap;
}
.glance-search-empty {
  margin: 0; padding: 22px 16px; font-size: 13.5px; color: var(--gray-text);
}

.glance-body--scroll {
  max-height: var(--glance-h, 520px); overflow-y: auto; overscroll-behavior: contain;
}
/* the header has to stay put, or a 121-row scroll is unreadable by row 20 */
.glance-body--scroll table.data thead th {
  position: sticky; top: 0; z-index: 2; background: var(--paper-2);
  box-shadow: inset 0 -1px 0 var(--gray-rule);
}
.glance-body--scroll > .table-scroll { max-height: none; overflow-y: visible; }
@media (max-width: 900px) { .glance-body--scroll { max-height: 60vh; } }
/* one line per row in a scrolling card; the full text is on the element's
   title and printed in full in the section the card links to */
.glance-body--scroll .qwhy {
  display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 100%;
}
/* The ruling column has no natural width, so it pushed the table past the
   card and the clamp above clipped mid-word at the card wall instead of
   ellipsing at the column edge. Cap the cell; the table then fits the card. */
.glance-body--scroll table.data { min-width: 0; width: 100%; }
.glance-body--scroll table.data td.qcell { max-width: 330px; }

/* ------------------------------------------------ the draft grid, v5.9 */
.nametoggle {
  display: inline-flex; align-items: center; gap: 6px; margin-left: auto;
}
.nametoggle .nt-lbl {
  font: 700 10px/1 var(--cond); letter-spacing: .11em; text-transform: uppercase;
  color: var(--gray-text);
}
.nametoggle button {
  border: 1px solid var(--gray-rule-2); background: var(--paper);
  color: var(--ink-2); cursor: pointer; padding: 5px 11px;
  font: 700 11px/1 var(--cond); letter-spacing: .09em; text-transform: uppercase;
  border-radius: var(--radius-sm);
}
.nametoggle button + button { margin-left: -1px; }
.nametoggle button:hover { background: var(--paper-2); }
.nametoggle button[aria-pressed="true"] {
  background: var(--fsn-red); border-color: var(--fsn-red); color: #fff;
}
.nametoggle button:focus-visible { outline: 2px solid var(--fsn-red);
  outline-offset: 1px; }

/* Club names are three to five times the length of a GM's first name, so the
   grid stops trying to hold fourteen equal columns and lets its scroller do
   the work — which now announces itself, per v5.4. */
.draft-grid.is-clubnames td, .draft-grid.is-clubnames th { white-space: nowrap; }

/* A conditional pick is not the same thing as a traded one: the pink cell
   says "this changed hands", the ring says "this is still owed". */
.draft-grid td.is-conditional {
  box-shadow: inset 0 0 0 2px var(--fsn-red);
  font-weight: 700;
}
.gk-cond { background: var(--paper); box-shadow: inset 0 0 0 2px var(--fsn-red); }
.gridkey [data-cond-note] { color: var(--gray-text); }

/* An overview is a denser reading than the section it excerpts, and this
   particular table is 15 columns wide. */
.glance-body .draft-grid th, .glance-body .draft-grid td {
  padding-left: 5px; padding-right: 5px; font-size: 12px;
}
.glance-body .draft-grid td:first-child { white-space: nowrap; }

/* ---------------------------------------------- the latest deal, in voice
   v5.6 gave this card a solid red header bar with a gold rule under it. On a
   page where every other panel — the headline rail, the glance cards, the GM
   cockpit — is a white card with a quiet paper header and a red edge, one
   scarlet slab reads as an advert someone dropped into the layout rather than
   as the newest entry in the ledger. Same card language as everything else
   now; the red is the edge, not the field. The chips are untouched — they
   already borrow the prospect-gate chip palette. */
.dc-top {
  padding: 11px 16px 10px;
  background: var(--paper-2); color: var(--ink);
  border-bottom: 1px solid var(--gray-rule);
  box-shadow: inset 3px 0 0 var(--fsn-red);
  align-items: baseline;
}
.dc-top b {
  font: 700 12.5px/1 var(--cond); letter-spacing: .13em; text-transform: uppercase;
}
.dc-meta {
  font: 400 11px/1 var(--mono); letter-spacing: 0; text-transform: none;
  color: var(--gray-text);
}
.deal-card { box-shadow: var(--sh-1); }
.deal-card:hover { box-shadow: var(--sh-2); }
/* see the note in fsn.js: the slack moves from the head list to the fold the
   moment the folds are open, so the summary bars stay on one line */
.cockpit.folds-open .ckp-dl--head { flex: 0 0 auto; }
.cockpit.folds-open .ckp-fold { flex: 1 1 auto; }
/* The keeper panel's head row carries a grade chip and the other two carry
   plain text, so its natural height ran 4px over theirs and the open summary
   bars sat a hair out of line. Give the head row one line box whatever is
   in it. */
.ckp-dl--head dd { min-height: 20px; display: flex; align-items: center;
  flex-wrap: wrap; gap: 0 5px; }
/* Two panels lead on a 38px numeral and one leads on a grade chip, and the
   chip's box ran 4px taller — which, now that the folds open together, put
   one summary bar out of line with the other two. Pin the lead row's height
   and keep the chip inside it. */
.ckp-lead { min-height: 62px; align-items: center; }
/* The chip lives inside the same <b> the numeral does, and that <b> sets a
   38px strut. An inline-block on the baseline of a 38px strut adds its own
   descent to the line box — which is where the 4px came from, not the chip's
   own box. inline-flex takes the chip out of that baseline arithmetic. */
.ckp-lead > b { display: inline-flex; align-items: center; }
.ckp-lead .gradechip { line-height: 1.45; padding: 1px 10px; }

/* ---------------------------------------------- key dates, actually dated
   The old highlight was `.dates--next .date-card:first-child` — a position.
   fsn.js now reads the dates and marks the cards, so the styling follows the
   calendar. `.dates--dated` is only set once every date on the strip parsed,
   so a strip the script could not read keeps exactly its old appearance. */
.dates--dated.datestrip { grid-auto-flow: dense; }
.dates--dated .date-card:first-child { grid-column: auto; background: var(--paper); }
.dates--dated .date-card:first-child .d { font-size: 11px; font-weight: 700; }

.date-card .when {
  margin-left: 8px; padding: 1px 7px; border-radius: 999px;
  font: 600 9.5px/1.7 var(--sans); letter-spacing: .06em; text-transform: uppercase;
  background: var(--paper-3); color: var(--gray-text); vertical-align: 1px;
}
.date-card .when:empty { display: none; }

/* what is next: first in the strip, wider, and counted down */
.dates--dated .date-card.is-next {
  order: -1; grid-column: span 2;
  background: linear-gradient(to bottom, var(--paper), var(--fsn-red-wash));
}
.dates--dated .date-card.is-next .d { font-size: 17px; font-weight: 700; }
.dates--dated .date-card.is-next .when {
  background: var(--fsn-red); color: #fff;
}

/* what is done: still on the strip, plainly behind us */
.dates--dated .date-card.is-past {
  border-top-color: var(--gray-rule-2); background: var(--paper-2);
  box-shadow: none;
}
.dates--dated .date-card.is-past .d { color: var(--gray-text); }
.dates--dated .date-card.is-past .l { color: var(--ink-2); }
.dates--dated .date-card.is-past:hover { transform: none; box-shadow: var(--sh-1); }

@media (max-width: 620px) {
  .dates--dated .date-card.is-next { grid-column: 1 / -1; }
}

/* ==========================================================================
   FSN v5.10 — Series One: the claim band and the binder.
   ========================================================================== */

/* ------------------------------------------------- the pack, in the rail
   It began as a fixed pop-up in the corner. A pop-up is an advert; this is
   meant to be an object sitting on the page that you want to pick up. So it
   lives in the rail under Top Headlines — a real slot, always in the same
   place — and does its work by looking grabbable rather than by appearing.

   The pack floats on its own, sheens every few seconds, and leans towards the
   pointer. Nothing about it moves the page. */
.packad {
  margin-top: 14px; border-radius: var(--radius); overflow: hidden;
  background: radial-gradient(120% 130% at 50% -20%, #1D2836 0%, #0C121B 58%, #07090E 100%);
  border: 1px solid #23262d;
  box-shadow: var(--sh-2);
}
.packad-go {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 3px; padding: 20px 20px 22px; text-decoration: none; color: #E8EFF5;
}
.packad-kick {
  font: 700 9.5px/1 var(--sans); letter-spacing: .24em; text-transform: uppercase;
  color: #C8A24B; margin-bottom: 15px;
}
.packad-go b {
  margin-top: 17px; font: 700 16px/1.15 var(--cond); letter-spacing: .09em;
  text-transform: uppercase; color: #fff;
}
.packad-sub {
  font-size: 12px; line-height: 1.5; color: #8FA3B8; max-width: 30ch; margin-top: 5px;
}
.packad-cta {
  margin-top: 13px; padding: 9px 16px; border-radius: var(--radius-sm);
  border: 1px solid #C8A24B; background: rgba(200,162,75,.13); color: #FFF3CC;
  font: 700 10px/1 var(--cond); letter-spacing: .16em; text-transform: uppercase;
  transition: background .14s ease;
}
.packad-go:hover .packad-cta { background: rgba(200,162,75,.28); }

/* -------------------------------------------------------------- the pack */
.packad-pack { position: relative; display: block; width: 116px; height: 156px; perspective: 760px; }
.pp-body {
  position: absolute; inset: 0; border-radius: 6px; overflow: hidden;
  transform-style: preserve-3d;
  transform: rotateX(var(--px, 5deg)) rotateY(var(--py, -15deg));
  transition: transform .3s cubic-bezier(.2,.9,.25,1);
  background: linear-gradient(147deg, #10243a 0%, #1d3d5e 30%, #0b1a2b 52%, #24486d 74%, #0a1522 100%);
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,.16),
    inset 0 -22px 30px rgba(0,0,0,.45),
    0 18px 26px -12px rgba(0,0,0,.8);
  animation: pp-float 5.5s ease-in-out infinite;
}
@keyframes pp-float { 0%,100% { translate: 0 0; } 50% { translate: 0 -8px; } }
.packad-go:hover .pp-body {
  animation-play-state: paused;
  transform: rotateX(2deg) rotateY(0deg) scale(1.07);
}
.pp-serr {
  position: absolute; left: 0; right: 0; height: 13px; opacity: .8;
  background: repeating-linear-gradient(90deg, rgba(255,255,255,.34) 0 1px, rgba(0,0,0,.34) 1px 3px);
}
.pp-serr.top { top: 0; box-shadow: 0 1px 0 rgba(0,0,0,.5); }
.pp-serr.bot { bottom: 0; box-shadow: 0 -1px 0 rgba(0,0,0,.5); }
.pp-face {
  position: absolute; inset: 16px 9px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px; text-align: center;
}
.pp-net { font: 700 5px/1 var(--sans); letter-spacing: .2em; text-transform: uppercase;
  color: rgba(232,239,245,.6); }
.pp-mark { font: 700 32px/1 var(--cond); letter-spacing: .06em; color: #fff;
  text-shadow: 0 1px 0 rgba(0,0,0,.5); }
.pp-rule { width: 66%; height: 2px; background: var(--fsn-red); margin: 4px 0 6px; }
.pp-dia {
  display: grid; place-items: center; width: 38px; height: 38px; margin-bottom: 6px;
  transform: rotate(45deg); border: 1px solid rgba(200,162,75,.85);
  color: #E8C878; font: 700 11px/1 var(--cond); letter-spacing: .04em;
}
.pp-dia::before { content: "S11"; transform: rotate(-45deg); }
.pp-ser { font: 700 9px/1 var(--cond); letter-spacing: .17em; text-transform: uppercase; color: #fff; }
.pp-yr { font: 500 7px/1 var(--mono); letter-spacing: .14em; color: rgba(200,162,75,.85); }
.pp-sheen {
  position: absolute; inset: -40% -120%; pointer-events: none;
  background: linear-gradient(100deg, transparent 42%, rgba(255,255,255,.42) 50%, transparent 58%);
  animation: pp-sweep 4.6s ease-in-out infinite;
}
@keyframes pp-sweep {
  0%, 62% { transform: translateX(-42%); opacity: 0; }
  70%     { opacity: .9; }
  100%    { transform: translateX(42%); opacity: 0; }
}
.pp-shadow {
  position: absolute; left: 14%; right: 14%; bottom: -10px; height: 10px;
  border-radius: 50%; background: rgba(0,0,0,.55); filter: blur(6px);
  animation: pp-shrink 5.5s ease-in-out infinite;
}
@keyframes pp-shrink {
  0%, 100% { transform: scaleX(1); opacity: .5; }
  50%      { transform: scaleX(.8); opacity: .3; }
}
@media (prefers-reduced-motion: reduce) {
  .pp-body, .pp-sheen, .pp-shadow { animation: none; }
  .pp-body { transition: none; }
}
/* v5.12: the rail is now the taller column and that is fine.
   The old arrangement stretched the hero to match the rail so the two columns
   ended level. Adding a 356px pack panel to the rail turned that into a 640px
   slab of gradient with a caption at the bottom; capping the hero instead left
   230px of empty page under the trade card, because the grid was still
   stretching the column its content no longer filled.

   So neither column is stretched any more. Each is its natural height, the
   rail is simply taller, and The League starts under both. */
.layout-rail { align-items: start; }
.layout-rail > .rail-main > .hero { flex: 0 0 auto; min-height: 440px; }
/* the rail is the taller column now, so the hero is given real presence
   rather than being sized to chase it */
