/* ── सर्वोदय अहिंसा — shared shell ─────────────────────────────────
   Not one theme colour is written literally below. Everything comes from
   the variables theme.js sets, so the same stylesheet serves the gold
   stage, a neon tambola and anything built later. The four answer
   colours are the one exception: they are the Jain flag's, and they
   stay the same in every theme so phone and projector always match.
   The rules behind this file live in D:\Games\SA-DESIGN-DIRECTION.md. */

@import url('https://fonts.googleapis.com/css2?family=Baloo+2:wght@600;700;800&family=Mukta:wght@400;600;700;800&family=Noto+Sans+Devanagari:wght@400;600;700&display=swap');

:root{
  /* fallbacks only — theme.js overwrites these on the first paint */
  --bg:#1a0d45; --bg-deep:#0b0620; --stage-top:#2c1672; --panel:#24125a; --panel-2:#2e1a6b;
  --bd:#47309c; --bd-lt:#6e58cf; --tx:#ffffff; --tx-mut:#cbbff5;
  --primary:#ffc83d; --primary-dk:#b27c00; --primary-lt:#ffe38a; --on-primary:#1b0f3f;
  --glow:rgba(255,200,61,.24); --glow-hard:rgba(255,200,61,.55);
  --accent:#8b6cff; --on-accent:#fff; --accent-glow:rgba(139,108,255,.25);
  --ok:#2bd46a; --bad:#ff4d6a; --ok-glow:rgba(43,212,106,.24); --bad-glow:rgba(255,77,106,.24);

  /* the answer colours, the same in every theme so phone and projector
     always match. No red and no green: those two mean "wrong" and
     "correct" at the reveal, and an option must never look like either. */
  --opt-a:#c2368f; --opt-a-dk:#7e1a5a;
  --opt-b:#f5b800; --opt-b-dk:#b27c00;
  --opt-c:#2f6bff; --opt-c-dk:#1b43b5;
  --opt-d:#ea6a0f; --opt-d-dk:#9c4100;
  --ink:#1b0f3f;
  --gold-grad:linear-gradient(180deg,#ffd866,#ffa425);

  --r:18px; --r-sm:12px; --r-lg:26px;
  --sp:14px;

  /* Devanagari is the reason these stacks are this long.
     Most Latin faces carry no Devanagari, and the generic `sans-serif`
     on Windows resolves to a font that drops or doubles matras —
     "शामिल" comes out as "शाामल". So every stack names real Devanagari
     fonts that are ALREADY on the machine (Nirmala UI ships with
     Windows, Kohinoor with macOS) before it ever reaches the generic. A
     projector with slow or blocked internet then still renders Hindi
     correctly instead of mangling it mid-show. Baloo 2 carries
     Devanagari of its own, which is why it can lead the display stack. */
  --dev:'Noto Sans Devanagari','Nirmala UI','Kohinoor Devanagari','Mangal','Kokila',sans-serif;
  --fs:'Mukta',var(--dev);
  --fd:'Baloo 2','Mukta',var(--dev);
  --shadow:0 12px 34px rgba(0,0,0,.38);
  --t:.18s cubic-bezier(.4,0,.2,1);
  --pop:cubic-bezier(.2,1.3,.4,1);
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  background:var(--bg-deep);
  color:var(--tx);
  font-family:var(--fs);
  font-size:16px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
/* ═══ THE STAGE ═════════════════════════════════════════════════════
   Four fixed layers behind every page, each one mirror-symmetric on the
   centre line (SA-DESIGN-DIRECTION.md, rule 2):
     1 html::before  the night sky — violet, a gold spotlight, a magenta
                     stage light from the left and a blue one from the right
     2 body::before  golden rays fanning out behind the logo
     3 body::after   a glowing studio floor in perspective
     4 html::after   twinkling stars and the four answer shapes at the sides
   Only transform and opacity ever animate, so a cheap phone composites
   them instead of repainting; the rays turn only on wide screens. */
html::before,html::after,body::before,body::after{content:'';position:fixed;pointer-events:none}
html::before{
  inset:0;z-index:-4;
  background:
    radial-gradient(62vmax 46vmax at 50% -12%, var(--glow-hard), transparent 64%),
    radial-gradient(46vmax 46vmax at -8% 30%, color-mix(in srgb,var(--opt-a) 30%,transparent), transparent 70%),
    radial-gradient(46vmax 46vmax at 108% 30%, color-mix(in srgb,var(--opt-c) 30%,transparent), transparent 70%),
    linear-gradient(180deg, var(--stage-top), var(--bg) 48%, var(--bg-deep));
}
body::before{
  z-index:-3;left:50%;top:20vh;width:150vmax;height:150vmax;margin:-75vmax 0 0 -75vmax;
  background:repeating-conic-gradient(from 0deg, rgba(255,214,102,.085) 0deg 6deg, transparent 6deg 15deg);
  -webkit-mask-image:radial-gradient(closest-side, #000 6%, rgba(0,0,0,.5) 36%, transparent 70%);
          mask-image:radial-gradient(closest-side, #000 6%, rgba(0,0,0,.5) 36%, transparent 70%);
  animation:rays 180s linear infinite;
}
@keyframes rays{to{transform:rotate(1turn)}}
body::after{
  z-index:-2;left:-50%;right:-50%;bottom:-2vh;height:62vh;
  background:
    radial-gradient(40% 70% at 50% 100%, color-mix(in srgb,var(--opt-a) 28%,transparent), transparent 70%),
    linear-gradient(90deg, color-mix(in srgb,var(--accent) 55%,transparent) 0 2px, transparent 2px) 50% 0 / 7vmax 100% repeat-x,
    linear-gradient(0deg, color-mix(in srgb,var(--accent) 55%,transparent) 0 2px, transparent 2px) 50% 100% / 100% 5vmax repeat-y;
  transform:perspective(56vh) rotateX(56deg);transform-origin:50% 100%;
  -webkit-mask-image:linear-gradient(to top, #000, rgba(0,0,0,.7) 40%, transparent 88%);
          mask-image:linear-gradient(to top, #000, rgba(0,0,0,.7) 40%, transparent 88%);
  opacity:.75;
}
html::after{
  inset:0;z-index:-1;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 2.2l8.6 15.2H1.4Z' fill='%23c2368f'/%3E%3C/svg%3E") 5% 24% / clamp(22px,2.4vw,46px) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 .8 19.2 10 10 19.2.8 10Z' fill='%23f5b800'/%3E%3C/svg%3E") 95% 24% / clamp(22px,2.4vw,46px) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='10' r='8.6' fill='%232f6bff'/%3E%3C/svg%3E") 9% 62% / clamp(18px,1.9vw,36px) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Crect x='1.8' y='1.8' width='16.4' height='16.4' rx='2.6' fill='%23ea6a0f'/%3E%3C/svg%3E") 91% 62% / clamp(18px,1.9vw,36px) no-repeat,
    radial-gradient(circle at 18% 22%, rgba(255,255,255,.9) 0 1px, transparent 1.7px) 0 0 / 230px 190px,
    radial-gradient(circle at 63% 71%, rgba(255,255,255,.7) 0 1.2px, transparent 2px) 0 0 / 310px 270px,
    radial-gradient(circle at 41% 9%, rgba(255,214,102,.8) 0 1px, transparent 1.8px) 0 0 / 170px 240px;
  opacity:.75;
  animation:twinkle 6s ease-in-out infinite alternate;
}
@keyframes twinkle{from{opacity:.45;transform:translateY(0)}to{opacity:.9;transform:translateY(-8px)}}
/* phones: smaller, still rays — a turning layer that size costs a cheap
   phone more than it is worth */
@media (max-width:900px){
  body::before{width:110vmax;height:110vmax;margin:-55vmax 0 0 -55vmax;top:16vh;animation:none}
  body::after{height:44vh;opacity:.6}
}
/* a bright hall wants a plain page */
html[data-mode="light"] body::before,html[data-mode="light"] body::after,html[data-mode="light"]::after{display:none}

h1,h2,h3,h4{font-family:var(--fd);line-height:1.2;font-weight:800}
a{color:var(--primary);text-decoration:none}
a:hover{text-decoration:underline}

/* ─── layout ─────────────────────────────────────────────────── */
.wrap{width:min(1240px,100% - 32px);margin-inline:auto}
.row{display:flex;gap:var(--sp);align-items:center}
.row.wrap-r{flex-wrap:wrap}
.col{display:flex;flex-direction:column;gap:var(--sp)}
.grow{flex:1;min-width:0}
.spread{display:flex;justify-content:space-between;align-items:center;gap:var(--sp)}
.grid{display:grid;gap:var(--sp)}
.g2{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
.center{display:grid;place-items:center}
.hide{display:none !important}
.mut{color:var(--tx-mut)}
.sm{font-size:13px}
/* Spaced capitals suit short English labels and nothing else. In Hindi
   the spacing tears joined letters apart ("सं स्कार"), so it is switched
   off whenever the page is in Hindi. */
.xs{font-size:12px;letter-spacing:.06em;text-transform:uppercase;font-weight:700}
html[lang="hi"] .xs{letter-spacing:0;text-transform:none;font-size:12.5px}
.nowrap{white-space:nowrap}
.tc{text-align:center}

/* ─── surfaces ───────────────────────────────────────────────── */
.card{
  background:linear-gradient(180deg,color-mix(in srgb,var(--panel) 96%,#fff 4%),var(--panel));
  border:1.5px solid var(--bd);
  border-radius:var(--r);
  padding:18px;
  box-shadow:var(--shadow);
}
.card.flat{box-shadow:none}
.card.tight{padding:12px}
.sub{background:var(--panel-2);border:1px solid var(--bd);border-radius:var(--r-sm);padding:12px}

/* The header lives inside a wrapper div that is exactly as tall as the
   header itself. A sticky element can only stick while its containing
   block is still on screen, so sticking the header alone did nothing —
   it scrolled away with its own wrapper. The WRAPPER has to be sticky. */
#hdr-slot-outer{position:sticky;top:0;z-index:40}
.hdr{
  background:color-mix(in srgb,var(--bg-deep) 72%,transparent);
  backdrop-filter:blur(14px);
  border-bottom:1px solid var(--bd);
}
.hdr .in{display:flex;align-items:center;gap:12px;padding:10px 16px}
/* the logo sits straight on the stage — no box — with a soft light
   behind it so its dark tagline line stays readable on violet */
.logo{height:40px;width:auto;flex:none;filter:drop-shadow(0 0 6px rgba(255,255,255,.55)) drop-shadow(0 0 14px rgba(255,255,255,.22))}
.brand-n{font-family:var(--fd);font-weight:800;font-size:18px;letter-spacing:.2px;line-height:1.1;color:var(--primary)}
.brand-s{font-size:11.5px;color:var(--tx-mut);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:46vw}
html[lang="en"] .brand-s{letter-spacing:.14em;text-transform:uppercase;font-size:11px}

/* Page switcher in the header — direct children only.

   Each item wraps its text in an inner <span class="lbl">, so a plain
   ".hdr-nav span" matched that inner span too and painted the label
   --tx-mut straight over the active chip's own colour. The icon took the
   right colour and the word beside it did not, which is what made the
   current page unreadable whatever the theme. */
.hdr-nav{display:flex;gap:3px;margin-left:14px;flex-wrap:wrap}
.hdr-nav > a,.hdr-nav > span{
  display:inline-flex;align-items:center;gap:6px;
  padding:7px 12px;border-radius:999px;
  font:700 13.5px/1 var(--fd);color:var(--tx-mut);
  text-decoration:none;border:1px solid transparent;transition:var(--t);white-space:nowrap;
}
.hdr-nav .lbl{color:inherit}
.hdr-nav > a:hover{color:var(--tx);background:var(--panel-2);text-decoration:none}
.hdr-nav > span.on{color:var(--on-primary);background:var(--primary)}
/* on a laptop the labels fit; on a narrow screen the icons carry it */
@media(max-width:1100px){ .hdr-nav .lbl{display:none} .hdr-nav > a,.hdr-nav > span{padding:7px 9px} }
@media(max-width:560px){ .hdr-nav{margin-left:6px;gap:1px} }

/* ─── buttons ────────────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:11px 17px;border-radius:var(--r-sm);
  border:1.5px solid var(--bd-lt);
  background:var(--panel-2);color:var(--tx);
  font-family:var(--fd);font-weight:700;font-size:15px;line-height:1.2;
  cursor:pointer;transition:var(--t);
  user-select:none;white-space:nowrap;
}
.btn:hover:not(:disabled){border-color:var(--primary);transform:translateY(-1px)}
.btn:active:not(:disabled){transform:translateY(1px)}
.btn:disabled{opacity:.42;cursor:not-allowed}
/* the main action: gold, with a solid "3-D" edge underneath like a
   game-show button, so it reads as the thing to press */
.btn.p{
  background:linear-gradient(180deg,var(--primary-lt),var(--primary));color:var(--on-primary);border-color:transparent;
  box-shadow:0 4px 0 var(--primary-dk),0 8px 22px var(--glow),inset 0 2px 0 rgba(255,255,255,.45);
}
.btn.p:active:not(:disabled){box-shadow:0 1px 0 var(--primary-dk),0 4px 12px var(--glow)}
.btn.a{background:var(--accent);color:var(--on-accent);border-color:transparent}
.btn.ok{background:var(--ok);color:#03150e;border-color:transparent;box-shadow:0 4px 0 color-mix(in srgb,var(--ok) 55%,#000)}
.btn.bad{background:var(--bad);color:#fff;border-color:transparent}
.btn.ghost{background:transparent}
.btn.big{padding:16px 26px;font-size:19px;border-radius:999px}
.btn.sm{padding:7px 12px;font-size:13px}
.btn.wide{width:100%}
.btn.on{border-color:var(--primary);box-shadow:inset 0 0 0 1px var(--primary),0 0 16px var(--glow)}

.kbd{
  display:inline-grid;place-items:center;min-width:19px;height:19px;padding:0 4px;
  font:700 11px/1 var(--fd);border-radius:5px;
  background:var(--bg-deep);border:1px solid var(--bd-lt);color:var(--tx-mut);
}

/* ─── form ───────────────────────────────────────────────────── */
label.f{display:block;font-size:12.5px;font-weight:700;color:var(--tx-mut);margin-bottom:5px}
/* tel belongs here too — the join form's mobile field was the one input
   on the site still wearing the browser's own white box */
input[type=text],input[type=number],input[type=email],input[type=password],
input[type=search],input[type=tel],input[type=url],textarea,select{
  width:100%;padding:12px 14px;
  background:color-mix(in srgb,var(--bg-deep) 70%,transparent);color:var(--tx);
  border:1.5px solid var(--bd);border-radius:var(--r-sm);
  font-family:var(--fs);font-size:16px;transition:var(--t);
}
input:focus,textarea:focus,select:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--glow)}
textarea{resize:vertical;min-height:76px;line-height:1.5}
select{cursor:pointer}
input[type=color]{width:46px;height:34px;padding:2px;border-radius:8px;border:1px solid var(--bd);background:var(--bg-deep);cursor:pointer}
input[type=range]{width:100%;accent-color:var(--primary)}
.chk{display:flex;align-items:center;gap:9px;cursor:pointer;font-size:14px;user-select:none}
.chk input{width:18px;height:18px;accent-color:var(--primary);cursor:pointer;flex:none}

/* ─── pills / badges ─────────────────────────────────────────── */
.pill{
  display:inline-flex;align-items:center;gap:6px;
  padding:4px 12px;border-radius:999px;
  font:700 12.5px/1.7 var(--fd);
  background:var(--panel-2);border:1px solid var(--bd);color:var(--tx-mut);
}
.pill.p{background:var(--glow);border-color:var(--primary);color:var(--primary)}
.pill.ok{background:var(--ok-glow);border-color:var(--ok);color:var(--ok)}
.pill.bad{background:var(--bad-glow);border-color:var(--bad);color:var(--bad)}
.pill.a{background:var(--accent-glow);border-color:var(--accent);color:var(--accent)}

.dot{width:8px;height:8px;border-radius:50%;background:var(--tx-mut);flex:none}
.dot.live{background:var(--ok);box-shadow:0 0 0 0 var(--ok-glow);animation:pulse 2s infinite}
.dot.off{background:var(--bad)}
@keyframes pulse{0%{box-shadow:0 0 0 0 var(--ok-glow)}70%{box-shadow:0 0 0 9px transparent}100%{box-shadow:0 0 0 0 transparent}}

/* ─── selectable row (game lists, session lists, venues) ─────── */
.gitem{
  display:flex;align-items:center;gap:10px;
  padding:10px 12px;border-radius:var(--r-sm);
  background:var(--panel-2);border:1px solid var(--bd);
  cursor:pointer;transition:var(--t);text-align:left;width:100%;
  color:var(--tx);font-family:var(--fs);
}
.gitem:hover{border-color:var(--primary);transform:translateY(-1px)}
.gitem.on{border-color:var(--primary);background:var(--glow)}
.gitem .ic{font-size:19px;flex:none}
.gitem .t{font-weight:700;font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ─── tabs ───────────────────────────────────────────────────── */
.tabs{display:flex;gap:4px;background:var(--bg-deep);padding:4px;border-radius:var(--r-sm);border:1px solid var(--bd);overflow-x:auto}
.tabs button{
  flex:1;padding:9px 10px;border:0;border-radius:9px;background:transparent;color:var(--tx-mut);
  font:700 14px/1.2 var(--fd);cursor:pointer;transition:var(--t);white-space:nowrap;
}
.tabs button.on{background:linear-gradient(180deg,var(--primary-lt),var(--primary));color:var(--on-primary)}
.tabs button:hover:not(.on){color:var(--tx)}

/* ═══ ANSWER TILES ═════════════════════════════════════════════════
   One tile, shared by phone and projector. A tile with data-l carries
   its own colour, shape and letter (पंचरंग); a tile without one — the
   "put in order" list, a numbered list — stays a neutral card. */
.opt{
  --oc:var(--panel-2); --od:color-mix(in srgb,var(--bd) 80%,#000); --on:var(--tx);
  position:relative;display:flex;align-items:center;gap:12px;
  min-height:60px;padding:8px 14px 8px 10px;border-radius:var(--r);
  background:var(--oc);color:var(--on);border:2px solid var(--bd);
  box-shadow:0 4px 0 var(--od);
  cursor:pointer;transition:transform .12s var(--pop),box-shadow var(--t),opacity var(--t),filter var(--t);
  text-align:left;width:100%;
  font:800 19px/1.25 var(--fs);
  -webkit-tap-highlight-color:transparent;
}
.opt[data-l]{border-color:transparent;box-shadow:0 5px 0 var(--od),inset 0 3px 0 rgba(255,255,255,.28)}
.opt[data-l="A"]{--oc:var(--opt-a);--od:var(--opt-a-dk);--on:#fff}
.opt[data-l="B"]{--oc:var(--opt-b);--od:var(--opt-b-dk);--on:var(--ink)}
.opt[data-l="C"]{--oc:var(--opt-c);--od:var(--opt-c-dk);--on:#fff}
.opt[data-l="D"]{--oc:var(--opt-d);--od:var(--opt-d-dk);--on:#fff}
.opt:hover:not(:disabled):not(.locked):not(.correct){transform:translateY(-2px)}
.opt:active:not(:disabled){transform:scale(.98)}
.opt:disabled{cursor:default}
.opt .lbl{
  flex:none;width:40px;height:40px;display:grid;place-items:center;border-radius:12px;
  background:rgba(0,0,0,.22);font:800 21px/1 var(--fd);color:inherit;
}
.opt[data-l="B"] .lbl{background:rgba(255,255,255,.45)}
.opt:not([data-l]) .lbl{background:var(--bg-deep);border:1px solid var(--bd-lt);color:var(--primary)}
.opt .tx{min-width:0;overflow-wrap:anywhere}
.opt .shp{flex:none;width:20px;height:20px;opacity:.8;display:grid;place-items:center}
.opt .shp svg{width:100%;height:100%;display:block}
.opt .tag{
  flex:none;display:inline-flex;align-items:center;gap:5px;
  padding:4px 10px;border-radius:999px;background:#fff;color:var(--ink);
  font:800 13px/1.2 var(--fd);white-space:nowrap;
}
.opt .tag svg{width:13px;height:13px}
.opt .mark{
  flex:none;width:34px;height:34px;border-radius:50%;display:grid;place-items:center;
  border:3px solid #fff;color:#fff;
}
.opt .mark svg{width:18px;height:18px}
/* picked — waiting for Send: a white ring and a little lift */
.opt.locked{
  border-color:#fff;
  box-shadow:0 6px 0 var(--od),0 0 0 2px #fff,0 0 24px rgba(255,255,255,.5),inset 0 3px 0 rgba(255,255,255,.28);
  transform:scale(1.02);
}
.opt.locked:not([data-l]){border-color:var(--primary);box-shadow:0 4px 0 var(--od),0 0 20px var(--glow)}
.opts.picked .opt:not(.locked){opacity:.82}
/* answer sent: everything else steps back */
.opts.sent .opt:not(.locked){opacity:.42}
/* reveal — the right tile keeps its own colour and glows green */
.opt.correct{
  border-color:var(--ok);opacity:1 !important;
  box-shadow:0 6px 0 var(--od),0 0 0 3px var(--ok),0 0 30px var(--ok-glow),0 0 50px var(--ok-glow);
  animation:okpop .5s var(--pop) both;
}
.opt.correct .mark{background:var(--ok)}
.opt.wrong{border-color:var(--bad);opacity:1 !important;box-shadow:0 5px 0 var(--od),0 0 0 3px var(--bad)}
.opt.wrong .mark{background:var(--bad)}
.opt.fade{opacity:.28;filter:saturate(.7);transform:scale(.97)}
/* removed by 50:50 — dashed, struck through, out of play */
.opt.dim{
  --oc:var(--panel);--on:var(--tx-mut);
  background:var(--panel);color:var(--tx-mut);border:2px dashed var(--bd-lt);box-shadow:none;
  pointer-events:none;opacity:.75;
}
.opt.dim .tx{text-decoration:line-through}
.opt.dim .lbl{background:var(--panel-2)}
/* host is still reading — the colours are there, the words are not yet */
.opt.ghost{background:color-mix(in srgb,var(--oc) 16%,transparent);border:2px solid var(--oc);box-shadow:none;color:transparent}
.opt.ghost .lbl{background:color-mix(in srgb,var(--oc) 30%,transparent);color:var(--oc)}
.opt.ghost .tx{display:block;height:12px;border-radius:6px;background:color-mix(in srgb,var(--oc) 40%,transparent);max-width:55%}
.opt.ghost .shp{opacity:.6}
@keyframes okpop{0%{transform:scale(.96)}60%{transform:scale(1.04)}100%{transform:scale(1.02)}}

/* ─── timer ──────────────────────────────────────────────────────
   Projector: a ring. Phone: a bar with the seconds beside it. Gold,
   then amber from 12 s, then red with a once-a-second beat from 5 s. */
.ring{
  --tc:var(--primary);
  position:relative;display:inline-grid;place-items:center;flex:none;
  width:84px;height:84px;border-radius:50%;
  background:color-mix(in srgb,var(--bg-deep) 90%,transparent);
  box-shadow:0 0 30px color-mix(in srgb,var(--tc) 45%,transparent);
}
.ring svg{position:absolute;inset:0;width:100%;height:100%;transform:rotate(-90deg)}
.ring .trk{fill:none;stroke:rgba(255,255,255,.12);stroke-width:9}
.ring .arc{fill:none;stroke:var(--tc);stroke-width:9;stroke-linecap:round;transition:stroke-dasharray .25s linear}
.ring b{position:relative;font:800 32px/1 var(--fd);color:#fff}
.ring.amb{--tc:#ff9f1c}
.ring.red{--tc:var(--bad)}
.ring.red b{color:var(--bad)}
.ring.red{animation:beat 1s infinite}
@keyframes beat{0%,100%{transform:scale(1)}12%{transform:scale(1.08)}}
/* kept for any page still asking for the old round badge */
.timer{display:inline-grid;place-items:center;width:74px;height:74px;border-radius:50%;
  font:800 27px/1 var(--fd);color:var(--primary);background:var(--bg-deep);border:3px solid var(--primary)}
.tbar{height:8px;border-radius:99px;background:var(--bg-deep);overflow:hidden;border:1px solid var(--bd)}
.tbar i{display:block;height:100%;background:var(--gold-grad);transition:width .25s linear}
.tline{display:flex;align-items:center;gap:10px}
.tline .tbar{flex:1;height:14px}
.tline .tbar i{border-radius:99px}
.tline.amb .tbar i{background:linear-gradient(90deg,#ff9f1c,#ffd27a)}
.tline.red .tbar i{background:linear-gradient(90deg,var(--bad),#ff9aa9)}
.tline .secs{
  flex:none;width:48px;height:48px;border-radius:50%;display:grid;place-items:center;
  background:var(--bg-deep);border:3px solid var(--primary);font:800 21px/1 var(--fd);
  box-shadow:0 0 16px var(--glow);
}
.tline.amb .secs{border-color:#ff9f1c}
.tline.red .secs{border-color:var(--bad);color:var(--bad);animation:beat 1s infinite}
/* waiting for the host to start it, and run out — quiet, but in place */
.tline.wait .tbar i{background:var(--accent);opacity:.35}
.tline.wait .secs,.tline.done .secs{box-shadow:none;border-color:var(--bd);color:var(--tx-mut)}
.tline.wait .secs{font-size:19px}

/* ─── question card — white, so it reads in a bright hall too ── */
.qcard{
  background:#fff;color:var(--ink);border-radius:22px;padding:14px 18px 18px;
  box-shadow:0 6px 0 #b9a6ff,0 14px 30px rgba(0,0,0,.35);
}
.qcard .qn{font:800 12.5px/1.3 var(--fd);color:#7b5ce0}
.qcard .qq{font:800 20px/1.35 var(--fd);color:var(--ink);margin-top:2px;overflow-wrap:anywhere}

/* round + question number strip */
.qstrip{display:flex;align-items:center;justify-content:space-between;gap:10px;font:700 13.5px/1.3 var(--fd);color:var(--tx-mut)}
.qdots{display:flex;gap:5px;align-items:center;flex:none}
.qdots i{width:7px;height:7px;border-radius:4px;background:var(--bd)}
.qdots i.d{background:var(--primary)}
.qdots i.c{width:18px;background:#fff}

/* ─── the big Send button ───────────────────────────────────── */
.sendbtn{
  display:flex;align-items:center;justify-content:center;gap:10px;width:100%;
  min-height:64px;border-radius:999px;border:0;cursor:pointer;
  background:var(--gold-grad);color:var(--ink);
  font:800 25px/1 var(--fd);
  box-shadow:0 5px 0 #b86a00,0 0 26px rgba(255,200,61,.5),inset 0 3px 0 rgba(255,255,255,.45);
  transition:transform .1s,box-shadow var(--t),opacity var(--t);
}
.sendbtn svg{width:22px;height:22px}
.sendbtn:active:not(:disabled){transform:translateY(3px);box-shadow:0 2px 0 #b86a00}
.sendbtn.go{animation:breathe 1.3s ease-in-out infinite}
.sendbtn:disabled{background:var(--panel-2);color:var(--tx-mut);box-shadow:none;border:2px solid var(--bd);cursor:not-allowed;font-size:21px}
@keyframes breathe{0%,100%{box-shadow:0 5px 0 #b86a00,0 0 18px rgba(255,200,61,.35),inset 0 3px 0 rgba(255,255,255,.45)}50%{box-shadow:0 5px 0 #b86a00,0 0 38px rgba(255,200,61,.8),inset 0 3px 0 rgba(255,255,255,.45)}}

/* the buzzer: one big red button, rings pulsing out of it */
.buzzbtn{
  position:relative;display:grid;place-items:center;width:200px;height:200px;margin:18px auto;border-radius:50%;
  border:6px solid rgba(255,255,255,.6);cursor:pointer;color:#fff;font:800 48px/1 var(--fd);
  background:radial-gradient(circle at 50% 35%,#ff8597,#e8344e 55%,#b0102b);
  box-shadow:0 12px 0 #7a0a1c,0 0 50px rgba(232,52,78,.6),inset 0 6px 0 rgba(255,255,255,.4);
  transition:transform .08s,box-shadow .08s;-webkit-tap-highlight-color:transparent;
}
.buzzbtn::before{content:'';position:absolute;inset:-22px;border-radius:50%;border:4px solid rgba(232,52,78,.45);animation:ripplebz 1.6s ease-out infinite}
@keyframes ripplebz{from{transform:scale(.9);opacity:1}to{transform:scale(1.15);opacity:0}}
.buzzbtn:active:not(:disabled){transform:translateY(8px);box-shadow:0 4px 0 #7a0a1c,0 0 30px rgba(232,52,78,.6)}
.buzzbtn:disabled{background:var(--panel-2);color:var(--tx-mut);box-shadow:none;border-color:var(--bd);cursor:default}
.buzzbtn:disabled::before{display:none}
.buzzbtn svg{width:64px;height:64px}

/* "your answer is in" — lilac, never green: green means correct, and
   nobody is correct until the reveal */
.sentnote{
  display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:var(--r);
  background:color-mix(in srgb,var(--accent) 16%,var(--panel));border:2px solid color-mix(in srgb,var(--accent) 70%,#fff);
}
.sentnote .ico{flex:none;width:38px;height:38px;border-radius:50%;display:grid;place-items:center;background:color-mix(in srgb,var(--accent) 80%,#fff);color:#fff}
.sentnote .ico svg{width:20px;height:20px}
.sentnote b{display:block;font:800 18px/1.25 var(--fd);color:#fff}
.sentnote span{font-size:13px;color:var(--tx-mut)}

/* result banner at the reveal */
.banner{
  display:flex;align-items:center;gap:12px;padding:12px 16px;border-radius:22px;
  border:2px solid rgba(255,255,255,.5);color:#fff;
}
.banner .em{font-size:34px;line-height:1;flex:none}
.banner b{display:block;font:800 26px/1.15 var(--fd)}
.banner span{font-size:13px;opacity:.9}
.banner.win{background:linear-gradient(90deg,#22c85f,#0e7f3a);box-shadow:0 0 28px var(--ok-glow)}
.banner.no{background:linear-gradient(90deg,#5b3fc4,#3a2290)}
.banner.none{background:var(--panel-2);border-color:var(--bd)}

.expl{padding:12px 14px;border-radius:var(--r);background:color-mix(in srgb,var(--opt-d) 14%,var(--panel));border:1.5px solid var(--opt-d);font-size:14.5px;line-height:1.5}

/* time-up stamp — drops in, sits a moment, then steps aside so the
   tiles underneath can be read again */
.stamp{
  position:fixed;left:50%;top:42%;z-index:70;pointer-events:none;
  padding:12px 30px;border-radius:20px;text-align:center;color:#fff;
  background:linear-gradient(180deg,#ff5c78,#d61f45);border:4px solid #fff;
  box-shadow:0 12px 36px rgba(0,0,0,.5);
  animation:stampin .45s var(--pop) both, stampout .4s ease 2.4s forwards;
}
.stamp b{display:block;font:800 40px/1.1 var(--fd);white-space:nowrap}
.stamp span{display:block;font:700 14px/1.3 var(--fd);opacity:.9}
@keyframes stampin{from{transform:translate(-50%,-50%) scale(1.5) rotate(0);opacity:0}to{transform:translate(-50%,-50%) scale(1) rotate(-6deg);opacity:1}}
@keyframes stampout{to{transform:translate(-50%,-50%) scale(.9) rotate(-6deg);opacity:0;visibility:hidden}}

/* confetti — always BEHIND the content (z-index below), never on words */
.confetti{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.confetti i{
  position:absolute;top:-24px;left:var(--x);width:9px;height:14px;border-radius:2px;background:var(--c);
  transform:rotate(var(--r));animation:fall var(--d) ease-in var(--w) forwards;
}
@keyframes fall{to{transform:translateY(105vh) rotate(calc(var(--r) + 540deg))}}
.above{position:relative;z-index:1}

/* +10 coin */
.coin{
  width:150px;height:150px;border-radius:50%;display:grid;place-items:center;margin:0 auto;
  background:var(--gold-grad);color:var(--ink);font:800 58px/1 var(--fd);
  border:6px solid #fff1b8;
  box-shadow:0 8px 0 #b86a00,0 0 60px rgba(255,200,61,.65),inset 0 5px 0 rgba(255,255,255,.5);
  animation:coin .6s var(--pop) both;
}
.coin.zero{background:var(--panel-2);color:var(--tx-mut);border-color:var(--bd-lt);box-shadow:none;font-size:46px}
@keyframes coin{from{transform:scale(.3) rotate(-30deg);opacity:0}}

/* rank change ▲ / ▼ */
.mv{display:inline-flex;align-items:center;gap:2px;font:800 13px/1 var(--fd);flex:none;min-width:30px;justify-content:center}
.mv.up{color:var(--ok)} .mv.dn{color:var(--bad)} .mv.eq{color:var(--tx-mut)}
.mv svg{width:10px;height:10px}

/* ─── faces — the players' avatars ──────────────────────────── */
.face{display:inline-block;flex:none;border-radius:50%;overflow:hidden;line-height:0;
  box-shadow:0 0 0 2px rgba(255,255,255,.35)}
.face svg{width:100%;height:100%;display:block}
/* "self", not "me": .me is already the phone's score pill */
.face.self{box-shadow:0 0 0 3px var(--primary),0 0 18px var(--glow)}

/* ─── tables / lists ─────────────────────────────────────────── */
.lb{display:flex;flex-direction:column;gap:7px}
.lb .r{
  display:flex;align-items:center;gap:11px;
  padding:8px 12px;border-radius:14px;
  background:var(--panel-2);border:1px solid var(--bd);
  min-width:0;animation:rowin .35s ease both;
}
.lb .r:nth-child(2){animation-delay:.05s} .lb .r:nth-child(3){animation-delay:.1s}
.lb .r:nth-child(4){animation-delay:.15s} .lb .r:nth-child(5){animation-delay:.2s}
.lb .r:nth-child(6){animation-delay:.25s} .lb .r:nth-child(7){animation-delay:.3s}
.lb .r:nth-child(n+8){animation-delay:.35s}
@keyframes rowin{from{opacity:0;transform:translateY(12px)}}
/* Without min-width:0 a long name refuses to shrink and pushes the score
   out of the card — which is how the host panel ended up showing eight
   names where ten had been asked for. */
.lb .r .nm{min-width:0;overflow:hidden}
.lb .r .nm b{
  display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:800;
}
.lb .r .n{
  flex:none;width:28px;height:28px;display:grid;place-items:center;border-radius:50%;
  background:var(--bg-deep);font:800 14px/1 var(--fd);color:var(--tx-mut);
}
/* the row that is you, on your own phone */
.lb .r.mine{border:2px solid var(--primary);background:linear-gradient(90deg,color-mix(in srgb,var(--primary) 22%,var(--panel-2)),var(--panel-2))}
.lb .r:nth-child(1) .n{background:var(--gold-grad);color:var(--ink)}
.lb .r:nth-child(2) .n{background:linear-gradient(180deg,#f2f5fa,#aeb9cc);color:var(--ink)}
.lb .r:nth-child(3) .n{background:linear-gradient(180deg,#f5c08f,#c46f2e);color:var(--ink)}
.lb.podded .r .n{background:var(--bg-deep) !important;color:var(--tx-mut) !important}
.lb .r .s{flex:none;margin-left:auto;font:800 18px/1 var(--fd);color:var(--primary)}
.lb .r .tm{flex:none;padding:3px 9px;border-radius:999px;background:var(--bg-deep);border:1px solid var(--bd-lt);font:700 12.5px/1.3 var(--fd);color:var(--tx)}

/* podium — 2nd, 1st, 3rd */
.podium{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;align-items:end}
.podium .pd{display:flex;flex-direction:column;align-items:center;gap:5px;min-width:0;text-align:center;animation:rise .55s var(--pop) both}
.podium .pd.p1{animation-delay:.35s} .podium .pd.p2{animation-delay:.18s}
.podium .pd .nm{font:800 13.5px/1.25 var(--fs);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.podium .pd .sc{font:800 16px/1 var(--fd);color:var(--primary)}
.podium .pd .crown{font-size:24px;line-height:1}
.podium .blk{width:100%;border-radius:14px 14px 6px 6px;display:grid;place-items:center;font:800 34px/1 var(--fd);color:var(--ink);box-shadow:inset 0 3px 0 rgba(255,255,255,.5)}
.podium .p1 .blk{height:96px;background:var(--gold-grad)}
.podium .p2 .blk{height:70px;background:linear-gradient(180deg,#f2f5fa,#aeb9cc)}
.podium .p3 .blk{height:52px;background:linear-gradient(180deg,#f5c08f,#c46f2e)}
.podium .pd.mine .nm{color:var(--primary)}
@keyframes rise{from{opacity:0;transform:translateY(30px)}}

/* team race */
.race{display:flex;justify-content:center;align-items:flex-end;gap:clamp(14px,3vw,60px);min-height:0}
.race .tm{display:flex;flex-direction:column;align-items:center;gap:8px;width:clamp(90px,15vw,280px)}
.race .bar{width:100%;border-radius:22px 22px 8px 8px;background:linear-gradient(180deg,var(--tc),color-mix(in srgb,var(--tc) 60%,#000));
  box-shadow:inset 0 5px 0 rgba(255,255,255,.3),0 0 30px color-mix(in srgb,var(--tc) 40%,transparent);animation:grow .8s var(--pop) both;transform-origin:bottom}
.race .sc{font:800 clamp(26px,3.6vw,72px)/1 var(--fd)}
.race .nm{font:800 clamp(20px,2.5vw,48px)/1.2 var(--fd);text-align:center}
@keyframes grow{from{transform:scaleY(.05)}}

/* ─── the audience's own score sheet ──────────────────────────
   A phone in a hall has no room for a permanent leaderboard, so it
   lives behind one button and slides up over the round when asked. */
.sheet{
  position:fixed;inset:0;z-index:60;display:flex;flex-direction:column;justify-content:flex-end;
  background:rgba(5,2,18,.6);backdrop-filter:blur(3px);
}
.sheet .panel-in{
  background:linear-gradient(180deg,var(--panel-2),var(--panel));border-top:2px solid var(--primary);
  border-radius:24px 24px 0 0;
  padding:14px 14px calc(16px + env(safe-area-inset-bottom));
  max-height:86vh;display:flex;flex-direction:column;gap:11px;
  animation:sheetup .26s cubic-bezier(.2,.9,.3,1) both;
}
@keyframes sheetup{from{transform:translateY(100%)}}
.sheet .scroll{overflow:auto;-webkit-overflow-scrolling:touch}

/* the score the audience keeps an eye on — never allowed to be squeezed
   out of the top bar by a long game title */
.me{flex:none}

/* ─── match the pairs ─────────────────────────────────────────
   One photo box, three sizes: a thumbnail in the Studio, a row on a
   phone, a tile on the projector. The picture is a background so that
   "fill the box" and "show the whole picture" are one property. */
.mph{
  width:100%;aspect-ratio:1/1;border-radius:var(--r-sm);
  background:var(--bg-deep) center/cover no-repeat;
  border:1px solid var(--bd-lt);
  display:grid;place-items:center;text-align:center;overflow:hidden;
}
.mrow{
  display:flex;align-items:center;gap:11px;padding:8px 11px;
  border-radius:var(--r-sm);background:var(--panel-2);border:1px solid var(--bd);
  min-width:0;transition:var(--t);
}
.mrow .mph{width:58px;height:58px;flex:none;aspect-ratio:auto}
.mrow .grow{min-width:0;overflow:hidden}
.mrow .tag{
  flex:none;width:24px;height:24px;display:grid;place-items:center;border-radius:6px;
  background:var(--bg-deep);font:800 12px/1 var(--fd);color:var(--tx-mut);
}
.mrow.tap{cursor:pointer}
.mrow.tap:hover{border-color:var(--bd-lt)}
.mrow.on{border-color:var(--primary);background:var(--glow);box-shadow:0 0 18px var(--glow)}
.mrow.filled{border-color:var(--bd-lt)}
.mrow.ok{border-color:var(--ok);background:var(--ok-glow)}
.mrow.bad{border-color:var(--bad);background:var(--bad-glow)}

/* --- phone: photos one side, names the other ---
   The same shape as the projector, so somebody glancing up from their
   phone is looking at the same puzzle. */
.mpair{display:grid;grid-template-columns:minmax(0,98px) minmax(0,1fr);gap:10px;align-items:stretch}
.mcol-ph{display:grid;gap:8px;grid-auto-rows:minmax(0,1fr);min-width:0}
/* The names are deliberately NOT level with the photos. Lining them up
   one for one reads as "photo 1 goes with name A", which is the single
   thing this puzzle must never suggest — so they are spaced to fall
   between the photo rows instead. */
.mcol-nm{display:flex;flex-direction:column;justify-content:center;gap:9px;min-width:0}
.mname-b{min-height:50px;flex:none}

.mpick{
  position:relative;display:grid;padding:0;width:100%;min-height:0;overflow:hidden;
  border:2px solid var(--bd);border-radius:var(--r-sm);background:var(--bg-deep);
  cursor:pointer;transition:var(--t);
}
.mpick .im{display:block;width:100%;height:100%;min-height:74px;background:center/cover no-repeat}
.mpick:hover:not(:disabled){border-color:var(--bd-lt)}
.mpick.on{border-color:var(--primary);box-shadow:0 0 0 3px var(--glow)}
.mpick.set{border-color:var(--ok)}
.mpick:disabled{opacity:.6;cursor:default}
.mpick .no{
  position:absolute;top:4px;left:4px;padding:0 4px;
  min-width:20px;height:20px;display:grid;place-items:center;border-radius:6px;
  background:rgba(0,0,0,.62);color:#fff;font:800 11px/1 var(--fd);
}
.mpick .let{
  position:absolute;right:4px;bottom:4px;
  min-width:24px;height:24px;display:grid;place-items:center;border-radius:7px;
  background:var(--ok);color:#03150e;font:800 13px/1 var(--fd);
  box-shadow:0 2px 10px rgba(0,0,0,.4);
}

/* --- the Studio's pair editor ---
   The tile is the button. Clicking anywhere on it opens the file picker
   because it is a <label> wrapping a hidden input, and a photo can also
   be dropped straight onto it. The old row put a "Choose a photo" button
   under a 96px tile, where its own label did not fit. */
.pair-row{
  display:grid;grid-template-columns:112px minmax(0,1fr) auto;gap:13px;align-items:start;
  padding:11px;border-radius:var(--r-sm);
  background:var(--panel-2);border:1px solid var(--bd);transition:var(--t);
}
.pair-row.ready{border-color:color-mix(in srgb,var(--ok) 50%,var(--bd))}
.drop{
  position:relative;display:grid;place-items:center;text-align:center;
  width:112px;aspect-ratio:1;border-radius:var(--r-sm);
  border:2px dashed var(--bd-lt);background:var(--bg-deep) center/cover no-repeat;
  cursor:pointer;overflow:hidden;transition:var(--t);
}
.drop:hover{border-color:var(--primary);box-shadow:0 0 0 3px var(--glow)}
.drop.has{border-style:solid}
.drop.over{border-color:var(--primary);background-color:var(--glow)}
.drop .plus{display:block;font:300 32px/1 var(--fd);color:var(--primary)}
.drop .cap{display:block;font-size:10.5px;line-height:1.3;color:var(--tx-mut);margin-top:5px;padding:0 8px}
.drop .num{
  position:absolute;top:5px;left:5px;z-index:2;padding:0 5px;
  min-width:22px;height:22px;display:grid;place-items:center;border-radius:6px;
  background:var(--primary);color:var(--on-primary);font:800 11px/1 var(--fd);
}
.drop .swap{
  position:absolute;left:0;right:0;bottom:0;padding:5px 4px;
  background:rgba(0,0,0,.6);color:#fff;
  font:700 9.5px/1.3 var(--fd);letter-spacing:.08em;text-transform:uppercase;
  opacity:0;transition:var(--t);
}
.drop.has:hover .swap{opacity:1}
.pair-row .kb{align-self:center;font-size:10.5px;color:var(--tx-mut)}

/* a quieter button than .btn.sm, for the second-rank actions on a row */
.chip{
  padding:4px 10px;border-radius:999px;cursor:pointer;
  background:transparent;border:1px solid var(--bd-lt);color:var(--tx-mut);
  font:700 12px/1.4 var(--fd);transition:var(--t);white-space:nowrap;
}
.chip:hover{border-color:var(--primary);color:var(--tx)}
@media(max-width:560px){
  .pair-row{grid-template-columns:86px minmax(0,1fr) auto;gap:10px;padding:9px}
  .drop{width:86px}
}

/* Projector: photos on the left, names on the right. Everything is sized
   off the stage rather than off the pictures — four portrait photos must
   not push the names off the bottom of a hall screen, so every row is
   minmax(0,1fr) and the tiles shrink to whatever is left. */
.mgrid{
  display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
  gap:2vw;flex:1;min-height:0;
}
.mcol{display:grid;gap:1.2vh;min-height:0;min-width:0}
.mcol.photos{grid-auto-rows:minmax(0,1fr)}
.mcol.names{align-content:center;grid-auto-rows:max-content}
.mcard{position:relative;min-height:0;min-width:0}
.mcard .mph.big{height:100%;aspect-ratio:auto;min-height:0}
.mcard .tag,.mname .tag{
  position:absolute;top:6px;left:6px;z-index:2;
  min-width:clamp(22px,2vw,34px);height:clamp(22px,2vw,34px);
  display:grid;place-items:center;border-radius:7px;padding:0 5px;
  background:var(--primary);color:var(--on-primary);font:800 clamp(12px,1.2vw,19px)/1 var(--fd);
}
.mcard .pair{
  position:absolute;right:6px;bottom:6px;z-index:2;
  min-width:clamp(24px,2.2vw,38px);height:clamp(24px,2.2vw,38px);
  display:grid;place-items:center;border-radius:8px;
  background:var(--ok);color:#03150e;font:800 clamp(13px,1.3vw,21px)/1 var(--fd);
  box-shadow:0 0 20px var(--ok-glow);
}
.mname{
  position:relative;display:flex;align-items:center;gap:10px;
  padding:clamp(8px,1.1vh,16px) clamp(10px,1vw,18px) clamp(8px,1.1vh,16px) clamp(40px,3.6vw,58px);
  border-radius:var(--r-sm);background:var(--panel-2);border:1px solid var(--bd);
  font:700 clamp(16px,1.6vw,28px)/1.35 var(--fs);
}
.mname .tag{position:absolute;top:50%;left:8px;transform:translateY(-50%)}
@media(max-width:700px){ .mgrid{grid-template-columns:1fr} }

/* ─── table ───────────────────────────────────────────────────
   Used by the audience record, which is the one place the host sees
   mobile numbers and ages. Header sticks so a long list stays legible. */
.tbl{width:100%;border-collapse:collapse;font-size:13.5px}
.tbl th,.tbl td{padding:8px 11px;text-align:left;white-space:nowrap}
.tbl th{
  position:sticky;top:0;z-index:1;
  background:var(--panel-2);border-bottom:1px solid var(--bd);
  font:700 11.5px/1 var(--fd);color:var(--tx-mut);
}
.tbl tbody tr{border-bottom:1px solid var(--bd)}
.tbl tbody tr:last-child{border-bottom:0}
.tbl tbody tr:hover{background:var(--panel-2)}

/* ─── toast ──────────────────────────────────────────────────── */
#toast{
  position:fixed;left:50%;bottom:26px;
  /* Hiding it with a percentage of its own height is not enough to clear
     the 26px offset — a sliver of the pill stays poking up at the bottom
     of every page, including the projector. Move it its full height PLUS
     the offset, and hide it outright as well. */
  transform:translate(-50%,calc(100% + 40px));
  opacity:0;visibility:hidden;
  z-index:9999;max-width:min(520px,92vw);
  padding:12px 20px;border-radius:999px;
  background:#fff;border:0;color:var(--ink);
  font:800 15px/1.35 var(--fd);box-shadow:0 12px 34px rgba(0,0,0,.45);
  transition:transform .3s var(--pop), opacity .2s linear, visibility .3s;
  pointer-events:none;text-align:center;
}
#toast.show{transform:translate(-50%,0);opacity:1;visibility:visible}
#toast.err{background:var(--bad);color:#fff}

/* ─── modal / gate ───────────────────────────────────────────── */
.ovl{
  position:fixed;inset:0;z-index:200;display:grid;place-items:center;padding:20px;
  background:rgba(5,2,18,.82);backdrop-filter:blur(7px);
}
.ovl .box{width:min(460px,100%);max-height:90vh;overflow:auto;animation:pop .25s var(--pop)}
.ovl .box.wide{width:min(860px,100%)}
@keyframes pop{from{opacity:0;transform:translateY(14px) scale(.97)}}

.spin{
  width:34px;height:34px;border-radius:50%;
  border:3px solid var(--bd);border-top-color:var(--primary);
  animation:spin .8s linear infinite;
}
@keyframes spin{to{transform:rotate(1turn)}}

/* ─── projector-only scale ───────────────────────────────────── */
.screen-mode{font-size:clamp(18px,1.6vw,30px)}
.screen-mode .q-text{font:800 clamp(28px,3.6vw,64px)/1.28 var(--fd);text-wrap:balance}
.screen-mode .qcard{border-radius:clamp(20px,2vw,36px);padding:clamp(14px,1.6vw,30px) clamp(18px,2.6vw,48px) clamp(18px,2vw,36px);text-align:center;box-shadow:0 10px 0 #b9a6ff,0 20px 50px rgba(0,0,0,.4)}
.screen-mode .qcard .qn{font-size:clamp(13px,1.1vw,22px)}
.screen-mode .qcard .qq{font-size:clamp(28px,3.4vw,64px);line-height:1.28;text-wrap:balance}
.screen-mode .opt{font:700 clamp(22px,2.5vw,48px)/1.2 var(--fd);min-height:clamp(70px,16vh,190px);padding:clamp(10px,1vw,20px) clamp(16px,1.6vw,30px) clamp(10px,1vw,20px) clamp(12px,1.2vw,24px);gap:clamp(12px,1.4vw,26px);border-radius:clamp(18px,1.8vw,32px)}
.screen-mode .opt[data-l]{box-shadow:0 8px 0 var(--od),inset 0 4px 0 rgba(255,255,255,.28)}
.screen-mode .opt .lbl{width:clamp(44px,4.4vw,84px);height:clamp(44px,4.4vw,84px);font-size:clamp(22px,2.4vw,46px);border-radius:clamp(12px,1.2vw,22px)}
.screen-mode .opt .shp{width:clamp(22px,2.1vw,40px);height:clamp(22px,2.1vw,40px)}
.screen-mode .opt .tag{font-size:clamp(14px,1.3vw,26px);padding:clamp(4px,.4vw,8px) clamp(10px,1vw,18px)}
.screen-mode .opt .mark{width:clamp(36px,3.6vw,70px);height:clamp(36px,3.6vw,70px);border-width:4px}
.screen-mode .opt .mark svg{width:55%;height:55%}
.screen-mode .opt .pct{flex:none;font:800 clamp(24px,2.7vw,52px)/1 var(--fd)}
.screen-mode .opt .tbg{position:absolute;inset:0 auto 0 0;background:rgba(255,255,255,.2);border-radius:inherit;pointer-events:none}
.screen-mode .opt.correct{box-shadow:0 8px 0 var(--od),0 0 0 6px var(--ok),0 0 60px var(--ok-glow)}
.screen-mode .ring{width:clamp(96px,10vw,200px);height:clamp(96px,10vw,200px)}
.screen-mode .ring b{font-size:clamp(36px,4.2vw,84px)}
.screen-mode .timer{width:clamp(86px,7vw,132px);height:clamp(86px,7vw,132px);font-size:clamp(30px,2.8vw,48px)}
.screen-mode .stamp{position:fixed;padding:clamp(14px,1.4vw,26px) clamp(30px,3.6vw,70px);border-width:8px;border-radius:36px}
.screen-mode .stamp b{font-size:clamp(48px,6.8vw,130px)}
.screen-mode .stamp span{font-size:clamp(18px,1.8vw,34px)}
.screen-mode .expl{font-size:clamp(18px,1.6vw,30px);padding:clamp(12px,1.1vw,20px) clamp(16px,1.6vw,30px)}
/* the projector's lists: big enough for the last row of the hall —
   names 52 px, points 56 px, no city line, nothing under 36 px */
.screen-mode .lb{gap:clamp(8px,1vh,14px)}
.screen-mode .lb .r{padding:clamp(6px,.8vh,12px) clamp(14px,1.4vw,26px);gap:clamp(12px,1.2vw,24px);border-radius:22px}
.screen-mode .lb .r .n{width:clamp(36px,3.2vw,62px);height:clamp(36px,3.2vw,62px);font-size:clamp(18px,1.9vw,36px)}
.screen-mode .lb .r .nm b{font:800 clamp(26px,2.7vw,52px)/1.15 var(--fd)}
.screen-mode .lb .r .s{font-size:clamp(28px,2.9vw,56px)}
.screen-mode .lb .r .tm{font-size:clamp(18px,1.9vw,36px);padding:4px 16px}
.screen-mode .lb .r .mv{font-size:clamp(18px,1.9vw,36px);min-width:2.4em}
.screen-mode .lb .r .mv svg{width:.6em;height:.6em}
.screen-mode .podium{gap:clamp(12px,1.4vw,26px)}
.screen-mode .podium .pd .nm{font:800 clamp(24px,2.7vw,52px)/1.15 var(--fd);white-space:normal;overflow:visible;overflow-wrap:anywhere;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.screen-mode .podium .pd .sc{font-size:clamp(26px,2.9vw,56px)}
.screen-mode .podium .pd .crown{font-size:clamp(34px,3.4vw,64px)}
.screen-mode .podium .blk{font-size:clamp(50px,6vw,120px);border-radius:28px 28px 10px 10px}
.screen-mode .podium .p1 .blk{height:clamp(120px,24vh,260px)}
.screen-mode .podium .p2 .blk{height:clamp(90px,17vh,190px)}
.screen-mode .podium .p3 .blk{height:clamp(66px,12vh,140px)}

.screen-mode .opt.fade{opacity:.45}

/* ─── host controls ─────────────────────────────────────────────
   One big "Next" button, the five steps as a row of numbered stops,
   and the live tally per option in the answer colours. */
.nextbtn{
  display:flex;align-items:center;gap:14px;width:100%;min-height:74px;padding:10px 20px;
  border:0;border-radius:22px;cursor:pointer;text-align:left;
  background:var(--gold-grad);color:var(--ink);font:800 clamp(19px,2vw,27px)/1.2 var(--fd);
  box-shadow:0 5px 0 #b86a00,0 0 26px rgba(255,200,61,.4),inset 0 3px 0 rgba(255,255,255,.45);
  transition:transform .1s,box-shadow var(--t);
}
.nextbtn:active:not(:disabled){transform:translateY(3px);box-shadow:0 2px 0 #b86a00}
.nextbtn .ic{flex:none;width:44px;height:44px;border-radius:50%;display:grid;place-items:center;background:rgba(27,15,63,.14);font-size:20px}
.nextbtn.pts{background:linear-gradient(180deg,#3be07d,#12873f);color:#fff;box-shadow:0 5px 0 #0b5a2a,0 0 26px var(--ok-glow),inset 0 3px 0 rgba(255,255,255,.35)}
.nextbtn:disabled{background:var(--panel-2);color:var(--tx-mut);box-shadow:none;border:1.5px solid var(--bd);cursor:default}
.nextbtn .ring{width:56px;height:56px;box-shadow:none}
.nextbtn .ring b{font-size:22px}
.steps{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px}
.stp{display:flex;flex-direction:column;align-items:center;gap:5px;padding:6px 2px;border:0;background:none;cursor:pointer;color:var(--tx-mut);font:700 12.5px/1.25 var(--fd);text-align:center}
.stp .c{width:38px;height:38px;border-radius:50%;display:grid;place-items:center;background:var(--panel-2);border:1.5px solid var(--bd);font:800 17px/1 var(--fd);color:var(--tx-mut);transition:var(--t)}
.stp .c svg{width:18px;height:18px}
.stp.done{color:var(--tx)} .stp.done .c{background:var(--ok);border-color:var(--ok);color:#fff}
.stp.cur{color:var(--primary)} .stp.cur .c{background:var(--gold-grad);border:3px solid #fff;color:var(--ink);box-shadow:0 0 16px var(--glow)}
.stp:hover:not(:disabled) .c{border-color:var(--primary)}
.stp:disabled{opacity:.4;cursor:not-allowed}
.hopt{
  --oc:var(--panel-2);display:flex;align-items:center;gap:10px;padding:7px 10px;border-radius:12px;
  background:color-mix(in srgb,var(--oc) 16%,transparent);border:1.5px solid var(--oc);font-weight:700;font-size:14.5px;
}
.hopt[data-l="A"]{--oc:var(--opt-a)} .hopt[data-l="B"]{--oc:var(--opt-b)} .hopt[data-l="C"]{--oc:var(--opt-c)} .hopt[data-l="D"]{--oc:var(--opt-d)}
.hopt .lt{flex:none;width:28px;height:28px;border-radius:8px;display:grid;place-items:center;background:var(--oc);color:#fff;font:800 15px/1 var(--fd)}
.hopt[data-l="B"] .lt{color:var(--ink)}
.hopt .hb{flex:none;width:90px;height:9px;border-radius:5px;background:var(--bg-deep);overflow:hidden}
.hopt .hb i{display:block;height:100%;background:var(--oc)}
.hopt .pc{flex:none;min-width:64px;text-align:right;font:800 13.5px/1 var(--fd)}

/* ─── animation helpers ──────────────────────────────────────── */
.fade-in{animation:fi .35s ease both}
@keyframes fi{from{opacity:0;transform:translateY(9px)}}
.pop-in{animation:pop .3s var(--pop) both}

/* the lobby logo drifts gently so a waiting screen does not look frozen */
.float-slow{
  animation:floaty 6s ease-in-out infinite;
  will-change:transform;
}
@keyframes floaty{
  0%,100%{transform:translateY(0) scale(1)}
  50%{transform:translateY(-14px) scale(1.015)}
}
/* the logo on a soft light — no box, but the dark tagline still reads */
.logo-glow{position:relative;display:inline-grid;place-items:center}
.logo-glow::before{content:'';position:absolute;inset:-18% -14%;border-radius:50%;
  background:radial-gradient(closest-side,rgba(255,255,255,.92),rgba(255,255,255,.55) 55%,transparent);z-index:-1}
.logo-glow img{display:block;position:relative}
.tagline{color:var(--tx-mut);font:700 clamp(13px,1.4vw,26px)/1.4 var(--fs)}
html[lang="en"] .tagline{letter-spacing:.16em;text-transform:uppercase}

/* everything still for anyone whose phone asks for less motion */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}
  .confetti{display:none}
  .stamp{animation:none;transform:translate(-50%,-50%) rotate(-6deg);opacity:0}
}

/* ─── print (host sheets, tambola tickets) ───────────────────── */
@media print{
  body::before,body::after,html::before,html::after{display:none}
  body{background:#fff;color:#000}
  .no-print{display:none !important}
}

/* ─── phone ──────────────────────────────────────────────────── */
@media (max-width:640px){
  .wrap{width:calc(100% - 24px)}
  .card{padding:14px}
  .g2,.g3{grid-template-columns:1fr}
  .hdr .in{padding:8px 12px}
  .logo{height:34px}
}

/* AI drafts — the sparkle while the book is being read */
.ai-spin{display:inline-block;animation:aispin 1.6s ease-in-out infinite}
@keyframes aispin{0%,100%{transform:scale(1) rotate(0)}50%{transform:scale(1.25) rotate(20deg)}}
@media (prefers-reduced-motion:reduce){.ai-spin{animation:none}}

/* ─── install as an app (assets/pwa.js) ─────────────────────── */
.app-steps{gap:11px}
.app-steps .st{display:flex;gap:10px;align-items:center;font-size:15px;font-weight:600;line-height:1.4}
.app-steps .st .n{flex:none;width:26px;height:26px;border-radius:50%;display:grid;place-items:center;
  background:var(--gold-grad);color:var(--ink);font:800 14px/1 var(--fd)}
