/* SplitClue — risograph print look: two inks (pink, blue) slightly out of register,
   halftone dots, thick ink outlines. Fonts: Anybody (display), Atkinson Hyperlegible (body),
   Martian Mono (codes, clocks, dials). */

:root{
  --paper:#F2EFE8; --paper-2:#E7E2D7; --card:#FBFAF6;
  --ink:#17161C; --ink-2:#57535F; --line:#C9C3B6;
  --pink:#FF4F9A; --blue:#2F5BFF; --yellow:#FFD23F;
  --pink-text:#C8196A; --blue-text:#2346D8;
  --on-accent:#17161C; --on-blue:#FFFFFF;
  --ok:#1D7F52; --shadow:#17161C;
  --case:#1E1D2B; --case-dot:rgba(255,255,255,.06); --case-slot:rgba(255,255,255,.07);
  --blend:multiply;
  --display:"Anybody","Arial Black",Impact,sans-serif;
  --body:"Atkinson Hyperlegible",system-ui,sans-serif;
  --mono:"Martian Mono",ui-monospace,Menlo,Consolas,monospace;
  --radius:16px;
  color-scheme:light;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --paper:#121117; --paper-2:#1B1A22; --card:#1D1C25;
    --ink:#F2EFE8; --ink-2:#ABA7B6; --line:#3A3845;
    --pink:#FF5FA5; --blue:#6F8BFF; --yellow:#FFD84D;
    --pink-text:#FF8CBF; --blue-text:#9AAEFF;
    --on-blue:#0E0D14; --ok:#5FD19A; --shadow:#6F8BFF;
    --case:#25233A; --case-dot:rgba(255,255,255,.05); --case-slot:rgba(255,255,255,.07);
    --blend:screen; color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --paper:#121117; --paper-2:#1B1A22; --card:#1D1C25;
  --ink:#F2EFE8; --ink-2:#ABA7B6; --line:#3A3845;
  --pink:#FF5FA5; --blue:#6F8BFF; --yellow:#FFD84D;
  --pink-text:#FF8CBF; --blue-text:#9AAEFF;
  --on-blue:#0E0D14; --ok:#5FD19A; --shadow:#6F8BFF;
  --case:#25233A; --case-dot:rgba(255,255,255,.05); --case-slot:rgba(255,255,255,.07);
  --blend:screen; color-scheme:dark;
}

*,*::before,*::after{box-sizing:border-box}
html{height:100%;-webkit-text-size-adjust:100%}
body{margin:0;min-height:100%;background:var(--paper);color:var(--ink);font-family:var(--body);font-size:17px;line-height:1.5;-webkit-font-smoothing:antialiased;
  padding:env(safe-area-inset-top,0) env(safe-area-inset-right,0) env(safe-area-inset-bottom,0) env(safe-area-inset-left,0)}
button,input{font:inherit;color:inherit}
button{cursor:pointer}
a{color:var(--blue-text);text-underline-offset:3px;text-decoration-thickness:2px}
:focus-visible{outline:3px solid var(--blue);outline-offset:3px}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
svg.i{width:1.25em;height:1.25em;flex:none;vertical-align:-.25em}

/* ---------- Riso overprint: blue ink with a pink layer slightly out of register ---------- */
.riso{position:relative;display:inline-block;color:var(--blue)}
.riso::after{content:attr(data-text);content:attr(data-text) / "";position:absolute;left:0;top:0;color:var(--pink);
  transform:translate(.055em,.04em);mix-blend-mode:var(--blend);pointer-events:none;white-space:nowrap}
.logo{font-family:var(--display);font-weight:900;font-stretch:118%;letter-spacing:-.03em;line-height:.9;text-decoration:none}
.halftone{background-image:radial-gradient(var(--dot,rgba(23,22,28,.14)) 1.1px,transparent 1.5px);background-size:7px 7px}

/* ---------- Buttons and fields ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5em;padding:.72em 1.15em;border:2px solid var(--ink);border-radius:12px;
  background:var(--card);color:var(--ink);font-weight:700;line-height:1.2;text-decoration:none;box-shadow:3px 3px 0 var(--shadow);
  transition:transform .08s ease,box-shadow .08s ease}
.btn:hover{transform:translate(-1px,-1px);box-shadow:4px 4px 0 var(--shadow)}
.btn:active{transform:translate(2px,2px);box-shadow:1px 1px 0 var(--shadow)}
.btn:disabled{opacity:.55;cursor:wait;transform:none}
.btn.primary{background:var(--pink);color:var(--on-accent);box-shadow:3px 3px 0 var(--blue);border-color:var(--on-accent)}
.btn.primary:hover{box-shadow:4px 4px 0 var(--blue)}
.btn.ghost{background:transparent;box-shadow:none;border-color:transparent;text-decoration:underline;text-underline-offset:3px;padding-inline:.4em}
.btn.ghost:hover,.btn.ghost:active{transform:none;box-shadow:none}
.btn.wide{width:100%}
.btn[hidden]{display:none}
.codefield{display:flex;gap:10px}
.codefield input{flex:1;min-width:0;padding:.45em .6em;border:2px solid var(--ink);border-radius:12px;background:var(--card);
  font-family:var(--mono);font-weight:700;font-size:1.7rem;letter-spacing:.3em;text-transform:uppercase;text-align:center}
.codefield input::placeholder{color:var(--line)}
.err{color:var(--pink-text);font-weight:700;font-size:.95rem;min-height:1.5em;margin:.5em 0 0}
.card{background:var(--card);border:2px solid var(--ink);border-radius:var(--radius)}
.eyebrow{font-family:var(--mono);font-size:.74rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2);margin:0}
.muted{color:var(--ink-2)}

/* ---------- Site header ---------- */
.site{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:18px 20px;max-width:1120px;margin:0 auto}
.site .logo{font-size:clamp(1.9rem,5vw,2.4rem)}
.site .tag{font-family:var(--mono);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);text-align:right}

/* ---------- Hub ---------- */
.hub{max-width:1120px;margin:0 auto;padding:4px 20px 56px}
.hero h1{font-family:var(--display);font-weight:850;font-stretch:78%;font-size:clamp(3rem,11vw,6.2rem);line-height:.9;letter-spacing:-.01em;margin:18px 0 18px}
.hero h1 .hl{background:linear-gradient(transparent 58%,var(--yellow) 58%,var(--yellow) 90%,transparent 90%);padding:0 .06em;-webkit-box-decoration-break:clone;box-decoration-break:clone}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .hero h1 .hl{background:none;color:var(--yellow)}}
:root[data-theme="dark"] .hero h1 .hl{background:none;color:var(--yellow)}
.hero .lede{font-size:1.15rem;max-width:30em;margin:0;color:var(--ink-2)}
.sect{display:flex;align-items:center;gap:14px;margin:56px 0 20px}
.sect h2{font-family:var(--mono);font-size:.8rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;margin:0;white-space:nowrap}
.sect::after{content:"";height:2px;flex:1;background:var(--ink)}
.gamegrid{display:grid;gap:24px}
.gamecard{overflow:hidden;box-shadow:6px 6px 0 var(--shadow);display:flex;flex-direction:column}
.cover{position:relative;aspect-ratio:16/8;background-color:#FFD23F;--dot:rgba(23,22,28,.16);border-bottom:2px solid var(--ink);display:grid;place-items:center;overflow:hidden}
.cover>svg{width:78%;max-width:420px;height:auto}
.cover .badge{position:absolute;left:14px;top:14px;background:#17161C;color:#FFD23F;font-family:var(--mono);font-size:.7rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;padding:5px 9px;border-radius:6px}
.gbody{padding:18px 20px 22px;display:flex;flex-direction:column;gap:12px;flex:1}
.gbody h3{font-family:var(--display);font-weight:850;font-stretch:90%;font-size:2rem;line-height:1;margin:0}
.gbody p{margin:0;color:var(--ink-2)}
.facts{display:flex;flex-wrap:wrap;gap:8px;list-style:none;padding:0;margin:0}
.facts li{font-family:var(--mono);font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;border:2px solid var(--ink);border-radius:999px;padding:3px 10px}
/* Difficulty chips: same colors in light and dark, dark text for contrast */
.facts li.diff{color:#17161C;border-color:var(--ink)}
.facts li.diff-easy{background:#6CCB5F}
.facts li.diff-medium{background:#FFD23F}
.facts li.diff-hard{background:#FF8A7A}
.gactions{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin-top:auto;padding-top:6px}
.foot{max-width:1120px;margin:0 auto;padding:24px 20px 40px;border-top:2px solid var(--ink);display:flex;flex-wrap:wrap;gap:20px 40px;justify-content:space-between;align-items:flex-start;color:var(--ink-2);font-size:.92rem}
.foot b{display:block;color:var(--ink);font-family:var(--display);font-weight:850;font-size:1.1rem;margin-bottom:2px}
.contact{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:16px 32px}
.contact li{display:flex;flex-direction:column;gap:2px}
.contact a{font-weight:700;overflow-wrap:anywhere}

/* ---------- Join page ---------- */
.joinpage{max-width:560px;margin:0 auto;padding:6px 20px 48px}
.roomchip{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-weight:700;font-size:.8rem;letter-spacing:.12em;text-transform:uppercase;
  background:#17161C;color:#F2EFE8;border:2px solid var(--ink);border-radius:8px;padding:5px 10px}   /* dark ink in both modes, so the yellow code always reads */
.roomchip b{letter-spacing:.3em;color:var(--yellow)}
.joinpage h1{font-family:var(--display);font-weight:850;font-stretch:85%;font-size:clamp(2.4rem,11vw,3.4rem);line-height:.95;margin:14px 0 8px}
.joinpage .lede{margin:0 0 22px;color:var(--ink-2)}
.roles{display:grid;gap:12px}
.role{display:flex;align-items:center;gap:14px;width:100%;text-align:left;padding:14px;background:var(--card);border:2px solid var(--ink);border-radius:14px;box-shadow:3px 3px 0 var(--shadow);
  transition:transform .08s ease,box-shadow .08s ease}
.role:hover{transform:translate(-1px,-1px);box-shadow:4px 4px 0 var(--shadow)}
.role:active{transform:translate(2px,2px);box-shadow:1px 1px 0 var(--shadow)}
.role .ric{width:46px;height:46px;border-radius:50%;display:grid;place-items:center;background:var(--yellow);color:#17161C;border:2px solid var(--ink);flex:none}
.role .ric svg{width:24px;height:24px}
.role .rt{flex:1;min-width:0}
.role .rt b{display:block;font-size:1.08rem}
.role .rt span{display:block;color:var(--ink-2);font-size:.92rem;line-height:1.35}
.avail{flex:none;font-family:var(--mono);font-size:.68rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;padding:4px 8px;border-radius:6px;background:var(--blue);color:var(--on-blue)}
.avail:empty{display:none}
.avail.taken{background:transparent;color:var(--ink-2);box-shadow:inset 0 0 0 2px var(--line)}
.role.is-taken{box-shadow:none;border-color:var(--line)}
.role:disabled{cursor:not-allowed;opacity:.6;transform:none}
.joinflash{margin:0 0 14px}
.role.is-taken .ric{background:var(--paper-2)}
.hint{min-height:1.5em;margin:14px 0 0;font-weight:700}
.others{margin-top:28px;padding-top:20px;border-top:2px dashed var(--line)}
.others .row{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin-top:10px}

/* ---------- In-game bar ---------- */
.bar{position:sticky;top:0;z-index:5;display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--paper);border-bottom:2px solid var(--ink)}
.bar .who{display:flex;align-items:center;gap:8px;font-family:var(--display);font-weight:800;font-stretch:95%;font-size:1.15rem;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bar .meta{display:flex;align-items:center;gap:10px;margin-left:auto;flex:none}
.miniclock{font-family:var(--mono);font-weight:700;font-size:1rem;font-variant-numeric:tabular-nums}
.miniclock.low,.clock.low{color:var(--pink-text)}
.codetag{font-family:var(--mono);font-weight:700;font-size:.78rem;letter-spacing:.2em;padding:3px 4px 3px 7px;border:2px solid var(--ink);border-radius:6px}
.net{width:10px;height:10px;border-radius:50%;background:var(--ink-2);flex:none}
.net.live{background:var(--ok)}
.net.reconnecting{background:var(--pink);animation:blink 1s steps(2) infinite}
@keyframes blink{50%{opacity:.25}}
.leave{display:grid;place-items:center;width:34px;height:34px;border:2px solid var(--ink);border-radius:10px;background:var(--card);padding:0}
.leave svg{width:16px;height:16px}
@media (max-width:330px){.codetag{display:none}}

/* ---------- Shared screen ---------- */
.tv{padding:20px 18px 32px;max-width:820px;margin:0 auto}
.tvhead{display:flex;justify-content:space-between;align-items:flex-end;gap:12px;flex-wrap:wrap;margin-bottom:16px}
.tvhead h2{font-family:var(--display);font-weight:850;font-stretch:85%;font-size:clamp(2rem,6vw,3rem);line-height:.95;margin:4px 0 0}
.clock{font-family:var(--mono);font-weight:700;font-size:clamp(2.4rem,8vw,3.6rem);font-variant-numeric:tabular-nums;line-height:1;letter-spacing:-.02em}
.joincard{display:flex;gap:18px;align-items:center;padding:14px;margin-bottom:18px;box-shadow:5px 5px 0 var(--pink)}
.joincard[hidden]{display:none}
.qr{width:136px;height:136px;flex:none;background:#fff;border:2px solid var(--ink);border-radius:10px;overflow:hidden}
.qr svg{display:block;width:100%;height:100%}
.joincard .jt{font-family:var(--display);font-weight:850;font-stretch:95%;font-size:1.6rem;line-height:1;margin:0 0 6px}
.joincard p{margin:0;color:var(--ink-2)}
.joincard p b{color:var(--ink);font-family:var(--mono);font-size:.92em}
.joincard .warn{color:var(--pink-text);font-weight:700;margin-top:6px}
.case{position:relative;background-color:var(--case);--dot:var(--case-dot);border:3px solid var(--ink);border-radius:22px;padding:clamp(10px,3vw,24px);box-shadow:6px 6px 0 var(--blue)}
.grid{display:grid;grid-template-columns:repeat(5,1fr);gap:clamp(6px,1.6vw,12px)}
.slot{aspect-ratio:1;background:var(--case-slot);border-radius:50%;display:grid;place-items:center}
.slot svg{width:80%;height:80%;filter:drop-shadow(0 3px 2px rgba(0,0,0,.4))}
.overlay{position:absolute;inset:0;z-index:4;border-radius:19px;display:grid;place-items:center;background:rgba(30,29,43,.93);background:color-mix(in srgb,var(--case) 93%,transparent);color:#F2EFE8;text-align:center;padding:20px}
.overlay[hidden]{display:none}
.overlay h3{font-family:var(--display);font-weight:900;font-stretch:90%;font-size:clamp(2.2rem,7vw,3.6rem);line-height:.95;margin:0 0 10px;color:#FFD23F}
.overlay p{margin:0;font-size:1.1rem}
.tvctl{display:flex;gap:12px;margin-top:22px;flex-wrap:wrap;align-items:center}
.lockstate{display:inline-flex;align-items:center;gap:10px;margin-left:auto}
.crewlist{display:flex;flex-wrap:wrap;gap:8px;list-style:none;padding:0;margin:18px 0 0}
.crewlist li{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border:2px dashed var(--ink-2);border-radius:999px;color:var(--ink-2);font-weight:700;font-size:.95rem}
.crewlist li.in{border:2px solid var(--blue);background:var(--blue);color:var(--on-blue)}
.crewnote{color:var(--ink-2);margin:10px 0 0}

/* ---------- Phones ---------- */
.phone{padding:20px 18px 34px;max-width:480px;margin:0 auto}
.brief{color:var(--ink-2);margin:0 0 18px}
.status{display:inline-block;background:var(--yellow);color:#17161C;font-weight:700;border:2px solid var(--ink);border-radius:10px;padding:6px 12px;margin:0 0 18px}
.status:empty{display:none}
.ticket{position:relative;background:var(--card);border:2px solid var(--ink);border-radius:18px;padding:20px 20px 18px;box-shadow:5px 5px 0 var(--pink)}
.ticket .stamp{position:absolute;top:-13px;right:16px;background:var(--pink);color:var(--on-accent);border:2px solid var(--on-accent);border-radius:6px;padding:3px 8px;
  font-family:var(--mono);font-size:.68rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;transform:rotate(3deg)}
.ticket h3{font-family:var(--display);font-weight:850;font-stretch:90%;font-size:1.7rem;line-height:1;margin:0}
.perf{position:relative;height:0;border-top:2px dashed var(--line);margin:16px -20px 16px}
.perf::before,.perf::after{content:"";position:absolute;top:-12px;width:22px;height:22px;border-radius:50%;background:var(--paper);border:2px solid var(--ink)}
.perf::before{left:-12px;clip-path:inset(0 0 0 50%)}
.perf::after{right:-12px;clip-path:inset(0 50% 0 0)}
.ticket p{margin:0 0 12px}
.ticket .fine{font-size:.92rem;color:var(--ink-2);margin:0}
.ticket ul{list-style:none;padding:0;margin:0 0 14px}
.ticket li{display:flex;align-items:center;gap:12px;padding:10px 0;border-bottom:2px dotted var(--line);font-size:1.1rem;font-weight:700}
.ticket li:last-child{border-bottom:none}
.dialno{font-family:var(--mono);font-size:.8rem;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-2);width:4.6rem;flex:none}
.sw{width:22px;height:22px;border-radius:50%;flex:none;border:2px solid var(--ink)}
.cuts{display:flex;gap:18px;margin:4px 0 16px}
.cut{text-align:center;font-weight:700}
.cut svg{width:78px;height:78px;display:block;margin:0 auto 4px}

.lock{padding:18px 14px;box-shadow:5px 5px 0 var(--blue)}
.dials{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.dial{display:flex;flex-direction:column;align-items:center;gap:8px}
.dial small{font-family:var(--mono);font-size:.68rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-2)}
.dial button{width:100%;max-width:72px;height:46px;border-radius:10px;border:2px solid var(--ink);background:var(--card);box-shadow:2px 2px 0 var(--shadow);font-size:1rem;line-height:1}
.dial button:active{transform:translate(2px,2px);box-shadow:none}
.digit{font-family:var(--mono);font-weight:700;font-size:2.6rem;line-height:1.2;font-variant-numeric:tabular-nums;width:100%;max-width:72px;text-align:center;
  border-radius:10px;background:var(--case);color:#FFD23F;border:2px solid var(--ink);padding:4px 0}
.try{width:100%;margin-top:18px;padding:.9em;font-size:1.08rem}
.pips{display:flex;gap:8px;justify-content:center}
.lock .pips{margin-top:16px}
.pip{width:14px;height:14px;border-radius:50%;background:var(--pink);border:2px solid var(--ink)}
.pip.used{background:transparent;border-color:var(--line)}
.feedback{text-align:center;min-height:3em;margin-top:10px;font-weight:700}
.ddpad .feedback:empty{min-height:0;margin:0}   /* the pad only makes room for a message when there is one (it appears below the keys, so they never move) */
.result{text-align:center;padding:30px 10px}
.result h3{font-family:var(--display);font-weight:900;font-stretch:88%;font-size:2.8rem;line-height:.95;margin:0 0 12px}
.result .brief{margin-bottom:22px}

/* ---------- Accounts ---------- */
.btn.small{padding:.5em .9em;font-size:.92rem;box-shadow:2px 2px 0 var(--shadow)}
.acctslot{display:flex;align-items:center}
.whoami{display:inline-flex;align-items:center;gap:8px;padding:4px 12px 4px 4px;border:2px solid var(--ink);border-radius:999px;background:var(--card);color:var(--ink);font-weight:700;text-decoration:none;max-width:12rem}
.whoami span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.avatar{width:30px;height:30px;border-radius:50%;flex:none;display:grid;place-items:center;background:var(--yellow);color:#17161C;font-family:var(--display);font-weight:900;border:2px solid var(--ink);object-fit:cover}
.avatar.big{width:64px;height:64px;font-size:1.8rem}
.acct{max-width:540px;margin:0 auto;padding:6px 20px 56px}
.acct h1{font-family:var(--display);font-weight:850;font-stretch:85%;font-size:clamp(2.4rem,10vw,3.2rem);line-height:.95;margin:10px 0 10px}
.acct .lede{color:var(--ink-2);margin:0 0 22px}
.acct h2{font-family:var(--display);font-weight:800;font-size:1.35rem;margin:0 0 10px}
.signin{padding:20px;box-shadow:6px 6px 0 var(--blue)}
.signin form{display:grid;gap:10px}
.signin .fine{margin:0;font-size:.9rem}
.label{font-weight:700}
.textin{width:100%;padding:.7em .8em;border:2px solid var(--ink);border-radius:12px;background:var(--card);font-size:1.05rem}
.gbtn{background:#fff;color:#1F1F1F;border-color:#17161C;box-shadow:3px 3px 0 var(--shadow)}
.gbtn svg{width:20px;height:20px}
.or{display:flex;align-items:center;gap:12px;margin:18px 0 14px;color:var(--ink-2);font-size:.88rem}
.or::before,.or::after{content:"";flex:1;height:2px;background:var(--line)}
.legal{margin-top:16px;font-size:.88rem}
.me{display:flex;align-items:center;gap:16px;margin:12px 0 22px}
.me h1{margin:0 0 2px;font-size:clamp(2rem,8vw,2.6rem);overflow-wrap:anywhere}
.me p{margin:0;overflow-wrap:anywhere}
svg.avatar{border:none;background:none;padding:0}
.avatar.huge{width:132px;height:132px}
.me .btn.small{margin-top:10px}
.editor{padding:20px;box-shadow:6px 6px 0 var(--blue);display:grid;gap:8px}
.preview{display:flex;flex-direction:column;align-items:center;gap:8px;padding:6px 0 14px}
.preview b{font-family:var(--display);font-weight:850;font-size:1.4rem;line-height:1.1;text-align:center;overflow-wrap:anywhere}
.count{margin:0;text-align:right;font-size:.82rem}
.nameerr{margin:-4px 0 0;min-height:0}
.nameerr:empty{display:none}
.picker{border:none;padding:0;margin:10px 0 0}
.picker legend{margin-bottom:10px;padding:0}
.swatches{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;max-width:320px}
.bgopt{display:grid;place-items:center;cursor:pointer}
.bgopt .dot{width:42px;height:42px;border-radius:50%;border:2px solid var(--ink);transition:transform .08s ease}
.bgopt input:checked+.dot{box-shadow:0 0 0 3px var(--paper),0 0 0 6px var(--ink);transform:scale(.92)}
.bgopt input:focus-visible+.dot{outline:3px solid var(--blue);outline-offset:6px}
.animals{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.an{display:flex;flex-direction:column;align-items:center;gap:4px;padding:8px 4px;border:2px solid transparent;border-radius:14px;cursor:pointer;font-size:.85rem;font-weight:700;color:var(--ink-2)}
.an .anart{width:56px;height:56px}
.an:hover{border-color:var(--line)}
.an:has(input:checked){border-color:var(--ink);background:var(--paper-2);color:var(--ink)}
.an:has(input:focus-visible){outline:3px solid var(--blue);outline-offset:2px}
.editor #rnd{justify-self:start;margin-top:8px}
.editoractions{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin-top:4px}
.acctcard{padding:20px;box-shadow:6px 6px 0 var(--pink)}
.gamelist{list-style:none;padding:0;margin:0 0 18px}
.gamelist li{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 0;border-bottom:2px dotted var(--line)}
.gamelist li:last-child{border-bottom:none}
.tagfree,.tagown{font-family:var(--mono);font-size:.68rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:3px 8px;border-radius:6px;white-space:nowrap}
.tagfree{box-shadow:inset 0 0 0 2px var(--line);color:var(--ink-2)}
.tagown{background:var(--blue);color:var(--on-blue)}
.acctactions{margin:24px 0}
.danger{margin-top:36px;padding-top:20px;border-top:2px dashed var(--line)}
.danger h2{font-size:1.1rem}
.danger p{margin:0 0 12px}
.legalinks{display:flex;gap:16px;margin:0;flex-basis:100%;font-size:.88rem}

/* ---------- Player profiles (per session) ---------- */
.avatar.tiny{width:24px;height:24px;flex:none}
.youbar{display:flex;align-items:center;gap:10px;padding:10px 12px;margin:4px 0 16px;background:var(--card);border:2px solid var(--ink);border-radius:14px}
.youbar .avatar{width:40px;height:40px}
.youbar span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.role .rt .takers{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.role .rt .takers:empty{display:none}
.role .rt .taker{display:inline-flex;align-items:center;gap:5px;font-weight:700;font-size:.85rem;color:var(--ink)}
.bar .who .avatar{width:28px;height:28px}
.whotext{display:flex;flex-direction:column;min-width:0;line-height:1.05}
.whoname{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.whorole{font-family:var(--mono);font-size:.68rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-2);font-stretch:normal}
.hostedby{display:flex;align-items:center;gap:8px;margin:18px 0 0;color:var(--ink-2)}
.hostedby b{color:var(--ink)}
.crewlist li .avatar.tiny{margin-right:-2px}
.crewlist li.in{gap:6px;padding:4px 12px 4px 5px}
.crewlist li.in b{margin-right:4px}
.crole{font-family:var(--mono);font-size:.64rem;letter-spacing:.08em;text-transform:uppercase;opacity:.85}

/* ---------- Heist status and host controls on phones ---------- */
.ctlphone{padding-bottom:0}
.ctlwrap:empty{display:none}
.ctl{position:relative;display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;padding:12px 14px;margin:0 0 18px;background:var(--card);border:2px solid var(--ink);border-radius:14px}
.ctl p{margin:0;flex:1 1 12rem;font-weight:700}
.ctl.is-host{padding-top:18px;box-shadow:4px 4px 0 var(--pink)}
.ctlbtns{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.ctl-ready.is-host .ctlbtns,.ctl-won.is-host .ctlbtns,.ctl-lost.is-host .ctlbtns{flex-basis:100%}
.ctl-ready.is-host .btn.primary,.ctl-won.is-host .btn.primary,.ctl-lost.is-host .btn.primary{flex:1}
.hostbadge{position:absolute;top:-11px;left:12px;background:var(--yellow);color:#17161C;border:2px solid var(--ink);border-radius:6px;padding:1px 7px;font-family:var(--mono);font-size:.64rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase}
.hostnote{color:var(--ink-2);font-weight:700}
.hostnote[hidden]{display:none}
.hostbox{position:relative;padding:18px 16px 14px;margin:6px 0 18px;box-shadow:5px 5px 0 var(--pink)}
.hostbox[hidden]{display:none}
.hostbox p{margin:0 0 6px}
.bigcode{font-family:var(--mono);font-weight:700;font-size:2.4rem;letter-spacing:.3em;text-align:center;margin:8px 0 10px!important}

/* ---------- Lobby (shared screen, before each heist) ---------- */
.lobby[hidden],#play[hidden]{display:none}
.lobbyhead{display:flex;justify-content:space-between;align-items:flex-end;gap:12px;flex-wrap:wrap;margin-bottom:20px}
.lobbyhead h2{font-family:var(--display);font-weight:850;font-stretch:85%;font-size:clamp(2rem,6vw,3.2rem);line-height:.95;margin:4px 0 0}
.lobbymeta{display:flex;align-items:center;gap:10px;font-family:var(--mono);font-weight:700;font-size:.85rem;color:var(--ink-2)}
.lobbygrid{display:grid;gap:20px}
@media (min-width:720px){.lobbygrid{grid-template-columns:auto 1fr;align-items:start}}
.lobbyjoin{display:flex;gap:18px;align-items:center;padding:16px;box-shadow:6px 6px 0 var(--pink)}
@media (min-width:720px){.lobbyjoin{flex-direction:column;text-align:center;max-width:300px}}
.qr.big{width:200px;height:200px}
.lobbyjoin .jt{font-family:var(--display);font-weight:850;font-size:1.5rem;line-height:1;margin:0 0 6px}
.lobbyjoin p{margin:0;color:var(--ink-2)}
.lobbyjoin p b{color:var(--ink);font-family:var(--mono)}
.lobbyjoin .bigcode{margin:6px 0 0!important;color:var(--ink)}
.lobbycrew .eyebrow{margin-bottom:10px}
.seats{list-style:none;padding:0;margin:0;display:grid;gap:12px}
.seat{display:flex;align-items:center;gap:14px;padding:14px 16px;border:2px dashed var(--ink-2);border-radius:16px;color:var(--ink-2);min-height:78px}
.seat b{font-family:var(--display);font-weight:800;font-size:1.35rem;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.seat.in{border:2px solid var(--ink);background:var(--card);color:var(--ink);box-shadow:4px 4px 0 var(--blue)}
.seaticon{width:48px;height:48px;border-radius:50%;display:grid;place-items:center;border:2px dashed var(--ink-2);flex:none}
.seaticon svg{width:24px;height:24px}
.avatar.seatav{width:48px;height:48px;flex:none}
.seatav+.seatav{margin-left:-18px}
.seatrole{font-family:var(--mono);font-size:.72rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase}
.lobbyfoot{margin-top:22px;display:flex;flex-direction:column;gap:14px}
.lobbystatus{margin:0;font-weight:700;font-size:1.15rem}
.lobbybtns{display:flex;flex-wrap:wrap;gap:12px}
.lobbyfoot .hostedby{margin:0}

/* ---------- Night Train ---------- */
.nightcar{position:relative;background-color:#1B2140;--dot:rgba(255,255,255,.05);border:3px solid var(--ink);border-radius:22px;padding:clamp(12px,3vw,24px);box-shadow:6px 6px 0 var(--pink);color:#F2EFE8}
.train{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:10px}
.compartment{position:relative;background:#FFE7A6;border:3px solid #17161C;border-radius:12px;min-height:118px;padding:22px 6px 6px;box-shadow:inset 0 -6px 0 rgba(0,0,0,.08)}
.cnum{position:absolute;top:4px;left:8px;font-family:var(--mono);font-weight:700;font-size:.8rem;color:#17161C}
.figs{display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-end;gap:2px;height:100%}
.fig{width:44px;height:53px;flex:none}
.fig.big{width:84px;height:100px;display:block;margin:0 auto 8px}
.fig.hatonly{width:30px;height:30px}
.route{list-style:none;display:flex;flex-wrap:wrap;gap:6px 0;padding:0;margin:18px 0 0;font-family:var(--mono);font-size:.8rem;font-weight:700}
.route li{display:flex;align-items:center;gap:6px;color:rgba(242,239,232,.85)}
.route li:not(:last-child)::after{content:"";width:28px;height:2px;background:rgba(242,239,232,.4);margin:0 6px}
.route .stop{width:12px;height:12px;border-radius:50%;border:2px solid #F2EFE8;flex:none}
.route li.here .stop{background:#FFD23F;border-color:#FFD23F}
.carnote{margin:14px 0 0;color:rgba(242,239,232,.75);font-size:.95rem}
.nightcar .overlay{background:rgba(27,33,64,.95);border-radius:19px}
.tags li,.log li{align-items:center}
.tags .fig{width:38px;height:46px}
.tags span{display:flex;flex-direction:column;line-height:1.2}
.tags small{font-weight:400;color:var(--ink-2);font-size:.85rem}
.log li{font-weight:400;font-size:1rem;gap:10px}
.log .fig{width:34px;height:41px}
.log .sw{width:26px;height:26px}
.logstop{font-family:var(--mono);font-size:.74rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);margin:14px 0 4px!important}
.accuse{margin-top:22px;padding:18px;box-shadow:5px 5px 0 var(--blue)}
.accuse h3{font-family:var(--display);font-weight:850;font-size:1.4rem;margin:0 0 4px}
.accuse #acnote{margin:0 0 12px;font-size:.92rem}
.suspects{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:14px}
.suspect{padding:.7em .6em;border:2px solid var(--ink);border-radius:12px;background:var(--card);font-weight:700;text-align:left;line-height:1.2}
.suspect.on{background:var(--yellow);color:#17161C}
.suspect.wrong{text-decoration:line-through;opacity:.5}
.suspect:disabled{cursor:default}
.accuse .pips{margin-top:14px}

/* ---------- Difficulty ---------- */
.diffchip{display:inline-block;font-family:var(--mono);font-size:.7rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;padding:3px 9px;border:2px solid var(--ink);border-radius:999px;color:#17161C}
.diff-easy{background:#6CCB5F}.diff-medium{background:#FFD23F}.diff-hard{background:#FF8A7A}
.tvclock{display:flex;align-items:center;gap:14px}
.diffpick{display:flex;flex-direction:column;gap:6px;flex-basis:100%}
.diffbtns{display:flex;flex-wrap:wrap;gap:8px}
.diffbtn{font-family:var(--mono);font-weight:700;font-size:.8rem;letter-spacing:.08em;text-transform:uppercase;padding:.55em 1em;border:2px solid var(--ink);border-radius:999px;color:#17161C;opacity:.55;box-shadow:none}
.diffbtn.on{opacity:1;box-shadow:3px 3px 0 var(--shadow)}
.diffbtn:not(.on):hover{opacity:.85}
.diffbtn:disabled{cursor:wait}
#tvdiff:empty{display:none}
#tvdiff{margin-top:16px}
.rolebanner{margin:0;padding:10px 16px;background:var(--yellow);color:#17161C;font-weight:700;text-align:center;border-bottom:2px solid var(--ink)}
.connecting{padding:28px 18px;color:var(--ink-2);text-align:center}

/* Labelled case (Medium, Hard) */
.grid.labelled{align-items:center}
.glabel{font-family:var(--mono);font-weight:700;font-size:clamp(.7rem,1.8vw,.95rem);color:rgba(242,239,232,.7);text-align:center;padding:0 4px}
/* Hard: the flashlight. Unlit rows are nearly black; lit rows fade in. */
.case.flash .slot{opacity:.05;transition:opacity .6s ease}
.case.flash .slot.lit{opacity:1}
.case.flash .glabel[data-row]{opacity:.35;transition:opacity .6s ease}
.case.flash .glabel.lit{opacity:1;color:#FFD23F}
.lightsout{position:absolute;inset:0;display:grid;place-items:center;text-align:center;padding:24px;color:#F2EFE8;font-size:1.1rem;pointer-events:none}
.lightsout[hidden]{display:none}
.lightsout p{max-width:26em;margin:0}
.dialno.sym{font-size:1.3rem;width:2.2rem;color:var(--ink)}
.dsym{display:block;font-size:1.25rem;line-height:1;color:var(--pink-text);margin-top:-4px}

/* ---------- Getting it on your TV (hub) ---------- */
.tvnote{margin:16px 0 0;color:var(--ink-2)}

/* ---------- Legal pages ---------- */
.doc{max-width:680px;margin:0 auto;padding:6px 20px 64px}
.doc h1{font-family:var(--display);font-weight:850;font-stretch:85%;font-size:clamp(2.4rem,9vw,3.4rem);line-height:.95;margin:12px 0 6px}
.doc h2{font-family:var(--display);font-weight:800;font-size:1.3rem;margin:32px 0 8px}
.doc p,.doc li{max-width:62ch}
.doc ul{padding-left:1.2em}
.doc ul.credits{list-style:none;padding:0}
.doc ul.credits li{margin:0 0 18px;line-height:1.5}
.creditsuse{color:var(--ink-2)}
.doc li{margin:4px 0}

/* ---------- Preview (all screens on one device) ---------- */
.tabs{display:flex;gap:4px;padding:8px 10px 0;border-bottom:2px solid var(--ink);overflow-x:auto;background:var(--paper)}
.tab{display:inline-flex;align-items:center;gap:6px;border:none;background:none;padding:10px 12px;border-bottom:4px solid transparent;margin-bottom:-2px;font-weight:700;color:var(--ink-2);white-space:nowrap}
.tab[aria-selected="true"]{color:var(--ink);border-bottom-color:var(--pink)}
.panel{display:none}
.panel.on{display:block}
.panelhead{display:none}
@media (min-width:1180px){
  .tabs{display:none}
  .soloGrid{display:grid;grid-template-columns:1.5fr repeat(var(--panels,3),minmax(0,1fr));align-items:start}
  .panel{display:block;border-right:2px solid var(--ink);min-height:calc(100vh - 60px)}
  .panel:last-child{border-right:none}
  .panelhead{display:flex;align-items:center;gap:8px;font-family:var(--display);font-weight:800;font-size:1.1rem;padding:14px 18px 0}
}

@media (prefers-reduced-motion: no-preference){
  .digit.bump{animation:bump .18s ease-out}
  @keyframes bump{from{transform:translateY(-5px)}to{transform:none}}
}
@media (prefers-reduced-motion: reduce){
  .btn,.role{transition:none}
  .net.reconnecting{animation:none}
}

/* ---------- TV mode: the shared screen, sized to be read from across the room ----------
   Only while a device is the shared screen (html.tvmode). Everything in rem grows with the screen:
   about 23px text at 1920px wide, more on bigger screens. */
html.tvmode{font-size:clamp(16px,1.2vw,40px)}
.tvmode body{font-size:1.05rem}
.tvmode .tv{max-width:none;padding:1.2rem 2.5vw 2rem}
.tvmode .bar{padding:.5rem 1.2rem}
.tvmode .tvhead h2{font-size:clamp(2.2rem,3.4vw,5.5rem)}
.tvmode .clock{font-size:clamp(3.5rem,5.5vw,9rem)}
.tvmode .diffchip{font-size:.85rem;padding:.25em .8em}
.tvmode .eyebrow{font-size:.8rem}
.tvmode .pip{width:1.1rem;height:1.1rem}
.tvmode .avatar.tiny{width:1.9rem;height:1.9rem}
.tvmode .crewlist li{font-size:1rem;padding:.35em .9em}
.tvmode .crewnote,.tvmode .hostedby,.tvmode .hostnote{font-size:1rem}
.tvmode .qr{width:9rem;height:9rem}
.tvmode .joincard .jt{font-size:1.6rem}
.tvmode .overlay h3{font-size:clamp(3rem,6vw,8rem)}
.tvmode .overlay p{font-size:1.4rem}
.tvmode .lightsout{font-size:1.4rem}

/* Wide screens: the case (or train) on the left at the largest size that fits, everything else beside it */
@media (min-width:1000px){
  .tvmode #play:not([hidden]){display:grid;grid-template-columns:minmax(0,1fr) clamp(18rem,27vw,36rem);grid-template-areas:"head head" "main side";column-gap:2.5vw;row-gap:1rem;align-items:start}
  .tvmode .tvhead{grid-area:head;margin:0}
  .tvmode #play .case,.tvmode #play .nightcar{grid-area:main}
  .tvmode #play .case{width:min(100%,calc((100vh - 16rem) * var(--ratio,1)));justify-self:center}
  .tvmode .tvside{grid-area:side;display:flex;flex-direction:column;gap:1.2rem}
  .tvmode .tvside .joincard{flex-direction:column;text-align:center;margin:0}
  .tvmode .tvctl{margin-top:0}
  .tvmode .lockstate{margin-left:0;flex-basis:100%}
  .tvmode #tvdiff{margin-top:0}
}

/* The Glass Vault's labels */
.tvmode .glabel{font-size:clamp(.9rem,1.4vw,1.6rem)}

/* Night Train: one row of compartments, big passengers */
.tvmode .train{grid-template-columns:repeat(var(--comps,5),minmax(0,1fr));gap:.8vw}
.tvmode .compartment{min-height:clamp(9rem,30vh,24rem);padding:2.4rem .4rem .5rem;border-radius:1rem}
.tvmode .cnum{font-size:1.2rem;top:.4rem;left:.7rem}
.tvmode .fig{width:clamp(3rem,4.6vw,7.5rem);height:auto;aspect-ratio:40/48}
.tvmode .fig.big{width:clamp(6rem,9vw,12rem)}
.tvmode .route{font-size:1.05rem;margin-top:1.4rem}
.tvmode .route .stop{width:1rem;height:1rem}
.tvmode .carnote{font-size:1.1rem}

/* Lobby: a big QR code and seats you can read from the sofa */
.tvmode .lobbyhead h2{font-size:clamp(2.5rem,4vw,6.5rem)}
.tvmode .lobbymeta{font-size:1rem}
.tvmode .lobbygrid{grid-template-columns:auto minmax(0,1fr);gap:2.5vw}
.tvmode .lobbyjoin{max-width:none;padding:1.4rem;flex-direction:column;text-align:center}
.tvmode .qr.big{width:min(36vh,24vw);height:min(36vh,24vw)}
.tvmode .lobbyjoin .bigcode{font-size:clamp(2.5rem,4vw,6rem)}
.tvmode .seats{gap:1rem}
.tvmode .seat{min-height:5.2rem;padding:.9rem 1.2rem}
.tvmode .seat b{font-size:1.7rem}
.tvmode .seaticon,.tvmode .avatar.seatav{width:3.6rem;height:3.6rem}
.tvmode .seaticon svg{width:1.8rem;height:1.8rem}
.tvmode .seatrole{font-size:.85rem}
.tvmode .lobbystatus{font-size:1.5rem}
/* Wide screens: QR code on the left; seats, status and controls stacked on the right, all on one screen */
@media (min-width:1000px){
  .tvmode .lobby:not([hidden]){display:grid;grid-template-columns:auto minmax(0,1fr);grid-template-areas:"head head" "join crew" "join foot";column-gap:3vw;row-gap:1.2rem;align-items:start}
  .tvmode .lobbyhead{grid-area:head;margin:0}
  .tvmode .lobbygrid{display:contents}
  .tvmode .lobbyjoin{grid-area:join}
  .tvmode .lobbycrew{grid-area:crew}
  .tvmode .lobbyfoot{grid-area:foot;margin-top:0}
}
/* Fine-tuning for a 1080p TV */
@media (min-width:1000px){
  .tvmode #play .case{width:min(100%,calc((100vh - 17rem) * var(--ratio,1)))}
}
.tvmode .fig{width:clamp(3rem,5.8vw,9rem)}
.tvmode .figs{flex-direction:column;align-items:center;justify-content:flex-end;gap:.6rem}
.tvmode .seat{min-height:4.3rem;padding:.55rem 1.1rem}
.tvmode .seaticon,.tvmode .avatar.seatav{width:3rem;height:3rem}
.tvmode .seat b{font-size:1.55rem}
.tvmode .seats{gap:.8rem}
.tvmode .qr.big{width:min(32vh,24vw);height:min(32vh,24vw)}
@media (max-height:800px){
  .tvmode .seat{min-height:3.6rem;padding:.4rem 1rem}
  .tvmode .seats{gap:.6rem}
  .tvmode .lobbyhead h2{font-size:clamp(2.2rem,3.4vw,5rem)}
}

/* ---------- Night Train: the train itself ---------- */
/* A night sky: a few stars over the dark blue */
.nightcar{background-image:
  radial-gradient(1.6px 1.6px at 12% 8%,#F2EFE8 50%,transparent 51%),radial-gradient(1.2px 1.2px at 34% 5%,#F2EFE8 50%,transparent 51%),
  radial-gradient(1.8px 1.8px at 58% 10%,#FFD23F 50%,transparent 51%),radial-gradient(1.2px 1.2px at 77% 4%,#F2EFE8 50%,transparent 51%),
  radial-gradient(1.5px 1.5px at 92% 12%,#F2EFE8 50%,transparent 51%),radial-gradient(rgba(255,255,255,.05) 1.1px,transparent 1.5px);
  background-size:auto,auto,auto,auto,auto,7px 7px;padding-top:clamp(18px,3vw,34px)}
/* Wheels are sized from the train's width (so the engine's and carriage's match) and hang below it onto the rail. */
.nightcar{container-type:inline-size}
.trainrow{--wd:clamp(18px,4.2cqi,96px);display:flex;align-items:flex-end;padding-bottom:calc(var(--wd) * .55)}
.loco{flex:none;width:18%;align-self:flex-end;margin-bottom:calc(var(--wd) * -.55)}
.loco svg{display:block;width:100%;height:auto;overflow:visible}
.coupler{flex:none;width:clamp(6px,1.2%,18px);height:10px;background:#2A2A38;border:2px solid #17161C;align-self:flex-end;margin-bottom:34px}
/* The carriage: a blue body with a rounded roof and a pink stripe; compartments are its lit windows */
.carriage{flex:1;min-width:0;position:relative;background:#2F5BFF;border:3px solid #17161C;border-radius:26px 26px 10px 10px;
  padding:16px 12px 30px;margin-top:14px;box-shadow:inset 0 -12px 0 #2443B8}
.carriage::before{content:"";position:absolute;left:5%;right:5%;top:-14px;height:14px;background:#2443B8;border:3px solid #17161C;border-bottom:none;border-radius:12px 12px 0 0}
.carriage::after{content:"";position:absolute;left:0;right:0;bottom:18px;height:7px;background:#FF4F9A;border-top:2px solid #17161C;border-bottom:2px solid #17161C}
.carriage .train{position:relative;z-index:1}
.carriage .compartment{border-radius:14px 14px 6px 6px;box-shadow:inset 0 0 0 5px #FFF3CC,inset 0 -8px 0 rgba(0,0,0,.08)}
.wheels{position:absolute;left:6%;right:6%;bottom:calc(var(--wd) * -.55 - 3px);display:flex;justify-content:space-between;z-index:2}
.wheels span{width:var(--wd);box-sizing:border-box;aspect-ratio:1;border-radius:50%;background:#2A2A38;border:3px solid #17161C;box-shadow:inset 0 0 0 clamp(6px,.8vw,13px) #2A2A38,inset 0 0 0 clamp(9px,1.1vw,18px) #8E8A98}
/* The track: a rail over wooden sleepers */
.rails{height:22px;margin-top:-2px;position:relative;
  background:linear-gradient(#8E8A98,#8E8A98) top/100% 5px no-repeat,repeating-linear-gradient(90deg,#6B4E3D 0 16px,transparent 16px 44px) 0 7px/100% 12px no-repeat}
@media (max-width:640px){.loco,.coupler{display:none}}
.tvmode .carriage{padding:1rem .8rem 2rem;border-radius:1.4rem 1.4rem .6rem .6rem}
.tvmode .rails{margin-top:-2px}
/* Every compartment stays in one row, like a real carriage; passengers shrink to fit narrow screens */
.carriage .train{grid-template-columns:repeat(var(--comps,5),minmax(0,1fr));gap:clamp(4px,.8vw,14px)}
.carriage .compartment{min-width:0;padding-left:3px;padding-right:3px}
.carriage .fig{width:min(44px,100%);height:auto;aspect-ratio:40/48}
.tvmode .carriage .fig{width:clamp(3rem,5.8vw,9rem)}
/* Windows are just tall enough for two passengers (the most that ever share one), so the carriage keeps
   a train's proportions instead of stretching to fill a tall screen. */
.tvmode .carriage .compartment{min-height:calc(clamp(3rem,5.8vw,9rem) * 2.4 + 4rem)}
@media (min-width:1000px) and (max-height:800px){
  .tvmode .carriage .fig{width:clamp(2.6rem,4.4vw,6rem)}
}

/* While a round is running, the side column steps aside and the case or train uses the full width */
.tvside[hidden]{display:none}
.headpause{align-self:center}
.headpause[hidden]{display:none}
@media (min-width:1000px){
  .tvmode #play.inround{grid-template-columns:minmax(0,1fr);grid-template-areas:"head" "main"}
}

/* ---------- Paused: clues are hidden, so pausing can't be used to study the case ----------
   The case or train on the shared screen, and every clue card on the phones, blur behind a "Paused" label.
   The Host card (with Resume), the header and the clock stay readable. */
html.paused :is(.case,.nightcar,.ddcity,.ticket,.lock,.accuse,.ddpad){position:relative;user-select:none}
html.paused :is(.case,.nightcar,.ddcity,.ticket,.lock,.accuse,.ddpad)>*{filter:blur(14px);pointer-events:none;transition:filter .25s ease}
html.paused :is(.case,.nightcar,.ddcity,.ticket,.lock,.accuse,.ddpad)::after{content:"Paused";position:absolute;inset:0;z-index:6;display:grid;place-items:center;
  font-family:var(--display);font-weight:900;font-stretch:90%;font-size:clamp(2rem,6vw,4.5rem);letter-spacing:-.01em;border-radius:inherit;pointer-events:none}
html.paused :is(.case,.nightcar,.ddcity)::after{color:#FFD23F;background:rgba(20,19,30,.35);font-size:clamp(3rem,9vw,9rem)}
html.paused :is(.ticket,.lock,.accuse)::after{color:var(--ink);background:color-mix(in srgb,var(--card) 35%,transparent)}
html.paused .ticket .stamp{filter:blur(14px)}

/* ---------- Before the round starts: clue cards stay blank until the host starts it ---------- */
html.notstarted :is(.ticket,.lock,.accuse,.ddpad){position:relative;min-height:9rem}
html.notstarted :is(.ticket,.lock,.accuse,.ddpad)>*{visibility:hidden}
html.notstarted :is(.ticket,.lock,.accuse,.ddpad)::after{content:"Your clue appears when the host starts the game.";position:absolute;inset:0;display:grid;place-items:center;
  padding:1.2rem;text-align:center;font-family:var(--display);font-weight:800;font-size:1.25rem;line-height:1.2;color:var(--ink-2);pointer-events:none}
html.notstarted .lock::after{content:"The lock unlocks when the host starts the game."}
html.notstarted .accuse::after{content:"The accusation board opens when the host starts the game."}
html.notstarted .ddpad::after{content:"The controls unlock when the host starts the mission."}

/* ======================================================================
   Motion: a little life everywhere. All of it is skipped for people who've
   asked their device for reduced motion.
   ====================================================================== */
.confetti{position:fixed;inset:0;pointer-events:none;z-index:100;overflow:hidden}
.confetti i{position:absolute;top:-24px;display:block;animation:confettiFall var(--t,2.4s) cubic-bezier(.3,.6,.6,1) var(--d,0s) forwards}
@keyframes confettiFall{to{transform:translate(var(--dx,0),112vh) rotate(var(--r,360deg))}}
/* Night Train wheels get spokes, so you can see them turn */
.wheels span{background:radial-gradient(circle,#8E8A98 0 16%,transparent 17%),linear-gradient(90deg,transparent 43%,#8E8A98 43% 57%,transparent 57%),linear-gradient(transparent 43%,#8E8A98 43% 57%,transparent 57%),#2A2A38;box-shadow:inset 0 0 0 clamp(3px,.35vw,6px) #8E8A98}

@media (prefers-reduced-motion: no-preference){
  @keyframes rise{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
  @keyframes pageIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
  @keyframes boing{0%{transform:scale(.55)}60%{transform:scale(1.08)}100%{transform:scale(1)}}
  @keyframes misprint{from{transform:translate(0,0)}to{transform:translate(.055em,.04em)}}
  @keyframes sweep{from{background-size:0% 100%}to{background-size:100% 100%}}
  @keyframes floaty{0%,100%{transform:translateY(0) rotate(0)}50%{transform:translateY(-7px) rotate(-1deg)}}
  @keyframes wobble{0%,55%,100%{transform:rotate(0)}62%{transform:rotate(-10deg)}70%{transform:rotate(8deg)}78%{transform:rotate(-4deg)}86%{transform:rotate(0)}}
  @keyframes seatPop{0%{transform:scale(.85)}55%{transform:scale(1.04);background:var(--yellow)}100%{transform:scale(1)}}
  @keyframes goPulse{0%,100%{box-shadow:3px 3px 0 var(--blue),0 0 0 0 rgba(255,79,154,.55)}50%{box-shadow:3px 3px 0 var(--blue),0 0 0 12px rgba(255,79,154,0)}}
  @keyframes gemIn{from{opacity:0;transform:scale(.3) rotate(-25deg)}}
  @keyframes rollIn{from{transform:translateX(70%);opacity:0}}
  @keyframes rock{from{transform:translateY(0)}to{transform:translateY(1.5px)}}
  @keyframes spin{to{transform:rotate(360deg)}}
  @keyframes puff{0%{transform:translate(0,4px) scale(.4);opacity:0}15%{opacity:.9}35%{transform:translate(3px,-20px) scale(.9)}65%{transform:translate(28px,-38px) scale(1.3);opacity:.7}100%{transform:translate(80px,-50px) scale(1.8);opacity:0}}   /* up, then trailing back over the carriage as the train pulls left */
  @keyframes pulseDot{0%,100%{box-shadow:0 0 0 0 rgba(255,210,63,.7)}50%{box-shadow:0 0 0 7px rgba(255,210,63,0)}}
  @keyframes heartbeat{0%,40%,100%{transform:scale(1)}15%{transform:scale(1.07)}28%{transform:scale(1.02)}}
  @keyframes popIn{from{opacity:0;transform:scale(.6)}}
  @keyframes dealIn{from{opacity:0;transform:translateY(26px) rotateX(40deg)}}
  @keyframes shake{0%,100%{transform:translateX(0)}20%{transform:translateX(-9px)}40%{transform:translateX(8px)}60%{transform:translateX(-5px)}80%{transform:translateX(3px)}}
  @keyframes slideDown{from{transform:translateY(-100%);opacity:0}}
  @keyframes fadeIn{from{opacity:0}}

  /* Every page eases in */
  #app>*{animation:pageIn .4s ease backwards}

  /* Home page */
  .logo .riso::after{animation:misprint .9s .25s cubic-bezier(.2,1.7,.4,1) backwards}
  .hero h1{animation:rise .6s ease backwards}
  .hero h1 .hl{background-repeat:no-repeat;animation:sweep .7s .55s ease backwards}
  .hero .lede{animation:rise .6s .15s ease backwards}
  .gamegrid>*{animation:rise .6s ease backwards}
  .gamegrid>:nth-child(2){animation-delay:.1s}
  .gamegrid>:nth-child(3){animation-delay:.2s}
  .cover>svg{animation:floaty 6s ease-in-out infinite}
  .gamegrid>:nth-child(2) .cover>svg{animation-delay:-3s}
  .soon .qmark{transform-origin:50% 90%;animation:wobble 4s ease-in-out infinite}

  /* Join page and the avatar picker */
  .roles>.role{animation:rise .45s ease backwards}
  .roles>.role:nth-child(2){animation-delay:.06s}
  .roles>.role:nth-child(3){animation-delay:.12s}
  .roles>.role:nth-child(4){animation-delay:.18s}
  .preview .avatar.huge{animation:boing .5s cubic-bezier(.2,1.8,.4,1)}
  .an:has(input:checked) .anart{animation:boing .35s cubic-bezier(.2,1.8,.4,1)}
  .rolebanner{animation:slideDown .4s ease backwards}

  /* Lobby: seats pop as players arrive; Start pulses once everyone's in */
  .lobby:not([hidden]){animation:pageIn .5s ease backwards}
  .seat.pop{animation:seatPop .7s cubic-bezier(.2,1.6,.4,1)}
  .lobbybtns .btn.go{animation:goPulse 1.4s ease-in-out infinite}

  /* The round starts: gems pop into the case, the train rolls in */
  .case .slot{animation:gemIn .5s cubic-bezier(.2,1.5,.4,1) backwards;animation-delay:calc(var(--i,0) * 26ms)}
  #play:not([hidden]) .trainrow{animation:rollIn 1.4s cubic-bezier(.15,.8,.25,1) backwards}
  .steam circle{transform-box:fill-box;transform-origin:center;animation:puff 2.4s linear infinite}
  .steam circle:nth-child(2){animation-delay:-.8s}
  .steam circle:nth-child(3){animation-delay:-1.6s}
  html.running .wheels span{animation:spin .9s linear infinite}
  html.running .loco .lw{transform-box:fill-box;transform-origin:center;animation:spin 1.1s linear infinite}
  html.running .carriage{animation:rock .45s ease-in-out infinite alternate}
  .route li.here .stop{animation:pulseDot 1.8s ease-in-out infinite}
  .clock.low,.miniclock.low{animation:heartbeat 1s ease-in-out infinite}
  .overlay:not([hidden])>div{animation:popIn .6s cubic-bezier(.2,1.5,.4,1) backwards}

  /* Phones: clue cards are dealt when the round starts; wrong answers shake */
  html:where(:not(.notstarted)) :where(.ticket,.lock,.accuse){animation:dealIn .6s cubic-bezier(.2,1.2,.4,1) backwards;transform-origin:50% 0}
  html:where(:not(.notstarted)) :where(.accuse){animation-delay:.12s}
  .shake{animation:shake .45s ease}
  html.paused :is(.case,.nightcar,.ddcity,.ticket,.lock,.accuse,.ddpad)::after{animation:fadeIn .3s ease backwards}
}

/* The 3-2-1 before the clock starts or resumes, over every screen (SC.drawCountdown) */
.countdown{position:fixed;inset:0;z-index:90;display:grid;place-items:center;align-content:center;gap:.4rem;
  background:rgba(18,17,24,.6);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);color:var(--yellow);text-align:center}
.countdown .cdnum{display:block;font-family:var(--display);font-weight:900;font-stretch:90%;line-height:.85;
  font-size:clamp(8rem,34vmin,24rem);text-shadow:.05em .04em 0 var(--pink)}
.countdown.go .cdnum{color:#F2EFE8;text-shadow:.05em .04em 0 var(--blue);font-size:clamp(6rem,26vmin,18rem)}
.countdown .cdnote{font-family:var(--mono,monospace);font-size:clamp(.9rem,2.4vmin,1.6rem);letter-spacing:.3em;text-transform:uppercase;color:#F2EFE8}
@media (prefers-reduced-motion: no-preference){
  @keyframes cdPop{0%{transform:scale(1.9);opacity:0}18%{transform:scale(1);opacity:1}72%{transform:scale(.97);opacity:1}100%{transform:scale(.75);opacity:0}}
  @keyframes cdGo{0%{transform:scale(.4) rotate(-8deg);opacity:0}35%{transform:scale(1.1) rotate(2deg);opacity:1}100%{transform:scale(1.25);opacity:0}}
  @keyframes cdFade{0%,60%{opacity:1}100%{opacity:0}}
  .countdown .cdnum{animation:cdPop 1s cubic-bezier(.2,1.4,.4,1) forwards}
  .countdown.go{animation:cdFade .7s ease forwards}
  .countdown.go .cdnum{animation:cdGo .7s cubic-bezier(.2,1.4,.4,1) forwards}
}

/* ======================================================================
   The Glass Vault's display case: a museum vitrine. A brass frame, plum velvet under a spotlight,
   each gem on its own cushion, glass with a reflection and a slow shine, and a plaque below.
   ====================================================================== */
.case{background:#FFD23F;background-image:radial-gradient(rgba(23,22,28,.16) 1px,transparent 1.4px);background-size:6px 6px;
  padding:clamp(8px,1.4vw,18px) clamp(8px,1.4vw,18px) clamp(6px,.9vw,12px);border-radius:18px}
.vitrine{position:relative;overflow:hidden;border:3px solid var(--ink);border-radius:10px;padding:clamp(10px,2.4vw,26px);
  background:radial-gradient(ellipse 70% 55% at 50% -8%,rgba(255,236,190,.22),transparent 70%),
    radial-gradient(rgba(255,255,255,.035) 1px,transparent 1.5px) 0 0/5px 5px,#2E1C3F;
  box-shadow:inset 0 0 0 3px rgba(255,255,255,.08),inset 0 10px 24px rgba(0,0,0,.45)}
/* The glass: an edge highlight and a fixed diagonal reflection, over the gems but never blocking taps */
.vitrine::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:2;border-radius:7px;
  background:linear-gradient(118deg,transparent 0 22%,rgba(255,255,255,.07) 22% 30%,transparent 30% 34%,rgba(255,255,255,.04) 34% 37%,transparent 37%)}
.sheen{position:absolute;top:-10%;bottom:-10%;left:0;width:22%;pointer-events:none;z-index:2;transform:translateX(-160%) skewX(-18deg);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.13),transparent)}
/* Each gem sits on a velvet cushion */
.vitrine .slot{position:relative;background:radial-gradient(circle at 50% 38%,rgba(255,255,255,.12),rgba(0,0,0,.22) 72%);
  box-shadow:inset 0 3px 7px rgba(0,0,0,.55),0 1px 0 rgba(255,255,255,.07)}
.vitrine .glabel{color:rgba(255,236,190,.75)}
/* A four-point twinkle that catches the light now and then (by position only: it says nothing about a gem) */
.vitrine .slot::after{content:"";position:absolute;top:10%;right:12%;width:26%;aspect-ratio:1;opacity:0;pointer-events:none;
  background:#fff;clip-path:polygon(50% 0,60% 40%,100% 50%,60% 60%,50% 100%,40% 60%,0 50%,40% 40%)}
/* The plaque */
.plinth{display:flex;justify-content:center;padding-top:clamp(6px,.9vw,12px)}
.plaque{position:relative;font-family:var(--mono);font-weight:700;font-size:clamp(.62rem,1vw,.95rem);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink);background:linear-gradient(#E9B83A,#CF9A1C);border:2px solid var(--ink);border-radius:6px;padding:.35em 2.2em;box-shadow:2px 2px 0 var(--ink)}
.plaque::before,.plaque::after{content:"";position:absolute;top:50%;width:.45em;height:.45em;margin-top:-.225em;border-radius:50%;background:var(--ink)}
.plaque::before{left:.8em}.plaque::after{right:.8em}
.case .overlay,.case .lightsout{border-radius:15px}
/* Hard: the flashlight warms the velvet under the rows it lights */
.case.flash .vitrine .slot.lit{box-shadow:inset 0 3px 7px rgba(0,0,0,.4),0 0 22px 4px rgba(255,214,140,.22)}
@media (prefers-reduced-motion: no-preference){
  @keyframes sheen{0%,55%{transform:translateX(-160%) skewX(-18deg)}100%{transform:translateX(560%) skewX(-18deg)}}
  @keyframes twinkle{0%,86%,100%{opacity:0;transform:scale(.2) rotate(0)}91%{opacity:1;transform:scale(1) rotate(45deg)}96%{opacity:.6;transform:scale(.6) rotate(90deg)}}
  .sheen{animation:sheen 7s ease-in-out infinite 1.5s}
  .vitrine .slot::after{animation:twinkle 5.5s ease-in-out infinite;animation-delay:calc(var(--i,0) * -3.4s)}   /* a golden-ratio step, so twinkles spread out evenly */
}

/* The Glass Vault mid-round on a wide TV: the title steps to the left of the case and the clock to the right,
   so the case can use the screen's full height (it's about square, and TVs are wide). Squarer screens keep
   the header above. vault.js sizes the case to fill what's left (SIDE_LAYOUT there matches this query). */
@media (min-width:1000px) and (min-aspect-ratio:3/2){
  .tvmode #play.vaultplay.inround{grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);grid-template-areas:"title main clock";align-items:start;column-gap:3vw}
  .tvmode #play.vaultplay.inround .tvhead{display:contents}
  .tvmode #play.vaultplay.inround .tvhead>div:first-child{grid-area:title;padding-top:.4rem}
  .tvmode #play.vaultplay.inround .eyebrow span{display:block}
  .tvmode #play.vaultplay.inround .eyebrow .dotsep{display:none}
  .tvmode #play.vaultplay.inround .tvhead h2{font-size:clamp(1.8rem,2.6vw,4.4rem);margin-top:.5rem}
  .tvmode #play.vaultplay.inround .tvclock{grid-area:clock;justify-self:end;flex-direction:column;align-items:flex-end;gap:.8rem}
  .tvmode #play.vaultplay.inround .tvclock .clock{order:-1}
  .tvmode #play.vaultplay.inround .case{width:min(calc((100vh - 9rem) * var(--ratio,1)),calc(100vw - 30rem))}
}

/* ---------- The logo mark, and the light/dark toggle ----------
   Two versions of the mark: ink question mark for light, cream sticker for dark. */
.logo{display:inline-flex;align-items:center;gap:.28em}
.logo .mark{width:1.3em;height:1.3em;flex:none;display:block}
.logo .mark-dark{display:none}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .logo .mark-light{display:none}
  :root:not([data-theme="light"]) .logo .mark-dark{display:block}
}
:root[data-theme="dark"] .logo .mark-light{display:none}
:root[data-theme="dark"] .logo .mark-dark{display:block}
.siteright{display:flex;align-items:center;gap:14px}
.themetoggle{display:grid;place-items:center;width:38px;height:38px;padding:0;border-radius:50%;border:2px solid var(--ink-2);background:transparent;color:var(--ink);cursor:pointer;opacity:.7;transition:opacity .15s,transform .15s}
.themetoggle:hover,.themetoggle:focus-visible{opacity:1}
.themetoggle .i{width:20px;height:20px}
@media (prefers-reduced-motion: no-preference){.themetoggle:active{transform:rotate(-25deg) scale(.92)}}

/* ======================================================================
   Home page. One spacing scale (--gap-*) and four text sizes: the headline, section labels,
   body, and small mono labels.
   ====================================================================== */
.hub{--gap-s:16px;--gap-m:28px;--gap-l:64px;padding-bottom:var(--gap-l)}
.hero{display:grid;gap:var(--gap-m);align-items:center;padding-top:8px}
@media (min-width:880px){.hero{grid-template-columns:1.15fr 1fr;gap:40px}.hero h1{font-size:clamp(3rem,5.2vw,4.5rem)}}
.hero h1{font-size:clamp(2.7rem,8.6vw,4.5rem);margin:0 0 var(--gap-s)}
.hero .lede{font-size:1.15rem;max-width:32em}
.heroactions{display:flex;flex-direction:column;align-items:flex-start;gap:var(--gap-s);margin-top:var(--gap-m)}
.heroactions .btn{font-size:1.05rem;padding:14px 22px}
.howto{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:6px 18px;font-size:.92rem;color:var(--ink-2)}
.howto li{display:flex;align-items:center;gap:6px}
.howto .hnum{font-family:var(--display);font-weight:900;font-size:1.5rem;line-height:1}   /* misprinted numerals, like the game pages' steps */
.heroart{display:grid;place-items:center}
.heroscene{width:100%;max-width:520px;height:auto;overflow:visible}
.heroink{stroke:var(--ink)}
.themed-dark{display:none}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .themed-light{display:none}:root:not([data-theme="light"]) .themed-dark{display:inline}}
:root[data-theme="dark"] .themed-light{display:none}:root[data-theme="dark"] .themed-dark{display:inline}

/* The code bar: players who already have a code skip everything else */
.codebar{display:grid;gap:12px 24px;align-items:center;padding:18px 22px;margin-top:var(--gap-l);box-shadow:6px 6px 0 var(--blue)}
@media (min-width:760px){.codebar{grid-template-columns:1fr minmax(320px,420px)}.codebar .err{grid-column:2}}
.codebar h2{font-family:var(--display);font-weight:800;font-size:1.35rem;margin:0}
.codebar p{margin:0;color:var(--ink-2)}
.codebar .codefield{margin:0;min-width:0}
.codebar .codefield input{min-width:0;width:100%}   /* the big spaced letters would otherwise refuse to shrink on phones */
.codebar>*{min-width:0}
.codebar .err:empty{display:none}
/* Phones: most visitors are players with a code, so "Got a code?" comes right after the intro, before the
   Host button, and the TV picture is left out. (The hero's boxes step aside so their parts can be reordered.) */
@media (max-width:879px){
  .hub{display:flex;flex-direction:column}
  .hero,.herotext{display:contents}
  .hero h1{order:1;margin-top:8px}
  .hero .lede{order:2}
  .codebar{order:3;margin-top:var(--gap-m)}
  .heroactions{order:4}
  .heroart{display:none}   /* the TV picture is for wide screens; on a phone it pushes the games down */
  .hub>:not(.hero):not(.codebar){order:6}
}

/* Games */
.hub .sect{margin:var(--gap-l) 0 var(--gap-m)}
/* The "coming next" card: the original dashed card, full width under the games */
.soon{border:2px dashed var(--ink-2);border-radius:var(--radius);padding:24px;display:flex;flex-direction:column;justify-content:flex-end;gap:10px;min-height:220px;--dot:color-mix(in srgb,var(--ink) 10%,transparent)}
.soon .qmark{font-family:var(--display);font-weight:900;font-stretch:120%;font-size:5.5rem;line-height:.8;margin-bottom:8px;align-self:flex-start}
.soon h3{font-family:var(--display);font-weight:800;font-stretch:90%;font-size:1.5rem;line-height:1.05;margin:0}
@media (min-width:760px){.gamegrid{grid-template-columns:1fr 1fr}.gamegrid .soon{grid-column:1/-1;min-height:0}
  /* an odd number of games: it fills the gap beside the last one, as tall as that card, so it centers
     its content instead of leaving an empty top */
  .gamegrid .gamecard:nth-child(odd)+.soon{grid-column:auto;min-height:220px;justify-content:center;align-items:center;text-align:center}
  .gamegrid .gamecard:nth-child(odd)+.soon .qmark{align-self:center;font-size:8rem;margin-bottom:18px}
  .gamegrid .gamecard:nth-child(odd)+.soon h3{font-size:1.75rem;max-width:17ch;text-wrap:balance}}
.cover-vault{background:#2E1C3F radial-gradient(rgba(255,255,255,.06) 1.2px,transparent 1.6px) 0 0/9px 9px}
.cover-train{background:#1B2140;background-image:radial-gradient(1.6px 1.6px at 12% 18%,#F2EFE8 50%,transparent 51%),radial-gradient(1.4px 1.4px at 34% 9%,#FFD23F 50%,transparent 51%),radial-gradient(1.2px 1.2px at 58% 16%,#F2EFE8 50%,transparent 51%),radial-gradient(1.6px 1.6px at 82% 8%,#F2EFE8 50%,transparent 51%),radial-gradient(1.2px 1.2px at 92% 26%,#FFD23F 50%,transparent 51%),radial-gradient(rgba(255,255,255,.05) 1.1px,transparent 1.5px);background-size:auto,auto,auto,auto,auto,8px 8px}
.cover .badge{background:#FFD23F;color:#17161C}
.cover > svg{width:86%;max-width:440px}
.facts{flex-wrap:nowrap;gap:6px}
.facts li{font-size:.66rem;letter-spacing:.04em;padding:3px 8px;white-space:nowrap}
.gbody h3{font-size:1.9rem}

/* How to get it on a TV: folded away until someone needs it */
.tvhelp{margin-top:var(--gap-l);border-top:2px dashed var(--line);border-bottom:2px dashed var(--line)}   /* printed rules, not a box */
.tvhelp summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px 4px;color:var(--ink-2)}
.tvhelp summary::-webkit-details-marker{display:none}
.tvhelp summary b{color:var(--ink);margin-right:6px}
.tvhelp summary::after{content:"+";font-family:var(--mono);font-weight:700;font-size:1.3rem;color:var(--ink);line-height:1}
.tvhelp[open] summary::after{content:"−"}
.tvopts{display:grid;gap:18px;padding:4px 4px 22px}
@media (min-width:760px){.tvopts{grid-template-columns:repeat(3,1fr);gap:16px}}
.tvopt{padding:0 0 0 14px;border-left:3px solid var(--pink)}
.tvopt b{display:block;font-family:var(--display);font-weight:800;font-size:1.05rem;margin-bottom:4px}
.tvopt span{color:var(--ink-2);font-size:.95rem}

/* Footer: the logo, what SplitClue is, contacts, and the small print */
.foot{align-items:center}
.footbrand{display:flex;flex-direction:column;gap:4px}
.footbrand .logo{font-size:1.5rem}
.footbrand span{font-size:.9rem}
.footdata{margin:6px 0 0;max-width:34em;font-size:.82rem;line-height:1.45}
@media (prefers-reduced-motion: no-preference){
  .heroart{animation:rise .7s .12s ease backwards}
  .codebar{animation:rise .6s .22s ease backwards}
}

/* ======================================================================
   Dead Drop. The city: roads every third tile, 2×2 buildings between them. On the TV the buildings are
   colored rooftops; on the Handler's intel map they're labeled, with the cameras' views in red.
   ====================================================================== */
.ddcity{position:relative;background:#1B2140;border:3px solid var(--ink);border-radius:22px;padding:clamp(8px,1.6vw,18px);box-shadow:6px 6px 0 var(--pink)}
.ddsvg{display:block;width:100%;height:auto}
.ddground{fill:#2B2A3D}
.ddlane{stroke:#57536E;stroke-width:2;stroke-dasharray:8 10}
.ddbldg{stroke:#17161C;stroke-width:3}
.ddroof{fill:#17161C;opacity:.2}
.ddvent{fill:#17161C;opacity:.35}
.ddbldg-intel{fill:#F2EFE8;stroke:#17161C;stroke-width:3}
.ddlabel{font-family:var(--mono);font-size:10px;font-weight:700;letter-spacing:.04em;text-anchor:middle;fill:#17161C}
.ddconeview{fill:url(#ddcamfade);transition:opacity .3s}
.ddconeview.turning{opacity:.3}
.ddcam{fill:#17161C;stroke:#F2EFE8;stroke-width:2}
.ddlens{fill:#F0503A}
.ddlaser{stroke:#F0503A;stroke-width:5;stroke-linecap:round}
.ddlaser.off{opacity:.25;stroke-dasharray:3 6;stroke-width:3}
.ddbeam{fill:url(#ddbeamfade)}
.ddshoulders{fill:#2F3F9E;stroke:#17161C;stroke-width:3}
.ddcap{fill:#1E2A6B;stroke:#17161C;stroke-width:2.5}
.ddvisor{fill:#17161C}
.ddbadge{fill:#FFD23F;stroke:#17161C;stroke-width:1}
.ddagentring{fill:none;stroke:#FF4F9A;stroke-width:3;opacity:.6}
.ddagentbody{fill:#FF4F9A;stroke:#17161C;stroke-width:3}
.ddpkg{fill:#FFD23F;stroke:#17161C;stroke-width:2.5}
.ddalarm{display:flex;align-items:center;gap:10px;margin-top:10px;color:#F2EFE8}
.ddalarm .eyebrow{color:#C9C4D1}
.ddcity::before{content:"";position:absolute;inset:0;border-radius:19px;background:#F0503A;opacity:0;pointer-events:none;z-index:3}   /* the red flash when the Agent is spotted */
.ddcity .overlay{background:rgba(27,33,64,.95);border-radius:19px}
.tvmode .ddcity .ddsvg{max-height:calc(100vh - 19rem);width:auto;max-width:100%;margin:0 auto}
@media (min-width:1000px){.tvmode #play.inround .ddcity .ddsvg{max-height:calc(100vh - 16.5rem)}}

/* The Agent's controls: big keys for thumbs, search in the middle */
.ddpad{padding:16px;margin-top:20px}   /* clear of the brief above it and its shadow */
.ddkeys{display:grid;grid-template-columns:repeat(3,1fr);grid-template-areas:". up ." "left search right" ". down .";gap:10px;max-width:320px;margin:0 auto}
.ddkey{grid-area:auto;min-height:64px;border:3px solid var(--ink);border-radius:16px;background:var(--card);color:var(--ink);font-size:1.5rem;cursor:pointer;touch-action:none;user-select:none;-webkit-user-select:none;box-shadow:3px 3px 0 var(--blue)}
.ddkey:active:not(:disabled){transform:translate(2px,2px);box-shadow:1px 1px 0 var(--blue)}
.ddkey:disabled{opacity:.4;cursor:default}
.ddkey.up{grid-area:up}.ddkey.left{grid-area:left}.ddkey.right{grid-area:right}.ddkey.down{grid-area:down}
.ddsearch{grid-area:search;min-height:64px;padding:6px;font-size:.9rem;line-height:1.1}
.ddpadfoot{display:flex;align-items:center;justify-content:center;gap:10px;margin-top:14px}
.ddtarget{display:none;margin:0 0 12px;font-size:.95rem;line-height:1.3;color:var(--ink-2)}
.ddtarget b{color:var(--ink)}

/* The Handler's intel map and its key */
.ddmap{margin:6px 0 10px;border-radius:10px;overflow:hidden}
.ddlegend{list-style:none;padding:0;margin:8px 0;display:flex;flex-wrap:wrap;gap:6px 14px;font-size:.85rem}
.ddlegend li{display:flex;align-items:center;gap:6px}
.ddlegend span{display:inline-block;width:14px;height:14px;border-radius:3px;border:2px solid var(--ink)}
.ddkey-cam{background:#F0503A}.ddkey-laser{background:repeating-linear-gradient(90deg,#F0503A 0 4px,transparent 4px 7px)}
.ddkey-sight{background:#FFD23F}.ddkey-agent{background:#FF4F9A;border-radius:50%!important}
.cover-drop{background:#1B2140 radial-gradient(rgba(255,255,255,.05) 1.1px,transparent 1.5px) 0 0/8px 8px}

@media (prefers-reduced-motion: no-preference){
  .ddguard{transition:transform .35s linear}
  .ddguardturn,.ddcamturn{transition:transform .5s ease-in-out}   /* a steady turn at corners; still finishes within one tick (550ms on Hard) */
  .ddagent{transition:transform .11s ease-out}
  .ddagent.safe{animation:ddblink .4s steps(2) infinite}
  @keyframes ddblink{50%{opacity:.25}}
  @keyframes ddflash{0%{opacity:.5}100%{opacity:0}}
  .ddcity.flash::before{animation:ddflash .9s ease-out}
}
/* Dead Drop intel card: the map as wide as the phone allows, and a compact key */
.ticket.intel{padding-left:10px;padding-right:10px}
.ticket.intel .perf{margin-left:-10px;margin-right:-10px}   /* the tear line meets the edges of this narrower-padded ticket */
.ticket .ddlegend li{padding:0;border:0;margin:0;font-size:.85rem}
.ticket .ddlegend{gap:6px 14px;margin:8px 4px}
.ddlabel{font-size:9px}

/* Night Train's hub cover: the train holds still while the sleepers slide past (it pulls left, so
   the world moves right), the wheels turn, the carriage rocks, the stars twinkle. Replaces the gentle float. */
@media (prefers-reduced-motion: no-preference){
  .cover-train>svg{animation:none!important}
  .ntc-ties{animation:ntcties .6s linear infinite}
  @keyframes ntcties{to{transform:translateX(16px)}}
  .cover-train .lw{transform-box:fill-box;transform-origin:center;animation:spin 1.1s linear infinite reverse}
  .ntc-car{animation:rock .45s ease-in-out infinite alternate}
  .ntc-star{animation:ntctwinkle 3.2s ease-in-out infinite}
  @keyframes ntctwinkle{0%,100%{opacity:1}50%{opacity:.3}}
}
/* Dead Drop's hub cover comes alive: the camera sweeps, the guard's flashlight scans, the package glows
   beside the Agent. (It replaces the gentle float the other covers use.) */
@media (prefers-reduced-motion: no-preference){
  .cover-drop>svg{animation:none!important}
  .ddc-cam{animation:ddcsweep 5s ease-in-out infinite}
  @keyframes ddcsweep{0%,30%{transform:rotate(0deg)}50%,80%{transform:rotate(90deg)}100%{transform:rotate(0deg)}}
  .ddc-guard{animation:ddcscan 3.4s ease-in-out infinite;transform:rotate(90deg)}
  @keyframes ddcscan{0%,100%{transform:rotate(65deg)}50%{transform:rotate(115deg)}}
  .ddc-glow{transform-box:fill-box;transform-origin:center;animation:ddcglow 1.8s ease-in-out infinite}
  @keyframes ddcglow{0%,100%{opacity:.5;transform:scale(.85)}50%{opacity:1;transform:scale(1.1)}}
}
@media (prefers-reduced-motion: reduce){.ddc-guard{transform:rotate(90deg)}}

/* ---------- Remote play: no TV, so each player's screen shows the board beside their own panel ----------
   Wide screens: board left, panel right (it stays in view while the board scrolls). Narrow: board first. */
.rplay{display:grid;gap:22px;align-items:start;max-width:1320px;margin:0 auto;padding:18px 18px 34px}
.rplay .tv,.rplay .phone{max-width:none;padding:0}
.rplay .rpanel .phone+.phone{margin-top:14px}
@media (min-width:900px){
  .rplay{grid-template-columns:minmax(0,1fr) minmax(300px,390px);padding:22px 24px 40px}
  .rplay .rpanel{position:sticky;top:12px}
}
/* The board's own buttons, host note and QR card are for a TV; each panel has the controls. Before the start,
   the lobby on the board has them instead, so the panel's copy steps aside. */
.rplay .rboard :is(.tvctl .btn,.hostnote,#tvdiff,.headpause,.joincard){display:none!important}
html.notstarted .rplay .rpanel .ctlwrap{display:none}
/* A role whose panel already shows everything (Dead Drop's Handler) sees the board only in the lobby. */
html:not(.notstarted) .rplay.board-lobby{grid-template-columns:minmax(0,760px);justify-content:center}
html:not(.notstarted) .rplay.board-lobby .rboard{display:none}
html.remote.notstarted :is(.ticket,.lock,.accuse,.ddpad)::after{content:"Your clue appears when the game starts."}
html.remote.notstarted .lock::after{content:"The lock unlocks when the game starts."}
html.remote.notstarted .accuse::after{content:"The accusation board opens when the game starts."}
html.remote.notstarted .ddpad::after{content:"The controls unlock when the mission starts."}

/* The invite card (lobby and join page): a link to send, since there's nothing to scan */
.invite{padding:16px 16px 12px;box-shadow:6px 6px 0 var(--pink)}
.invite .jt{display:flex;align-items:center;gap:8px;font-family:var(--display);font-weight:850;font-size:1.5rem;line-height:1;margin:0 0 8px}
.invite .jt .i{width:1.1em;height:1.1em}
.invite p{margin:0 0 10px;color:var(--ink-2)}
.invite p b{color:var(--ink);font-family:var(--mono)}
.invitelink{display:flex;gap:8px;margin:0 0 10px}
.invitelink input{flex:1;min-width:0;font:inherit;font-family:var(--mono);font-size:.82rem;padding:9px 10px;border:2px solid var(--ink);border-radius:10px;background:var(--paper);color:var(--ink)}
.invitelink .btn{flex:none}
.linkbtn{background:none;border:0;padding:0;font:inherit;color:var(--ink);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
@media (min-width:720px){.lobbygrid>.invite{max-width:360px}}
.joinpage #invitebox .invite{margin:6px 0 18px}
.tvmode .lobbygrid>.invite{grid-area:join}
/* On a phone the board sits above the panel, so keep it compact and put what each player acts on first:
   the bar at the top already shows the room and the clock, so the board drops its own. While the clock runs,
   the Pause card moves to the end, and the Safecracker's lock and the Agent's move pad sit right under the board. */
@media (max-width:899px){
  .rplay{padding-top:12px;gap:16px}
  .rplay .rboard .tvhead{margin-bottom:10px}
  .rplay .rboard :is(.tvhead .eyebrow,.tvclock){display:none}
  .rplay .rboard .tvhead h2{font-size:1.7rem;margin:0}
  .rplay .rpanel,.rplay .rpanel .phone,.rplay .rpanel .safebody{display:flex;flex-direction:column}
  html.running .rplay .rpanel :is(.ctlwrap,.ctlphone){order:9}
  html.running .rplay .rpanel .ctlwrap{margin-top:4px}
  .rplay .rpanel :is(.lock,.ddpad){order:-1;margin:0 0 14px}
  .rplay .ddtarget{display:block}   /* the Agent's target, on the pad (the brief is further down) */
  .rplay .ddpad{padding:12px 14px}
  .rplay .ddpad .ddpadfoot{display:none}   /* the map above shows the alarm */
  /* Short screens (a phone browser with its bars showing): the case shrinks a little so the panel starts sooner */
  .rplay .rboard .case{width:min(100%,calc(42svh * var(--ratio,1)));margin-inline:auto}
  /* and the Safecracker's lock tightens up (the buttons stay a comfortable 40px to tap) */
  .rplay .lock{padding:12px}
  .rplay .dial{gap:6px}
  .rplay .dial button{height:40px}
  .rplay .digit{font-size:2.2rem}
  .rplay .try{margin-top:12px;padding:.75em}
}
.rplay .hostbadge{display:none}   /* remote: every player can run the game, so nobody is "the host" */

/* ---------- A game's own page (/games/<slug>, built by scripts/build-games.js) ---------- */
/* Hub game cards: the name's link stretches over the whole card, so clicking anywhere opens the game's page.
   The buttons sit above it. Hovering (or tabbing to the name) lifts the card and turns its shadow pink. */
.gamecard{position:relative;transition:transform .18s ease,box-shadow .18s ease}
.gamelink{color:inherit;text-decoration:none}
.gamelink::after{content:"";position:absolute;inset:0;z-index:1}
.gamecard .gactions{position:relative;z-index:2}
.gamelink:focus-visible{outline:none}
.gamecard:has(.gamelink):hover,.gamecard:has(.gamelink:focus-visible){transform:translate(-3px,-3px);box-shadow:9px 9px 0 var(--pink)}
.gamecard:has(.gamelink:focus-visible){outline:3px solid var(--blue);outline-offset:3px}
.gamecard:hover .gamelink,.gamelink:focus-visible{text-decoration:underline;text-decoration-thickness:3px;text-underline-offset:5px}
@media (prefers-reduced-motion: reduce){.gamecard:has(.gamelink):hover,.gamecard:has(.gamelink:focus-visible){transform:none}}
.gpage{max-width:1120px;margin:0 auto;padding:4px 20px 64px}
.gpback{margin:0 0 18px}
.gpback a{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:.78rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);text-decoration:none}
.gpback a:hover{color:var(--ink)}
.gpback .i{width:16px;height:16px;transform:scaleX(-1)}
.gphero{display:grid;gap:28px;align-items:center}
@media (min-width:880px){.gphero{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:48px}}
.gpart{overflow:hidden;box-shadow:8px 8px 0 var(--shadow)}
.gpart .cover{border-bottom:0}
.gpintro h1{font-family:var(--display);font-weight:850;font-stretch:85%;font-size:clamp(2.8rem,7vw,4.6rem);line-height:.92;margin:0 0 16px}
.gpintro .facts{margin:0 0 18px;flex-wrap:wrap}
.gpintro .lede{font-size:1.15rem;line-height:1.5;color:var(--ink-2);margin:0 0 24px;max-width:46ch}
.gpfree{margin:16px 0 0;font-size:.9rem;color:var(--ink-2)}
.gpage .ric{width:46px;height:46px;border-radius:50%;display:grid;place-items:center;background:var(--yellow);color:#17161C;border:2px solid var(--ink);flex:none}
.gpage .ric svg{width:24px;height:24px}
/* Printed, not boxed (STYLE.md): steps on a halftone band with misprinted numerals, roles as tickets,
   levels as a printed list with dashed rules. */
.gptitle .riso{margin-right:.02em}
.gpfree{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.gpstamp,.cbstamp{display:inline-block;transform:rotate(-5deg);background:var(--pink);color:#17161C;border:2px solid var(--ink);border-radius:6px;padding:2px 10px;font-family:var(--mono);font-size:.78rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;box-shadow:2px 2px 0 var(--ink)}
.gpsteps{list-style:none;margin:0;padding:22px 24px;border-radius:var(--radius);display:grid;gap:18px;--dot:color-mix(in srgb,var(--pink) 42%,transparent);background-size:6px 6px}
@media (min-width:760px){.gpsteps{grid-template-columns:repeat(3,minmax(0,1fr));gap:28px;padding:26px 30px}}
.gpsteps li{display:flex;align-items:center;gap:14px;font-size:1.08rem;font-weight:700;line-height:1.3}
.gpnum{flex:none;font-family:var(--display);font-weight:900;font-size:3.4rem;line-height:.8;min-width:.7em}
.gproles{list-style:none;padding:0;margin:0;display:grid;gap:22px;grid-template-columns:repeat(2,minmax(0,1fr))}
@media (min-width:760px){.gproles{grid-template-columns:repeat(var(--n,3),minmax(0,1fr))}}
.gprole{margin:0}
.gprolehead{display:flex;align-items:center;gap:12px}
.gprolehead b{font-family:var(--display);font-weight:850;font-stretch:90%;font-size:1.45rem;line-height:1}
.gpage .gprole .ric{width:38px;height:38px}
.gpage .gprole .ric svg{width:20px;height:20px}
.gprole .perf{margin:14px -20px}
.gprole p{margin:0;color:var(--ink-2);line-height:1.4}
/* Phones: two tickets a row, name under the icon */
@media (max-width:759px){.gproles{gap:16px}.gprole{padding:14px 14px 14px}.gprole .perf{margin:12px -14px}.gprolehead{flex-direction:column;align-items:flex-start;gap:8px}.gprolehead b{font-size:1.15rem;font-stretch:75%}}
.gplevels{list-style:none;padding:0;margin:0;border-top:2px dashed var(--line)}
.gplevels li{display:grid;grid-template-columns:6.5rem minmax(0,1fr) auto;align-items:center;gap:14px;padding:14px 4px;border-bottom:2px dashed var(--line)}
.gplevels .diffchip{justify-self:start}
.gplevels p{margin:0;font-size:1.05rem}
.gplevels .gptime{font-family:var(--mono);font-weight:700;font-size:.85rem;color:var(--ink-2)}
@media (max-width:520px){.gplevels li{grid-template-columns:auto 1fr;gap:8px 12px}.gplevels p{grid-column:1/-1;grid-row:2}.gplevels .gptime{justify-self:end}}
.gpmore{display:grid;gap:24px}
@media (min-width:720px){.gpmore{grid-template-columns:repeat(2,minmax(0,1fr))}}
.gpother{display:flex;flex-direction:column;overflow:hidden;box-shadow:6px 6px 0 var(--shadow);color:inherit;text-decoration:none;transition:transform .15s ease,box-shadow .15s ease}
.gpother:hover,.gpother:focus-visible{transform:translate(-3px,-3px);box-shadow:9px 9px 0 var(--pink)}
.gpotherbody{padding:14px 18px 18px;display:flex;flex-direction:column;gap:10px}
.gpotherbody b{font-family:var(--display);font-weight:850;font-stretch:90%;font-size:1.7rem;line-height:1}
#games{scroll-margin-top:20px}   /* "All games" on a game's page lands just above the section */

/* ---------- Homepage, in print (STYLE.md) ---------- */
/* "whole clue." is misprinted over the yellow marker; in dark mode (no marker) it prints in yellow with the pink offset. */
.hero h1 .hl .riso{margin-right:.02em}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .hero h1 .hl .riso{color:var(--yellow)}}
:root[data-theme="dark"] .hero h1 .hl .riso{color:var(--yellow)}
/* The TV picture sits on a big pink halftone disc, like a printed backdrop. */
.heroart{position:relative}
.heroart::before{content:"";position:absolute;width:78%;aspect-ratio:1;border-radius:50%;left:50%;top:50%;transform:translate(-46%,-52%);
  background-image:radial-gradient(color-mix(in srgb,var(--pink) 55%,transparent) 1.6px,transparent 2px);background-size:9px 9px;z-index:0}
.heroart>*{position:relative;z-index:1}
/* Got a code? is a ticket: a stamp on its corner and a tear line before the code. */
.codebar{position:relative}
.cbstamp{position:absolute;top:-13px;left:18px;z-index:1}
.codebar .codefield{padding-top:14px;border-top:2px dashed var(--line)}
@media (min-width:760px){.codebar{padding-top:22px}.codebar .codefield{padding:0 0 0 24px;border-top:0;border-left:2px dashed var(--line)}}

/* ---------- The Discord Activity (discord.html, discord.js) ----------
   Discord's phone apps say how much of the screen their own controls cover. There's no TV, so the join page's
   shared-screen options are hidden. The picker is printed like the rest of the site (STYLE.md). */
html.discord body{padding:var(--discord-safe-area-inset-top,0px) var(--discord-safe-area-inset-right,0px) var(--discord-safe-area-inset-bottom,0px) var(--discord-safe-area-inset-left,0px)}
html.discord .others .eyebrow,html.discord .others .row:has([data-go]){display:none}
.dhub{max-width:1120px;margin:0 auto;padding:18px 20px 48px}
.dhead{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:22px}
.dlogo{font-family:var(--display);font-weight:900;font-size:1.7rem;line-height:1}
.dtitle{font-family:var(--display);font-weight:850;font-stretch:80%;font-size:clamp(2.4rem,7vw,4.2rem);line-height:.92;margin:0 0 14px}
.dtitle .riso{margin-right:.06em}
.dhub .lede{color:var(--ink-2);font-size:1.1rem;margin:0 0 26px;max-width:36em}
.dnow{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px 20px;margin:6px 0 30px}
.dnow p{margin:0;font-size:1.1rem}
.doutside .dlogo{display:block;margin-bottom:22px}
