/* Friday Quiz: visual language
   Restrained, high-contrast, generous. Large type and 44px+ targets throughout:
   the audience is not looking for small affordances. */

:root {
  --font: "SF Pro Display", -apple-system, BlinkMacSystemFont, "Segoe UI Variable Display",
          "Segoe UI", Inter, Roboto, Helvetica, Arial, sans-serif;

  --bg: #ffffff;
  --bg-sunk: #f5f5f7;
  --surface: #ffffff;
  --surface-2: #f5f5f7;
  --ink: #1d1d1f;
  --ink-2: #6e6e73;
  --ink-3: #86868b;
  --line: rgba(0, 0, 0, .10);
  --line-soft: rgba(0, 0, 0, .06);
  --accent: #0071e3;
  --accent-ink: #ffffff;
  --accent-soft: rgba(0, 113, 227, .10);
  --good: #1d8a4e;
  --good-soft: rgba(29, 138, 78, .12);
  --warn: #b25000;
  --warn-soft: rgba(178, 80, 0, .12);
  --gold: #b8860b;

  --r-sm: 10px;
  --r: 16px;
  --r-lg: 22px;
  --r-xl: 30px;
  --pill: 980px;

  --shadow: 0 1px 2px rgba(0,0,0,.04), 0 8px 28px rgba(0,0,0,.06);
  --shadow-lg: 0 2px 6px rgba(0,0,0,.05), 0 24px 64px rgba(0,0,0,.12);

  --ease: cubic-bezier(.25,.1,.25,1);
  --ease-out: cubic-bezier(.16,1,.3,1);

  --nav-h: 60px;
}

/* Light is the default, so say so to the browser too: scrollbars and native
   controls should match the page, not the machine it happens to be on. */
:root[data-theme="light"] { color-scheme: light; }

:root[data-theme="dark"], html.dark {
  color-scheme: dark;
  --bg: #000000;
  --bg-sunk: #000000;
  --surface: #1c1c1e;
  --surface-2: #2c2c2e;
  --ink: #f5f5f7;
  --ink-2: #a1a1a6;
  --ink-3: #86868b;
  --line: rgba(255, 255, 255, .14);
  --line-soft: rgba(255, 255, 255, .08);
  --accent: #0a84ff;
  --accent-soft: rgba(10, 132, 255, .16);
  --good: #30d158;
  --good-soft: rgba(48, 209, 88, .16);
  --warn: #ff9f0a;
  --warn-soft: rgba(255, 159, 10, .16);
  --gold: #ffd60a;
  --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 28px rgba(0,0,0,.5);
  --shadow-lg: 0 2px 6px rgba(0,0,0,.5), 0 24px 64px rgba(0,0,0,.7);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #000000; --bg-sunk: #000000; --surface: #1c1c1e; --surface-2: #2c2c2e;
    --ink: #f5f5f7; --ink-2: #a1a1a6; --ink-3: #86868b;
    --line: rgba(255,255,255,.14); --line-soft: rgba(255,255,255,.08);
    --accent: #0a84ff; --accent-soft: rgba(10,132,255,.16);
    --good: #30d158; --good-soft: rgba(48,209,88,.16);
    --warn: #ff9f0a; --warn-soft: rgba(255,159,10,.16);
    --gold: #ffd60a;
    --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 28px rgba(0,0,0,.5);
    --shadow-lg: 0 2px 6px rgba(0,0,0,.5), 0 24px 64px rgba(0,0,0,.7);
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

/* .stage and .sheet-host set display on the class, which beats the UA
   [hidden] rule, so without this they cover the page while "hidden". */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

/* Nothing may make the page wider than the screen. Anything that does is a
   bug, and on a phone it reads as the whole page having drifted sideways and
   zoomed in. `clip` rather than `hidden`: it does not make a scroll container,
   so the sticky header keeps working. */
html, body { max-width: 100%; overflow-x: clip; }

body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--ink);
  font-size: 15px;
  line-height: 1.5;
  letter-spacing: -.011em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -.02em; line-height: 1.08; }
p { margin: 0; }
button, input, textarea, select { font: inherit; color: inherit; letter-spacing: inherit; }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}

/* Navigation */

.nav {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--line-soft);
}
.nav-inner {
  max-width: 1040px; margin: 0 auto; height: var(--nav-h);
  padding: 0 22px; display: flex; align-items: center; gap: 24px;
}
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--ink); flex-shrink: 0; }
.brand-mark {
  width: 28px; height: 28px; border-radius: 8px; background: var(--ink); color: var(--bg);
  display: grid; place-items: center; font-weight: 700; font-size: 16px; letter-spacing: -.02em;
}
.brand-name { font-weight: 600; font-size: 17px; letter-spacing: -.02em; }

.nav-links { display: flex; gap: 4px; margin-left: auto; }
.nav-links a {
  color: var(--ink-2); text-decoration: none; font-size: 15px; font-weight: 450;
  padding: 8px 14px; border-radius: var(--pill); transition: color .2s var(--ease), background .2s var(--ease);
}
.nav-links a:hover { color: var(--ink); background: var(--surface-2); }
.nav-links a.on { color: var(--ink); font-weight: 550; background: var(--surface-2); }

.nav-right { display: flex; align-items: center; gap: 8px; }
.whoami {
  display: flex; align-items: center; gap: 8px;
  background: transparent; border: 1px solid var(--line); color: var(--ink);
  border-radius: var(--pill); padding: 7px 14px 7px 7px; font-size: 14px; font-weight: 500;
  cursor: pointer; transition: background .2s var(--ease), border-color .2s var(--ease);
}
.whoami:hover { background: var(--surface-2); }
.whoami .av { width: 24px; height: 24px; font-size: 11px; }

.nav-storage { display: none; }

/* Layout */

.app { max-width: 1040px; margin: 0 auto; padding: 44px 22px 96px; }
.foot {
  max-width: 1040px; margin: 0 auto; padding: 0 22px 40px;
  color: var(--ink-3); font-size: 13px;
}

.page-head { margin-bottom: 32px; }
.page-head h1 { font-size: 26px; }
.page-head .sub { color: var(--ink-2); font-size: 15px; margin-top: 8px; letter-spacing: -.01em; }

.kicker {
  font-size: 13px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-3);
}

.stack { display: flex; flex-direction: column; gap: 18px; }
.row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.spacer { flex: 1; }
.muted { color: var(--ink-2); }
.dim { color: var(--ink-3); }
.small { font-size: 14px; }
.center { text-align: center; }

/* Cards */

.card {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  padding: 19px;
  box-shadow: var(--shadow);
}
.card.flat { box-shadow: none; background: var(--surface-2); border-color: transparent; }
.card.pad-lg { padding: 40px; }

.hero {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-xl);
  padding: 28px;
  box-shadow: var(--shadow);
  position: relative; overflow: hidden;
}
.hero h2 { font-size: 28px; letter-spacing: -.025em; }
.hero .when { color: var(--ink-2); font-size: 15px; margin-top: 10px; }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
@media (max-width: 760px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } }

/* Buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 38px; padding: 0 16px;
  border-radius: var(--pill); border: 1px solid transparent;
  background: var(--surface-2); color: var(--ink);
  font-size: 15px; font-weight: 500; cursor: pointer; text-decoration: none;
  transition: background .2s var(--ease), transform .12s var(--ease), opacity .2s var(--ease);
  white-space: nowrap;
}
.btn:hover { background: color-mix(in srgb, var(--surface-2) 88%, var(--ink)); }
.btn:active { transform: scale(.975); }
.btn[disabled] { opacity: .38; pointer-events: none; }

.btn.primary { background: var(--accent); color: #fff; }
.btn.primary:hover { background: color-mix(in srgb, var(--accent) 86%, #000); }

.btn.ghost { background: transparent; border-color: var(--line); }
.btn.ghost:hover { background: var(--surface-2); }

.btn.quiet { background: transparent; color: var(--accent); padding: 0 8px; min-height: 40px; }
.btn.quiet:hover { background: var(--accent-soft); }

.btn.danger { background: transparent; color: #d0342c; border-color: var(--line); }
.btn.danger:hover { background: rgba(208,52,44,.10); }

.btn.lg { min-height: 56px; padding: 0 34px; font-size: 19px; font-weight: 550; }
.btn.sm { min-height: 36px; padding: 0 14px; font-size: 14px; }
.btn.block { width: 100%; }

.btn-icon {
  width: 40px; height: 40px; min-height: 40px; padding: 0; border-radius: 50%;
  display: grid; place-items: center; background: transparent; border: 1px solid var(--line);
  color: var(--ink-2); cursor: pointer; font-size: 18px; line-height: 1;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.btn-icon:hover { background: var(--surface-2); color: var(--ink); }

/* Forms */

.field { display: flex; flex-direction: column; gap: 8px; }
.field > label { font-size: 15px; font-weight: 550; color: var(--ink); }
.field .hint { font-size: 14px; color: var(--ink-3); }
.field .hint.warn { color: var(--warn); font-weight: 600; }

.input, .textarea, .select {
  width: 100%; min-height: 40px; padding: 9px 13px;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  /* 16px is a floor, not a preference. Safari and Chrome on iOS zoom the whole
     page in when you focus a field smaller than this, and it stays zoomed after
     you are done - which is what made signing in leave the app magnified. */
  font-size: 16px; transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.input::placeholder, .textarea::placeholder { color: var(--ink-3); }
.input:focus, .textarea:focus, .select:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft);
}
.textarea { resize: vertical; min-height: 78px; line-height: 1.4; }
.select { appearance: none; padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%2386868b'%3E%3Cpath d='M4.5 6.5 8 10l3.5-3.5z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 18px;
}

.seg { display: inline-flex; background: var(--surface-2); border-radius: var(--r-sm); padding: 3px; gap: 3px; }
.seg button {
  border: 0; background: transparent; color: var(--ink-2); cursor: pointer;
  padding: 9px 18px; border-radius: 8px; font-size: 15px; font-weight: 500;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.seg button.on { background: var(--surface); color: var(--ink); box-shadow: 0 1px 3px rgba(0,0,0,.10); font-weight: 550; }

/* Avatars & people */

.av {
  width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center;
  font-size: 15px; font-weight: 600; letter-spacing: 0;
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--line-soft);
}
.av.lg { width: 54px; height: 54px; font-size: 20px; }
.av.xl { width: 96px; height: 96px; font-size: 34px; }

.av-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
.av-wrap .presence {
  position: absolute; right: -1px; bottom: -1px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--ink-3); border: 2px solid var(--surface);
}
.av-wrap .presence.on { background: var(--good); }

.person { display: flex; align-items: center; gap: 13px; }
.person .nm { font-weight: 550; font-size: 16px; }
.person .rl { color: var(--ink-3); font-size: 14px; }

/* Role cards */

.role-card {
  display: flex; align-items: center; gap: 16px;
  background: var(--surface-2); border-radius: var(--r);
  padding: 18px 20px;
}
.role-card .who { min-width: 0; }
.role-card .who .lbl { font-size: 13px; font-weight: 600; letter-spacing: .03em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: 3px; }
.role-card .who .val { font-size: 20px; font-weight: 600; letter-spacing: -.02em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Status pills */

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 13px; border-radius: var(--pill);
  font-size: 14px; font-weight: 550;
  background: var(--surface-2); color: var(--ink-2);
}
.pill.wait { background: var(--warn-soft); color: var(--warn); }
.pill.done { background: var(--good-soft); color: var(--good); }
.pill.live { background: var(--accent-soft); color: var(--accent); }
.dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

/* Lists */

.list { border: 1px solid var(--line-soft); border-radius: var(--r); overflow: hidden; background: var(--surface); }
.list-row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 15px; border-bottom: 1px solid var(--line-soft);
}
.list-row:last-child { border-bottom: 0; }
.list-row.inactive { opacity: .5; }

.empty {
  text-align: center; padding: 60px 24px; color: var(--ink-2);
  border: 1px dashed var(--line); border-radius: var(--r-lg);
}
.empty .big { font-size: 21px; font-weight: 600; color: var(--ink); margin-bottom: 8px; letter-spacing: -.02em; }

/* Steps */

.steps { display: flex; flex-direction: column; gap: 2px; }
.step { display: flex; gap: 15px; padding: 15px 0; align-items: flex-start; }
.step .bullet {
  width: 27px; height: 27px; border-radius: 50%; flex-shrink: 0; margin-top: 1px;
  display: grid; place-items: center; font-size: 14px; font-weight: 600;
  background: var(--surface-2); color: var(--ink-3);
}
.step.done .bullet { background: var(--good); color: #fff; }
.step.now .bullet { background: var(--accent); color: #fff; }
.step .t { font-weight: 550; font-size: 17px; }
.step .d { color: var(--ink-2); font-size: 15px; margin-top: 2px; }
.step.done .t { color: var(--ink-2); }

/* Question editor */

.q-editor { display: flex; flex-direction: column; gap: 16px; }
.q-card {
  background: var(--surface); border: 1px solid var(--line-soft);
  border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow);
}
.q-head {
  display: flex; align-items: center; gap: 14px; padding: 16px 22px;
  cursor: pointer; user-select: none; background: transparent;
  border: 0; width: 100%; text-align: left;
  transition: background .18s var(--ease);
}
.q-head:hover { background: var(--surface-2); }
.q-num {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center; font-size: 15px; font-weight: 600;
  background: var(--surface-2); color: var(--ink-3);
}
.q-card.filled .q-num { background: var(--good); color: #fff; }
.q-card.tb .q-num { background: var(--gold); color: #fff; font-size: 16px; }
.q-title { flex: 1; min-width: 0; font-size: 17px; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.q-title.ph { color: var(--ink-3); font-weight: 400; }
.q-chev { color: var(--ink-3); transition: transform .25s var(--ease); font-size: 15px; }
.q-card.open .q-chev { transform: rotate(90deg); }
.q-body { padding: 4px 22px 24px; display: flex; flex-direction: column; gap: 18px; }

.opt-row { display: flex; align-items: center; gap: 12px; }
.opt-key {
  width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0; cursor: pointer;
  display: grid; place-items: center; font-size: 15px; font-weight: 600;
  background: var(--surface-2); color: var(--ink-2); border: 2px solid transparent;
  transition: all .18s var(--ease);
}
.opt-key:hover { border-color: var(--line); }
.opt-key.on { background: var(--good); color: #fff; border-color: var(--good); }

.opt-drop {
  width: 36px; height: 36px; flex-shrink: 0; border-radius: 50%;
  border: 0; background: transparent; color: var(--ink-3);
  font-size: 22px; line-height: 1; cursor: pointer;
  display: grid; place-items: center;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.opt-drop:hover { background: rgba(208,52,44,.12); color: #d0342c; }

/* A picture or clip on the option itself, for "which of these is the badger". */
.opt-clip {
  width: 36px; height: 36px; flex-shrink: 0; border-radius: 50%;
  border: 0; background: transparent; color: var(--ink-3);
  font-size: 16px; line-height: 1; cursor: pointer;
  display: grid; place-items: center;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.opt-clip:hover { background: var(--surface-2); color: var(--ink-2); }
.opt-media { position: relative; flex-shrink: 0; line-height: 0; }
.opt-media img {
  width: 44px; height: 44px; object-fit: cover;
  border-radius: var(--r-sm); border: 1px solid var(--line-soft);
}
.opt-media-kind {
  width: 44px; height: 44px; border-radius: var(--r-sm);
  background: var(--surface-2); border: 1px solid var(--line-soft);
  display: grid; place-items: center; font-size: 18px; line-height: 1;
}
.opt-media-x {
  position: absolute; top: -6px; right: -6px;
  width: 20px; height: 20px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface);
  color: var(--ink-3); font-size: 14px; line-height: 1;
  display: grid; place-items: center; padding: 0;
}
.opt-media-x:hover { background: rgba(208,52,44,.12); color: #d0342c; }

/* Scoreboard tables */

.board { display: flex; flex-direction: column; gap: 10px; }
.board-row {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 16px;
  padding: 15px 20px; border-radius: var(--r);
  background: var(--surface-2);
}
.board-row .nm { font-size: 16px; font-weight: 550; letter-spacing: -.015em; }
.board-row .sc { font-size: 19px; font-weight: 650; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.board-row.p1 { background: color-mix(in srgb, var(--gold) 16%, var(--surface-2)); }
.board-row.last { background: var(--accent-soft); }

/* The placing sits in the circle instead of initials. A medal keeps the disc
   and gets a ring in its own metal, so the top three read at a glance from
   across the room rather than needing the emoji to be squinted at. */
.av.medal {
  font-size: 26px; line-height: 1;
  border-width: 3px; border-style: solid;
  box-shadow: 0 0 0 1px var(--surface) inset;
}
.av.medal.m1 {
  border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 22%, var(--surface-2));
}
.av.medal.m2 {
  border-color: #9aa3ad;
  background: color-mix(in srgb, #9aa3ad 20%, var(--surface-2));
}
.av.medal.m3 {
  border-color: #c07a45;
  background: color-mix(in srgb, #c07a45 20%, var(--surface-2));
}
.av.place {
  color: var(--ink-3); font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.board-row .tag { font-size: 13px; font-weight: 600; color: var(--ink-3); }

/* Score entry */

.score-row {
  display: grid; grid-template-columns: 1fr auto auto; gap: 20px; align-items: center;
  padding: 16px 4px; border-bottom: 1px solid var(--line-soft);
}
.score-row:last-child { border-bottom: 0; }
.stepper { display: flex; align-items: center; gap: 10px; }
.stepper button {
  width: 48px; height: 48px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); font-size: 24px; line-height: 1;
  cursor: pointer; display: grid; place-items: center; font-weight: 400;
  transition: background .15s var(--ease);
}
.stepper button:hover { background: var(--surface-2); }
.stepper button:active { transform: scale(.94); }
.stepper .val {
  min-width: 62px; text-align: center; font-size: 30px; font-weight: 650;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.tie-input { width: 130px; text-align: center; font-variant-numeric: tabular-nums; }

/* Sheets / dialogs */

.sheet-host {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center; padding: 24px;
  background: rgba(0,0,0,.42);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  animation: fade .22s var(--ease);
}
.sheet {
  background: var(--surface); border-radius: var(--r-xl);
  width: min(520px, 100%); max-height: 84vh; overflow: auto;
  padding: 34px; box-shadow: var(--shadow-lg);
  animation: pop .34s var(--ease-out);
}
.sheet h3 { font-size: 26px; margin-bottom: 8px; }
.sheet .sub { color: var(--ink-2); font-size: 16px; margin-bottom: 24px; }

@keyframes fade { from { opacity: 0 } }
@keyframes pop { from { opacity: 0; transform: translateY(16px) scale(.97) } }

/* Quizzy: a rail down the right-hand side, part of the page rather than a
   layer over it. Writing the quiz is a sit-at-a-monitor job, so the rail is
   simply where the screen ends: one hairline, no shadow, nothing floating.
   It hangs under the header, which keeps running edge to edge above it - so
   the account menu stays where it always is and the page reads as one screen
   with a column in it. Phones get the slide-over further down. */
.assist-dock {
  position: fixed; top: var(--nav-h); right: 0; bottom: 0; z-index: 90;
  width: var(--assist-w, 400px);
  background: var(--surface); border-left: 1px solid var(--line);
  display: flex; flex-direction: column;
}

/* Only the editor column reserves room, never the header. .app is border-box
   and capped at 1040px, so the cap grows by the rail's width as well -
   otherwise the gutter would eat the questions instead of the space beside
   them, and the column would drift off centre. */
body.assist-docked .app {
  max-width: calc(1040px + var(--assist-w, 400px));
  padding-right: calc(var(--assist-w, 400px) + 40px);
}

/* Drag handle: a hairline that only colours in on approach, so at rest the
   rail reads as an edge rather than a control. */
.assist-grip {
  position: absolute; top: 0; bottom: 0; left: -3px; width: 7px;
  cursor: col-resize; z-index: 1; touch-action: none;
}
.assist-grip::after {
  content: ''; position: absolute; inset: 0 3px;
  background: var(--accent); opacity: 0; transition: opacity .15s var(--ease);
}
.assist-grip:hover::after, .assist-grip:focus-visible::after { opacity: .5; }
body.assist-resizing .assist-grip::after { opacity: .75; }
/* Nothing should select or hover-flicker while a drag is in flight. */
body.assist-resizing { user-select: none; cursor: col-resize; }
body.assist-resizing .assist-dock-body { pointer-events: none; }

/* Deliberately no border under this: the page header's rule sits directly
   above the panel, and a second rule a little lower never lines up with it -
   which reads as a misalignment rather than as structure. The title is a
   quiet label; the scroll area below carries the weight. */
.assist-head {
  flex: none; display: flex; align-items: center; gap: 8px;
  padding: 18px 20px 6px; color: var(--ink-2);
}
.assist-mark { display: flex; color: var(--accent); }
.assist-head h3 {
  font-size: 13px; font-weight: 600; margin: 0;
  letter-spacing: -.005em; color: var(--ink-2);
}
.assist-close { display: none; }

.assist-body {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 14px 20px 20px; display: flex; flex-direction: column; gap: 22px;
}

/* Empty state: one line of welcome, then examples worth actually clicking. */
.assist-welcome p { font-size: 14px; line-height: 1.6; color: var(--ink-2); }
.assist-try {
  margin-top: 20px; font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .07em; color: var(--ink-3);
}
.assist-examples { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.assist-example {
  text-align: left; width: 100%; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: transparent; color: var(--ink-2);
  padding: 9px 12px; font: inherit; font-size: 13px; line-height: 1.45;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.assist-example:hover { background: var(--surface-2); color: var(--ink); }

.assist-msg { font-size: 14px; line-height: 1.6; }
.assist-role {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .07em; color: var(--ink-3); margin-bottom: 5px;
}
.assist-msg.user .assist-role { color: var(--accent); }
.assist-text { white-space: pre-wrap; color: var(--ink); }
.assist-msg.user .assist-text { color: var(--ink-2); }

.assist-card {
  margin-top: 12px; padding: 14px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface-2);
}
.assist-card-title { font-size: 13px; font-weight: 550; color: var(--ink); }
.assist-card-sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; }

/* Composer: input and send share one rounded field that lights up on focus,
   rather than a bare textarea with a button parked underneath it. */
.assist-foot { flex: none; padding: 14px 16px 16px; border-top: 1px solid var(--line-soft); }
.assist-field {
  display: flex; align-items: flex-end; gap: 8px;
  background: var(--surface-2); border: 1px solid transparent;
  border-radius: var(--r); padding: 6px 6px 6px 14px;
  transition: border-color .15s var(--ease), background .15s var(--ease);
}
.assist-field:focus-within { background: var(--surface); border-color: var(--accent); }
.assist-input {
  flex: 1; min-width: 0; resize: none; border: 0; outline: none;
  background: transparent; color: var(--ink);
  font: inherit; font-size: 14px; line-height: 1.5;
  padding: 7px 0; max-height: 140px;
}
.assist-input::placeholder { color: var(--ink-3); }
.assist-send {
  flex: none; width: 32px; height: 32px; border: 0; border-radius: 50%;
  background: var(--accent); color: var(--accent-ink);
  display: grid; place-items: center; cursor: pointer;
  transition: opacity .15s var(--ease);
}
.assist-send:disabled { opacity: .35; cursor: default; }
.assist-err { color: var(--warn); font-size: 13px; margin-top: 10px; }

/* A phone has no room to keep Quizzy alongside, so there it slides over the
   editor from a floating button and can be shut again. */
.assist-fab { display: none; }
@media (max-width: 899px) {
  .assist-dock {
    top: 0; width: min(420px, 100vw); box-shadow: var(--shadow-lg);
    transform: translateX(105%); transition: transform .28s var(--ease-out);
  }
  body.assist-open .assist-dock { transform: translateX(0); }
  body.assist-docked .app { max-width: 1040px; padding-right: 16px; }
  .assist-grip { display: none; }
  .assist-close { display: inline-flex; }
  .assist-fab {
    display: flex; align-items: center; justify-content: center;
    position: fixed; right: 16px; bottom: 16px; z-index: 89;
    width: 52px; height: 52px; border-radius: 50%; border: 0;
    background: var(--accent); color: var(--accent-ink);
    box-shadow: var(--shadow-lg); cursor: pointer;
  }
  .assist-fab svg { width: 22px; height: 22px; }
  body.assist-open .assist-fab { display: none; }
}

/* Toasts */

.toasts {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  z-index: 500; display: flex; flex-direction: column; gap: 10px; align-items: center;
  pointer-events: none;
}
.toast {
  background: var(--ink); color: var(--bg);
  padding: 13px 22px; border-radius: var(--pill);
  font-size: 15px; font-weight: 500; box-shadow: var(--shadow-lg);
  animation: rise .3s var(--ease-out);
}
@keyframes rise { from { opacity: 0; transform: translateY(14px) } }

/* PRESENTATION STAGE */

.stage {
  position: fixed; inset: 0; z-index: 300;
  background: var(--bg); color: var(--ink);
  display: flex; flex-direction: column;
  --pad: clamp(32px, min(5vw, 7.5vh), 80px);
}

/* A slide is a slide: it fits the screen, like presenting in PowerPoint. It
   must never scroll, in either direction - a projector has no scrollbar and
   nobody is going to reach for the mouse mid-question. Everything inside is
   allowed to shrink instead, which is what min-height: 0 on the children buys.
   Small screens are the exception and are handled further down. */
.slide {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column;
  padding: var(--pad);
  max-width: 1500px; width: 100%; margin: 0 auto;
  overflow: hidden;
}
/* Every direct child may give up room rather than push the slide taller. */
.slide > * { min-height: 0; flex-shrink: 1; }
/* The question, the answers and the tally keep their content height; only the
   picture is allowed to take what is left. */
.slide > .s-q, .slide > .s-kicker, .slide > .s-opts, .slide > .tally { flex-grow: 0; }
.s-opts { min-height: 0; }
/* Whatever happens above it, the tally stays on the slide and stays last. */
.slide > .tally { flex-shrink: 0; margin-top: auto; padding-top: clamp(10px, 2vh, 28px); }
/* Centred vertically, but by margin rather than justify-content. With
   justify-content: center an overflowing slide has its top clipped off and no
   scroll can reach it - which is exactly what running the quiz from a phone
   looked like. Auto margins collapse when there is no room, so the content
   simply starts at the top and scrolls. */
.slide > :first-child { margin-top: auto; }
.slide > :last-child { margin-bottom: auto; }
.slide > * { animation: slideIn .5s var(--ease-out) both; }
@keyframes slideIn { from { opacity: 0; transform: translateY(20px) } }

.s-kicker {
  font-size: clamp(15px, min(1.5vw, 2.25vh), 22px); font-weight: 600;
  letter-spacing: .10em; text-transform: uppercase; color: var(--ink-3);
  margin-bottom: clamp(14px, 2vh, 28px);
}
.s-title {
  font-size: clamp(38px, min(6.4vw, 9.6vh), 104px); font-weight: 650;
  letter-spacing: -.03em; line-height: 1.03;
}
.s-sub {
  font-size: clamp(19px, min(2.1vw, 3.15vh), 34px); color: var(--ink-2);
  margin-top: clamp(16px, 2.4vh, 32px); font-weight: 400; letter-spacing: -.015em;
}
.s-q {
  font-size: clamp(30px, min(4.4vw, 6.6vh), 72px); font-weight: 600;
  letter-spacing: -.028em; line-height: 1.14;
}

.s-opts {
  /* No default column count - one of the .cols-N classes always sets it, chosen
     from how many answers there are and how long they run. */
  display: grid;
  gap: clamp(12px, min(1.6vw, 2.4vh), 22px);
  margin-top: clamp(28px, 4.4vh, 64px);
}
/* Three or fewer read better as full-width rows on a big screen. */
/* Laid out by what is in them, not how many there are. A row of years should
   not be four full-width bars with an ocean of space in each. */
/* The shape decides the type; the column count decides the arrangement. */

/* Short answers can afford to be large; a phrase has to give way. */
.s-opts.opts-tight > .s-opt { font-size: clamp(22px, min(3vw, 4.5vh), 46px); justify-content: center; }
.s-opts.opts-wide  > .s-opt { font-size: clamp(17px, min(1.9vw, 2.85vh), 30px); }
/* Explicit column counts, set from how many answers there are and how long
   they run. auto-fit left three answers as two-and-a-lonely-one, and stretching
   the last across the slide to hide the gap looked worse than the gap. */
.s-opts.cols-1 { grid-template-columns: 1fr; }
.s-opts.cols-2 { grid-template-columns: repeat(2, 1fr); }
.s-opts.cols-3 { grid-template-columns: repeat(3, 1fr); }
.s-opts.cols-4 { grid-template-columns: repeat(4, 1fr); }
/* Narrow screens step down: four across is unreadable on a phone. */
@media (max-width: 1100px) { .s-opts.cols-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 820px)  { .s-opts.cols-3 { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px)  {
  .s-opts.cols-2, .s-opts.cols-3, .s-opts.cols-4 { grid-template-columns: 1fr; }
  .s-opts.opts-tight.cols-3, .s-opts.opts-tight.cols-4 { grid-template-columns: repeat(2, 1fr); }
}
.s-opt {
  display: flex; align-items: center; gap: clamp(14px, min(1.5vw, 2.25vh), 22px);
  background: var(--surface-2); border: 2px solid transparent;
  border-radius: var(--r-lg); padding: clamp(16px, min(2vw, 3.0vh), 26px) clamp(18px, min(2.2vw, 3.3vh), 30px);
  font-size: clamp(19px, min(2.3vw, 3.45vh), 36px); font-weight: 450; letter-spacing: -.015em;
  transition: background .45s var(--ease), border-color .45s var(--ease),
              opacity .45s var(--ease), transform .45s var(--ease);
}
/* Picture options on the projector: the picture is the answer, so give it room
   and let the letter sit alongside rather than the other way round. */
.s-opts.with-media { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.s-opts.with-media > .s-opt { flex-direction: column; text-align: center; gap: 12px; }
.s-opt .opt-pic {
  width: 100%; max-height: clamp(120px, 18vh, 260px);
  object-fit: contain; border-radius: var(--r-md);
}
.s-opt .opt-clip { width: 100%; }
.s-opt .k {
  width: clamp(38px, min(3.4vw, 5.1vh), 56px); height: clamp(38px, min(3.4vw, 5.1vh), 56px); flex-shrink: 0;
  border-radius: 50%; display: grid; place-items: center;
  background: var(--surface); color: var(--ink-2); font-weight: 650;
  font-size: clamp(17px, min(1.8vw, 2.7vh), 27px); border: 1px solid var(--line-soft);
}
.s-opt.right {
  background: var(--good-soft); border-color: var(--good); transform: scale(1.015);
}
.s-opt.right .k { background: var(--good); color: #fff; border-color: var(--good); }
.s-opt.wrong { opacity: .32; }

.s-answer {
  margin-top: clamp(28px, 4.4vh, 60px);
  padding: clamp(22px, min(2.8vw, 4.2vh), 40px) clamp(26px, min(3vw, 4.5vh), 46px);
  background: var(--good-soft); border-radius: var(--r-xl);
  border-left: 6px solid var(--good);
  animation: revealIn .55s var(--ease-out) both;
}
@keyframes revealIn { from { opacity: 0; transform: translateY(18px) scale(.985) } }
.s-answer .lbl {
  font-size: clamp(13px, min(1.2vw, 1.8vh), 18px); font-weight: 650; letter-spacing: .10em;
  text-transform: uppercase; color: var(--good); margin-bottom: 8px;
}
.s-answer .val {
  font-size: clamp(26px, min(3.6vw, 5.4vh), 58px); font-weight: 650; letter-spacing: -.025em; line-height: 1.1;
}
.s-answer .note {
  font-size: clamp(16px, min(1.6vw, 2.4vh), 25px); color: var(--ink-2); margin-top: 12px; font-weight: 400;
}

.s-hint {
  margin-top: clamp(24px, 3.5vh, 48px);
  font-size: clamp(15px, min(1.5vw, 2.25vh), 22px); color: var(--ink-3); font-weight: 450;
  display: flex; align-items: center; gap: 10px;
}
.s-hint kbd {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 7px; padding: 4px 11px; font-family: inherit; font-size: .92em; font-weight: 550;
}

/* Stage chrome */
.stage-bar {
  display: flex; align-items: center; gap: 14px;
  padding: 14px clamp(20px, min(3vw, 4.5vh), 40px);
  border-top: 1px solid var(--line-soft);
  background: var(--surface);
  flex-shrink: 0;
}
.stage-bar .count {
  font-size: 15px; color: var(--ink-2); font-variant-numeric: tabular-nums; font-weight: 500;
  min-width: 84px;
}
/* Switch, the phone-settings kind. The checkbox stays in the DOM unseen so it
   keeps its keyboard and screen-reader behaviour for free. */
.switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; user-select: none; }
.switch input {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
.switch .track {
  width: 51px; height: 31px; border-radius: 999px; flex-shrink: 0;
  background: var(--surface-2); border: 1px solid var(--line-soft);
  position: relative; transition: background .22s var(--ease), border-color .22s var(--ease);
}
.switch .knob {
  position: absolute; top: 2px; left: 2px; width: 25px; height: 25px;
  border-radius: 50%; background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,.28);
  transition: transform .22s var(--ease);
}
.switch input:checked + .track { background: var(--good); border-color: var(--good); }
.switch input:checked + .track .knob { transform: translateX(20px); }
.switch input:focus-visible + .track { outline: 2px solid var(--accent); outline-offset: 3px; }
.switch-t { font-size: 15px; color: var(--ink-2); font-weight: 500; }
.stage-bar .progress {
  flex: 1; height: 5px; background: var(--surface-2); border-radius: 3px; overflow: hidden;
}
.stage-bar .progress i { display: block; height: 100%; background: var(--accent);
  border-radius: 3px; transition: width .4s var(--ease); }
.nav-big {
  min-height: 52px; padding: 0 26px; font-size: 17px; font-weight: 550;
  border-radius: var(--pill); border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); cursor: pointer;
  display: inline-flex; align-items: center; gap: 8px;
  transition: background .18s var(--ease);
}
.nav-big:hover { background: var(--surface-2); }
.nav-big[disabled] { opacity: .3; pointer-events: none; }
.nav-big.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.nav-big.primary:hover { background: color-mix(in srgb, var(--accent) 86%, #000); }

.timer-ring { display: flex; align-items: center; gap: 10px; font-variant-numeric: tabular-nums;
  font-size: 16px; font-weight: 600; color: var(--ink-2); }
.timer-ring.low { color: #d0342c; }

/* Stage scoreboard */
.stage-board { display: flex; flex-direction: column; gap: clamp(8px, 1.1vh, 14px); margin-top: clamp(20px,3vh,40px); }
.stage-board .board-row {
  padding: clamp(12px, 1.7vh, 22px) clamp(18px, min(2.2vw, 3.3vh), 32px);
  grid-template-columns: auto 1fr auto;
  animation: slideIn .5s var(--ease-out) both;
}
/* On the projector it all scales with the screen, medal included. */
.stage-board .av.lg {
  width: clamp(52px, min(4.6vw, 6.9vh), 84px); height: clamp(52px, min(4.6vw, 6.9vh), 84px);
  font-size: clamp(22px, min(2.1vw, 3.15vh), 36px);
}
.stage-board .av.lg.medal { font-size: clamp(34px, min(3.2vw, 4.8vh), 58px); }
.stage-board .board-row .nm { font-size: clamp(21px, min(2.4vw, 3.6vh), 40px); }
.stage-board .board-row .sc { font-size: clamp(24px, min(2.8vw, 4.2vh), 46px); }
.stage-board .board-row .tag { font-size: clamp(12px, min(1.1vw, 1.65vh), 17px); }

/* Someone taken off the team. Dimmed rather than hidden - the admin needs to
   see who is in here to put them back. */
.list-row.is-removed { opacity: .55; }
.list-row.is-removed .nm { text-decoration: line-through; text-decoration-thickness: 1px; }

/* Your running score, on your own screen only */

/* Same small caps as the question counter it sits beside, with a hairline to
   separate them - it is a running tally, not a headline. */
.play-score {
  font-size: 13px; font-weight: 650; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  padding-left: 12px; border-left: 1px solid var(--line-soft);
}
.play-score.final { color: var(--good); }

/* Tiebreaker guesses as bars, with the answer ruled across them */

.tie-chart { margin-top: 16px; width: 100%; }
.tie-chart-svg { width: 100%; height: auto; display: block; overflow: visible; }
.tc-grid { stroke: var(--line-soft); stroke-width: 1; }
.tc-tick { fill: var(--ink-3); font-size: 19px; font-variant-numeric: tabular-nums; }
.tc-bar { fill: var(--surface-2); stroke: var(--line-soft); stroke-width: 1; }
/* Nearest guess wins the tiebreaker, so it is the one to pick out. */
.tc-bar.best { fill: var(--good); stroke: var(--good); }
.tc-val { fill: var(--ink-2); font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; }
.tc-name { fill: var(--ink-3); font-size: 20px; font-weight: 500; }
/* Dashed, because it is the reference and not another bar. */
.tc-line { stroke: var(--accent); stroke-width: 3; stroke-dasharray: 10 8; }
.tc-line-lbl { fill: var(--accent); font-size: 21px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* The phone gets the same drawing in a smaller box, so the type has to come
   up to stay readable - it is scaled by the viewBox, not by pixels. */
.play .tc-tick { font-size: 26px; }
.play .tc-val, .play .tc-name { font-size: 27px; }
.play .tc-line-lbl { font-size: 28px; }

/* Who guessed what on the tiebreaker, once the answer is up */

.tie-board { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.tie-row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 14px; border-radius: var(--r);
  background: var(--surface-2); border: 1px solid transparent;
}
.tie-row.mine { border-color: var(--accent); }
.tie-row.closest { background: var(--good-soft); border-color: var(--good); }
.tie-who { min-width: 0; }
.tie-who .nm { font-size: 16px; font-weight: 600; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.tie-who .tag { font-size: 13px; color: var(--ink-2); margin-top: 1px; }
.tie-guess { font-size: 19px; font-weight: 650; font-variant-numeric: tabular-nums; }
.tie-row.closest .tie-guess { color: var(--good); }
.tie-flag { flex-shrink: 0; }

/* Same list on the projector, sized for the back of the room */
.tie-board.big { gap: clamp(7px, .9vh, 13px); margin-top: clamp(16px, 2.4vh, 34px); }
.tie-board.big .tie-row { padding: clamp(8px, 1.2vh, 16px) clamp(14px, min(1.8vw, 2.7vh), 26px); gap: clamp(12px,min(1.4vw, 2.1vh),20px); }
.tie-board.big .tie-who .nm { font-size: clamp(18px, min(2vw, 3.0vh), 34px); }
.tie-board.big .tie-who .tag { font-size: clamp(12px, min(1.1vw, 1.65vh), 19px); }
.tie-board.big .tie-guess { font-size: clamp(20px, min(2.3vw, 3.45vh), 40px); }
.tie-board.big .tie-flag { font-size: clamp(12px, min(1.1vw, 1.65vh), 18px); }
/* The guess list is tall, so the question above it gives up some room. */
.slide.tight .s-q { font-size: clamp(22px, min(2.6vw, 3.9vh), 40px); }
.s-q.q-long  { font-size: clamp(24px, min(3.2vw, 4.8vh), 50px); }
.s-q.q-xlong { font-size: clamp(20px, min(2.5vw, 3.75vh), 38px); line-height: 1.2; }
.slide.tight .s-answer { margin-top: clamp(16px, 2vh, 28px); padding: clamp(14px,min(1.8vw, 2.7vh),26px) clamp(18px,min(2.2vw, 3.3vh),32px); }
.slide.tight .s-answer .val { font-size: clamp(22px, min(2.8vw, 4.2vh), 44px); }
.slide.tight .s-media { flex: 0 1 auto; }
.slide.tight .s-media img, .slide.tight .s-media video { max-height: 22vh; }

.next-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(18px,min(2.4vw, 3.6vh),34px);
  margin-top: clamp(28px, 4vh, 56px); }
@media (max-width: 820px) { .next-grid { grid-template-columns: 1fr; } }
.next-card {
  background: var(--surface-2); border-radius: var(--r-xl);
  padding: clamp(26px, min(3.2vw, 4.8vh), 46px); text-align: center;
}
.next-card .lbl { font-size: clamp(13px,min(1.2vw, 1.8vh),18px); font-weight: 650; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-3); }
.next-card .av { margin: clamp(16px,2.2vh,28px) auto clamp(12px,1.6vh,20px);
  width: clamp(70px,min(7vw, 10.5vh),110px); height: clamp(70px,min(7vw, 10.5vh),110px); font-size: clamp(26px,min(2.7vw, 4.05vh),42px); }
.next-card .val { font-size: clamp(24px,min(2.8vw, 4.2vh),46px); font-weight: 650; letter-spacing: -.025em; }
.next-card .why { font-size: clamp(14px,min(1.3vw, 1.95vh),20px); color: var(--ink-2); margin-top: 8px; }

.stage-scoring {
  max-width: 900px; width: 100%; margin: 0 auto; padding: clamp(28px,min(4vw, 6.0vh),60px);
  overflow-y: auto; flex: 1;
}

/* SIGN IN */

body.bare .app { padding: 0; max-width: none; }

.auth {
  min-height: 100vh; min-height: 100dvh;
  display: grid; place-items: center; padding: 24px;
  background: var(--bg-sunk);
}
.auth-card {
  width: min(420px, 100%);
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-xl);
  padding: 40px 34px;
  box-shadow: var(--shadow-lg);
  text-align: center;
}
.auth-card h1 { font-size: 32px; }
.auth-card .stack, .auth-card .field { text-align: left; }
.auth-mark { font-size: 48px; margin-bottom: 14px; }
.auth-err {
  color: #d0342c; font-size: 15px; font-weight: 500;
  margin-top: 14px; text-align: left;
}
.seg.block { display: flex; width: 100%; }
.seg.block button { flex: 1; }

/* LIVE: the big screen */

/* Only the big screen is locked. A player's own screen scrolls like any page -
   with this on the body, anything past the first viewport was unreachable. */
body.playing.presenting { overflow: hidden; }
body.playing .app { padding: 0; max-width: none; }

.stage-live {
  /* Fixed to the viewport and clipped: nothing inside can make the page scroll,
     in either direction. Presenting is a fixed frame, not a document. */
  position: fixed; inset: 0; z-index: 100; overflow: hidden;
  background: var(--bg); color: var(--ink);
  display: flex; flex-direction: column;
  --pad: clamp(28px, min(5vw, 7.5vh), 80px);
}

/* Always plain black-on-white, in a white card of its own - a phone camera
   does not care what theme the projector is in, and dark mode would just
   make it harder to scan. */
.qr-code { display: inline-flex; background: #fff; padding: 10px; border-radius: 12px; line-height: 0; }
.qr-code svg { display: block; width: 132px; height: 132px; }

/* The lobby is a join screen first, like Kahoot's PIN slide: the QR is the
   biggest thing on it, with who has already joined off to the side. */
.lobby-grid {
  display: flex; align-items: stretch; flex-wrap: wrap;
  gap: clamp(28px, min(4vw, 6.0vh), 64px);
  margin-top: clamp(32px, 5vh, 64px);
}

.lobby-join {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: clamp(22px, min(2.6vw, 3.9vh), 40px);
  background: var(--surface-2); border-radius: 28px;
}
.lobby-join .qr-code { padding: clamp(10px, min(1.2vw, 1.8vh), 18px); border-radius: 18px; }
.lobby-join .qr-code svg {
  width: clamp(190px, min(17vw, 25vh), 320px); height: clamp(190px, min(17vw, 25vh), 320px);
}
.lobby-join-label { font-size: clamp(18px, min(1.7vw, 2.55vh), 26px); font-weight: 650; }
.lobby-join-or {
  font-size: clamp(13px, min(1.1vw, 1.65vh), 17px); color: var(--ink-3);
  margin-top: 2px;
}
.lobby-join-url {
  font-size: clamp(14px, min(1.3vw, 1.95vh), 19px); color: var(--ink-2);
  font-family: ui-monospace, monospace; font-weight: 600;
}
/* Read off a projector and typed on a phone, so it gets room to breathe and
   wide letter-spacing - the two things that make a code easy to copy. */
.lobby-code {
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line-soft);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  align-self: stretch;
}
.lobby-code .lbl {
  font-size: clamp(11px, min(.95vw, 1.4vh), 15px); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3);
}
.lobby-code .val {
  font-size: clamp(22px, min(2.1vw, 3.15vh), 34px); font-weight: 700;
  letter-spacing: .14em; font-family: ui-monospace, monospace;
}

/* Same code on the Team page, where it gets copied rather than read out. */
.invite-box {
  padding: 14px 16px; border-radius: var(--r);
  background: var(--surface-2); border: 1px solid var(--line-soft);
}
.invite-code {
  margin-top: 4px; font-family: ui-monospace, monospace;
  font-size: 26px; font-weight: 700; letter-spacing: .12em;
  cursor: pointer; word-break: break-all;
}
.invite-code:hover { color: var(--accent); }

.lobby-players {
  flex: 1; min-width: 260px;
  display: flex; flex-direction: column; justify-content: center;
}
.lobby-players-count {
  font-size: clamp(17px, 1.6vw, 23px); font-weight: 600; color: var(--ink-2);
}
.lobby-faces {
  display: flex; flex-wrap: wrap; gap: clamp(16px, 2.4vw, 34px);
  margin-top: clamp(20px, 3vh, 34px);
}
.lobby-face {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  font-size: clamp(15px, 1.4vw, 21px); color: var(--ink-2); font-weight: 500;
  animation: pop .4s var(--ease-out) both;
}
.lobby-face .av { width: clamp(56px, 5vw, 84px); height: clamp(56px, 5vw, 84px);
  font-size: clamp(20px, 2vw, 31px); }

/* how many have answered */
.tally { margin-top: clamp(14px, 2.4vh, 40px); }
.tally-bar {
  height: 10px; background: var(--surface-2); border-radius: 6px; overflow: hidden;
  max-width: 620px;
}
.tally-bar i {
  display: block; height: 100%; background: var(--accent); border-radius: 6px;
  transition: width .45s var(--ease-out);
}
.tally-text {
  margin-top: 12px; font-size: clamp(16px, 1.6vw, 24px);
  color: var(--ink-2); font-weight: 500; font-variant-numeric: tabular-nums;
}
.tally.all-in .tally-bar i { background: var(--good); }
.tally.all-in .tally-text { color: var(--good); font-weight: 600; }

/* LIVE: the phone */

.play {
  /* dvh, not vh: on a phone vh includes the browser chrome, so the card starts
     taller than the screen and pushes its own header out of sight. */
  min-height: 100dvh;
  padding: 22px 18px calc(28px + env(safe-area-inset-bottom));
  max-width: 620px; margin: 0 auto;
  display: flex; flex-direction: column;
}
.play-head {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: 16px; min-height: 32px;
}
.play-step {
  font-size: 13px; font-weight: 650; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-3);
}
.play-q {
  font-size: clamp(23px, 5.6vw, 32px); font-weight: 600;
  letter-spacing: -.022em; line-height: 1.2;
}
.play-opts { display: flex; flex-direction: column; gap: 12px; margin-top: 24px; }

.play-opt {
  display: flex; align-items: center; gap: 14px; width: 100%;
  min-height: 68px; padding: 14px 18px; text-align: left;
  background: var(--surface); color: var(--ink);
  border: 2px solid var(--line); border-radius: var(--r);
  font-size: 18px; font-weight: 500; cursor: pointer;
  transition: border-color .18s var(--ease), background .18s var(--ease), transform .12s var(--ease);
}
button.play-opt:active { transform: scale(.985); }
.play-opt .k {
  width: 40px; height: 40px; flex-shrink: 0; border-radius: 50%;
  display: grid; place-items: center; font-weight: 650; font-size: 17px;
  background: var(--surface-2); color: var(--ink-2);
}
.play-opt .t { flex: 1; min-width: 0; }
/* On a phone the picture has to be tappable-sized but must not push the
   answer text off the row. Sound and video stay on the big screen: a cue only. */
.play-opt .opt-pic {
  width: 56px; height: 56px; flex-shrink: 0; object-fit: cover;
  border-radius: var(--r-sm); border: 1px solid var(--line-soft);
}
.play-opt .opt-cue { font-size: 20px; flex-shrink: 0; }
.play-opt .tick { font-size: 22px; font-weight: 700; color: var(--good); }

.play-opt.picked { border-color: var(--accent); background: var(--accent-soft); }
.play-opt.picked .k { background: var(--accent); color: #fff; }
.play-opt.picked .tick { color: var(--accent); }

.play-opt.right { border-color: var(--good); background: var(--good-soft); }
.play-opt.right .k { background: var(--good); color: #fff; }
.play-opt.mine-wrong { border-color: #d0342c; background: rgba(208,52,44,.10); }
.play-opt.faded { opacity: .45; }

/* Media in the editor */

.media-box {
  border: 1px solid var(--line); border-radius: var(--r);
  padding: 12px; background: var(--surface-2);
}
/* Inside the question box the frame is already there. */
.compose-media .media-box { border: 0; padding: 0; background: transparent; }
.media-thumb {
  display: block; width: 100%; max-height: 240px;
  object-fit: contain; border-radius: var(--r-sm); background: var(--bg);
}
.compose-media .media-thumb { max-height: 190px; }
.media-player { display: block; width: 100%; max-height: 240px; border-radius: var(--r-sm); }
audio.media-player { height: 44px; }
.media-meta { display: flex; align-items: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }

/* The question box: text and attachment in one frame, so a file can be
   dropped straight onto the question you are writing. */

.q-compose {
  position: relative; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); overflow: hidden;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.q-compose:focus-within { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
/* The frame draws the border now, so the box inside must not draw its own. */
.q-compose .textarea {
  border: 0; border-radius: 0; background: transparent; min-height: 86px;
}
.q-compose .textarea:focus { box-shadow: none; }
.compose-media { border-top: 1px solid var(--line-soft); padding: 10px 12px 12px; }

/* Attach strip along the bottom of the question box */
.attach {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 8px 10px; border-radius: var(--r-sm);
  border: 1px dashed var(--line); color: var(--ink-2);
  transition: border-color .18s var(--ease), background .18s var(--ease), color .18s var(--ease);
}
.attach:hover { border-color: var(--accent); color: var(--ink); background: var(--accent-soft); }
.attach:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.attach.busy { cursor: default; border-style: solid; flex-direction: column; align-items: stretch; }
.attach-icon { font-size: 15px; line-height: 1; }
.attach-t { font-size: 14px; }

/* Hovering a file over the question box */
.q-compose.dropping { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.q-compose.dropping::after {
  content: "Drop it here"; position: absolute; inset: 0; z-index: 2;
  display: grid; place-items: center; pointer-events: none;
  background: var(--accent-soft); backdrop-filter: blur(2px);
  color: var(--accent); font-size: 17px; font-weight: 600;
  border-radius: var(--r-sm);
}
.q-compose.dropping .attach { border-color: var(--accent); }

.media-bar {
  width: 100%; max-width: 280px; height: 6px; margin-top: 10px;
  border-radius: var(--pill); background: var(--line-soft); overflow: hidden;
}
.media-bar i {
  display: block; height: 100%; width: 0; border-radius: var(--pill);
  background: var(--accent); transition: width .15s linear;
}

/* A card lit up because a file is hovering somewhere over it */
.q-card.dropping { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft), var(--shadow); }
.q-card.dropping .q-head { background: var(--accent-soft); }
.q-card.dropping .media-box { border-color: var(--accent); }

/* Media on the big screen */

/* The picture takes whatever height the question and the answers leave, rather
   than a fixed slice of the screen. A capped percentage meant a slide with four
   short answers showed a small picture above a band of empty space - the space
   was there, nothing was using it. */
.s-media {
  margin-top: clamp(18px, 2.6vh, 34px);
  display: flex; justify-content: center; align-items: center;
  flex: 1 1 auto; min-height: 0;
}
.s-media img, .s-media video {
  /* width/height 100% rather than auto: an img at height:auto draws at its own
     natural size and will not scale UP, so the box grew and the picture stayed
     small with white space around it. object-fit keeps the proportions. */
  width: 100%; height: 100%; min-height: 0;
  object-fit: contain; border-radius: var(--r-lg);
  background: var(--surface-2);
}
/* A slide with a picture fills the frame; the auto margins that centre a
   text-only slide would fight the picture for the same space. */
.slide.has-media > :first-child, .slide.has-media > :last-child {
  margin-top: 0; margin-bottom: 0;
}
.slide.has-media { justify-content: flex-start; }
/* Sound is a bar, not a picture - it should not stretch to fill the slide. */
.s-media.audio { flex: 0 0 auto; }
.s-media.audio { justify-content: stretch; align-items: stretch; }
.s-media audio { width: 100%; max-width: 760px; height: 54px; }

/* With media the question text gives up some room so the options still fit. */
.slide.has-media .s-q { font-size: clamp(24px, min(3.1vw, 4.65vh), 46px); }
.slide.has-media .s-opts { margin-top: clamp(16px, 2.2vh, 30px); }
.slide.has-media .s-opt { padding: clamp(11px, min(1.4vw, 2.1vh), 18px) clamp(16px, min(2vw, 3.0vh), 26px); font-size: clamp(17px, min(1.8vw, 2.7vh), 28px); }
.slide.has-media .s-media img, .slide.has-media .s-media video { max-height: 34vh; }

/* Media on a phone */

.play-media {
  display: block; width: 100%; max-height: 38vh;
  object-fit: contain; border-radius: var(--r);
  margin-top: 16px; background: var(--surface-2);
}
.play-media-note {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  margin-top: 16px; padding: 20px;
  border: 1px dashed var(--line); border-radius: var(--r);
  color: var(--ink-2); font-size: 17px; font-weight: 500;
}
.play-media-note .icon { font-size: 26px; }

.play-number { font-size: 26px; text-align: center; min-height: 64px; font-variant-numeric: tabular-nums; }
.play-foot { margin-top: auto; padding-top: 24px; color: var(--ink-3); font-size: 15px; }
.play-note {
  margin-top: 20px; padding: 16px 18px; border-radius: var(--r);
  background: var(--surface-2); color: var(--ink-2); font-size: 16px;
}

.play-wait { margin: auto; text-align: center; padding: 40px 20px; }
.play-wait h2 { font-size: 26px; margin-bottom: 10px; }
.pulse {
  width: 58px; height: 58px; border-radius: 50%; margin: 0 auto 24px;
  background: var(--accent); opacity: .28;
  animation: breathe 1.8s var(--ease) infinite;
}
@keyframes breathe {
  0%, 100% { transform: scale(.82); opacity: .22; }
  50%      { transform: scale(1);   opacity: .45; }
}

/* connection warning */
.conn {
  position: fixed; top: 12px; left: 50%; transform: translateX(-50%);
  z-index: 600; background: var(--warn); color: #fff;
  padding: 8px 18px; border-radius: var(--pill);
  font-size: 14px; font-weight: 600; box-shadow: var(--shadow);
}

.save-state { font-variant-numeric: tabular-nums; }

@media (max-width: 560px) {
  /* A phone is held closer than a monitor, so the same sizes read larger.
     Everything comes down a step rather than just the headings. */
  body { font-size: 14px; }
  .app { padding: 20px 14px 64px; }
  .card { border-radius: var(--r); }
  .btn { min-height: 36px; padding: 0 14px; font-size: 14px; }
  /* Never below 16px on a phone: see the note on .input - iOS zooms the page
     to focus anything smaller, and does not zoom back out. */
  .input, .textarea, .select { min-height: 38px; font-size: 16px; padding: 8px 12px; }
  .kicker { font-size: 12px; }
  .list-row { padding: 10px 13px; gap: 10px; }
  .av { width: 32px; height: 32px; font-size: 13px; }
  .av.lg { width: 46px; height: 46px; font-size: 17px; }
  .page-head .sub { font-size: 14px; }
  .hero .when { font-size: 14px; }
  .person .nm { font-size: 15px; }
  .rl, .rl.small { font-size: 13px; }
  .page-head h1 { font-size: 25px; }
  .hero { padding: 22px 18px; border-radius: var(--r-lg); }
  .hero h2 { font-size: 26px; }
  .card { padding: 18px 16px; }
  /* The nav used to add up to more than a phone is wide: four links, the
     brand and a name-bearing profile button, at desktop padding. The excess
     pushed the profile past the right edge and let the whole page slide
     sideways, which is what made it feel like it was floating.

     Same 16px gutter as .app above, so the Q and the profile line up with
     the cards rather than sitting inside their own wider margin. */
  /* viewport-fit=cover is set, so in landscape the notch eats the gutter
     unless the insets are honoured. max() keeps the normal 16px otherwise. */
  .nav-inner {
    gap: 10px;
    padding: 0 max(16px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left));
  }
  .app {
    padding-left: max(16px, env(safe-area-inset-left));
    padding-right: max(16px, env(safe-area-inset-right));
  }
  .brand-name { display: none; }
  /* Links take what is left and scroll inside themselves if they still do not
     fit, instead of shoving anything off-screen. */
  .nav-links { min-width: 0; overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none; }
  .nav-links::-webkit-scrollbar { display: none; }
  .nav-links a { padding: 8px 10px; font-size: 14px; white-space: nowrap; }
  /* Just the face. The name is the widest part of the button and it is already
     obvious whose session this is. */
  .nav-right { flex-shrink: 0; }
  .whoami { padding: 5px; gap: 0; }
  .whoami-name { display: none; }
  .board-row { grid-template-columns: auto 1fr auto; gap: 10px; padding: 13px 15px; }
  /* Tighter on a phone, but the medal must stay readable. */
  .board-row .av { width: 34px; height: 34px; font-size: 14px; }
  .board-row .av.medal { font-size: 25px; }
  .board-row .nm { font-size: 17px; }
  .board-row .sc { font-size: 20px; }
  .stage-bar { gap: 8px; padding: 12px 14px; }
  .stage-bar .count, .stage-bar .progress { display: none; }
  .nav-big { flex: 1; padding: 0 14px; font-size: 16px; }
}

@media print { .nav, .foot, .stage-bar { display: none !important; } }

/* The site admin's list of teams. Their code is the useful part, so it reads
   as something you copy rather than prose. */
.team-code {
  font-family: ui-monospace, monospace; font-size: 15px; font-weight: 700;
  letter-spacing: .08em; padding: 4px 10px; border-radius: var(--r-sm);
  background: var(--surface-2); border: 1px solid var(--line-soft);
  color: var(--ink-2);
}
.list-row.is-mine { background: var(--surface-2); border-radius: var(--r-sm); }

/* A button that is deliberately unavailable, with the reason on hover. Kept
   legible rather than ghosted away: it is information, not clutter. */
.btn.is-off, .btn.is-off:hover {
  opacity: .45; cursor: not-allowed; background: transparent;
}

/* Which team a typed code belongs to, on the sign-in card. */
.auth-team {
  margin-top: 8px; font-size: 14px; font-weight: 600;
  color: var(--good); text-align: center;
}

/* One team per fold. <details> so the browser handles keyboard and screen
   readers; the marker is replaced by a chevron that turns when it opens. */
.team-fold {
  border: 1px solid var(--line-soft); border-radius: var(--r);
  background: var(--surface); overflow: hidden;
}
.team-sum {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 18px; cursor: pointer; list-style: none;
  transition: background .18s var(--ease);
}
.team-sum::-webkit-details-marker { display: none; }
.team-sum:hover { background: var(--surface-2); }
.team-sum::before {
  content: '›'; color: var(--ink-3); font-size: 18px; line-height: 1;
  transition: transform .25s var(--ease); flex-shrink: 0;
}
.team-fold[open] > .team-sum::before { transform: rotate(90deg); }
.team-fold[open] > .team-sum { border-bottom: 1px solid var(--line-soft); }
.team-nm { font-size: 17px; font-weight: 600; letter-spacing: -.015em; }
.team-body { padding: 18px; }
.btn.quiet.sm.danger { color: #d0342c; }
.btn.quiet.sm.danger:hover { background: rgba(208,52,44,.12); }

/* A small pill-shaped action that sits beside a heading rather than under it -
   quiet enough not to compete with the primary button, solid enough to read
   as a control rather than a link. */
.btn.chip {
  /* .btn stands 46px tall for a thumb; a chip sits beside a heading and has to
     be shorter than the text it accompanies, so the floor comes off. */
  min-height: 0; padding: 7px 15px; font-size: 13.5px; font-weight: 550;
  border-radius: var(--pill); border: 1px solid var(--accent);
  background: var(--surface); color: var(--accent);
  transition: background .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
}
.btn.chip:hover { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.btn.chip:active { transform: scale(.97); }

/* A redraw that is not a new slide keeps what is on screen exactly where it is. */
.slide.still > * { animation: none; }

/* Presenting from a phone rather than a projector. The slide keeps its shape
   but stops trying to fill a wall, and scrolls when the question, the options
   and the answer will not fit at once. */
@media (max-width: 700px) {
  .stage-live { --pad: 16px; }
  /* The one place scrolling is allowed: a phone has too little height to fit a
     question, four answers and a picture, and clipping would hide an answer. */
  .slide { justify-content: flex-start; overflow-y: auto; }
  .slide > .tally { margin-top: 0; }
  .slide > :first-child, .slide > :last-child { margin-top: 0; margin-bottom: 0; }
  .s-q { font-size: 22px; line-height: 1.25; }
  .s-title { font-size: 28px; }
  .s-sub { font-size: 15px; }
  .s-kicker { font-size: 12px; margin-bottom: 10px; }
  .s-opts { gap: 8px; margin-top: 14px; }
  .s-opt { font-size: 16px; padding: 11px 14px; gap: 10px; }
  .s-opt .k { width: 30px; height: 30px; font-size: 14px; }
  .s-answer { margin-top: 14px; padding: 12px 14px; }
  .s-answer .val { font-size: 19px; }
  .s-media { flex: 0 1 auto; }
  .s-media img, .s-media video { max-height: 30vh; }

  /* The lobby is the worst offender: a QR sized for a projector, plus the code,
     pushed the Start button off the bottom of the screen. */
  .lobby-grid { gap: 14px; margin-top: 14px; flex-direction: column; }
  .lobby-join { padding: 14px; border-radius: 18px; gap: 6px; }
  .lobby-join .qr-code { padding: 8px; border-radius: 12px; }
  .lobby-join .qr-code svg { width: 150px; height: 150px; }
  .lobby-join-label { font-size: 15px; }
  .lobby-join-or { font-size: 12px; }
  .lobby-join-url { font-size: 13px; }
  .lobby-code { margin-top: 8px; padding-top: 8px; }
  .lobby-code .lbl { font-size: 10px; }
  .lobby-code .val { font-size: 20px; }
  .lobby-players { min-width: 0; }
  .lobby-players-count { font-size: 15px; }
  .lobby-face span { font-size: 12px; }
  .s-hint { font-size: 13px; margin-top: 10px; }
}

/* The topic on its own, before the first question. Bigger than a question,
   because it is the only thing on the screen and the point of the moment. */
.topic-slide {
  text-align: center;
  /* Nothing else is on this slide, so it sits in the middle of the screen
     rather than at the top like a question. */
  justify-content: center; align-items: center;
}
.topic-slide > * { margin-top: 0; margin-bottom: 0; }
.topic-slide .s-title { font-size: clamp(38px, min(7vw, 10.5vh), 116px); margin-top: 8px; }
@media (max-width: 700px) { .topic-slide .s-title { font-size: 32px; } }

/* The topic on a player's own screen: nothing to do here, so it sits in the
   middle of the screen rather than at the top like a question. */
.play.play-topic {
  justify-content: center; align-items: center; text-align: center; gap: 10px;
}
.play-topic-t {
  font-size: clamp(28px, 7vw, 40px); font-weight: 650;
  letter-spacing: -.025em; line-height: 1.15;
}

/* Same idea on a player's own screen: short answers pair up two to a row
   instead of four lonely full-width buttons. */
.play-opts.opts-tight {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
}
.play-opts.opts-tight .play-opt { justify-content: center; }
.play-opts.opts-tight .play-opt .t { flex: 0 1 auto; }
.play-opts.opts-pics {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
}
.play-q.q-long  { font-size: clamp(20px, 4.8vw, 27px); }
.play-q.q-xlong { font-size: clamp(18px, 4.2vw, 23px); line-height: 1.25; }

/* How much of the slide a picture takes, when the automatic share is not what
   the quiz master wanted. Still proportions rather than positions, so the slide
   keeps working on a projector and on a phone. */
.s-media.size-large { flex: 2 1 auto; }
.s-media.size-fill  { flex: 4 1 auto; }
.slide.has-media .s-media.size-fill ~ .s-opts { margin-top: clamp(10px, 1.4vh, 18px); }
/* Filling the slide means the question gets out of the way too. */
.slide.has-media .s-media.size-fill { margin-top: clamp(10px, 1.4vh, 18px); }
