/* ==========================================================================
 * nflschedule.colesalgopicks.com — one stylesheet, no framework.
 * Tokens intentionally mirror the ColesAlgo network palette so the tool reads
 * as part of the family, with its own accent (field green / chalk gold).
 * ========================================================================*/
:root{
  --bg:#080a0e; --bg-2:#0d0f14; --panel:#14161d; --panel-2:#1b1e27; --panel-3:#242833;
  --border:#232733; --border-2:#313644; --hairline:rgba(255,255,255,.06);
  /* --line and --ease were used 13 times and DEFINED NOWHERE. An
     undefined custom property with no fallback is invalid at
     computed-value time, so every one of those declarations silently
     reset to initial: `border:medium none` instead of a hairline on
     nine rules, ALL row separators gone from .rectbl (its fallback
     named --line-2, which is also undefined), and the LIVE pulse
     animation never ran at all. No error, no warning, no test
     failure - which is why it survived. Aliased rather than renamed
     so both names keep working and the theme blocks still drive them. */
  --line:var(--border);--line-2:var(--border-2);
  --ease:cubic-bezier(.4,0,.2,1);
  /* --muted-2 was #6f7682, which measured 4.33:1 on the page background,
     3.95:1 on a panel and 3.39:1 on a muted chip. That is every role the token
     has, under 4.5:1, with no large text among them: the breadcrumb, the
     footer, the table headers on /standings/, the muted chips, and the bye and
     no-game cells that fill most of /grid/. #8a919e measures 6.25:1 on the
     background and 5.70:1 on a panel, and still clears 4.5:1 on the lightest
     surface the token lands on (4.64:1 on --panel-3). Contrast is a property
     of the two colours, so those ratios did not change with the sport. */
  --text:#f4f5f8; --text-2:#cbcfd9; --muted:#9aa0ad; --muted-2:#8a919e;
  --pos:#5fd2a0; --neg:#ff7d8c; --warn:#f5c66b;
  --accent:#6ee7a8; --accent-2:#f5c542; --accent-ink:#07120c;
  /* the losing half of a comparison bar: chosen to clear 3:1 against the card
     it sits on, because at 1.23:1 the chart read as one team having bars and
     the other having nothing */
  --bar-track:#6b7386;
  --r-xs:7px; --r-sm:10px; --r-md:14px; --r-lg:18px;
  --shadow-sm:0 1px 2px rgba(0,0,0,.45);
  --shadow-md:0 8px 24px -8px rgba(0,0,0,.55);
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,Helvetica,Arial,sans-serif;
}
*{box-sizing:border-box}
/* The [hidden] attribute is how every filter on this site removes a row, and
   the browser only honours it through a UA rule of `display:none`. Any author
   rule that sets `display` on the same element beats that UA rule, so a
   `.game{display:grid}` row kept rendering while JS believed it was gone: the
   conference filter marked most of a board hidden, the counter agreed with the
   filter, and every filtered row stayed on screen anyway. Filtering is a
   display concern, so it is settled here once for every component instead of
   per class. */
[hidden]{display:none !important}
img{max-width:100%;height:auto}
/* every team mark on the site is a square logo: give them ONE rule instead of
   per-component widths that a new component can forget to opt into */
.team img,.copp h4 img,.vs .side img,.bteam img,.pk img,.tbl img,.hero img,
.champmini img{object-fit:contain;flex:0 0 auto}
.vs .side img{width:26px;height:26px}
.tbl img,.copp h4 img,img.tlogo{width:18px;height:18px}
.vs .side img.tlogo{width:26px;height:26px}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--bg); color:var(--text); font-family:var(--sans);
  font-size:15px; line-height:1.45; -webkit-font-smoothing:antialiased;
  background-image:radial-gradient(1100px 560px at 50% -10%,rgba(110,231,168,.07),transparent 70%);
  background-attachment:scroll;
}
a{color:inherit;text-decoration:none}
a:hover{color:var(--accent)}
/* color:inherit plus text-decoration:none left inline links with no cue at
   all. On /grid/, /glossary/ and /standings/ the link and the sentence around
   it were both #9aa0ad, same weight, no underline: nothing said the words were
   clickable. Underline only the containers that actually hold sentences - the
   page subtitle, card hints, .tiny notes, real paragraphs - and leave the nav,
   the week strip, game rows and table team links alone, because those are
   whole targets with their own borders and hover states. */
main p a,main .sub a,main .hint a,main .tiny a{
  text-decoration:underline;text-underline-offset:2px}
.wrap{max-width:1180px;margin:0 auto;padding:0 16px}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}

/* ---------- top bar ---------- */
.topbar{position:sticky;top:0;z-index:40;background:rgba(8,10,14,.92);
  backdrop-filter:blur(10px);border-bottom:1px solid var(--border)}
.topbar .wrap{display:flex;align-items:center;gap:18px;height:56px;position:relative}
.brand{display:flex;align-items:center;gap:9px;font-weight:800;letter-spacing:-.02em;
  font-size:16px;white-space:nowrap}
.brand .dot{width:9px;height:9px;border-radius:2px;background:var(--accent);
  box-shadow:0 0 12px rgba(110,231,168,.7)}
.brand small{color:var(--muted);font-weight:600;font-size:11px;letter-spacing:.08em;
  text-transform:uppercase}
.nav{display:flex;gap:2px;margin-left:auto;align-items:center}
/* no overflow-x here any more: a nav that scrolls sideways on a desktop is a
   nav with links nobody will ever find */
.nav a,.navbtn{padding:7px 11px;border-radius:var(--r-xs);color:var(--text-2);font-size:13.5px;
  font-weight:600;white-space:nowrap}
.nav a:hover,.navbtn:hover{background:var(--panel-2);color:var(--text)}
.nav a.on,.navbtn.on{background:var(--panel-3);color:var(--text)}

/* ---------- grouped navigation ---------- */
/* WITHOUT JAVASCRIPT THE BUTTON CANNOT OPEN ANYTHING.
   The mobile sheet was gated on [data-js] for exactly this reason and the
   desktop groups were not, so a reader with scripting off could reach four of
   seventeen destinations and the other thirteen sat in panels nothing could
   open. The default is now the honest one - no buttons, every link in the row -
   and the collapsing only happens where there is script to uncollapse it. */
.navbtn{display:none;align-items:center;gap:5px;background:none;
  border:0;cursor:pointer;font:inherit;font-size:13.5px;white-space:nowrap}
html[data-js] .navbtn{display:inline-flex}
.navgroup{display:contents}
html[data-js] .navgroup{display:block;position:relative}
.nav{flex-wrap:wrap}
html[data-js] .nav{flex-wrap:nowrap}
.navbtn .caret{width:0;height:0;border-left:3.5px solid transparent;
  border-right:3.5px solid transparent;border-top:4px solid currentColor;
  opacity:.7;transition:transform .15s ease}
.navbtn[aria-expanded="true"]{background:var(--panel-3);color:var(--text)}
.navbtn[aria-expanded="true"] .caret{transform:rotate(180deg)}
.navmenu{display:contents}
html[data-js] .navmenu{display:none;position:absolute;right:0;top:calc(100% + 6px);z-index:60;
  min-width:190px;padding:6px;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--r-sm,8px);
  box-shadow:0 14px 34px rgba(0,0,0,.55)}
html[data-js] .navmenu.open{display:block}
.navmenu-head{display:none}
.navmenu a{display:block;padding:8px 10px;white-space:nowrap}
.navmenu a.on{background:var(--panel-3);color:var(--accent)}

/* ---------- page head ---------- */
.phead{padding:26px 0 14px}
.phead h1{margin:0 0 6px;font-size:26px;letter-spacing:-.03em;line-height:1.15}
.phead .sub{color:var(--muted);font-size:13.5px}
.crumb{color:var(--muted-2);font-size:12px;letter-spacing:.06em;text-transform:uppercase;
  font-weight:700;margin-bottom:8px}

/* ---------- week strip ---------- */
.weekstrip{display:flex;gap:6px;overflow-x:auto;padding:10px 0 12px;scrollbar-width:thin}
.weekstrip a{flex:0 0 auto;padding:7px 12px;border:1px solid var(--border);
  border-radius:999px;font-size:13px;font-weight:700;color:var(--text-2);background:var(--panel)}
.weekstrip a:hover{border-color:var(--border-2);color:var(--text)}
.weekstrip a.on{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.weekstrip a small{display:block;font-size:10px;font-weight:600;opacity:.7;letter-spacing:.02em}

/* ---------- filters ---------- */
.filters{position:sticky;top:56px;z-index:30;background:rgba(13,15,20,.95);
  backdrop-filter:blur(8px);border:1px solid var(--border);border-radius:var(--r-md);
  padding:10px;margin:6px 0 14px;display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.filters label{display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--muted)}
select,input[type=search],input[type=text]{
  background:var(--panel-2);color:var(--text);border:1px solid var(--border-2);
  border-radius:var(--r-xs);padding:6px 9px;font-size:13px;font-family:inherit;min-width:0}
select:focus,input:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 3px rgba(110,231,168,.18)}
.chk{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--text-2);
  background:var(--panel-2);border:1px solid var(--border);border-radius:var(--r-xs);
  padding:6px 9px;cursor:pointer;user-select:none}
.chk input{accent-color:var(--accent);margin:0}
.chk:hover{border-color:var(--border-2)}
.count{margin-left:auto;color:var(--muted);font-size:12.5px;font-weight:600}
.btn{background:var(--panel-2);border:1px solid var(--border-2);border-radius:var(--r-xs);
  color:var(--text);padding:6px 11px;font-size:13px;font-weight:600;cursor:pointer;font-family:inherit}
.btn:hover{border-color:var(--accent);color:var(--accent)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}

/* ---------- day header ---------- */
.dayhead{display:flex;align-items:baseline;gap:10px;margin:20px 0 8px;
  padding-bottom:6px;border-bottom:1px solid var(--border)}
.dayhead h2{margin:0;font-size:14px;letter-spacing:.06em;text-transform:uppercase;color:var(--text-2)}
.dayhead span{color:var(--muted-2);font-size:12px}

/* the day being played right now - marked by app.js, never at build time, so
   it cannot be left over from yesterday. Both rules degrade to nothing when
   the class is absent, which is what a reader without JS gets. */
.dayhead.is-today{border-bottom-color:var(--accent)}
.dayhead.is-today h2{color:var(--accent)}
.dayhead h2 .todaychip{margin-left:8px;padding:1px 7px;border-radius:999px;
  background:var(--accent);color:var(--accent-ink);font-size:10px;
  letter-spacing:.08em;vertical-align:2px}
a.todayjump{display:inline-block;margin:14px 0 0;padding:6px 12px;
  border:1px solid var(--border);border-radius:999px;background:var(--panel-2);
  color:var(--text-2);font-size:12px;text-decoration:none}
a.todayjump:hover{border-color:var(--accent);color:var(--accent)}

/* ---------- game rows ---------- */
.games{display:flex;flex-direction:column;gap:6px}
/* Column widths are a claim about the widest thing that can land in them.
   The kickoff cell has to hold "12:30am Sun" - 87px - which nobody in the
   United States ever sees, and the odds cell has to hold the line-movement
   note, which is the longest string on the row. Both used to be narrower
   than their own content, and nowrap text that overflows does not clip:
   it prints across the venue beside it. tests/overlap_test.js measures it. */
.game{display:grid;grid-template-columns:92px minmax(0,1fr) 192px 168px;gap:12px;
  align-items:center;background:var(--panel);border:1px solid var(--border);
  border-radius:var(--r-sm);padding:9px 12px}
.game:hover{border-color:var(--border-2);background:var(--panel-2)}
.game .kick{font-family:var(--mono);font-size:12.5px;color:var(--muted);white-space:nowrap}
.game .kick b{display:block;color:var(--text-2);font-size:13px;font-weight:700}
.mu{display:flex;flex-direction:column;gap:3px;min-width:0}
.team{display:flex;align-items:center;gap:8px;min-width:0}
.team img{width:20px;height:20px;object-fit:contain;flex:0 0 20px}
.team .nm{font-size:14px;font-weight:650;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.team .rec{color:var(--muted-2);font-size:11.5px;font-family:var(--mono)}
.team .sc{margin-left:auto;font-family:var(--mono);font-weight:800;font-size:14px;color:var(--muted)}
.team.win .sc,.team.win .nm{color:var(--text)}
.team.lose .nm,.team.lose .sc{color:var(--muted)}
.team.win .nm::after{content:"";}
.rank{font-family:var(--mono);font-size:11px;font-weight:800;color:var(--accent-2);flex:0 0 auto}
.at{color:var(--muted-2);font-size:11px;font-weight:700;flex:0 0 auto}
.meta{font-size:11.5px;color:var(--muted);display:flex;flex-direction:column;gap:2px;
  text-align:right;justify-self:end;min-width:0;max-width:100%}
.meta span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.meta .tv{color:var(--text-2);font-weight:700}
.line{font-family:var(--mono);font-size:12px;color:var(--muted);text-align:right;white-space:nowrap}
.line b{color:var(--text-2)}
.tags{display:flex;gap:4px;flex-wrap:wrap;margin-top:2px}
.tag{font-size:10px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;
  padding:1px 5px;border-radius:4px;background:var(--panel-3);color:var(--muted)}
.tag.conf{background:rgba(110,231,168,.14);color:var(--accent)}
.tag.pick{background:rgba(245,197,66,.18);color:var(--accent-2);font-weight:800}
.tag.neutral{background:rgba(245,197,66,.14);color:var(--accent-2)}
.tag.rk{background:rgba(245,197,66,.16);color:var(--accent-2)}
/* the quiet variant of a chip: used where the chip is an admission rather
   than a label - "not derivable from picks" on the tiebreaker pages */
.tag.dim{background:rgba(255,255,255,.06);color:var(--muted-2)}
.final{color:var(--accent);font-weight:800;font-size:11px;letter-spacing:.06em}
/* A game that is not being played. Deliberately not the accent colour:
   FINAL and POSTPONED are opposite kinds of news and reading one as the
   other at a glance is the whole risk. */
.calledoff{color:var(--warn,#e0a750);font-weight:800;font-size:11px;
  letter-spacing:.06em;text-transform:uppercase}
.live{color:#ff7d8c;font-weight:800;font-size:11px;letter-spacing:.06em}

/* ---------- generic cards / tables ---------- */
.card{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-md);
  padding:14px;margin:12px 0}
.card h2,.card h3{margin:0 0 10px;font-size:13px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted)}
.grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px}
.grid3{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:10px}
.stat{background:var(--panel-2);border:1px solid var(--border);border-radius:var(--r-sm);padding:10px 12px}
.stat .k{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted-2);font-weight:700}
.stat .v{font-size:20px;font-weight:800;letter-spacing:-.02em;font-family:var(--mono)}
.stat .n{font-size:11.5px;color:var(--muted)}
.tblwrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
/* A fade on the edge that is still to come, so a reader can SEE there is more
   table than screen. app.js adds .can-scroll only to the wrappers that really
   overflow, so a table that fits is not decorated with a promise of more. */
.tblwrap.can-scroll{position:relative;
  -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent);
  mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent)}
/* THE MASK PAINTS THE OUTLINE TOO. A mask applies to everything the element
   draws, its focus ring included, so the ring for a keyboard user arrived
   faded on the right and invisible at the edge - the fade silently cancelled
   the focus indicator on exactly the tables it was added to help. While the
   wrapper has focus there is no fade: the ring is worth more than the hint. */
.tblwrap.can-scroll:focus-visible{outline:2px solid var(--accent);outline-offset:2px;
  -webkit-mask-image:none;mask-image:none}
/* Two seasons of betting record share one label column so they can actually be
   compared, instead of being two stacked blocks a reader holds in their head. */
.rectbl{width:100%;border-collapse:collapse}
.rectbl th,.rectbl td{padding:6px 8px;text-align:right;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.rectbl thead th{color:var(--text-2);font-size:11px;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;border-bottom:1px solid var(--line)}
.rectbl tbody th{text-align:left;font-weight:400;color:var(--text-2)}
.rectbl tbody tr+tr th,.rectbl tbody tr+tr td{border-top:1px solid var(--line-2,var(--line))}
.rectbl tbody td{color:var(--text)}
/* A TABLE IN A SCROLLING WRAPPER HAS TO BE ALLOWED TO BE WIDER THAN IT.
   width:100% alone means it never exceeds the wrapper, so it never scrolls -
   it squashes, and cells whose text cannot shrink print over their neighbours.
   The roster's seven columns on a 390px phone rendered as "Judd AndQBerson".
   min-width:max-content lets the wrapper do the job it exists for; where the
   content fits, width:100% still wins and nothing changes. */
table.tbl{width:100%;border-collapse:collapse;font-size:13.5px}
/* ONLY IN A SCROLLER. A table allowed to exceed its container is fine inside
   .tblwrap, which scrolls, and is a page that scrolls sideways anywhere else -
   several tables on this site are written without a wrapper. */
.tblwrap>table.tbl{min-width:max-content}
/* A ROW HEADER IS NOT A COLUMN HEADER. The team cell in the standings is a
   <th scope="row"> so a screen reader knows whose row it is; without this it
   would inherit the column styling and render 138 team names as tiny uppercase
   grey text. Semantics changed, appearance did not. */
table.tbl tbody th{font-size:inherit;letter-spacing:normal;text-transform:none;
  color:inherit;font-weight:400;background:none}
table.tbl th{text-align:left;font-size:11px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted-2);font-weight:800;padding:7px 9px;border-bottom:1px solid var(--border-2);
  white-space:nowrap;background:var(--panel)}
/* NO position:sticky HERE. Every .tbl on this site sits in a .tblwrap, and
   overflow-x:auto makes that wrapper the scroll container on BOTH axes - it is
   content-height, so it never scrolls vertically and the header never stuck.
   Measured: scrolling the page 600px moved the header 600px. The rule read as
   a feature in the stylesheet and did nothing on the screen. Column headers
   are held by the sticky FIRST COLUMN instead, which does work, because that
   is the axis these tables actually scroll on. */
table.tbl td{padding:7px 9px;border-bottom:1px solid var(--hairline);vertical-align:middle}
table.tbl tr:hover td{background:var(--panel-2)}
table.tbl td.num,table.tbl th.num{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums}
.wl{font-family:var(--mono);font-weight:800;font-size:12px;padding:1px 6px;border-radius:4px}
.wl.w{background:rgba(95,210,160,.16);color:var(--pos)}
.wl.l{background:rgba(255,125,140,.14);color:var(--neg)}
.wl.t{background:var(--panel-3);color:var(--muted)}
.tiny{font-size:11.5px;color:var(--muted)}
.hint{color:var(--muted);font-size:13px}
.empty{padding:28px;text-align:center;color:var(--muted);background:var(--panel);
  border:1px dashed var(--border-2);border-radius:var(--r-md)}

/* ---------- team hero ---------- */
.hero{border:1px solid var(--border);border-radius:var(--r-md);padding:16px;
  display:flex;align-items:center;gap:14px;margin:6px 0 4px;
  background:linear-gradient(120deg,var(--tc,#222) -30%,var(--panel) 60%)}
.hero img{width:54px;height:54px;object-fit:contain}
.hero h1{margin:0;font-size:24px;letter-spacing:-.03em}
.hero .sub{color:var(--text-2);font-size:13px;margin-top:3px}
.hero .rec{margin-left:auto;text-align:right;font-family:var(--mono)}
.hero .rec b{font-size:26px;font-weight:800;display:block;letter-spacing:-.02em}

/* ---------- grid matrix ---------- */
.matrix{font-size:11.5px;border-collapse:separate;border-spacing:2px}
.matrix th{position:sticky;top:0;background:var(--bg-2);z-index:2;font-size:10px;padding:4px 5px}
.matrix td{padding:0}
.matrix .tname{position:sticky;left:0;background:var(--bg-2);z-index:1;white-space:nowrap;
  font-weight:700;padding:3px 8px 3px 4px;font-size:12px}
.cell{display:block;padding:4px 5px;border-radius:5px;background:var(--panel);
  border:1px solid var(--border);min-width:62px;text-align:center;font-family:var(--mono);
  font-size:11px;color:var(--text-2);white-space:nowrap}
.cell.away{background:var(--panel-2);color:var(--muted)}
.cell.bye{background:transparent;border-style:dashed;color:var(--muted-2)}
.cell.w{border-color:rgba(95,210,160,.45)}
.cell.l{border-color:rgba(255,125,140,.4)}

/* ---------- compare ---------- */
.pickrow{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.vs{display:grid;grid-template-columns:1fr auto 1fr;gap:10px;align-items:center;
  background:var(--panel-2);border:1px solid var(--border);border-radius:var(--r-sm);
  padding:8px 10px;margin-bottom:6px}
.vs .side{display:flex;align-items:center;gap:8px;min-width:0}
.vs .side.r{justify-content:flex-end;text-align:right}
.vs .mid{font-size:11px;color:var(--muted-2);font-weight:800;text-align:center;white-space:nowrap}
.copp{border:1px solid var(--border);border-radius:var(--r-sm);padding:10px;background:var(--panel);margin-bottom:8px}
.copp h4{margin:0 0 8px;font-size:13.5px;display:flex;align-items:center;gap:8px}
.copp h4 img{width:18px;height:18px}

/* ---------- footer ---------- */
footer{margin:44px 0 30px;padding-top:16px;border-top:1px solid var(--border);
  color:var(--muted-2);font-size:12.5px;display:flex;flex-wrap:wrap;gap:10px 18px;align-items:center}
footer a{color:var(--muted)}
footer .grow{margin-left:auto}

/* ---------- mobile menu ----------
   Ten links (fourteen in predict mode) in a horizontally scrolling strip meant
   everything past "Top 25" was off screen with nothing to say it was there.
   Below 860px the strip becomes a sheet. Gated on [data-js] so a browser
   without JS keeps the scrolling strip rather than a button that does nothing. */
.hamb{display:none;flex-direction:column;justify-content:center;gap:4px;
  width:40px;height:36px;padding:0 9px;margin-left:auto;cursor:pointer;
  background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-xs)}
.hamb span{display:block;height:2px;background:var(--text-2);border-radius:2px;
  transition:transform .18s ease,opacity .18s ease}
.hamb[aria-expanded="true"] span{background:var(--text)}
.hamb[aria-expanded="true"] span:nth-child(1){transform:translateY(6px) rotate(45deg)}
.hamb[aria-expanded="true"] span:nth-child(2){opacity:0}
.hamb[aria-expanded="true"] span:nth-child(3){transform:translateY(-6px) rotate(-45deg)}

@media (max-width:860px){
  html[data-js] .hamb{display:flex}
  html[data-js] .topbar .wrap{gap:10px}
  html[data-js] .nav{display:none;position:absolute;left:0;right:0;top:100%;margin:0;
    grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;padding:10px;
    background:var(--panel);border-bottom:1px solid var(--line);
    box-shadow:0 14px 30px rgba(0,0,0,.5);overflow:visible;
    max-height:calc(100dvh - 56px);overflow-y:auto}
  html[data-js] .nav.open{display:grid}
  /* Two columns, because ten single-file rows are a full phone screen of menu.
     44px tall is the tap target; the type does not need to grow to match. */
  html[data-js] .nav a,html[data-js] .navbtn{display:flex;align-items:center;
    min-height:44px;padding:8px 12px;font-size:14px;line-height:1.2;
    background:var(--panel-2);border:1px solid transparent;text-align:left}
  html[data-js] .nav a.on,html[data-js] .navbtn.on{background:var(--panel-3);
    border-color:var(--accent);color:var(--accent);font-weight:700}
  /* On a phone there is nothing to save room for, so nothing is collapsed:
     every group is open under its own heading. A dropdown inside a dropdown is
     two taps to reach a link that could have been one. */
  html[data-js] .navgroup{grid-column:1/-1;position:static;display:grid;
    grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}
  html[data-js] .navbtn{display:none}
  html[data-js] .navmenu{display:grid;position:static;grid-column:1/-1;
    grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;padding:0;
    background:none;border:0;box-shadow:none;min-width:0}
  html[data-js] .navmenu-head{display:block;grid-column:1/-1;
    padding:8px 2px 0;font-size:11px;font-weight:700;letter-spacing:.08em;
    text-transform:uppercase;color:var(--text-2)}
}
@media (max-width:340px){
  html[data-js] .nav,html[data-js] .navgroup,
  html[data-js] .navmenu{grid-template-columns:1fr}
}

/* REFLOW ON A NARROW SCREEN, WHICH IS ALSO 400% ZOOM ON A 1280 WINDOW.
   The header is a non-wrapping flex row and the mode switch is flex:0 0 auto,
   so it could not fit and pushed the whole page 49px off the side - on every
   page, with the title reading "ek 1" and the brand reading "FB Schedule". The
   reader who needs 400% zoom is exactly the reader who cannot scroll sideways
   to find the rest of a sentence.

   THE BREAKPOINT IS MEASURED, NOT GUESSED. The header needs 374px at its
   normal sizing; the first attempt at this put the rule at 340px and left
   341-374 still overflowing, which the check caught at 360. 400 covers it with
   room, and every common phone width sits above the range where anything is
   dropped. */
@media (max-width:400px){
  .brand{font-size:14px}
  .brand .bword{display:none}
  .modesw .seg{padding:6px 9px;font-size:12px}
  .topbar .wrap{gap:8px}
}

/* ---------- responsive ---------- */
@media (max-width:860px){
  .game{grid-template-columns:92px minmax(0,1fr);row-gap:6px}
  .game .line{grid-column:1/-1;text-align:left;padding-left:104px}
  .game .meta{grid-column:1/-1;text-align:left;justify-self:start;flex-direction:row;
    gap:10px;flex-wrap:wrap;padding-left:104px}
  .filters{position:static}
  .phead h1{font-size:21px}
  .hero{flex-wrap:wrap}
  .hero .rec{margin-left:0;text-align:left}
}
@media (max-width:520px){
  .brand small{display:none}
  .game .line,.game .meta{padding-left:0}
}
@media print{ .topbar,.filters,.weekstrip,footer{display:none} body{background:#fff;color:#000} }

/* ==========================================================================
 * Predictor, playoff bracket, rankings
 * ========================================================================*/
.team.tbd .nm{color:var(--muted-2);font-style:italic}
/* AN EVENT ROW'S TITLE IS THE WHOLE ROW. A normal game row can ellipsize a
   team name because the crest and the opponent still identify it; a postseason
   row whose teams are not known yet has nothing else - "Super Bowl LXI at SoFi
   Stadium" truncated to "Super Bowl LX" is a row that no longer says which
   game it is, and it is one character from naming a different one. It wraps
   instead. */
.game.event .mu .nm{font-weight:700;white-space:normal;overflow:visible}
.game.event{border-style:dashed}

.predbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;background:var(--panel);
  border:1px solid var(--border);border-radius:var(--r-md);padding:10px;margin:10px 0}
.predgrid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(300px,.85fr);gap:14px;
  align-items:start}
.predpicks{display:flex;flex-direction:column;gap:4px}
.predout{position:sticky;top:70px}
.pdayhead{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted-2);
  font-weight:800;margin:12px 0 2px}
.prow{display:grid;grid-template-columns:minmax(0,1fr) 22px minmax(0,1fr) 74px;
  gap:6px;align-items:center;background:var(--panel);border:1px solid var(--border);
  border-radius:var(--r-sm);padding:5px 8px}
.prow.locked{opacity:.72}
.pdate{white-space:nowrap}
.pat{color:var(--muted-2);font-size:10.5px;text-align:center;font-weight:700}
.pmeta{text-align:right}
.pk{display:flex;align-items:center;gap:6px;min-width:0;width:100%;cursor:pointer;
  background:var(--panel-2);border:1px solid var(--border);border-radius:var(--r-xs);
  padding:5px 8px;color:var(--text-2);font-family:inherit;font-size:13px;text-align:left}
.pk img{width:18px;height:18px;object-fit:contain;flex:0 0 18px}
.pk .pkn{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:650}
.pk .pks{margin-left:auto;font-family:var(--mono);font-weight:800}
.pk:hover{border-color:var(--border-2);color:var(--text)}
.pk.on{background:rgba(110,231,168,.14);border-color:var(--accent);color:var(--text)}
.pk.on .pkn{font-weight:800}
.pk.lock{cursor:default}
.pk.big{padding:9px 12px;font-size:15px}
.pk.big img{width:26px;height:26px;flex:0 0 26px}

.champbox{background:var(--panel);border:1px solid var(--accent);border-radius:var(--r-md);
  padding:12px;margin-bottom:12px}
.champrow{display:grid;grid-template-columns:1fr auto 1fr;gap:8px;align-items:center;
  margin-top:8px}
.champgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:10px}
.champmini{background:var(--panel-2);border:1px solid var(--border);border-radius:var(--r-sm);
  padding:9px;display:flex;flex-direction:column;gap:5px}
h4.dv{margin:12px 0 6px;font-size:12px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--accent-2)}
table.tbl tr.in td{background:rgba(110,231,168,.07)}
table.tbl tr.in td:first-child{box-shadow:inset 2px 0 0 var(--accent)}
.proxy{color:var(--warn)}
ol.rules{margin:0;padding-left:20px;font-size:13.5px;color:var(--text-2)}
ol.rules li{margin-bottom:6px}
ol.rules .tag{margin-left:4px;vertical-align:1px}

.bracket{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
.bcol h4{margin:0 0 8px;font-size:11px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted-2)}
.bmatch{background:var(--panel-2);border:1px solid var(--border);border-radius:var(--r-sm);
  padding:8px;margin-bottom:8px;display:flex;flex-direction:column;gap:4px;align-items:stretch}
.bmatch>.tiny{text-align:center;color:var(--muted-2)}
.bteam{display:flex;align-items:center;gap:7px;font-size:13.5px;font-weight:650}
.bteam img{width:20px;height:20px;object-fit:contain}
.bteam .tiny{margin-left:auto;font-family:var(--mono)}
.bteam.empty2{color:var(--muted-2);font-style:italic;font-weight:500}
.bseed{font-family:var(--mono);font-size:11px;font-weight:800;color:var(--accent-2);
  min-width:16px;text-align:right}

a.stat{display:block;color:inherit}
a.stat:hover{border-color:var(--accent-2)}

@media (max-width:920px){
  /* minmax(0,1fr), not 1fr: a grid column defaults to min-width:auto, so the
     pick list held the page open 37px wider than a 320px screen and the whole
     document scrolled sideways. */
  .predgrid{grid-template-columns:minmax(0,1fr)}
  .predpicks{min-width:0}
  .predout{position:static;order:-1}
  .prow{grid-template-columns:minmax(0,1fr) 18px minmax(0,1fr);row-gap:4px}
  .pmeta{grid-column:1/-1;text-align:left}
}

/* ==========================================================================
 * Matchup preview pages
 * ========================================================================*/
.game.clickable{cursor:pointer}
.preview{color:var(--accent);font-weight:700;font-size:11px;white-space:nowrap}
.game:hover .preview{text-decoration:underline}

.mhead{display:grid;grid-template-columns:1fr auto 1fr;gap:12px;align-items:center;
  background:var(--panel);border:1px solid var(--border);border-radius:var(--r-md);
  padding:14px;margin:6px 0 12px}
.mteam{display:flex;align-items:center;gap:10px;min-width:0}
.mteam img{width:44px;height:44px;object-fit:contain;flex:0 0 44px}
.mname{font-size:17px;font-weight:750;letter-spacing:-.01em;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.mscore{margin-left:auto;font-family:var(--mono);font-size:26px;font-weight:800}
.mvs{text-align:center;display:flex;flex-direction:column;align-items:center;gap:2px;
  padding:0 6px;white-space:nowrap}
.mvs .kick{font-family:var(--mono);color:var(--muted)}
.mvs .kick b{display:block;color:var(--text-2);font-size:14px}

.mcompare{display:flex;flex-direction:column;gap:5px}
.mrow{display:grid;grid-template-columns:1fr 168px 1fr;gap:10px;align-items:center;
  padding:3px 0}
.mlabel{text-align:center;font-size:11.5px;color:var(--muted);letter-spacing:.02em}
.mbar-wrap{display:flex;align-items:center;gap:6px;position:relative;min-width:0;
  max-width:100%}
.mbar-wrap.a{flex-direction:row-reverse}
/* The losing half of every comparison was --panel-3 on --panel: 1.23:1, so the
   chart read as "one team has bars and the other has nothing" rather than as a
   comparison. The track is now a mid-tone that holds its own against the card,
   and the bars are constrained so a long one cannot push the row wider than the
   phone it is on. */
/* THE TRACK FLEXES; THE FILL DOES NOT. The fill carries an inline width -
   the whole point of the row - and it used to be the flex item itself with
   `flex:1 1 auto`, which grew it to fill and discarded that width. Both bars
   then rendered identically on all 888 preview pages while the caption said
   "a longer bar is always the better number". */
.mbar-track{flex:1 1 auto;min-width:0;height:8px;border-radius:99px;
  background:var(--bar-track);display:block;overflow:hidden}
.mbar{height:8px;border-radius:99px;background:var(--muted-2);display:block}
.mbar-wrap.a .mbar{margin-left:auto}
.mbar-wrap{overflow:hidden}
.mbar-v{font-family:var(--mono);font-size:12.5px;font-weight:700;color:var(--text-2);
  min-width:44px;text-align:right}
.mbar-wrap.b .mbar-v{text-align:left}
.mbar-empty{opacity:.5}
.lead-a .a .mbar{background:var(--accent)}
.lead-a .a .mbar-v{color:var(--text)}
.lead-b .b .mbar{background:var(--accent)}
.lead-b .b .mbar-v{color:var(--text)}

.form{display:flex;flex-wrap:wrap;gap:6px}
.fpill{display:flex;flex-direction:column;align-items:center;gap:1px;padding:5px 9px;
  border-radius:var(--r-xs);background:var(--panel-2);border:1px solid var(--border);
  font-family:var(--mono);font-size:12px;min-width:64px}
.fpill b{font-size:12px}
.fpill.w{border-color:rgba(95,210,160,.4)}
.fpill.w b{color:var(--pos)}
.fpill.l{border-color:rgba(255,125,140,.35)}
.fpill.l b{color:var(--neg)}
.trow{display:flex;justify-content:space-between;align-items:baseline;gap:10px;
  padding:5px 0;border-bottom:1px solid var(--hairline)}
.trow:last-child{border-bottom:0}
details.pdetails{margin-top:8px}
details.pdetails summary{cursor:pointer;font-size:12.5px;color:var(--muted);
  padding:5px 0}
details.pdetails summary:hover{color:var(--accent)}

@media (max-width:760px){
  .mhead{grid-template-columns:1fr;gap:8px}
  /* Predict mode injects .pickctl into .mvs, and a nowrap row of flex items
     that all default to min-width:auto has no way to break. On a 390px phone
     documentElement.scrollWidth measured 466px: .mvs and .mteam both laid out
     at 435px inside a 358px .mhead, and the pick buttons landed at x=345-460,
     cutting the team names by 54-70px so only the logo and the first letter
     survived. Predict mode is remembered in localStorage, so one tap did that
     to all 888 matchup previews until the reader toggled back. Letting the
     column wrap and shrink is the whole fix; the kickoff line keeps the nowrap
     it is the reason .mvs sets in the first place. */
  .mvs{flex-direction:row;flex-wrap:wrap;gap:10px;justify-content:center;
    white-space:normal;min-width:0}
  .mvs .kick{white-space:nowrap}
  .mrow{grid-template-columns:1fr 96px 1fr;gap:6px}
  .mlabel{font-size:10.5px}
  .mbar-v{min-width:38px;font-size:11.5px}
}

/* a sub-note inside a card heading is prose, not a label — the uppercase
   treatment belongs to the heading itself */
.card h2 .tiny,.card h3 .tiny{text-transform:none;letter-spacing:0;font-weight:600}

.serieslead{font-size:15px}
.serieslead b{color:var(--text)}

/* ---------- roster ---------- */
details.prow-r{border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--panel-2);margin-bottom:5px}
details.prow-r summary{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:8px 10px;cursor:pointer;list-style:none}
details.prow-r summary::-webkit-details-marker{display:none}
details.prow-r summary::before{content:"\25B8";color:var(--muted-2);font-size:11px;
  transition:transform .15s var(--ease)}
details.prow-r[open] summary::before{transform:rotate(90deg)}
details.prow-r:hover{border-color:var(--border-2)}
details.prow-r[open]{border-color:var(--accent);background:var(--panel)}
.pname{font-weight:700;font-size:14px}
.pgs{margin-left:auto;font-family:var(--mono);font-size:11.5px;color:var(--muted)}
.pstat{font-family:var(--mono);font-size:13px;color:var(--text-2);min-width:110px;
  text-align:right}
.pbody{padding:2px 10px 10px;display:flex;flex-direction:column;gap:6px}
.pline{display:flex;flex-wrap:wrap;gap:8px;align-items:baseline;
  padding:5px 0;border-top:1px solid var(--hairline)}
.pline>.tiny:first-child{min-width:110px;color:var(--muted-2);
  text-transform:uppercase;letter-spacing:.05em;font-weight:700}
.sstat{font-family:var(--mono);font-size:12.5px;color:var(--text-2);
  display:inline-block;margin-right:12px;white-space:nowrap}
.sstat:last-child{margin-right:0}
.sstat b{color:var(--text)}
@media (max-width:600px){
  .pstat{min-width:0;text-align:left;width:100%}
  .pgs{margin-left:0}
}

/* ---------- depth chart ---------- */
.depth{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px}
.dcol h4{margin:0 0 6px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--accent-2);display:flex;gap:6px;align-items:baseline}
.dcol h4 .tiny{color:var(--muted-2);text-transform:none;letter-spacing:0}
details.dcard{border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--panel-2);margin-bottom:5px}
details.dcard summary{display:flex;align-items:center;gap:7px;flex-wrap:wrap;
  padding:7px 9px;cursor:pointer;list-style:none}
details.dcard summary::-webkit-details-marker{display:none}
details.dcard:hover{border-color:var(--border-2)}
details.dcard[open]{border-color:var(--accent);background:var(--panel)}
details.dcard[open] .dslot{background:var(--accent);color:var(--accent-ink)}
.dslot{font-family:var(--mono);font-size:10.5px;font-weight:800;padding:2px 6px;
  border-radius:4px;background:var(--panel-3);color:var(--muted);flex:0 0 auto}
details.dcard .pname{font-size:13.5px}
details.dcard .pstat{margin-left:auto;min-width:0;font-size:12px}
details.dcard .pbody{padding:2px 9px 9px}
details.dcard .pline>.tiny:first-child{min-width:96px}

/* ---------- published two-deep ---------- */
.dunit{margin-bottom:14px}
.dunit h4{margin:0 0 7px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--accent-2);display:flex;gap:8px;align-items:baseline}
.dunit h4 .tiny{color:var(--muted-2);text-transform:none;letter-spacing:0}
.drow{display:grid;grid-template-columns:64px minmax(0,1fr);gap:8px;align-items:start;
  padding:3px 0;border-top:1px solid var(--hairline)}
.drow:first-of-type{border-top:0}
.dpos{font-family:var(--mono);font-size:11px;font-weight:800;color:var(--muted);
  padding-top:9px;white-space:nowrap}
.dnames{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:5px}
.dno{font-family:var(--mono);font-size:11px;font-weight:800;color:var(--accent-2);
  min-width:20px;text-align:right;flex:0 0 auto}
details.dcard .pbody .tblwrap{margin-top:4px}
@media (max-width:640px){
  .drow{grid-template-columns:1fr;gap:2px}
  .dpos{padding-top:0}
  .dnames{grid-template-columns:1fr}
}

/* ==========================================================================
 * View mode / Predict mode
 * ========================================================================*/
/* Predict is a nav GROUP now, visible in both modes, so there is nothing left
   to reveal on a mode switch. Its links used to appear only once you were
   already in predict mode - the way in was the one thing you could not see
   from the way out. */
html[data-mode="predict"] .navgroup .navmenu a[href^="/predict"],
html[data-mode="predict"] .navgroup .navmenu a[href^="/playoff"]{
  color:var(--accent)}
.modesw{flex:0 0 auto;display:inline-flex;border:1px solid var(--border-2);
  border-radius:999px;overflow:hidden;background:var(--panel-2)}
.modesw .seg{background:none;border:0;color:var(--muted);font-family:inherit;
  font-size:12.5px;font-weight:700;padding:6px 14px;cursor:pointer;white-space:nowrap}
.modesw .seg:hover{color:var(--text)}
.modesw .seg.on{background:var(--accent);color:var(--accent-ink)}
.modesw .seg:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.predictbar{position:sticky;top:56px;z-index:35;background:rgba(110,231,168,.10);
  border-bottom:1px solid rgba(110,231,168,.35);backdrop-filter:blur(8px)}
.predictbar .wrap{display:flex;align-items:center;gap:10px;padding-top:8px;
  padding-bottom:8px;flex-wrap:wrap}
.predictbar b{color:var(--accent)}
.grow{margin-left:auto}
html[data-mode="view"] [data-pickhost],
html[data-mode="view"] [data-matchup-pick]{display:none}

.pickctl{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.pickctl .pk{width:auto;flex:0 1 auto;max-width:210px}
.pickctl.locked{opacity:.7}
.pickhost{padding-top:4px}
tr .pickhost{padding:4px 8px}

.teamgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
  gap:6px;margin:10px 0}
.teamcard{display:flex;align-items:center;gap:7px;background:var(--panel-2);
  border:1px solid var(--border);border-radius:var(--r-sm);padding:7px 9px;
  cursor:pointer;color:var(--text-2);font-family:inherit;font-size:13px;text-align:left}
.teamcard:hover{border-color:var(--border-2);color:var(--text)}
.teamcard.on{border-color:var(--accent);background:rgba(110,231,168,.12);color:var(--text)}
.teamcard .tcn{font-weight:650;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.teamcard .tiny{margin-left:auto;font-family:var(--mono)}
.prow2{display:grid;grid-template-columns:64px 150px minmax(0,1fr);gap:8px;
  align-items:center;padding:5px 0;border-top:1px solid var(--hairline)}
.predpick{background:var(--panel);border:1px solid var(--border);
  border-radius:var(--r-md);padding:12px;margin:10px 0}
@media (max-width:760px){
  .predictbar{position:static}
  .prow2{grid-template-columns:1fr;gap:3px}
  .modesw{padding:5px 10px;font-size:11.5px}
}

/* ==========================================================================
 * Live scores and play-by-play
 * ========================================================================*/
.lstamp{font-family:var(--mono)}
.lstamp.on::before{content:"";display:inline-block;width:7px;height:7px;border-radius:50%;
  background:var(--neg);margin-right:6px;vertical-align:1px;
  animation:lpulse 2s var(--ease) infinite}
.lstamp.warn{color:var(--warn)}
@keyframes lpulse{0%,100%{opacity:1}50%{opacity:.35}}
@media (prefers-reduced-motion:reduce){ .lstamp.on::before{animation:none} }

.lgroup{margin:22px 0 10px;font-size:12px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);display:flex;gap:8px;align-items:baseline}
.lgroup .tiny{color:var(--muted-2)}
.lgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(310px,1fr));gap:10px}
.lcard{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-sm);
  padding:10px 12px}
.lcard:hover{border-color:var(--border-2)}
.lhead{display:flex;align-items:center;gap:8px;margin-bottom:7px}
.lhead .btn{margin-left:auto;padding:3px 8px;font-size:11px}
.lteam{display:flex;align-items:center;gap:7px;padding:3px 0}
.lteam img{width:20px;height:20px;object-fit:contain}
.lteam .lnm{font-size:14px;font-weight:650;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;color:var(--muted)}
.lteam .lsc{margin-left:auto;font-family:var(--mono);font-size:17px;font-weight:800;
  color:var(--muted)}
.lteam.lead .lnm,.lteam.lead .lsc,.lteam.win .lnm,.lteam.win .lsc{color:var(--text)}
.lteam .poss{color:var(--accent-2);font-size:9px}
.lsit{margin-top:6px;padding-top:6px;border-top:1px solid var(--hairline);
  font-size:11.5px;color:var(--muted)}
.ltrack{margin-top:8px;padding-top:8px;border-top:1px solid var(--border)}
.game.is-live{border-color:rgba(255,125,140,.45)}

.lsub{margin:10px 0 6px;font-size:11px;letter-spacing:.07em;text-transform:uppercase;
  color:var(--accent-2)}
ol.lscore{margin:0;padding-left:18px;font-size:13px;color:var(--text-2)}
ol.lscore li{margin-bottom:4px}
.ldrives{display:flex;flex-direction:column;gap:4px}
details.ldrive{border:1px solid var(--border);border-radius:var(--r-xs);
  background:var(--panel-2)}
details.ldrive summary{display:flex;gap:8px;align-items:baseline;padding:6px 9px;
  cursor:pointer;list-style:none;font-size:12.5px}
details.ldrive summary::-webkit-details-marker{display:none}
details.ldrive[open]{border-color:var(--accent)}
.dabbr{font-family:var(--mono);font-weight:800;font-size:11px;color:var(--accent-2);
  min-width:42px}
.dres{font-weight:700;color:var(--text-2)}
ol.lplays{margin:0;padding:2px 9px 9px 26px;font-size:12.5px;color:var(--muted);
  display:flex;flex-direction:column;gap:3px}
ol.lplays li.score{color:var(--pos)}
ol.lplays li.turnover{color:var(--neg)}
@media (max-width:600px){ .lgrid{grid-template-columns:1fr} }


/* ---------- picking on the row itself ---------- */
.game.pickable .team{cursor:default}
.pickdot{margin-left:8px;flex:0 0 auto;width:22px;height:22px;border-radius:50%;
  border:1.5px solid var(--border-2);background:var(--panel-2);color:var(--accent-ink);
  font-size:12px;font-weight:800;line-height:1;cursor:pointer;display:inline-flex;
  align-items:center;justify-content:center;font-family:inherit}
.pickdot:hover:not(:disabled){border-color:var(--accent);color:var(--accent)}
.pickdot.on{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.pickdot:disabled{opacity:.35;cursor:default}
.pickdot:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.game.pickable .team.picked .nm{color:var(--text);font-weight:800}
.game.pickable .team .sc{margin-left:auto}
.pickhost.rowtag{margin-top:4px}
html[data-mode="predict"] .game.pickable{cursor:default}

/* ---------- glossary ---------- */
.gwrap{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:14px}
.gterm h4{margin:0 0 4px;font-size:15.5px;color:var(--text)}
.gterm p{margin:0;font-size:14px;color:var(--text-2);line-height:1.5}
.gseen{margin-top:4px;color:var(--muted-2)}
.gterm:target h4{color:var(--accent)}

/* ---------- compare picks ---------- */
.pastebox{display:flex;gap:8px;align-items:flex-start;margin-top:10px}
.pastebox textarea{flex:1;background:var(--panel-2);border:1px solid var(--border-2);
  border-radius:var(--r-sm);color:var(--text);padding:9px 11px;font-family:var(--mono);
  font-size:12.5px;resize:vertical;min-height:64px}
.pastebox textarea:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 3px rgba(110,231,168,.18)}
@media (max-width:600px){ .pastebox{flex-direction:column} .pastebox .btn{width:100%} }

/* ---------- season grid encoding ---------- */
.matrix td{vertical-align:top}
.matrix td .cell + .cell{margin-top:2px}
.cell{position:relative}
.cell.away{border-style:dashed}
.cell.neutral{border-color:var(--accent-2)}
.crk{font-size:9px;font-weight:800;color:var(--accent-2);margin-right:3px;
  vertical-align:1px}
/* difficulty: the opponent's rating, five steps from a walkover to a wall */
.cell.h0{background:#171a20;color:var(--muted-2)}
.cell.h1{background:#1b2430}
.cell.h2{background:#1f2d3d}
.cell.h3{background:#26384c;color:var(--text-2)}
.cell.h4{background:#2f465f;color:var(--text)}
.gridkey{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-top:10px;
  font-size:11.5px;color:var(--muted)}
.gridkey .sw{display:inline-block;width:22px;height:11px;border-radius:3px;
  border:1px solid var(--border);vertical-align:-1px;margin-right:4px}

/* ---------- following ---------- */
.followbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:10px 0 0}
.followbar .tiny{color:var(--muted)}
.followstrip{border-color:var(--accent)}
.fgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px}
.fcard{display:flex;align-items:center;gap:8px;background:var(--panel-2);
  border:1px solid var(--border);border-radius:var(--r-sm);padding:8px 10px;
  color:var(--text-2)}
.fcard:hover{border-color:var(--accent);color:var(--text)}
.fcard .fnm{font-weight:700;font-size:13.5px}
.fcard .fwhen{margin-left:auto;font-family:var(--mono);color:var(--muted)}
/* The one part of the odds cell allowed to wrap: a longer abbreviation or a
   bigger move must cost a second line, never a collision. */
.moved{color:var(--accent-2);font-size:11px;font-family:var(--mono);white-space:normal}
/* .mvs sets nowrap for the kickoff line; the differential sentence must not
   inherit it or a long "no rating for X" message widens the whole page */
.implied{margin-top:4px;font-size:12px;color:var(--muted);white-space:normal;
  max-width:220px;margin-left:auto;margin-right:auto}
.implied b{color:var(--text-2);font-family:var(--mono)}
.confsel{margin-left:8px;background:var(--panel-2);border:1px solid var(--border-2);
  border-radius:var(--r-xs);color:var(--text-2);font-family:var(--mono);font-size:11.5px;
  padding:2px 4px}
.confsel:focus{outline:none;border-color:var(--accent)}
html[data-mode="view"] .confsel{display:none}

/* ---------- keyboard and screen reader ---------- */
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--accent);
  color:var(--accent-ink);padding:10px 16px;font-weight:800;border-radius:0 0 var(--r-sm) 0}
.skip:focus{left:0}
/* Text for screen readers only. display:none and visibility:hidden both drop
   the node out of the accessibility tree, which is the opposite of what this
   is for; the 1px clip keeps it announced and out of the layout. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
main:focus{outline:none}
a:focus-visible,button:focus-visible,select:focus-visible,input:focus-visible,
textarea:focus-visible,summary:focus-visible,[tabindex]:focus-visible{
  outline:2px solid var(--accent);outline-offset:2px;border-radius:3px}

/* ---------- leagues ---------- */
.lglist{display:grid;gap:8px}
.lgrow{display:flex;flex-direction:column;gap:2px;padding:11px 13px;
  background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-xs)}
.lgrow:hover{border-color:var(--accent)}
.lgtable td:nth-child(2),.lgtable th:nth-child(2){text-align:left}
.lgtable tr.mine td{background:rgba(110,231,168,.07)}
.av{border-radius:50%;vertical-align:middle}
.av-none{display:inline-flex;align-items:center;justify-content:center;
  width:24px;height:24px;border-radius:50%;background:var(--panel-3);
  color:var(--text-2);font-size:12px;font-weight:700}
.msg-ok{border-left:3px solid var(--accent);padding-left:10px}
.msg-bad{border-left:3px solid var(--accent-2);padding-left:10px}

/* ---------- crowd split ---------- */
.crowd{display:flex;align-items:center;justify-content:flex-end;gap:6px;
  margin-top:3px;white-space:nowrap}
.crowd .tiny{white-space:nowrap}
/* flex:0 0 - as a flex item beside nowrap text the bar shrank to ZERO width
   and the row still looked almost right, which is why the test measures it */
.crowdbar{flex:0 0 46px;display:inline-block;width:46px;height:5px;border-radius:3px;
  background:var(--panel-3);overflow:hidden;position:relative}
/* the fill is the HOME share, filling from the right, so the bar reads the
   same way the row does: away on the left, home on the right */
.crowdbar i{position:absolute;right:0;top:0;bottom:0;display:block;
  background:var(--accent);opacity:.75}
.crowdn{color:var(--text-2)}
@media (max-width:860px){
  .crowd{justify-content:flex-start}
  .crowdn{display:none}          /* the count lives in the title on a phone */
}

/* ---------- national leaders ---------- */
/* .rectbl right-aligns everything, which is right for a two-column record card
   and wrong here: it pushed names to the far edge of wide columns and left a
   gap between the rank and the player it belongs to. */
.leadtbl th,.leadtbl td{padding:5px 10px}
.leadtbl td:nth-child(1),.leadtbl th:nth-child(1){text-align:right;width:34px;
  color:var(--text-2)}
.leadtbl td:nth-child(2),.leadtbl th:nth-child(2),
.leadtbl td:nth-child(3),.leadtbl th:nth-child(3){text-align:left}
.leadtbl td:nth-child(3){white-space:nowrap}
.leadtbl td:nth-child(4),.leadtbl th:nth-child(4){width:64px}
.leadtbl td:nth-child(5),.leadtbl th:nth-child(5){font-family:var(--mono);
  font-size:11.5px;color:var(--text-2)}
.leadtbl img{vertical-align:-3px;margin-right:3px}
.leadtbl tbody tr:hover td{background:var(--panel-2)}
.leadtbl .tabbr{display:none}
@media (max-width:700px){
  .leadtbl td:nth-child(5),.leadtbl th:nth-child(5){display:none}
  .leadtbl th,.leadtbl td{padding:5px 6px}
  .leadtbl .tfull{display:none}
  .leadtbl .tabbr{display:inline}
  .leadtbl td:nth-child(2){font-size:13px;white-space:normal}
  .leadtbl td:nth-child(4),.leadtbl th:nth-child(4){width:48px}
}

/* ---------- player movement ---------- */
.ptbl td:nth-child(3),.ptbl th:nth-child(3),
.ptbl td:nth-child(4),.ptbl th:nth-child(4){text-align:left;white-space:nowrap}
.ptbl .pmove{color:var(--text-2)}
.ptbl td:nth-child(5),.ptbl th:nth-child(5){text-align:right}
@media (max-width:760px){
  .ptbl td:nth-child(5),.ptbl th:nth-child(5){display:none}
  /* Ten pixels over on a 390px phone, which is a table you have to drag.
     Trimming padding made it WORSE: with auto layout the columns are sized by
     their longest content, so the saving went straight back into the names.
     Fixed layout is the thing that actually constrains it. */
  .ptbl{table-layout:fixed;width:100%}
  .ptbl th,.ptbl td{padding:5px 4px}
  .ptbl td:nth-child(1),.ptbl th:nth-child(1){width:22px}
  .ptbl td:nth-child(3),.ptbl th:nth-child(3){width:74px}
  .ptbl td:nth-child(4),.ptbl th:nth-child(4){width:80px}
  .ptbl td:nth-child(2){white-space:normal;word-break:break-word}
  .ptbl td:nth-child(3),.ptbl td:nth-child(4){white-space:normal}
}

/* ---------- roster movement ---------- */
.mvgrid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.mvhead{font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-2);padding-bottom:6px;border-bottom:1px solid var(--line);
  margin-bottom:6px}
.mvrow{display:grid;grid-template-columns:1fr auto;gap:2px 10px;padding:5px 0;
  border-bottom:1px solid var(--line)}
.mvrow:last-child{border-bottom:0}
.mvto{text-align:right;white-space:nowrap;color:var(--text-2)}
.mvline{grid-column:1/-1;font-family:var(--mono);font-size:11px;color:var(--text-2)}
@media (max-width:700px){ .mvgrid{grid-template-columns:1fr;gap:14px} }

/* ---------- leaderboard ---------- */
.lbme{display:flex;align-items:baseline;gap:12px}
.lbme b{font-size:22px}
.lbtable td:nth-child(2),.lbtable th:nth-child(2){text-align:left}
.lbtable tr.mine td{background:rgba(110,231,168,.07)}

/* ---------- week bands ---------- */
/* A week in this league is not a day. It opens Thursday night, fills a
   Sunday and closes Monday night, and around Thanksgiving Week 12 puts games
   on five different days - while Week 18 puts all sixteen on one Sunday. The
   band names each cluster instead of running the whole week together. */
.weekband{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  margin:22px 0 8px;padding-bottom:8px;border-bottom:2px solid var(--accent)}
.weekband h2{margin:0;font-size:17px}
.weekband .tiny{color:var(--text-2)}


/* ---------- game rail on a matchup page ----------
   A scoreboard strip: kickoff and network on top, then a row per team with
   logo, abbreviation and score. No 0-0 before kickoff - a zero is a
   measurement everywhere else on this site. */
.gameslider{margin:0 0 16px}
.gsbar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:8px}
.gswrap{display:flex;align-items:stretch;gap:4px}
.gsarrow{flex:0 0 auto;width:26px;border:1px solid var(--line);
  border-radius:var(--r-xs);background:var(--panel-2);color:var(--text-2);
  font-size:18px;line-height:1;cursor:pointer}
.gsarrow:hover:not(:disabled){border-color:var(--accent);color:var(--text)}
.gsarrow:disabled{opacity:.3;cursor:default}
.gstrack{flex:1 1 auto;display:flex;gap:0;overflow-x:auto;
  scrollbar-width:thin;scroll-behavior:smooth;
  border:1px solid var(--line);border-radius:var(--r-xs);background:var(--panel)}
.gscard{flex:0 0 auto;display:flex;flex-direction:column;gap:3px;
  min-width:132px;padding:7px 11px;border-right:1px solid var(--line);
  color:var(--text-2);white-space:nowrap;font-size:12.5px;line-height:1.2}
a.gscard:hover{background:var(--panel-2);color:var(--text)}
.gscard.on{background:var(--panel-3);color:var(--text);
  box-shadow:inset 3px 0 0 var(--accent)}
.gshead{display:flex;gap:8px;align-items:baseline;font-size:10.5px;
  color:var(--text-2)}
.gscard.on .gsday{color:var(--accent);font-weight:700}
.gstv{margin-left:auto;opacity:.85}
.gsrow{display:flex;align-items:center;gap:5px}
.gsrow.win{color:var(--text);font-weight:700}
.gslogo{width:16px;height:16px;flex:0 0 16px;object-fit:contain}
.gsab{font-family:var(--mono);font-size:12px}
.gssc{margin-left:auto;font-family:var(--mono);font-size:12px;
  font-variant-numeric:tabular-nums}
@media (max-width:600px){
  .gscard{min-width:120px;padding:6px 9px}
  .gsarrow{display:none}          /* a phone swipes; a button is in the way */
}

/* a card whose game is under way, on the matchup rail */
.gscard.is-live{background:rgba(255,125,140,.07)}
.gscard.is-live .gsday .live{animation:none}

/* ---------- weather ---------- */
.wx{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
.wx-d{color:var(--text-2)}
.wx-in{color:var(--text-2);font-style:italic}
.wx-pop{color:#7ec8ff}
.wx-wind{color:var(--text-2)}
.wxcard .wxnow{font-size:20px}
.wxcard .wxnow b{font-size:26px}

/* ==========================================================================
 * Player pages
 * Sections are all in the document and JS turns the extra ones off, so every
 * rule that HIDES is gated on html[data-js]. Without JavaScript the dropdowns
 * are not drawn and every section is on screen.
 * ========================================================================*/
/* Gated on data-ptabs, which player.js sets, and NOT on data-js, which app.js
   sets. Those are different claims: "scripting is on" does not mean "the file
   that can reopen these sections is running". */
[data-js-only]{display:none}
html[data-ptabs] [data-js-only]{display:block}
html[data-ptabs] .psec[data-off]{display:none}
html[data-ptabs] .pseason[data-off]{display:none}
.psec{margin:0 0 22px}
.psec h2{font-size:15px;letter-spacing:.04em;text-transform:uppercase;
  color:var(--muted);margin:0 0 10px}
.ptabs,.pseasonpick{margin:0 0 16px}
.ptabs label,.pseasonpick label{display:inline-flex;align-items:center;gap:8px;
  font-size:12px;color:var(--muted)}
.ptabs select,.pseasonpick select{background:var(--panel-2);color:var(--text);
  border:1px solid var(--border-2);border-radius:var(--r-sm);padding:6px 10px;
  font:inherit;font-size:13px}
.phero{align-items:center}
.pshot{width:96px;height:70px;object-fit:cover;object-position:top center;
  border-radius:var(--r-sm);background:var(--panel-3);flex:0 0 96px}
.psumwrap{margin-left:auto;text-align:right}
.psumhead{font-size:10px;font-weight:800;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted-2);margin-bottom:6px}
.psums{display:flex;gap:18px;flex-wrap:wrap;justify-content:flex-end}
.psum .k{font-size:10px;font-weight:800;letter-spacing:.05em;color:var(--muted-2)}
.psum .v{font-family:var(--mono);font-size:19px;font-weight:800;color:var(--text)}
.psum .n{font-size:10.5px;color:var(--muted-2);white-space:nowrap}
.pnext{margin:0 0 16px}
.pnext .k{font-size:10px;font-weight:800;letter-spacing:.05em;color:var(--muted-2)}
.pnext .v{font-size:15px;font-weight:700}
.pnext .n{font-size:11.5px;color:var(--muted)}
.dtbl th[scope=row],.ptbl th[scope=row]{white-space:nowrap;font-weight:700}
.dtbl tr.ptot,.ptbl tr.ptot th,.ptbl tr.ptot td{font-weight:800;color:var(--text);
  border-top:1px solid var(--border-2)}
.dtbl tr.pnote,.ptbl tr.pnote td{font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;
  color:var(--muted-2);padding-top:2px}
.dtbl td.w,.ptbl td.w{color:var(--accent)}
.dtbl td.l,.ptbl td.l{color:var(--muted)}
.psec h3{font-size:13px;margin:16px 0 6px;color:var(--text-2)}
.psec h3:first-child{margin-top:0}
.phist{list-style:none;padding:0;margin:6px 0 0}
.phist li{padding:4px 0;border-bottom:1px solid var(--border)}
.pgloss{margin-top:18px}
.pgloss dl{display:grid;grid-template-columns:auto 1fr;gap:2px 10px;
  font-size:11.5px;margin:0}
.pgloss dt{font-weight:800;color:var(--text-2);font-family:var(--mono)}
.pgloss dd{margin:0;color:var(--muted)}
@media (max-width:720px){
  .psumwrap{margin-left:0;text-align:left;width:100%}
  .psums{justify-content:flex-start;gap:14px}
}

/* ==========================================================================
 * Site search
 * The button and the panel are only drawn by search.js, so there is nothing
 * here to hide when it is absent - an element that does not exist cannot be a
 * control that does nothing.
 * ========================================================================*/
.searchbtn{display:inline-flex;align-items:center;gap:6px;background:var(--panel-2);
  color:var(--text-2);border:1px solid var(--border-2);border-radius:999px;
  padding:6px 12px;font:inherit;font-size:13px;font-weight:650;cursor:pointer;
  white-space:nowrap}
.searchbtn:hover{border-color:var(--accent);color:var(--text)}
.searchbtn span[aria-hidden]{font-size:16px;line-height:1}
.searchpanel{position:fixed;inset:0;z-index:200;background:rgba(0,0,0,.62);
  display:flex;align-items:flex-start;justify-content:center;padding:8vh 16px 16px}
.searchpanel[data-off]{display:none}
/* THE ROW HOLDING THE RESULTS HAS TO BE ALLOWED TO BE SHORTER THAN ITS
   CONTENT. As `auto` it grew to fit forty results and ran straight out of the
   bottom of the panel and down the page - max-height on the box does nothing
   while a grid row inside it is still sizing to content. */
.searchpanel .swrap{width:min(680px,100%);background:var(--panel);
  border:1px solid var(--border-2);border-radius:var(--r-sm);
  display:grid;grid-template-columns:1fr auto;
  grid-template-rows:auto auto minmax(0,1fr);gap:0 8px;padding:12px;
  max-height:76vh}
.searchpanel .sinput{background:var(--panel-2);color:var(--text);font:inherit;
  font-size:16px;border:1px solid var(--border-2);border-radius:var(--r-sm);
  padding:10px 12px;width:100%}
.searchpanel .sclose{background:none;border:0;color:var(--muted);font-size:22px;
  line-height:1;cursor:pointer;padding:0 8px}
.searchpanel .sstatus{grid-column:1/-1;font-size:11.5px;color:var(--muted);
  padding:8px 2px 4px}
.searchpanel .slist{grid-column:1/-1;overflow-y:auto;min-height:0}
.sres{display:grid;grid-template-columns:74px 1fr auto;gap:10px;align-items:baseline;
  padding:7px 8px;border-radius:var(--r-sm);color:var(--text);text-decoration:none}
.sres:hover{background:var(--panel-2);outline:1px solid var(--border-2)}
/* THE ROW YOU ARE ON WAS THE LEAST VISIBLE ROW ON SCREEN. This selector has
   specificity (0,2,0) and beat a:focus-visible at (0,1,1), so the keyboard
   selection rendered as a 1px border-2 outline - 1.37:1 against the panel,
   where WCAG wants 3:1 - while every other result kept the accent ring. It now
   uses the same 2px accent the rest of the site uses for focus. */
.sres.on{background:var(--panel-2);outline:2px solid var(--accent);
  outline-offset:-2px}
.sres .skind{font-size:9.5px;font-weight:800;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted-2)}
.sres .slabel{font-size:14px;font-weight:650;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.sres .sdetail{font-size:11.5px;color:var(--muted);white-space:nowrap}
html.searching{overflow:hidden}
@media (max-width:860px){
  .searchbtn .slbl{display:none}
  .searchbtn{padding:6px 10px}
  .searchpanel{padding:4vh 10px 10px}
  .sres{grid-template-columns:60px 1fr;row-gap:0}
  .sres .sdetail{grid-column:2}
}

/* ==========================================================================
 * Data tables: rosters, career statistics, game logs, splits
 * These were borrowing .ptbl, which is the PLAYER-MOVEMENT table's class -
 * and its mobile rules hard-code that table's five columns: a fixed layout,
 * column three pinned to 74px, column five hidden. Applied to a seven-column roster
 * that meant the names printed over the positions ("Judd AndQBerson") and the
 * height column rendered at zero width. Reusing a class is reusing a claim
 * about the shape of the thing.
 *
 * These tables are wide on purpose - a game log has fifteen statistics - so
 * they SCROLL inside .tblwrap rather than being squeezed, and the first column
 * stays put so a reader who scrolls right still knows whose row they are on.
 * ========================================================================*/
.dtbl{min-width:max-content}
.dtbl th:first-child,.dtbl td:first-child{position:sticky;left:0;z-index:1;
  background:var(--panel)}
.dtbl thead th:first-child{z-index:2}
.dtbl.pbio{min-width:0}
.dtbl.pbio th:first-child,.dtbl.pbio td:first-child{position:static}
@media (max-width:760px){
  .dtbl th,.dtbl td{padding:6px 8px}
}

/* THE COLUMN THAT EXPLAINS THE RANKING WAS THE ONE BEING CUT OFF.
   The projected-standings table put the tiebreaker reason in a nowrap cell at
   the right-hand edge, so it read "record vs the 1 common confere" with no
   ellipsis, no tooltip and no scrollbar - the tool's most important admission,
   truncated mid-word. It is prose; it wraps. */
/* THIS TABLE FITS ITS CARD RATHER THAN SCROLLING INSIDE IT. The projected
   standings live in a 452px panel and the tiebreak column is prose, so
   min-width:max-content made the table 545px and pushed the sentence off the
   edge - "record vs the 1 common confere" - where a reader had to discover a
   sideways scroll to read the tool's most important admission. Wrapping is the
   right answer for prose in a narrow column. */
.tblwrap > table.standtbl{min-width:0;table-layout:auto}
.confstand .pos{color:var(--muted-2);font-family:var(--mono);font-size:11px;
  display:inline-block;min-width:1.4em;text-align:right}
.standtbl .tbwhy{white-space:normal;line-height:1.35}
.standtbl td,.standtbl th{vertical-align:top}

/* The network strip above the header. Slim by design: it is a way out of the
   site, not part of it, and it must never compete with the navigation. The
   descriptions disappear first on a narrow screen because a reader who knows
   what "The Gridiron King" is does not need them and one who does not is not
   reading a 360px strip anyway. */
.sisterbar{background:var(--bg-2);border-bottom:1px solid var(--hairline);
  font-size:11.5px;line-height:1}
.sisterbar>.wrap{display:flex;align-items:center;gap:14px;
  padding:6px 16px;flex-wrap:wrap}
.sblabel{color:var(--muted-2);text-transform:uppercase;letter-spacing:.07em;
  font-size:10px;font-weight:700}
.sisterbar a{color:var(--text-2);text-decoration:none;display:inline-flex;
  align-items:baseline;gap:6px}
.sisterbar a:hover{color:var(--accent)}
.sbwhat{color:var(--muted-2);font-size:10.5px}
@media (max-width:640px){.sbwhat{display:none}
  .sisterbar>.wrap{gap:12px;padding:5px 12px}}

/* THE LEAGUE SWITCHER, in the topbar where a reader is already looking.
   It began life as a slim strip above the header - correct information, sized
   so that nobody would ever see it. This is a control, shaped like the mode
   control beside it, and the half you are not on is a link to the other site.
   Same idea as a tab bar: the point is that both leagues are visible at once,
   not that one of them is mentioned. */
.leagueswitch{flex:0 0 auto;display:inline-flex;border:1px solid var(--border-2);
  border-radius:999px;overflow:hidden;background:var(--panel-2);margin-left:10px}
.leagueswitch>*{font-size:12.5px;font-weight:800;padding:6px 13px;
  white-space:nowrap;text-decoration:none;letter-spacing:.03em}
.leagueswitch .ls-on{background:var(--accent);color:var(--accent-ink)}
.leagueswitch a{color:var(--muted)}
.leagueswitch a:hover{color:var(--text);background:var(--panel)}
.leagueswitch a:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
@media (max-width:520px){.leagueswitch>*{padding:5px 10px;font-size:12px}}

/* THE HEADER MAY WRAP ON A PHONE. Adding the league switcher put five controls
   on one row - brand, switcher, menu, search, mode - and at 390px they came to
   419, so the mode switch hung 13px off the right and the whole document
   scrolled sideways. Squeezing every control until they fit is how a row ends
   up unreadable at the next size down; letting the mode switch take its own
   line costs nothing and holds at 320. */
@media (max-width:430px){
  .topbar .wrap{flex-wrap:wrap;gap:8px}
  .topbar .modesw{margin-left:auto}
}

/* THE HEADER NEVER PUSHES THE PAGE SIDEWAYS.
   Adding the league switcher put the row at 1,218px inside a 1,200px window,
   so the mode switch hung 22px off the right and the whole document scrolled -
   on a matchup page, where a horizontal rail is a deliberate feature and a
   horizontally scrolling PAGE is the bug it is there to avoid being mistaken
   for. Two changes, neither of which shrinks a control: the row may wrap
   instead of overflowing, and the gap between items comes in from 18px below a
   width where 18px is a luxury. */
.topbar .wrap{flex-wrap:wrap}
@media (max-width:1400px){ .topbar .wrap{gap:12px} }
