/* 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)}

/* The signal dot: material news against a game.

   NOT animated. The live dot next to it pulses because a game in progress is
   genuinely changing; this one marks a fact that is already settled, and two
   competing animations in adjacent columns turn the left edge of the board
   into a fairground. Colour and a number carry it. */
th.sig,td.sig{width:26px;padding-left:2px;padding-right:2px;text-align:center}
.sigdot{background:none;border:0;padding:2px 3px;cursor:pointer;
  color:var(--bad);font-size:12px;line-height:1;border-radius:5px;
  display:inline-flex;align-items:center;gap:2px}
.sigdot:hover{background:var(--line)}
.sigdot:focus-visible{outline:2px solid var(--bad);outline-offset:1px}
.sigdot .sign{font-size:10.5px;font-weight:700;color:var(--bad)}

.sigwrap{max-width:720px}
.sigwrap h3{font-size:13px;margin:2px 0 8px;font-weight:600}
.siglist{list-style:none;margin:0;padding:0}
.siglist li{padding:5px 0;border-bottom:1px solid var(--line)}
.siglist li:last-child{border-bottom:none}
.siglist .sigteam{display:inline-block;min-width:150px;color:var(--dim);
  font-size:12px}
.siglist .st{margin-left:7px;font-size:11.5px;text-transform:uppercase;
  letter-spacing:.03em}
.siglist .st.bad{color:var(--bad);font-weight:600}
.siglist .st.warn{color:var(--warn);font-weight:600}
.siglist .st.dim{color:var(--dim)}
.signote{margin:10px 0 0;font-size:12px;line-height:1.5;color:var(--dim);
  border-left:3px solid var(--warn);padding-left:9px}

@media (max-width:700px){
  .siglist .sigteam{display:block;min-width:0}
}

/* Confidence: the claim and the record.

   Green is NOT the default for a high probability. It is reserved for a band
   whose measured interval clears break-even -- see ConfClass. An "unproven"
   band is deliberately neutral, because a reassuring colour on an unmeasured
   number is the whole failure this display exists to avoid. */
.conf{margin-left:7px;font-size:11.5px;white-space:nowrap}
.conf .confv{color:var(--dim);margin-left:3px}
.conf-good .term{color:var(--good);font-weight:600}
.conf-bad .term{color:var(--bad);font-weight:600}
.conf-unknown .term{color:var(--dim);font-weight:600}

.confbox{border:1px solid var(--line);border-left-width:3px;border-radius:8px;
  padding:10px 12px;margin:10px 0 12px;background:var(--card)}
.confbox.conf-good{border-left-color:var(--good)}
.confbox.conf-bad{border-left-color:var(--bad)}
.confbox.conf-unknown{border-left-color:var(--dim)}
.confrow{display:flex;gap:26px;flex-wrap:wrap}
.confcell{display:flex;flex-direction:column;gap:1px;min-width:0}
.confcell b{font-size:17px;line-height:1.2;
  font-family:"IBM Plex Mono",ui-monospace,monospace}
.conflab{font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;
  color:var(--dim)}
.confcell .dim{font-size:11.5px}
.confwhy{margin:9px 0 0;font-size:12.5px;line-height:1.5}
.confnote{margin:6px 0 0;font-size:11.5px;line-height:1.5;color:var(--dim)}

@media (max-width:640px){
  .confrow{gap:14px}
  .confcell{flex:1 1 100%}
}

/* Why a price-dependent panel is empty.

   Warn-coloured, not error-coloured: nothing is broken, the data is simply too
   old to support the claim the panel makes. It is a deliberate refusal and
   should read as one. */
.stalebox{border:1px solid var(--warn);border-left-width:3px;border-radius:8px;
  padding:11px 13px;margin:4px 0 10px;background:var(--card);
  font-size:13px;line-height:1.55;max-width:680px}
.stalebox p{margin:0 0 7px}
.stalebox p:last-child{margin-bottom:0}
.stalehead{font-size:13.5px}
.stalebox .dim{color:var(--dim);font-size:12px}

/* The movement stamp. Muted on purpose: it qualifies the panel, it is not a
   finding in the panel. */
.tag.stale{color:var(--warn);border-color:var(--warn)}

/* 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}
}

/* The in-page explanation when the human check cannot load or was not
   completed. Warn-coloured, not error: nothing is broken on the server, and
   the reader can act on it. */
.botwarn{border:1px solid var(--warn);border-left-width:3px;border-radius:8px;
  padding:10px 12px;margin-top:10px;text-align:left;font-size:13px;
  line-height:1.5}
.botwarn p{margin:6px 0 0;color:var(--dim);font-size:12.5px}
/* A submit button that cannot yet be satisfied. Reads as unavailable rather
   than broken: the label says what it is waiting for. */
button[type="submit"]:disabled{opacity:.55;cursor:not-allowed}
/* A confidence figure the record does not support.

   MUTED, NOT COLOURED. The accent is reserved for the model's number where
   that number has been measured; here it has been measured and found wanting,
   so the figure is set in dim and the graded rate sits beside it. Removing it
   outright was tried and was worse to use -- a reader could no longer see what
   the model claimed, only that something had been taken away. */
.conf-unvalidated .term{color:var(--dim);font-weight:600;
  text-decoration:underline dotted var(--stale)}
.confbox.conf-unvalidated{border-left-color:var(--stale)}
.skillwarn{border-left:3px solid var(--stale);padding-left:9px;margin-top:9px}
.skillrow{margin-top:9px}
/* The model's figure on a pick card. Its <b> carries the weight; the muted
   variant dims the whole line so a claim the record does not support does not
   read with the same authority as one it does. */
.pickconf b{font-family:"IBM Plex Mono",ui-monospace,monospace;
  font-variant-numeric:tabular-nums;color:var(--ink)}
.pickconf.conf-unvalidated b{color:var(--dim);
  text-decoration:underline dotted var(--stale)}
/* Cascading sort: up to three levels in one heading. Each level is its own
   group so the label, its select and its direction arrow stay together when
   the row wraps at phone width -- a "then" that wraps away from its dropdown
   reads as a separate control. */
.sortlevel{display:inline-flex;align-items:center;gap:4px;margin-right:10px}
.sortlevel:last-child{margin-right:0}
.sortbar{display:inline-flex;flex-wrap:wrap;align-items:center;gap:4px 0}
.sortlevel .dirbtn{padding:0 4px;font-size:12px;line-height:1}

/* SPREAD DRILL (LineHistoryPanel.razor). The board's Spread cell is a button
   that opens every book's line, one column per Eastern day. Direction gets the
   accent colour, not good/bad: a line moving toward the home side is neither. */
.linebtn{background:none;border:0;padding:0;font:inherit;color:inherit;
  border-bottom:1px dotted var(--dim);border-radius:0;cursor:pointer;
  font-variant-numeric:tabular-nums}
.linebtn:hover,.linebtn.on{border-bottom-color:var(--accent)}
.linebtn.on{color:var(--accent)}
.linebtn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.lhwrap{min-width:0}
.lhhead{display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap}
.lhhead h3{font-size:13px;margin:2px 0;font-weight:600}
.lhtabs{display:flex;gap:4px}
.lhtabs button{padding:3px 9px;font-size:12px}
.lhtabs button.on{border-color:var(--accent);color:var(--accent)}
.lhscroll{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:8px 0 4px;
  border:1px solid var(--line);border-radius:8px;background:var(--bg);
  /* A table cell grows to fit its content, so overflow on its own does not
     stop a three-week history from widening the whole board. The cap does. */
  max-width:min(calc(100vw - 48px), 728px)}
.lhgrid{width:auto;min-width:100%;font-size:12.5px}
.lhgrid th,.lhgrid td{padding:5px 8px;white-space:nowrap}
.lhgrid .lhbook,
table.grid tr.drill .lhgrid th.lhbook{position:sticky;left:0;top:auto;z-index:1;background:var(--bg);
  text-align:left;font-weight:600;border-right:1px solid var(--line)}
.lhgrid thead .lhbook{color:var(--dim);font-weight:600}
.lhgrid tbody tr:hover .lhbook{background:var(--card)}
.lhgrid tfoot td{border-top:2px solid var(--line);border-bottom:0}
.lhgrid tfoot tr + tr td{border-top:0}
.lhgrid td.lhopen{font-weight:600}
.lhgrid td.lhflat{color:var(--dim)}
.lhgrid td.lhup,.lhgrid td.lhdn{color:var(--accent);font-weight:600}
.lhgrid td.lhoff{color:var(--warn);font-style:italic}
.lhgrid td.lhnone{background:repeating-linear-gradient(135deg,transparent 0 5px,var(--line) 5px 6px)}
.lharr{font-size:9px;margin-right:2px;vertical-align:1px}
.lhdot{color:var(--warn);margin-left:1px}

/* RECORD DRILL (TeamLogPanel.razor). The W-L beside a team name is a button
   that opens the games behind it. It keeps the quiet sidenote look and the
   hover explanation; the dotted underline turns accent when open. */
.recbtn{background:none;border:0;padding:0;font:inherit;font-size:11.5px;
  color:var(--dim);border-bottom:1px dotted var(--dim);border-radius:0;
  cursor:pointer;margin-left:6px;font-variant-numeric:tabular-nums}
.recbtn:hover,.recbtn.on{color:var(--accent);border-bottom-color:var(--accent)}
.recbtn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.tlwrap{min-width:0}
.tlsum{margin-top:4px}
.tlgrid td .good{color:var(--good);font-weight:600}
.tlgrid td .bad{color:var(--bad);font-weight:600}
.tlres{display:inline-block;min-width:2.2em;text-align:left;margin-right:4px}

/* RESULTS SUB-TAB (ResultsPanel.razor) and the record drill's "Our pick"
   column: our logged picks against the final scores. */
.ressum{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));
  gap:8px;margin:6px 0 8px}
.ressum .card{margin:0}
.resultswrap .lnk.on{color:var(--accent);font-weight:600}
.resgrid td{white-space:nowrap}
.tlpick{white-space:nowrap}
.tlpick div+div{margin-top:2px}

/* ELO SUB-TAB (EloPanel.razor): upcoming games + power rankings. The win
   cell carries a faint bar the width of the probability. */
.elowrap h3{margin:10px 0 4px;font-size:14px}
.elogrid td{white-space:nowrap}
.elopct{display:inline-block;min-width:3.2em;text-align:right;padding:1px 4px;
  border-radius:4px;background:linear-gradient(90deg,
  color-mix(in srgb,var(--accent) 22%,transparent) calc(var(--p)*1%),transparent 0)}
.elopct.fav{font-weight:700}

/* points-per-play column (slab/ppp.py) */
.pppcell{white-space:nowrap}
.pppcell .lnk{font-size:11.5px}
table.why.ppp td:first-child{white-space:nowrap}
.pppgrids{display:flex;gap:28px;flex-wrap:wrap;margin:10px 0 4px}
.pppgrid{flex:1 1 420px;min-width:0}
.pppgrid h3{font-size:13px;margin:2px 0 6px;font-weight:600}

/* PPP player drill (2026-10-16): PppPlayersPanel.razor */
table.why tr.drill{cursor:pointer}
table.why tr.drill:hover td{background:var(--hover, rgba(127,127,127,.08))}
table.why tr.drillrow > td{padding:4px 0 12px;border-bottom:1px solid var(--line)}
.pppplayers .meta{margin:4px 0 6px;font-size:12.5px}
table.pppplayergrid{margin:0 0 4px}
table.pppplayergrid tr.scored td:first-child{font-weight:600}
.pppplayers .pppnote{font-size:11.5px;margin:2px 0 0}

/* ================================================== 2026-10-16 redesign ===
   Deep charcoal ground, one neon accent (tokens in brand.css), the Line Move
   mark, pill league chips, arrows on line moves. Appended LAST so it wins
   over the rules above without editing them; delete this block to go back.
   Full previous files: _backup\design-20261016\.  */
body{font-family:var(--font-display)}
.card{border-radius:var(--radius-lg)}

header{background:color-mix(in srgb,var(--bg) 92%,transparent);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}

/* The mark is now a square tile; 40px is enough for a line and an arrow. */
h1.brand .brandmark{height:40px;width:40px;border-radius:9px}
.tld{font-family:var(--font-mono);font-weight:500;color:var(--accent)}
@media (max-width:640px){
  h1.brand .brandmark{height:32px;width:32px;border-radius:7px}
}

/* League chips: a horizontal carousel of pills, the picked one filled. */
.tabs{gap:8px;padding:10px 0 4px;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tabs button{border-radius:var(--radius-pill);min-height:36px;padding:7px 16px;
  font-weight:600;font-size:13.5px;background:var(--card);border-color:var(--line)}
.tabs button.on{background:var(--accent);border-color:var(--accent);
  color:var(--on-edge)}

/* Line moves: the colour now comes with an arrow, so it never carries the
   meaning alone. The sign stays in the number. */
.movecol b.pos::before{content:"\25B2\00a0";font-size:.75em}
.movecol b.neg::before{content:"\25BC\00a0";font-size:.75em}

.liverow{background:color-mix(in srgb,var(--accent) 8%,transparent)}
.grid tbody tr:hover{background:color-mix(in srgb,var(--accent) 5%,var(--card))}

/* Dark team logos (Raiders, Nets, Kings) disappear on a near-black page; a
   one-pixel light halo keeps their outline without boxing them. */
:root:not([data-theme="light"]) .tlogo,
:root:not([data-theme="light"]) .lg{filter:drop-shadow(0 0 1px rgba(255,255,255,.45))}

/* Team colour strip, beside the logo. ESPN's colour; decoration only. */
.tstrip{display:inline-block;width:4px;height:18px;border-radius:2px;
  vertical-align:-4px;margin-right:4px}

/* Watch star: the first board column. Outline until starred, then filled in
   the accent. A real button, 36px target on a dense table, 44px on phones. */
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.grid th.watchcell,.grid td.watchcell{width:40px;padding-left:4px;padding-right:0}
button.star{display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;padding:0;border:1px solid transparent;border-radius:8px;
  background:transparent;color:var(--dim)}
button.star svg path{fill:none}
button.star:hover{color:var(--ink)}
button.star.on{color:var(--accent)}
button.star.on svg path{fill:var(--accent)}
@media (max-width:640px){button.star{width:44px;height:44px}}

/* Watchlist tray, fixed to the bottom of the window. */
.watchspacer{height:150px}
.watchtray{position:fixed;left:0;right:0;bottom:0;z-index:6;
  background:color-mix(in srgb,var(--bg) 94%,transparent);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  border-top:1px solid var(--line);
  padding:8px 16px calc(8px + env(safe-area-inset-bottom))}
.watchhead{display:flex;align-items:center;gap:10px;max-width:1360px;margin:0 auto}
.watchtitle{display:inline-flex;align-items:center;gap:6px;font-weight:700;color:var(--ink)}
.watchtitle svg{color:var(--accent)}
.watchtitle svg path{fill:var(--accent)}
.watchhead .lnk{margin-left:auto}
.watchitems{display:flex;gap:10px;overflow-x:auto;padding:8px 0 2px;
  max-width:1360px;margin:0 auto;scrollbar-width:thin}
.watchitem{flex:0 0 auto;display:flex;align-items:stretch;border:1px solid var(--line);
  border-radius:var(--radius-md);background:var(--card)}
.watchgo{display:flex;flex-direction:column;align-items:flex-start;gap:2px;
  border:0;background:transparent;text-align:left;padding:8px 10px;min-width:210px;
  font-size:13px}
.watchgo .tag{margin:0 0 2px}
.watchx{border:0;border-left:1px solid var(--line);border-radius:0 8px 8px 0;
  background:transparent;color:var(--dim);font-size:18px;width:40px}
.watchx:hover{color:var(--ink)}

/* Ask (2026-10-16): a question box under the header, answers as cards. */
.ask{margin-top:14px}
.askrow{display:flex;gap:8px;align-items:stretch}
.askinput{flex:1 1 auto;min-width:0;font:inherit;font-size:15px;padding:10px 12px;
  border-radius:var(--radius-md);border:1px solid var(--line);background:var(--card);
  color:var(--ink)}
.askinput::placeholder{color:var(--dim)}
.askinput:focus{outline:2px solid var(--edge);outline-offset:1px}
button.mic{width:44px;padding:0;display:inline-flex;align-items:center;justify-content:center;
  color:var(--dim)}
button.mic.on{color:var(--on-edge);background:var(--accent);border-color:var(--accent);
  animation:pulse 1.6s ease-in-out infinite}
button.askgo{background:var(--accent);border-color:var(--accent);color:var(--on-edge);
  font-weight:700;padding:0 18px}
button.askgo[disabled]{opacity:.45}
.askturn{margin-top:10px;display:flex;flex-direction:column;gap:6px}
.askq{font-weight:600}
.aska{white-space:pre-wrap;line-height:1.55}
.askspeak{align-self:flex-start;margin-left:0}
.askmeta{font-size:12px;margin:8px 0 0}
.askacts{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
button.askshow{border-color:var(--accent);color:var(--ink);font-weight:600;
  border-radius:var(--radius-pill);padding:6px 12px}
button.askshow .tag{margin-left:6px}
button.star.speak{width:32px;height:32px}
@keyframes flashrow{0%{background:color-mix(in srgb,var(--accent) 28%,transparent)}100%{background:transparent}}
tr.flashrow td{animation:flashrow 2.4s ease-out 2}
.grid th.watchcell,.grid td.watchcell{width:76px;white-space:nowrap}
button.askctl{padding:6px 12px;border-radius:var(--radius-pill);font-weight:600;font-size:12.5px;
  min-height:32px;color:var(--ink)}
button.star.speak.on svg path{fill:none}

/* 2026-10-17: college poll rank beside the name, and the team log's
   "still to play" list with opponents' records. */
.pollrank{font-size:.78em;font-weight:700;color:var(--edge,#38d4ff);margin-right:.25em;letter-spacing:.01em}
.tlup{margin:1.1em 0 .4em;font-size:.95rem;font-weight:600}
.tlupgrid td:nth-child(3){white-space:nowrap}

/* 2026-10-17: hockey, sportsbook-style grid (HockeyGrid.razor). */
tr.hgridrow > td{padding-top:0;border-top:none}
.hgrid{display:grid;grid-template-columns:minmax(120px,1.4fr) repeat(3,minmax(92px,1fr));gap:6px;max-width:720px;margin:2px 0 4px}
.hgh{font-size:.78rem;color:var(--dim,#9aa0aa);text-align:center;letter-spacing:.02em}
.hgteam{align-self:center;font-weight:600}
.hgcell{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;padding:6px 4px;border-radius:8px;background:var(--card,#18181d);border:1px solid var(--line,#2a2a32);font-variant-numeric:tabular-nums}
.hgcell .hgline{font-size:.85rem}
.hgcell .hgprice{font-weight:700}
.hgcell .hgprice.big{font-size:1.02rem}
.hgcell .hgours{font-size:.74rem;color:var(--dim,#9aa0aa)}
.hgcell.pick{border-color:var(--edge,#38d4ff);box-shadow:inset 0 0 0 1px var(--edge,#38d4ff)}
.hgcell.pick .hgours{color:var(--edge,#38d4ff);font-weight:700}
.hgcell.lowconf.pick{border-style:dashed;box-shadow:none}
.hgnote{margin:2px 0 6px;font-size:.78rem}
@media (max-width:640px){.hgrid{grid-template-columns:minmax(80px,1fr) repeat(3,1fr)}}
