:root {
  --ink: #14181f;
  --muted: #5b6470;
  --faint: #8b939e;
  --line: #e2e5e9;
  --line-soft: #eef0f3;
  --surface: #ffffff;
  --canvas: #f5f6f8;
  --accent: #17706b;
  --accent-soft: #e6f1f0;
  --accent-line: #b9d7d4;
  --miss: #b3261e;
  --miss-soft: #fbeceb;
  --warn: #8a6410;
  --warn-soft: #f7efdc;
  --radius: 10px;
  /* Vertical rhythm. Three steps, owned by containers, never by margins on the
     children: a margin on a child dies with the child, which is how a section
     ships flush against its neighbour. Tightened once in the phone block. */
  --gap-page: 18px;
  --gap-block: 12px;
  --gap-bind: 8px;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  background: var(--canvas); color: var(--ink);
  font-family: var(--sans);
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

h1, h2, h3, h4, p, ul, ol, dl { margin: 0; }
h1, h2, h3 { font-weight: 600; letter-spacing: -0.01em; }

button {
  font-family: inherit; font-size: 15px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  border-radius: var(--radius); padding: 12px 16px; cursor: pointer;
  touch-action: manipulation;
}
button:active { transform: scale(0.985); }
button.primary { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
button:disabled { opacity: 0.45; cursor: default; }
button.wide { width: 100%; }
/* The one button that throws away a rehearsal. It should not look like
   the button next to it. */
button.danger { border-color: var(--miss); color: var(--miss); font-weight: 600; }
button.danger:hover { background: var(--miss-soft); }
button.link {
  border: 0; background: none; color: var(--accent); padding: 10px 0 0;
  font-size: 14px; font-weight: 600;
}

input, select, textarea {
  font-family: inherit; font-size: 16px; width: 100%; min-height: 44px;
  padding: 12px 13px; border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--surface); color: var(--ink);
}
textarea { resize: vertical; line-height: 1.45; }
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--accent-line); outline-offset: -1px;
}

.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 14px; padding: 18px;
}
.card.mt, .mt { margin-top: var(--gap-block); }

/* The two spacing primitives. Anything that stacks gets one of these instead of
   a margin on each child, so deleting a child cannot leave a section flush
   against its neighbour. */
.vstack { display: grid; gap: var(--gap-block); align-content: start; }
.card > .mt, .vstack > .mt, .card > .card.mt { margin-top: 0; }
.vbind { display: grid; gap: var(--gap-bind); align-content: start; }
.err:empty, .lede:empty, .empty:empty { display: none; }
.center { text-align: center; }
.card.center { display: grid; gap: var(--gap-block); justify-items: center; }
.pad-lg { padding: 34px 20px; }
.pad-xl { padding: 48px 20px; }
.muted { color: var(--faint); font-size: 14px; }
.empty { font-size: 13px; color: var(--faint); margin: 0; }

.label {
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--faint); font-weight: 600;
}
.lede { font-size: 14px; color: var(--muted); line-height: 1.55; margin: 0; }
.lede.center { text-align: center; }
.err { font-size: 13px; color: var(--miss); margin: 10px 0 0; }
.cnt { font-size: 15px; font-weight: 700; }
.big { font-size: 26px; font-weight: 700; }
.rowb { display: flex; align-items: baseline; justify-content: space-between; }
.two { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* ------------------------------------------------------------ phone client */

.phone-wrap { max-width: 520px; margin: 0 auto; padding: 14px 14px 40px; min-height: 100vh; }
.phone-wrap .card { display: grid; gap: var(--gap-block); align-content: start; }
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 4px 2px 14px;
}
.topbar .t1 { font-size: 15px; font-weight: 600; line-height: 1.25; }
.topbar .t2 { font-size: 12px; color: var(--faint); margin-top: 2px; }
.chip {
  font-size: 12px; font-weight: 600; padding: 6px 11px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent); white-space: nowrap;
}

.fields { display: grid; gap: var(--gap-block); }
.field { display: grid; gap: var(--gap-bind); }
.field > .label { display: block; }
.opts { display: grid; gap: var(--gap-bind); }
.opt {
  display: block; width: 100%; text-align: left; padding: 13px 14px;
  font-size: 15px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); color: var(--ink); line-height: 1.35;
}
.opt[aria-pressed="true"] {
  border-color: var(--accent); background: var(--accent-soft);
  color: var(--accent); font-weight: 600;
}

.hero { font-size: 40px; font-weight: 700; letter-spacing: -0.03em; line-height: 1; }
.hero .pct { font-size: 24px; font-weight: 600; }
.hero-sm { font-size: 26px; font-weight: 700; letter-spacing: -0.02em; }
.bandname { font-size: 16px; font-weight: 600; color: var(--accent); }
.qtext { font-size: 17px; line-height: 1.45; font-weight: 500; }

.progress { margin: 0; height: 8px; border-radius: 4px; background: var(--line-soft); overflow: hidden; }
.progress > i { display: block; height: 100%; width: 0; background: var(--accent); transition: width 0.25s; }

.sheet {
  display: grid;
  grid-template-columns: calc(7ch + 8px) calc(8ch + 8px) calc(8ch + 8px) calc(5ch + 8px) minmax(0, 1fr);
  gap: 3px; font-family: var(--mono); font-size: 11px; user-select: none;
}
.sheet .hd {
  font-family: var(--sans); font-size: 10px; font-weight: 600; color: var(--faint);
  padding: 4px 3px 6px; text-transform: uppercase; letter-spacing: 0.02em; line-height: 1.2;
}
.sheet .cl {
  padding: 12px 4px; min-height: 46px; display: flex; align-items: center;
  background: var(--surface); border: 1px solid var(--line-soft); border-radius: 6px;
  color: var(--ink); white-space: nowrap; line-height: 1.3;
  touch-action: manipulation; cursor: pointer;
}
.sheet .cl.c5 { white-space: normal; word-break: break-word; }
.sheet .cl.hit { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 600; }
.sheet .cl.miss { background: var(--miss-soft); border-color: var(--miss); color: var(--miss); }

.feedback { font-size: 13px; line-height: 1.5; color: var(--muted); min-height: 40px; }
.feedback.good { color: var(--accent); }
.feedback.bad { color: var(--miss); }
.misscount { font-size: 12px; color: var(--faint); }

.answer { border-top: 1px solid var(--line-soft); padding: 13px 0; display: grid; gap: var(--gap-bind); }
.answer:first-child { border-top: 0; }
.a-top { display: flex; align-items: center; gap: 8px; }
.a-mark {
  width: 20px; height: 20px; flex: 0 0 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: #fff; background: var(--accent);
}
.a-mark.no { background: var(--faint); }
.a-label { font-size: 14px; font-weight: 600; }
.a-why { font-size: 13px; color: var(--muted); line-height: 1.55; margin: 0 0 0 28px; }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip-btn {
  font-size: 13px; padding: 9px 12px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
}
.chip-btn.on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }

table.piv { width: 100%; border-collapse: collapse; font-size: 13px; }
table.piv th {
  text-align: left; font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--faint); font-weight: 600; padding: 0 6px 7px; border-bottom: 1px solid var(--line);
}
table.piv td { padding: 9px 6px; border-bottom: 1px solid var(--line-soft); font-variant-numeric: tabular-nums; }
table.piv td.num, table.piv th.num { text-align: right; }
table.piv tr:last-child td { border-bottom: 0; }

.dq { border-top: 1px solid var(--line-soft); padding: 12px 0; }
.dq:first-child { border-top: 0; }
.dq-t { font-size: 14px; font-weight: 500; margin: 0 0 9px; line-height: 1.4; }

.refrow { border-top: 1px solid var(--line-soft); padding: 14px 0;
          display: grid; gap: var(--gap-bind); }
.refrow:first-child { border-top: 0; }
.refq { font-size: 14px; line-height: 1.45; font-weight: 500; }
.stack { display: flex; height: 12px; border-radius: 6px; overflow: hidden; background: var(--line-soft); }
.seg { height: 100%; }
.seg-allow { background: var(--accent); }
.seg-guardrail { background: #d0a43c; }
.seg-block { background: var(--miss); }
.reflg { display: flex; flex-wrap: wrap; gap: 10px; font-size: 12px; color: var(--muted); }
.reflg .votes { color: var(--faint); }
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; }
.dot-allow { background: var(--accent); }
.dot-guardrail { background: #d0a43c; }
.dot-block { background: var(--miss); }
.mine { font-size: 12px; color: var(--accent); font-weight: 600; }
.bysize { display: flex; flex-wrap: wrap; gap: 8px; }
.bschip { font-size: 11px; color: var(--faint); background: var(--canvas); padding: 4px 8px; border-radius: 6px; }

.exrow { border-top: 1px solid var(--line-soft); padding: 10px 0;
         display: grid; gap: var(--gap-bind); }
.exrow:first-child { border-top: 0; }
.ex-t { font-size: 14px; line-height: 1.4; }
.ex-m { font-size: 12px; color: var(--faint); }

.promptbox {
  padding: 12px; background: var(--canvas);
  border: 1px solid var(--line-soft); border-radius: var(--radius);
  font-family: var(--mono); font-size: 11px; line-height: 1.5;
  white-space: pre-wrap; word-break: break-word; max-height: 300px; overflow-y: auto;
}

/* ----------------------------------------------------- phone: teach phases */

/* The idle screen while somebody is talking. One slow dot, nothing to read. */
.idledot {
  width: 12px; height: 12px; border-radius: 50%; margin: 0 auto;
  background: var(--accent); animation: idlepulse 2.4s ease-in-out infinite;
}
@keyframes idlepulse {
  0%, 100% { opacity: 0.25; transform: scale(0.85); }
  50%      { opacity: 1;    transform: scale(1.15); }
}
@media (prefers-reduced-motion: reduce) {
  .idledot { animation: none; opacity: 0.7; }
}

/* ------------------------------------------------------ phone: roster join */

.hits { margin-top: 8px; display: grid; gap: 6px; }
/* NOT .hit: that is the autopsy grid's found-cell state, and reusing the name
   here restyled every found cell to 15px inside a column sized for 11px, which
   clipped the value the moment someone got one right. */
.namehit {
  display: block; width: 100%; text-align: left; padding: 11px 13px;
  font-size: 15px; line-height: 1.3;
}
.pn-co { display: block; font-size: 12px; color: var(--faint); margin-top: 2px; }
.taken { display: block; font-size: 11px; color: var(--warn); margin-top: 3px; font-weight: 600; }
.picked-name {
  padding: 12px 13px; border: 1px solid var(--accent); background: var(--accent-soft);
  border-radius: var(--radius); font-size: 16px; font-weight: 600; color: var(--accent);
}
.picked-name .pn-co { color: var(--accent); opacity: 0.75; font-weight: 500; }

/* An anchor that has to read as a button (the toolkit link opens a new tab,
   so it cannot be a real button). */
a.btn {
  display: block; text-align: center; text-decoration: none;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  border-radius: var(--radius); padding: 12px 16px; font-size: 15px; font-weight: 600;
}

.brows { display: grid; gap: var(--gap-block); }
.brow { display: grid; gap: var(--gap-bind); }
.bh { display: flex; justify-content: space-between; font-size: 13px; }
.bp { font-weight: 700; font-variant-numeric: tabular-nums; }
.bt { height: 10px; background: var(--line-soft); border-radius: 5px; overflow: hidden; }
.bf { height: 100%; background: var(--accent); border-radius: 5px; transition: width 0.35s; }
.bf.cold { background: var(--miss); }

/* ------------------------------------------------------ presenter console */

/* Bottom padding clears the floating stepper. Without it the arrows sit on top
   of the last row of whatever board is on screen. */
.pres > .mt { margin-top: 0; }
.pfoot { font-size: 12px; color: var(--faint); }
.h-sub { font-size: 13px; color: var(--faint); }
.deepline { font-size: 15px; line-height: 1.6; }
.pres {
  padding: 16px 20px 108px; max-width: 1640px; margin: 0 auto;
  display: grid; gap: var(--gap-page); align-content: start;
}
.pres-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.phasebar { display: flex; gap: 6px; flex-wrap: wrap; }
.stagebtn {
  padding: 9px 16px; font-size: 13px; font-weight: 600; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted); min-height: 44px;
}
.stagebtn.on { background: var(--accent); border-color: var(--accent); color: #fff; }

.console { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: var(--gap-page); align-items: start; }
#stage { display: grid; gap: var(--gap-block); align-content: start; min-width: 0; }
#stage > .card.mt, #stage > .mt { margin-top: 0; }
.rail { padding: 12px; position: sticky; top: 14px; display: grid; gap: var(--gap-block); align-content: start; }
.rail-head { display: flex; justify-content: space-between; align-items: baseline; padding: 2px 6px 10px; }
.rail-clock { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.rail-i {
  display: flex; align-items: center; gap: 8px; padding: 8px 6px;
  border-radius: 6px; cursor: pointer; border-left: 2px solid transparent;
}
.rail-i:hover { background: var(--canvas); }
.rail-i.on { background: var(--accent-soft); border-left-color: var(--accent); }
.rail-i.on .rl { color: var(--accent); font-weight: 600; }
.rail-n { width: 16px; font-size: 11px; color: var(--faint); font-variant-numeric: tabular-nums; }
.rl { font-size: 13px; flex: 1; line-height: 1.25; }
.rsub { display: block; font-size: 11px; color: var(--faint); font-weight: 400; margin-top: 1px; }
.rm { font-size: 11px; color: var(--faint); font-variant-numeric: tabular-nums; }
.rail-i.done .rl, .rail-i.done .rsub, .rail-i.done .rm { color: var(--faint); }
.rail-foot { padding-top: 12px; border-top: 1px solid var(--line-soft); text-align: center;
             display: grid; gap: var(--gap-bind); }
.qr-mini img { width: 100%; max-width: 150px; height: auto; image-rendering: pixelated; }
.qrurl { font-family: var(--mono); font-size: 11px; font-weight: 600; word-break: break-all; }

.metrics { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.metric { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; }
.metric .m-v { font-size: 28px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.1; }
.metric .m-l {
  font-size: 11px; color: var(--faint); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em; margin-top: 4px;
}

.grid-2 { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 14px; align-items: start; }

.bars { display: grid; gap: var(--gap-block); }
.bar-row { display: grid; gap: var(--gap-bind); }
.bar-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; font-size: 13px; }
.bar-head .bl { font-weight: 500; }
.bar-track { height: 12px; background: var(--line-soft); border-radius: 6px; overflow: hidden; }
.bar-fill { height: 100%; background: var(--accent); border-radius: 6px; transition: width 0.4s; }
.bar-fill.cold { background: var(--miss); }
.bar-note { font-size: 12px; color: var(--faint); line-height: 1.45; }

table.lb { width: 100%; border-collapse: collapse; font-size: 14px; table-layout: auto; }
table.lb th {
  text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--faint); font-weight: 600; padding: 0 8px 8px; border-bottom: 1px solid var(--line);
}
table.lb td { padding: 9px 8px; border-bottom: 1px solid var(--line-soft); font-variant-numeric: tabular-nums; }
table.lb tr:last-child td { border-bottom: 0; }
table.lb td.num, table.lb th.num { text-align: right; }
table.lb tr.total td { border-top: 2px solid var(--line); font-weight: 700; border-bottom: 0; }

.dist { display: flex; align-items: flex-end; gap: 5px; height: 110px; }
.d-col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end;
         align-items: center; gap: var(--gap-bind); height: 100%; }
.d-bar { width: 100%; background: var(--accent); border-radius: 4px 4px 0 0; min-height: 2px; transition: height 0.4s; }
.d-n { font-size: 11px; color: var(--faint); font-variant-numeric: tabular-nums; }
.d-v { font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums; }

.bigclock { font-size: 92px; font-weight: 700; letter-spacing: -0.04em; line-height: 1; font-variant-numeric: tabular-nums; }
.bigq { font-size: 24px; line-height: 1.35; font-weight: 500; }
.pq { font-size: 14px; line-height: 1.5; color: var(--muted); }

.specrow { display: flex; align-items: center; gap: 12px; border-top: 1px solid var(--line-soft); padding: 11px 0; }
.specrow:first-child { border-top: 0; }
.specrow.picked { background: var(--accent-soft); border-radius: 8px; padding-left: 10px; padding-right: 10px; }
.spec-b { flex: 1; min-width: 0; }
.spec-t { font-size: 14px; line-height: 1.4; }
.spec-m { font-size: 12px; color: var(--faint); }
.spec-a { display: flex; gap: 6px; flex: 0 0 auto; }
.spec-a button { padding: 8px 12px; font-size: 13px; }

.card.warn { border-color: var(--warn); background: var(--warn-soft); }

/* ------------------------------------------------------- console: the deck */

.stagebtn.teach { border-style: dashed; }
.stagebtn.teach.on { border-style: solid; }

.slide {
  --gap-page: 30px; --gap-block: 16px; --gap-bind: 8px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  padding: 46px 52px 22px; min-height: 460px;
  display: flex; flex-direction: column; justify-content: space-between;
  gap: var(--gap-page);
}
.slide-body { flex: 1; display: grid; gap: var(--gap-page); align-content: start; }
.slide-head { display: grid; gap: var(--gap-block); }
.slide-t { font-size: 40px; line-height: 1.15; letter-spacing: -0.02em; }
.slide-lead { font-size: 21px; line-height: 1.45; color: var(--muted); margin: 0; max-width: 34em; }
.slide-pts { margin: 0; padding-left: 24px; display: grid; gap: var(--gap-block); }
.slide-pts li { font-size: 21px; line-height: 1.5; }

/* Words and figure side by side, both centred against each other. A 16:9
   projector is far wider than a comfortable reading measure, so a single
   column of text leaves half the wall empty and makes the lines break early
   and look cramped. Splitting it uses the width without stretching any line
   past about 30em. */

.slide-main.split {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 44px; align-items: center;
}
.slide-main.split .slide-pts { margin: 0; }
.slide-main.split .g-cols { flex-direction: column; }
.slide-fig { min-width: 0; }

/* A slide whose whole body is a figure. It gets the full width, and a long
   definition list runs in two columns so it fills a 16:9 wall instead of
   sitting in a narrow strip with the right half empty. */
.slide-main.figonly .g-bars { max-width: none; }
.slide-main.figonly .g-terms {
  grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr);
  column-gap: 30px;
}
@media (max-width: 1180px) {
  .slide-main.figonly .g-terms { grid-template-columns: auto minmax(0, 1fr); }
}
body.screenmode .slide-main.figonly .g-terms {
  column-gap: clamp(20px, 2.6vw, 54px);
}
body.screenmode .slide-main.figonly .g-terms dt { font-size: clamp(16px, 2.7vh, 32px); }
body.screenmode .slide-main.figonly .g-terms dd { font-size: clamp(15px, 2.5vh, 30px); }

/* The room's own answers, sitting on the teaching slide. */
.livebox {
  border: 1px solid var(--accent-line); background: var(--accent-soft);
  border-radius: 12px; padding: 20px 22px;
  display: grid; gap: var(--gap-block); align-content: start;
}
.live-h {
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.09em; color: var(--accent);
}
.live-q { font-size: 16px; line-height: 1.4; }
.live-cap { font-size: 13px; color: var(--muted); }
.livebox .bar-row:last-child { margin-bottom: 0; }
.slide-img { display: block; width: 100%; height: auto; border-radius: 8px; }

/* Slide diagrams. Three shapes, all built from the same tokens as the rest of
   the console so a slide never looks like it came from somewhere else. */
.g-steps { display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap; }
.g-step {
  flex: 1 1 0; min-width: 120px; padding: 16px 18px;
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  border-radius: 10px; font-size: 17px; line-height: 1.35; color: var(--ink);
  display: flex; align-items: center;
}
.g-arrow { align-self: center; color: var(--accent); font-size: 22px; flex: 0 0 auto; }

.g-cols { display: flex; gap: 12px; flex-wrap: wrap; }
.g-col {
  flex: 1 1 0; min-width: 150px; padding: 16px 18px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--surface);
  display: grid; gap: var(--gap-bind); align-content: start;
}
.g-h {
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em;
  font-weight: 600; color: var(--accent);
}
.g-b { font-size: 16px; line-height: 1.45; color: var(--ink); }
.g-b.mono { font-family: var(--mono); font-size: 13px; line-height: 1.6; white-space: nowrap; }

/* A small bar chart on a slide. Same bones as the dashboard bars, sized to be
   read from the back of the room. */
.g-bars { max-width: 640px; display: grid; gap: var(--gap-block); }
.g-bar { display: grid; gap: var(--gap-bind); }
.g-bar-head {
  display: flex; justify-content: space-between; gap: 14px; font-size: 16px;
}
.g-bar-head b { font-variant-numeric: tabular-nums; }
.g-bar-track { height: 14px; background: var(--line-soft); border-radius: 7px; overflow: hidden; }
.g-bar-fill { height: 100%; background: var(--accent); border-radius: 7px; }
.g-bar-fill.soft { background: var(--accent-line); }
body.screenmode .g-bars { max-width: 900px; }
body.screenmode .g-bar-head { font-size: clamp(15px, 2.2vh, 21px); }
body.screenmode .g-bar-track { height: clamp(12px, 2.2vh, 20px); }

body.screenmode .g-step {
  font-size: clamp(15px, 2.2vh, 21px); padding: clamp(11px, 2.2vh, 20px) 22px;
}
body.screenmode .g-b { font-size: clamp(15px, 2.1vh, 20px); }
body.screenmode .g-b.mono { font-size: clamp(12px, 1.7vh, 16px); }

.slide-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding-top: 16px; border-top: 1px solid var(--line-soft);
}
.slide-n { font-size: 12px; color: var(--faint); font-variant-numeric: tabular-nums; }
.sdots { display: flex; gap: 6px; flex: 1; justify-content: center; }
.sdot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--line);
  cursor: pointer; transition: background 0.2s;
}
.sdot.on { background: var(--accent); }
.slide-nav { display: flex; gap: 8px; }
.slide-nav button { padding: 9px 18px; font-size: 14px; }
.pnote { font-size: 15px; line-height: 1.55; }

/* Screen mode is the projector: the deck takes the whole width and the run
   order rail gets out of the way. */
body.screenmode.teaching .console { grid-template-columns: minmax(0, 1fr); }
body.screenmode.teaching .rail { display: none; }
/* Sized off the viewport height, not off a fixed number. A five-bullet slide at
   27px runs off the bottom of a 760px screen, and the bottom of the screen is
   where the last bullet lives. Clamped so it still reads big on a real
   projector and never shrinks below legible on a laptop. */
body.screenmode .slide {
  --gap-page: clamp(18px, 3.4vh, 34px); --gap-block: clamp(10px, 2.2vh, 24px);
  --gap-bind: clamp(6px, 1.2vh, 12px);
  min-height: 72vh; padding: clamp(28px, 5vh, 60px) 68px 26px;
}
/* Centred down the page. Left to itself the content hugged the top and left a
   third of the wall empty underneath, which is most of what made it look
   unfinished. */
body.screenmode .slide-body { align-content: center; }
body.screenmode .slide-t { font-size: clamp(30px, 5.4vh, 56px); max-width: 20em; }
body.screenmode .slide-lead { font-size: clamp(17px, 2.7vh, 27px); max-width: 40em; }

body.screenmode .slide-main.split { gap: clamp(28px, 4vw, 64px); }
body.screenmode .slide-pts { gap: var(--gap-block); }
body.screenmode .slide-pts li { font-size: clamp(17px, 2.9vh, 31px); line-height: 1.42; }
/* Cap the LINE, not the list. max-width on the ul resolves against the ul's own
   16px font, not the 31px of the bullets inside it, so a "44em" cap was landing
   at about 700px and wrapping every line less than half way across the wall.
   ch on the li is measured in the type actually being read. */
body.screenmode .slide-main:not(.split) .slide-pts { max-width: none; }
body.screenmode .slide-pts li { max-width: 62ch; }
body.screenmode .livebox { padding: clamp(16px, 2.6vh, 26px) clamp(18px, 2vw, 28px); }
body.screenmode .live-h { font-size: clamp(11px, 1.5vh, 15px); }
body.screenmode .live-q { font-size: clamp(15px, 2.2vh, 21px); }
body.screenmode .live-cap { font-size: clamp(12px, 1.7vh, 17px); }
body.screenmode .livebox .bar-head { font-size: clamp(14px, 2.1vh, 20px); }

/* ---------------------------------------------------- console: showcase Q&A */

.qlist { border-top: 1px solid var(--line-soft); padding-top: 4px; }
.qrow { font-size: 14px; line-height: 1.45; padding: 9px 0; border-bottom: 1px solid var(--line-soft); }
.qrow:last-child { border-bottom: 0; }
.qt { font-size: 11px; color: var(--faint); font-weight: 600; margin-right: 8px;
      text-transform: uppercase; letter-spacing: 0.04em; }

body.screenmode .hide-on-screen { display: none !important; }
body.screenmode .metric .m-v { font-size: 42px; }
body.screenmode table.lb { font-size: 17px; }
body.screenmode .bar-head { font-size: 16px; }
body.screenmode .refq { font-size: 17px; }
body.screenmode .spec-t { font-size: 17px; }
body.screenmode .qrow { font-size: 17px; }

/* --------------------------------------------- phone: terms check (basics) */

/* Right and wrong stay legible after the buttons disable, or the feedback
   lands on three greyed-out options nobody can read. */
.opts .opt:disabled { opacity: 1; }
.opts .opt.right {
  border-color: var(--accent); background: var(--accent-soft); color: var(--accent);
  font-weight: 600;
}
.opts .opt.wrong {
  border-color: var(--miss); background: var(--miss-soft); color: var(--miss);
}

/* The five kinds of defect, above the grid the whole time. */
.kinds { margin: 0; padding-left: 20px; display: grid; gap: 7px; }
.kinds li { font-size: 14px; line-height: 1.35; }
.kinds li b { font-weight: 600; }
.kinds li span { display: block; color: var(--muted); }
.a-kind {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--accent);
}

/* Hallucination: what the AI was given, before what it answered. Without this
   the exercise is a guess about tone. */
.hgiven {
  margin-top: 14px; padding: 11px 13px; border-radius: var(--radius);
  background: var(--canvas); border: 1px solid var(--line-soft);
  font-size: 14px; line-height: 1.4;
}
.hgiven .hg-l {
  display: block; font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--faint); margin-bottom: 3px;
}
.briefsteps { margin: 0; padding-left: 20px; display: grid; gap: 9px; }
.briefsteps li { font-size: 15px; line-height: 1.45; }

/* --------------------------------------------------- phone: pulse ladders */

.ladq { font-size: 14px; color: var(--muted); line-height: 1.4; }
.rungs { display: grid; gap: var(--gap-bind); }
.rung {
  display: flex; align-items: flex-start; gap: 10px; width: 100%; text-align: left;
  padding: 11px 12px; font-size: 14px; line-height: 1.35; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
}
.rung .rn {
  flex: 0 0 auto; width: 19px; height: 19px; border-radius: 50%; font-size: 11px;
  font-weight: 700; display: grid; place-items: center; color: var(--faint);
  border: 1px solid var(--line);
}
.rung.on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.rung.on .rn { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ------------------------------------------------- phone: prompt writing */

/* Step numbers, so a numbered form reads as steps and not as one wall. */
.stepn-in {
  display: inline-grid; place-items: center; width: 17px; height: 17px;
  border-radius: 50%; background: var(--accent); color: #fff; font-size: 10px;
  font-weight: 700; margin-right: 7px; vertical-align: middle;
}

/* ------------------------------------------------- console: prompt lab wall */

.promptwall {
  padding: 16px 18px; background: var(--canvas);
  border: 1px solid var(--line-soft); border-radius: var(--radius);
  font-family: var(--mono); font-size: 13px; line-height: 1.55; white-space: pre-wrap;
}
.promptwall.lazy { color: var(--muted); font-style: italic; }
.promptbox.big { font-size: 15px; line-height: 1.6; }
body.screenmode .promptwall { font-size: 18px; line-height: 1.6; }

/* Score spread, 0 to 5. A single average hides a room where half wrote three
   pieces and half wrote all five. */
.dist { display: flex; align-items: flex-end; gap: 8px; height: 130px; }
.dcol { flex: 1 1 0; display: flex; flex-direction: column; align-items: center;
        justify-content: flex-end; height: 100%; gap: var(--gap-bind); }
.dbar { width: 100%; min-height: 2px; background: var(--accent); border-radius: 4px 4px 0 0; }
.dcol .dn { font-size: 12px; font-weight: 700; }
.dcol .dl { font-size: 11px; color: var(--faint); }

/* One prompt on the console list: score chip, the text, what it is missing. */
.spec-t { flex: 1 1 auto; font-size: 14px; line-height: 1.4; min-width: 0;
          display: grid; gap: var(--gap-bind); }
.spec-t b { font-weight: 600; }
.spec-m { display: block; color: var(--faint); font-size: 12px; }

/* Reusable pager. One per surface, never per table. */
.pager {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  font-size: 13px; color: var(--muted);
}
.pager button { padding: 9px 14px; font-size: 13px; min-height: 44px; }
.blockrows { display: grid; gap: var(--gap-block); }
.blockrow { display: grid; gap: var(--gap-bind); }
.blk-h {
  display: flex; justify-content: space-between; font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--faint);
  margin-bottom: 8px;
}

/* -------------------------------------------------- console: step-through */

/* Two arrows, always in the same place, that walk the run order. The presenter
   holds a clicker; this is what the clicker is pressing. */
.stepper {
  position: fixed; right: 18px; bottom: 18px; display: flex; align-items: center;
  gap: 8px; padding: 8px; background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: 0 6px 20px rgba(15, 20, 30, 0.12); z-index: 40;
}
.stepper button { font-size: 18px; line-height: 1; padding: 10px 16px; min-height: 44px; }
.stepper button:disabled { opacity: 0.35; }
.stepn { text-align: center; min-width: 44px; font-variant-numeric: tabular-nums; }
.stepn b { display: block; font-size: 15px; }
.stepn span { display: block; font-size: 10px; color: var(--faint); }

.fullhint {
  position: fixed; right: 18px; bottom: 18px; padding: 8px 12px; z-index: 40;
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  font-size: 12px; color: var(--muted); transition: opacity 0.6s;
}
.fullhint.gone { opacity: 0; pointer-events: none; }

/* ------------------------------------------------------- the projector view */

/* Everything the audience should never see is either absent from the payload
   or gone from the layout here. The rail carries the clock and the run order,
   which is the presenter's business and nobody else's. */
body.audience .rail { display: none; }
body.audience .console { grid-template-columns: minmax(0, 1fr); }
body.audience .pres { max-width: none; padding: 0; }
body.audience .stepper { display: none; }
/* No header on the wall. The module name and its one-liner are presenter
   furniture; a slide carries its own title. */
body.audience .pres-top { display: none; }
body.audience .slide { min-height: 96vh; border: 0; border-radius: 0; }
body.audience { cursor: default; }

/* The wall. Fills the projector and sits in the optical middle: a slide box
   sized to its content left a third of the screen as empty canvas underneath,
   which is what read as unfinished (MJ 2026-08-20). */
.slide.aud, body.screenmode .slide.aud {
  --gap-page: clamp(18px, 3.8vh, 38px);
  display: flex; flex-direction: column; justify-content: center;
  min-height: 88vh; padding: clamp(34px, 5vh, 60px) clamp(40px, 4vw, 72px);
}
.slide.aud > .slide-body { flex: 0 1 auto; }
.slide.aud .slide-t { font-size: clamp(32px, 6vh, 56px); }
.slide.aud .slide-lead { font-size: clamp(17px, 2.9vh, 27px); max-width: 46em; }
.aud-body { display: grid; gap: var(--gap-page); align-content: start; }
.slide.center-slide { display: grid; place-content: center; text-align: center; }

/* Big numbers, three at most. A wall can hold three numbers; a dashboard row
   of eight is something you read on a laptop. */
.audstats { display: flex; gap: 56px; flex-wrap: wrap; }
.audstats b {
  display: block; font-size: 62px; line-height: 1; letter-spacing: -0.03em;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.audstats span {
  display: block; margin-top: 8px; font-size: 15px; text-transform: uppercase;
  letter-spacing: 0.09em; color: var(--muted);
}

.audbars .bars { gap: var(--gap-block); }
.audbars .bar-head { font-size: 21px; }
.audbars .bar-track { height: 16px; }
.audbars .bar-note { font-size: 15px; line-height: 1.45; }

.audbig { font-size: 30px; line-height: 1.45; margin: 0; max-width: 30em; }
.audbig b { color: var(--accent); }

/* Join screen: the code has to be readable from the back of a ballroom. */
.joingrid {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 60px;
  align-items: center;
}
.qrbig img { width: 300px; height: 300px; display: block; }
.qrbig .qrurl {
  font-family: var(--mono); font-size: 14px; color: var(--muted); margin-top: 12px;
  text-align: center; word-break: break-all; max-width: 300px;
}
.agenda-h {
  font-size: 14px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--faint);
}
.agenda {
  margin: 0; padding: 0; list-style: none; columns: 3; column-gap: 44px;
}
.agenda li {
  break-inside: avoid; margin-bottom: 12px; font-size: 17px; line-height: 1.3;
  padding-left: 14px; border-left: 2px solid var(--accent-line);
}
.agenda li b { display: block; font-weight: 600; }
.agenda li span { color: var(--muted); font-size: 15px; }

/* Padded panels, not naked blocks. A block sitting flush against its
   neighbour with no inset reads as an unfinished page on a projector
   (MJ 2026-08-20: "blocks with no outer padding, which should never be the
   case"). Spacing is owned by the grid gap here, never by a margin on the
   child, so deleting a wrapper cannot ship a flush section. */
.auddemos { display: grid; gap: var(--gap-page); }
.auddemo {
  padding: 24px 28px; border: 1px solid var(--line);
  border-left: 4px solid var(--line); border-radius: 14px;
  background: var(--surface); display: grid; gap: var(--gap-bind); align-content: start;
}
.auddemo.live { border-left-color: var(--accent); }
.auddemo .auddemo .stack { margin: 0; }
.ad-t { font-size: 24px; font-weight: 600; }
.auddemo .stack { height: 20px; }
.auddemo .reflg { font-size: 16px; }

/* The five checks, on the wall while the room writes. */
.audchecks { margin: 0; padding-left: 26px; display: grid; gap: var(--gap-block); }
.audchecks li { font-size: clamp(16px, 2.3vh, 23px); line-height: 1.35; }
.audchecks li b { display: block; font-weight: 600; }
.audchecks li span { color: var(--muted); font-size: 0.82em; }
.audrefs .refq { font-size: 22px; }
.audrefs { display: grid; gap: var(--gap-page); }
.audrefs .reflg { font-size: 16px; }
.audjobs { display: grid; gap: 12px; }
.audjob { font-size: 22px; line-height: 1.35; }
.audjob span { color: var(--faint); font-size: 15px; margin-left: 10px; }
.audvs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 34px; }
.audvs-h {
  font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--faint); margin-bottom: 10px;
}
.audvs .promptwall { margin-top: 0; font-size: clamp(13px, 1.9vh, 18px); }

/* A term against its meaning. Ten one-line definitions as bullets is the wall
   of words; two columns reads at projector distance. */
.g-terms { margin: 0; display: grid; grid-template-columns: auto 1fr;
           gap: 10px 20px; align-items: baseline; }
.g-terms dt { font-weight: 600; font-size: clamp(14px, 2vh, 21px); white-space: nowrap; }
.g-terms dd { margin: 0; color: var(--muted); font-size: clamp(13px, 1.9vh, 20px);
              line-height: 1.4; }
body.screenmode .g-terms { gap: clamp(9px, 1.6vh, 18px) clamp(18px, 2vw, 34px); }
@media (max-width: 700px) {
  .g-terms { grid-template-columns: 1fr; gap: 4px 0; }
  .g-terms dt { margin-top: 8px; }
}

@media (max-width: 1180px) {
  .stagebtn, .slide-nav button, .chip-btn { min-height: 44px; }
  .console { grid-template-columns: 1fr; }
  .rail { position: static; }
  .grid-2 { grid-template-columns: 1fr; }
  .metrics { grid-template-columns: repeat(2, 1fr); }
  .slide { padding: 30px 26px 18px; min-height: 380px; }
  .slide-t { font-size: 30px; }
  .slide-lead, .slide-pts li { font-size: 18px; }
}

/* Phones. Desktop is untouched: every rule for a small screen lives inside a
   media block. Floor is 44px on anything you tap and 16px on anything you type
   into, measured in the browser at 375px, not eyeballed. */
@media (max-width: 767px) {
  .phone-wrap .chip-btn, .phone-wrap button.link {
    min-height: 44px; display: inline-flex; align-items: center;
  }
  .phone-wrap .chips { gap: 8px; }

  /* The console is a laptop dashboard and the control room at /admin is the
     surface built for a handset. But MJ does open /present on his phone, and
     when he does it has to be usable rather than a sideways scroll: the top
     bar and the phase chips wrap, the rail drops under the stage, every table
     scrolls inside its own card, and nothing you tap is under 44px. */
  .pres { padding: 12px 12px 108px; }
  .pres-top { flex-wrap: wrap; gap: 10px; }
  .pres-top > div:last-child { flex-wrap: wrap; }
  .pres-top button, .pres-top .btn { min-height: 44px; }
  .phasebar { flex-wrap: wrap; width: 100%; }
  .stagebtn { min-height: 44px; }
  .stepper button { min-height: 44px; min-width: 56px; }
  .console { grid-template-columns: minmax(0, 1fr); }
  .rail { position: static; order: 2; }
  #stage { order: 1; min-width: 0; }
  /* minmax(0, 1fr), not 1fr: a plain 1fr track refuses to shrink below its
     content and pushes the whole page sideways by a pixel or two. */
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-2 { grid-template-columns: minmax(0, 1fr); }
  .pres .card, .pres .metric { max-width: 100%; min-width: 0; }
  /* Wide tables scroll inside the card instead of pushing the page sideways. */
  .card table.lb, .card table.piv { display: block; overflow-x: auto; }
  .slide { padding: 20px 16px 14px; min-height: 0; }
  .slide-t { font-size: 24px; }
  .slide-lead, .slide-pts li { font-size: 16px; }
}

@media (max-width: 400px) {
  .phone-wrap { padding-left: 10px; padding-right: 10px; }
  .phone-wrap .card { padding: 14px; }
}

/* ---------------------------------------------------------- table talk */

/* Two minutes of people talking to each other. Both screens carry the question
   and nothing else, because the whole point is that nobody is reading. */
.talkq { font-size: 21px; line-height: 1.35; font-weight: 600; }
.talk-lab {
  font-size: 13px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--accent);
}
body.screenmode .talk-lab { font-size: clamp(12px, 1.7vh, 17px); }

/* The demo currently on stage, on the console and on the wall. */
.auddemo.live .ad-t { color: var(--accent); }
.nowtag {
  margin-left: 12px; font-size: 0.55em; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--accent); vertical-align: middle;
}

/* ------------------------------------------------------------ gate + admin */

/* Password gate. One card, centred, and the input is 16px so iOS does not zoom
   and leave a presenter typing a password they cannot see. */
.gatewrap {
  min-height: 100vh; padding: 24px 16px;
  display: grid; place-content: center;
  /* An explicit column, not justify-items: a max-content column sized each
     card to its own longest line, so the two gates came out different widths. */
  grid-template-columns: min(380px, 100%);
}
.gatecard { display: grid; gap: var(--gap-block); }
.gatehead { display: grid; gap: var(--gap-bind); }
.gatehead h1 { font-size: 22px; }
.gatehead .lede { margin: 0; }
.gatecard .err { margin: 0; }

/* The control room. Built for an iPad in portrait, works down to 375px.
   Vertical spacing is owned by this grid, never by margins on the children. */
.adminwrap {
  max-width: 720px; margin: 0 auto; padding: 16px 16px 48px;
  display: grid; gap: 12px; align-content: start;
}
.adminwrap > .card.mt, .adminwrap > .mt, .adminwrap > .lede { margin-top: 0; }
.adminwrap .card { display: grid; gap: var(--gap-block); align-content: start; }
.adminwrap button, .adminwrap .btn { min-height: 44px; }
.adm-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; }
.adm-clock { text-align: right; line-height: 1.1; }
.adm-clock b { display: block; font-size: 30px; font-variant-numeric: tabular-nums; }
.adm-clock span { font-size: 12px; color: var(--faint); }

/* Two big targets. Driven mid-sentence with one thumb, so nothing here is
   smaller than 56px tall. */
.adm-drive { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.adm-drive button { min-height: 56px; font-size: 17px; font-weight: 600; }
.adm-people { display: flex; gap: 22px; }
.adm-people b { font-size: 22px; font-variant-numeric: tabular-nums; }
.adm-people span { display: block; font-size: 12px; color: var(--faint); }
.adm-timer { margin: 0; }
.adm-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.adm-grid.two { grid-template-columns: 1fr 1fr; }
.adm-grid button, .adm-grid .btn { min-height: 48px; text-align: center; }
.adm-grid button.on, .adm-grid .btn.on {
  border-color: var(--accent); background: var(--accent-soft); color: var(--accent);
  font-weight: 600;
}
.adm-jump { display: grid; gap: var(--gap-bind); }
.adm-jumpi {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  min-height: 48px; padding: 8px 10px; font-size: 14px;
}
.adm-jumpi.on { border-color: var(--accent); background: var(--accent-soft); }
.adm-jumpi .aj-n {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; font-size: 11px;
  font-weight: 700; display: grid; place-items: center; color: var(--faint);
  border: 1px solid var(--line);
}
.adm-jumpi.on .aj-n { background: var(--accent); border-color: var(--accent); color: #fff; }
.adm-jumpi .aj-l { flex: 1 1 auto; font-weight: 600; min-width: 0; }
.adm-jumpi .aj-s { display: block; font-weight: 400; font-size: 12px; color: var(--faint); }
.adm-jumpi .aj-m { flex: 0 0 auto; font-size: 12px; color: var(--faint); }
.adm-specs { display: grid; gap: var(--gap-bind); }
.adm-spec {
  display: grid; gap: var(--gap-bind); width: 100%; text-align: left;
  padding: var(--gap-block) 12px; min-height: 48px;
}
.adm-spec.on { border-color: var(--accent); background: var(--accent-soft); }
.adm-spec .as-h { display: block; font-size: 12px; color: var(--faint); }
.adm-spec .as-h b { color: var(--accent); }
.adm-spec .as-p { display: block; font-size: 14px; line-height: 1.4; }

@media (max-width: 420px) {
  .adm-grid { grid-template-columns: 1fr 1fr; }
  .adm-clock b { font-size: 24px; }
}

/* -------------------------------------------------------------- settings */

.setwrap { max-width: 560px; margin: 0 auto; padding: 14px 14px 40px; }
.setwrap .topbar { align-items: flex-start; }
.setwrap a.chip { text-decoration: none; }
.setlist { padding-left: 20px; }
.setlist li { font-size: 14px; line-height: 1.5; color: var(--muted); margin-bottom: 7px; }
.setrow {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px; padding: 9px 0; border-top: 1px solid var(--line-soft); font-size: 14px;
}
.setrow:first-of-type { border-top: 0; }
.setrow b { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------ hallucination game */

.hasked { font-size: 13px; color: var(--faint); }
/* The answer is styled like something that arrived in your inbox, because the
   decision being practised is whether to forward it. */
.hanswer {
  padding: 16px; border: 1px solid var(--line); border-left: 3px solid var(--accent-line);
  border-radius: var(--radius); background: var(--canvas);
  font-size: 16px; line-height: 1.5;
}
.hverdict {
  margin-top: 14px; padding: 12px 14px; border-radius: var(--radius);
  font-size: 14px; line-height: 1.45;
}
.hverdict.good { background: var(--accent-soft); color: var(--accent); }
.hverdict.bad { background: var(--miss-soft); color: var(--miss); }

/* A short projector. Some venue outputs land at 1280x800 or 1366x768, and a
   reveal with six bars ran off the bottom of one: the row nobody caught is
   exactly what would have been cut. Tighten the scale rather than clip. */
@media (max-height: 840px) {
  body.screenmode .slide {
    --gap-page: clamp(12px, 2.4vh, 22px); --gap-block: clamp(8px, 1.6vh, 16px);
    padding: 22px 56px 16px; min-height: 0;
  }
  body.screenmode .slide.aud { --gap-page: clamp(12px, 2.6vh, 24px); min-height: 94vh; }
  body.screenmode .audstats { gap: 40px; }
  body.screenmode .audstats b { font-size: 46px; }
  body.screenmode .slide-t { font-size: clamp(26px, 4.6vh, 40px); }
}

/* Control room rows: who is here, what they did, who signed in. One shape for
   all three, spacing owned by the containers like everything else. */
.adm-row {
  display: flex; align-items: center; gap: var(--gap-block);
  padding: 10px 0; border-top: 1px solid var(--line-soft); min-height: 48px;
}
.adm-row:first-child { border-top: 0; }
.ar-dot {
  flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%;
  background: var(--line);
}
.ar-dot.on { background: var(--accent); }
.ar-dot.bad { background: var(--miss); }
.ar-b { flex: 1 1 auto; min-width: 0; font-size: 14px; display: grid; gap: 2px; }
.ar-b b { font-weight: 600; }
.ar-b span { font-size: 12px; color: var(--faint); }
.ar-m {
  flex: 0 0 auto; font-size: 12px; color: var(--faint); text-align: right;
  white-space: nowrap;
}
/* 16px, or iOS zooms in on the paste box and stays zoomed. */
#a-rosterpaste { font-family: var(--mono); font-size: 16px; }

/* The activity page reuses the control room's row, plus a second line under the
   timestamp for what the device last did. */
.ar-m .ar-s { display: block; font-size: 11px; color: var(--faint); max-width: 13em; }
.adminwrap .btn.wide { text-align: center; }
.adminwrap .metrics { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 520px) {
  .adminwrap .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Live view. A pulsing dot and a brief highlight on a row that just arrived:
   on a page that refreshes every second, the only way to see WHAT changed is
   for the new thing to announce itself. */
.adm-topbtns { display: flex; gap: var(--gap-bind); flex-wrap: wrap; }
.live-head { border-color: var(--accent-line); background: var(--accent-soft); }
.livedot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent); margin-right: 6px; vertical-align: baseline;
  animation: pulse 1.6s ease-in-out infinite;
}
@keyframes pulse { 0%,100% { opacity: 1 } 50% { opacity: 0.25 } }
.adm-row.justin { animation: justin 1.8s ease-out 1; }
@keyframes justin {
  0% { background: var(--accent-soft); }
  100% { background: transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .livedot, .adm-row.justin { animation: none; }
  .adm-row.justin { background: var(--accent-soft); }
}
