@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@500;700&display=swap');

/* ──────────────────────────────────────────────────────────────────────────
   NightboX skin. Electric cyan on deep indigo: a lone cube crossing a night
   world, neon ramps against a dark, starless sky. Its own identity, distinct
   from its MazeX sibling, but still family: we map the shared --sx-* tokens
   onto the cyan/indigo palette and keep the core.css chrome + aurora backdrop.
   data-motion="playful" is set on <html> (a game, not an app).
   (Internal var names kept from the shared base so nothing downstream breaks;
   only their VALUES change to NightboX's palette.)
   ────────────────────────────────────────────────────────────────────────── */
:root{
  /* NightboX brand vars */
  --calm:        #22d3ee;   /* electric cyan accent */
  --calm-2:      #7c6cff;   /* electric indigo-violet */
  --dusk:        #0b1026;   /* deep indigo night, never pure black */
  --dusk-2:      #121a3a;
  --dusk-3:      #1b2450;
  --path-glow:   #67e8f9;   /* the neon ramp's luminous edge */

  /* map onto the family contract */
  --sx-bg:        var(--dusk);
  --sx-surface:   var(--dusk-2);
  --sx-surface2:  var(--dusk-3);
  --sx-border:    #283667;
  --sx-border2:   #3a4c92;
  --sx-text:      #e9edff;
  --sx-muted:     #8b93c7;
  --sx-muted2:    #aab1dd;
  --sx-accent:      var(--calm);
  --sx-accent2:     var(--calm-2);
  --sx-accent-ink:  #041018;
  --sx-accent-soft: #0e2740;
  --sx-accent-hover:#4fe3f5;
  /* night aurora: electric cyan + indigo-violet glows */
  --sx-glow-1: var(--calm);
  --sx-glow-2: var(--calm-2);
  --sx-bg-hi: color-mix(in srgb, var(--sx-bg) 86%, #2a3a8a);
  --sx-bg-lo: color-mix(in srgb, var(--sx-bg) 74%, #000);
  --sx-page-max: 100%;   /* full-width chrome: the app fills the screen */
}

/* a larger primary CTA for the gate */
.sx-btn-lg{ padding:14px 26px; font-size:16px; }

/* ── layout: full-screen. The app fills the viewport; the game fills the space
   between the top bar and the footer, as big as its 10:7 shape allows. ────────*/
html, body{ height:100%; }
/* --app-h is the REAL visible height, measured from visualViewport in the page head (iOS
   dvh/svh can't be trusted when the toolbars are shown). Fallbacks: 100dvh, then 100%. */
body{ display:flex; flex-direction:column; overflow:hidden; height:100%; height:100dvh; height:var(--app-h, 100dvh); }
/* full width: auto side-margins (from .sx-wrap) would cancel flex-stretch and
   shrink-wrap the bar, so force it to span. */
.sx-topbar{ flex:0 0 auto; width:100%; margin:0; }
#hud-tries.bad{ color:#ffd0c4; border-color:#5a2f2a; background:#2a1512; }

.stage-wrap{
  flex:1 1 auto; min-height:0; container-type:size;
  display:flex; align-items:center; justify-content:center; padding:10px 16px;
}
.stage{
  position:relative;
  width:min(100%, calc(100cqh * 1000 / 700)); max-height:100%;
  aspect-ratio:1000 / 700;
  border-radius:var(--sx-radius); overflow:hidden; background:#07100f;
  box-shadow:var(--sx-shadow), inset 0 0 0 1px var(--sx-border);
}
.sx-famfoot{ flex:0 0 auto; margin-top:0; }
.sx-famfoot-inner{ padding:14px 22px; }
#game, .scare-canvas{
  position:absolute; inset:0; width:100%; height:100%; display:block;
  touch-action:none;
}
.scare-canvas{ z-index:40; }
/* the video reveal rides the same takeover layer: cover the stage, no chrome */
.scare-video{
  position:absolute; inset:0; width:100%; height:100%; display:block;
  object-fit:cover; background:#000; z-index:41; touch-action:none;
}
.scare-video[hidden]{ display:none; }
/* the hidden attr MUST win over the display:block above, or this transparent
   layer sits on top of the game and swallows every click. */
.scare-canvas[hidden]{ display:none; }
/* never hide the OS cursor: the real mouse stays visible everywhere, always */
#stage, #game, .scare-canvas, .veil{ cursor:default; }

.statusline{
  position:absolute; left:0; right:0; bottom:14px; z-index:5; text-align:center;
  font-weight:700; font-size:15px; letter-spacing:.2px; pointer-events:none;
  color:var(--path-glow); text-shadow:0 2px 12px rgba(0,0,0,.7);
  opacity:0; transition:opacity var(--sx-dur-base) var(--sx-ease);
}
.statusline.show{ opacity:1; }
.statusline.fail{ color:#ff9b86; }

.hint{ text-align:center; margin-top:14px; }

/* ── veils (gate + gotcha) ─────────────────────────────────────────────────*/
.veil{
  position:absolute; inset:0; z-index:30; display:flex; align-items:center; justify-content:center;
  padding:22px; background:radial-gradient(120% 120% at 50% 20%, rgba(8,18,18,.72), rgba(5,12,12,.94));
  backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px);
}
.veil[hidden]{ display:none; }
.veil-card{
  width:min(440px, 100%); padding:30px 28px; text-align:center;
  display:flex; flex-direction:column; align-items:center; gap:14px;
}
.gate-mark{ margin-bottom:2px; }
.dot{
  display:inline-block; width:20px; height:20px; border-radius:6px;
  background:linear-gradient(135deg, var(--sx-accent), var(--sx-accent2));
  box-shadow:0 0 14px color-mix(in srgb, var(--sx-accent) 55%, transparent);
}
.dot.big{ width:42px; height:42px; border-radius:12px; }
/* Joey's logo (brand/logo-mazex-original.jpg, served as logo-mazex.jpg): the green
   maze-M on near-black. mix-blend-mode:screen melts the JPG's dark square into
   whatever dark surface it sits on (the JPG has no alpha channel). */
.brand-logo{
  width:22px; height:22px; border-radius:6px; mix-blend-mode:screen;
  filter:drop-shadow(0 0 10px color-mix(in srgb, var(--sx-accent) 45%, transparent));
}
.gate-logo{
  width:132px; height:132px; border-radius:16px; mix-blend-mode:screen;
  filter:drop-shadow(0 0 22px color-mix(in srgb, var(--sx-accent) 35%, transparent));
}
.veil-card h1{ font-size:30px; font-weight:700; letter-spacing:-.5px; line-height:1; }
.veil-card h1 b{ color:var(--sx-accent); }
.veil-card .lede{ color:var(--sx-muted2); font-size:15px; line-height:1.55; margin:0; }
/* the quiet row under the hero Play button: sound toggle + windowed start */
.gate-sub{ display:flex; gap:10px; align-items:center; justify-content:center; margin-top:-4px; flex-wrap:wrap; }
.fineprint{ color:var(--sx-muted); font-size:12.5px; margin:0; }
.fineprint b{ color:var(--sx-accent); }

/* the Twitch row on the gate: one small centred field + its hint. Optional by design —
   a non-streamer never has to touch it. */
.gate-chat{ display:flex; flex-direction:column; gap:6px; align-items:center; margin-top:2px; }
.gate-chat input{ max-width:240px; text-align:center; font-size:13.5px; padding:8px 12px; }
.gate-chat .fineprint{ max-width:420px; }
/* crowd mode launcher: lives with the channel field (it needs one), accent-edged so it
   reads as a MODE, not another start button */
#crowd-btn{ border-color:var(--sx-accent); color:var(--sx-accent); }
/* the HUD chat chip breathes teal once the socket is live */
#hud-chat.live{ color:var(--calm); border-color:var(--calm); }

/* ── the three faces (v0.28 two, v0.30 adds NightboX) ───────────────────────
   '/' wears html.prank (the innocent send-around gate: hero Play and nothing that
   tips the surprise); '/play' wears html.dash (the games dashboard: mode tiles,
   skins, powers, the stream panel); '/nightbox' wears html.nightbox (the NightboX
   runner game, its own gate + night skin). One page, the head script sets the class.
   .only-game = shown on the game faces (dash + nightbox), hidden on prank. */
html.prank .only-dash, html.prank .only-nightbox, html.prank .only-game{ display:none !important; }
html.dash .only-prank, html.dash .only-nightbox{ display:none !important; }
html.nightbox .only-prank, html.nightbox .only-dash, html.nightbox .gate-title{ display:none !important; }
/* only-nightbox has no base display:none — it is hidden per-face above (like only-prank /
   only-dash), so on html.nightbox it surfaces with its natural display. */
html.dash #gate .veil-card{ width:min(600px, 100%); max-height:94%; overflow-y:auto; }

/* ── NightboX night skin (v0.30): its own identity inside the StrmrX world —
   electric cyan on a deep indigo night, distinct from the prank face's calm mint.
   Same chrome + aurora bones (sx-design), different flavour. */
html.nightbox{
  --calm:        #58d5ff;   /* electric cyan */
  --calm-2:      #8a7bff;   /* indigo */
  --dusk:        #070a14;   /* deeper night base */
  --dusk-2:      #0e1322;
  --dusk-3:      #161d33;
  --sx-border:   #1d2740;
  --sx-border2:  #2c3a5c;
  --sx-glow-1:   #3aa0ff;
  --sx-glow-2:   #8a7bff;
  --sx-bg-hi: color-mix(in srgb, var(--dusk) 86%, #2a3a8a);
  --sx-bg-lo: color-mix(in srgb, var(--dusk) 74%, #000);
}
.nb-mark{ letter-spacing:.5px; }
html.nightbox #gate .veil-card{ width:min(560px, 100%); }

/* the mode tiles: the four solo games in a 2x2, Stream mode full-width under them */
.gate-modes{ display:grid; grid-template-columns:1fr 1fr; gap:10px; width:100%; }
.mode-tile{
  appearance:none; font:inherit; color:var(--sx-text, #e8f4f1); text-align:left; cursor:pointer;
  position:relative; display:flex; flex-direction:column; gap:3px; padding:13px 14px 12px;
  background:rgba(13,26,28,.72); border:1px solid rgba(120,200,190,.16); border-radius:14px;
  transition:transform var(--sx-dur-1, .14s) var(--sx-spring, cubic-bezier(.2,.9,.3,1.1)),
    border-color .14s ease-out, box-shadow .14s ease-out, background .14s ease-out;
}
.mode-tile:hover{
  border-color:var(--sx-accent); background:rgba(16,32,34,.86);
  box-shadow:0 8px 24px rgba(0,0,0,.35), inset 0 0 0 1px color-mix(in srgb, var(--sx-accent) 30%, transparent);
  transform:translateY(-2px);
}
.mode-tile:active{ transform:scale(.96); }
.mode-tile b{ font-size:15px; letter-spacing:.1px; }
.mode-tile .x-accent{ color:var(--sx-accent); }
.mode-tile .mode-desc{ color:var(--sx-muted2); font-size:12px; line-height:1.45; }
.mode-tile .mode-count{
  position:absolute; top:11px; right:12px; color:var(--sx-muted); font-size:11px;
  font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* Stream mode reads as the AUDIENCE tile: accent name, full row, it unfolds the panel */
.mode-tile.mode-stream{ grid-column:1 / -1; }
.mode-tile.mode-stream b{ color:var(--sx-accent); }
.mode-tile[aria-expanded="true"]{ border-color:var(--sx-accent); }
@media (max-width:640px){ .gate-modes{ grid-template-columns:1fr; } }

/* content line: small boilerplate, deliberately not a spoiler gate */
.warn-line{ color:var(--sx-faint); font-size:11.5px; letter-spacing:.2px; margin-top:-4px; }
/* iPhone-only "add to home screen" tip (shown by game.js); a hair brighter than the warn line */
.fs-tip{ color:var(--sx-muted2); font-size:12.5px; margin-top:-2px; }
.fs-tip[hidden]{ display:none; }

/* gotcha card runs hot (the one place red is allowed) */
.got-h{ color:#ff3b30 !important; text-shadow:0 0 24px rgba(255,59,48,.5); font-size:38px !important; letter-spacing:1px; }
.got-btns{ display:flex; gap:10px; flex-wrap:wrap; justify-content:center; }

/* ── live race lobby (v0.42, Phase 10 multiplayer) ─────────────────────────*/
.race-code-row{ display:flex; flex-direction:column; align-items:center; gap:4px; margin:4px 0 2px; }
.race-code-row[hidden]{ display:none; }
.race-code-label{ color:var(--sx-muted); font-size:12px; letter-spacing:.14em; text-transform:uppercase; }
.race-code{ font:800 34px/1 ui-monospace, "SF Mono", Menlo, monospace; letter-spacing:.22em; color:var(--sx-accent); text-shadow:0 0 22px var(--sx-glow-1); }
.race-track{ display:flex; align-items:center; justify-content:center; gap:10px; margin:8px 0 2px; }
.race-track[hidden]{ display:none; }
.race-track-label{ color:var(--sx-muted); font-size:12px; letter-spacing:.14em; text-transform:uppercase; }
.race-track-sel{ background:rgba(255,255,255,.05); border:1px solid var(--sx-line); border-radius:12px; color:var(--sx-ink); font:600 14px/1 var(--sx-font, system-ui); padding:9px 12px; outline:none; cursor:pointer; transition:border-color var(--sx-dur-2,.18s) var(--sx-ease-out,ease), box-shadow var(--sx-dur-2,.18s) var(--sx-ease-out,ease); }
.race-track-sel[hidden]{ display:none; }
.race-track-sel:focus{ border-color:var(--sx-accent); box-shadow:0 0 0 3px var(--sx-glow-1); }
.race-track-name{ font:700 15px/1 var(--sx-font, system-ui); color:var(--sx-ink); }
.race-track-name[hidden]{ display:none; }
.race-roster{ display:flex; flex-direction:column; gap:7px; align-items:stretch; max-width:320px; margin:10px auto 2px; }
.race-roster-row{ display:flex; align-items:center; gap:9px; color:var(--sx-muted2); font-size:14px; }
.race-dot{ width:11px; height:11px; border-radius:50%; box-shadow:0 0 10px currentColor; flex:none; }
.race-roster-name{ flex:1 1 auto; text-align:left; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.race-roster-tag{ flex:none; font-size:12px; color:var(--sx-muted); letter-spacing:.02em; }
.race-roster-tag.ready{ color:#7cf58a; }

/* the fun display face — chunky + rounded — for the game's big moments (also painted on canvas) */
@font-face{ font-family:'Fredoka'; font-style:normal; font-weight:600 700; font-display:swap; src:url(fredoka.woff2?v=0.43.0) format('woff2'); }

/* ── live race: identity (v0.43) ───────────────────────────────────────────*/
.race-identity{ display:flex; flex-direction:column; gap:10px; align-items:center; margin:4px 0 8px; }
.race-identity[hidden]{ display:none; }
.race-name-input,.race-code-input{ background:rgba(255,255,255,.05); border:1px solid var(--sx-line); border-radius:12px; color:var(--sx-ink); font:600 15px/1 var(--sx-font, system-ui); padding:11px 14px; text-align:center; outline:none; transition:border-color var(--sx-dur-2,.18s) var(--sx-ease-out,ease), box-shadow var(--sx-dur-2,.18s) var(--sx-ease-out,ease); }
.race-name-input{ width:min(260px,78vw); }
.race-name-input:focus,.race-code-input:focus{ border-color:var(--sx-accent); box-shadow:0 0 0 3px var(--sx-glow-1); }
.race-code-input{ width:116px; letter-spacing:.24em; text-transform:uppercase; font-family:ui-monospace,"SF Mono",Menlo,monospace; }
.race-colors{ display:flex; flex-wrap:wrap; gap:8px; justify-content:center; max-width:300px; }
.race-colors[hidden]{ display:none; }
.race-swatch{ width:24px; height:24px; border-radius:50%; border:2px solid transparent; cursor:pointer; padding:0; box-shadow:0 0 10px -2px currentColor; transition:transform var(--sx-dur-1,.14s) var(--sx-spring,ease-out), border-color var(--sx-dur-1,.14s) var(--sx-ease-out,ease), opacity var(--sx-dur-1,.14s) ease; }
.race-swatch:hover{ transform:scale(1.14); }
.race-swatch:active{ transform:scale(.94); }
.race-swatch.sel{ border-color:#fff; transform:scale(1.14); box-shadow:0 0 14px 0 currentColor; }
.race-swatch.taken{ opacity:.26; cursor:not-allowed; transform:none; }

/* ── live race: setup (host / join / watch) ────────────────────────────────*/
.race-setup{ display:flex; flex-direction:column; gap:10px; align-items:center; margin:2px 0 6px; }
.race-setup[hidden]{ display:none; }
.race-join-row{ display:flex; gap:8px; align-items:center; justify-content:center; flex-wrap:wrap; }

/* ready button lit state + a disabled Start that reads as "waiting on the lobby" */
#race-ready.on{ background:linear-gradient(180deg,#2f8f4e,#227a3e); border-color:#3ba85c; color:#fff; }
#race-start.is-disabled{ opacity:.45; cursor:not-allowed; filter:grayscale(.3); }

/* a spectator watches with no cube, so no run controls clutter the board */
body.spectating #boost-btn,body.spectating #brake-btn,body.spectating #pause-btn,body.spectating #hud-timer{ display:none !important; }

/* ── the scare state: the calm skin violently inverts ──────────────────────*/
body.scaring{ --sx-glow-1:#ff2a1e; --sx-glow-2:#8a0f0f; }
body.scaring .stage{ animation:sx-quake .07s linear infinite; }
@keyframes sx-quake{
  0%{transform:translate(0,0)} 25%{transform:translate(-6px,4px)}
  50%{transform:translate(5px,-5px)} 75%{transform:translate(-4px,-3px)} 100%{transform:translate(4px,5px)}
}

/* ── mobile ────────────────────────────────────────────────────────────────*/
body{ overscroll-behavior:none; }   /* no pull-to-refresh / rubber-band eating a drag */

@media (max-width:640px){
  .veil-card h1{ font-size:26px; }
}

/* Portrait on a phone: the landing is NOT the game, so don't trap the gate/gotcha card
   inside the short 10:7 board box (it clips the card). Let the stage fill the column so
   the card centers with room to breathe; the board reclaims its aspect in landscape. */
@media (pointer:coarse) and (orientation:portrait){
  .stage{ aspect-ratio:auto; width:100%; height:100%; max-height:100%; border-radius:0; box-shadow:none; }

  /* Make the family footer an actual slim footer, not a block that eats the page: brand
     left, links right, drop the long blurb (the wordmark + links still credit StrmrX).
     This hands the vertical budget back to the gate/Play card. */
  .sx-famfoot{ flex:0 0 auto; margin-top:0; }
  .sx-famfoot-inner{
    flex-direction:row; align-items:center; flex-wrap:wrap; gap:8px 12px;
    padding:10px 16px calc(10px + env(safe-area-inset-bottom));
  }
  .sx-famfoot p{ display:none; }
  .sx-famfoot-brand{ margin-right:auto; }
  .sx-famfoot-word{ font-size:16px; }
  .sx-famfoot .sx-btn{ padding:7px 12px; font-size:12.5px; }
}

/* MazeX plays in landscape, but only the GAME needs it. The landing/gate and the gotcha
   card stay usable in portrait; the rotate nudge appears only while a run is live
   (body.playing, set by game.js) AND the phone is upright. Clears on rotate, pure CSS. */
.rotate-nudge{ display:none; }
@media (pointer:coarse) and (orientation:portrait){
  body.playing .rotate-nudge{
    display:flex; position:fixed; inset:0; z-index:200;
    align-items:center; justify-content:center; text-align:center; padding:30px;
    background:radial-gradient(120% 120% at 50% 30%, var(--sx-bg-hi), var(--sx-bg-lo));
  }
  .rotate-inner{ display:flex; flex-direction:column; align-items:center; gap:12px; max-width:320px; }
  .rotate-icon{ font-size:52px; animation:rot-tip 2.4s var(--sx-ease, ease) infinite; }
  .rotate-inner h2{ font-size:22px; font-weight:700; color:var(--sx-text); margin:0; }
  .rotate-inner h2 b{ color:var(--sx-accent); }
  .rotate-inner p{ color:var(--sx-muted2); font-size:14px; line-height:1.5; margin:0; }
}
@keyframes rot-tip{ 0%,60%,100%{ transform:rotate(0) } 75%,90%{ transform:rotate(-90deg) } }

/* Landscape on a phone: reclaim every pixel for the maze. Drop the browsing footer,
   tighten the chrome to one slim row, kill the stage padding/rounding so the board fits
   by height and fills the short viewport (pillar-boxed on the sides, which is correct for
   a 10:7 board on a 16:9+ screen). env() keeps the bar clear of the notch. */
@media (pointer:coarse) and (orientation:landscape){
  .sx-famfoot{ display:none; }
  .sx-topbar{
    flex:0 0 auto; padding:5px max(14px, env(safe-area-inset-right)) 5px max(14px, env(safe-area-inset-left));
    gap:8px;
  }
  .sx-topbar .sx-chip, .sx-topbar .sx-btn-sm{ padding-top:5px; padding-bottom:5px; }
  .stage-wrap{ padding:0 env(safe-area-inset-right) 0 env(safe-area-inset-left); }
  .stage{ border-radius:0; box-shadow:none; }
  .statusline{ bottom:6px; font-size:13px; }
}

/* reduced motion: never quake */
@media (prefers-reduced-motion: reduce){
  body.scaring .stage{ animation:none; }
}

/* ── play chrome (v0.25.0): one slim bar, nothing else. Joey's immersion call:
   during a run the topbar and the big family footer hide; this bar carries the
   StrmrX credit (there for everyone), the run HUD and the exit. ─────────────── */
.playbar{
  flex:0 0 auto; display:none; align-items:center; gap:8px;
  width:100%; padding:5px 12px calc(5px + env(safe-area-inset-bottom)) 12px;
  background:rgba(8,13,15,0.82); border-top:1px solid var(--sx-border);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  font-size:13px;
}
body.playing .playbar{ display:flex; }
body.playing .sx-topbar, body.playing .sx-famfoot{ display:none; }
.pb-brand{
  font-weight:800; letter-spacing:.3px; color:inherit; text-decoration:none;
  display:flex; align-items:baseline; gap:7px; white-space:nowrap;
}
.pb-brand b, .pb-by b{ color:var(--sx-accent); }
.pb-by{ font-size:11px; font-weight:600; opacity:.65; color:inherit; text-decoration:none; white-space:nowrap; }
.playbar .sx-chip{ padding-top:3px; padding-bottom:3px; }
.playbar .sx-btn-sm{ padding-top:4px; padding-bottom:4px; }

/* ── the skins shelf + the gate account row (v0.25.0) ───────────────────────── */
.store-card{ width:min(680px, 100%); max-height:92%; }
.store-head{ display:flex; align-items:center; width:100%; gap:10px; }
.store-head h2{ margin:0; font-size:22px; }
.store-head .sx-btn{ margin-left:auto; }
.store-grid{
  width:100%; overflow-y:auto; max-height:58vh; padding:4px 2px 8px;
  display:grid; grid-template-columns:repeat(auto-fill, minmax(138px, 1fr)); gap:10px;
}
.skin-card{
  display:flex; flex-direction:column; align-items:center; gap:6px;
  padding:12px 8px 10px; border-radius:12px; border:1px solid var(--sx-border);
  background:rgba(13,22,24,0.65);
}
.skin-card.on{ border-color:var(--sx-accent); box-shadow:0 0 14px color-mix(in srgb, var(--sx-accent) 30%, transparent); }
.skin-card.locked .skin-art{ opacity:.55; filter:saturate(.6); }
.skin-art{ width:84px; height:84px; object-fit:contain; }
.skin-name{ font-weight:700; font-size:13px; }
.skin-sub{ font-size:11px; opacity:.7; line-height:1.35; min-height:30px; }
.skin-act.arming{ border-color:#ff6b35; color:#ffb597; }
.gate-account{ display:flex; align-items:center; justify-content:center; gap:10px; min-height:26px; }
.acct-who{ display:flex; align-items:center; gap:7px; font-size:13px; opacity:.85; }
.acct-who img{ width:20px; height:20px; border-radius:50%; }

/* ── Power-ups (v0.26): the gate Powers row + the playbar coin chip ─────────── */
/* earned ink coins only: a balance pill + two spend buttons, NOT a second store */
.gate-powers{ display:flex; gap:10px; align-items:center; justify-content:center; flex-wrap:wrap; margin-top:-2px; }
.powers-bal{
  font:700 13px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color:#ffd23f; background:rgba(255,210,63,.08);
  border:1px solid rgba(255,210,63,.35); border-radius:999px; padding:7px 12px;
}
/* amber like the coins; pulses softly while coins are PENDING (bank on the win) */
.playbar .coin-chip{ color:#ffd23f; border-color:rgba(255,210,63,.4); }
.playbar .coin-chip.gain{ animation:coinPulse 1.1s ease-in-out infinite; }
/* speedrun timer chip (v0.30): a calm monospace clock; flashes green on a new best */
.playbar .timer-chip{ color:var(--sx-accent2); border-color:color-mix(in srgb, var(--sx-accent2) 40%, transparent); min-width:62px; text-align:center; }
.playbar .timer-chip.best{ color:#9be35a; border-color:rgba(155,227,90,.5); animation:coinPulse 1.1s ease-in-out 2; }
/* BOOST button (v0.30): bright when ready, dimmed with a sweeping cooldown fill while
   recharging (--cd is 0..1, written each cooling frame by game.js) */
#boost-btn{ position:relative; overflow:hidden; color:var(--sx-accent2); border-color:color-mix(in srgb, var(--sx-accent2) 45%, transparent); }
#boost-btn.ready{ box-shadow:0 0 12px color-mix(in srgb, var(--sx-accent2) 45%, transparent); }
#boost-btn.cooling{ color:var(--sx-muted); opacity:.75; }
#boost-btn.cooling::after{
  content:""; position:absolute; left:0; bottom:0; height:3px;
  width:calc(var(--cd, 0) * 100%); background:var(--sx-accent2); transition:width .08s linear;
}
@keyframes coinPulse{
  0%,100%{ box-shadow:0 0 0 rgba(255,210,63,0); }
  50%{ box-shadow:0 0 10px rgba(255,210,63,.45); }
}

/* ── IMMERSIVE HOMESCREEN (v0.1.6) ───────────────────────────────────────────
   The canvas behind paints a LIVING night scene (drawAttract): moon, parallax
   spires, the lone cube, the far glimmer. These landing layers are the MENU
   only — kept transparent (no card, no blur) so the art reads through, with a
   soft scrim just for text legibility. A game title, not a website card. */
.nb-landing{
  background:
    radial-gradient(130% 92% at 50% 44%, rgba(5,8,18,.52), rgba(5,8,18,0) 58%),
    linear-gradient(to bottom, rgba(4,6,14,.40) 0%, rgba(4,6,14,0) 26%, rgba(4,6,14,0) 62%, rgba(4,6,14,.60) 100%);
  backdrop-filter:none; -webkit-backdrop-filter:none;
  padding:20px;
}
.nb-landing-inner{
  position:relative; z-index:1;
  width:min(560px, 94%); max-height:100%; overflow-y:auto;
  display:flex; flex-direction:column; align-items:center; gap:18px;
  text-align:center; padding:8px;
}
.nb-hero{ display:flex; flex-direction:column; align-items:center; gap:6px; }
.nb-title{
  font-family:'Fredoka','Space Grotesk',system-ui,sans-serif;
  font-weight:700; letter-spacing:.5px; line-height:.94; margin:0;
  font-size:clamp(46px, 11vw, 92px); color:#eaf3ff;
  text-shadow:0 3px 30px rgba(8,12,34,.85), 0 0 64px rgba(88,213,255,.22);
}
.nb-title b{ color:var(--sx-accent); text-shadow:0 0 30px color-mix(in srgb, var(--sx-accent) 62%, transparent); }
.nb-tagline{
  font-family:'Space Grotesk',system-ui; font-weight:600; letter-spacing:.34em; text-transform:uppercase;
  font-size:12.5px; color:var(--sx-muted2); margin:0;
}
.nb-lede{ max-width:440px; color:var(--sx-muted2); font-size:14.5px; line-height:1.55; margin:2px 0 0; }

.nb-menu{ display:flex; flex-direction:column; align-items:center; gap:12px; width:100%; }
.nb-menu[hidden]{ display:none; }

/* the two mode tiles (signed in) */
.nb-modes{ display:grid; grid-template-columns:1fr 1fr; gap:12px; width:100%; max-width:520px; }
.nb-mode{
  appearance:none; font:inherit; cursor:pointer; text-align:left;
  display:flex; align-items:center; gap:12px; padding:16px;
  border-radius:16px; color:var(--sx-text);
  background:linear-gradient(180deg, rgba(18,26,48,.84), rgba(11,16,32,.84));
  border:1px solid var(--sx-border2); box-shadow:0 10px 30px rgba(0,0,0,.38);
  transition:transform var(--sx-dur-1,.14s) var(--sx-spring, cubic-bezier(.2,.9,.3,1.1)),
    border-color .16s var(--sx-ease-out,ease), box-shadow .16s var(--sx-ease-out,ease), background .16s var(--sx-ease-out,ease);
}
.nb-mode:hover{
  transform:translateY(-3px); border-color:var(--sx-accent);
  background:linear-gradient(180deg, rgba(22,32,58,.92), rgba(13,20,40,.92));
  box-shadow:0 16px 42px rgba(0,0,0,.48), inset 0 0 0 1px color-mix(in srgb, var(--sx-accent) 32%, transparent);
}
.nb-mode:active{ transform:scale(.97); }
.nb-mode-ic{ font-size:26px; line-height:1; filter:drop-shadow(0 0 10px color-mix(in srgb, var(--sx-accent) 42%, transparent)); }
.nb-mode-body{ display:flex; flex-direction:column; gap:3px; }
.nb-mode-body b{ font-size:16px; letter-spacing:.2px; }
.nb-mode-desc{ font-size:12px; color:var(--sx-muted2); line-height:1.4; }

/* sign-in front door (signed out) */
.nb-signin{ min-width:264px; }
.nb-signin b{ color:inherit; }   /* the X rides the button's own ink, not the cyan accent */
.nb-signin-note{ color:var(--sx-muted2); font-size:12.5px; margin:0; max-width:340px; line-height:1.5; }
.nb-guest-join{ margin-top:2px; }

.nb-secondary{ display:flex; gap:10px; align-items:center; justify-content:center; flex-wrap:wrap; margin-top:4px; }

/* ── Single Player journey screen ─────────────────────────────────────────── */
.solo-inner{ gap:16px; }
.solo-h{
  font-family:'Fredoka','Space Grotesk',system-ui; font-size:30px; font-weight:700; margin:0;
  color:#eaf3ff; letter-spacing:.3px; text-shadow:0 2px 20px rgba(8,12,34,.7);
}
.solo-journey{ display:flex; flex-direction:column; align-items:center; gap:10px; }
.solo-journey-label{ font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--sx-muted); }
.world-dots{ display:flex; gap:12px; align-items:flex-start; flex-wrap:wrap; justify-content:center; }
.world-dot{ display:flex; flex-direction:column; align-items:center; gap:6px; width:60px; }
.world-dot i{
  width:14px; height:14px; border-radius:5px; background:rgba(180,200,240,.16);
  border:1px solid var(--sx-border2); transition:all .2s var(--sx-ease-out,ease);
}
.world-dot em{ font-style:normal; font-size:10px; color:var(--sx-muted); line-height:1.25; text-align:center; }
.world-dot.on i{
  background:linear-gradient(135deg, var(--sx-accent), var(--sx-accent2)); border-color:transparent;
  box-shadow:0 0 12px color-mix(in srgb, var(--sx-accent) 60%, transparent);
}
.world-dot.on em{ color:var(--sx-text); }
.solo-how{ max-width:420px; color:var(--sx-muted2); font-size:14px; line-height:1.5; margin:0; }
.solo-sub{ display:flex; gap:10px; flex-wrap:wrap; justify-content:center; }
.solo-back{ margin-top:2px; }

@media (max-width:560px){ .nb-modes{ grid-template-columns:1fr; } }
/* landscape phone: tighten the vertical rhythm so the title + menu fit the short viewport */
@media (pointer:coarse) and (orientation:landscape){
  .nb-landing-inner{ gap:12px; }
  .nb-title{ font-size:clamp(38px, 9vh, 62px); }
  .nb-lede{ display:none; }
}
