/* Duel, three screens with one set of tokens.
 *
 * The wall is dark because a beamer in a lit room washes out light backgrounds,
 * and because the deck it sits between is light: switching to Duel should look
 * like switching, not like a slide that failed to load.
 *
 * The host panel and the phone are the ordinary tool look, zinc neutrals, so
 * nothing on them competes for attention with what is on the wall.
 */

:root {
  --zinc-950: #09090b;
  --zinc-900: #18181b;
  --zinc-800: #27272a;
  --zinc-700: #3f3f46;
  --zinc-500: #71717a;
  --zinc-400: #a1a1aa;
  --zinc-200: #e4e4e7;
  --zinc-50: #fafafa;

  --accent: #ff7e35;
  --good: #4d888a;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
}

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

body {
  margin: 0;
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  background: var(--zinc-50);
  color: var(--zinc-900);
}

button {
  font: inherit;
  cursor: pointer;
  border: 1px solid var(--zinc-200);
  background: #fff;
  color: var(--zinc-900);
  border-radius: 8px;
  padding: 8px 14px;
}
button:hover { background: var(--zinc-50); }
button:disabled { opacity: .45; cursor: not-allowed; }
button.primary { background: var(--zinc-900); border-color: var(--zinc-900); color: #fff; }
button.primary:hover { background: var(--zinc-800); }

textarea, input {
  font: inherit;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--zinc-200);
  border-radius: 8px;
  background: #fff;
  color: inherit;
  resize: vertical;
}
textarea:focus, input:focus { outline: 2px solid var(--zinc-700); outline-offset: -1px; }

.muted { color: var(--zinc-500); }
.error { color: #b3261e; }

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

.host { max-width: 1180px; margin: 0 auto; padding: 26px 22px 60px; }
.host h1 { font-size: 22px; margin: 0 0 3px; letter-spacing: -.01em; }
.host .lede { margin: 0 0 22px; font-size: 14px; color: var(--zinc-500); }

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

.card {
  background: #fff;
  border: 1px solid var(--zinc-200);
  border-radius: 12px;
  padding: 16px;
}
.card + .card { margin-top: 14px; }
.card h2 {
  margin: 0 0 12px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--zinc-500);
}
.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-size: 34px;
  font-weight: 700;
  letter-spacing: .18em;
  font-variant-numeric: tabular-nums;
}
.links { font-size: 13px; line-height: 1.7; word-break: break-all; }
.links a { color: var(--zinc-900); }

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

.entries { display: flex; flex-direction: column; gap: 8px; max-height: 62vh; overflow-y: auto; }
.entry {
  border: 1px solid var(--zinc-200);
  border-radius: 10px;
  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(--zinc-500); margin-right: auto; }
.entry.left { border-color: var(--accent); }
.entry.right { border-color: var(--good); }
.entry button { padding: 3px 9px; font-size: 12px; border-radius: 999px; }

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

/* --- stage ----------------------------------------------------------------- */

body.stage {
  background: var(--zinc-950);
  color: var(--zinc-50);
  min-height: 100vh;
  overflow: hidden;
}
.wall {
  /* Vast op de hoogte van het scherm, niet minimaal. Een lange inzending
     scrollt dan binnen zijn eigen vak in plaats van van de muur af te lopen. */
  height: 100vh;
  padding: 5vh 5vw;
  display: flex;
  flex-direction: column;
  gap: 3vh;
  justify-content: center;
}
.wall .prompt {
  font-size: clamp(30px, 4.2vw, 74px);
  line-height: 1.14;
  font-weight: 600;
  letter-spacing: -.02em;
  white-space: pre-wrap;
  margin: 0;
}
.wall .kicker {
  font-size: clamp(15px, 1.45vw, 28px);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--zinc-500);
  margin: 0;
}
.wall .joinbar { display: flex; align-items: center; gap: 4vw; }
.wall .joinbar .qr { width: min(36vh, 28vw); flex: none; background: #fff; padding: 12px; border-radius: 14px; }
/* img as well as svg: the QR is loaded as an image, and without this it paints
   at its own intrinsic size and walks straight over the text next to it. */
.wall .joinbar .qr img,
.wall .joinbar .qr svg { display: block; width: 100%; height: auto; }
.wall .joinbar .how { font-size: clamp(18px, 1.8vw, 34px); line-height: 1.45; }
.wall .joinbar .how b { display: block; font-size: clamp(26px, 3vw, 56px); letter-spacing: .05em; }
.wall .counter { font-size: clamp(22px, 2.4vw, 44px); color: var(--zinc-400); font-variant-numeric: tabular-nums; }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 26vw), 1fr));
  gap: 14px;
  overflow-y: auto;
}
.grid .said {
  background: var(--zinc-900);
  border-radius: 12px;
  padding: 1.8vh 1.4vw;
  font-size: clamp(18px, 1.75vw, 34px);
  line-height: 1.5;
  white-space: pre-wrap;
}

/* Achter in de zaal moet je dit kunnen lezen, dus de tekst staat op dezelfde
   maat als een slide: rond 34px op een scherm van 1920 breed. */
/* Zo hoog als de inhoud, en niet hoger dan wat er over is. Dan staat een kort
   duel in het midden van de muur en scrollt een lang antwoord in zijn eigen vak. */
.versus {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: minmax(0, 1fr);
  gap: 3vw;
  flex: 0 1 auto;
  min-height: 0;
}
.versus .side { display: flex; flex-direction: column; gap: 1.6vh; min-height: 0; }
.versus .tag {
  font-size: clamp(14px, 1.3vw, 26px);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--zinc-500);
}
.versus .said {
  background: var(--zinc-900);
  border-radius: 12px;
  padding: 2vh 1.6vw;
  font-size: clamp(18px, 1.75vw, 34px);
  line-height: 1.4;
  white-space: pre-wrap;
  max-height: 32vh;
  overflow-y: auto;
  flex: none;
}
.versus .out {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  font-size: clamp(18px, 1.8vw, 35px);
  line-height: 1.4;
  white-space: pre-wrap;
}
.versus .left .tag { color: var(--accent); }
.versus .right .tag { color: var(--good); }

/* Scaled, not resized. These grow while a room watches them, and a bar that
   animates its height relayouts the whole wall on every vote. */
/* Twee staande staven op een spoor dat er altijd staat. Zonder dat spoor leest
   een staaf met de meeste stemmen als een blok en de andere als een streep, en
   zie je niet dat het twee delen van één geheel zijn. */
.bars { display: flex; gap: 3vw; height: 28vh; flex: none; }
.bars .b { flex: 1; display: grid; grid-template-rows: auto 1fr; gap: 1vh; min-height: 0; }
.bars .track { overflow: hidden; border-radius: 12px; background: var(--zinc-900); }
.bars .fill {
  height: 100%;
  transform: scaleY(var(--p, 0));
  transform-origin: bottom center;
  transition: transform 400ms cubic-bezier(.22, .61, .36, 1);
}
.bars .left .fill { background: var(--accent); }
.bars .right .fill { background: var(--good); }
.bars .n { font-size: clamp(22px, 2.2vw, 42px); font-variant-numeric: tabular-nums; }

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

.phone { max-width: 620px; margin: 0 auto; padding: 20px 18px 44px; }
.phone h1 { font-size: 17px; margin: 0 0 2px; }
.phone .prompt {
  margin: 14px 0 16px;
  font-size: 19px;
  line-height: 1.45;
  font-weight: 600;
  white-space: pre-wrap;
}
.phone textarea { min-height: 190px; font-size: 16px; }  /* 16px keeps iOS from zooming in */
.phone .send { margin-top: 12px; display: flex; gap: 10px; align-items: center; }
.phone .send button { flex: 1; padding: 14px; font-size: 16px; }
.phone .state { margin-top: 16px; font-size: 14px; }
.phone .choice { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 14px; }
.phone .choice button { padding: 22px 12px; font-size: 16px; font-weight: 600; }
.phone .choice button.on { background: var(--zinc-900); border-color: var(--zinc-900); color: #fff; }
.phone .said {
  border: 1px solid var(--zinc-200);
  border-radius: 10px;
  padding: 12px;
  font-size: 15px;
  line-height: 1.5;
  white-space: pre-wrap;
  background: #fff;
}


/* --- de namenwand ----------------------------------------------------------
   De zaal loopt binnen en ziet zichzelf verschijnen. Dat is de reden dat we om
   een naam vragen, dus hij staat groot en niet als een lijstje in een hoek.  */

.wall .roster {
  display: flex;
  flex-wrap: wrap;
  gap: .8vh 1vw;
  align-content: flex-start;
  overflow-y: auto;
}
.wall .roster .who {
  background: var(--zinc-900);
  border-radius: 999px;
  padding: .8vh 1.4vw;
  font-size: clamp(18px, 2vw, 38px);
  line-height: 1.2;
  /* Een naam die er net bij komt schuift de rest op. Hij komt op zijn plek in
     plaats van er te staan, zodat je ziet dat er iemand bij is. */
  animation: pop 320ms cubic-bezier(.22, .61, .36, 1);
}
@keyframes pop { from { opacity: 0; transform: scale(.9); } }

/* --- de zaal tegenover de machine ------------------------------------------ */

.wall .twoup { display: grid; grid-template-columns: 1fr 1fr; gap: 4vw; min-height: 0; }
.wall .tag {
  font-size: clamp(14px, 1.3vw, 26px);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--zinc-500);
  margin: 0 0 2vh;
}

/* Liggende staven voor alles wat een lijst met labels is. De staande staven
   blijven voor het stemmen: daar zijn er twee en telt de hoogte. */
.bars.wide { flex-direction: column; height: auto; gap: 2.2vh; }
.bars.wide .b { display: block; }
.bars.wide .track { height: 3.4vh; border-radius: 999px; background: var(--zinc-900); }
.bars.wide .fill {
  transform: scaleX(var(--p, 0));
  transform-origin: left center;
  border-radius: 999px;
  background: var(--accent);
}
.bars.wide .fill.alt { background: var(--good); }
.bars.wide .n {
  font-size: clamp(20px, 2.05vw, 40px);
  line-height: 1.15;
  margin-bottom: .9vh;
  display: flex;
  align-items: baseline;
  gap: .8vw;
}
.bars.wide .n b { color: var(--zinc-400); font-weight: 600; }
.bars.wide .n .sure { margin-left: auto; color: var(--zinc-500); font-size: .72em; }

/* Het juiste antwoord licht op, de rest zakt weg. Alleen na de onthulling. */
.bars.wide .b.right .fill { background: var(--accent); }
.bars.wide .b.right .n { color: #fff; font-weight: 700; }
.bars.wide .b.wrong .fill { background: var(--zinc-800); }
.bars.wide .b.wrong .n { color: var(--zinc-500); }

/* Zeker tegenover goed. Het gat tussen die twee getallen is de les. */
.gap { display: flex; gap: 6vw; margin-top: 2vh; }
.gap .big { display: block; font-size: clamp(40px, 6vw, 110px); font-weight: 700; letter-spacing: -.03em; }
.gap .lab { display: block; font-size: clamp(14px, 1.3vw, 26px); color: var(--zinc-400); }
.gap div:first-child .big { color: var(--accent); }

/* --- de alinea met de warmtekaart ------------------------------------------
   Elk stuk krijgt een tint naar hoeveel mensen erop tikten. De tekst loopt
   gewoon door: valt hij uit elkaar in losse blokjes, dan lees je hem niet meer
   als één verhaal en gaat het punt van de slide verloren.                    */

.wall .para {
  font-size: clamp(22px, 2.55vw, 49px);
  line-height: 1.85;
  margin: 0;
  overflow-y: auto;
}
/* De tint loopt tot 52 procent en niet hoger. Vol oranje achter witte tekst is
   niet te lezen, en dan is de warmtekaart mooi maar nutteloos: de zaal moet de
   zin nog kunnen lezen terwijl hij ziet waar iedereen wees. */
.wall .para .span {
  padding: .12em .22em;
  border-radius: 7px;
  background: color-mix(in srgb, var(--accent) calc(var(--h, 0) * 52%), transparent);
  /* Zonder dit krijgt een stuk dat over twee regels valt alleen aan de
     buitenkant een ronde hoek en ziet het eruit als een fout. */
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.wall .para .span i {
  font-style: normal;
  font-size: .62em;
  vertical-align: super;
  color: #fff;
  font-weight: 700;
  margin-left: .25em;
}
.wall .para .span.right {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}
.wall .para .word { display: inline-block; }

.out-panel { margin-top: 2vh; min-height: 0; display: flex; flex-direction: column; }
.out-panel .out {
  background: var(--zinc-900);
  border-radius: 12px;
  padding: 2vh 1.6vw;
  font-size: clamp(18px, 1.75vw, 34px);
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-y: auto;
}

/* Wie het schreef, boven wat hij schreef. */
.grid .said .by {
  display: block;
  font-size: .78em;
  color: var(--accent);
  font-weight: 600;
  margin-bottom: .35em;
}

/* --- de telefoon: keuzes ---------------------------------------------------- */

.phone .opts { display: flex; flex-direction: column; gap: 10px; }
.phone .opt {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  text-align: left;
  padding: 14px;
  font-size: 16px;
  line-height: 1.45;
  border-radius: 10px;
}
.phone .opt .letter {
  flex: none;
  width: 26px; height: 26px;
  border-radius: 999px;
  background: var(--zinc-200);
  color: var(--zinc-700);
  display: grid; place-items: center;
  font-size: 13px; font-weight: 700;
}
.phone .opt.on { background: var(--zinc-900); border-color: var(--zinc-900); color: #fff; }
.phone .opt.on .letter { background: var(--accent); color: #fff; }

/* Een alinea waarin je een stuk aantikt. De knoppen zijn stukken tekst, dus ze
   erven de regelhoogte en lopen door alsof het gewone tekst is. */
.phone .spans { font-size: 17px; line-height: 1.9; margin: 0; }
.phone .spans .span {
  display: inline;
  border: 0;
  background: var(--zinc-200);
  border-radius: 6px;
  padding: 3px 5px;
  font: inherit;
  color: inherit;
}
.phone .spans .span.on { background: var(--accent); color: #fff; }
.phone .spans.words .span { display: inline-block; margin-bottom: 4px; }

.phone .scale { display: block; margin-top: 18px; font-size: 15px; }
.phone .scale span { display: block; margin-bottom: 8px; color: var(--zinc-500); }
.phone .scale b { color: var(--zinc-900); font-variant-numeric: tabular-nums; }
.phone .scale input[type=range] { width: 100%; accent-color: var(--accent); padding: 0; }

.phone input { font-size: 16px; }   /* 16px, anders zoomt iOS in bij het tikken */

/* --- de spelkiezer in het hostpaneel --------------------------------------- */

.games { display: flex; flex-direction: column; gap: 8px; }
.games .game { text-align: left; padding: 10px 12px; line-height: 1.35; }
.games .game b { display: block; font-size: 14px; }
.games .game span { font-size: 12px; color: var(--zinc-500); }
.host .names { font-size: 14px; line-height: 1.7; color: var(--zinc-700); margin: 0; }
.host summary { font-size: 13px; cursor: pointer; }
