/* ============================================================
   Pigskin Lab — one token set, two themes.

   Look: a reference database, not an app. Flat surfaces, hairline rules,
   square corners, dense tables, condensed uppercase section heads.
   Light is the default; dark is neutral charcoal (no tinted blues).
   Every color in charts, tables and exported PNGs comes from these tokens.
   ============================================================ */

:root {
  color-scheme: light;
  --bg: #ffffff;
  --surface: #ffffff;
  --surface-2: #f4f4f4;
  --surface-3: #e8e8e8;
  --row-alt: #fafafa;
  --row-hover: #fff8d6;
  --border: #d0d0d0;
  --border-strong: #9a9a9a;
  --grid: #e9e9e9;
  --text: #111111;
  --text-2: #3b3b3b;
  --muted: #5f5f5f;
  --link: #0b57d0;
  --focus: #0b57d0;
  --brand: #c8102e;
  --brand-ink: #c8102e;   /* the brand red as small text: AA on the page background */
  --brand-btn: #c8102e;   /* the brand red behind white text */
  --ink-btn: #111111;
  --ink-btn-text: #ffffff;
  --header-bg: #111111;
  --header-ink: #ffffff;
  --header-muted: #bdbdbd;
  --sel: #0b57d0;

  --real: #0f7a34;
  --noise: #a84a06;
  --early: #1f4fc4;
  --void: #5f5f5f;
  --right: #0f7a34;
  --wrong: #b3261e;

  --s1: #2a78d6; --s2: #eb6834; --s3: #1baf7a; --s4: #eda100; --s5: #e87ba4; --s6: #008300;
  --div-neg: #c8322f; --div-mid: #f0efec; --div-pos: #2a78d6;

  --font: "Roboto", "Helvetica Neue", Arial, system-ui, sans-serif;
  --display: "Roboto Condensed", "Arial Narrow", "Helvetica Neue", Arial, sans-serif;
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #161616; --surface: #1d1d1d; --surface-2: #252525; --surface-3: #2f2f2f;
  --row-alt: #212121; --row-hover: #3a3520;
  --border: #3a3a3a; --border-strong: #6a6a6a; --grid: #2c2c2c;
  --text: #ededed; --text-2: #cfcfcf; --muted: #a8a8a8;
  --link: #8ab4f8; --focus: #8ab4f8; --brand: #e0443c; --brand-ink: #ff6b61; --brand-btn: #b8302a;
  --ink-btn: #ededed; --ink-btn-text: #111111;
  --header-bg: #0c0c0c; --header-ink: #ededed; --header-muted: #a8a8a8; --sel: #8ab4f8;
  --real: #16803c; --noise: #b4570c; --early: #2d5fd6; --void: #5f5f5f; --right: #3ecf73; --wrong: #ff7b72;
  --s1: #3987e5; --s2: #d95926; --s3: #199e70; --s4: #c98500; --s5: #d55181; --s6: #2e9e2e;
  --div-neg: #e66767; --div-mid: #383835; --div-pos: #3987e5;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--header-h, 90px) + 8px); }
body { margin: 0; background: var(--bg); color: var(--text); font: 14px/1.5 var(--font); min-height: 100vh; display: flex; flex-direction: column; }
a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }
/* Links inside running text are underlined, not told apart by colour alone (WCAG 1.4.1). */
p a:not(.btn), .site-footer a, dd a, .notice a { text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
h1, h2, h3, h4 { font-family: var(--display); font-weight: 700; line-height: 1.15; margin: 0 0 .4em; }
h1 { font-size: 2rem; }
h2 { font-size: 1.15rem; text-transform: uppercase; letter-spacing: .02em; }
h3 { font-size: 1rem; }
p { margin: 0 0 .75em; }
.muted { color: var(--muted); }
.small { font-size: .85rem; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.wrap { width: 100%; max-width: 1320px; margin: 0 auto; padding: 0 16px; }
.wrap.wide { max-width: none; }
/* A screen tall before the page arrives: the footer then starts below the fold instead of
   sitting on screen and being shoved down (Lighthouse measured that jump as 0.15 layout shift). */
main { flex: 1; min-width: 0; padding-bottom: 40px; min-height: 100vh; }
main.flush { padding-bottom: 0; }
.skip { position: absolute; left: -999px; top: 8px; background: var(--surface); color: var(--text); padding: 8px 12px; z-index: 100; }
.skip:focus { left: 8px; }

/* ---------- header ---------- */
.site-header { background: var(--header-bg); color: var(--header-ink); position: sticky; top: 0; z-index: 40; border-bottom: 3px solid var(--brand); }
.site-header .wrap { display: flex; align-items: center; gap: 22px; height: 50px; max-width: none; }
.brand { color: var(--header-ink); font: 700 1.35rem/1 var(--display); letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; display: flex; align-items: center; gap: 10px; }
.brand:hover { text-decoration: none; }
.brand .mark { display: inline-block; width: 12px; height: 12px; border: 3px solid var(--brand); transform: rotate(45deg); }
.nav { display: flex; flex: 1; overflow-x: auto; scrollbar-width: none; height: 100%; }
.nav::-webkit-scrollbar { display: none; }
.nav a { color: var(--header-muted); padding: 0 11px; font: 600 .8rem/50px var(--font); text-transform: uppercase; letter-spacing: .04em; white-space: nowrap; border-bottom: 3px solid transparent; }
.nav a:hover { color: var(--header-ink); text-decoration: none; }
.nav a[aria-current="page"] { color: var(--header-ink); border-bottom-color: var(--header-ink); }
.header-tools { display: flex; align-items: center; gap: 8px; }
.site-header .search { position: relative; }
.site-header .search input { width: 210px; background: #2a2a2a; border: 1px solid #4a4a4a; color: #fff; padding: 5px 9px; }
.site-header .search input::placeholder { color: #a3a3a3; }
.search-results { position: absolute; right: 0; top: calc(100% + 4px); width: 320px; background: var(--surface); color: var(--text); border: 1px solid var(--border-strong); padding: 4px 0; display: none; z-index: 60; }
.search-results.open { display: block; }
.search-results a { display: flex; justify-content: space-between; gap: 8px; padding: 6px 10px; color: var(--text); }
.search-results a small { color: var(--muted); }
.search-results a:hover, .search-results a.active { background: var(--row-hover); text-decoration: none; }
.icon-btn { background: transparent; border: 1px solid #4a4a4a; color: #ededed; height: 30px; padding: 0 9px; display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font: 600 .74rem/1 var(--font); text-transform: uppercase; letter-spacing: .04em; }
.icon-btn:hover { background: #2a2a2a; }
a.icon-btn { text-decoration: none; }
.icon-btn svg { width: 14px; height: 14px; }
/* Below 1366px the logo, eight links and the tools do not fit on one line (on a 1280px laptop
   "Trend watch" was cut off), so the links move to their own row and wrap there instead of
   scrolling sideways, where the last ones sat out of sight. */
@media (max-width: 1365px) {
  .site-header .wrap { flex-wrap: wrap; height: auto; padding-top: 8px; gap: 8px; }
  .nav { order: 3; flex-basis: 100%; height: auto; flex-wrap: wrap; justify-content: center; overflow: visible; padding-bottom: 2px; }
  .nav a { line-height: 34px; padding: 0 9px; }
  .header-tools { margin-left: auto; }
}
@media (max-width: 960px) {
  .site-header .search input { width: 150px; }
}

/* ---------- page furniture ---------- */
.page-head { padding: 16px 0 10px; border-bottom: 1px solid var(--border); margin-bottom: 14px; }
.page-head h1 { margin: 0 0 4px; }
.page-head p { color: var(--text-2); max-width: 72em; margin: 0; }
.crumbs { font-size: .78rem; color: var(--muted); margin-bottom: 4px; }
.crumbs a { color: var(--muted); }
.controls-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: end; margin-top: 10px; }
.section { margin-top: 26px; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; border-bottom: 2px solid var(--text); padding-bottom: 3px; margin-bottom: 10px; }
.section-head h2 { margin: 0; }
.section-head .more { font-size: .8rem; }
.box { background: var(--surface); border: 1px solid var(--border); padding: 10px 12px; }
.box > h3:first-child { margin-top: 0; }
.grid { display: grid; gap: 16px; }
.grid.two { grid-template-columns: repeat(auto-fit, minmax(min(100%, 460px), 1fr)); }
.grid.three { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.grid.side { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
@media (max-width: 960px) { .grid.side { grid-template-columns: minmax(0, 1fr); } }
.btn { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; height: 30px; border: 1px solid var(--border-strong); background: var(--surface); color: var(--text); font: 600 .8rem/1.2 var(--font); cursor: pointer; white-space: nowrap; }
.btn:hover { background: var(--surface-2); text-decoration: none; }
.btn.primary { background: var(--ink-btn); color: var(--ink-btn-text); border-color: var(--ink-btn); }
.btn.primary:hover { opacity: .88; }
.btn.small { height: 26px; padding: 3px 8px; font-size: .75rem; }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn svg { width: 14px; height: 14px; }
.seg { display: inline-flex; border: 1px solid var(--border-strong); height: 30px; }
.seg button { border: 0; border-right: 1px solid var(--border-strong); background: var(--surface); color: var(--text-2); padding: 0 10px; font: 600 .78rem/1 var(--font); cursor: pointer; }
.seg button:last-child { border-right: 0; }
.seg button[aria-pressed="true"], .seg button[aria-selected="true"] { background: var(--text); color: var(--bg); }
select, input[type="number"], input[type="text"], input[type="search"], input[type="email"], input[type="password"] {
  font: inherit; font-size: .84rem; color: var(--text); background: var(--surface); border: 1px solid var(--border-strong); border-radius: 0; padding: 3px 6px; min-width: 0; height: 30px;
}
input[type="number"] { width: 76px; }
input[type="color"] { width: 32px; height: 26px; padding: 1px; border: 1px solid var(--border-strong); background: var(--surface); cursor: pointer; }
input[type="checkbox"] { accent-color: var(--text); }
label.field { display: grid; gap: 2px; font-size: .68rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; }
label.check { display: inline-flex; gap: 6px; align-items: center; font-size: .84rem; color: var(--text-2); height: 30px; }
.notice { border-left: 3px solid var(--noise); background: var(--surface-2); padding: 8px 10px; font-size: .86rem; color: var(--text-2); }
.notice.info { border-color: var(--early); }
.error { color: var(--wrong); }
.loading { color: var(--muted); padding: 24px 0; }
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); border: 1px solid var(--border); background: var(--surface); }
.kpi { padding: 8px 12px; border-right: 1px solid var(--border); }
.kpi:last-child { border-right: 0; }
.kpi .v { font: 700 1.55rem/1.1 var(--display); font-variant-numeric: tabular-nums; }
.kpi .l { font-size: .7rem; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; }

/* ---------- tables (reference-site style) ---------- */
.tbl-wrap { overflow: auto; border: 1px solid var(--border); max-width: 100%; background: var(--surface); }
.tbl-wrap.tall { max-height: 72vh; }
table.stats { border-collapse: collapse; width: 100%; font-size: .8rem; font-variant-numeric: tabular-nums; }
table.stats th, table.stats td { padding: 3px 7px; border-bottom: 1px solid var(--grid); white-space: nowrap; text-align: right; }
table.stats th.l, table.stats td.l { text-align: left; }
table.stats thead th { position: sticky; top: 0; z-index: 2; background: var(--surface-2); color: var(--text); font-weight: 700; border-bottom: 1px solid var(--border-strong); cursor: pointer; user-select: none; }
table.stats thead th[aria-sort="descending"]::after { content: " \25BC"; font-size: .6em; }
table.stats thead th[aria-sort="ascending"]::after { content: " \25B2"; font-size: .6em; }
table.stats thead th:hover { background: var(--surface-3); }
table.stats tbody tr:nth-child(even) td { background: var(--row-alt); }
table.stats tbody tr:hover td { background: var(--row-hover); }
table.stats td.rk { color: var(--muted); }
table.stats td.lead { font-weight: 700; }
table.stats tr.pin td { font-weight: 700; background: var(--row-hover); }
table.stats tfoot td { font-weight: 700; border-top: 1px solid var(--border-strong); background: var(--surface-2); position: sticky; bottom: 0; }
table.stats td .bar { display: inline-block; height: 8px; background: var(--s1); opacity: .35; vertical-align: middle; margin-right: 4px; }
.tbl-tools { display: flex; gap: 8px; flex-wrap: wrap; align-items: end; padding: 8px 0; }
.tbl-meta { font-size: .76rem; color: var(--muted); padding: 4px 0; }
.pop { position: relative; }
.pop .menu { position: absolute; z-index: 45; top: calc(100% + 2px); left: 0; background: var(--surface); border: 1px solid var(--border-strong); padding: 8px 10px; max-height: 380px; overflow: auto; min-width: 250px; display: none; }
.pop.open .menu { display: block; }
.pop .menu h4 { font-size: .68rem; text-transform: uppercase; color: var(--muted); margin: 8px 0 2px; letter-spacing: .05em; }
.pop .menu label { display: flex; gap: 6px; font-size: .82rem; padding: 1px 0; align-items: center; }
.filter-row { display: flex; gap: 4px; align-items: center; margin-bottom: 4px; }

/* ---------- team chip, badges ---------- */
.tchip { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; color: var(--text); }
.tchip i { width: 4px; height: 15px; display: inline-block; background: var(--tc, var(--muted)); }
/* A team's colour on the dark card (fix.colour): the element carries --tc (3:1 on the light card) and --tc-dark (3:1 on
   the dark card, ui.js tcStyle); a stylesheet !important beats the inline --tc, so navy and black strips stay visible. */
:root[data-theme="dark"] [style*="--tc-dark"] { --tc: var(--tc-dark) !important; }
.badge { display: inline-flex; align-items: center; gap: 5px; padding: 2px 6px; font: 700 .66rem/1.3 var(--font); letter-spacing: .06em; text-transform: uppercase; color: #fff; white-space: nowrap; }
.badge svg { width: 11px; height: 11px; }
.badge.real { background: var(--real); }
.badge.noise { background: var(--noise); }
.badge.early { background: var(--early); }
.badge.void { background: var(--void); }
.outcome { display: inline-flex; align-items: center; gap: 4px; font-weight: 700; }
.outcome.right { color: var(--right); }
.outcome.wrong { color: var(--wrong); }
.outcome svg { width: 14px; height: 14px; }

/* ---------- trend cards (flat) ---------- */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 310px), 1fr)); border-top: 1px solid var(--border); border-left: 1px solid var(--border); }
.vcard { display: flex; flex-direction: column; gap: 5px; background: var(--surface); border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); padding: 9px 12px 10px 14px; color: var(--text); position: relative; }
.vcard::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--tc, var(--border)); }
.vcard:hover { background: var(--row-hover); text-decoration: none; }
.vcard .top { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: .78rem; }
.vcard h3 { font: 700 1rem/1.2 var(--display); margin: 0; }
.vcard .vals { display: flex; gap: 12px; font-size: .78rem; color: var(--text-2); flex-wrap: wrap; font-variant-numeric: tabular-nums; }
.vcard .vals b { color: var(--text); }
.vcard .when { font-size: .78rem; color: var(--text-2); }
.vcard .when strong { color: var(--text); }
.meter { height: 6px; background: var(--surface-3); position: relative; }
.meter span { position: absolute; inset: 0 auto 0 0; background: var(--early); }
.meter.done span { background: var(--real); }
.meter-label { display: flex; justify-content: space-between; font-size: .7rem; color: var(--muted); margin-top: 2px; font-variant-numeric: tabular-nums; }

/* ---------- charts ---------- */
.chart { position: relative; width: 100%; }
.chart svg { display: block; width: 100%; height: auto; }
.chart.fill { height: 100%; min-height: 60px; }
.chart.fill svg { height: 100%; }
.chart-note { font-size: .74rem; color: var(--muted); margin-top: 4px; }
.legend { display: flex; flex-wrap: wrap; gap: 3px 14px; margin: 0 0 4px; font-size: .76rem; }
.legend button { display: inline-flex; align-items: center; gap: 5px; background: none; border: 0; padding: 1px 0; color: var(--text-2); font: inherit; cursor: pointer; }
.legend button[aria-pressed="false"] { opacity: .45; text-decoration: line-through; }
.legend svg { width: 12px; height: 12px; }
.tooltip { position: fixed; z-index: 90; pointer-events: none; background: var(--surface); color: var(--text); border: 1px solid var(--border-strong); padding: 6px 8px; font-size: .78rem; line-height: 1.4; max-width: 320px; opacity: 0; }
.tooltip.on { opacity: 1; }
.tooltip .tt-h { font-weight: 700; margin-bottom: 2px; }
.tooltip .tt-r, .tip-sheet .tt-r { display: flex; align-items: center; gap: 10px; justify-content: space-between; }
.tooltip .tt-r span:first-child, .tip-sheet .tt-r span:first-child { display: inline-flex; align-items: center; gap: 5px; color: var(--text-2); }
.tooltip .tt-r b, .tip-sheet .tt-r b { font-variant-numeric: tabular-nums; }
.tooltip .tt-note { color: var(--muted); margin-top: 2px; }

/* ---------- home ---------- */
.scoreboard { display: flex; overflow-x: auto; border: 1px solid var(--border); background: var(--surface); scrollbar-width: thin; }
.score { min-width: 142px; padding: 5px 10px; border-right: 1px solid var(--border); font-size: .78rem; color: var(--text); font-variant-numeric: tabular-nums; }
.score:hover { background: var(--row-hover); text-decoration: none; }
.score .ln { display: flex; justify-content: space-between; gap: 8px; }
.score .ln.win { font-weight: 700; }
.score .st { color: var(--muted); font-size: .66rem; text-transform: uppercase; letter-spacing: .04em; }
/* Six links, always in full rows: 3 across on a desktop, 2 on a tablet, 1 on a phone (auto-fit left five and an orphan). */
.tool-links { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-top: 1px solid var(--border); border-left: 1px solid var(--border); }
@media (max-width: 900px) { .tool-links { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .tool-links { grid-template-columns: minmax(0, 1fr); } }
.tool-links a { display: flex; flex-direction: column; gap: 4px; padding: 14px 16px; border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); color: var(--text); background: var(--surface); }
.tool-links a:hover { background: var(--row-hover); text-decoration: none; }
.tool-links b { display: block; font: 700 1.05rem/1.2 var(--display); text-transform: uppercase; letter-spacing: .03em; }
.tool-links b::after { content: " ›"; color: var(--brand-ink); }
.tool-links span { color: var(--text-2); font-size: .86rem; line-height: 1.45; }

/* ---------- dashboard maker ---------- */
.dash-top { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; padding: 8px 0 6px; }
.dash-top .title-input { font: 700 1.25rem/1 var(--display); border: 1px solid transparent; background: transparent; height: 34px; width: 340px; max-width: 100%; }
.dash-top .title-input:hover, .dash-top .title-input:focus { border-color: var(--border-strong); background: var(--surface); }
.dash-top .spacer { flex: 1; }
.dash-top .sep { width: 1px; height: 22px; background: var(--border); margin: 0 4px; }
.board-scroll { overflow: auto; border: 1px solid var(--border-strong); background: var(--surface-2); }
.board { position: relative; background-color: var(--surface-2); }
.board.grid-on { background-image: linear-gradient(var(--grid) 1px, transparent 1px), linear-gradient(90deg, var(--grid) 1px, transparent 1px); background-size: 20px 20px; }
.board-empty { position: absolute; left: 0; right: 0; top: 60px; display: grid; place-items: center; text-align: center; color: var(--muted); }
.board-empty > div { max-width: 620px; background: var(--surface); border: 1px solid var(--border); padding: 16px 18px; }
.board-empty .presets { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin-top: 10px; }
.widget { position: absolute; background: var(--surface); border: 1px solid var(--border-strong); display: flex; flex-direction: column; }
.widget.selected { outline: 2px solid var(--sel); z-index: 20; }
.widget .wbar { display: flex; align-items: center; gap: 6px; padding: 3px 4px 3px 9px; border-bottom: 1px solid var(--border); cursor: grab; user-select: none; touch-action: none; min-height: 34px; }
.widget.dragging .wbar { cursor: grabbing; }
.widget .wtitle { flex: 1; min-width: 0; }
.widget.pcoded { border-top: 5px solid var(--pc); }
.widget.pcoded .wtitle span::before { content: ''; display: inline-block; width: .6em; height: .6em; margin-right: .35em; background: var(--pc); vertical-align: baseline; }
.widget .wtitle b { display: block; font: 700 .9rem/1.2 var(--display); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.widget .wtitle span { display: block; font-size: .7rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.widget .wtools { display: flex; gap: 1px; }
.widget .wtools button { width: 24px; height: 24px; display: grid; place-items: center; border: 1px solid transparent; background: none; color: var(--text-2); cursor: pointer; }
.widget .wtools button:hover { border-color: var(--border-strong); background: var(--surface-2); }
.widget .wtools svg { width: 13px; height: 13px; }
.widget .wbody { flex: 1; min-height: 0; padding: 4px 8px 6px; overflow: hidden; display: flex; flex-direction: column; }
.widget .wbody > .chart { flex: 1; min-height: 0; }
.widget .wbody > .tbl-wrap { flex: 1; min-height: 0; }
/* How it swung: the biggest swings listed under the win-probability chart, numbered like its markers, two lines each.
   A widget too short for both keeps the chart and its numbered markers (each marker's tip still tells the play). */
.widget .wbody:has(> .swings) { container-type: size; }
.widget .wbody > .swings { flex: none; list-style: none; counter-reset: swing; margin: 6px 0 0; padding: 6px 0 0; border-top: 1px solid var(--grid); font-size: .74rem; line-height: 1.35; color: var(--text-2); }
.swings li { counter-increment: swing; position: relative; padding-left: 24px; margin: 0 0 4px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.swings li::before { content: counter(swing); position: absolute; left: 0; top: 0; width: 17px; height: 17px; box-sizing: border-box; border-radius: 50%; border: 1.5px solid var(--text-2); display: grid; place-items: center; font-size: .66rem; font-weight: 700; color: var(--text); }
.swings li b { color: var(--text); font-weight: 700; }
@container (max-height: 330px) { .swings { display: none; } }
.widget .wnote { font-size: .68rem; color: var(--muted); padding: 2px 8px 3px; border-top: 1px solid var(--grid); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A ranking's profile chart says what it is in full, on a phone too: its title and note wrap. */
.widget.profile .wtitle b, .widget.profile .wnote { white-space: normal; }
.widget.profile .wnote { font-size: .74rem; color: var(--text); }
.widget .h-se { position: absolute; width: 14px; height: 14px; right: -1px; bottom: -1px; cursor: nwse-resize; background: linear-gradient(135deg, transparent 55%, var(--border-strong) 55%); touch-action: none; }
.widget .h-e { position: absolute; top: 34px; bottom: 14px; right: -5px; width: 10px; cursor: ew-resize; touch-action: none; }
.widget .h-s { position: absolute; left: 0; right: 14px; bottom: -5px; height: 10px; cursor: ns-resize; touch-action: none; }
.widget.text .wbody { overflow: auto; }
.widget .note-edit { outline: none; min-height: 100%; font-size: .9rem; white-space: pre-wrap; }
.widget .kpi-big { font: 700 2.8rem/1 var(--display); font-variant-numeric: tabular-nums; }
.inspector { position: fixed; z-index: 70; width: 310px; max-height: 76vh; overflow: auto; background: var(--surface); border: 1px solid var(--text); padding: 10px 12px; box-shadow: 0 8px 28px rgba(0, 0, 0, .2); }
.inspector h3 { display: flex; justify-content: space-between; align-items: center; margin: 0 0 8px; font-size: .95rem; text-transform: uppercase; }
.inspector .row { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 8px; }
.inspector .row.one { grid-template-columns: 1fr; }
.inspector .colors { display: grid; gap: 4px; margin-bottom: 8px; }
.inspector .colors label { display: flex; align-items: center; gap: 8px; font-size: .8rem; }
.inspector hr { border: 0; border-top: 1px solid var(--border); margin: 8px 0; }
.series-row { display: flex; gap: 4px; align-items: center; margin-top: 4px; }
.series-row .sw { width: 10px; height: 10px; flex: none; }
.series-row .x { background: none; border: 0; color: var(--muted); cursor: pointer; font-size: 1.1rem; padding: 0 2px; }
.ac { position: relative; }
.ac input { width: 170px; }
.ac-list { position: absolute; z-index: 80; left: 0; min-width: 270px; bottom: 100%; background: var(--surface); border: 1px solid var(--border-strong); max-height: 240px; overflow: auto; display: none; }
.ac-list.open { display: block; }
.ac-list button { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 5px 8px; color: var(--text); font: inherit; font-size: .8rem; cursor: pointer; }
.ac-list button:hover { background: var(--row-hover); }

/* ---------- misc ---------- */
.list { list-style: none; margin: 0; padding: 0; }
.list li { display: flex; gap: 10px; align-items: center; justify-content: space-between; padding: 5px 0; border-bottom: 1px solid var(--grid); flex-wrap: wrap; }
.results { display: flex; flex-wrap: wrap; gap: 2px; }
.results a { min-width: 28px; height: 22px; padding: 0 4px; display: grid; place-items: center; font: 700 .68rem/1 var(--font); color: #fff; }
.results a.w { background: var(--real); }
.results a.l { background: #b3261e; }
.results a.t { background: var(--void); }
.results a:hover { text-decoration: none; opacity: .85; }
.rule { display: grid; gap: 4px; padding: 10px 0; border-bottom: 1px solid var(--grid); }
.rule .rh { display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; align-items: center; }
.rule .nums { display: flex; gap: 16px; flex-wrap: wrap; font-size: .8rem; color: var(--text-2); }
.rule .nums b { color: var(--text); font-variant-numeric: tabular-nums; }
.src { font-size: .76rem; color: var(--muted); }
.site-footer { border-top: 1px solid var(--border); background: var(--surface-2); padding: 14px 0; font-size: .78rem; color: var(--muted); }
.site-footer .wrap { display: flex; gap: 16px; justify-content: space-between; flex-wrap: wrap; }
/* The sister sites and the author's site: a name and a caption each, above the credits. */
.site-footer .site-family { justify-content: flex-start; align-items: stretch; gap: 10px 12px; padding-bottom: 12px; margin-bottom: 12px; border-bottom: 1px solid var(--border); }
.site-family .family-head { flex-basis: 100%; font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-2); }
.site-footer .site-family a { display: grid; align-content: start; gap: 2px; flex: 1 1 140px; padding: 8px 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface, transparent); text-decoration: none; color: var(--text); }
.site-family a b { font-size: .86rem; }
.site-family a small { font-size: .74rem; color: var(--muted); }
/* Each site's colour, the same on every site: football red, baseball green, basketball orange,
   hockey blue, Kingside Lab (chess) a chessboard charcoal (its own orange is too near basketball's),
   Mason Obegi purple. Darker shades on light, lighter on dark, for readable names. */
.site-family a { --fam: var(--text-2); }
.site-footer .site-family a { border-left: 4px solid var(--fam); }
.site-family a b { color: var(--fam); }
.site-footer .site-family a:hover, .site-footer .site-family a:focus-visible { border-color: var(--fam); }
.site-family .fam-football { --fam: #c8102e; }
.site-family .fam-baseball { --fam: #15803d; }
.site-family .fam-basketball { --fam: #c2410c; }
.site-family .fam-hockey { --fam: #1d4ed8; }
.site-family .fam-chess { --fam: #3f3f46; }
.site-family .fam-mason { --fam: #6d28d9; }
:root[data-theme="dark"] .site-family .fam-football { --fam: #f87171; }
:root[data-theme="dark"] .site-family .fam-baseball { --fam: #4ade80; }
:root[data-theme="dark"] .site-family .fam-basketball { --fam: #fb923c; }
:root[data-theme="dark"] .site-family .fam-hockey { --fam: #93c5fd; }
:root[data-theme="dark"] .site-family .fam-chess { --fam: #d4d4d8; }
:root[data-theme="dark"] .site-family .fam-mason { --fam: #c4b5fd; }

@media (prefers-reduced-motion: reduce) { * { transition-duration: 0s !important; animation-duration: 0s !important; } }
/* Phones: the wrapped header is too tall to pin, so it scrolls away with the page. */
@media (max-width: 600px) { .site-header { position: static; } }
/* Phones: logo and Menu on the first row, search and the two buttons on the second; the page
   links open under Menu. The tip bar stays off (the footer has the tip link and feedback), so the
   first screen is the page, not the site's furniture. */
.menu-btn { display: none; }
@media (max-width: 600px) {
  .site-header .wrap { padding-bottom: 8px; }
  .menu-btn { display: inline-flex; }
  .site-header:not(.menu-open) .nav { display: none; }
  .header-tools { flex-basis: 100%; margin-left: 0; order: 2; }
  .header-tools .search { flex: 1; min-width: 0; }
  .site-header .search input { width: 100%; }
  #theme-label { display: none; }
}
@media (max-width: 480px) { .nav a { padding: 0 7px; font-size: .74rem; line-height: 30px; } }
@media print { .site-header, .site-footer, .dock { display: none; } }
#theme-toggle[data-mode="dark"] .moon, #theme-toggle[data-mode="light"] .sun { display: none; }
body.no-select, body.no-select * { user-select: none !important; }

/* ============================================================
   Frames: panels, tables and widgets get a dark outline so each box
   reads as its own unit (light: near-black; dark: light gray).
   ============================================================ */
:root { --frame: #1f1f1f; --cat-chart: #1f5fbf; --cat-model: #6a3ca8; --cat-table: #0f7a34; --cat-note: #5f5f5f; }
:root[data-theme="dark"] { --frame: #8f8f8f; --cat-chart: #6ea2f0; --cat-model: #b996ec; --cat-table: #5fcf88; --cat-note: #b0b0b0; }
.box, .tbl-wrap, .kpis, .scoreboard, .widget, .board-scroll, .inspector { border-color: var(--frame); }
.tool-links, .tool-links a { border-color: var(--frame); }
.cards { border-color: var(--frame); }
.vcard { border-color: var(--frame); }
.grid.two > .box, .grid.side > .box { border-width: 1px; }

/* brand mark: a small grid, drawn in CSS */
.brand .mark { width: 16px; height: 16px; border: 0; transform: none; background:
  linear-gradient(var(--brand), var(--brand)) 0 0 / 100% 3px no-repeat,
  linear-gradient(var(--brand), var(--brand)) 0 50% / 100% 2px no-repeat,
  linear-gradient(var(--brand), var(--brand)) 0 100% / 100% 3px no-repeat,
  linear-gradient(var(--brand), var(--brand)) 0 0 / 3px 100% no-repeat,
  linear-gradient(var(--brand), var(--brand)) 50% 0 / 2px 100% no-repeat,
  linear-gradient(var(--brand), var(--brand)) 100% 0 / 3px 100% no-repeat; }

/* ---------- dashboard: zoom and width ---------- */
.board-zoom { position: relative; }
.board { transform-origin: 0 0; position: absolute; left: 0; top: 0; }
.board.fixed-width { box-shadow: inset calc(-1 * 2px) 0 0 var(--frame); }
.inline-field { display: inline-flex; align-items: center; gap: 6px; font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.dash-top .seg button { min-width: 30px; font-size: .85rem; }

/* ---------- dashboard dock, colour-coded by category ---------- */
.cat-chart { --cat: var(--cat-chart); } .cat-model { --cat: var(--cat-model); } .cat-table { --cat: var(--cat-table); } .cat-note { --cat: var(--cat-note); }
.form-title { display: flex; flex-direction: column; gap: 1px; padding: 6px 16px 0; }
.form-title b { font: 700 .95rem/1.2 var(--display); color: var(--cat); text-transform: uppercase; letter-spacing: .03em; }
.form-title span { font-size: .76rem; color: var(--text-2); }
.pick-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 1px 10px; max-height: 120px; overflow: auto; }
.pick-list label { display: flex; gap: 5px; align-items: center; font-size: .78rem; }

/* Wide tables: keep rank and name in view while scrolling sideways, like a reference site. */
table.stats td { background: var(--surface); }
table.stats tbody tr:nth-child(even) td { background: var(--row-alt); }
table.stats tbody tr:hover td { background: var(--row-hover); }
table.stats tr > :first-child { position: sticky; left: 0; z-index: 1; }
table.stats tr > :nth-child(2) { position: sticky; left: var(--rk-w, 34px); z-index: 1; box-shadow: inset -1px 0 0 var(--border); }
table.stats thead th:first-child, table.stats thead th:nth-child(2) { z-index: 3; }
table.stats tfoot td:first-child, table.stats tfoot td:nth-child(2) { z-index: 2; }
.model-card { display: flex; flex-direction: column; }
.model-body { height: 400px; display: flex; flex-direction: column; min-height: 0; }
.model-body > .chart { flex: 1; min-height: 0; }
.model-body > div:has(> .tbl-wrap) { flex: 1; min-height: 0; overflow: auto; }

/* ---------- dashboard focus bar ---------- */
.focus-bar { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; padding: 6px 10px; margin-bottom: 8px; border: 1px solid var(--frame); border-left: 6px solid var(--tc); background: var(--surface); }
.focus-bar > b { font: 700 .8rem/1 var(--display); text-transform: uppercase; letter-spacing: .06em; margin-right: 4px; }
.focus-bar select { max-width: 220px; }
.focus-note { font-size: .78rem; color: var(--text-2); flex: 1 1 260px; }

/* ---------- chart window ---------- */
.chart-window { position: fixed; inset: 0; z-index: 85; background: rgba(0, 0, 0, .55); display: grid; place-items: center; padding: 16px; }
.win-panel { background: var(--surface); border: 2px solid var(--frame); width: min(1500px, 100%); height: min(920px, 100%); display: flex; flex-direction: column; }
.win-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--frame); }
.win-head h2 { margin: 0 0 2px; font-size: 1.15rem; }
.win-head p { margin: 0; max-width: 90ch; }
.win-body { flex: 1; min-height: 0; display: grid; grid-template-columns: 340px minmax(0, 1fr); }
.win-side { border-right: 1px solid var(--frame); overflow: auto; padding: 10px 12px; }
.win-side h3 { font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; margin: 4px 0 6px; }
.win-side .form { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.win-side .form > fieldset, .win-side .form > .hint, .win-side .form > .pick-list, .win-side .form > div:last-child { grid-column: 1 / -1; }
.win-side .form select, .win-side .form input[type="text"] { width: 100%; }
.win-side .row { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 8px; }
.win-side .row.one { grid-template-columns: 1fr; }
.win-side .colors { display: grid; gap: 4px; margin-bottom: 8px; }
.win-side .colors label { display: flex; gap: 8px; align-items: center; font-size: .8rem; }
.win-side hr { border: 0; border-top: 1px solid var(--border); margin: 8px 0; }
.win-style { margin-top: 10px; border-top: 2px solid var(--frame); padding-top: 6px; }
.win-chart { padding: 10px 14px; display: flex; flex-direction: column; min-height: 0; }
.win-chart > .chart { flex: 1; min-height: 0; }
.win-chart > div:has(> .tbl-wrap) { flex: 1; min-height: 0; overflow: auto; }
@media (max-width: 900px) { .win-body { grid-template-columns: 1fr; grid-template-rows: auto 1fr; } .win-side { max-height: 40vh; border-right: 0; border-bottom: 1px solid var(--frame); } }
.widget .wbody { cursor: zoom-in; }
.widget.text .wbody, .widget .wbody:has(.tbl-wrap), .widget .wbody:has(.story) { cursor: auto; }

/* ---------- dashboard front door ---------- */
.quick-start { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.quick-start > b { font: 700 .8rem/1 var(--display); text-transform: uppercase; letter-spacing: .06em; }

/* phones: stacked board, no drag or resize handles */
.board.stacked .wbar { cursor: default; }
.board.stacked .h-e, .board.stacked .h-s, .board.stacked .h-se { display: none; }
@media (max-width: 700px) { .dash-top .seg, .dash-top .inline-field, .dash-top [title^="Zoom so"] { display: none; } .focus-note { display: none; } }
/* model cards on narrow screens: let the view buttons wrap under the title */
.model-card .section-head > span { flex-wrap: wrap; }
.model-card .seg { flex-wrap: wrap; height: auto; }
.model-card .seg button { height: 28px; }

/* Picking a widget type: the set-up panel slides in and flashes in its category colour. */
@keyframes form-in { from { opacity: 0; transform: translateX(18px); } to { opacity: 1; transform: none; } }
@keyframes form-flash {
  0%, 20% { box-shadow: inset 0 0 0 3px var(--cat); background: color-mix(in srgb, var(--cat) 16%, var(--surface)); }
  100% { box-shadow: inset 0 0 0 0 transparent; background: transparent; }
}
@keyframes title-flash { 0%, 30% { transform: scale(1.06); } 100% { transform: none; } }
.dock-form.flash { animation: form-in .3s ease-out, form-flash 1.4s ease-out; }
.dock-form.flash .form-title b { display: inline-block; transform-origin: left center; animation: title-flash .6s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .dock-form.flash { animation: form-flash 1.4s linear; }
  .dock-form.flash .form-title b { animation: none; }
}

/* Add panel, step 1: a scrollable menu of groups that open and close. */
.dock-menu { overflow: auto; flex: 1; scrollbar-width: thin; }
.step-head { display: flex; align-items: center; gap: 8px; font: 700 .74rem/1 var(--font); text-transform: uppercase; letter-spacing: .06em; color: var(--text-2); padding: 8px 12px 6px; }
.step { display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--text); color: var(--bg); font: 700 .72rem/1 var(--font); flex: none; }
.dock-group { border-top: 1px solid var(--border); border-left: 4px solid var(--cat); }
.dock-group > summary { display: grid; grid-template-columns: 1fr auto; grid-template-areas: "l c" "d c"; align-items: center; column-gap: 10px; padding: 7px 12px 7px 10px; cursor: pointer; list-style: none; }
.dock-group > summary::-webkit-details-marker { display: none; }
.dock-group > summary::after { content: ""; grid-area: c; justify-self: end; width: 7px; height: 7px; border-right: 2px solid var(--text-2); border-bottom: 2px solid var(--text-2); transform: rotate(-45deg); margin-right: 2px; transition: transform .15s; }
.dock-group[open] > summary::after { transform: rotate(45deg); }
.dock-group > summary:hover { background: var(--surface-2); }
.g-label { grid-area: l; font: 700 .82rem/1.2 var(--display); text-transform: uppercase; letter-spacing: .04em; color: var(--cat); }
.g-desc { grid-area: d; font-size: .72rem; color: var(--muted); }
.g-count { grid-area: c; justify-self: end; margin-right: 22px; font: 700 .68rem/1 var(--font); color: var(--text-2); border: 1px solid var(--border-strong); padding: 2px 6px; }
.dock-group .cat-types { display: flex; flex-direction: column; flex-wrap: nowrap; gap: 0; padding: 0 0 6px; }
.dock-group .cat-types button { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; text-align: left; border: 0; border-left: 3px solid transparent; background: none; padding: 5px 12px 5px 14px; color: var(--text); }
.dock-group .cat-types button b { font: 600 .8rem/1.25 var(--font); }
.dock-group .cat-types button span { font-size: .72rem; line-height: 1.3; color: var(--text-2); display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
.dock-group .cat-types button:hover { background: var(--surface-2); color: var(--text); border-left-color: var(--cat); }
.dock-group .cat-types button[aria-pressed="true"] { background: color-mix(in srgb, var(--cat) 12%, var(--surface)); border-left-color: var(--cat); color: var(--text); }
.dock-group .cat-types button[aria-pressed="true"] b { color: var(--cat); }
:root[data-theme="dark"] .dock-group .cat-types button[aria-pressed="true"] { color: var(--text); }
/* Steps 2 and 3: the fields scroll, the add button stays in view. */
.form-title .step-head { padding: 2px 0 4px; }
.add-bar { display: flex; gap: 8px; align-items: center; padding: 8px 16px; border-top: 1px solid var(--border); background: var(--surface); }
.form-title .step-head .step { color: var(--bg); font-size: .72rem; }

/* Wide tooltips: the similar-seasons comparison and other rich hovers. */
.tooltip.wide { max-width: min(460px, calc(100vw - 16px)); padding: 8px 10px; }
.tooltip .tt-why { margin: 2px 0 6px; color: var(--text-2); }
.tooltip table.tt-cmp { border-collapse: collapse; width: 100%; font-size: .74rem; font-variant-numeric: tabular-nums; }
.tooltip table.tt-cmp th, .tooltip table.tt-cmp td { padding: 1px 6px 1px 0; text-align: right; white-space: nowrap; }
.tooltip table.tt-cmp th:first-child, .tooltip table.tt-cmp td:first-child { text-align: left; color: var(--text-2); white-space: normal; }
.tooltip table.tt-cmp thead th { color: var(--text); font-weight: 700; border-bottom: 1px solid var(--border); }
.tooltip table.tt-cmp tr.tt-sep td { border-top: 1px solid var(--border); padding-top: 3px; }
.tooltip table.tt-cmp td.tt-rk { color: var(--muted); font-size: .68rem; padding-right: 8px; }
.tooltip .tt-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 5px; vertical-align: 0; }
.tooltip .tt-dot.m0 { background: var(--right); }
.tooltip .tt-dot.m1 { background: #8fbf5a; }
.tooltip .tt-dot.m2 { background: #d4a72c; }
.tooltip .tt-dot.m3 { background: var(--wrong); }
.tooltip .tt-next { margin-top: 6px; color: var(--text-2); }

/* Storylines: a written summary of one team, one line per topic. */
.story { list-style: none; margin: 0; padding: 4px 2px; overflow: auto; flex: 1; min-height: 0; font-size: .9rem; line-height: 1.45; }
.story li { padding: 5px 0 5px 12px; border-bottom: 1px solid var(--grid); position: relative; }
.story li:last-child { border-bottom: 0; }
.story li::before { content: ''; position: absolute; left: 0; top: 11px; width: 6px; height: 6px; border-radius: 50%; background: var(--border-strong); }
.story li.tone-good::before { background: var(--right); }
.story li.tone-bad::before { background: var(--wrong); }
.story li b { font-family: var(--display); text-transform: uppercase; letter-spacing: .02em; font-size: .78rem; color: var(--text-2); margin-right: 4px; }

/* ---------- dashboard: add drawer ----------
   Wide screens: a column beside the board, sticky while the page scrolls.
   Narrower: a sheet over the right of the board. Phones: full screen. */
.dash-main { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; align-items: start; }
.dock { position: fixed; top: 61px; right: 8px; bottom: 8px; width: min(400px, calc(100vw - 16px)); z-index: 60; display: flex; flex-direction: column; background: var(--surface); border: 2px solid var(--frame); min-width: 0; box-shadow: 0 10px 40px rgba(0, 0, 0, .28); }
.dock[hidden] { display: none; }
.dock .dock-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 10px 8px 14px; border-bottom: 1px solid var(--frame); }
.dock .dock-head h2 { margin: 0; font-size: 1rem; }
.dock .dock-close { font-size: 1.1rem; line-height: 1; width: 30px; padding: 0; }
.dock-search { padding: 0 12px 8px; }
.dock-search input { width: 100%; }
.dock-menu { overflow: auto; flex: 1; min-height: 0; scrollbar-width: thin; }
.dock-added { padding: 8px 12px; border-top: 1px solid var(--border); background: color-mix(in srgb, var(--right) 12%, var(--surface)); font-size: .8rem; }
.dock-form { display: flex; flex-direction: column; min-height: 0; flex: 1; overflow: auto; border-top: 4px solid var(--cat); }
.dock-form .form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 10px; align-items: end; padding: 8px 14px 12px; }
.dock-form .form > fieldset, .dock-form .form > .hint, .dock-form .form > .pick-list, .dock-form .form > div:last-child, .dock-form .form > .ac { grid-column: 1 / -1; }
.dock-form .form select, .dock-form .form input[type="text"], .dock-form .form input[type="number"] { width: 100%; }
.dock-form .form fieldset { border: 1px solid var(--border); padding: 2px 8px 8px; margin: 0; min-width: 0; }
.dock-form .form legend { font-size: .66rem; font-weight: 700; color: var(--muted); text-transform: uppercase; padding: 0 4px; letter-spacing: .05em; }
.dock-form .form .hint { font-size: .74rem; color: var(--muted); }
.dock-form .series-row { flex-wrap: wrap; }
.dock-form .series-row select { flex: 1 1 120px; min-width: 0; }
.dock-form .pick-list { grid-template-columns: repeat(2, minmax(0, 1fr)); max-height: 200px; }
.dock-back { align-self: flex-start; border: 0; background: none; color: var(--link); font: 600 .8rem/1 var(--font); padding: 8px 14px 2px; cursor: pointer; }
.dock-back:hover { text-decoration: underline; }
.form-title { display: flex; flex-direction: column; gap: 1px; padding: 6px 14px 0; }
.form-title b { font: 700 .95rem/1.2 var(--display); color: var(--cat); text-transform: uppercase; letter-spacing: .03em; }
.form-title span { font-size: .76rem; color: var(--text-2); }
.add-bar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding: 10px 14px; border-top: 1px solid var(--frame); background: var(--surface); }
.add-widget span { font-weight: 700; font-size: 1.05em; margin-right: 2px; }
.widget.just-added { animation: just-added 1.6s ease-out; }
@keyframes just-added { 0%, 30% { box-shadow: 0 0 0 4px var(--sel); } 100% { box-shadow: 0 0 0 0 transparent; } }
@media (prefers-reduced-motion: reduce) { .widget.just-added { animation: none; outline: 3px solid var(--sel); } }
@media (max-width: 700px) {
  .dock { inset: 0; width: auto; border: 0; z-index: 80; }
  .dock-form .form { grid-template-columns: minmax(0, 1fr); }
}
/* Toolbar: the title takes what is left, so everything fits on one line at 1366px and up. */
.dash-top .title-input { flex: 1 1 180px; width: auto; min-width: 150px; max-width: 380px; text-overflow: ellipsis; }
.dash-top .spacer { flex: 0 1 auto; }
.dock .dock-close { display: inline-grid; place-items: center; height: 30px; }
@media (max-width: 1500px) { .dash-top .inline-field .lbl { display: none; } }
@media (max-width: 700px) {
  .dash-top .desk-only, .dash-top .sep { display: none; }
  .dash-top .title-input { flex: 1 1 100%; max-width: none; order: -2; }
  .dash-top .add-widget { order: -1; }
  .board-empty { top: 16px; padding: 0 8px; }
  .board-empty > div { max-width: 100%; padding: 12px; }
  .board-empty .quick-start { justify-content: center; }
  .board-empty .presets .btn { white-space: normal; height: auto; min-height: 32px; text-align: center; }
}
.board.stacked .w-dup { display: none; }
/* A wide Storylines widget reads in two columns instead of scrolling. */
.story { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 420px), 1fr)); column-gap: 24px; align-content: start; }
/* Touch: rich tooltips open as a bottom sheet. */
.tip-sheet { position: fixed; inset: 0; z-index: 95; background: rgba(0, 0, 0, .45); display: flex; align-items: flex-end; justify-content: center; }
.tip-sheet-panel { background: var(--surface); color: var(--text); width: min(560px, 100%); max-height: 82vh; display: flex; flex-direction: column; border-top: 3px solid var(--frame); font-size: .82rem; line-height: 1.4; }
.tip-sheet-bar { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 8px 10px; border-bottom: 1px solid var(--border); }
.tip-sheet-body { overflow: auto; padding: 10px 12px 16px; }
.tip-sheet.wide .tip-sheet-panel { width: min(920px, 100%); }
@media (min-width: 700px) { .tip-sheet.wide { align-items: center; } .tip-sheet.wide .tip-sheet-panel { border: 1px solid var(--border); border-top: 3px solid var(--frame); } }
/* A drive's plays: one row per snap; the description wraps, numbers line up. */
.play-table { border-collapse: collapse; width: 100%; font-size: .8rem; font-variant-numeric: tabular-nums; }
.play-table th { text-align: left; font-weight: 700; color: var(--text-2); border-bottom: 1px solid var(--border-strong); padding: 4px 6px; position: sticky; top: 0; background: var(--surface); }
.play-table td { padding: 5px 6px; border-bottom: 1px solid var(--border); vertical-align: top; white-space: nowrap; }
.play-table td.desc { white-space: normal; min-width: 220px; }
.play-table td.num, .play-table th:nth-last-child(-n+2) { text-align: right; }
.play-table td.pos { color: var(--right); font-weight: 600; } .play-table td.neg { color: var(--wrong); font-weight: 600; }
.play-table tr.np td { color: var(--muted); }
.play-table tbody tr:nth-child(even) td { background: var(--row-alt); }
.tip-sheet .tt-h { font-weight: 700; margin-bottom: 2px; }
.tip-sheet .tt-why { margin: 2px 0 8px; color: var(--text-2); }
.tip-sheet .tt-note { color: var(--muted); margin-top: 6px; font-size: .74rem; }
.tip-sheet .tt-next { margin-top: 6px; color: var(--text-2); }
.tip-sheet table.tt-cmp { border-collapse: collapse; width: 100%; font-size: .78rem; font-variant-numeric: tabular-nums; }
.tip-sheet table.tt-cmp th, .tip-sheet table.tt-cmp td { padding: 2px 4px 2px 0; text-align: right; }
.tip-sheet table.tt-cmp th:first-child, .tip-sheet table.tt-cmp td:first-child { text-align: left; color: var(--text-2); }
.tip-sheet table.tt-cmp thead th { border-bottom: 1px solid var(--border); }
.tip-sheet table.tt-cmp tr.tt-sep td { border-top: 1px solid var(--border); padding-top: 4px; }
.tip-sheet table.tt-cmp td.tt-rk { color: var(--muted); font-size: .7rem; padding-right: 6px; }
.tip-sheet .tt-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 5px; }
.tip-sheet .tt-dot.m0 { background: var(--right); } .tip-sheet .tt-dot.m1 { background: #8fbf5a; } .tip-sheet .tt-dot.m2 { background: #d4a72c; } .tip-sheet .tt-dot.m3 { background: var(--wrong); }
/* Series rows in the add drawer: swatch, who, from, to, remove on one line. */
.dock-form .series-row { display: grid; grid-template-columns: 10px minmax(0, 1fr) 76px 76px 22px; gap: 4px; align-items: center; }
.dock-form .series-row select, .dock-form .series-row .ac, .dock-form .series-row .ac input { width: 100%; min-width: 0; }
.dock-form .series-row .x { justify-self: center; }
.dock-form .series-row.wk { grid-template-columns: 10px minmax(0, 1fr) 76px 22px; }
.wloading { margin: auto; color: var(--muted); font-size: .8rem; }
/* The working panel (ui.js busy): shown when something takes longer than a second. */
/* In the middle of the screen, large (the owner, 2026-10-23: "building your dashboard should be more in the middle of the
   screen; it was a little hard to see when it was at the top"). */
.busy { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 120; display: flex; align-items: center; gap: 16px;
  max-width: calc(100vw - 32px); padding: 22px 30px; background: var(--surface); color: var(--text); border: 3px solid var(--frame);
  box-shadow: 0 12px 48px rgba(0, 0, 0, .35); font-weight: 700; font-size: 1.25rem; pointer-events: none; }
.busy .busy-spin { width: 34px; height: 34px; border-width: 4px; }
.busy-spin, .spin { flex: none; width: 18px; height: 18px; border-radius: 50%; border: 3px solid var(--muted); border-top-color: var(--sel, #c8102e); animation: busy-spin .8s linear infinite; }
@keyframes busy-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .busy-spin, .spin { animation: busy-pulse 1.6s ease-in-out infinite !important; animation-duration: 1.6s !important; } }
@keyframes busy-pulse { 50% { opacity: .35; } }
.help-dialog { position: fixed; inset: 0; z-index: 96; background: rgba(0, 0, 0, .45); display: grid; place-items: center; padding: 16px; }
.help-panel { background: var(--surface); border: 2px solid var(--frame); width: min(520px, 100%); padding: 12px 16px 16px; }
.help-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.help-head h2 { margin: 0; font-size: 1.05rem; }
.help-panel dl { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; margin: 0; font-size: .86rem; }
.help-panel dt { white-space: nowrap; }
.help-panel dd { margin: 0; color: var(--text-2); }
.help-panel kbd { font: 600 .78rem/1 var(--font); border: 1px solid var(--border-strong); border-bottom-width: 2px; padding: 2px 6px; background: var(--surface-2); }
/* "View the SQL" (public/js/sqlview.js): the button under a page that read data, and its panel of queries. The SQL keeps
   its own lines and scrolls sideways inside its block, never the page. */
.sql-foot { text-align: center; padding: 28px 16px 24px; }
.sql-foot[hidden] { display: none; }
.sql-foot-note { margin: 6px 0 0; color: var(--muted); font-size: .85rem; }
.sql-panel { width: min(960px, 100%); max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); overflow-y: auto; min-width: 0; }
.sql-intro { color: var(--text-2); font-size: .9rem; max-width: 72ch; }
.sql-req { border-top: 1px solid var(--border); padding-top: 10px; margin-top: 14px; min-width: 0; }
.sql-req h3 { margin: 0 0 10px; font: 700 .82rem/1.35 ui-monospace, Consolas, "Courier New", monospace; overflow-wrap: anywhere; }
.sql-q { margin: 0 0 16px; min-width: 0; }
.sql-q-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; font-size: .82rem; font-weight: 600; color: var(--text-2); }
.sql-cached, .sql-more, .sql-gone { margin: 4px 0; color: var(--muted); font-size: .82rem; }
.sql-code { margin: 6px 0 4px; padding: 10px 12px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text); overflow-x: auto; white-space: pre; tab-size: 2;
  font: .78rem/1.5 ui-monospace, Consolas, "Courier New", monospace; }
.sql-code code { font: inherit; }
.sql-params { list-style: none; margin: 4px 0 0; padding: 0; font-size: .78rem; color: var(--text-2); }
.sql-params code { font-family: ui-monospace, Consolas, "Courier New", monospace; overflow-wrap: anywhere; }
.sql-dialog .loading { padding: 4px 0; }
/* Phones: the chart window fills the screen, chart first, settings below it. */
@media (max-width: 700px) {
  .chart-window { padding: 0; }
  .win-panel { width: 100%; height: 100%; border: 0; }
  .win-hint { display: none; }
  .win-head { padding: 8px 10px; }
  .win-head h2 { font-size: .95rem; }
  .win-head p { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  /* One scroll for the whole window: the chart, then every setting at full height below it. A small
     inner scroll box under a tall chart was too cramped to scroll with a thumb. */
  .win-body { display: flex; flex-direction: column; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
  .win-chart { order: -1; flex: 0 0 auto; height: 58vh; min-height: 280px; padding: 6px 8px; border-bottom: 1px solid var(--frame); }
  .win-side { flex: 0 0 auto; max-height: none; overflow: visible; border-bottom: 0; padding-bottom: 96px; }
  .win-head { flex-wrap: wrap; }
  .win-head h2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .win-head .btn { padding: 6px 10px; font-size: .8rem; }
  .inspector { left: 8px !important; right: 8px; width: auto; max-height: 70vh; }
}

/* After adding a widget: a short note with a way straight back to the add panel. */
.dash-toast { position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 70; display: flex; gap: 10px; align-items: center; background: var(--text); color: var(--bg); padding: 8px 10px 8px 14px; font-size: .85rem; box-shadow: 0 6px 24px rgba(0, 0, 0, .3); max-width: calc(100vw - 24px); }
.dash-toast .btn { background: var(--bg); color: var(--text); border-color: var(--bg); }
.dock-form .form > .full, .win-side .form > .full { grid-column: 1 / -1; }
.dock-form .form > .full .field select, .win-side .form > .full .field select { width: 100%; }
.full .ac, .full .ac input { width: 100%; }

/* Ask: describe a dashboard in words. */
.ask-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding: 6px 10px; margin-bottom: 8px; border: 1px solid var(--frame); background: var(--surface); }
.ask-bar > label { display: inline-flex; align-items: center; gap: 6px; font: 700 .8rem/1 var(--display); text-transform: uppercase; letter-spacing: .06em; }
.ask-mark { color: var(--brand); font-size: 1rem; }
.ask-input { flex: 1 1 360px; min-width: 0; height: 32px; font-size: .9rem; }
.ask-msg { flex: 1 1 100%; font-size: .8rem; color: var(--text-2); }
.ask-ideas { flex: 1 1 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 2px; }
.ask-ideas:empty { display: none; }
.ask-ideas .chip { margin: 2px; }
.ask-msg:empty { display: none; }
.ask-msg.ok { color: var(--text); }
.ask-msg.err { color: var(--wrong); }
.ask-msg .ask-note { color: var(--noise); }
.ask-msg .ask-answer { display: block; margin: 4px 0; }
/* League words in the main Ask with no league linked: one tap to link it (lib/fantasy/mainask.js). */
.ask-msg.league { color: var(--text); }
.ask-league { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 4px 0 2px; padding: 8px 10px; border: 1px solid var(--border-strong); background: var(--surface-2); }
.ask-league p { flex: 1 1 260px; margin: 0; font-size: .85rem; line-height: 1.4; }
.ask-league .btn { height: 36px; }
@media (max-width: 700px) { .ask-league .btn { flex: 1 1 100%; justify-content: center; height: 40px; } }
.ask-wrong input { font: inherit; font-size: .85rem; padding: 2px 6px; width: min(280px, 60vw); }
.linkish { border: 0; background: none; padding: 0; color: var(--link); font: inherit; cursor: pointer; text-decoration: underline; }
.chip { border: 1px solid var(--border-strong); background: var(--surface-2); color: var(--text); font: 500 .74rem/1.2 var(--font); padding: 3px 8px; margin: 2px 3px; cursor: pointer; border-radius: 12px; }
.chip:hover { border-color: var(--text); }
@media (max-width: 700px) { .ask-input { flex-basis: 100%; } }
.btn[hidden] { display: none; }
.btn.mic { width: 32px; height: 32px; padding: 0; justify-content: center; }
.btn.mic.on { border-color: var(--wrong); color: var(--wrong); animation: mic-pulse 1.2s ease-in-out infinite; }
@keyframes mic-pulse { 50% { opacity: .55; } }
@media (prefers-reduced-motion: reduce) { .btn.mic.on { animation: none; } }
.home-ask { margin: 0 0 10px; border-color: var(--border-strong); }

/* Ads, tip jar and Pro. Ad slots take no room until something fills them. */
.ad-slot[hidden] { display: none; }
.ad-slot { margin: 12px 0; padding: 6px 8px; border: 1px solid var(--border); background: var(--surface); text-align: center; min-height: 60px; overflow: hidden; }
.ad-slot .ad-label { display: block; font-size: .62rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin-bottom: 4px; text-align: left; }
.ad-slot.placeholder { border: 2px dashed var(--border-strong); color: var(--muted); display: grid; place-items: center; min-height: 90px; font-size: .8rem; }
.ad-wrap:empty, .ad-wrap:has(> .ad-slot[hidden]) { display: none; }
.pro-box { max-width: 640px; }
.pass-code { font-size: .95rem; padding: 4px 8px; background: var(--surface-2); border: 1px solid var(--border-strong); user-select: all; }
.ok-note { color: var(--right); font-weight: 500; }
/* The dashboard maker has its own slot under the board; the page-wide top slot would push the board down. */
#ad-top:has(+ main.flush) { display: none; }
/* Ask conversation: a short log under the box. */
.ask-thread { flex: 1 1 100%; order: 3; display: flex; flex-direction: column; gap: 2px; max-height: 150px; overflow: auto; font-size: .8rem; }
.ask-thread:empty { display: none; }
.ask-turn { display: flex; flex-wrap: wrap; gap: 0 8px; padding: 2px 0; border-bottom: 1px solid var(--grid); }
.ask-turn .you { color: var(--text); }
.ask-turn .did { color: var(--text-2); }
.ask-thread > .linkish { align-self: flex-end; font-size: .76rem; position: sticky; top: 0; background: var(--surface); padding: 0 2px; }
.ask-msg { order: 4; }
/* The board's filters as chips (each x takes off that one filter) and the Kept / Changed / Dropped line after every
   request (public/js/facets.js, FR-01). The x is drawn 24 px and answers a 44 px tap (DESIGN_SYSTEM INT-02, INT-12). */
.ask-filters { flex: 1 1 100%; order: 5; display: flex; flex-direction: column; gap: 4px; font-size: .8rem; }
.ask-filters:empty { display: none; }
.ask-kept { margin: 0; color: var(--text-2); line-height: 1.45; }
.ask-kept b { color: var(--text); font-weight: 700; }
.filter-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.filter-chips > .muted { margin-right: 2px; }
.filter-chip { display: inline-flex; align-items: center; gap: 2px; margin: 0; padding: 1px 2px 1px 10px; cursor: default; border-color: var(--text-2); background: var(--surface); border-radius: 999px; }
.filter-chip:hover { border-color: var(--text-2); }
.chip-x { position: relative; z-index: 1; display: inline-grid; place-items: center; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 999px; background: none; color: var(--text-2); font: 700 1rem/1 var(--font); cursor: pointer; transition: background-color 120ms, color 120ms; }
.chip-x::before { content: ''; position: absolute; inset: -10px; }
.chip-x:hover, .chip-x:focus-visible { background: var(--surface-3); color: var(--text); }
.chip-x:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.filter-chip.ro { padding: 2px 10px; }
/* A shared board seen signed out: its filters under the sign-in bar, without the x (FR-01). */
.locked-filters { margin: 0 0 8px; padding: 6px 10px; border: 1px solid var(--frame); background: var(--surface); }
.locked-filters .ask-filters:empty, .locked-filters:has(.ask-filters:empty) { display: none; }
/* Privacy and terms */
.legal > * { max-width: 820px; }   /* the column sits on the page grid, left, as every other page (and the sister sites) */
.legal-sec h2 { font-size: 1.05rem; margin: 22px 0 6px; }
.legal-sec p, .legal-sec li { line-height: 1.55; color: var(--text-2); }
.legal li a { text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
.legal-now { margin: 12px 0 4px; padding: 10px 14px; background: var(--surface-2); }
.legal-now h2, .legal-now h3 { margin: 0 0 4px; font-size: .9rem; text-transform: uppercase; letter-spacing: .04em; }
.legal-now ul { margin: 0; padding-left: 18px; font-size: .88rem; }

/* ============================================================
   Home: the dashboard maker's advertisement, with a looping demo.
   Motion eases out on an expo curve and staggers by --i.
   ============================================================ */
.home { --ease: cubic-bezier(.16, 1, .3, 1); --la: var(--s1); --lb: var(--s2); }
.hero-ad { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 28px; align-items: center; padding: 30px 0 22px; }
@media (max-width: 1020px) { .hero-ad { grid-template-columns: minmax(0, 1fr); gap: 18px; padding-top: 20px; } }
.eyebrow { margin: 0 0 8px; font: 700 .78rem/1 var(--display); text-transform: uppercase; letter-spacing: .12em; color: var(--brand-ink); }
.hero-title { font-size: clamp(2.1rem, 4.4vw, 3.4rem); line-height: 1.02; margin: 0 0 14px; text-transform: uppercase; letter-spacing: -.01em; }
.hero-title .line { display: block; overflow: hidden; padding-bottom: .04em; }
.hero-title .line > span { display: inline-block; animation: line-up .9s var(--ease) both; }
.hero-title .line + .line > span { animation-delay: .09s; }
.hero-title .accent { color: var(--brand); }
@keyframes line-up { from { transform: translateY(105%); } }
.lede { font-size: 1.05rem; color: var(--text-2); margin: 0 0 16px; max-width: 46ch; }
.home-ask { margin: 0 0 10px; border: 2px solid var(--frame); padding: 8px 10px; }
.home-ask .ask-input { font-size: 1rem; }
.try { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: .8rem; }
.try-chip { border: 1px solid var(--border-strong); background: var(--surface); color: var(--text); padding: 4px 9px; font: 500 .8rem/1.2 var(--font); cursor: pointer; transition: border-color .15s, background .15s; }
.try-chip:hover { border-color: var(--brand); background: var(--row-hover); }
.hero-note { margin: 12px 0 0; font-size: .82rem; color: var(--muted); }
.hero-also { margin: 6px 0 0; font-size: .82rem; }

/* The demo window. Decorative (aria-hidden); a hidden paragraph describes it. */
.demo-wrap { position: relative; min-width: 0; padding-bottom: 26px; }
.demo-wrap.demo-none { display: none; }
.demo { position: relative; border: 2px solid var(--frame); background: var(--surface); box-shadow: 8px 8px 0 var(--surface-3); overflow: hidden; transition: opacity .5s; }
.demo.fade { opacity: 0; }
.demo-chrome { display: flex; align-items: center; gap: 6px; height: 32px; padding: 0 10px; background: var(--header-bg); color: var(--header-muted); font-size: .72rem; }
.demo-chrome i { width: 9px; height: 9px; border-radius: 50%; background: #555; }
.demo-url { margin-left: 8px; padding: 2px 10px; background: #2a2a2a; color: #cfcfcf; flex: 1 1 auto; min-width: 0; max-width: 260px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.demo-share { margin-left: auto; padding: 3px 10px; border: 1px solid #555; color: #eee; font-weight: 600; transition: transform .15s, background .15s; }
.demo-share.pressed { transform: scale(.94); background: var(--brand); border-color: var(--brand); }
.demo-ask { display: flex; align-items: center; gap: 8px; margin: 10px 10px 0; padding: 6px 8px; border: 1px solid var(--frame); font-size: .85rem; }
.demo-mark { font: 700 .72rem/1 var(--display); text-transform: uppercase; letter-spacing: .06em; color: var(--brand-ink); white-space: nowrap; }
.demo-field { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; display: flex; align-items: center; }
.demo-caret { display: inline-block; flex: none; width: 2px; height: 1.1em; margin-left: 1px; background: var(--text); animation: caret 1s steps(1) infinite; }
@keyframes caret { 50% { opacity: 0; } }
.demo-btn { padding: 4px 10px; background: var(--ink-btn); color: var(--ink-btn-text); font-weight: 600; font-size: .75rem; white-space: nowrap; transition: transform .15s; }
.demo-btn.pressed { transform: scale(.92); }
.demo-status { height: 26px; margin: 0 10px; padding: 6px 0 0; font-size: .75rem; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: 0; transition: opacity .25s; }
.demo-status.on { opacity: 1; }
.demo-dots { display: inline-flex; gap: 4px; }
.demo-dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--muted); animation: dot-bob 1.1s ease-in-out infinite; }
.demo-dots i:nth-child(2) { animation-delay: .15s; }
.demo-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes dot-bob { 0%, 60%, 100% { transform: translateY(0); opacity: .45; } 30% { transform: translateY(-4px); opacity: 1; } }
.demo.held, .demo.held * { animation-play-state: paused !important; }

.demo-board { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-template-rows: 74px minmax(0, 1fr) 118px; gap: 8px; height: 370px; margin: 4px 10px 10px;
  transition: grid-template-rows .7s var(--ease), row-gap .7s var(--ease); }
.demo-w { min-width: 0; min-height: 0; overflow: hidden; border: 1px solid var(--frame); background: var(--surface); padding: 6px 8px; opacity: 0; transform: translateY(12px) scale(.97);
  transition: opacity .35s, transform .7s var(--ease); transition-delay: calc(var(--i, 0) * 80ms); }
.demo-board.on .demo-w { opacity: 1; transform: none; }
/* While the demo types, the board area shows the dashboard maker's dotted canvas rather than
   a blank white box that reads as a page still loading. */
.demo-board { background-image: radial-gradient(var(--border-strong) 1px, transparent 1.2px); background-size: 18px 18px; background-position: -4px -4px; }
.demo-w .k { display: block; font: 700 .62rem/1.2 var(--display); text-transform: uppercase; letter-spacing: .05em; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.demo-tile .vals { display: flex; align-items: baseline; gap: 8px; margin: 3px 0 1px; }
.demo-tile .v, .demo-tile .v2 { font: 700 1.35rem/1 var(--display); font-variant-numeric: tabular-nums; white-space: nowrap; }
.demo-tile .v2 { display: none; color: var(--lb); }
.demo-tile .sub { display: block; font-size: .64rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmp .demo-tile .v { color: var(--la); }
.cmp .demo-tile .v2 { display: inline; animation: pop-in .5s var(--ease); }
.cmp .demo-tile .v, .cmp .demo-tile .v2 { font-size: 1.1rem; }
@keyframes pop-in { from { opacity: 0; transform: translateY(6px); } }

.demo-barsw { grid-column: 1 / 3; }
.demo-linew { grid-column: 3 / 5; }
.demo-tablew { grid-column: 1 / 5; }
.demo-chart { display: flex; flex-direction: column; }
.demo-chart svg { flex: 1; width: 100%; min-height: 0; margin-top: 4px; overflow: visible; }
.demo-ch-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px 8px; align-items: center; }   /* full names can push the legend to a second line */
.demo-legend { display: none; gap: 4px; align-items: center; font-size: .62rem; color: var(--muted); white-space: nowrap; }
.demo-legend i { width: 8px; height: 8px; display: inline-block; }
.demo-legend .la { background: var(--la); }
.demo-legend .lb { background: var(--lb); margin-left: 4px; }
.cmp .demo-legend { display: inline-flex; animation: pop-in .4s var(--ease); }
.demo-x { display: flex; justify-content: space-between; font-size: .58rem; color: var(--muted); }
.demo-chart .axis { stroke: var(--border-strong); stroke-width: 1; vector-effect: non-scaling-stroke; }
.demo-chart .zero { stroke: var(--border-strong); stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; }
.bar-a, .bar-b { transform-box: fill-box; transform-origin: 0 100%; transform: scaleY(0); transition: transform .9s var(--ease); transition-delay: var(--d, 0ms); }
.bar-a { fill: var(--la); }
.bar-b { fill: var(--lb); }
.grown .bar-a { transform: scaleY(1); transition-delay: calc(var(--d, 0ms) + 250ms); }
.cmp .bar-a { transform: scaleX(.543); transition-delay: 0ms; }
.cmp .bar-b { transform: scaleY(1); }
.line-a, .line-b { fill: none; stroke-width: 2.4; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; clip-path: inset(0 100% 0 0); transition: clip-path 1.2s var(--ease); }
.demo-chart .dots { stroke-width: 7; }
.line-a { stroke: var(--la); }
.line-b { stroke: var(--lb); }
.area-a { fill: var(--la); opacity: 0; transition: opacity .8s .6s; }
.grown .line-a { clip-path: inset(0 0 0 0); transition-delay: .35s; }
.grown .area-a { opacity: .12; }
.cmp .line-b { clip-path: inset(0 0 0 0); }
.cmp .area-a { opacity: 0; transition-delay: 0s; }

.demo-tablew table { width: 100%; border-collapse: collapse; font-size: .68rem; font-variant-numeric: tabular-nums; margin-top: 3px; }
.demo-tablew th, .demo-tablew td { text-align: right; padding: 2px 4px; border-bottom: 1px solid var(--grid); white-space: nowrap; }
.demo-tablew th:first-child, .demo-tablew td:first-child { text-align: left; }
.demo-tablew th { font-weight: 700; color: var(--muted); }
.demo-tablew tbody tr { opacity: 0; transform: translateX(-8px); transition: opacity .3s, transform .5s var(--ease); }
.grown .demo-tablew tbody tr { opacity: 1; transform: none; }
.grown .demo-tablew tbody tr:nth-child(2) { transition-delay: .06s; }
.grown .demo-tablew tbody tr:nth-child(3) { transition-delay: .12s; }
.grown .demo-tablew tbody tr:nth-child(4) { transition-delay: .18s; }
.grown .demo-tablew tbody tr:nth-child(5) { transition-delay: .24s; }
.demo-tablew .cmp-rows { display: none; }
.cmp .demo-tablew tbody.cmp-rows { display: table-row-group; }
.cmp .demo-tablew thead.cmp-rows { display: table-header-group; }
.cmp .demo-tablew thead:not(.cmp-rows), .cmp .demo-tablew tbody:not(.cmp-rows) { display: none; }
.cmp .demo-tablew tbody.cmp-rows tr:first-child td:first-child { color: var(--la); font-weight: 700; }
.cmp .demo-tablew tbody.cmp-rows tr:last-child td:first-child { color: var(--lb); font-weight: 700; }

/* "only leave the charts": tiles and table fade and sink first, then their rows fold away and
   the charts grow into the room. Padding and borders ease out with the rows; snapped to zero
   at once they made the whole board jump. */
.demo-board.only-charts { grid-template-rows: 0 minmax(0, 1fr) 0; row-gap: 0;
  transition: grid-template-rows .8s var(--ease) .22s, row-gap .8s var(--ease) .22s; }
.demo-board.only-charts .demo-tile, .demo-board.only-charts .demo-tablew { opacity: 0; transform: scale(.96); padding-block: 0; border-width: 0; border-color: transparent;
  transition: opacity .28s, transform .4s var(--ease), padding .8s var(--ease) .22s, border-width .8s var(--ease) .22s, border-color .28s; }
.demo-board.only-charts .demo-tile { transform-origin: 50% 0; }
.demo-board.only-charts .demo-tablew { transform-origin: 50% 100%; }

.demo-toast { position: absolute; right: 14px; bottom: 14px; padding: 8px 12px; background: var(--header-bg); color: #eee; font-size: .78rem; border-left: 4px solid var(--brand);
  opacity: 0; transform: translateY(24px); transition: transform .5s var(--ease), opacity .3s; }
.demo-toast.on { transform: none; opacity: 1; }
.demo-toast .muted { color: #bdbdbd; }
.demo-cursor { position: absolute; left: 0; top: 0; width: 18px; height: 18px; opacity: 0; transform: translate(60%, 70%); transition: transform .7s var(--ease), opacity .2s; pointer-events: none; z-index: 2; }
.demo-cursor.on { opacity: 1; }
.demo-cursor svg { width: 18px; height: 18px; fill: #111; stroke: #fff; stroke-width: 1.2; }
.demo-pause { position: absolute; right: 0; bottom: 0; border: 0; background: none; color: var(--muted); font-size: .75rem; cursor: pointer; text-decoration: underline; padding: 4px 0; }
.demo-pause:hover { color: var(--text); }
.demo-foot { position: absolute; left: 0; right: 0; bottom: 0; display: flex; justify-content: space-between; align-items: center; }
.demo-foot .demo-pause { position: static; }
.demo-open { font-size: .8rem; font-weight: 700; color: var(--link); }
.demo-link { cursor: pointer; }
.demo-link:hover { box-shadow: 8px 8px 0 var(--accent, var(--surface-3)); }

@media (max-width: 640px) {
  .demo-board { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: 64px 64px minmax(0, 1fr) minmax(0, 1fr); height: 440px; }
  .demo-barsw, .demo-linew { grid-column: 1 / 3; }
  .demo-tablew { display: none; }
  .demo-board.only-charts { grid-template-rows: 0 0 minmax(0, 1fr) minmax(0, 1fr); }
  .demo { box-shadow: 5px 5px 0 var(--surface-3); }
}

/* Sections below the fold. */
.home-sec { margin-top: 44px; }
.home-h { font-size: 1.5rem; text-transform: uppercase; letter-spacing: .01em; margin: 0 0 12px; }
.home-h-row { display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: baseline; margin-bottom: 12px; }
.home-h-row .home-h { margin: 0; }
.reveal { opacity: 0; transform: translateY(18px); transition: opacity .6s, transform .9s var(--ease); transition-delay: calc(var(--i, 0) * 70ms); }
.reveal.in { opacity: 1; transform: none; }
.steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-top: 2px solid var(--frame); }
.how-step { padding: 16px 18px 18px 0; }
.how-step + .how-step { padding-left: 18px; border-left: 1px solid var(--border); }
.how-step:nth-child(2) { --i: 1; }
.how-step:nth-child(3) { --i: 2; }
.step-n { display: block; font: 700 2.6rem/1 var(--display); color: var(--brand); margin-bottom: 6px; }
.how-step h3 { font-size: 1.15rem; text-transform: uppercase; margin: 0 0 4px; }
.how-step p { margin: 0 0 8px; color: var(--text-2); }
.step-eg { font-size: .85rem; color: var(--muted); font-style: italic; margin: 0; }
@media (max-width: 800px) { .steps { grid-template-columns: minmax(0, 1fr); } .how-step, .how-step + .how-step { padding: 14px 0; border-left: 0; border-bottom: 1px solid var(--border); } }
.examples { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); gap: 10px; }
.example { position: relative; display: flex; flex-direction: column; gap: 6px; text-align: left; padding: 14px 16px 12px; border: 1px solid var(--frame); border-left: 4px solid var(--frame); background: var(--surface); color: var(--text); cursor: pointer; font: inherit;
  transition: opacity .6s, transform .5s var(--ease), border-color .2s, box-shadow .3s var(--ease); transition-delay: calc(var(--i, 0) * 70ms); }
.example q { font: 700 1.05rem/1.2 var(--display); quotes: "\201C" "\201D"; }
.example span { color: var(--muted); font-size: .82rem; }
.example .go { color: var(--brand); font-weight: 700; font-size: .75rem; text-transform: uppercase; letter-spacing: .06em; opacity: 0; transform: translateX(-6px); transition: opacity .2s, transform .3s var(--ease); }
.example.in:hover, .example.in:focus-visible { border-left-color: var(--brand); transform: translateY(-3px); box-shadow: 4px 4px 0 var(--surface-3); transition-delay: 0ms; }
.example:hover .go, .example:focus-visible .go { opacity: 1; transform: none; }
@media (hover: none) { .example .go { opacity: 1; transform: none; } }
.facts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border: 2px solid var(--frame); background: var(--surface); }
.fact { padding: 16px 18px; }
.fact + .fact { border-left: 1px solid var(--border); }
.fact:nth-child(2) { --i: 1; }
.fact:nth-child(3) { --i: 2; }
.fact:nth-child(4) { --i: 3; }
.fact b { display: block; font: 700 2.8rem/1 var(--display); font-variant-numeric: tabular-nums; }
.fact span { color: var(--text-2); font-size: .85rem; }
@media (max-width: 800px) { .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); } .fact:nth-child(3) { border-left: 0; } .fact:nth-child(n+3) { border-top: 1px solid var(--border); } }
.by-hand { display: flex; flex-wrap: wrap; gap: 12px 28px; align-items: center; justify-content: space-between; padding: 18px 20px; border: 1px solid var(--frame); border-left: 6px solid var(--brand); background: var(--surface); }
.by-hand .home-h { margin-bottom: 4px; }
.by-hand p { margin: 0; max-width: 56ch; }
.home .tool-links { margin-bottom: 30px; }
@media (prefers-reduced-motion: reduce) { .hero-title .line > span { animation: none; } .reveal { opacity: 1; transform: none; } }

/* Export menu opens leftward from the right end of the toolbar; the bare blank-board note. */
.pop .menu.right { left: auto; right: 0; }
.board-empty.bare { top: 40px; }
.board-empty.bare > div { background: var(--surface); border: 1px dashed var(--border-strong); padding: 12px 16px; display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center; justify-content: center; }
.board { color: var(--text); }
/* Toast: one line at the bottom of the screen, gone after a few seconds. */
.toast { position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 120; background: var(--text); color: var(--bg); padding: 10px 14px; font-size: .85rem; max-width: calc(100% - 32px); box-shadow: 0 4px 18px rgba(0, 0, 0, .25); animation: toast-in .18s ease-out; }
.toast a { color: inherit; font-weight: 700; text-decoration: underline; }
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 8px); } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }
.box-head > :first-child { margin-right: auto; }
.box-head { display: flex; align-items: baseline; gap: 8px; }
.box-head h3 { margin: 0 0 4px; }

/* ---------- Graphics maker: controls on the left, the card on the right ---------- */
.gfx { display: grid; grid-template-columns: minmax(300px, 380px) minmax(0, 1fr); gap: 20px; max-width: 1500px; margin: 0 auto; padding: 16px; align-items: start; }
.gfx-panel { display: flex; flex-direction: column; gap: 10px; }
.gfx-head h1 { margin: 0 0 2px; font-family: var(--display); font-size: 1.6rem; }
.gfx-head p { margin: 0; }
.gfx-sec { border: 1px solid var(--border); background: var(--surface); padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; }
.gfx-sec h3 { margin: 0; font-family: var(--display); font-size: .95rem; text-transform: uppercase; letter-spacing: .03em; }
.gfx-sec .field { display: flex; flex-direction: column; gap: 3px; font-size: .78rem; color: var(--text-2); flex: 1; min-width: 0; }
.gfx-sec input[type=text], .gfx-sec input[type=search], .gfx-sec select { width: 100%; min-width: 0; }
.gfx-row { display: flex; gap: 8px; flex-wrap: wrap; }
.gfx-examples { display: flex; flex-wrap: wrap; gap: 6px; }
.gfx-layouts { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.gfx-layouts button { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left; padding: 8px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); cursor: pointer; font: inherit; }
.gfx-layouts button span { font-size: .72rem; color: var(--muted); }
.gfx-layouts button[aria-pressed=true] { border-color: var(--frame); box-shadow: inset 0 -3px 0 var(--brand); background: var(--surface); }
.gfx-subj { border-left: 4px solid var(--tc); padding: 6px 0 6px 8px; display: flex; flex-direction: column; gap: 6px; }
.gfx-subj-top { display: flex; justify-content: space-between; gap: 6px; align-items: center; }
.gfx-subj-tools { display: inline-flex; gap: 3px; }
.gfx-subj-tools .btn.small { padding: 2px 7px; min-width: 26px; }
.gfx-span { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; font-size: .8rem; }
.gfx-span select { width: auto; }
.gfx-check { display: flex; gap: 6px; align-items: center; font-size: .82rem; }
/* Blind (who is who hidden): a bar above the card, big enough to find at a glance; outlined in the brand colour while on. */
.gfx-blind { margin: 0 0 8px; padding: 8px 12px; border: 2px solid var(--border-strong); background: var(--surface-2); }
.gfx-blind.on { border-color: var(--brand); }
.gfx-blind .gfx-check { font-size: .95rem; font-weight: 700; cursor: pointer; }
.gfx-blind .gfx-check input { width: 18px; height: 18px; }
.gfx-acwrap { position: relative; }
.gfx-ac { position: absolute; z-index: 30; left: 0; right: 0; top: 100%; margin: 0; padding: 0; list-style: none; background: var(--surface); border: 1px solid var(--border-strong); max-height: 260px; overflow: auto; box-shadow: 0 6px 18px rgba(0, 0, 0, .18); }
.gfx-ac:empty { display: none; }
.gfx-ac li { padding: 6px 8px; cursor: pointer; font-size: .85rem; }
.gfx-ac li:hover, .gfx-ac li.on { background: var(--row-hover); }
.gfx-stats { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 3px; counter-reset: st; }
.gfx-stats li { display: flex; justify-content: space-between; align-items: center; gap: 6px; padding: 4px 6px; background: var(--surface-2); font-size: .85rem; }
.gfx-stats li::before { counter-increment: st; content: counter(st); color: var(--muted); font-size: .72rem; width: 14px; }
.gfx-stats li > span:first-of-type { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gfx-games { display: flex; flex-direction: column; gap: 3px; max-height: 220px; overflow: auto; }
.gfx-stage { position: sticky; top: 12px; display: flex; flex-direction: column; gap: 10px; }
/* Side by side, each column scrolls on its own (the owner, 2026-09-29: on iPad scrolling the
   settings moved the card): both stick below the top and scroll inside, and a scroll that
   reaches a column's end does not carry on into the page. */
@media (min-width: 901px) {
  .gfx:not(.locked) > .gfx-panel, .gfx:not(.locked) > .gfx-stage { position: sticky; top: 12px; max-height: calc(100dvh - 24px); overflow-y: auto;
    overscroll-behavior: contain; -webkit-overflow-scrolling: touch; touch-action: pan-y; scrollbar-gutter: stable; }
  .gfx:not(.locked) > .gfx-panel { padding-right: 4px; }
}
/* The empty maker: what can be made, in the card's place, until there is a card. */
.gfx-placeholder { display: none; border: 1px dashed var(--border-strong); background: var(--surface); padding: 22px 20px; }
.gfx-placeholder h2 { margin: 0 0 4px; font-family: var(--display); font-size: 1.35rem; }
.gfx-placeholder p { margin: 0 0 14px; }
.gfx-try { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 8px; }
.gfx-try-card { display: flex; flex-direction: column; gap: 3px; text-align: left; padding: 10px 12px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); cursor: pointer; font: inherit; }
.gfx-try-card:hover, .gfx-try-card:focus-visible { border-color: var(--frame); box-shadow: inset 0 -3px 0 var(--brand); }
.gfx-try-card .muted { font-size: .78rem; }
.gfx-stage.gfx-blank > .gfx-placeholder { display: block; }
.gfx-stage.gfx-blank > .gfx-frame, .gfx-stage.gfx-blank > .gfx-player, .gfx-stage.gfx-blank > .gfx-status, .gfx-stage.gfx-blank > .gfx-motion, .gfx-stage.gfx-blank > .gfx-actions { display: none; }
.gfx-frame { background: repeating-linear-gradient(45deg, var(--surface-2) 0 10px, var(--surface) 10px 20px); border: 1px solid var(--border); padding: 14px; display: flex; justify-content: center; }
.gfx-canvas { width: auto; height: auto; max-width: 100%; max-height: 68vh; display: block; box-shadow: 0 10px 34px rgba(0, 0, 0, .28); background: #111; }
.gfx-status { min-height: 1.2em; margin: 0; }
.gfx-status:empty { display: none; }

/* player: play button, scrubber, clock */
.gfx-player { display: flex; align-items: center; gap: 10px; }
.gfx-play { min-width: 92px; font-variant-numeric: tabular-nums; }
.gfx-scrub { flex: 1; min-width: 0; accent-color: var(--brand); }
.gfx-clock { font-variant-numeric: tabular-nums; white-space: nowrap; min-width: 88px; text-align: right; }

/* motion controls */
.gfx-motion { border: 1px solid var(--border); background: var(--surface); padding: 10px 12px; display: flex; flex-direction: column; gap: 10px; }
.gfx-motion-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.gfx-motion-label { font-family: var(--display); text-transform: uppercase; font-size: .85rem; letter-spacing: .03em; width: 72px; }
.gfx-motion-opts .field { display: flex; flex-direction: column; gap: 3px; font-size: .74rem; color: var(--text-2); text-transform: uppercase; letter-spacing: .03em; }
.gfx-motion-opts .seg { height: 28px; }
.gfx-anims { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; flex: 1; min-width: 0; }
.gfx-anims button { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 8px 4px 6px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); cursor: pointer; font: 600 .78rem/1 var(--font); }
.gfx-anims button:hover { border-color: var(--border-strong); }
.gfx-anims button[aria-pressed=true] { border-color: var(--frame); box-shadow: inset 0 -3px 0 var(--brand); background: var(--surface); }
/* each entrance button shows its own motion in miniature: three bars, on hover or when picked */
.gfx-demo { display: flex; flex-direction: column; gap: 3px; width: 46px; height: 26px; justify-content: center; }
.gfx-demo i { display: block; height: 6px; background: var(--text-2); transform-origin: center; }
.gfx-demo i:nth-child(1) { background: var(--brand); width: 100%; }
.gfx-demo i:nth-child(2) { width: 80%; }
.gfx-demo i:nth-child(3) { width: 90%; }
.gfx-anims button:hover .gfx-demo i, .gfx-anims button[aria-pressed=true] .gfx-demo i { animation: 1.6s cubic-bezier(.2, .8, .2, 1) infinite both; }
.gfx-anims button .gfx-demo i:nth-child(2) { animation-delay: .12s !important; }
.gfx-anims button .gfx-demo i:nth-child(3) { animation-delay: .24s !important; }
[data-anim=slide] .gfx-demo i { animation-name: gfx-slide !important; }
[data-anim=blinds] .gfx-demo i { animation-name: gfx-blinds !important; }
[data-anim=wipe] .gfx-demo i { animation-name: gfx-wipe !important; }
[data-anim=pop] .gfx-demo i { animation-name: gfx-pop !important; }
[data-anim=none] .gfx-demo i { animation: none !important; }
@keyframes gfx-slide { 0% { transform: translateX(-120%); opacity: 0; } 35%, 100% { transform: none; opacity: 1; } }
@keyframes gfx-blinds { 0% { transform: scaleY(0); filter: brightness(.4); } 30%, 100% { transform: none; filter: none; } }
@keyframes gfx-wipe { 0% { clip-path: inset(0 100% 0 0); } 35%, 100% { clip-path: inset(0 0 0 0); } }
@keyframes gfx-pop { 0% { transform: scale(.3); opacity: 0; } 22% { transform: scale(1.12); opacity: 1; } 34%, 100% { transform: none; } }

.gfx-actions { display: flex; flex-wrap: wrap; gap: 6px; }

/* ready-made cards, drawn live */
.gfx-gallery { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.gfx-thumb { display: flex; flex-direction: column; gap: 5px; padding: 0 0 6px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); cursor: pointer; text-align: left; font: inherit; overflow: hidden; transition: transform .18s ease, box-shadow .18s ease; }
.gfx-thumb:hover, .gfx-thumb:focus-visible { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(0, 0, 0, .2); }
.gfx-thumb canvas { width: 100%; height: auto; display: block; background: #111; }
.gfx-thumb > span { display: flex; flex-direction: column; gap: 1px; padding: 0 8px; font-size: .78rem; }
.gfx-thumb > span .muted { font-size: .7rem; }

/* layout buttons get a small picture of their shape */
.gfx-lay-ico { display: flex; gap: 2px; height: 16px; width: 34px; margin-bottom: 3px; }
.gfx-lay-ico i { flex: 1; background: var(--text-2); opacity: .55; }
.gfx-layouts button[aria-pressed=true] .gfx-lay-ico i { background: var(--brand); opacity: 1; }
.gfx-lay-ico[data-lay=h2h] i:nth-child(2) { flex: 1.4; background: var(--border-strong); }
.gfx-lay-ico[data-lay=games] i:first-child { flex: 1.3; }
.gfx-lay-ico[data-lay=bars] { flex-direction: column; justify-content: center; }
.gfx-lay-ico[data-lay=bars] i { flex: none; height: 4px; }
.gfx-lay-ico[data-lay=bars] i:nth-child(1) { width: 100%; }
.gfx-lay-ico[data-lay=bars] i:nth-child(2) { width: 65%; }
.gfx-lay-ico[data-lay=bars] i:nth-child(3) { width: 85%; }
@media (max-width: 900px) {
  .gfx { grid-template-columns: minmax(0, 1fr); padding: 12px 16px; }
  /* Phones: the preview stays pinned (smaller) while the editor scrolls under it; motion,
     export and the ready-made cards follow the editor instead of pushing it off screen. */
  .gfx-stage { display: contents; }
  .gfx-frame { order: -3; position: sticky; top: 0; z-index: 5; padding: 8px; }
  .gfx-placeholder { order: -3; }
  .gfx-canvas { max-height: 34vh; }
  .gfx-player { order: -2; }
  .gfx-credit { order: -2; }   /* the photos' credit in words, under the pinned preview (before the play bar in the page) */
  .gfx-status { order: -1; }
  .gfx-motion { order: 1; }
  .gfx-actions { order: 2; }
  .gfx-start { order: 3; }
  .gfx-anims { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .gfx-gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .gfx-motion-label { width: 100%; }
}
.gfx > *, .gfx-sec, .gfx-subj { min-width: 0; }
.gfx-layouts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.gfx-subj-top .seg { flex-shrink: 0; }

/* ---------- Account ---------- */
.account .acct-card { border: 1px solid var(--border); background: var(--surface); padding: 16px; display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; max-width: 100%; }
.account > .acct-card { max-width: 460px; }
.account .acct-card h2 { margin: 0; font-family: var(--display); font-size: 1.15rem; }
.acct-form { display: flex; flex-direction: column; gap: 10px; }
.acct-field { display: flex; flex-direction: column; gap: 4px; }
.acct-field > span:first-child { font-size: .8rem; font-weight: 600; color: var(--text-2); }
.acct-field input { width: 100%; }
.acct-form .btn { align-self: flex-start; }
.acct-msg { margin: 0; min-height: 1.2em; font-size: .88rem; }
.acct-msg.error { color: var(--wrong); }
.acct-code { font-family: ui-monospace, Consolas, monospace; font-size: 1.25rem; letter-spacing: .06em; padding: 10px 12px; background: var(--surface-2); border: 1px dashed var(--border-strong); user-select: all; margin: 0; overflow-wrap: anywhere; }
.acct-trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.acct-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.acct-list li { display: flex; gap: 10px; align-items: center; padding: 6px 0; border-bottom: 1px solid var(--border); }
.acct-list li a { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
/* A saved item's row: name, when, then Pin / Rename / Delete; on a phone the buttons wrap under the name. */
.acct-list li { flex-wrap: wrap; row-gap: 4px; }
.acct-list li a { flex-basis: 40%; }
.acct-when { display: inline-flex; gap: 6px; align-items: center; white-space: nowrap; }
.acct-pin-tag { font-weight: 700; color: var(--text); text-transform: uppercase; letter-spacing: .06em; font-size: .66rem; }
.acct-acts { display: flex; gap: 4px; margin-left: auto; }
.acct-rename { display: flex; gap: 6px; flex: 1; align-items: center; min-width: 0; }
.acct-rename input { flex: 1; min-width: 0; font-size: 16px; }
.acct-danger { border-top: 1px solid var(--border); padding-top: 12px; margin-top: 6px; }
.acct-danger h3 { margin: 0; font-size: 1rem; }
.btn.danger { background: var(--wrong); border-color: var(--wrong); color: #fff; }
.account-link { text-decoration: none; white-space: nowrap; }
.acct-mini { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; max-height: 200px; overflow: auto; }
.acct-mini a { font-size: .85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-field .small { text-transform: none; letter-spacing: normal; font-weight: 400; }
.acct-card > .btn, .acct-card > a.btn, .acct-card > button { align-self: flex-start; }
/* The sign-in screen's three choices (Sign in, Create account, Sponsored account): one row, the
   full width of the card, so each is a comfortable tap on a phone. */
.account .seg.acct-tabs { display: flex; width: 100%; height: auto; }
.account .seg.acct-tabs button { flex: 1 1 0; min-width: 0; height: 36px; padding: 0 6px; white-space: normal; line-height: 1.15; font-size: .8rem; }
.acct-forgot { margin: 0; }
/* "Continue with Google": full width above the email form, the plain white button Google's guidelines ask for
   (no Google script or font is loaded; the G is drawn in text), then "or use your email". */
.acct-google { display: flex; flex-direction: column; gap: 6px; }
.acct-google .small { margin: 0; }
.account a.btn.acct-google-btn { align-self: stretch; display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 44px;
  background: #fff; color: #1f1f1f; border: 1px solid #747775; font-weight: 600; text-decoration: none; }
.account a.btn.acct-google-btn:hover { background: #f2f2f2; }
.acct-google-g { font: 700 1.1rem/1 Arial, sans-serif; color: #4285f4; }
.acct-or { display: flex; align-items: center; gap: 10px; color: var(--text-2); font-size: .8rem; margin: 4px 0 2px; }
.acct-or::before, .acct-or::after { content: ''; flex: 1; border-top: 1px solid var(--border); }
/* "Email me when new features launch": the box, a touch larger than a menu checkbox, and its hint under it. */
.acct-updates-wrap { display: flex; flex-direction: column; gap: 3px; }
.account .acct-updates { font-size: .9rem; }
.account .acct-updates input { width: 16px; height: 16px; margin: 0; flex: none; }
.acct-pro { display: inline-block; margin-left: 4px; padding: 2px 7px; background: var(--text); color: var(--bg); font: 700 .66rem/1.3 var(--font); letter-spacing: .06em; text-transform: uppercase; vertical-align: 2px; }

/* ---------- Home: the graphics maker section and its demo ---------- */
.gfx-ad { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 28px; align-items: center; }
.gfx-ad-copy p { max-width: 46ch; }
@media (max-width: 1020px) { .gfx-ad { grid-template-columns: minmax(0, 1fr); } }
.fx-ad { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 28px; align-items: center; }
.fx-ad-copy p { max-width: 46ch; }
.fx-ad-btns { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.fx-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
@media (max-width: 560px) { .fx-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } .fx-tile { padding: 12px; } .fx-tile b { font-size: .95rem; } .fx-tile span { font-size: .8rem; } }
.fx-tile { display: flex; flex-direction: column; gap: 4px; padding: 14px 16px; border: 1px solid var(--frame); border-top: 4px solid var(--brand); background: var(--surface); color: var(--text); }
.fx-tile:hover { background: var(--row-hover); text-decoration: none; }
.fx-tile b { font: 700 1.05rem/1.15 var(--display); text-transform: uppercase; letter-spacing: .03em; }
.fx-tile span { color: var(--text-2); font-size: .84rem; }
.fx-tile small { color: var(--brand-ink); font-size: .78rem; margin-top: auto; padding-top: 4px; }
@media (max-width: 1020px) { .fx-ad { grid-template-columns: minmax(0, 1fr); } }
.gdemo { position: relative; border: 2px solid var(--frame); box-shadow: 8px 8px 0 var(--surface-3); overflow: hidden; transition: opacity .5s; background: #0a0f1c; }
.gdemo.fade { opacity: 0; }
.gdemo.held, .gdemo.held * { animation-play-state: paused !important; }
.gd-segs { display: inline-flex; margin-left: auto; border: 1px solid #555; }
.gd-seg { padding: 3px 8px; color: #bbb; white-space: nowrap; transition: background .2s, color .2s, transform .15s; }
.gd-seg.on { background: #eee; color: #111; font-weight: 700; }
.gd-seg.pressed, .gd-dl.pressed { transform: scale(.92); }
.gd-dl { margin-left: 6px; padding: 3px 10px; background: var(--brand-btn); color: #fff; font-weight: 700; white-space: nowrap; transition: transform .15s; }
/* A phone: "Side by side" and "Download PNG" broke onto three lines and spilled out of the 32 px bar.
   The window dots go and the address gives way, so the buttons keep one line. */
@media (max-width: 520px) {
  .gdemo .demo-chrome { gap: 4px; padding: 0 6px; }
  .gdemo .demo-chrome i { display: none; }
  .gdemo .demo-url { margin-left: 0; padding: 2px 6px; }
  .gd-seg { padding: 3px 6px; }
  .gd-dl { margin-left: 4px; padding: 3px 7px; }
}
.gd-card { --ease: cubic-bezier(.16, 1, .3, 1); position: relative; aspect-ratio: 16 / 9; padding: 3.5% 5% 2%; display: flex; flex-direction: column; gap: 3%;
  background: repeating-linear-gradient(-45deg, rgba(255, 255, 255, .035) 0 14px, transparent 14px 46px), linear-gradient(135deg, #0a0f1c, #1a2233); color: #fff; font-family: var(--display); overflow: hidden; }
.gd-title { background: #f4f4f4; color: #0d0d0d; text-align: center; padding: .6% 0; border-bottom: 3px solid #f5c542; font-size: clamp(1rem, 2.6vw, 1.9rem); letter-spacing: .02em;
  transform: translateY(-140%); opacity: 0; transition: transform .6s var(--ease), opacity .3s; }
.s-title .gd-title { transform: none; opacity: 1; }
.gd-body { flex: 1; min-height: 0; display: grid; grid-template-columns: 26% minmax(0, 1fr) 26%; gap: 1.2%; }
.gd-side { position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end; background: linear-gradient(180deg, color-mix(in srgb, var(--c) 88%, #fff), color-mix(in srgb, var(--c) 60%, #000));
  transition: transform .75s var(--ease), opacity .4s; opacity: 0; }
.gd-side.a { transform: translateX(-115%); }
.gd-side.b { transform: translateX(115%); }
.s-sides .gd-side { transform: none; opacity: 1; }
.gd-ghost { position: absolute; inset: 0; display: grid; place-items: center; font-size: clamp(2rem, 7vw, 5rem); opacity: .14; letter-spacing: .02em; }
.gd-side canvas { position: absolute; left: 50%; top: 38%; width: 84%; height: auto; translate: -50% -50%; opacity: 0; transition: transform .9s var(--ease) .25s, opacity .4s .25s; }
.gd-side.a canvas { transform: rotate(-35deg) scale(.6); }
.gd-side.b canvas { transform: rotate(35deg) scale(.6); }
.s-sides .gd-side canvas { transform: none; opacity: 1; }
.gd-name { position: relative; background: rgba(0, 0, 0, .62); padding: 6% 4%; text-align: center; display: flex; flex-direction: column; }
.gd-name b { font-size: clamp(.9rem, 2.2vw, 1.6rem); }
.gd-name span { font-family: var(--font); font-size: clamp(.6rem, 1vw, .75rem); opacity: .8; }
.gd-rows { display: flex; flex-direction: column; gap: 2%; min-height: 0; }
.gd-row { position: relative; flex: 1; min-height: 0; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 4%; padding: 0 5%;
  background: #111; font-size: clamp(.95rem, 2.4vw, 1.8rem); clip-path: inset(0 50% 0 50%); transition: clip-path .5s var(--ease) calc(var(--i) * 170ms); }
.gd-row:nth-child(even) { background: #1b1b1b; }
.s-rows .gd-row { clip-path: inset(0 0 0 0); }
.gd-v { font-variant-numeric: tabular-nums; transition: color .35s, text-shadow .35s, opacity .35s; }
.va { text-align: center; }
.vb { text-align: center; }
.gd-lab { font-size: .52em; color: #a9b0bd; text-transform: uppercase; letter-spacing: .04em; white-space: nowrap; transition: opacity .35s; }
.s-lead .gd-row[data-lead="a"] .va, .s-lead .gd-row[data-lead="b"] .vb { color: #f5c542; text-shadow: 0 0 14px rgba(245, 197, 66, .55); animation: gd-glint .9s calc(var(--i) * 120ms) both; }
@keyframes gd-glint { 0% { transform: scale(1); } 35% { transform: scale(1.18); } 100% { transform: scale(1); } }
/* Bars: the numbers slide to the ends, bars grow from the centre line toward each side. */
.gd-bar { position: absolute; top: 22%; height: 56%; width: 0; transition: width .8s var(--ease) calc(var(--i) * 120ms); opacity: .92; }
.gd-bar.ba { right: 50%; background: var(--ca); }
.gd-bar.bb { left: 50%; background: var(--cb); }
.s-bars .gd-row.has-bar .gd-bar.ba { width: calc(var(--wa) * .36); }
.s-bars .gd-row.has-bar .gd-bar.bb { width: calc(var(--wb) * .36); }
.s-bars .gd-row.has-bar .gd-lab { opacity: 0; }
.s-bars .gd-row:not(.has-bar) { opacity: .35; transition: opacity .5s, clip-path .5s; }
.gd-row .gd-v { position: relative; z-index: 1; }
.gd-foot { display: flex; justify-content: space-between; font-family: var(--font); font-size: clamp(.5rem, .9vw, .7rem); color: #a9b0bd; }
.gd-flash { position: absolute; inset: 0; background: #fff; opacity: 0; pointer-events: none; transition: opacity .12s; }
.gd-flash.on { opacity: .85; }
.gd-toast { z-index: 3; }
@media (prefers-reduced-motion: reduce) {
  .gd-title, .gd-side, .gd-side canvas, .gd-row, .gd-bar, .gd-v { transition: none !important; animation: none !important; }
}

/* What crawlers read before the app starts (lib/og.js inject); replaced on load. */
.prerender { padding: 24px 0; }
.prerender h1 { font-family: var(--display); margin: 0 0 8px; }

/* The tip strip under the header (public/js/pro.js decorateShell). */
.tip-strip { background: #1c1a14; border-bottom: 1px solid #3a3322; color: #d8d2c0; font-size: .85rem; }
.tip-strip .wrap { display: flex; align-items: center; justify-content: center; gap: 12px; padding-top: 6px; padding-bottom: 6px; flex-wrap: wrap; }
.tip-strip-link { color: #f2d27a; font-weight: 700; text-decoration: none; border: 1px solid #6b5a2a; padding: 3px 10px; }
.tip-strip-link:hover { background: #2e2716; }
.tip-strip-close { background: none; border: 0; color: #9a927e; font-size: 1.1rem; cursor: pointer; padding: 0 4px; line-height: 1; }
.tip-strip-close:hover { color: #fff; }
/* Phones keep the strip: "free during the beta" has to be seen there too. Compact, the line on its own row. */
@media (max-width: 600px) { .tip-strip { font-size: .78rem; } .tip-strip .wrap { gap: 6px 10px; padding-top: 5px; padding-bottom: 5px; } .tip-strip .wrap > span:first-child { flex-basis: 100%; text-align: center; } .tip-strip-link { padding: 2px 8px; } }

/* The tip ask after a download. */
.tip-nudge { position: fixed; right: 16px; bottom: 16px; z-index: 60; max-width: 340px; background: var(--surface); color: var(--text); border: 1px solid var(--border-strong); border-top: 3px solid #d4a72c; box-shadow: 0 10px 30px rgba(0, 0, 0, .25); padding: 12px 14px; animation: tip-in .25s cubic-bezier(.2, .8, .2, 1); }
.tip-nudge p { margin: 0 0 10px; font-size: .88rem; line-height: 1.4; }
.tip-nudge-row { display: flex; gap: 8px; }
.tip-nudge.leaving { opacity: 0; transform: translateY(8px); transition: opacity .2s, transform .2s; }
@keyframes tip-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@media (max-width: 520px) { .tip-nudge { left: 12px; right: 12px; max-width: none; } }

/* The thank-you after a tip (public/js/pro.js): centred over a dimmed page. */
.tip-thanks-back { position: fixed; inset: 0; z-index: 80; background: rgba(0, 0, 0, .55); display: flex; align-items: center; justify-content: center; padding: 16px; animation: tip-fade .2s ease; }
.tip-thanks { background: var(--surface); color: var(--text); border-top: 5px solid #d4a72c; box-shadow: 0 24px 60px rgba(0, 0, 0, .4); max-width: 520px; width: 100%; padding: 32px 32px 28px; text-align: center; animation: tip-in .3s cubic-bezier(.2, .8, .2, 1); }
.tip-thanks-icon { font-size: 3rem; line-height: 1; margin-bottom: 10px; }
.tip-thanks h2 { font-family: var(--display); font-size: 2rem; margin: 0 0 10px; text-transform: uppercase; }
.tip-thanks p { font-size: 1.05rem; margin: 0 0 22px; color: var(--text-2); }
@keyframes tip-fade { from { opacity: 0; } to { opacity: 1; } }

/* Beta badge beside the logo: feedback, opening the email box (public/js/feedback.js). */
.beta-pill { align-self: center; border: 1px solid #6b5a2a; color: #f2d27a; font: 700 .66rem/1 var(--font); text-transform: uppercase; letter-spacing: .06em; padding: 4px 6px; white-space: nowrap; text-decoration: none; flex-shrink: 0; }
@media (min-width: 1366px) { .beta-pill { margin-left: -12px; } }   /* one-line header: sit close to the logo */
.beta-pill:hover { background: #2e2716; text-decoration: none; color: #ffe39a; }
/* "Check your spam" while the sending domain is new (account page). */
.acct-spam { background: #fff7e0; border-left: 3px solid #d4a72c; padding: 8px 10px; font-size: .9rem; color: #3a2f10; }
:root[data-theme="dark"] .acct-spam { background: #2a2414; color: #f0e2b8; }
.tip-strip-feedback { color: #d8d2c0; text-decoration: underline; text-underline-offset: 2px; }
.tip-strip-feedback:hover { color: #fff; }

/* Jargon with a hover explanation (public/js/glossary.js). */
.jargon { text-decoration: underline dotted; text-decoration-color: var(--muted); text-underline-offset: 3px; cursor: help; }

/* Phones: tighter cells, a capped name column (it stays pinned, so every pixel it takes is
   one the stats lose), bigger tap targets on the sortable headers, and a shadow on the
   right edge while there are more columns to swipe to. */
.tbl-wrap { position: relative; }
.tbl-wrap.more { box-shadow: inset -14px 0 10px -10px rgba(0, 0, 0, .28); }
@media (max-width: 600px) {
  table.stats { font-size: .78rem; }
  table.stats th, table.stats td { padding: 4px 5px; }
  table.stats thead tr:last-child th { padding-top: 9px; padding-bottom: 9px; }
  table.stats tbody td { padding-top: 6px; padding-bottom: 6px; }
  table.stats tr > :nth-child(2) { max-width: 118px; overflow: hidden; text-overflow: ellipsis; }
  table.stats td.rk { padding-left: 4px; padding-right: 3px; }
}

/* ---------- trend watch: summary and the by-team view ---------- */
.trend-summary { border: 1px solid var(--border); border-left: 4px solid var(--brand); background: var(--surface); padding: 10px 14px; margin: 12px 0 4px; max-width: 820px; }
.trend-summary p { margin: 0 0 6px; }
.trend-summary p:last-child { margin: 0; }
.trend-summary .lead { font-size: 1.02rem; }
.nowrap { white-space: nowrap; }
.dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; vertical-align: middle; flex: none; }
.dot.real { background: var(--real); } .dot.early { background: var(--early); } .dot.noise { background: var(--noise); } .dot.void { background: var(--void); }
.tgroups { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 290px), 1fr)); gap: 10px; }
.tgroup { border: 1px solid var(--border); border-top: 3px solid var(--tc, var(--border)); background: var(--surface); padding: 8px 10px; }
.tgroup-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 4px; }
.tgroup ul { list-style: none; margin: 0; padding: 0; }
.tgroup li a { display: flex; gap: 7px; align-items: baseline; padding: 5px 0; border-top: 1px solid var(--grid); color: var(--text); font-size: .84rem; line-height: 1.3; }
.tgroup li a .dot { transform: translateY(-1px); }
.tgroup li a .what { flex: 1; }
.tgroup li a .nums { white-space: nowrap; font-variant-numeric: tabular-nums; font-weight: 700; }
/* The words are what matter (colour alone must not carry it); the colour is a quick cue. */
.tgroup .dir { font-weight: 600; font-size: .76rem; }
.tgroup .dir.up { color: var(--right); } .tgroup .dir.down { color: var(--wrong); }
.tgroup li a:hover .what { text-decoration: underline; }

/* ---------- glossary ---------- */
.gloss-index { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 4px 0 18px; font-size: .86rem; }
.gloss { max-width: 60em; margin: 0; }
.gloss dt { font: 700 1.1rem/1.3 var(--display); margin-top: 18px; padding-top: 10px; border-top: 1px solid var(--border); }
.gloss dd { margin: 4px 0 0; }
.gloss dd p { margin: 0 0 6px; }
.gloss-ex { color: var(--text-2); }
/* Glossary sections, the filter and each term's parts (public/js/views/glossary.js, from public/js/defs.js). */
.gloss-group { margin-top: 26px; }
.gloss-group > h2 { font: 700 1.3rem/1.2 var(--display); margin: 0 0 4px; }
.gloss-filter { width: 100%; max-width: 420px; min-height: 44px; margin: 4px 0 12px; font-size: 1rem; }
.gloss-k { color: var(--muted); font-weight: 600; }
.gloss-how, .gloss-src { color: var(--text-2); font-size: .92rem; }
.gloss-try a { display: inline-block; padding: 8px 0; min-height: 44px; box-sizing: border-box; }
.gloss dt[hidden], .gloss dd[hidden] { display: none; }
/* Ask's answer to "what is EPA?" (glossary.js defineLine). */
.define-answer .define-more { color: var(--text-2); }

/* ---------- teams index ---------- */
.team-index { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); gap: 14px; }
.team-div h2 { font-size: .9rem; border-bottom: 2px solid var(--text); padding-bottom: 3px; margin-bottom: 4px; }
.team-div ul { list-style: none; margin: 0; padding: 0; }
.team-div li { display: flex; justify-content: space-between; align-items: center; padding: 7px 0; border-bottom: 1px solid var(--grid); }
.team-div li a:hover { text-decoration: none; }
.team-div li a:hover .tchip { text-decoration: underline; }
.team-div h2 { display: flex; justify-content: space-between; align-items: baseline; }
.team-div-cols, .team-rec { font-variant-numeric: tabular-nums; color: var(--muted); white-space: nowrap; }
.team-div-cols { font-size: .7rem; font-weight: 600; }
.team-div-cols span, .team-rec span { display: inline-block; min-width: 3.2em; text-align: right; }
.team-season { max-width: 140px; margin-top: 8px; }

/* ---------- the dashboard's graphic widget ---------- */
.widget .wbody > .w-graphic { flex: 1; min-height: 0; width: 100%; object-fit: contain; }
.w-graphic-links { padding-top: 4px; text-align: right; color: var(--muted); }

/* ---------- phones: a reading view of the dashboard until "Edit board" ---------- */
/* Moving and resizing widgets only in "Edit dashboard", on every screen: outside it the title bar
   is not a handle, the resize edges are gone, and a touch on a widget scrolls or reads it. */
.dash-page:not(.editing) .widget .wbar { cursor: default; touch-action: auto; }
.dash-page:not(.editing) .widget .h-e, .dash-page:not(.editing) .widget .h-s, .dash-page:not(.editing) .widget .h-se { display: none; }
.dash-page.editing .widget:not(.selected) { outline: 1px dashed var(--border-strong); outline-offset: 2px; }
.dash-page.editing .edit-toggle { background: var(--text); color: var(--bg); border-color: var(--text); }
.dash-page.locked .edit-toggle { display: none; }
@media (max-width: 700px) {
  /* (Export stays: a PNG, the data sheet and the animations are as much for a phone as Share is; the owner, 2026-10-24.) */
  .dash-page:not(.editing) .dash-top > :not(.title-input):not(.edit-toggle):not(.share-btn):not(.export-pop) { display: none; }
  .dash-page:not(.editing) .focus-bar { display: none; }
  .dash-page:not(.editing) .board.stacked .wtools { display: none; }
  .dash-top .edit-toggle { display: inline-flex; order: -1; }
  .dash-top .share-btn { order: -1; }
  .dash-top .export-pop { order: -1; }
  .dash-top .export-pop .menu { position: fixed; left: 8px !important; right: 8px !important; top: auto; width: auto !important; max-width: none; max-height: 70vh; }
  .dash-page.editing .edit-toggle { background: var(--text); color: var(--bg); }
}

/* ---------- jargon on touch screens: a tap-to-open explanation ---------- */
.jargon-i { border: 0; background: none; color: var(--link); font-size: .95em; padding: 0 2px 0 4px; margin: 0; cursor: pointer; line-height: 1; vertical-align: baseline; min-width: 22px; min-height: 22px; }
.jargon-pop { position: absolute; z-index: 90; background: var(--surface); color: var(--text); border: 1px solid var(--border-strong); box-shadow: 0 6px 20px rgba(0, 0, 0, .25); padding: 10px 12px; font: 400 .86rem/1.4 var(--font); text-transform: none; letter-spacing: 0; text-align: left; white-space: normal; }
.jargon-pop b { display: block; margin-bottom: 4px; }
.jargon-pop p { margin: 0 0 6px; }
.jargon-pop .jargon-how, .jargon-pop .jargon-src, .jargon-pop .jargon-chart { color: var(--text-2); font-size: .82rem; }
.jargon-pop .jargon-k { color: var(--muted); font-weight: 600; }
.jargon-pop a { display: inline-block; padding: 6px 0 2px; }
/* A widget title: only the title itself is underlined, not its subtitle. */
.wtitle.jargon { text-decoration: none; cursor: default; }
.wtitle.jargon > b { text-decoration: underline dotted; text-decoration-color: var(--muted); text-underline-offset: 3px; cursor: help; }

/* The key to a two-tone bar chart (above or below a player's average, or the league's). */
.tone-key { display: flex; flex-wrap: wrap; gap: 2px 14px; margin: 0 0 4px; font-size: .74rem; color: var(--text-2); }
.tone-key-item { display: inline-flex; align-items: center; gap: 5px; }
.tone-key-item i { width: 10px; height: 10px; flex: none; }
/* Nothing on the board follows the focus (players each in his own season): greyed out. */
.focus-bar.idle { border-left-color: var(--border); opacity: .55; }
.focus-bar.idle select:disabled { cursor: not-allowed; }

/* Which games count (public/js/weekpick.js): the kind first, then the weeks as a sentence. */
.week-pick { display: flex; flex-direction: column; gap: 6px; }
.week-pick-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: .82rem; }
.week-pick-line select { width: auto; }
.week-pick-line > span:first-child { min-width: 2.6em; }
.week-pick-says { margin: 0; font-size: .76rem; color: var(--text-2); }

/* ---------- the makers need an account (ui.js signInGate / signInBar) ---------- */
.signin-gate { max-width: 560px; margin: 48px auto; padding: 24px; box-sizing: border-box; border: 1px solid var(--border); border-top: 4px solid var(--brand); background: var(--surface); }
.signin-gate h1 { margin: 0 0 10px; font-family: var(--display); font-size: 1.5rem; }
.signin-gate p { margin: 0 0 10px; }
.signin-gate-btns { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.signin-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding: 8px 12px; margin-bottom: 8px; border: 1px solid var(--border); border-left: 4px solid var(--brand); background: var(--surface); font-size: .86rem; }
/* A shared dashboard, signed out: the board to read, Share, and nothing that edits it. */
.dash-page.locked .dash-top > :not(.title-input):not(.share-btn) { display: none; }
/* A locked shared board can be copied from: its widgets keep only the Copy tool. */
.dash-page.locked .wtools > :not(.w-copy), .dash-page:not(.editing) .board.stacked .wtools > :not(.w-copy) { display: none; }
.dash-page.locked .wtools, .dash-page:not(.editing) .board.stacked .wtools { display: flex !important; }
.clip-menu { min-width: 320px; }
.clip-row { display: flex; align-items: center; gap: 6px; padding: 3px 0; border-bottom: 1px solid var(--border); }
.clip-row label { flex: 1; min-width: 0; }
.clip-row label span { overflow: hidden; text-overflow: ellipsis; }
.clip-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.dash-page.locked .focus-bar, .dash-page.locked .dock, .dash-page.locked .h-e, .dash-page.locked .h-s, .dash-page.locked .h-se { display: none; }
.dash-page.locked .wbar { cursor: default; }
.dash-page.locked .title-input { border-color: transparent; background: none; }
/* A shared graphic, signed out: the card and its Play button, nothing that edits it. */
.gfx.locked { display: block; max-width: 1100px; margin: 0 auto; }
.gfx.locked .gfx-panel, .gfx.locked .gfx-motion, .gfx.locked .gfx-start { display: none; }
/* A shared card can be copied to the clipboard; nothing else in its actions is for a viewer. */
.gfx.locked .gfx-actions > :not(.gfx-copy) { display: none; }

/* ---------- plays widget (build.js renderPlays): a summary line, then every play ---------- */
.plays-sum { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 0 0 6px; font-size: .82rem; color: var(--text-2); }
.plays-sum b { color: var(--text); font-variant-numeric: tabular-nums; }
.plays-table .tbl-wrap { flex: 1; min-height: 0; }
.plays-table table.stats td:last-child { white-space: normal; min-width: 340px; max-width: 640px; }
.plays-list { list-style: none; margin: 0; padding: 0; overflow: auto; flex: 1; min-height: 0; }
.plays-list li { padding: 6px 0; border-top: 1px solid var(--border); font-size: .82rem; }
.plays-list .plays-top { color: var(--text-2); font-variant-numeric: tabular-nums; }
.plays-list .plays-top b { color: var(--text); }
.plays-list .plays-descr { margin-top: 2px; line-height: 1.35; }
/* The spider's "Choose stats" line, under the chart (build.js renderRadar). */
.radar-pick { font-size: .76rem; padding-top: 2px; }
.dash-page.locked .radar-pick { display: none; }
.btn.preset[aria-pressed="true"] { background: var(--text); color: var(--bg); border-color: var(--text); }

/* ---------- Fantasy (views/fantasy.js, fantasygraphic.js, fantasy.js) ---------- */
.fx-head p { max-width: 60em; }
.fx-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 12px; }
.fx-league select { max-width: min(460px, 100%); font-weight: 700; }
.fx-where { font-size: .78rem; }
.fx-link-box { border: 1px solid var(--frame); border-top: 4px solid var(--brand); background: var(--surface); padding: 12px 14px; margin: 0 0 14px; display: flex; flex-direction: column; gap: 8px; }
.fx-link-box[hidden] { display: none; }
.fx-link-box h2 { margin: 0; }
.fx-link-box h3 { margin: 0; font-size: .82rem; text-transform: uppercase; letter-spacing: .04em; }
.fx-step { display: flex; flex-direction: column; gap: 6px; }
.fx-row { display: flex; gap: 8px; flex-wrap: wrap; }
.fx-row input { flex: 1 1 220px; min-width: 0; height: 34px; font-size: 1rem; }
.fx-row .btn { height: 34px; }
.fx-msg { margin: 0; font-size: .86rem; }
.fx-msg:empty { display: none; }
.fx-msg.error { color: var(--wrong); }
.fx-pick { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); gap: 6px; }
.fx-pick:empty { display: none; }
.fx-pick > h3, .fx-pick > p { grid-column: 1 / -1; margin: 4px 0 0; }
.fx-choice { display: flex; align-items: center; gap: 10px; padding: 8px 10px; min-height: 48px; border: 1px solid var(--border-strong); background: var(--surface); color: var(--text); text-align: left; font: inherit; cursor: pointer; }
.fx-choice:hover, .fx-choice:focus-visible { background: var(--row-hover); }
.fx-choice.yours { border-color: var(--frame); box-shadow: inset 4px 0 0 var(--brand); }
.fx-choice span { display: flex; flex-direction: column; min-width: 0; }
.fx-choice b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fx-choice small { color: var(--muted); font-size: .76rem; }
.fx-soon { margin: 2px 0 0; color: var(--text-2); }
.fx-try { border: 1px solid var(--border); background: var(--surface); padding: 12px 14px; display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: space-between; }
.fx-try p { margin: 0; }
.fx-note { margin: 0 0 12px; }
.fx-av { position: relative; display: inline-flex; flex: none; align-items: center; justify-content: center; border-radius: 50%; overflow: hidden; color: #fff; font: 700 1rem/1 var(--display); letter-spacing: .02em;
  background: hsl(var(--hue, 212) 55% 38%); }
.fx-av img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.fx-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.fx-card { border: 1px solid var(--frame); background: var(--surface); padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.fx-card > h2 { margin: 0; padding-bottom: 3px; border-bottom: 2px solid var(--text); font-size: 1rem; }
.fx-card p { margin: 0; }
.fx-card .tbl-wrap { border-color: var(--border); }
.fx-side { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 6px 0; border-bottom: 1px solid var(--grid); }
.fx-who { display: flex; flex-direction: column; min-width: 0; }
.fx-who b { font: 700 1.05rem/1.2 var(--display); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fx-who small { color: var(--muted); font-size: .76rem; }
.fx-score { font: 700 2rem/1 var(--display); font-variant-numeric: tabular-nums; color: var(--text-2); }
.fx-side.lead .fx-score { color: var(--text); }
.fx-side.lead { box-shadow: inset 3px 0 0 var(--brand); padding-left: 8px; }
.fx-lineups summary { cursor: pointer; font-size: .82rem; font-weight: 600; padding: 2px 0; }
.fx-lineups .tbl-wrap { margin-top: 6px; }
.fx-alerts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.fx-alerts li { padding: 6px 0 6px 10px; border-bottom: 1px solid var(--grid); border-left: 3px solid var(--noise); font-size: .88rem; }
.fx-alerts li.injury, .fx-alerts li.empty { border-left-color: var(--wrong); }
.fx-alerts li.bye { border-left-color: var(--early); }
.fx-ok { color: var(--real); font-weight: 600; }
.fx-stand { font-size: .92rem; }
.fx-in { color: var(--real); font-weight: 700; }
.fx-go { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin: 16px 0; }
.fx-big { display: flex; flex-direction: column; gap: 4px; padding: 14px 16px; border: 1px solid var(--frame); border-top: 4px solid var(--brand); background: var(--surface); color: var(--text); }
.fx-big:hover { background: var(--row-hover); text-decoration: none; }
.fx-big b { font: 700 1.25rem/1.15 var(--display); text-transform: uppercase; letter-spacing: .03em; }
.fx-big b::after { content: " ›"; color: var(--brand-ink); }
.fx-big span { color: var(--text-2); font-size: .86rem; }
.fx-ask { margin-top: 4px; }
.fx-answer { display: flex; flex-direction: column; gap: 6px; }
.fx-answer:empty { display: none; }
.fx-answer h3 { margin: 4px 0 0; font-size: 1.1rem; }
.fx-answer p { margin: 0; max-width: 72em; }
.fx-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.fx-foot { margin-top: 18px; max-width: 72em; }
@media (max-width: 760px) {
  .fx-grid, .fx-go { grid-template-columns: minmax(0, 1fr); }
  .fx-score { font-size: 1.7rem; }
  .fx-bar .fx-league { flex: 1 1 100%; }
  .fx-bar .fx-league select { width: 100%; max-width: none; height: 36px; }
}
/* Fantasy graphics maker: the maker's layout, with its own card list. */
.fx-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.fx-cards button { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left; padding: 8px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); cursor: pointer; font: inherit; }
.fx-cards button span { font-size: .72rem; color: var(--muted); }
.fx-cards button[aria-pressed=true] { border-color: var(--frame); box-shadow: inset 0 -3px 0 var(--brand); background: var(--surface); }
/* The fantasy pages' small tables fit a phone: names wrap, and nothing sticks sideways. */
.fx-table table.stats tr > :first-child, .fx-table table.stats tr > :nth-child(2) { position: static; box-shadow: none; }
.fx-table table.stats td.l { white-space: normal; }
/* With the Fantasy tab the header needs about 1,450 px at full spacing; from 1366 px up to that it
   stays on one line with tighter spacing and a shorter search box (runbook: nine links, 2026-09-28). */
@media (min-width: 1366px) and (max-width: 1499px) {
  .nav a { padding: 0 7px; letter-spacing: .02em; }
}
/* Fantasy with no league (the player tools, public/js/views/fantasy.js): the scoring picker, a
   start/sit box, leaders and risers. Linking a league is optional. */
.fx-go { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
.fx-scoring { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0 0 10px; }
.fx-sc-label { font: 700 .8rem/1 var(--display); text-transform: uppercase; letter-spacing: .06em; }
.fx-seg { height: 34px; }
.fx-seg button { min-width: 44px; font-size: .84rem; }
.fx-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.fx-tools .fx-pos { flex-wrap: wrap; height: auto; }
.fx-tools .fx-pos button { height: 32px; }
.fx-tools select { height: 32px; }
.fx-inline { display: inline-flex; align-items: center; gap: 6px; }
.fx-compare { margin: 0 0 14px; }
.fx-compare .fx-row { max-width: 520px; }
.fx-picker { display: flex; min-width: 0; }
.fx-row .fx-picker { flex: 1 1 240px; }
.fx-picker input { flex: 1; min-width: 0; height: 34px; font-size: 1rem; }
.fx-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.fx-chips:empty { display: none; }
.fx-chip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 4px 3px 10px; border: 1px solid var(--border-strong); background: var(--surface-2); border-radius: 16px; font-size: .86rem; font-weight: 600; }
.fx-chip small { color: var(--muted); font-weight: 500; }
.fx-chip button { border: 0; background: none; color: var(--text-2); font-size: 1.1rem; line-height: 1; width: 28px; height: 28px; border-radius: 50%; cursor: pointer; }
.fx-chip button:hover, .fx-chip button:focus-visible { background: var(--row-hover); color: var(--text); }
.fx-yours { margin: 14px 0 0; border-top: 4px solid var(--brand); }
.fx-grid + .fx-yours { margin-top: 14px; }
@media (max-width: 760px) {
  .fx-seg button { padding: 0 8px; }
  .fx-compare .fx-row { max-width: none; }
}

/* The email box (public/js/feedback.js): a mailto: link opens this instead of the mail program.
   The address to copy, Copy, and "Open email app" for anyone who wants it. */
.fb-back { position: fixed; inset: 0; z-index: 90; background: rgba(0, 0, 0, .5); display: flex; align-items: center; justify-content: center; padding: 16px; animation: tip-fade .15s ease; }
.fb-box { position: relative; background: var(--surface); color: var(--text); border-top: 4px solid #d4a72c; box-shadow: 0 20px 50px rgba(0, 0, 0, .4); width: 100%; max-width: 440px; padding: 22px 22px 16px; animation: tip-in .2s cubic-bezier(.2, .8, .2, 1); }
.fb-title { font-family: var(--display); font-size: 1.35rem; text-transform: uppercase; margin: 0 36px 6px 0; }
.fb-prompt { margin: 0 0 12px; color: var(--text-2); }
.fb-row { display: flex; gap: 8px; align-items: stretch; }
.fb-addr { flex: 1; min-width: 0; display: flex; align-items: center; padding: 8px 10px; border: 1px solid var(--border-strong); background: var(--surface-2); font: 500 1rem/1.3 var(--font); overflow-wrap: anywhere; user-select: all; -webkit-user-select: all; cursor: text; }
.fb-row .fb-copy { height: auto; min-height: 44px; min-width: 88px; justify-content: center; font-size: .9rem; }
.fb-status { min-height: 1.3em; margin: 8px 0 0; font-size: .85rem; color: var(--text-2); }
.fb-alt { margin: 4px 0 0; font-size: .85rem; }
.fb-open-app { display: inline-block; padding: 8px 0; color: var(--link); text-decoration: underline; text-underline-offset: 2px; }
.fb-close { position: absolute; top: 6px; right: 6px; width: 44px; height: 44px; background: none; border: 0; color: var(--muted); font-size: 1.5rem; line-height: 1; cursor: pointer; }
.fb-close:hover { color: var(--text); }
@media (max-width: 420px) { .fb-box { padding: 18px 16px 12px; } .fb-row { flex-direction: column; } .fb-row .fb-copy { width: 100%; } }

/* ---------- the shared sign-in page, as a sister site (lib/brand.js, public/js/brand.js) ----------
   /account?site=mlb|nba|nhl: someone signing in to Batter Lab sees Batter Lab. The colours are the
   sister sites' own tokens (their site.css, body[data-sport]); Pigskin Lab's menus, search, ads
   and footer give way to one line saying this is the shared sign-in for all four sites. */
html[data-brand="mlb"] { --brand: #138a43; --brand-ink: #0f6e36; --brand-btn: #0f7a3c; --brand-2: #1fa855; }
html[data-brand="nba"] { --brand: #e06a14; --brand-ink: #b4500a; --brand-btn: #b4500a; --brand-2: #f39a1a; }
html[data-brand="nhl"] { --brand: #0a7fe0; --brand-ink: #0864b0; --brand-btn: #0864b0; --brand-2: #00a3ee; }
:root[data-theme="dark"][data-brand="mlb"] { --brand: #2fb866; --brand-ink: #4cc97e; --brand-btn: #117a3d; }
:root[data-theme="dark"][data-brand="nba"] { --brand: #f08a36; --brand-ink: #ff9d4d; --brand-btn: #b4500a; }
:root[data-theme="dark"][data-brand="nhl"] { --brand: #3d9df0; --brand-ink: #6bb6ff; --brand-btn: #0864b0; }
.shared-signin-foot { display: none !important; }
html[data-brand] .shared-signin-foot { display: flex !important; }
html[data-brand] #main-nav, html[data-brand] .site-header .search, html[data-brand] .beta-pill, html[data-brand] #account-link,
html[data-brand] #menu-btn, html[data-brand] .ad-wrap, html[data-brand] .tip-strip, html[data-brand] .site-family, html[data-brand] .site-foot-main { display: none !important; }
html[data-brand] .site-header .wrap { justify-content: space-between; flex-wrap: nowrap; height: 50px; padding-top: 0; padding-bottom: 0; }
html[data-brand] .site-header .header-tools { margin-left: auto; flex-basis: auto; order: 0; }
html[data-brand] .site-footer { border-top: 3px solid var(--brand); }
.acct-brand { display: flex; align-items: center; gap: 14px; margin: 0 0 6px; }
.acct-brand img { width: 56px; height: 56px; flex: none; }
.acct-brand .on-dark { display: none; }
:root[data-theme="dark"] .acct-brand .on-light { display: none; }
:root[data-theme="dark"] .acct-brand .on-dark { display: block; }
.acct-brand h1 { margin: 0; }
html[data-brand] .account .page-head { border-bottom: 3px solid var(--brand); }
html[data-brand] .account > .acct-card { border-top: 4px solid var(--brand); }
html[data-brand] .account .btn.primary { background: var(--brand-btn); border-color: var(--brand-btn); color: #fff; }
html[data-brand] .account .seg button[aria-pressed="true"] { background: var(--brand-btn); color: #fff; }
html[data-brand] .account .linkish, html[data-brand] .account .page-head a, html[data-brand] .shared-signin-foot a { color: var(--brand-ink); }
.acct-sister-note { font-size: .86rem; color: var(--text-2); margin: 6px 0 0; }

/* ---------- a board drawn on a page (the game page), read-only ---------- */
.static-board { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin: 12px 0 24px; }
.static-w { border: 1px solid var(--border); background: var(--surface); display: flex; flex-direction: column; min-width: 0; height: var(--h); }
.static-w.wide { grid-column: 1 / -1; }
.static-w .wbar { display: flex; align-items: center; padding: 6px 10px; border-bottom: 1px solid var(--border); min-height: 36px; }
.static-w .wtitle { display: flex; flex-direction: column; min-width: 0; }
.static-w .wtitle b { font-family: var(--display); font-size: .95rem; }
.static-w .wtitle span { font-size: .74rem; color: var(--muted); }
.static-w .wbody { flex: 1; min-height: 0; display: flex; flex-direction: column; padding: 8px 10px; overflow: auto; }
.static-w .wnote { font-size: .74rem; color: var(--muted); padding: 4px 10px 8px; }
.static-w[data-type=gstory] { height: auto; }
.static-w[data-type=gstory] .wbody { overflow: visible; }
@media (max-width: 760px) {
  .static-board { grid-template-columns: minmax(0, 1fr); }
  .static-w { height: auto; min-height: min(var(--h), 460px); }
  .static-w .wbody { min-height: 300px; }
  .static-w[data-type=gstory] .wbody, .static-w[data-type=gbox] .wbody { min-height: 0; }
}

/* ---------- a player's plays in part of games: the numbers as tiles ---------- */
.pscope-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 8px; }
.pscope-tile { display: flex; flex-direction: column; padding: 6px 8px; background: var(--surface-2); }
.pscope-tile b { font-family: var(--display); font-size: 1.35rem; font-variant-numeric: tabular-nums; }
.pscope-tile span { font-size: .74rem; color: var(--text-2); }

/* ---------- the game board's paired bars (lib/slice.js context) ---------- */
.pair-rows { display: flex; flex-direction: column; gap: 8px; overflow: auto; flex: 1; min-height: 0; padding-right: 4px; }
.pair-row { display: flex; flex-direction: column; gap: 2px; }
.pair-label { font-size: .8rem; font-weight: 600; }
.pair-label .muted { font-weight: 400; }
.pair-bar { display: grid; grid-template-columns: min(40%, calc(var(--pn, 6ch) + 2px)) minmax(0, 1fr) calc(var(--pv, 6ch) + 2px); align-items: center; gap: 6px; font-size: .78rem; }
.pair-name { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pair-track { height: 12px; background: var(--surface-2); position: relative; }
/* The bar's value end rounded and a soft sheen toward it, like the charts' bars (the owner, 2026-10-24: colour and pop); never an outline. */
.pair-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 0 3px 3px 0; }
.pair-fill::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: linear-gradient(90deg, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, .22)); pointer-events: none; }
.pair-val { text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- touch screens: every control big enough to hit with a thumb (QoL, 2026-09-29) ----------
   The glossary ⓘ buttons were 22 px, "3 calls ›" 21 px tall, the graphics maker's ticks 13 px and the
   account page's fields 21 px tall on an iPad and a phone. The ⓘ keeps its size in the text and
   gets an invisible 44 px hit area around it instead. */
@media (pointer: coarse) {
  .jargon-i { position: relative; }
  .jargon-i::after { content: ''; position: absolute; inset: -11px; }
  .tgroup-head .linkish, .demo-pause { min-height: 36px; padding: 6px 10px; }
  .gfx-check input[type=checkbox], input[type=checkbox] { width: 20px; height: 20px; }
  input[type=text], input[type=email], input[type=password], input[type=search], input[type=number], select { min-height: 40px; }
}

/* ---------- an open pop-up scrolls on its own; the page behind it is locked (ui.js) ---------- */
.tip-sheet, .tip-sheet-body, .chart-window, .chart-window *, .inspector, .help-dialog, .help-dialog *, .fb-box { overscroll-behavior: contain; }
.tip-sheet, .chart-window, .help-dialog { touch-action: none; }
.tip-sheet-body, .chart-window .cw-body, .chart-window [class*=body], .inspector, .help-dialog > *, .fb-box { touch-action: pan-x pan-y; -webkit-overflow-scrolling: touch; }
html.scroll-locked { scrollbar-gutter: stable; }

/* The feedback form (public/js/feedback.js openFeedback), in the site's own colours (--brand). It shares the
   shade (.fb-back), so the page behind is locked while it is open (ui.js). */
.fb-box.fb-form-box { max-width: 520px; max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); overflow-y: auto; border-top-color: var(--brand); }
.fb-form { display: flex; flex-direction: column; gap: 6px; }
.fb-field { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-top: 6px; font-weight: 600; font-size: .9rem; }
.fb-opt, .fb-count { font-weight: 400; font-size: .8rem; color: var(--text-2); }
.fb-count { font-variant-numeric: tabular-nums; }
.fb-text, .fb-email { width: 100%; box-sizing: border-box; font: 400 1rem/1.4 var(--font); padding: 8px 10px; border: 1px solid var(--border-strong); background: var(--surface); color: var(--text); border-radius: 0; }
.fb-text { min-height: 120px; resize: vertical; }
.fb-text:focus-visible, .fb-email:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; border-color: var(--brand); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.fb-error { margin: 4px 0 0; color: var(--wrong, #b3261e); font-size: .88rem; font-weight: 600; }
.fb-error[hidden] { display: none; }
.fb-actions { display: flex; gap: 8px; margin-top: 10px; }
.fb-actions .btn { height: 40px; min-width: 96px; justify-content: center; font-size: .9rem; }
.fb-actions .btn.primary { background: var(--brand-btn); border-color: var(--brand-btn); color: #fff; }
.fb-form-box .fb-alt { margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--border); color: var(--text-2); }
.fb-alt-addr { color: var(--text); user-select: all; -webkit-user-select: all; overflow-wrap: anywhere; }
.fb-form-box .fb-copy { font-size: .85rem; padding: 6px 2px; }
@media (max-width: 420px) { .fb-actions .btn { flex: 1; } }
/* The feedback controls are buttons now (they open the form, not a mail program). */
button.beta-pill { background: transparent; cursor: pointer; }
button.tip-strip-feedback { background: none; border: 0; padding: 0; font: inherit; cursor: pointer; }
.site-footer .footer-feedback { color: var(--link); font-size: inherit; text-underline-offset: 2px; text-decoration-thickness: 1px; }
@media (pointer: coarse), (max-width: 700px) { .site-footer .footer-feedback { display: inline-flex; align-items: center; min-height: 32px; padding: 4px 0; } }

/* The header's logo: the same size and spacing as the sister sites' (their .brand-logo), so the
   wordmark sits 8 px from the flask on all four (owner: cosmetically one family, 2026-09-29). */
.brand-logo { width: 30px; height: 30px; display: block; flex: none; margin: -4px -2px -4px 0; }
/* Phones and touch screens: the logo link is big enough to tap, and the header the same height as the
   sister sites' (one family, 2026-09-29). */
@media (pointer: coarse), (max-width: 700px) { .site-header .brand { min-height: 32px; } }
/* On a phone the gate keeps the page gutter: main.flush has no .wrap around it (the sister sites keep 16 px). */
@media (max-width: 600px) { .signin-gate { margin: 32px 16px; } }

/* A refusal that is never a dead end (views/build.js nearBlock, lib/nearest.js): the reason, what Pigskin Lab keeps, and the
   nearest questions as chips that each build a board here, or another Lab's link. */
.ask-msg.err .ask-near { display: flex; flex-direction: column; gap: 4px; }
.ask-near .near-said { color: var(--wrong); }
.ask-near .near-keeps { color: var(--muted); font-size: .76rem; }
.ask-near .near-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.ask-near .near-lead { color: var(--muted); font-size: .76rem; font-weight: 700; }
.ask-near .near-chip { margin: 0; text-decoration: none; max-width: 100%; overflow-wrap: anywhere; text-align: left; color: var(--text); }
.ask-near .near-chip:hover { border-color: var(--brand); color: var(--text); }
.ask-near .near-lab { border-color: var(--brand); }
.ask-near .near-wrong { font-size: .74rem; color: var(--text-2); }
@media (pointer: coarse) { .ask-near .near-chip { min-height: 44px; display: inline-flex; align-items: center; } }
/* The sample under a widget's title (lib/sample.js): games counted and the window's real dates, and a
   small-sample mark in words. The season banner says once that a season is still being played. */
.widget .wtitle .wsample { display: flex; align-items: baseline; gap: 6px; font-size: .7rem; line-height: 1.3; color: var(--muted); font-variant-numeric: tabular-nums; min-width: 0; }
.widget .wtitle .wsample .wsample-n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.wsample .wthin { flex: none; font-style: normal; font-weight: 600; font-size: .7rem; letter-spacing: .02em; color: var(--noise); border: 1px solid currentColor; padding: 0 4px; line-height: 1.35; white-space: nowrap; }
.chart-window .wsample { display: flex; gap: 8px; align-items: baseline; margin-top: 2px; }
.widget.thin-sample .kpi-big { color: var(--text-2); }
.season-banner { margin: 0 0 8px; }
.season-banner.early { border-left-color: var(--noise); }
.sample-line { display: flex; align-items: baseline; gap: 8px; font-size: .78rem; color: var(--muted); font-variant-numeric: tabular-nums; margin: 2px 0 6px; }
.page-head .season-banner { margin: 10px 0 0; }


/* ---------- touch screens: every control is a 44 x 44 target (lane touch, 2026-10-01; INT-02, INT-07, INT-12) ----------
   Measured at 390 px and on a 1024 px touch tablet (user-research/tools/capture/touch/touchcheck.js): most controls on a
   board were under 44 px with a finger: widget copy and tool buttons 24 px, legend switches 20 px, chips 22 px, "Wrong
   answer?" and the other text buttons 18-20 px, buttons 30 px, sortable table headings 29-41 px, inputs and menus 40 px,
   the header's links 30-37 px. Each keeps its drawn size and gets an invisible hit area at least 44 px each way, centred
   on it (::before; no control here draws with it). Neighbours closer than 44 px overlap and the nearer one takes the tap.
   :where() keeps the position rule weaker than any rule that already places a control (absolute, sticky). Chart marks
   get theirs in charts.js (whole rows and columns, end rows reaching the edges, a nearest-point layer for dots and
   spider points). */
@media (pointer: coarse) {
  :where(.btn, .chip, .linkish, .icon-btn, .beta-pill, .brand, .nav a, .legend button, .wtools button, .w-tools button, .w-copy, .w-dup, .w-grip, .seg button, .mic, .crumbs a, .site-footer a, .footer-feedback, .tbl td a, table.stats td a, .tgroup a, .gloss-index a, .tip-sheet .btn, summary) { position: relative; }
  :where(.btn, .chip, .linkish, .icon-btn, .beta-pill, .brand, .nav a, .legend button, .wtools button, .w-tools button, .w-copy, .w-dup, .w-grip, .seg button, .mic, .crumbs a, .site-footer a, .footer-feedback, .tbl td a, table.stats td a, .tgroup a, .gloss-index a, .tip-sheet .btn, summary)::before {
    content: ''; position: absolute; left: 50%; top: 50%; width: max(100%, 44px); height: max(100%, 44px); transform: translate(-50%, -50%);
  }
  /* A thin text control above a block drawn after it ("Wrong answer?" over the board, a legend over its chart): its
     target is lifted over that block so its lower half is not lost. */
  :where(.linkish, .legend button, .chip) { z-index: 1; }
  input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=hidden]), select { min-height: 44px; }
  /* Sortable table headings sit edge to edge: each is 44 px tall instead (a dense row, INT-12). */
  .tbl th, table.stats thead th, table th[tabindex] { height: 44px; }
  /* Controls packed side by side, or inside a box that clips them, cannot borrow room around them (a widget's corner
     clips its copy button; the next zoom button's target would cover this one's edge): they are drawn 44 px instead.
     The header's links, the widget bar's tools and the zoom group. */
  .nav a { line-height: 44px; }
  .widget .wbar, .w-head { min-height: 44px; }
  .widget .wtools button, .w-tools button, .w-copy, .w-dup { width: 44px; height: 44px; }
  .seg { height: auto; }
  .seg button { min-width: 44px; min-height: 44px; }
}
/* Chart lines and words are not targets: a grid line or a value printed over a bar took the tap (or the hover) meant
   for the bar under it. The spider's names keep theirs (their full name shows on hover). */
.widget svg line, .chart-box svg line, .widget svg text:not(.radar-label), .chart-box svg text:not(.radar-label) { pointer-events: none; }
/* A tooltip never taller than the screen: a long one scrolls inside itself (INT-04; place() in charts.js keeps it 8 px
   inside every edge). */
.tooltip { max-height: calc(100vh - 16px); max-height: calc(100dvh - 16px); overflow-y: auto; overscroll-behavior: contain; }
/* The tap sheet (a phone's tooltip) is never cut by the browser's bar or a phone's home indicator: it is measured against
   the visible screen (dvh) and keeps the bottom safe area. */
.tip-sheet-panel { max-height: 82dvh; padding-bottom: env(safe-area-inset-bottom, 0px); }

/* ---------- launch audit, phone / iPad / desktop (lane fix.launch, 2026-10-03) ----------
   A widget's ⓘ sits beside its title, not on a line of its own: on a touch screen the extra line pushed a stat tile's
   number down to 5 px words and cut the last row off charts. The title takes two lines before it is cut with "…". */
.widget .wtitle.jargon { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0; }
.widget .wtitle.jargon > b { flex: 0 1 auto; min-width: 0; max-width: calc(100% - 26px); }
.widget .wtitle.jargon > .jargon-i { flex: none; }
.widget .wtitle.jargon > span, .widget .wtitle.jargon > .wsample { flex: 1 0 100%; min-width: 0; }
.widget .wtitle.jargon > .wsample[hidden] { display: none; }
@media (pointer: coarse) {
  .widget .wtitle b { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow-wrap: anywhere; }
  /* Outside "Edit dashboard" a touch screen shows only the tools that read a widget (open it large, copy it). Settings,
     Duplicate and Remove change the board and come back with Edit dashboard: five 44 px tools left an iPad's half-width
     widget "Brock Purdy: EPA per dropback, every …" and a stat tile no title at all, and pushed its Remove off the edge. */
  .dash-page:not(.editing) .widget .wtools > :is(.w-gear, .w-dup, .w-x) { display: none; }
  /* The graphics maker's Numbers, Finish and Speed groups: 44 px buttons in a 28 px row overlapped the label under them. */
  .gfx-motion-opts .seg { height: auto; flex-wrap: wrap; }
}
/* The board's title on a line of its own whenever the toolbar shares the row with it (up to 1500 px), so
   "Patrick Mahomes vs Josh Allen, 2023" is never cut to "Patrick Mahomes vs …" on a laptop or an iPad. */
@media (max-width: 1500px) {
  .dash-top .title-input { flex: 1 1 100%; max-width: none; order: -2; }
}

/* ---------- arriving with a question: the next step (views/build.js drawIdeas, 2026-10-06) ----------
   A visitor from a Reddit ad or a shared link lands on a board built from their question. Under the Answer's line, right
   above the board: "Now try" and three of the board's own follow-ups as big one-tap chips, then the box for their own
   question and the free allowance in plain words. The 35 ad visitors of 2026-10-05..06 saw their board and none asked a
   second one: the "Try:" chips were 22 px, above the Answer, and the allowance a muted line. The sister sites have the
   same rules, word for word (public/js/ask.js). */
.dash-page .ask-bar .ask-ideas.ask-next { order: 6; display: flex; flex-direction: column; align-items: stretch; gap: 6px; margin: 2px 0 0; padding: 8px 10px; border: 0; border-left: 3px solid var(--brand); background: var(--surface-2); min-width: 0; }
.ask-next .next-lead { font: 700 .8rem/1 var(--display); text-transform: uppercase; letter-spacing: .06em; color: var(--text); }
.ask-next .next-chips { display: flex; flex-wrap: wrap; gap: 6px 8px; min-width: 0; }
.dash-page .ask-bar .ask-next .chip { margin: 0; min-height: 36px; padding: 6px 14px; display: inline-flex; align-items: center; max-width: 100%; border: 1px solid var(--brand); border-radius: 18px; background: var(--surface); color: var(--text); font: 600 .86rem/1.2 var(--font); text-align: left; overflow-wrap: anywhere; }
@media (hover: hover) { .dash-page .ask-bar .ask-next .chip:hover { background: var(--brand-btn); border-color: var(--brand-btn); color: #fff; } }
.dash-page .ask-bar .ask-next .chip:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.ask-next .next-own { margin: 0; font-size: .8rem; line-height: 1.4; color: var(--text-2); }
.ask-next .next-own b { color: var(--text); font-weight: 600; }
.dash-page .ask-bar.guided .ask-left { display: none; }
/* (A follow-up brings its reply to the top of a phone's screen, under nothing; the conversation log of the Answer's
   line shows on a computer only: on a phone it pushed the row and the Answer off the screen.) */
.dash-page .ask-bar.guided :is(.ask-msg, .ask-log) { scroll-margin-top: 72px; }
@media (max-width: 700px) { .dash-page .ask-bar.guided .ask-thread { display: none; } }
@media (max-width: 600px) { .dash-page .ask-bar.guided :is(.ask-msg, .ask-log) { scroll-margin-top: 8px; } }
/* (The one question an arrival asked is said in the reply under it: "You:" shows from the second.) */
.dash-page .ask-bar.guided .ask-log > .you:first-child:nth-last-child(2) { display: none; }
@media (pointer: coarse) { .dash-page .ask-bar .ask-next .chip { min-height: 44px; } }
/* (The tenth free question answered: the row offers the free account, Google first, as buttons a thumb can hit; ui.js
   wallWays. The Ask box's own line at the limit uses the same links, small.) */
.ask-next-wall .next-chips .btn { min-height: 40px; display: inline-flex; align-items: center; gap: 6px; }
@media (pointer: coarse) { .ask-next-wall .next-chips .btn { min-height: 44px; } }
.btn.primary.wall-google .acct-google-g { color: #fff; }

/* ---------- phones and iPads: device pass (2026-10-09) ----------
   The same block ends all four sports sites' site.css.
   1. iOS Safari zooms the whole page into any field whose text is under 16 px, and every field here was
      13.4 px (the Ask box, the search box, every select in the dashboard maker). On a touch screen every
      field is 16 px. The board title is left out: it is 20 px already, and on Pigskin Lab it is an input, so
      this rule (0,4,1) would beat its font (0,2,0) and shrink the board's visible heading to 16 px.
   2. Buttons and header icons were drawn 30 px tall on touch on Pigskin Lab, and small buttons 26 px on all four
      (each already had an invisible 44 px hit area): every .btn and .icon-btn is drawn 44 px tall on touch, small
      ones included. That overrides the siblings' older .btn:not(.small) rule; whether small buttons stay 44 px is
      Mason's call (DEVICES, Open). Two older, more specific rules keep their own size, with their 44 px hit area:
      an empty board's preset buttons on a phone (32 px, .board-empty .presets .btn) and, on the siblings, the
      graphics maker's subject tools (32 x 32, .gfx-subj-tools .btn.small). Header icons and the mic are 44 px wide
      as well (34 x 44 and 32 x 44 on Pigskin Lab), as the siblings already drew them.
   3. A segmented control (Regular / Playoffs / All on the team and game pages) was 340 px wide inside a
      320 px phone and pushed the page sideways; it wraps instead. */
@media (pointer: coarse) {
  input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]):not(.title-input), select, textarea { font-size: 16px; }
  .btn, .icon-btn { min-height: 44px; }
  .icon-btn, .mic { min-width: 44px; }
  .seg { height: auto; }
  .seg button { min-height: 44px; }
}
.controls-row .seg { flex-wrap: wrap; height: auto; max-width: 100%; }
.controls-row .seg button { min-height: 28px; }
@media (pointer: coarse) { .controls-row .seg button { min-height: 44px; } }
/* A 320 px phone: a primary button in a page head ("Open this breakdown in the dashboard maker ›" on a game page) was
   344 px of unbroken text, and a model card's select (16 px on touch) pushed its heading past the edge. Both wrap
   inside the page instead. The wrap rule is outside any media query, so the two after it give a small page-head button
   its 26 px back on a computer and every page-head button its 44 px on touch (without them it beat the touch rule
   above, 0,2,0 over 0,1,0, and drew them 30 px). */
.page-head .btn { white-space: normal; height: auto; min-height: 30px; max-width: 100%; text-align: left; }
.page-head .btn.small { min-height: 26px; }
@media (pointer: coarse) { .page-head .btn, .page-head .btn.small { min-height: 44px; } }
.section-head { flex-wrap: wrap; }
.section-head > span { min-width: 0; max-width: 100%; }
.section-head select { max-width: 100%; }
/* Touch, found by the tap check after the review fixes: the tip bar (on every page until it is closed) and the board
   title. The bar's "Leave a tip" link was 25 px tall with no hit area on all four, and on Pigskin Lab "Beta: send
   feedback" was 19 px and the close 18 x 18 (the siblings already gave those two theirs). The siblings' board title is a
   textarea, which the touch lane's input rule never reached: 34 px tall, where Pigskin Lab's input is 44. fitTitle sets
   its height from scrollHeight, so 9 px top and bottom make one line exactly 44 px with the words centred. */
@media (pointer: coarse) {
  :where(.tip-strip-link, .tip-strip-feedback, .tip-strip-close) { position: relative; }
  :where(.tip-strip-link, .tip-strip-feedback, .tip-strip-close)::before { content: ''; position: absolute; left: 50%; top: 50%; width: max(100%, 44px); height: max(100%, 44px); transform: translate(-50%, -50%); }
  .dash-top textarea.title-input { min-height: 44px; padding-top: 9px; padding-bottom: 9px; }
}

/* The photo credits page (/photos, public/js/views/photos.js): one row per photo, its thumbnail beside who, the file,
   the author and the licence, wrapping on a phone instead of scrolling sideways. */
.photo-notes ul { margin: 0; padding-left: 1.2em; line-height: 1.55; color: var(--text-2); max-width: 72em; }
.photo-credits { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); gap: 10px; margin: 14px 0 24px; }
.photo-credits > p { grid-column: 1 / -1; margin: 0; }
.photo-credit { display: flex; gap: 12px; align-items: flex-start; padding: 10px 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 6px; min-width: 0; }
.photo-credit img, .photo-credit-blank { flex: none; width: 56px; height: 70px; object-fit: cover; object-position: 50% 25%; border-radius: 4px; background: var(--surface-2); }
.photo-credit > div { min-width: 0; overflow-wrap: anywhere; line-height: 1.45; }
.gfx-credit { margin: 6px 0 0; overflow-wrap: anywhere; }

/* Comparison pages (lib/compare.js): written by the server, kept by the app. */
.compare-page section { margin: 22px 0; }
.compare-page h2 { font-family: var(--display); margin: 0 0 8px; font-size: 1.2rem; }
.cmp-table { border-collapse: collapse; width: 100%; max-width: 640px; font-variant-numeric: tabular-nums; font-size: .95rem; border: 1px solid var(--border); background: var(--surface); }
.cmp-table th, .cmp-table td { padding: 6px 10px; border-bottom: 1px solid var(--grid); text-align: right; }
.cmp-table thead th { background: var(--surface-2); }
.cmp-table tbody th { text-align: left; font-weight: 500; color: var(--text-2); }
.cmp-table td.lead { font-weight: 700; background: var(--row-hover); }
.cmp-links { padding-left: 1.2em; line-height: 1.7; }
.cmp-list { columns: 2 280px; }
.compare-page .crumbs { font-size: .85rem; color: var(--muted); margin-bottom: 6px; }

/* Front-page trust line, owner 2026-10-26: Reddit readers called a game graphic "AI slop". Nothing on the site is generated by
   AI, so the home page says so where people look, not in the footer. */
.no-ai { margin: 14px 0 0; padding: 2px 0 2px 10px; border-left: 3px solid var(--brand); font-size: .85rem; line-height: 1.45; color: var(--text); max-width: 46em; }
.no-ai b { font-weight: 700; }
