/* ==========================================================================
   OXP arcade  (/oxp)

   Lives in static/src/ rather than inline in the template for three reasons:
   the template response is served no-store so anything inline is re-downloaded
   on every hit; Jinja's {# delimiter silently eats a compact media query like
   @media(max-width:480px){#hud{...}}; and Tailwind's content glob only scans
   static/templates/site/**.*.html, so a utility class named here would never be
   generated. Nothing in this file is Tailwind. Do not add any.

   Typography is the system stack on purpose. The design called for Outfit from
   Google Fonts, which is a render-blocking stylesheet on a new origin that then
   references a second new origin: roughly six extra round trips before first
   paint, paid by every player, on congested conference wifi, off a cold cache.
   ========================================================================== */

:root{
  --bg:#DBE4F0; --card:#FFFFFF; --ink:#1B2440; --slate:#64758B; --line:#C8D3E2;
  --wine:#831743; --winehi:#A81D57; --box:#1B2440; --wall:#7D90B0;
  --logo-c:#831743; --logo-d:#64758B;
  --fo:clamp(12px,3.2vw,36px); --ft:clamp(6px,1.3vw,13px);
  box-sizing:border-box;
  padding-top:env(safe-area-inset-top,0px);
  padding-bottom:env(safe-area-inset-bottom,0px);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg:#111829; --card:#1B2440; --ink:#EEF2F8; --slate:#A3B2CC; --line:#2F3B5C;
    --wine:#D2457E; --winehi:#E0558D; --box:#0A0F1E; --wall:#6F83A8;
    --logo-c:#D2457E; --logo-d:#A3B2CC;
  }
}
:root[data-theme="dark"]{
  --bg:#111829; --card:#1B2440; --ink:#EEF2F8; --slate:#A3B2CC; --line:#2F3B5C;
  --wine:#D2457E; --winehi:#E0558D; --box:#0A0F1E; --wall:#6F83A8;
  --logo-c:#D2457E; --logo-d:#A3B2CC;
}
*,*::before,*::after{box-sizing:inherit}
html{height:100%;scroll-padding-top:env(safe-area-inset-top,0px);overscroll-behavior:none}
body{margin:0;height:100%;background:var(--bg);color:var(--ink);
  font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  touch-action:manipulation;-webkit-tap-highlight-color:transparent;overscroll-behavior:none;-webkit-text-size-adjust:100%}
button{font:inherit;color:inherit;cursor:pointer}
:focus-visible{outline:3px solid var(--wine);outline-offset:3px}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.num{font-variant-numeric:tabular-nums}

#app{height:100%;display:flex;flex-direction:column}
header{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:10px max(16px,env(safe-area-inset-right,0px)) 10px max(16px,env(safe-area-inset-left,0px))}
.logo{display:block;height:clamp(26px,6vw,36px);user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;cursor:default}
.logo svg{height:100%;width:auto;display:block}
.logo .lc{stroke:var(--logo-c)} .logo .ld{stroke:var(--logo-d)}
.hbtns{display:flex;gap:8px;align-items:center}
.btn{border:0;border-radius:3px;white-space:nowrap;padding:12px 22px;min-height:48px;font-weight:600;font-size:1.05rem;background:var(--wine);color:#fff}
.btn.ghost{background:transparent;color:var(--ink);box-shadow:inset 0 0 0 2px var(--line)}
.btn.small{padding:8px 14px;min-height:40px;font-size:.95rem}
.btn:disabled{opacity:.5;cursor:default}
.btn:active{transform:translateY(1px)}
.who{font-size:.9rem;color:var(--slate);font-weight:600;white-space:nowrap}

/* Live strip. Muted while the contest is not running so it reads as a state,
   not an alarm; wine and pulsing while scores actually count. */
.livebar{display:flex;align-items:center;gap:10px;flex:none;
  padding:7px max(16px,env(safe-area-inset-right,0px)) 7px max(16px,env(safe-area-inset-left,0px));
  background:var(--line);color:var(--slate);font-size:.82rem;line-height:1.25}
.livebar .tag{flex:none;font-weight:700;letter-spacing:.14em;font-size:.72rem;
  padding:3px 8px;border-radius:3px;background:var(--slate);color:var(--card)}
.livebar .msg{min-width:0}
.livebar.on{background:var(--wine);color:#fff}
.livebar.on .tag{background:#fff;color:var(--wine)}
@media (prefers-reduced-motion:no-preference){
  .livebar.on .tag{animation:pulse 2.4s ease-in-out infinite}
}
@media (max-width:360px){
  .livebar{font-size:.76rem;gap:7px;padding-left:8px;padding-right:8px}
}

main{flex:1;min-height:0;position:relative}
.view{position:absolute;inset:0;display:none;flex-direction:column;
  padding:0 max(16px,env(safe-area-inset-right,0px)) 14px max(16px,env(safe-area-inset-left,0px))}
.view.active{display:flex}

/* Brand frame: burgundy outline offset down-right behind the card */
.framed{position:relative;isolation:isolate}
.framed::before{content:"";position:absolute;z-index:-1;pointer-events:none;
  top:8%;left:7%;right:calc(var(--fo) * -1);bottom:calc(var(--fo) * -1);
  border:var(--ft) solid var(--wine)}

/* Menu */
#view-menu{overflow-y:auto;-webkit-overflow-scrolling:touch;padding-top:6px;padding-bottom:calc(20px + var(--fo))}
.menu{margin:auto;width:min(1120px,100% - var(--fo))}
.menu .cardbody{background:var(--card);padding:clamp(20px,5vw,56px)}
.menu h1{color:var(--wine);font-weight:600;font-size:clamp(2.6rem,9.5vw,5.6rem);line-height:.95;letter-spacing:-.035em;margin:0 0 .22em}
.menu .sub{color:var(--slate);font-size:clamp(1.05rem,2.4vw,1.35rem);line-height:1.4;margin:0 0 1.5em;max-width:34ch}
.games{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:16px}
.game{border:0;border-radius:0;background:var(--bg);text-align:left;padding:0;display:flex;flex-direction:column}
.game:active{transform:translateY(1px)}
.game .art{aspect-ratio:16/10;display:grid;place-items:center;background:var(--box)}
.game .art.pale{background:#E9EFF6}
.game .art svg{width:80%;height:80%}
.game .txt{padding:12px 14px 16px}
.game h2{font-weight:600;font-size:1.2rem;margin:0 0 3px;letter-spacing:-.01em;line-height:1.15}
.game p{margin:0;color:var(--slate);line-height:1.35;font-size:.93rem}
.game .mybest{display:block;margin-top:6px;font-size:.82rem;font-weight:600;color:var(--wine);font-variant-numeric:tabular-nums}
@media (max-width:560px){
  .games{grid-template-columns:1fr 1fr;gap:10px}
  .game .txt{padding:9px 10px 12px}
  .game h2{font-size:1rem}
  .game p{font-size:.82rem}
}

/* Game views */
.hud{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:4px 16px;padding:0 0 12px}
.hud h1{color:var(--wine);font-weight:600;font-size:clamp(1.15rem,2.8vw,1.7rem);margin:0;letter-spacing:-.015em}
.stats{display:flex;gap:16px;color:var(--slate);font-variant-numeric:tabular-nums;font-size:.95rem}
.stats b{color:var(--ink);font-weight:600;font-size:1.25rem;margin-left:5px}
.body{flex:1;min-height:0;display:flex;flex-direction:column}
.stage{flex:1;min-height:0;position:relative;display:grid;place-items:center;padding:0 var(--fo) var(--fo) 0}
.stage.touchlock{touch-action:none}
.stage .framed{line-height:normal}
.stage canvas{display:block;background:var(--card);touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.dombox{background:var(--card);width:100%;height:100%;display:flex;flex-direction:column;gap:12px;padding:clamp(12px,2.6vw,24px);overflow:hidden;user-select:none;-webkit-user-select:none}
.overlay{position:absolute;inset:0;display:grid;place-items:center;padding:16px;cursor:pointer;z-index:3;
  background:color-mix(in srgb,var(--bg) 55%,transparent);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}
.overlay[hidden]{display:none}
.overlay .inner{background:var(--card);padding:clamp(22px,4.5vw,36px);max-width:28rem;width:100%;box-shadow:0 24px 60px -28px rgba(27,36,64,.55)}
.overlay h2{color:var(--wine);font-weight:600;font-size:clamp(1.8rem,5.5vw,2.4rem);line-height:1.02;letter-spacing:-.025em;margin:0 0 .45em}
.overlay p{margin:0 0 1.1em;color:var(--slate);line-height:1.45;font-size:1.05rem}
.overlay p strong{color:var(--ink);font-weight:600}
.dpad{display:none;grid-template-columns:repeat(3,72px);grid-template-rows:repeat(2,60px);gap:8px;justify-content:center;padding-top:6px;flex:none}
.dpad button{border:0;border-radius:3px;background:var(--card);color:var(--wine);font-size:1.6rem;font-weight:600;touch-action:none;box-shadow:inset 0 0 0 2px var(--line)}
.dpad button:active{background:var(--wine);color:#fff;box-shadow:none}
.dpad [data-dir="1"]{grid-column:2;grid-row:1}
.dpad [data-dir="8"]{grid-column:1;grid-row:2}
.dpad [data-dir="4"]{grid-column:2;grid-row:2}
.dpad [data-dir="2"]{grid-column:3;grid-row:2}
@media (pointer:coarse){.dpad{display:grid}}
.below{display:flex;justify-content:center;padding-top:4px;flex:none}
.below .btn{min-width:240px}
@media (max-width:560px){
  #fsBtn{display:none}
  .overlay .btn,.below .btn{width:100%}
  .hud{padding-bottom:8px}
  .stats{gap:12px}
  /* The header carries the logo plus up to two nav buttons. At 390px the
     full-size pair overflowed the viewport once "All games" appeared next to
     "Leaderboard", so shrink them rather than dropping one: both are the only
     way out of a game on a phone. */
  header{gap:6px;padding-left:12px;padding-right:12px}
  .hbtns{gap:6px}
  .btn.small{padding:8px 11px;min-height:38px;font-size:.86rem}
  .who{font-size:.8rem}
}
/* 320px is an old iPhone SE and a vanishing share of any crowd, but a header
   that overflows is visibly broken rather than merely cramped, and both nav
   buttons have to stay: they are the only way out of a game on a phone. */
@media (max-width:360px){
  .who{display:none}
  .logo{height:22px}
  .btn.small{padding:8px 7px;font-size:.8rem}
  header{gap:4px;padding-left:8px;padding-right:8px}
  .hbtns{gap:4px}
}
@media (pointer:coarse) and (orientation:landscape) and (max-height:540px){
  header{padding-top:4px;padding-bottom:4px}
  .hud{padding-bottom:4px}
  .hud h1{font-size:1rem}
  #view-maze .body{flex-direction:row;align-items:center;gap:12px}
  .dpad{padding-top:0}
  .below{padding-top:0}
}
@keyframes shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-6px)}75%{transform:translateX(6px)}}

/* Pipeline Builder */
.pl-hint{color:var(--slate);margin:0;font-size:1rem}
.pl-slots{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:8px}
.pl-slots li{min-height:46px;border:2px dashed var(--line);display:flex;align-items:center;gap:8px;padding:6px 10px;font-weight:600;color:var(--slate);font-size:.98rem}
.pl-slots li .n{font-variant-numeric:tabular-nums;font-size:.8rem;opacity:.8}
.pl-slots li.filled{border:2px solid var(--wine);background:var(--wine);color:#fff}
.pl-slots li.next{border-color:var(--slate)}
.pl-chips{margin-top:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:10px}
.chip{min-height:58px;border:0;border-radius:3px;background:var(--box);color:#fff;font-weight:600;font-size:1.05rem;padding:6px 10px}
.chip.used{visibility:hidden}
.chip.wrong{animation:shake .32s;background:var(--winehi)}
.pl-banner{margin:auto;text-align:center;color:var(--wine);font-weight:600;font-size:clamp(1.6rem,5vw,2.4rem)}

/* SSH Whack-a-Mole */
.whack{flex:1;min-height:0;display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);gap:clamp(8px,2vw,14px)}
.hole{position:relative;overflow:hidden;background:var(--box);border-radius:3px}
.hole .host{position:absolute;top:7px;left:9px;font-size:clamp(.62rem,1.8vw,.78rem);color:#8FA0BD}
.mole{position:absolute;left:9%;right:9%;bottom:0;height:64%;border:0;border-radius:3px 3px 0 0;background:var(--wine);color:#fff;
  transform:translateY(106%);transition:transform .13s ease-out;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:4px;touch-action:manipulation}
.mole .t{font-weight:600;font-size:clamp(.82rem,2.7vw,1.1rem);line-height:1.1;text-align:center}
.mole .c{font-size:clamp(.6rem,1.7vw,.75rem);opacity:.85}
.mole.up{transform:translateY(0)}
.mole.trap{background:#FFFFFF;color:#831743;box-shadow:inset 0 0 0 3px #831743}
.mole.hit{background:var(--slate);color:#fff;box-shadow:none}
.mole.oops{background:#1B2440;color:#fff;box-shadow:inset 0 0 0 3px #E0558D}

/* Key Match */
.mgrid{flex:1;min-height:0;display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(4,1fr);gap:clamp(6px,1.6vw,12px)}
.mcard{position:relative;border:0;padding:0;background:transparent;perspective:700px}
.mcard .in{position:absolute;inset:0;transition:transform .32s;transform-style:preserve-3d}
.mcard.up .in{transform:rotateY(180deg)}
.face{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;border-radius:3px;padding:4px}
.face svg{width:42%;height:auto;max-height:50%}
.back{background:var(--box)}
.front{background:var(--bg);transform:rotateY(180deg);font-weight:600;font-size:clamp(.7rem,2.3vw,.95rem);line-height:1.1;text-align:center;color:var(--ink)}
.mcard.done .front{background:var(--wine);color:#fff}
.mcard.done .front svg *{fill:#fff}

/* Terminal Speed Type */
.term{background:var(--box);color:#DDE4EE;padding:clamp(12px,2.5vw,20px);border-radius:3px;display:flex;flex-direction:column;gap:10px;font-size:clamp(1rem,3vw,1.25rem);flex:none}
.term .target{white-space:pre-wrap;word-break:break-all;line-height:1.4}
.term .target .ok{color:#FFFFFF}
.term .target .bad{background:#A81D57;color:#fff}
.term .target .rest{color:#7D90B0}
.term .target .cur{color:#FFFFFF;border-bottom:3px solid #E0558D}
.tinput{font:inherit;font-size:1.15rem;width:100%;padding:12px 14px;border-radius:3px;border:2px solid var(--line);background:var(--bg);color:var(--ink);user-select:text;-webkit-user-select:text}
.tinput:focus{outline:none;border-color:var(--slate)}
.tinput.err{border-color:var(--wine)}
.thist{flex:1;min-height:0;overflow:hidden;display:flex;flex-direction:column;gap:4px;color:var(--slate);font-size:.95rem}
.thist div::before{content:"\2713 ";color:var(--wine)}

/* Fix the Build */
.simon-status{margin:0;text-align:center;font-weight:600;color:var(--slate);font-size:1.1rem;min-height:1.4em}
.simon{flex:1;min-height:0;display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;gap:clamp(8px,2vw,14px)}
.pad{border:0;border-radius:3px;font-weight:600;font-size:clamp(1.1rem,3.6vw,1.7rem);color:#fff;opacity:.5;transition:opacity .1s,transform .1s}
.pad.lit{opacity:1;transform:scale(1.03);box-shadow:inset 0 0 0 4px #fff}
.pad[data-i="0"]{background:#831743}
.pad[data-i="1"]{background:#64758B}
.pad[data-i="2"]{background:#1B2440;box-shadow:inset 0 0 0 2px #3A4A70}
.pad[data-i="2"].lit{box-shadow:inset 0 0 0 4px #fff}
.pad[data-i="3"]{background:#DBE4F0;color:#1B2440}
.pad[data-i="3"].lit{box-shadow:inset 0 0 0 4px #831743}

/* ---------- End screen ---------- */
.end{position:fixed;inset:0;z-index:20;display:none;align-items:center;justify-content:center;
  padding:calc(36px + env(safe-area-inset-top,0px)) calc(16px + var(--fo)) calc(14px + var(--fo) + env(safe-area-inset-bottom,0px)) 16px;
  background:color-mix(in srgb,var(--bg) 90%,transparent);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.end.open{display:flex}
.pwrap{width:100%;max-width:820px;max-height:100%;display:flex;flex-direction:column;min-height:0}
.qmark{position:absolute;z-index:2;top:clamp(-40px,-5vw,-26px);right:clamp(14px,3vw,30px);width:clamp(66px,12vw,112px);color:var(--wine);pointer-events:none}
.panel{background:var(--card);overflow:auto;min-height:0;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  padding:clamp(22px,4.5vw,46px)}
.panel h2{color:var(--wine);font-weight:600;font-size:clamp(2.1rem,7.5vw,3.7rem);line-height:.98;letter-spacing:-.035em;margin:0 0 .3em;padding-right:clamp(60px,11vw,100px)}
.stars{display:flex;gap:6px;margin:0 0 12px}
.stars svg{width:clamp(24px,5vw,32px);height:clamp(24px,5vw,32px)}
.stars[hidden]{display:none}
.stat{color:var(--slate);font-size:1.15rem;line-height:1.4;margin:0 0 1.2em}
.actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:1.3em}
.actions .btn{flex:1;min-width:150px}

/* ---------- Sheet: a second dialog layer above the end panel ----------
   Above .end (z-index 20), because the demo sheet opens FROM the end panel and
   has to cover it. Same paddings as .end on purpose: .framed::before draws
   var(--fo) outside the box, and without the room the burgundy frame clips. No
   .qmark here, it needs .end's 36px top padding or it sits off-screen. */
.sheet{position:fixed;inset:0;z-index:30;display:none;align-items:center;justify-content:center;
  padding:calc(36px + env(safe-area-inset-top,0px)) calc(16px + var(--fo)) calc(14px + var(--fo) + env(safe-area-inset-bottom,0px)) 16px;
  background:color-mix(in srgb,var(--bg) 92%,transparent);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.sheet.open{display:flex}
.sheet .panel h2{padding-right:0}
.sheet .lede{margin:0 0 1.2em;color:var(--slate);line-height:1.5;font-size:1.05rem}
.sheet .lede strong{color:var(--ink);font-weight:600}
.sheet .fine{margin:1.2em 0 0;font-size:.85rem;line-height:1.45;color:var(--slate)}

/* Slot picker: tappable pills, not a native select. A select on a phone is an
   OS wheel, which would be a third modal on top of two dialogs, and this
   sheet's whole promise is one tap. */
.slots{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:0 0 4px}
.slots label{position:relative;display:block}
.slots input{position:absolute;opacity:0;width:1px;height:1px}
.slots span{display:block;padding:12px 10px;border-radius:3px;font-weight:600;font-size:.95rem;
  text-align:center;background:var(--bg);color:var(--ink);box-shadow:inset 0 0 0 2px var(--line)}
.slots input:checked + span{background:var(--wine);color:#fff;box-shadow:none}
.slots input:focus-visible + span{outline:3px solid var(--wine);outline-offset:3px}
@media (max-width:360px){ .slots{grid-template-columns:1fr} }

/* ---------- Saying what this is ---------- */
/* The one-liner under the menu title, and the tie-in shown when a run ends.
   Quiet weight on purpose: it is an explanation, not a pitch, and it sits next
   to a score the player actually cares about. */
.who-by{font-size:.95rem}
.who-by a{color:var(--wine);white-space:nowrap}
.why{margin:0 0 1.2em;padding:12px 14px;border-radius:3px;background:var(--bg);
  color:var(--slate);font-size:.95rem;line-height:1.5;border-left:3px solid var(--wine)}
.why[hidden],.why:empty{display:none}
.rules .abstract{margin:0 0 1.8em;font-size:1.15rem;line-height:1.5;color:var(--ink)}
.rules .abstract strong{color:var(--wine)}
.rules p{margin:0 0 1em;color:var(--slate);font-size:1rem;line-height:1.55}

/* ---------- Prize and demo CTAs ---------- */
.prize{margin:0 0 1.1em;color:var(--wine);font-weight:600;line-height:1.45}
.prize:empty{display:none}
.demo-cta{margin:16px 0 0;font-size:.95rem;color:var(--slate);line-height:1.5}
.demo-cta:empty{display:none}
.demo-cta .btn{margin-top:10px}

/* ---------- Registration sheet (initials + email + consent) ---------- */
.reg{margin:0 0 1.3em;padding:18px;background:var(--bg);border-radius:3px}
.reg h3{margin:0 0 4px;font-size:1.15rem;font-weight:600;color:var(--ink)}
.reg .lede{margin:0 0 14px;color:var(--slate);font-size:.98rem;line-height:1.4}
.reg label{display:block;font-weight:600;margin-bottom:6px;font-size:.95rem}
.reg .row{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end}
.reg .f{flex:1;min-width:150px;margin-bottom:12px}
/* Every text-ish input, not a list of types: a tel field left out of this
   selector keeps the browser's intrinsic 20-character width and renders
   visibly narrower than the ones above it. Radios are excluded because the
   slot picker puts them inside .reg and they would render as full-width
   text boxes. */
.reg input:not([type=checkbox]):not([type=radio]){font:inherit;font-size:1.05rem;width:100%;padding:12px 14px;border-radius:3px;border:2px solid var(--line);background:var(--card);color:var(--ink)}
.reg input:focus{border-color:var(--wine);outline:none}
.reg .tick{display:flex;gap:10px;align-items:flex-start;margin:0 0 12px;font-weight:400;font-size:.92rem;line-height:1.4;color:var(--slate)}
.reg .tick input{width:22px;height:22px;flex:none;margin:1px 0 0;accent-color:var(--wine)}
.reg .tick a{color:var(--wine)}
.reg .err{margin:0 0 12px;padding:10px 12px;border-radius:3px;background:var(--winehi);color:#fff;font-size:.95rem;font-weight:600}
.reg .err[hidden]{display:none}
.reg .fine{margin:12px 0 0;font-size:.82rem;line-height:1.45;color:var(--slate)}
.reg .cf{margin:0 0 12px}

.reg .opt{font-weight:400;color:var(--slate);font-size:.82rem}
.reg .asinit{margin:0 0 12px;font-size:.9rem;color:var(--slate)}
.reg .asinit b{color:var(--wine);letter-spacing:.12em;font-size:1.05rem}

/* ---------- House rules ---------- */
#view-rules{overflow-y:auto;-webkit-overflow-scrolling:touch;padding-top:6px;padding-bottom:calc(20px + var(--fo))}
.rules .lede{margin:0 0 1.6em;color:var(--slate);font-size:1.05rem;line-height:1.45}
.rules h2{font-size:1.05rem;font-weight:600;color:var(--wine);margin:1.8em 0 .5em;
  text-transform:uppercase;letter-spacing:.09em}
.rules h2:first-of-type{margin-top:0}
.rules ol{margin:0;padding-left:1.5em;color:var(--slate);font-size:1rem;line-height:1.55}
.rules li{margin-bottom:.7em}
.rules li strong{color:var(--ink);font-weight:600}
.rules a{color:var(--wine)}
.rules-link{margin:14px 0 0;font-size:.9rem}
.rules-link a{color:var(--slate)}

/* ---------- Leaderboard ---------- */
#view-board{overflow-y:auto;-webkit-overflow-scrolling:touch;padding-top:6px;padding-bottom:calc(20px + var(--fo))}
.board-wrap{margin:auto;width:min(760px,100% - var(--fo))}
.board-wrap .cardbody{background:var(--card);padding:clamp(18px,4vw,40px)}
.board-wrap h1{color:var(--wine);font-weight:600;font-size:clamp(2rem,7vw,3.4rem);line-height:1;letter-spacing:-.03em;margin:0 0 .3em}
.tabs{display:flex;gap:6px;overflow-x:auto;padding:0 0 14px;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tab{border:0;border-radius:3px;background:var(--bg);color:var(--slate);font-weight:600;font-size:.92rem;padding:9px 14px;min-height:40px;white-space:nowrap}
.tab.on{background:var(--wine);color:#fff}
.lb{list-style:none;margin:0;padding:0}
.lb li{display:flex;align-items:center;gap:12px;padding:11px 0;border-bottom:1px solid var(--line);font-size:1.05rem}
.lb li .pos{width:2.2em;font-weight:600;color:var(--slate);font-variant-numeric:tabular-nums}
.lb li .who{flex:1;font-weight:600;color:var(--ink);letter-spacing:.06em}
.lb li .v{font-weight:600;font-variant-numeric:tabular-nums;text-align:right}
/* The tiebreak, shown so the ordering of equal scores has a visible reason. */
.lb li .v .in{display:block;font-weight:400;font-size:.78rem;color:var(--slate)}
.lb li.me .v .in{color:var(--wine);opacity:.75}
.lb li.me{color:var(--wine)}
.lb li.me .who,.lb li.me .pos,.lb li.me .v{color:var(--wine)}
.lb .empty,.lb .down{padding:16px 0;color:var(--slate);font-size:1rem}
.live{display:flex;align-items:center;gap:7px;font-size:.85rem;color:var(--slate);margin:14px 0 0}
.live .dot{width:8px;height:8px;border-radius:50%;background:#3FA66A;flex:none}
.live.stale .dot{background:var(--slate)}
.live.down .dot{background:var(--winehi)}
@media (prefers-reduced-motion:no-preference){
  .live:not(.stale):not(.down) .dot{animation:pulse 2.4s ease-in-out infinite}
}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}

@media (prefers-reduced-motion:reduce){
  .btn:active,.game:active{transform:none}
  .mcard .in,.mole{transition:none}
  .chip.wrong{animation:none}
}
