/* Duel, three screens with one set of tokens.
 *
 * The wall sits inside the deck, in an iframe that fills a 1920 by 1080 slide,
 * so it wears the deck's clothes: the same paper, the same ink, the same one
 * accent, the same letter. Switching from a slide to Duel should look like the
 * next slide, not like another program. The deck has two themes and passes its
 * own on the address (?theme=pure or ?theme=zoku), pure being the default.
 *
 * The phone and the host panel use the same tokens at tool size, so the three
 * screens are visibly one thing.
 *
 * The fonts are the deck's own files (Inter, and Jost with Nunito Sans for the
 * Zoku theme), all under the Open Font License, served from /fonts so a room
 * without internet looks exactly the same.
 */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/fonts/inter-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/fonts/inter-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/fonts/jost-latin.woff2) format('woff2');
}
@font-face {
  font-family: 'Nunito Sans';
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url(/fonts/nunito-sans-latin.woff2) format('woff2');
}

/* --- tokens ----------------------------------------------------------------
   Pure is Dirck's own theme from the deck (theme-pure.css): black ink on white
   paper, zinc greys, and #ff7e35 as the one colour that means "look here".
   Zoku is the deck's other theme (theme-zoku.css): cream, coral, slate.      */

:root {
  /* Een kleur per antwoord, op de muur en op de telefoon dezelfde, zodat je
     op de kleur kiest. Uit het palet van de vierkanten. */
  --o1: #2563eb; --o1-ink: #ffffff;
  --o2: #db2777; --o2-ink: #ffffff;
  --o3: #f5b700; --o3-ink: #111111;
  --o4: #16a34a; --o4-ink: #ffffff;
  --o5: #7c3aed; --o5-ink: #ffffff;
  --o6: #0d9488; --o6-ink: #ffffff;
  --paper: #ffffff;
  --ink: #000000;
  --muted: #71717a;
  --dim: #a1a1aa;
  --line: #e4e4e7;
  --soft: #f4f4f5;
  --accent: #ff7e35;
  --accent-soft: #fff1e8;
  --accent-ink: #a8430b;
  --bar: #71717a;
  --track: transparent;
  --track-edge: var(--line);
  --bar-radius: 0px;
  --card-radius: 24px;
  --card-shadow: 0 2px 3px rgba(16, 12, 8, .04), 0 12px 28px rgba(16, 12, 8, .07);
  --error: #b3261e;

  --display: "Inter", -apple-system, system-ui, sans-serif;
  --body: "Inter", -apple-system, system-ui, sans-serif;
  --head-weight: 800;
  --head-track: -.038em;

  /* Kept for the host panel, which still speaks in zinc. */
  --zinc-900: #18181b;
  --zinc-700: #3f3f46;
  --zinc-500: #71717a;
  --zinc-200: #e4e4e7;
  --zinc-50: #fafafa;
}

:root[data-theme="zoku"] {
  --o1: #44596b; --o1-ink: #ffffff;
  --o2: #ff6264; --o2-ink: #ffffff;
  --o3: #e9a23b; --o3-ink: #111111;
  --o4: #4d888a; --o4-ink: #ffffff;
  --o5: #8e6fb3; --o5-ink: #ffffff;
  --o6: #855729; --o6-ink: #ffffff;
  --paper: #fdf5f2;
  --ink: #111111;
  --muted: #6b625f;
  --dim: #a09a97;
  --line: #e8dcd7;
  --soft: #f6e9e4;
  --accent: #ff6264;
  --accent-soft: #ffe7e5;
  --accent-ink: #b3373a;
  --bar: #7b93a6;
  --track: var(--line);
  --track-edge: transparent;
  --bar-radius: 6px;
  --card-shadow: 0 2px 3px rgba(40, 20, 12, .05), 0 12px 28px rgba(40, 20, 12, .09);

  --display: "freight-neo-pro", "Jost", "Helvetica Neue", sans-serif;
  --body: "bryant-web", "Nunito Sans", "Helvetica Neue", sans-serif;
  --head-weight: 500;
  --head-track: -.028em;
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--body);
  -webkit-font-smoothing: antialiased;
  background: var(--paper);
  color: var(--ink);
}

button {
  font: inherit;
  cursor: pointer;
  border: 1.5px solid var(--line);
  background: #fff;
  color: var(--ink);
  border-radius: 12px;
  padding: 9px 15px;
  -webkit-tap-highlight-color: transparent;
}
button:hover { border-color: var(--dim); }
button:disabled { opacity: .45; cursor: not-allowed; }
button.primary { background: var(--ink); border-color: var(--ink); color: #fff; font-weight: 700; }
button.primary:hover { background: #27272a; }

textarea, input {
  font: inherit;
  width: 100%;
  padding: 12px 14px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: #fff;
  color: inherit;
  resize: vertical;
}
textarea:focus, input:focus { outline: 2.5px solid var(--ink); outline-offset: -1px; border-color: transparent; }

.muted { color: var(--muted); }
.error { color: var(--error); }

/* --- host ------------------------------------------------------------------ */

.host { max-width: 1180px; margin: 0 auto; padding: 30px 22px 60px; }
.host h1 {
  font-family: var(--display);
  font-size: 30px;
  font-weight: var(--head-weight);
  letter-spacing: var(--head-track);
  margin: 0 0 4px;
}
.host .lede { margin: 0 0 24px; font-size: 15px; color: var(--muted); }

.host .cols { display: grid; grid-template-columns: 330px 1fr; gap: 22px; align-items: start; }
@media (max-width: 900px) { .host .cols { grid-template-columns: 1fr; } }

.card {
  background: #fff;
  border-radius: 20px;
  box-shadow: var(--card-shadow);
  padding: 18px;
}
.card + .card { margin-top: 16px; }
.card h2 {
  margin: 0 0 12px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}
.card .row { display: flex; gap: 8px; align-items: center; }
.card .row + .row { margin-top: 8px; }
.card .stack { display: flex; flex-direction: column; gap: 8px; }

.code {
  font-family: var(--display);
  font-size: 36px;
  font-weight: 800;
  letter-spacing: .14em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.links { font-size: 13px; line-height: 1.7; word-break: break-all; }
.links a { color: var(--ink); }

.phases { display: flex; flex-wrap: wrap; gap: 6px; }
.phases button.on { background: var(--ink); border-color: var(--ink); color: #fff; }

.entries { display: flex; flex-direction: column; gap: 8px; max-height: 62vh; overflow-y: auto; }
.entry {
  border: 1.5px solid var(--line);
  border-radius: 14px;
  padding: 10px 12px;
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap;
}
.entry .bar { display: flex; gap: 6px; align-items: center; margin-bottom: 6px; }
.entry .n { font-size: 12px; color: var(--muted); margin-right: auto; }
.entry.left { border-color: var(--ink); }
.entry.right { border-color: var(--accent); }
.entry button { padding: 3px 9px; font-size: 12px; border-radius: 999px; }

.tally { display: flex; gap: 18px; font-size: 15px; font-variant-numeric: tabular-nums; }

.games { display: flex; flex-direction: column; gap: 8px; }
.games .game { text-align: left; padding: 11px 13px; line-height: 1.35; }
.games .game b { display: block; font-size: 14px; }
.games .game span { font-size: 12px; color: var(--muted); }
.host .names { font-size: 14px; line-height: 1.7; color: var(--zinc-700); margin: 0; }
.host summary { font-size: 13px; cursor: pointer; }
.host .switch { display: block; margin-top: 14px; font-size: 13px; color: var(--muted); }
.host .switch select {
  display: block;
  width: 100%;
  margin-top: 5px;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  padding: 8px 10px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: #fff;
}

/* --- phone ------------------------------------------------------------------
   One hand, one thumb. Everything you tap is at least 56 points high, the
   option you picked is unmistakable, and what you sent stays visible.        */

.phone { max-width: 560px; margin: 0 auto; padding: 22px 18px 48px; }
.phone h1 {
  font-family: var(--display);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.01em;
  margin: 0 0 2px;
}
.phone #sub { font-size: 14px; margin: 0; }
.phone .prompt {
  margin: 22px 0 18px;
  font-family: var(--display);
  font-size: 27px;
  line-height: 1.16;
  font-weight: var(--head-weight);
  letter-spacing: -.025em;
  white-space: pre-wrap;
}
.phone textarea { min-height: 190px; font-size: 17px; line-height: 1.45; }  /* 16px or more keeps iOS from zooming in */
.phone input { font-size: 19px; padding: 15px 16px; }
.phone .send { margin-top: 14px; display: flex; gap: 10px; align-items: center; }
.phone .ask { margin: -4px 0 14px; font-size: 17px; font-weight: 700; color: var(--accent, #ff7e35); line-height: 1.35; }
.phone .send button { flex: 1; min-height: 58px; padding: 14px; font-size: 18px; border-radius: 16px; transition: background .25s, border-color .25s; }
.phone .send button.primary.sent { background: #16a34a; border-color: #16a34a; color: #fff; }
.confetti { position: fixed; inset: 0; pointer-events: none; z-index: 50; overflow: hidden; }
.confetti i { position: absolute; width: 9px; height: 14px; border-radius: 2px; }
.phone .state { margin-top: 16px; font-size: 15px; line-height: 1.45; }
.phone .state:empty { display: none; }
.phone .state.ok {
  color: var(--ink);
  font-weight: 600;
  background: var(--accent-soft);
  border-radius: 14px;
  padding: 12px 14px;
}
.phone .state.error { color: var(--error); font-weight: 600; background: var(--paper); padding: 12px 14px; border-radius: 14px; }
/* A tap on a card sends on its own, so there is no button above the message
   and the list of cards can push it off the screen. There "Sent" and an error
   float at the bottom, in view, also when the card you tapped is low down. */
.phone .send:empty + .state.ok, .phone .send:empty + .state.error {
  position: sticky;
  bottom: max(12px, env(safe-area-inset-bottom));
  z-index: 2;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .10);
}

/* Kiezen. Grote kaarten onder elkaar, met een letter die ook op de muur staat. */
.phone .opts { display: flex; flex-direction: column; gap: 12px; }
.phone .opt {
  display: flex;
  gap: 14px;
  align-items: center;
  width: 100%;
  min-height: 68px;
  text-align: left;
  padding: 14px 16px;
  font-size: 18px;
  line-height: 1.38;
  border: 2px solid var(--line);
  border-radius: 18px;
  background: #fff;
  transition: background 140ms, border-color 140ms, transform 120ms;
}
.phone .opt:active { transform: scale(.985); }
.phone .opt .letter {
  flex: none;
  width: 38px; height: 38px;
  border-radius: 999px;
  background: var(--soft);
  color: var(--ink);
  display: grid; place-items: center;
  font-size: 16px; font-weight: 800;
}
.phone .opt .text { flex: 1; }
.phone .opt .tick {
  flex: none;
  width: 28px; height: 28px;
  border-radius: 999px;
  border: 2px solid var(--line);
  display: grid; place-items: center;
  color: transparent;
  font-size: 16px; font-weight: 800;
}
/* Elke optie in de kleur van zijn blok op de muur. Gekozen: een ring en een
   vinkje, de rest wordt stiller. Opnieuw tikken op een ander kan altijd. */
.phone .opt { background: var(--c, var(--o1)); border-color: var(--c, var(--o1)); color: var(--ci, #fff); font-weight: 650; }
.phone .opt:nth-child(6n+1) { --c: var(--o1); --ci: var(--o1-ink); }
.phone .opt:nth-child(6n+2) { --c: var(--o2); --ci: var(--o2-ink); }
.phone .opt:nth-child(6n+3) { --c: var(--o3); --ci: var(--o3-ink); }
.phone .opt:nth-child(6n+4) { --c: var(--o4); --ci: var(--o4-ink); }
.phone .opt:nth-child(6n+5) { --c: var(--o5); --ci: var(--o5-ink); }
.phone .opt:nth-child(6n+6) { --c: var(--o6); --ci: var(--o6-ink); }
.phone .opt .letter { background: rgba(255, 255, 255, .24); color: inherit; }
.phone .opt .tick { border-color: currentColor; opacity: .5; }
.phone .opts:has(.on) .opt:not(.on) { opacity: .42; }
.phone .opt.on { box-shadow: 0 0 0 3px #fff, 0 0 0 6px var(--ink); }
.phone .opt.on .tick { background: #fff; border-color: #fff; color: var(--ink); opacity: 1; }
/* A whole sentence to tap (spot the hallucination) starts at the top. */
.phone .opts.long .opt { font-size: 17px; align-items: flex-start; }

.phone .scale {
  display: block;
  margin-top: 22px;
  padding: 18px 16px 16px;
  border-radius: 18px;
  background: var(--soft);
}
.phone .scale span { display: flex; align-items: baseline; justify-content: space-between; font-size: 16px; font-weight: 600; }
.phone .scale b {
  font-family: var(--display);
  font-size: 40px;
  font-weight: 800;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}
.phone .scale input[type=range] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 48px;
  margin: 8px 0 0;
  padding: 0;
  border: 0;
  background: transparent;
  touch-action: pan-y;
}
.phone .scale input[type=range]:focus { outline: none; }
.phone .scale input[type=range]::-webkit-slider-runnable-track {
  height: 12px; border-radius: 999px;
  background: linear-gradient(to right, var(--accent) var(--fill, 50%), var(--line) var(--fill, 50%));
}
.phone .scale input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 40px; height: 40px; margin-top: -14px;
  border-radius: 999px;
  background: #fff;
  border: 3px solid var(--ink);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
}
.phone .scale input[type=range]::-moz-range-track { height: 12px; border-radius: 999px; background: var(--line); }
.phone .scale input[type=range]::-moz-range-progress { height: 12px; border-radius: 999px; background: var(--accent); }
.phone .scale input[type=range]::-moz-range-thumb {
  width: 34px; height: 34px; border-radius: 999px; background: #fff; border: 3px solid var(--ink);
}
.phone .scale .ends { display: flex; justify-content: space-between; font-size: 13px; color: var(--muted); }

.phone .choice { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px; }
.phone .choice button {
  min-height: 120px;
  font-family: var(--display);
  font-size: 24px;
  font-weight: 800;
  border: 2px solid var(--line);
  border-radius: 20px;
}
.phone .choice button.on { background: var(--ink); border-color: var(--ink); color: #fff; }
.phone .said {
  border-radius: 14px;
  padding: 13px 14px;
  font-size: 16px;
  line-height: 1.5;
  white-space: pre-wrap;
  background: var(--soft);
}

/* De open vraag: één korte regel, en meteen zichtbaar hoe hij op de muur staat. */
.phone textarea.short { min-height: 0; height: auto; resize: none; font-size: 19px; }
.phone .onwall {
  margin-top: 10px;
  padding: 14px 16px;
  border-radius: 16px;
  background: var(--ink);
  color: #fff;
  font-size: 17px;
  line-height: 1.35;
}
.phone .onwall .by { display: block; font-size: 13px; font-weight: 700; color: var(--accent); margin-bottom: 3px; }
.phone .onwall-label { margin: 18px 0 0; font-size: 13px; color: var(--muted); }

/* --- stage ------------------------------------------------------------------
   One canvas of exactly 1920 by 1080, the size of a slide, scaled to whatever
   window it is in. So every size below is the size it has on the slide, the
   wall at 1280 by 720 is the same picture smaller, and nothing reflows.     */

body.stage { overflow: hidden; min-height: 100vh; }
.canvas {
  position: absolute;
  left: 50%; top: 50%;
  width: 1920px; height: 1080px;
  transform: translate(-50%, -50%) scale(var(--k, 1));
  transform-origin: center center;
  background: var(--paper);
  overflow: hidden;
}

.wall {
  position: absolute;
  inset: 0;
  padding: 96px 128px;
  display: flex;
  flex-direction: column;
  gap: 32px;
  justify-content: center;
}

.wall .kicker {
  margin: 0;
  font-family: var(--body);
  font-size: 24px;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}
.wall .q {
  margin: 0;
  font-family: var(--display);
  font-size: 80px;
  font-weight: var(--head-weight);
  line-height: 1.06;
  letter-spacing: var(--head-track);
  white-space: pre-wrap;
  max-width: 22ch;
}
.wall .q.sm { font-size: 58px; max-width: 30ch; }
.wall .q3 {
  margin: 0;
  font-family: var(--display);
  font-size: 50px;
  font-weight: var(--head-weight);
  line-height: 1.12;
  letter-spacing: var(--head-track);
  max-width: 40ch;
}
.wall .counter {
  margin: 0;
  font-size: 30px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: center;
  gap: 14px;
}
.wall .counter b { color: var(--ink); font-weight: 700; }
.dot {
  width: 16px; height: 16px;
  border-radius: 999px;
  background: var(--accent);
  flex: none;
  animation: breathe 1.8s ease-in-out infinite;
}
@keyframes breathe { 50% { opacity: .35; transform: scale(.8); } }

.chip {
  display: inline-block;
  padding: 8px 18px;
  border-radius: 999px;
  background: var(--soft);
  color: var(--accent);
  font-size: 26px;
  font-weight: 700;
  letter-spacing: .12em;
}

/* The QR on a plain white card. The svg carries its own white margin (four
   modules, as the spec asks), so the card needs little padding and no frame. */
.qr {
  flex: none;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--card-radius);
  box-shadow: var(--card-shadow);
  padding: 10px;
}
.qr img { display: block; width: 100%; height: auto; }

/* --- de lobby -------------------------------------------------------------- */

.lobby { display: grid; grid-template-columns: 500px 1fr; gap: 96px; flex: 1; min-height: 0; }
.lobby .join { display: flex; flex-direction: column; gap: 22px; align-items: flex-start; }
.lobby .join .qr { width: 420px; }
.lobby .url { margin: 6px 0 0; font-size: 30px; font-weight: 700; line-height: 1.2; overflow-wrap: anywhere; }
.lobby .note { margin: 0; font-size: 26px; line-height: 1.4; color: var(--muted); }
.lobby .people { display: flex; flex-direction: column; gap: 28px; min-height: 0; }
.roster {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .4em .45em;
  align-content: flex-start;
  overflow: hidden;
  font-size: 40px;
}
.roster .who {
  background: var(--soft);
  border-radius: 999px;
  padding: .26em .7em;
  font-weight: 600;
  line-height: 1.2;
  animation: pop 420ms cubic-bezier(.22, 1, .36, 1);
}
.roster .none { color: var(--dim); font-size: 34px; }
@keyframes pop { from { opacity: 0; transform: scale(.7); } }

/* --- verzamelen ------------------------------------------------------------ */

.collect { display: grid; grid-template-columns: 1fr 380px; gap: 96px; align-items: center; flex: 1; min-height: 0; }
.collect .main { display: flex; flex-direction: column; gap: 32px; min-height: 0; max-height: 100%; }
.collect .join { display: flex; flex-direction: column; gap: 18px; align-items: flex-start; }
.collect .join .qr { width: 380px; }
.collect .join .url { margin: 4px 0 0; font-size: 24px; font-weight: 700; overflow-wrap: anywhere; }

/* De antwoorden als gekleurde blokken. Kort: twee bij twee. Lange zinnen:
   volle breedte onder elkaar. Dezelfde kleur staat op de telefoon. */
.choices {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .4em;
  min-height: 0;
  overflow: hidden;
  font-size: 34px;
}
.choices.long { grid-template-columns: 1fr; gap: .3em; }
.choices li {
  display: flex;
  gap: .6em;
  align-items: center;
  min-height: 2.6em;
  padding: .55em .8em;
  border-radius: 18px;
  background: var(--c, var(--o1));
  color: var(--ci, #fff);
  font-weight: 700;
  line-height: 1.25;
}
.choices.long li { min-height: 0; padding: .45em .7em; font-weight: 600; }
.choices li:nth-child(6n+1) { --c: var(--o1); --ci: var(--o1-ink); }
.choices li:nth-child(6n+2) { --c: var(--o2); --ci: var(--o2-ink); }
.choices li:nth-child(6n+3) { --c: var(--o3); --ci: var(--o3-ink); }
.choices li:nth-child(6n+4) { --c: var(--o4); --ci: var(--o4-ink); }
.choices li:nth-child(6n+5) { --c: var(--o5); --ci: var(--o5-ink); }
.choices li:nth-child(6n+6) { --c: var(--o6); --ci: var(--o6-ink); }
.choices .l {
  flex: none;
  width: 1.6em; height: 1.6em;
  border-radius: 999px;
  background: rgba(255, 255, 255, .24);
  display: inline-grid; place-items: center;
  font-size: .8em;
  font-weight: 800;
}

/* De uitslag als staafdiagram. Per antwoord een kolom in de kleur van zijn
   blok, zo hoog als zijn deel van de tikken, het getal erboven. Eronder het
   antwoord zelf in een blok van dezelfde kleur. Bij de onthulling een kader en
   een label op het ene dat telt, de rest vervaagt. */
.chart {
  flex: 1;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  /* Minstens 300px staaf. Past het niet, dan loopt het over en maakt fit() de
     letter kleiner, in plaats van dat de staven verdwijnen. */
  grid-template-rows: minmax(300px, 1fr) auto;
  column-gap: .6em;
  row-gap: .3em;
  margin: 0 -14px;
  padding: .7em 14px 14px;
  overflow: hidden;
  font-size: 40px;
}
.chart .k0 { --c: var(--o1); --ci: var(--o1-ink); }
.chart .k1 { --c: var(--o2); --ci: var(--o2-ink); }
.chart .k2 { --c: var(--o3); --ci: var(--o3-ink); }
.chart .k3 { --c: var(--o4); --ci: var(--o4-ink); }
.chart .k4 { --c: var(--o5); --ci: var(--o5-ink); }
.chart .k5 { --c: var(--o6); --ci: var(--o6-ink); }
.chart .bar {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  min-height: 0;
  padding-top: 2.8em;
  border-bottom: 4px solid var(--line);
  transition: opacity 500ms;
}
.chart .col {
  position: relative;
  width: 64%;
  height: calc(var(--p) * 100%);
  min-height: 10px;
  transition: height 700ms cubic-bezier(.22, 1, .36, 1);
}
.chart .col i { position: absolute; inset: 0; border-radius: 14px 14px 0 0; background: var(--c); transform-origin: bottom; }
.chart .num {
  position: absolute;
  left: -25%; right: -25%;
  bottom: 100%;
  padding-bottom: .2em;
  text-align: center;
  line-height: 1;
}
.chart .num b { display: block; font-size: 2em; font-weight: 800; font-variant-numeric: tabular-nums; }
.chart .num small { display: block; margin-top: .2em; font-size: .5em; font-weight: 600; color: var(--muted); }
.chart.grow .col i { animation: rise 900ms cubic-bezier(.22, 1, .36, 1) both; }
.chart.grow .num { animation: show-num 400ms 600ms both; }
@keyframes rise { from { transform: scaleY(0); } }
@keyframes show-num { from { opacity: 0; transform: translateY(.3em); } }
.chart .tile {
  position: relative;
  display: flex;
  gap: .45em;
  align-items: flex-start;
  padding: .5em .6em;
  border-radius: 16px;
  background: var(--c);
  color: var(--ci);
  font-weight: 700;
  line-height: 1.22;
  overflow-wrap: anywhere;
  transition: opacity 500ms;
}
.chart.long .tile { font-weight: 600; }
.chart .tile .l {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.5em; height: 1.5em;
  border-radius: 50%;
  background: rgba(255, 255, 255, .24);
  font-size: .85em;
  font-weight: 800;
}
.chart .tile .src { display: block; margin-top: .35em; font-size: .7em; font-weight: 600; opacity: .9; }
.chart .wrong { opacity: .45; }
.chart .tile.right { box-shadow: 0 0 0 5px var(--paper), 0 0 0 10px var(--ink); z-index: 1; }
.chart .badge {
  position: absolute;
  top: -.75em; right: .7em;
  padding: .3em .8em;
  border-radius: 999px;
  background: var(--ink);
  color: var(--paper);
  font-size: .6em;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .chart.grow .col i, .chart.grow .num { animation: none; }
}

/* --- wat de zaal deed ------------------------------------------------------ */

.room { display: flex; flex-direction: column; gap: 40px; flex: 1; min-height: 0; justify-content: center; }
.room > * { min-height: 0; }

/* Liggende staven, als op de slide met "The cat sat on the": het woord rechts
   uitgelijnd, een spoor met een rand, het getal grijs erachter. De eerste is
   oranje, de rest grijs. Eén kleur, één betekenis. */
.hbars { display: flex; flex-direction: column; gap: 26px; }
.hb { display: grid; grid-template-columns: var(--wcol, 340px) 1fr 150px; gap: 30px; align-items: center; }
.hb .w { font-size: 40px; font-weight: 600; text-align: right; line-height: 1.15; overflow-wrap: anywhere; }
/* Wie toch een hele zin typt, krijgt één regel met puntjes: drie regels per
   staaf duwen de rest van de muur van het scherm. */
.hbars:not(.stacked) .hb .w { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.hb .track {
  height: 44px;
  background: var(--track);
  box-shadow: inset 0 0 0 3px var(--track-edge);
  border-radius: var(--bar-radius);
  overflow: hidden;
}
.hb .track i {
  display: block;
  height: 100%;
  width: 100%;
  transform: scaleX(var(--p, 0));
  transform-origin: left center;
  background: var(--bar);
  transition: transform 600ms cubic-bezier(.22, 1, .36, 1);
}
.hb .c { font-size: 34px; color: var(--muted); font-variant-numeric: tabular-nums; line-height: 1.1; }
.hb .c small { display: block; font-size: 22px; }
.hb.lead .track i, .hb.right .track i { background: var(--accent); }
.hb.ink .track i { background: var(--ink); }
.hb.wrong .w { color: var(--dim); }
.hb.wrong .track i { background: var(--line); }
.hb.right .w { font-weight: 800; }

/* Long labels go above their bar instead of next to it. */
.hbars.stacked { gap: 22px; }
.hbars.stacked .hb { grid-template-columns: 1fr 150px; row-gap: 10px; }
.hbars.stacked .hb .w { grid-column: 1 / -1; text-align: left; font-size: 30px; font-weight: 500; }
.hbars.stacked .hb.right .w { font-weight: 800; }
.hbars.stacked .hb .track { height: 34px; }

.twoup { display: grid; grid-template-columns: 1fr 1fr; gap: 96px; min-height: 0; }
.twoup > div { display: flex; flex-direction: column; gap: 26px; min-height: 0; }
.twoup .hb { --wcol: 230px; grid-template-columns: var(--wcol) 1fr 90px; gap: 22px; }
.twoup .hb .w { font-size: 34px; }
.twoup .hb .c { font-size: 30px; }
.tag {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}
.tag.hot { color: var(--accent-ink); }

/* Zeker tegenover goed. Het gat tussen die twee getallen is de les. */
.gap { display: flex; gap: 120px; }
.gap b {
  display: block;
  font-family: var(--display);
  font-size: 150px;
  font-weight: var(--head-weight);
  letter-spacing: -.05em;
  line-height: .95;
}
.gap div:first-child b { color: var(--accent); }
.gap span { display: block; margin-top: 10px; font-size: 28px; color: var(--muted); }

/* De alinea met de warmtekaart. De tekst loopt door, zodat je hem als één
   verhaal leest terwijl je ziet waar iedereen wees. */
.para {
  margin: 0;
  font-size: 44px;
  line-height: 1.7;
  overflow: hidden;
  max-width: 64ch;
}
.para .span {
  padding: .1em .2em;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) calc(var(--h, 0) * 42%), transparent);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.para .span i {
  font-style: normal;
  font-size: .5em;
  font-weight: 800;
  vertical-align: .35em;
  margin-left: .3em;
  padding: .12em .5em;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
}
.para .span.right { box-shadow: 0 0 0 4px var(--ink); background: var(--accent-soft); }
.para .span.right i { background: var(--accent); }
.para .word { display: inline-block; margin-bottom: .2em; }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14em, 1fr));
  gap: .7em;
  align-content: start;
  overflow: hidden;
  font-size: 30px;
}
.grid .said {
  background: var(--soft);
  border-radius: var(--card-radius);
  padding: .8em .95em;
  line-height: 1.42;
  white-space: pre-wrap;
}
/* Every entry its own block colour, like the answers on the phones. */
.grid .said { background: var(--c, var(--soft)); color: var(--ci, inherit); font-weight: 600; }
.grid .said:nth-child(6n+1) { --c: var(--o1); --ci: var(--o1-ink); }
.grid .said:nth-child(6n+2) { --c: var(--o2); --ci: var(--o2-ink); }
.grid .said:nth-child(6n+3) { --c: var(--o3); --ci: var(--o3-ink); }
.grid .said:nth-child(6n+4) { --c: var(--o4); --ci: var(--o4-ink); }
.grid .said:nth-child(6n+5) { --c: var(--o5); --ci: var(--o5-ink); }
.grid .said:nth-child(6n+6) { --c: var(--o6); --ci: var(--o6-ink); }
.grid .said .by { color: inherit; opacity: .7; }

/* The code stays on the wall, small in the corner, for whoever is late. */
.qrcorner { position: absolute; top: 32px; right: 48px; width: 176px; z-index: 2; }
.qrcorner .qr { width: 176px; padding: 6px; border-radius: 16px; }
.wall:has(.qrcorner) .q3 { padding-right: 120px; }

/* Many entries: a list you scroll on the wall, the letter stays readable. */
.grid.scroll { overflow-y: auto; min-height: 0; flex: 0 1 auto; padding-right: 10px; overscroll-behavior: contain; }
.grid.scroll::-webkit-scrollbar { width: 14px; }
.grid.scroll::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }
.grid.scroll::-webkit-scrollbar-track { background: transparent; }
.said .by { display: block; font-size: .72em; font-weight: 700; color: var(--accent-ink); margin-bottom: .3em; }

.out-panel { display: flex; flex-direction: column; gap: 22px; min-height: 0; }
.out-panel .out {
  background: var(--accent-soft);
  color: var(--ink);
  border-radius: var(--card-radius);
  padding: 30px 34px;
  font-size: 30px;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow: hidden;
  min-height: 0;
}

/* --- het duel -------------------------------------------------------------- */

.versus { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; min-height: 0; flex: 1; }
.versus .side { display: flex; flex-direction: column; gap: 20px; min-height: 0; }
.versus .said {
  background: var(--soft);
  border-radius: var(--card-radius);
  padding: 24px 28px;
  font-size: 28px;
  line-height: 1.42;
  white-space: pre-wrap;
  max-height: 290px;
  overflow: hidden;
  flex: none;
}
.versus .out {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  font-size: 28px;
  line-height: 1.45;
  white-space: pre-wrap;
  border-top: 4px solid var(--ink);
  padding-top: 20px;
}
.versus .right .out { border-top-color: var(--accent); }
.out p { margin: 0 0 .55em; }
.out p:last-child { margin-bottom: 0; }
.versus .left .tag { color: var(--ink); }
.versus .right .tag { color: var(--accent-ink); }
.votes .hb { --wcol: 200px; }
.votes .hb.left .track i { background: var(--ink); }
.votes .hb.right .track i { background: var(--accent); }

/* --- de open vraag ----------------------------------------------------------
   The icebreaker, as a cloud of squares. One square per line of work, its
   area grows with the number of people in it, and the room watches it grow.
   Only this round looks like this.                                          */

.open { position: absolute; inset: 0; }

.open .pill {
  position: absolute;
  top: 40px; left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 12px 10px 28px;
  border-radius: 999px;
  background: var(--soft);
  font-size: 26px;
  white-space: nowrap;
  transition: opacity 400ms;
}
.open .pill .lab { color: var(--muted); }
.open .pill b { font-weight: 700; }
.open .pill .chip { background: #fff; font-size: 24px; padding: 6px 16px; }

.open .qrcard {
  position: absolute;
  top: 32px; right: 48px;
  width: 264px;
  transform-origin: center;
  transition: opacity 400ms, top 900ms var(--glide), right 900ms var(--glide), transform 900ms var(--glide);
}
.open { --glide: cubic-bezier(.65, 0, .25, 1); }
/* Nobody in yet: the question in the middle and the code big under it. */
.open.empty .qrcard { top: calc(50% + 120px - 132px); right: calc(50% - 132px); transform: scale(1.65); }
.open.empty .ohead { top: calc(50% - 330px); }
.open.empty .owait { opacity: 0; }
.open .qrcard .qr { width: 264px; padding: 8px; border-radius: 20px; }

.open .ohead {
  position: absolute;
  top: 128px; left: 50%;
  transition: top 900ms var(--glide);
  transform: translateX(-50%);
  width: 1180px;
  text-align: center;
}
.open .oq {
  margin: 0;
  font-family: var(--display);
  font-size: 84px;
  font-weight: var(--head-weight);
  letter-spacing: var(--head-track);
  line-height: 1.02;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* Room for the tail of a y or g: overflow cuts at the line box, and a
     line-height this tight puts descenders outside it. */
  padding: .04em 0 .16em;
  margin: -.04em 0 -.16em;
}
.open .ocount {
  margin: 16px 0 0;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: 26px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.open .ocount b { color: var(--ink); }
.open.closed .pill, .open.closed .qrcard { opacity: 0; pointer-events: none; }
.open.closed .dot { display: none; }

.open .cloud { position: absolute; left: 64px; right: 64px; top: 300px; bottom: 36px; }
.open .owait {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  margin: 0;
  font-size: 34px;
  color: var(--dim);
  transition: opacity 400ms 500ms;
}

/* A square. Its box is placed by its middle, so it grows from the middle
   out: width and height spring, the position glides. */
.sq {
  position: absolute;
  left: 0; top: 0;
  container-type: size;
  transition:
    width 950ms cubic-bezier(.3, 1.32, .55, 1),
    height 950ms cubic-bezier(.3, 1.32, .55, 1),
    transform 900ms cubic-bezier(.22, 1, .36, 1),
    opacity 400ms;
}
.cloud.still .sq { transition: none; }
.sq .face {
  position: absolute;
  inset: 0;
  border-radius: clamp(14px, 11cqi, 30px);
  background: var(--c);
  color: var(--on);
  box-shadow: var(--card-shadow);
  padding: 8cqi 8.5cqi;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.sq .lab {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(15px, 9.4cqi, 46px);
  line-height: 1.04;
  letter-spacing: -.025em;
  overflow-wrap: anywhere;
}
.sq .who {
  flex: 1;
  min-height: 0;
  margin-top: 4.5cqi;
  font-size: clamp(13px, 5.2cqi, 22px);
  line-height: 1.3;
  opacity: .9;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 80%, transparent);
  mask-image: linear-gradient(to bottom, #000 80%, transparent);
}
.sq .who .ln { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sq .who .ln b { font-weight: 700; }
.sq .cnt {
  margin-top: auto;
  align-self: flex-end;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(22px, 17cqi, 120px);
  line-height: .8;
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
}
.sq:not(.roomy) .who { display: none; }
/* A small square only has room for its name and its number, centred. */
@container (max-height: 175px) {
  .sq .face { justify-content: center; align-items: center; text-align: center; padding: 8cqi; }
  .sq .lab { font-size: clamp(14px, 11cqi, 30px); }
  .sq .cnt { margin-top: 5cqi; align-self: center; font-size: clamp(20px, 21cqi, 46px); }
}

.sq.born .face { animation: born 800ms cubic-bezier(.3, 1.32, .55, 1) both; }
@keyframes born { from { transform: scale(.15); opacity: 0; } }
.sq.hit .face { animation: hit 900ms ease-out; }
@keyframes hit {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--c) 60%, transparent), var(--card-shadow); }
  100% { box-shadow: 0 0 0 26px transparent, var(--card-shadow); }
}
.sq.gone { opacity: 0; }

/* Who just answered, for a few seconds, at the square it landed in. */
.pop {
  position: absolute;
  left: 0; top: 0;
  z-index: 5;
  max-width: 560px;
  padding: 12px 20px;
  border-radius: 16px;
  background: var(--ink);
  color: #fff;
  font-size: 26px;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
  animation: popin 520ms cubic-bezier(.22, 1, .36, 1) both;
  transition: opacity 500ms;
}
.pop b { color: var(--accent); font-weight: 700; margin-right: .25em; }
.pop.out { opacity: 0; }
@keyframes popin { from { opacity: 0; scale: .6; } }

@media (prefers-reduced-motion: reduce) {
  .sq, .hb .track i, .pop { transition: none; }
  .sq.born .face, .sq.hit .face, .pop, .roster .who, .dot { animation: none; }
}

/* The stage tells the room when it lost the server, quietly, in a corner. */
body.offline .canvas::after {
  content: '';
  position: absolute;
  right: 24px; bottom: 24px;
  width: 14px; height: 14px;
  border-radius: 999px;
  background: var(--dim);
}
/* The pair slide after the prompt wall: entry 2 in orange, as on the deck. */
.versus.pair { flex: 0 1 auto; align-items: start; }
.versus.pair .right .said { background: var(--accent-soft); color: var(--accent-ink); }
