/* Phone-first. Roughly 200 lines, no framework, so it can be restyled
   without fighting anything. Dark mode follows the device. */
/* THE TOKENS LIVE IN brand.css, WHICH LOADS BEFORE THIS FILE.
   They were duplicated here, and a duplicate that loads LAST silently wins:
   with both files present this block would have kept --accent on the old
   desaturated navy and the brand hue would never have appeared, with nothing
   to show why. One definition, one place.

   brand.css also carries a manual [data-theme] override that this block did
   not, so a theme switch becomes possible without touching component CSS. */
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{background:var(--bg);color:var(--ink);
  font:15px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  -webkit-text-size-adjust:100%}
main{padding:0 16px 64px;max-width:760px;margin:0 auto}

header{position:sticky;top:0;background:var(--bg);z-index:5;
  padding:14px 0 8px;border-bottom:1px solid var(--line)}
.top{display:flex;justify-content:space-between;align-items:center;gap:10px}
h1{font-size:17px;margin:0;letter-spacing:.02em}
.acts{display:flex;gap:6px;flex-wrap:wrap}

button{font:inherit;font-size:13px;padding:7px 11px;border-radius:8px;
  border:1px solid var(--line);background:var(--card);color:var(--ink);
  cursor:pointer;-webkit-tap-highlight-color:transparent}
button:active{transform:translateY(1px)}
button[disabled]{opacity:.5;cursor:default}
button.wide{width:100%;padding:10px}

.asof{color:var(--dim);font-size:12px;margin-top:6px}
.asof.bad,.bad{color:var(--bad)}
.msg{font-size:12.5px;color:var(--accent);margin-top:5px}

.tabs{display:flex;gap:6px;overflow-x:auto;padding:9px 0 2px;
  -webkit-overflow-scrolling:touch}
.tabs button{white-space:nowrap}
.tabs button.on{border-color:var(--accent);color:var(--accent)}

section{margin-top:22px}
h2{font-size:12px;text-transform:uppercase;letter-spacing:.09em;
  color:var(--dim);margin:0 0 8px;font-weight:600}

.card{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:11px 13px;margin-bottom:8px}
.card.claude{white-space:pre-wrap;line-height:1.55;font-size:14.5px}
.row{display:flex;justify-content:space-between;gap:10px;align-items:baseline}
.game{font-weight:600}
.meta{color:var(--dim);font-size:12.5px;margin-top:3px}
.num{font-variant-numeric:tabular-nums;white-space:nowrap}
/* The price on an EV card, next to the fighter or team being backed. Tabular
   so +360 and -428 line up down the column, and dimmed so the NAME is what
   the eye lands on first -- the name is the part that was being misread. */
.price{font-weight:400;color:var(--dim);font-variant-numeric:tabular-nums;
  margin-left:4px}
.pos{color:var(--good);font-weight:600}
.neg{color:var(--bad)}

.warn{border-left:3px solid var(--warn);padding-left:10px;color:var(--dim);
  font-size:12.5px;margin:8px 0}
.empty{color:var(--dim);font-size:13.5px;padding:2px 0 6px}
.tag{display:inline-block;font-size:11px;padding:1px 6px;border-radius:5px;
  border:1px solid var(--line);color:var(--dim);margin-left:6px}
code{font-size:12px;background:var(--card);padding:1px 4px;border-radius:4px}

footer{margin-top:28px;color:var(--dim);font-size:12px;line-height:1.5;
  border-top:1px solid var(--line);padding-top:12px;
  padding-bottom:env(safe-area-inset-bottom)}

/* Team logos. Decoration only: a broken image is hidden rather than showing
   the browser's torn-page icon, which reads as "this dashboard is broken". */
.lg{height:1.15em;width:1.15em;object-fit:contain;vertical-align:-0.18em;
    margin-right:5px}
.lg[src=""],.lg:not([src]){display:none}

/* Fighter headshots. Coverage from TheSportsDB is patchy, so the row has to
   read correctly with no picture — hence a flex row rather than a fixed
   two-column layout that leaves a hole. */
.fighter{display:flex;gap:9px;align-items:center;margin:6px 0}
.mug{width:44px;height:44px;border-radius:50%;object-fit:cover;
     background:var(--line);flex:0 0 auto}

/* ---------------------------------------------------------- scoreboard ---
   Scores, the number, and the distance between them. Table rather than cards
   because the whole point is comparing one game's margin against another's,
   and cards make the eye travel. Tabular numerals so the columns line up. */
/* border-collapse: SEPARATE, and that is load-bearing.
   With `collapse` the borders belong to the table rather than to the cells,
   and `position:sticky` on a <th> is unreliable to broken across browsers --
   which is exactly why the frozen column headers did not freeze. Separate
   borders stay with their own cell, so the header can float over the rows
   and keep its underline. border-spacing:0 makes it look identical. */
.grid{width:100%;border-collapse:separate;border-spacing:0;font-size:13.5px}
.grid th{text-align:left;font-weight:600;color:var(--dim);font-size:11.5px;
  text-transform:uppercase;letter-spacing:.04em;padding:6px 8px;
  border-bottom:1px solid var(--line)}
.grid th.num,.grid td.num{text-align:right;font-variant-numeric:tabular-nums;
  white-space:nowrap}
.grid td{padding:7px 8px;border-bottom:1px solid var(--line);vertical-align:top}
.grid tbody tr:hover{background:var(--card)}

/* A game in progress is the one row you want to find instantly. */
.liverow{background:color-mix(in srgb,var(--accent) 7%,transparent)}
.livedot{color:var(--bad);margin-right:5px;animation:pulse 2s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}

.dim{color:var(--dim)}
.good{color:var(--good);font-weight:600}
.grid td .bad{color:var(--bad);font-weight:600}

/* A button that reads as a link: the injury count is the affordance for
   opening the list, so it has to look clickable without becoming a button. */
.lnk{background:none;border:none;padding:0;margin:0 0 0 8px;font:inherit;
  color:var(--accent);cursor:pointer;text-decoration:underline dotted}
.lnk:hover{text-decoration:underline}

/* The drill-in. Two columns so away and home can be compared directly
   rather than scrolled between. */
.drill td{background:var(--card);border-bottom:2px solid var(--line)}
.drillwrap{display:flex;gap:28px;flex-wrap:wrap}
.drillcol{flex:1 1 260px;min-width:0}
.drillcol h3{font-size:13px;margin:2px 0 8px;font-weight:600}
.injlist{list-style:none;margin:0;padding:0}
.injlist li{padding:5px 0;border-bottom:1px solid var(--line)}
.injlist li:last-child{border-bottom:none}
.injlist .st{margin-left:7px;font-size:11.5px;text-transform:uppercase;
  letter-spacing:.03em}
.injlist .st.bad{color:var(--bad);font-weight:600}
.injlist .st.warn{color:var(--warn);font-weight:600}
.injlist .st.dim{color:var(--dim)}

/* A caveat that must not be mistaken for a number. */
.warnbox{border-left:3px solid var(--warn);padding:6px 10px;margin:0 0 10px;
  color:var(--dim);font-size:12.5px;background:var(--card)}

/* ---- the model's own view, and the reasoning behind it ---------------- */
/* The recommendation is the widest thing on the row, so it gets to wrap
   rather than forcing a horizontal scrollbar on the whole board. */
.modelcell{min-width:230px;max-width:340px}
.mrec{display:block;line-height:1.35}
.modelcell .lnk.why{margin:3px 0 0;font-size:12px;display:inline-block}

.whywrap{padding:2px 0 4px}
.whysum{margin:0 0 12px;font-size:13.5px;line-height:1.45}

/* The breakdown. The footer rows are the load-bearing part: the prediction
   and, under it, what the signals failed to explain. A reasoning panel that
   does not add up is decoration, so the residual is given the same visual
   weight as the answer rather than being tucked away. */
table.why{width:100%;border-collapse:collapse;margin:0 0 14px;font-size:12.5px}
table.why th{text-align:left;font-weight:600;color:var(--dim);
  padding:4px 10px 4px 0;border-bottom:1px solid var(--line)}
table.why td{padding:5px 10px 5px 0;border-bottom:1px solid var(--line);
  vertical-align:top}
table.why th.num,table.why td.num{text-align:right;
  font-variant-numeric:tabular-nums}
table.why tfoot .sum td{border-top:2px solid var(--line);border-bottom:none;
  font-weight:600;padding-top:7px}
table.why tfoot .resid td{border-bottom:none;color:var(--dim);
  font-size:12px;padding-top:2px}
table.why tfoot .resid.bad td{color:var(--bad);font-weight:600}
.tag.mkt{margin-left:6px;opacity:.85}

.whyctx{display:flex;gap:28px;flex-wrap:wrap;margin:0 0 12px}
.whyctx .drillcol p{margin:0 0 4px}

/* The Phase 1 correction, called out rather than folded into the table: it
   is about the probability, not about the margin the table decomposes. */
.keynum{border-left:3px solid var(--accent);padding:7px 11px;margin:0 0 10px;
  font-size:12.5px;line-height:1.5;background:var(--card)}

/* An honest refusal. Deliberately not styled as an error — "this model does
   not decompose" is a fact about the model, not a fault in the page. */
.nobreak{border-left:3px solid var(--warn);padding:7px 11px;margin:0 0 10px;
  font-size:12.5px;line-height:1.5;background:var(--card);color:var(--dim)}
.nobreak b{color:var(--fg);display:block;margin-bottom:2px}

/* The over/under cell carries two figures: simulated points, then the
   probability. The second is deliberately quieter — it sits near 50% on every
   game by construction, so giving it equal weight would suggest it separates
   rows more than it does. */
.grid td .term > b{font-weight:600}
.grid td .term > span{margin-left:6px;font-size:11.5px}

/* The three movement figures on a "biggest moves" card. Laid out as columns
   with their labels above them, because "+4.5  -0.5  -0.5" in a row is three
   numbers that answer three different questions and look like one series. */
.moved{display:flex;gap:16px;align-items:flex-end;flex:0 0 auto}
.movecol{display:flex;flex-direction:column;align-items:flex-end;line-height:1.2}
.movecol b{font-variant-numeric:tabular-nums;font-size:14px}
.movelbl{font-size:10px;text-transform:uppercase;letter-spacing:.05em;
  color:var(--dim);font-weight:500}
.movecol .dim{color:var(--dim);font-weight:400}

@media (max-width:760px){
  .moved{gap:11px}
  .movecol b{font-size:13px}
}

/* ---- glossary -------------------------------------------------------- */
/* A term that has a definition behind it.

   NOT a native title= tooltip. Those wait about a second before appearing,
   cannot be styled, truncate long text, and do nothing at all on a touch
   screen -- which reads as a broken tooltip rather than a slow one. This
   renders the definition from data-tip immediately on hover.

   `position:relative` on the term and no overflow clipping on the row is what
   lets the bubble escape its table cell. */
.term{border-bottom:1px dotted var(--dim);cursor:help;position:relative}
th .term{border-bottom-color:var(--line)}

.term:hover::after,
.term:focus::after{
  content:attr(data-tip);
  position:absolute;
  left:0;
  top:calc(100% + 7px);
  z-index:60;
  width:max-content;
  max-width:340px;
  white-space:normal;
  text-align:left;
  font-size:12px;
  font-weight:400;
  font-style:normal;
  line-height:1.5;
  letter-spacing:normal;
  text-transform:none;
  color:var(--fg);
  background:var(--card);
  border:1px solid var(--line);
  border-radius:6px;
  padding:8px 11px;
  box-shadow:0 8px 24px rgba(0,0,0,.45);
  pointer-events:none;
}
/* A term with no definition behind it gets no bubble, rather than an empty
   one. `Def` returns null for an unknown key, so data-tip is simply absent. */
.term:not([data-tip]):hover::after,
.term[data-tip=""]:hover::after{content:none}

/* Near the right-hand edge the bubble would run off the page. */
.grid td:last-child .term:hover::after,
.grid th:last-child .term:hover::after{left:auto;right:0}

.gloss{margin:0 0 22px}
.gloss h3{font-size:14px;margin:0 0 2px;font-weight:600}
.gloss > .meta{margin:0 0 12px}
.gloss dl{margin:0;display:grid;grid-template-columns:170px 1fr;
  gap:0 22px;align-items:baseline}
.gloss dt{font-weight:600;padding:9px 0;border-top:1px solid var(--line)}
.gloss dd{margin:0;padding:9px 0;border-top:1px solid var(--line);
  color:var(--dim);font-size:12.5px;line-height:1.55}
.gloss dd p{margin:0 0 7px}
.gloss dd p:last-child{margin-bottom:0}

@media (max-width:760px){
  .grid{font-size:12.5px}
  .grid th,.grid td{padding:6px 5px}
  .modelcell{min-width:170px}
  .whyctx{gap:16px}
  /* A 170px definition-list gutter leaves no room for the definition on a
     phone, so the term becomes a heading above its own text. */
  .gloss dl{grid-template-columns:1fr;gap:0}
  .gloss dt{padding-bottom:0;border-top:1px solid var(--line)}
  .gloss dd{padding-top:3px;border-top:none}
}

/* Team marks beside a pick. Cosmetic only: alt="" and a fixed box, so a
   missing or slow logo shifts nothing and reads as nothing. */
.tlogo{height:18px;width:18px;object-fit:contain;vertical-align:-4px;margin:0 5px}

/* Who has the ball. Small and quiet: it marks a row, it is not a stat. */
.ball{color:var(--accent);margin-right:5px;font-size:10px;vertical-align:1px}

/* The line under a model pick that spells out its arithmetic. Quiet: it is
   there to be consulted once and then ignored. */
.meta.calc{font-size:11.5px;color:var(--dim);margin-top:2px;font-variant-numeric:tabular-nums}

/* A record or rating beside a team name. Quiet and parenthetical: the name is
   what the eye is looking for, this is what it checks a beat later. */
.sidenote{margin-left:6px;font-size:11.5px;color:var(--dim);
  font-variant-numeric:tabular-nums;font-weight:400}

/* The "tough" marker on a division that is both strong and tight. A chip
   rather than a colour: it is a claim, and a claim should be readable. */
.divmark{display:inline-block;margin-left:6px;font-size:10px;padding:1px 5px;
  border-radius:4px;border:1px solid var(--warn);color:var(--warn);
  text-transform:uppercase;letter-spacing:.05em;vertical-align:1px}

/* The per-panel sort control. Sits in the heading, so it reads as part of the
   section rather than as a toolbar floating above it. */
.sortbar{display:inline-flex;align-items:center;gap:5px;margin-left:10px;
  font-size:11px;text-transform:none;letter-spacing:normal;font-weight:400}
.sortbar label{color:var(--dim)}
.sortbar select{font:inherit;font-size:11px;padding:2px 4px;border-radius:5px;
  border:1px solid var(--line);background:var(--card);color:var(--ink)}
.sortbar .dirbtn{margin:0;font-size:11px;white-space:nowrap}
@media (max-width:760px){
  .sortbar{margin-left:0;margin-top:5px;width:100%}
}

/* Header link that reads as a button, and the signed-in name beside sign out. */
.btnlink{display:inline-block;font-size:13px;padding:7px 11px;border-radius:8px;
  border:1px solid var(--line);background:var(--card);color:var(--ink);
  text-decoration:none}
.whoami{display:block;color:var(--dim);font-size:12px;margin-bottom:6px}

/* Sub-tabs under a league: Board / Live / Everything. Quieter than the league
   tabs above them, because they are a view of the same thing rather than a
   different subject. */
.subtabs{display:flex;gap:5px;margin:0 0 10px}
.subtabs button{font-size:12px;padding:5px 10px;border-radius:7px}
.subtabs button.on{border-color:var(--accent);color:var(--accent)}
.livecount{display:inline-block;margin-left:5px;padding:0 5px;border-radius:8px;
  background:var(--bad);color:#fff;font-size:10px;font-weight:600;
  vertical-align:1px}

/* ---- UFC head-to-head matchup panel --------------------------------------
   Laid out the way ufc.com does it: a fighter on each side, the statistic
   named down the middle, and opposing bars so the comparison is readable
   without reading the numbers. Bars scale to a FIXED maximum per statistic,
   not to whichever fighter is higher -- scaling to the pair makes 0.40 vs
   0.42 look like a rout. */
.h2h{padding:4px 2px 10px}
.h2hhead{display:grid;grid-template-columns:1fr auto 1fr;gap:14px;
    align-items:center;padding:6px 0 14px;border-bottom:1px solid var(--line)}
.h2hhead .corner{display:flex;flex-direction:column;align-items:center;gap:4px;
    text-align:center;font-size:13.5px}
.h2hhead .corner img{width:64px;height:64px;object-fit:cover;object-position:top;
    border-radius:50%;background:var(--card)}
.h2hhead .corner.a b{color:var(--bad)}
.h2hhead .corner.b b{color:var(--accent)}
.h2hhead .bout{text-align:center;font-size:11px;text-transform:uppercase;
    letter-spacing:.06em}
.h2htabs{display:flex;gap:4px;margin-top:8px;flex-wrap:wrap;justify-content:center}
.h2htabs button{font:inherit;font-size:10.5px;text-transform:uppercase;
    letter-spacing:.05em;padding:5px 8px;border-radius:7px;cursor:pointer;
    border:1px solid var(--line);background:transparent;color:var(--dim)}
.h2htabs button.on{border-color:var(--accent);color:var(--accent)}
.h2hrow{display:grid;grid-template-columns:1fr minmax(150px,auto) 1fr;
    gap:12px;align-items:center;padding:9px 0;font-size:13.5px}
.h2hrow + .h2hrow{border-top:1px solid var(--line)}
.h2hrow .va{text-align:right;color:var(--bad);font-variant-numeric:tabular-nums}
.h2hrow .vb{text-align:left;color:var(--accent);font-variant-numeric:tabular-nums}
.h2hrow .lbl{text-align:center;font-size:10.5px;text-transform:uppercase;
    letter-spacing:.06em;color:var(--dim)}
.h2hrow .bars{display:grid;grid-template-columns:1fr 1fr;gap:3px;margin-top:5px;
    direction:ltr}
.h2hrow .bars .ba{justify-self:end;height:4px;border-radius:2px;
    background:var(--bad)}
.h2hrow .bars .bb{justify-self:start;height:4px;border-radius:2px;
    background:var(--accent)}
.h2hnote{color:var(--dim);font-size:11.5px;line-height:1.55;margin:12px 0 0}
table.grid.fights .form{font-variant-numeric:tabular-nums;letter-spacing:.06em;
    font-size:12px}

@media (max-width:640px){
  .h2hhead .corner img{width:48px;height:48px}
  .h2hrow{grid-template-columns:1fr minmax(96px,auto) 1fr;gap:7px;font-size:12.5px}
}

/* ---- matchup panel v2: photos beside the stats, odds along the bottom ---- */
.h2hbout{display:flex;flex-direction:column;align-items:center;gap:8px;
    padding:2px 0 12px;font-size:11px;text-transform:uppercase;letter-spacing:.06em}
.h2hpred{display:flex;gap:9px;align-items:center;justify-content:center;
    flex-wrap:wrap;padding:10px;margin:0 0 12px;border:1px solid var(--line);
    border-radius:9px;font-size:13.5px}
.h2hpred .lbl{font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;
    color:var(--dim)}
.conf{font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;
    padding:2px 7px;border-radius:999px;border:1px solid var(--line)}
.conf.high{border-color:var(--good);color:var(--good)}
.conf.medium{border-color:var(--accent);color:var(--accent)}
.conf.low{border-color:var(--warn);color:var(--warn)}
.conf.coinflip{border-color:var(--line);color:var(--dim)}

.h2hbody{display:grid;grid-template-columns:120px 1fr 120px;gap:14px;
    align-items:start}
.h2hbody .shot{display:flex;flex-direction:column;align-items:center;gap:5px;
    text-align:center;font-size:12.5px;position:sticky;top:8px}
.h2hbody .shot img{width:100%;max-width:118px;aspect-ratio:3/4;
    object-fit:cover;object-position:top center;border-radius:10px;
    background:var(--card)}
.h2hbody .shot.a b{color:var(--bad)}
.h2hbody .shot.b b{color:var(--accent)}

.h2hodds{display:grid;
    grid-template-columns:1fr auto minmax(60px,auto) auto 1fr;
    gap:10px;align-items:center;margin-top:14px;padding:11px 12px;
    border-top:1px solid var(--line);font-size:13.5px}
.h2hodds .side{display:flex;align-items:center;gap:7px;
    text-transform:uppercase;letter-spacing:.05em;font-size:11.5px;
    color:var(--dim)}
.h2hodds .side.b{justify-content:flex-end}
.h2hodds .flag{width:18px;height:12px;object-fit:cover;border-radius:2px}
.h2hodds .price{font-variant-numeric:tabular-nums;font-weight:600}
.h2hodds .price.a{color:var(--bad);text-align:right}
.h2hodds .price.b{color:var(--accent);text-align:left}
.h2hodds .price.fav{text-decoration:underline;text-underline-offset:3px}
.h2hodds .lbl{text-align:center;font-size:10.5px;text-transform:uppercase;
    letter-spacing:.06em;color:var(--dim)}

.parlay{margin:14px 0 4px}
.parlay h3{font-size:14px;margin:0 0 10px;display:flex;gap:8px;
    align-items:center}
.parlaymath{display:flex;gap:18px;flex-wrap:wrap;margin:12px 0 4px;
    padding:10px 12px;border:1px solid var(--line);border-radius:9px;
    font-size:13px}

@media (max-width:760px){
  .h2hbody{grid-template-columns:70px 1fr 70px;gap:8px}
  .h2hbody .shot img{max-width:68px}
  .h2hbody .shot b{font-size:11px}
  .h2hodds{grid-template-columns:auto 1fr auto;row-gap:6px}
  .h2hodds .lbl{grid-column:1/-1;order:-1}
}

/* ---- fight card main line: a face at each end, prices beside them -------- */
table.grid.fights td.fightcell{min-width:260px}
table.grid.fights .mini{display:flex;align-items:center;gap:9px}
table.grid.fights .mini .mug{width:34px;height:34px;flex:0 0 34px;
    border-radius:50%;object-fit:cover;object-position:top center;
    background:var(--card)}
table.grid.fights .mini .mug.a{order:0}
table.grid.fights .mini .mug.b{order:2}
table.grid.fights .mini .nm{order:1;flex:1 1 auto;line-height:1.35}
table.grid.fights .mini .nm b.a{color:var(--bad)}
table.grid.fights .mini .nm b.b{color:var(--accent)}
table.grid.fights .mini .nm .vs{margin:0 5px;font-size:11px;
    text-transform:uppercase;letter-spacing:.05em}
table.grid.fights td.odds{font-variant-numeric:tabular-nums;white-space:nowrap}
table.grid.fights td.odds .a{color:var(--bad)}
table.grid.fights td.odds .b{color:var(--accent)}
table.grid.fights td.odds .fav{font-weight:600;text-decoration:underline;
    text-underline-offset:2px}

@media (max-width:760px){
  table.grid.fights td.fightcell{min-width:0}
  table.grid.fights .mini .mug{width:26px;height:26px;flex:0 0 26px}
  table.grid.fights .mini .nm .vs{margin:0 3px}
}

/* ---- game room link on a board row -------------------------------------- */
.lnk.room{margin-left:9px;font-size:12px;padding:2px 8px;border-radius:999px;
    border:1px solid var(--line);color:var(--dim);text-decoration:none}
.lnk.room:hover{border-color:var(--accent);color:var(--accent)}

/* ---- "next fight is live" bar ------------------------------------------- */
.nudge{display:flex;gap:12px;align-items:center;justify-content:space-between;
    flex-wrap:wrap;padding:10px 13px;border:1px solid var(--accent);
    border-radius:10px;font-size:13.5px}

/* The discuss link is a sentence now, not a chip — let it breathe. */
.lnk.room{white-space:nowrap}

/* ---- "Discuss this game" — a real button, centred in its cell ------------ */
.roombtn{display:block;width:fit-content;margin:6px auto 2px;
    font:inherit;font-size:13.5px;font-weight:500;padding:8px 16px;
    border-radius:9px;border:1px solid var(--line);background:var(--card);
    color:var(--ink);text-decoration:none;white-space:nowrap;text-align:center}
.roombtn:hover{border-color:var(--accent);color:var(--accent)}

/* ---- watch-along video -------------------------------------------------- */
.videobar{display:flex;gap:12px;align-items:center;flex-wrap:wrap}
.videobar button{padding:9px 16px}
.videowrap{position:relative;width:100%;aspect-ratio:16/10;
    border:1px solid var(--line);border-radius:10px;overflow:hidden;
    background:#000}
.videowrap iframe{position:absolute;inset:0;width:100%;height:100%;border:0}

@media (max-width:640px){
  .videowrap{aspect-ratio:4/3}
}

/* ---- frozen table headers ------------------------------------------------
   The page header is already sticky; on a hundred-and-eleven-row board the
   COLUMN headers are the ones that matter, because by row thirty nobody
   remembers which number is "to cover" and which is "proj total".

   --hdr is the sticky page header's height, and the column row parks directly
   beneath it. Set as a variable so the two can never drift apart by a few
   pixels and leave a stripe of rows showing through the gap.

   A sticky th needs its own background: the cells scrolling beneath it are
   otherwise visible straight through, since the thead itself paints nothing. */
:root{--hdr:52px}

table.grid thead th{position:sticky;top:var(--hdr);z-index:4;
    background:var(--bg);
    box-shadow:inset 0 -1px 0 var(--line)}

/* The matchup drill-in opens INSIDE a table whose header is sticky. Its own
   sub-headers must sit below that one, not compete with it. */
table.grid tr.drill th{position:static;box-shadow:none}

/* The room's pinned line sits under the page header for the same reason. */
.pinned{top:var(--hdr)}

@media (max-width:640px){
  :root{--hdr:46px}
}

/* ---- the video consent notice ------------------------------------------- */
.vidnotice{border:1px solid var(--line);border-radius:10px;padding:12px 14px;
    font-size:13px;line-height:1.55}
.vidnotice b{display:block;margin-bottom:6px}
.vidnotice p{color:var(--dim);margin:0 0 8px}
.vidnotice p:last-child{margin-bottom:0}

/* The sticky header draws its own underline via box-shadow (set earlier), so
   the cell border would double it now that borders are separate. */
table.grid thead th{border-bottom:0}

/* ---- board search -------------------------------------------------------- */
.boardsearch{display:flex;gap:10px;align-items:center;flex-wrap:wrap;
    margin:0 0 10px}
.boardsearch input{flex:1 1 260px;max-width:420px;font:inherit;font-size:14px;
    padding:8px 11px;border-radius:9px;border:1px solid var(--line);
    background:var(--card);color:var(--ink)}
.boardsearch input:focus{outline:none;border-color:var(--accent)}

/* "Watch on" — the network is the answer; the medium is a footnote. */
.watchcell{white-space:nowrap}
.watchcell .dim{font-size:11px}

/* model filter on the picks panel */
.modelpick{display:inline-flex;gap:4px;margin-left:8px}
.modelpick button{font:inherit;font-size:10.5px;text-transform:uppercase;
    letter-spacing:.05em;padding:3px 8px;border-radius:7px;cursor:pointer;
    border:1px solid var(--line);background:transparent;color:var(--dim)}
.modelpick button.on{border-color:var(--accent);color:var(--accent)}

/* Team cell: badge, then name. The logo never replaces the name — a badge
   that fails to resolve must not take the team with it. */
.teamcell{text-align:center;min-width:104px}
.teamcell .tlogo{display:block;height:30px;width:30px;margin:0 auto 4px;
    object-fit:contain}
.teamcell .tname{display:block;line-height:1.25}

@media (max-width:760px){
  .teamcell{min-width:74px}
  .teamcell .tlogo{height:24px;width:24px}
}

/* ---- brand typography ----------------------------------------------------
   Archivo for text, IBM Plex Mono for every number. brand.css already maps
   .num and .fig onto the mono face; these are the places this dashboard
   writes figures without that class. Tabular figures matter here more than
   most: a column of prices where each row sits slightly differently reads as
   carelessness long before anyone works out why. */
body{font-family:var(--font-display)}
h1,h2,h3{font-family:var(--font-display);font-feature-settings:"ss01"}
.score,.pinrow .score,.parlaymath b,.h2hrow .va,.h2hrow .vb,
.moved b,.movecol b,td.odds,.grid td.num,.grid th.num,
.conf,.tag{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.tag,.conf{font-size:10.5px}

/* The mark, where a header wants it. */
.brandmark{height:18px;width:auto;vertical-align:-3px;margin-right:8px}

/* Wordmark lockup in the page header. The mark is inline SVG filled with
   --mark-quiet and --edge, so it follows the theme without a second file. */
h1.brand{display:flex;align-items:center;gap:12px;font-family:var(--font-display);
    font-weight:700;letter-spacing:-.01em;font-size:19px;white-space:nowrap}
/* BIG ENOUGH TO BE THE DRAWING IT IS. The mark carries yard lines, a centre
   circle and goal creases; at the 17px it started on, all of that collapsed
   into a green bar above a white pill. 40px is where the markings read.
   The viewBox is 48x27, so this is about 71px wide. */
h1.brand .brandmark{height:56px;width:auto;flex:0 0 auto;display:block}

/* 56px is not a guess. Rendered as a ladder against the real file: at 17px it
   is a green bar over a white pill; at 30px the yard lines appear; at 40px the
   centre circle resolves; at 56px the goal creases and the red centre line are
   legible, which is the point at which it is the drawing rather than a
   suggestion of one. Past 80px nothing further appears. */

@media (max-width:640px){
  h1.brand{gap:9px;font-size:16px}
  h1.brand .brandmark{height:38px}
}
