/* PixFray UI stylesheet: design.css v1 primitives (~/.claude/design) re-themed as a dark tavern
   (warm near-black wood, 1px gold trim, Fraunces headings). Dark always, because this is a streamer
   tool used next to OBS. Bounded vocabulary: use these tokens and classes instead of inventing new
   ones. App classes are at the end. */

/* Fraunces by Undercase Type, SIL OFL 1.1 (public/assets/fonts/FRAUNCES_OFL.txt). Latin subset. */
@font-face {
  font-family: "Fraunces"; font-style: normal; font-weight: 500 700; font-display: swap;
  src: url("/assets/fonts/fraunces-latin.woff2") format("woff2");
}

:root {
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "Cascadia Code", "SF Mono", Consolas, monospace;
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;

  --text-xs: 12px; --text-sm: 14px; --text-md: 16px; --text-lg: 20px;
  --text-xl: 24px; --text-2xl: 32px; --text-3xl: 44px;

  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 24px;
  --space-6: 32px; --space-7: 48px; --space-8: 64px; --space-9: 96px;

  --radius-sm: 4px; --radius: 6px;
  --container: 1120px; --measure: 68ch;

  /* dark tavern: wood near-black, raised planks, bronze rules, gold trim as the one accent */
  --bg: #17110c; --surface: #201710; --raised: #2a2014; --topbar: #110c08;
  --border: #3b2c1d; --border-strong: #6b5234; --trim: #c9a45c;
  --text: #f2e8d5; --text-2: #d6c6a8; --text-3: #b3a184;
  --accent: #c9a45c; --accent-hover: #dcbb78; --accent-soft: #2e2415; --on-accent: #1b130a;
  --positive: #7fc98a; --negative: #f08c7c; --warning: #e3aa4a;
  --chart-1: #c9a45c; --chart-2: #7fa7d9; --chart-3: #d9825b; --chart-4: #a98bc9;
  --chart-5: #7d6c55; --chart-6: #8fbf9a;
  color-scheme: dark;
}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: rgb(201 164 92 / .25); }
a, button, input, select, label, summary, [role="tab"] { touch-action: manipulation; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font: 400 var(--text-md)/1.55 var(--font-sans);
  font-feature-settings: "tnum" 0; -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { margin: 0 0 var(--space-3); line-height: 1.15; font-weight: 650; letter-spacing: 0; font-style: normal; }
h1, h2, h3 { font-family: var(--font-display); text-wrap: balance; }
h1 { font-size: var(--text-3xl); letter-spacing: -0.01em; }
h2 { font-size: var(--text-xl); margin-top: var(--space-7); }
h3 { font-size: var(--text-lg); margin-top: var(--space-5); }
h4 { font-size: var(--text-md); }
p, li { max-width: var(--measure); }
p { margin: 0 0 var(--space-4); }
a { color: var(--accent); text-underline-offset: 2px; }
a:not(.btn):hover { color: var(--accent-hover); }
code, kbd, samp, pre { font-family: var(--font-mono); font-size: 0.92em; }
pre { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--space-4); overflow-x: auto; }
hr { border: 0; border-top: 1px solid var(--border); margin: var(--space-7) 0; }
img, svg, video { max-width: 100%; height: auto; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- layout ---------- */
.page { max-width: var(--container); margin: 0 auto; padding: var(--space-7) var(--space-5) var(--space-9); }
.page-header { padding-bottom: var(--space-5); margin-bottom: var(--space-6); border-bottom: 1px solid var(--border); }
.page-header .subtitle { font-size: var(--text-lg); color: var(--text-2); margin: 0; max-width: var(--measure); }
.meta { font-size: var(--text-sm); color: var(--text-3); margin-top: var(--space-3); }
.section { margin-top: var(--space-7); }
.channel-list { list-style: none; padding: 0; margin: var(--space-5) 0; display: flex; flex-wrap: wrap; gap: var(--space-3); }
.section > h2:first-child { margin-top: 0; }
.stack > * + * { margin-top: var(--space-4); }
.grid-2, .grid-3 { display: grid; gap: var(--space-5); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.split { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: var(--space-6); align-items: start; }
.full { max-width: none; width: 100%; }

/* ---------- blocks ---------- */
.summary { border-left: 3px solid var(--accent); background: var(--accent-soft); padding: var(--space-5); border-radius: 0 var(--radius) var(--radius) 0; }
.summary h2, .summary h3 { margin-top: 0; }
.summary p:last-child { margin-bottom: 0; }
.card { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--space-5); }
.card > :last-child { margin-bottom: 0; }
.muted { color: var(--text-2); }
.small { font-size: var(--text-sm); }
.caveat { font-size: var(--text-sm); color: var(--text-2); border-top: 1px solid var(--border); padding-top: var(--space-3); margin-top: var(--space-4); }
.callout { border: 1px solid var(--border-strong); border-radius: var(--radius); padding: var(--space-4) var(--space-5); }
.callout.warning { border-color: var(--warning); }
.callout.negative { border-color: var(--negative); }

/* ---------- numbers ---------- */
.stat-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
/* dividers drawn as 1px inset lines so they stay correct at any column count */
.stat { padding: var(--space-4) var(--space-5); box-shadow: 1px 0 0 var(--border), 0 1px 0 var(--border); }
.stat .label { font-size: var(--text-sm); color: var(--text-2); }
.stat .value { font-size: var(--text-2xl); font-weight: 650; line-height: 1.2; font-variant-numeric: tabular-nums; margin-top: var(--space-1); }
.stat .delta { font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.up { color: var(--positive); }
.down { color: var(--negative); }
.num { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }

/* ---------- tables ---------- */
.table-wrap { width: 100%; overflow-x: auto; }
table.data { width: 100%; border-collapse: collapse; font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
table.data th, table.data td { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--border); text-align: left; vertical-align: top; }
table.data th { font-weight: 600; color: var(--text-2); border-bottom-color: var(--border-strong); white-space: nowrap; }
table.data td.num, table.data th.num { text-align: right; }
table.data tr.total td { font-weight: 650; border-top: 1px solid var(--border-strong); }
table.data caption { caption-side: top; text-align: left; font-weight: 600; padding-bottom: var(--space-2); }

/* ---------- controls ---------- */
.btn { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 40px; padding: 0 var(--space-4);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--bg); color: var(--text);
  font: 500 var(--text-sm)/1 var(--font-sans); cursor: pointer; text-decoration: none; }
.btn:hover:not(:disabled) { background: var(--surface); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn-primary:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); }
.badge { display: inline-block; padding: 2px var(--space-2); border-radius: var(--radius-sm); border: 1px solid var(--border-strong);
  font-size: var(--text-xs); font-weight: 600; line-height: 1.5; color: var(--text-2); }
.badge.positive { color: var(--positive); border-color: currentColor; }
.badge.negative { color: var(--negative); border-color: currentColor; }
.badge.warning { color: var(--warning); border-color: currentColor; }
label { display: block; font-size: var(--text-sm); font-weight: 600; margin-bottom: var(--space-1); }
input, select, textarea { width: 100%; min-height: 40px; padding: var(--space-2) var(--space-3); font: inherit;
  color: var(--text); background: var(--bg); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); }
.controls { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--space-4);
  padding: var(--space-5); border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }

/* ---------- charts ---------- */
.chart { margin: 0; }
.chart figcaption { font-size: var(--text-sm); color: var(--text-2); margin-top: var(--space-2); }
.chart .title { font-weight: 600; font-size: var(--text-md); margin-bottom: var(--space-2); }
/* .bars: HTML bar comparison whose text never shrinks. Row: <div class="bar-label">…</div>
   <div class="bar [is-key]" style="--v: 84%"><span></span><b>$84,000</b></div>; --v = value / max. */
.bars { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--space-2) var(--space-4); align-items: center; font-size: var(--text-sm); }
.bars .bar-label { color: var(--text-2); }
.bars .bar { display: flex; align-items: center; gap: var(--space-2); }
.bars .bar > span { flex: 0 0 calc(var(--v) * 0.78); height: 20px; background: var(--chart-5); border-radius: 0 2px 2px 0; }
.bars .bar.is-key > span { background: var(--chart-1); }
.bars .bar > b { font-weight: 500; font-variant-numeric: tabular-nums; white-space: nowrap; }
.bars .bar.is-key > b { font-weight: 650; }

/* ---------- responsive + print ---------- */
@media (max-width: 760px) {
  .page { padding: var(--space-6) var(--space-4) var(--space-8); }
  h1 { font-size: var(--text-2xl); }
  .grid-2, .grid-3, .split { grid-template-columns: minmax(0, 1fr); }
  .table-wrap > table.data { width: max-content; min-width: 100%; }
  .table-wrap > table.data td:first-child { min-width: 160px; }
}
@media print {
  .page { max-width: none; padding: 0; }
  .btn, .controls { display: none; }
  .section { break-inside: avoid-page; }
}

/* ---------- PixFray app classes (built from the tokens above) ---------- */
[hidden] { display: none !important; }
/* .table-wrap is positioned so absolutely placed children (sr-only headers) scroll with it instead of widening the page */
.table-wrap { position: relative; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
html { scroll-padding-top: var(--space-4); }
.btn-primary { font-weight: 650; }
.section > h2:first-child { padding-bottom: var(--space-3); border-bottom: 1px solid var(--border); }
.page > .section:first-child { margin-top: 0; }
.grid-2 + p { margin-top: var(--space-5); }
td code { white-space: nowrap; }
.lead { font-size: var(--text-lg); color: var(--text-2); margin: 0; max-width: var(--measure); }

/* top bar: dark plank with a gold rule */
.topbar { border-bottom: 1px solid var(--trim); background: var(--topbar); }
.topbar-inner { max-width: var(--container); margin: 0 auto; padding: var(--space-3) var(--space-5); display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap; }
.topbar .brand { font: 650 var(--text-lg)/1.2 var(--font-display); color: var(--trim); text-decoration: none; }
.topbar nav { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); font-size: var(--text-sm); }
.topbar nav a { color: var(--text-2); text-decoration: none; padding: var(--space-1) 0; border-bottom: 1px solid transparent; }
.topbar nav a:hover { color: var(--text); border-bottom-color: var(--border-strong); }
.topbar nav a[aria-current="page"] { color: var(--text); border-bottom-color: var(--trim); }
.topbar .who { margin-left: auto; display: flex; align-items: center; gap: var(--space-3); font-size: var(--text-sm); color: var(--text-2); }

.page-header h1 { margin-bottom: var(--space-2); }
.toolbar { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
.status { font-size: var(--text-sm); color: var(--text-2); min-height: 1.55em; margin: var(--space-2) 0 0; }
.status.ok { color: var(--positive); }
.status.error { color: var(--negative); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
.btn-danger { color: var(--negative); border-color: var(--negative); }
input[aria-invalid="true"] { border-color: var(--negative); }
.btn-small { min-height: 32px; padding: 0 var(--space-3); font-size: var(--text-xs); }
fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }
legend { font-size: var(--text-sm); font-weight: 600; margin-bottom: var(--space-2); padding: 0; }
input[type="radio"], input[type="checkbox"] { width: auto; min-height: 0; accent-color: var(--accent); }
input[type="range"] { accent-color: var(--accent); padding: 0; }
input[type="color"] { padding: 2px; width: 56px; cursor: pointer; }
.hint { font-size: var(--text-sm); color: var(--text-3); margin: var(--space-1) 0 0; }
.note { font-size: var(--text-sm); color: var(--text-2); border-left: 2px solid var(--trim); padding-left: var(--space-3); margin: var(--space-4) 0 0; }

/* viewer hero: the fighter picker and the framed fighter card sit on a raised plank */
.hero { background: var(--surface); border-bottom: 1px solid var(--border-strong); }
.hero-grid { max-width: var(--container); margin: 0 auto; padding: var(--space-7) var(--space-5);
  display: grid; grid-template-columns: minmax(0, 1fr) 360px; grid-template-areas: "copy card" "pick card"; gap: var(--space-6) var(--space-7); align-items: start; }
.hero-copy { grid-area: copy; }
.hero-copy h1 { margin-bottom: var(--space-3); }
.hero-copy .how { margin-top: var(--space-4); color: var(--text-2); }
.rules { margin: 0 0 var(--space-4); padding-left: var(--space-5); max-width: var(--measure); }
.rules li + li { margin-top: var(--space-1); }
.hero-pick { grid-area: pick; }
/* /start: the overlay demo on a dark stage (the overlay itself is transparent on stream) */
.stage-figure { margin: 0; }
.stage { aspect-ratio: 16 / 9; background: var(--topbar); border: 1px solid var(--border-strong); border-radius: var(--radius); overflow: hidden; }
.stage iframe { display: block; width: 100%; height: 100%; border: 0; color-scheme: normal; }   /* matching the overlay's scheme keeps the frame transparent */
/* wide screens: the demo runs under the copy and the sign-in card across the full width; fighters and nameplates need the room */
.hero-grid:has(.invite-card) { grid-template-areas: "copy card" "pick pick"; }
.invite-card { grid-area: card; }
.invite-card h2 { margin: 0; }
.hero-card { grid-area: card; position: sticky; top: var(--space-4); }
.hero-card .status:empty:has(+ .next-step:not([hidden])) { display: none; }   /* the next step takes the empty status line's place */
.form-stack > * + * { margin-top: var(--space-5); }

/* the fighter card: 1px gold trim with an inner bronze line, like a framed card */
.fighter-card { background: var(--bg); border: 1px solid var(--trim); border-radius: var(--radius); padding: var(--space-5);
  outline: 1px solid var(--border-strong); outline-offset: -6px; display: grid; gap: var(--space-4); }
.fighter-card .toolbar > .btn { flex: 1 1 auto; justify-content: center; }
.fighter-card .status { margin: 0; }
.fighter-card .stat-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.fighter-card .stat { padding: var(--space-3) var(--space-4); }
.fighter-card .stat .value { font-size: var(--text-xl); }

/* character picker */
.char-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: var(--space-3); }
.char-option { position: relative; }
.char-option input { position: absolute; opacity: 0; inset: 0; margin: 0; pointer-events: none; }
.char-option label { display: grid; justify-items: center; gap: var(--space-1); margin: 0; padding: var(--space-3) var(--space-2) var(--space-2);
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); cursor: pointer; font-weight: 500; text-align: center; }
.char-option label:hover { border-color: var(--border-strong); background: var(--raised); }
.char-option input:checked + label { border-color: var(--trim); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--trim); }
.char-option input:focus-visible + label { outline: 2px solid var(--accent); outline-offset: 2px; }
.char-option input:disabled + label { cursor: default; }
.char-option .tag { font-size: var(--text-xs); color: var(--text-3); font-weight: 400; }
canvas.sprite { image-rendering: pixelated; display: block; }
.item-grid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
.item-grid.text-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.text-grid .char-option label { align-content: center; min-height: 56px; }
.pet-thumb { image-rendering: pixelated; vertical-align: middle; object-fit: contain; }
.item-grid .char-option { display: flex; flex-direction: column; }   /* Buy buttons line up under labels of any height */
.item-grid .char-option label { flex: 1; align-content: start; }
.char-option.locked label > span:first-of-type { color: var(--text-2); }
.char-option .title-text { color: var(--trim); font-weight: 650; }
canvas.sprite.sample { width: 64px; height: 48px; }
/* character search and type filters */
.char-filter { display: grid; gap: var(--space-2); margin-bottom: var(--space-3); }
.char-filter input[type="search"] { max-width: 320px; }
.filter-buttons { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.filter-buttons .btn[aria-pressed="true"] { border-color: var(--trim); background: var(--accent-soft); color: var(--text); }
/* builds: one button per slot, then the Buy button for the next slot */
.build-bar { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: stretch; margin-top: var(--space-2); }
.build { display: grid; gap: 2px; min-width: 120px; padding: var(--space-2) var(--space-3); text-align: left; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); color: var(--text); font: inherit; }
.build:hover { border-color: var(--border-strong); background: var(--raised); }
.build[aria-pressed="true"] { border-color: var(--trim); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--trim); }
.build:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.build-bar .buy { align-self: center; width: auto; margin: 0; }
.char-option .buy { width: 100%; margin-top: var(--space-1); white-space: nowrap; }
fieldset .status:empty { display: none; }
/* collapsed picker: the first 12 characters plus the picked one, so hat and upgrades are a short scroll away */
.char-grid.collapsed > .char-option:nth-child(n+13):not(:has(input:checked)) { display: none; }
.more-chars { margin-top: var(--space-3); }
.points-link { font-weight: 600; }
.char-option input:disabled + label { opacity: .7; }

/* upgrades: one row per stat, name and effect on the left, − value + on the right */
.upgrade-list { display: grid; gap: var(--space-2); margin-top: var(--space-2); }
.upgrade { display: grid; grid-template-columns: minmax(0, 1fr) auto 4.5em auto; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-3); border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); }
.upgrade-name { display: grid; }
.upgrade-value { text-align: center; font-variant-numeric: tabular-nums; }
.upgrade .btn { min-width: 36px; justify-content: center; }
#upgrades-help { margin: 0; }

/* the on-stream preview: the fighter as the overlay draws it, on a dark stage like a stream behind a transparent overlay */
.preview { margin: 0; display: grid; overflow: hidden; background: var(--topbar); border: 1px solid var(--border); border-radius: var(--radius); }
.stage-canvas { display: block; width: 100%; height: 230px; }
.preview-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) var(--space-3); border-top: 1px solid var(--border); background: var(--surface); }
.preview-bar .caption { text-align: left; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.preview-bar .btn { flex: 0 0 auto; }
.panel-section { margin-top: var(--space-7); }
#my-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.nameplate { font-size: var(--text-sm); font-weight: 650; padding: 2px var(--space-2); border-radius: var(--radius-sm); background: var(--bg); border: 1px solid var(--border); }
.preview .caption { font: 650 var(--text-md)/1.3 var(--font-display); color: var(--text-2); text-align: center; }
.swatches { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.swatch { width: 36px; height: 36px; border-radius: var(--radius-sm); border: 1px solid var(--border-strong); cursor: pointer; padding: 0; }
.swatch:hover { border-color: var(--text-2); }
.swatch[aria-pressed="true"] { outline: 2px solid var(--trim); outline-offset: 2px; }
.swatch:focus-visible { outline-color: var(--text); }   /* focus is white, selection gold */
/* the custom color well carries a visible "Custom" label so it reads as a control, not a fifth swatch */
.custom-color { display: inline-flex; align-items: center; gap: var(--space-2); margin: 0; min-height: 34px; padding: 2px var(--space-3) 2px 2px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); color: var(--text-2); font-weight: 500; cursor: pointer; }
.custom-color:hover { border-color: var(--trim); color: var(--text); }
.custom-color:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.custom-color input[type="color"] { width: 28px; height: 28px; min-height: 0; padding: 0; border: 0; background: none; }
tr.me td { background: var(--accent-soft); }
td canvas.sprite { display: inline-block; vertical-align: middle; margin-right: var(--space-2); }
tr.podium td:first-child { color: var(--trim); font-weight: 650; }

/* die-roll table: the outcome word carries the meaning, color only repeats it */
.outcome-good { color: var(--positive); font-weight: 600; }
.outcome-bad { color: var(--negative); font-weight: 600; }

/* admin tabs */
.tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--border-strong); margin-bottom: var(--space-6); overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; }
.tabs [role="tab"] { flex: 0 0 auto; min-height: 44px; padding: 0 var(--space-4); border: 1px solid transparent; border-bottom: 0; border-radius: var(--radius) var(--radius) 0 0;
  background: none; color: var(--text-2); font: 600 var(--text-sm)/1 var(--font-sans); cursor: pointer; margin-bottom: -1px; }
.tabs [role="tab"]:hover { color: var(--text); background: var(--surface); }
.tabs [role="tab"][aria-selected="true"] { color: var(--text); background: var(--bg); border-color: var(--trim); border-bottom: 1px solid var(--bg); }
.tabs [role="tab"]:focus-visible { outline-offset: -2px; }
[role="tabpanel"] > :first-child { margin-top: 0; }
details.history { margin-top: var(--space-6); border-top: 1px solid var(--border); padding-top: var(--space-4); }
details.history > summary { cursor: pointer; font: 650 var(--text-lg)/1.3 var(--font-display); }
details.history > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
details.history[open] > summary { margin-bottom: var(--space-4); }
/* stream setup checklist: a status badge, then the step and what to do */
.checklist { list-style: none; padding: 0; margin: 0 0 var(--space-4); border-top: 1px solid var(--border); }
.checklist > li { display: grid; grid-template-columns: 6.5rem 1fr; gap: var(--space-3); padding: var(--space-3) 0; border-bottom: 1px solid var(--border); }
.checklist > li:focus { outline: none; }
.checklist > li:focus-visible, .checklist > li.flash { outline: 2px solid var(--accent); outline-offset: 2px; }
.checklist .badge { justify-self: start; align-self: start; margin-top: 2px; }
.checklist p { margin: var(--space-1) 0 0; max-width: var(--measure); }
.checklist .check { display: flex; align-items: center; gap: var(--space-2); margin: var(--space-2) 0 0; font-weight: 600; }
/* numbered setup steps: each step holds its own actions */
.setup-steps { counter-reset: step; }
.setup-steps > li { counter-increment: step; padding: var(--space-5) 0; }
.setup-steps > li > div { min-width: 0; }
.setup-steps h3 { margin: 0; }
.setup-steps h3::before { content: counter(step) ". "; }
.setup-steps .stack, .setup-steps details { margin-top: var(--space-3); }
.setup-steps ol, .setup-steps ul { margin: 0; padding-left: var(--space-5); max-width: var(--measure); }
.setup-steps details > summary, #troubleshoot details > summary { cursor: pointer; font-weight: 600; padding: var(--space-1) 0; }
.setup-steps details > summary:focus-visible, #troubleshoot details > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.setup-steps details[open] > summary { margin-bottom: var(--space-3); }
#troubleshoot details { border-top: 1px solid var(--border); padding: var(--space-2) 0; }
#troubleshoot details ol, #troubleshoot details p { margin: var(--space-2) 0 0; max-width: var(--measure); }
@media (max-width: 480px) { .checklist > li { grid-template-columns: 1fr; gap: var(--space-1); } }

/* admin */
.hp { display: inline-flex; align-items: center; gap: var(--space-2); }
.hp > .track { display: inline-block; width: 64px; height: 6px; background: var(--border); border-radius: 2px; overflow: hidden; }
.hp > .track > i { display: block; height: 100%; width: var(--v); background: var(--positive); }
.config-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--space-4); }
.config-grid .changed input { border-color: var(--accent); }
.config-group > legend { float: left; width: 100%; margin-bottom: var(--space-3); }
.config-group > legend + * { clear: both; }
.config-group + .config-group { margin-top: var(--space-5); padding-top: var(--space-5); border-top: 1px solid var(--border); }
/* Rules: with unsaved changes the Save bar stays at the bottom of the screen while you scroll the fields */
.config-bar { margin-top: var(--space-4); }
.config-bar.dirty { position: sticky; bottom: 0; z-index: 2; margin: var(--space-4) calc(-1 * var(--space-4)) 0; padding: var(--space-3) var(--space-4); background: var(--bg); border-top: 1px solid var(--border-strong); }
html:has(.config-bar.dirty) { scroll-padding-bottom: 140px; }   /* a focused field scrolls clear of the bar */
.config-bar .status:empty { display: none; }
.mount { border: 1px dashed var(--border-strong); border-radius: var(--radius); padding: var(--space-4); }
.gate { max-width: var(--measure); }

/* page body with a sticky section index (dev page) */
.with-index { display: grid; grid-template-columns: 184px minmax(0, 1fr); gap: var(--space-7); align-items: start; }
.page-index { position: sticky; top: var(--space-4); font-size: var(--text-sm); }
.page-index ol { list-style: none; margin: 0; padding: 0; border-left: 1px solid var(--border-strong); }
.page-index a { display: block; padding: var(--space-2) var(--space-3); color: var(--text-2); text-decoration: none; border-left: 2px solid transparent; margin-left: -1px; }
.page-index a:hover { color: var(--text); border-left-color: var(--trim); }

@media (max-width: 900px) {
  /* narrow screens: the preview card sticks to the top of the screen as a compact bar while you pick in the tabs
     below it, so the fighter and Save are always in view (dashboard.js keeps scroll-padding-top clear of it) */
  .hero-grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "copy" "card" "pick"; padding: var(--space-6) var(--space-4); gap: var(--space-5); }
  .hero-card { top: 0; z-index: 2; margin: 0 calc(-1 * var(--space-4)); padding: var(--space-2) var(--space-4);
    border-width: 0 0 1px; border-radius: 0; outline: 0; box-shadow: 0 4px 12px rgb(0 0 0 / 0.3);
    grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "preview preview" "points save" "status save" "next next"; gap: var(--space-2) var(--space-3); align-items: center; }
  .hero-card .preview { grid-area: preview; }
  .hero-card .stage-canvas { height: 128px; }
  .hero-card .preview-bar { padding: var(--space-1) var(--space-2); }
  .hero-card .toolbar { grid-area: save; max-width: 210px; }
  .hero-card .toolbar > .btn { white-space: normal; line-height: 1.25; padding: var(--space-2) var(--space-3); text-align: center; }
  .hero-card .points-link { grid-area: points; font-size: var(--text-sm); }
  .hero-card .status { grid-area: status; font-size: var(--text-xs); min-height: 0; }
  .hero-card .status:empty { display: none; }
  .hero-card .next-step { grid-area: next; margin: 0; padding: var(--space-1) var(--space-3); font-size: var(--text-xs); }
  .with-index { grid-template-columns: minmax(0, 1fr); gap: var(--space-5); }
  .page-index { position: static; }
  .page-index ol { display: flex; flex-wrap: wrap; gap: var(--space-2); border-left: 0; }
  .page-index a { border: 1px solid var(--border); border-radius: var(--radius-sm); margin: 0; padding: var(--space-1) var(--space-3); }
}
@media (max-width: 760px) {
  .topbar-inner { padding: var(--space-3) var(--space-4); gap: var(--space-2) var(--space-4); }
  .topbar .who { margin-left: 0; width: 100%; }
  .char-grid { grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: var(--space-2); }
  .char-option label { padding: var(--space-2) var(--space-1) var(--space-1); font-size: var(--text-sm); line-height: 1.3; }
  /* phones: tabs wrap into rows so every tab stays visible */
  .tabs { flex-wrap: wrap; gap: var(--space-2); overflow: visible; border-bottom: 0; }
  .tabs [role="tab"] { flex: 1 1 auto; margin: 0; border: 1px solid var(--border); border-radius: var(--radius-sm); }
  .tabs [role="tab"][aria-selected="true"] { border: 1px solid var(--trim); background: var(--accent-soft); }
  /* rank columns are short numbers; skip the 160px first-column minimum on phones */
  .table-wrap > table.data td.num:first-child { min-width: 0; }
  /* tables of explanations wrap their text on phones instead of scrolling it out of view */
  .table-wrap > table.data.prose-table { width: 100%; }
  .table-wrap > table.data.prose-table td:first-child { min-width: 0; }
  table.data.prose-table th { white-space: normal; }
  /* leaderboard: drop the Character column so rank, viewer, Elo, wins and losses fit without sideways scrolling */
  #leaderboard .col-char { display: none; }
  .table-wrap > table#leaderboard { width: 100%; }
  /* mod tables: keep who, state and the row's button on screen; the detail columns are on wider screens */
  table#duels :is(th, td):nth-child(n+3):nth-child(-n+5),
  table#players :is(th, td):nth-child(n+3):nth-child(-n+6),
  table#ranks :is(th, td):nth-child(n+4):nth-child(-n+5) { display: none; }
  .table-wrap > table:is(#duels, #players, #ranks) { width: 100%; }
  .table-wrap > table:is(#duels, #players, #ranks) td:first-child { min-width: 0; }
  .stat .value { font-size: var(--text-xl); overflow-wrap: anywhere; }
  #my-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* short headers on phones: "Dollars ($)" becomes "$" so the ranks table keeps its buttons on screen */
  .wide-only { display: none; }
}

/* empty leaderboard: a sentence on how to get on it, wrapped to the table width */
#leaderboard tr.empty td { white-space: normal; color: var(--text-2); padding: var(--space-4) var(--space-3); }
#leaderboard tr.empty strong { color: var(--text); }

/* StreamElements responses: a short preview without the key, next to the button that copies the whole line */
.reply-preview { font-size: var(--text-xs); color: var(--text-2); white-space: nowrap; }
#se-table input { width: 9rem; }
#se-table .btn { white-space: nowrap; }


/* Stream setup steps: the step list spans the content width so tables can use it; prose and fields stay at reading width */
.checklist > li { max-width: none; }
.setup-steps .stack > :not(.table-wrap) { max-width: var(--measure); }
.badge { white-space: nowrap; }
#se-table th, #se-table td { white-space: nowrap; }
#se-table td:first-child { white-space: normal; min-width: 9rem; }
#se-table td:nth-child(2) { min-width: 10rem; }


/* Characters: the uploader's slot line repeats the usage figure above it; the limits line stays in the form */
#upload-root .upload-usage { display: none; }
.summary .toolbar + .small { margin-top: var(--space-3); }
