/* =====================================================================
   TETRABLOX · "GLOW BLOCKS"
   Every surface is one of the game's own blocks: a rounded cell with the
   board's top gloss band, a dark ink outline, a short extrusion underneath
   and a neon glow in its own colour. Menus are block trays (a dark panel
   with the board's cell grid inside and a rim that cycles cyan, pink and
   gold), with tetrominoes resting on the corners. The wordmark is spelt in
   blocks that drop in like pieces. Fredoka, self-hosted.

   Colour roles (the game's own neon):
     cyan  #34e7e4  lead: Play, primary actions
     pink  #ff5fa2  racing
     gold  #ffd23f  numbers, stars and the chosen pick
     white          focus only (a white ring + halo, for keys and pads)
     The in-game control blocks keep their piece colours: orange undo,
     sky and violet mirrors, gold rotates, violet mute, pink race, lime
     start over.

   Rules: hub menu corner is bottom-left (64px, the control row slides
   right of it); every big button has an icon cell and a sub-line; focus
   shows only for keys/pads (:focus-visible, [data-hub-focus]); motion
   stops under prefers-reduced-motion.
   ===================================================================== */

@font-face{ font-family:'Fredoka'; font-weight:300 700; font-display:swap; src:url(fonts/fredoka.woff2) format('woff2'); }

@property --tb-spin{ syntax:'<angle>'; inherits:false; initial-value:0deg; }

:root{
  --font:'Fredoka','Trebuchet MS',system-ui,sans-serif;
  --gold:#ffd23f; --pink:#ff5fa2; --cyan:#34e7e4; --lime:#b0ff4d; --violet:#9d7bff; --orange:#ff9442; --sky:#48b8ff;
  --ink:#0a0f2c; --ink-2:#140d3a; --deep:#1a1147;
  --bounce:cubic-bezier(.2,1.6,.4,1); --settle:cubic-bezier(.2,.9,.3,1.1);
  --hub-menu-clear:64px;
  /* the icons drawn inside the big buttons' icon cells (ink on a white cell) */
  --i-play:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 5.5v13l11-6.5z' fill='%230a0f2c' stroke='%230a0f2c' stroke-width='2' stroke-linejoin='round'/%3E%3C/svg%3E");
  --i-flag:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0f2c' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 21V4'/%3E%3Cpath d='M6 4h12l-2.5 4.5L18 13H6' fill='%230a0f2c'/%3E%3C/svg%3E");
  --i-retry:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0f2c' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 12a7.5 7.5 0 1 0 2.2-5.3'/%3E%3Cpath d='M4.5 3.5v5h5'/%3E%3C/svg%3E");
  --i-star:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%230a0f2c' d='M12 2l2.9 6.3 6.9.7-5.1 4.6 1.4 6.8L12 17.8 5.9 20.4l1.4-6.8L2.2 9l6.9-.7z'/%3E%3C/svg%3E");
  --i-list:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M9 6h11M9 12h11M9 18h11'/%3E%3Ccircle cx='4.5' cy='6' r='1.3' fill='%23ffffff'/%3E%3Ccircle cx='4.5' cy='12' r='1.3' fill='%23ffffff'/%3E%3Ccircle cx='4.5' cy='18' r='1.3' fill='%23ffffff'/%3E%3C/svg%3E");
  --i-clock:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8.5'/%3E%3Cpath d='M12 7.5V12l3 2'/%3E%3C/svg%3E");
  --i-back:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 5l-7 7 7 7'/%3E%3C/svg%3E");
  --i-play-w:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 5.5v13l11-6.5z' fill='%23ffffff' stroke='%23ffffff' stroke-width='2' stroke-linejoin='round'/%3E%3C/svg%3E");
}

*{ box-sizing:border-box; margin:0; padding:0; -webkit-tap-highlight-color:transparent; }
html,body{ width:100%; height:100%; overflow:hidden; }
body{
  font-family:var(--font);
  background:
    radial-gradient(120% 90% at 10% 0%, #2a1457 0%, rgba(42,20,87,0) 55%),
    radial-gradient(120% 90% at 100% 100%, #06324a 0%, rgba(6,50,74,0) 55%),
    linear-gradient(160deg,#0a0f2c 0%, #1a1147 50%, #120b33 100%);
  color:#fff; user-select:none; -webkit-user-select:none; touch-action:none;
}
/* drifting neon glow blobs */
body::before, body::after{
  content:""; position:fixed; border-radius:50%; filter:blur(70px);
  opacity:.45; pointer-events:none; z-index:0;
}
body::before{ width:46vmin; height:46vmin; background:var(--pink); top:-12vmin; right:-10vmin; animation:float1 16s ease-in-out infinite; }
body::after { width:52vmin; height:52vmin; background:var(--cyan); bottom:-16vmin; left:-12vmin; animation:float2 19s ease-in-out infinite; }
@keyframes float1{ 0%,100%{ transform:translate(0,0) scale(1);} 50%{ transform:translate(-6vmin,8vmin) scale(1.12);} }
@keyframes float2{ 0%,100%{ transform:translate(0,0) scale(1);} 50%{ transform:translate(8vmin,-6vmin) scale(1.1);} }

#game{ position:fixed; inset:0; z-index:1; }
canvas{ display:block; }
button{ font-family:var(--font); }
button:focus{ outline:none; }

/* ---------------------------------------------------------------------
   The block recipe, shared by every button: --c is the block's colour.
   Gloss band on top (like the board's cells), ink outline, extrusion.
   --------------------------------------------------------------------- */
.ctrl, .big-btn, .pill, .mini-btn{
  --c:var(--cyan); --ex:6px;
  --c-hi:color-mix(in srgb, var(--c) 62%, #fff);
  --c-lo:color-mix(in srgb, var(--c) 62%, #000);
  --c-ex:color-mix(in srgb, var(--c) 40%, #000);
  border:none; cursor:pointer; color:var(--ink); font-weight:700; position:relative;
  background:
    linear-gradient(180deg, rgba(255,255,255,.42) 0 42%, transparent 42%) top/100% 100% no-repeat,
    linear-gradient(180deg, var(--c-hi), var(--c) 46%, var(--c-lo));
  box-shadow:
    inset 0 2px 0 rgba(255,255,255,.55), inset 0 -4px 0 var(--c-lo),
    0 0 0 2.5px var(--ink),
    0 var(--ex) 0 0 var(--c-ex), 0 var(--ex) 0 2.5px var(--ink),
    0 calc(var(--ex) + 8px) 18px rgba(0,0,0,.45),
    0 0 24px color-mix(in srgb, var(--c) 45%, transparent);
  transition:transform .09s ease, box-shadow .09s ease, filter .15s ease;
}
.ctrl:active, .big-btn:active, .pill:active, .mini-btn:active{
  --ex:2px; transform:translateY(4px);
}
@media (hover:hover){
  .ctrl:not([disabled]):hover, .big-btn:hover, .pill:hover, .mini-btn:hover{ filter:brightness(1.1) saturate(1.05); }
}

/* Focus: keys and pads only (the hub's ring is off over our menus). */
:is(.ctrl, .big-btn, .pill, .mini-btn):is(:focus-visible, [data-hub-focus]){
  outline:3px solid #fff; outline-offset:6px;
  animation:tb-wobble .5s var(--bounce);
}
:is(.big-btn, .pill, .mini-btn):is(:focus-visible, [data-hub-focus])::before{ filter:drop-shadow(0 0 6px #fff); }
html[data-hub-input="touch"] :is(.ctrl, .big-btn, .pill, .mini-btn)[data-hub-focus]:not(:focus-visible){ outline:none; animation:none; }
@keyframes tb-wobble{ 0%{ transform:scale(1);} 35%{ transform:scale(1.07,.95);} 65%{ transform:scale(.97,1.03);} 100%{ transform:scale(1);} }

/* ===== HUD: the top bar ===== */
#hud{ position:fixed; inset:0; z-index:2; pointer-events:none; }
.bar{
  position:absolute; top:max(10px, env(safe-area-inset-top)); left:0; right:0;
  display:flex; align-items:center; justify-content:center; gap:8px; padding:0 10px;
  flex-wrap:wrap;
}
.badge{
  --c:var(--cyan);
  pointer-events:none; position:relative;
  display:flex; align-items:center; gap:7px; min-height:38px; padding:4px 12px 4px 4px;
  border-radius:13px;
  background:
    linear-gradient(180deg, rgba(255,255,255,.08) 0 42%, transparent 42%),
    linear-gradient(180deg, rgba(26,17,71,.92), rgba(10,15,44,.94));
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--c) 55%, transparent), 0 0 0 2px var(--ink),
    0 4px 0 2px var(--ink), 0 0 16px color-mix(in srgb, var(--c) 35%, transparent);
  animation:tb-drop .45s var(--bounce) both;
}
.badge:nth-child(2){ --c:var(--violet); animation-delay:.07s; }
.badge.stars{ --c:var(--gold); animation-delay:.14s; padding-left:4px; }
.badge.score{ --c:var(--pink); animation-delay:.21s; }
.badge .lab{
  font-size:10px; letter-spacing:1.2px; font-weight:700; text-transform:uppercase; color:var(--ink);
  min-width:30px; height:30px; padding:0 6px; border-radius:9px; display:grid; place-items:center;
  background:linear-gradient(180deg, rgba(255,255,255,.45) 0 42%, transparent 42%), var(--c);
  box-shadow:inset 0 -2px 0 color-mix(in srgb, var(--c) 60%, #000);
}
.badge .val{ font-size:19px; font-weight:700; line-height:1; color:var(--gold); font-variant-numeric:tabular-nums; text-shadow:0 2px 0 var(--ink); }
.badge.stars{ transition:transform .15s var(--bounce); }
.badge.stars.pulse{ transform:scale(1.18); }
.star-ico{
  width:30px; height:30px; padding:5px; border-radius:9px; display:block;
  background:linear-gradient(180deg, rgba(255,255,255,.45) 0 42%, transparent 42%), var(--gold);
  box-shadow:inset 0 -2px 0 #9a7a0c;
}
.star-ico path{ fill:var(--ink); }

/* ===== HUD: the control blocks ===== */
.ctrl{
  pointer-events:auto; position:absolute;
  width:60px; height:60px; border-radius:14px;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  animation:tb-rise .5s var(--bounce) both;
}
.ctrl .glyph{ display:grid; place-items:center; line-height:1; }
.ctrl svg{ width:32px; height:32px; fill:none; stroke:currentColor; stroke-width:3; stroke-linecap:round; stroke-linejoin:round; overflow:visible; }
.ctrl svg .fill{ fill:currentColor; stroke:none; }
/* the count: a gold number on a little ink block at the top-right corner */
.ctrl .cnt{
  position:absolute; top:-8px; right:-8px; min-width:24px; height:24px; padding:0 5px;
  display:grid; place-items:center; border-radius:8px;
  font-size:13px; font-weight:700; color:var(--gold); background:var(--ink);
  box-shadow:0 0 0 2px color-mix(in srgb, var(--c) 70%, #fff), 0 2px 6px rgba(0,0,0,.5);
  font-variant-numeric:tabular-nums;
}
.ctrl[disabled]{
  cursor:default; color:rgba(10,15,44,.55);
  --c:#4a4f78; filter:none; box-shadow:
    inset 0 2px 0 rgba(255,255,255,.18), inset 0 -4px 0 #2d3157,
    0 0 0 2.5px var(--ink), 0 var(--ex) 0 0 #23264a, 0 var(--ex) 0 2.5px var(--ink),
    0 calc(var(--ex) + 8px) 18px rgba(0,0,0,.4);
}
.ctrl[disabled] .cnt{ color:#8b90b8; box-shadow:0 0 0 2px #4a4f78; }
.ctrl[disabled]:active{ --ex:6px; transform:none; }
.ctrl.earn{ animation:earnPop .5s var(--bounce); }
@keyframes earnPop{ 0%{transform:scale(1);} 40%{transform:scale(1.28); filter:brightness(1.5) drop-shadow(0 0 14px var(--c));} 100%{transform:scale(1);} }
@keyframes tb-rise{ from{ opacity:0; transform:translateY(40px) scale(.7);} }
@keyframes tb-drop{ from{ opacity:0; transform:translateY(-30px) scale(.8);} }
/* The bottom row (270px wide) is centered but never starts inside the hub menu's
   bottom-left corner: --hub-menu-clear is its 44px button + 12px margin + 8px gap.
   On a narrow phone the row slides right to leave the button its spot. */
#hud{ --row-x:max(calc(50% - 135px), calc(var(--hub-menu-clear) + env(safe-area-inset-left, 0px))); }
#undoBtn{ --c:var(--orange); left:var(--row-x); bottom:max(22px, env(safe-area-inset-bottom)); }
#mirrorVBtn{ --c:var(--sky); left:calc(var(--row-x) + 70px); bottom:max(94px, calc(env(safe-area-inset-bottom) + 72px)); animation-delay:.05s; }
#mirrorBtn{ --c:var(--violet); left:calc(var(--row-x) + 70px); bottom:max(22px, env(safe-area-inset-bottom)); animation-delay:.1s; }
#rotateLeftBtn{ --c:var(--gold); left:calc(var(--row-x) + 140px); bottom:max(22px, env(safe-area-inset-bottom)); animation-delay:.15s; }
#rotateBtn{ --c:var(--gold); left:calc(var(--row-x) + 210px); bottom:max(22px, env(safe-area-inset-bottom)); animation-delay:.2s; }
#mirrorBtn, #mirrorVBtn{ color:#fff; }
#mirrorBtn svg, #mirrorVBtn svg{ filter:drop-shadow(0 1.5px 0 rgba(10,15,44,.5)); }
#muteBtn, #raceCtrl, #restartBtn{
  width:46px; height:46px; border-radius:12px; --ex:4px;
  top:max(58px, calc(env(safe-area-inset-top) + 50px)); color:#fff;
}
#muteBtn .glyph svg, #raceCtrl .glyph svg, #restartBtn .glyph svg{ width:24px; height:24px; filter:drop-shadow(0 1.5px 0 rgba(10,15,44,.45)); }
#muteBtn{ --c:var(--violet); right:max(14px, env(safe-area-inset-right)); }
#muteBtn .slash{ display:none; }
#muteBtn.muted{ --c:#6a6f98; }
#muteBtn.muted .slash{ display:inline; }
#raceCtrl{ --c:var(--pink); left:max(14px, env(safe-area-inset-left)); }
/* Daily challenge only: Start over, beside the race button (the hub menu is bottom-left). */
#restartBtn{
  --c:var(--lime); color:var(--ink);
  width:auto; flex-direction:row; gap:6px; padding:0 14px 0 10px;
  left:calc(max(14px, env(safe-area-inset-left)) + 56px);
  font-size:15px; white-space:nowrap;
}
#restartBtn .glyph svg{ filter:none; }
#restartBtn.off{ display:none; }

/* ===== Race mode: the hub's race HUD sits at the top, so the game's own
   top bar (and the mute button) drop below it. --race-top is the HUD's
   bottom edge, measured live. Score isn't part of a race, so it hides. ===== */
body.race .bar{ top:calc(var(--race-top, 112px) + 6px); }
body.race .badge.score{ display:none; }
body.race #muteBtn{ top:calc(var(--race-top, 112px) + 3px); }
body.race #raceCtrl{ display:none; }

/* ---------------------------------------------------------------------
   Overlays: a dim over the board, and a block tray in the middle.
   --------------------------------------------------------------------- */
.overlay{
  position:fixed; inset:0; z-index:5; display:flex; flex-direction:column;
  align-items:center; justify-content:safe center; text-align:center;
  padding:max(20px, env(safe-area-inset-top)) 16px max(84px, calc(env(safe-area-inset-bottom) + 72px));
  overflow-y:auto; overscroll-behavior:contain;
  background:radial-gradient(120% 120% at 50% 30%, rgba(20,11,51,.55), rgba(10,15,44,.92));
  backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px);
  animation:tb-fade .25s ease both;
}
.overlay.hidden{ display:none; }
@keyframes tb-fade{ from{ opacity:0; } }

.tb-card{
  position:relative; flex:none; width:min(92vw, 440px); margin:auto 0;
  display:flex; flex-direction:column; align-items:center; gap:16px;
  padding:30px 24px 28px; border-radius:26px;
  background:
    radial-gradient(120% 60% at 50% 0%, rgba(52,231,228,.12), transparent 60%),
    linear-gradient(rgba(255,255,255,.035) 1.5px, transparent 1.5px) 0 0/26px 26px,
    linear-gradient(90deg, rgba(255,255,255,.035) 1.5px, transparent 1.5px) 0 0/26px 26px,
    linear-gradient(180deg, rgba(26,17,71,.96), rgba(10,15,44,.97));
  box-shadow:0 0 0 3px var(--ink), 0 10px 0 3px var(--ink), 0 24px 50px rgba(0,0,0,.55);
  animation:tb-tray-in .55s var(--settle) both;
}
/* the rim: a slow cyan → pink → gold cycle */
.tb-card::before{
  content:""; position:absolute; inset:0; border-radius:inherit; padding:3px; pointer-events:none;
  background:conic-gradient(from var(--tb-spin), var(--cyan), var(--pink), var(--gold), var(--cyan));
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude;
  filter:drop-shadow(0 0 8px rgba(255,95,162,.55));
  animation:tb-spin 8s linear infinite;
}
@keyframes tb-spin{ to{ --tb-spin:360deg; } }
@keyframes tb-tray-in{ from{ opacity:0; transform:translateY(26px) scale(.92); } }
/* tetrominoes resting on the tray: a cyan T on the top-left, a pink L on the bottom-right */
.tb-card > .tb-tet{
  position:absolute; width:18px; height:18px; border-radius:5px; pointer-events:none;
  --c:var(--cyan);
  background:linear-gradient(180deg, rgba(255,255,255,.5) 0 42%, transparent 42%), var(--c);
  box-shadow:
    20px 0 0 var(--c), 40px 0 0 var(--c), 20px 20px 0 var(--c),
    0 0 0 2px var(--ink), 20px 0 0 2px var(--ink), 40px 0 0 2px var(--ink), 20px 20px 0 2px var(--ink);
  top:-11px; left:24px; transform:rotate(-6deg);
  animation:tb-tet-bob 4s ease-in-out infinite;
}
.tb-card > .tb-tet.b{
  --c:var(--pink); top:auto; left:auto; bottom:-8px; right:62px; transform:rotate(5deg);
  box-shadow:
    0 -20px 0 var(--c), 0 -40px 0 var(--c), 20px 0 0 var(--c),
    0 0 0 2px var(--ink), 0 -20px 0 2px var(--ink), 0 -40px 0 2px var(--ink), 20px 0 0 2px var(--ink);
  animation-delay:-2s;
}
@keyframes tb-tet-bob{ 0%,100%{ translate:0 0; } 50%{ translate:0 -4px; } }

/* the in-tray stagger: --i is set in the markup */
.tb-card > *:not(.tb-tet){ animation:tb-in .45s var(--bounce) both; animation-delay:calc(.12s + var(--i, 0) * .06s); }
@keyframes tb-in{ from{ opacity:0; transform:translateY(14px) scale(.9); } }

/* ===== Headings: neon letters on a block extrusion ===== */
.title{
  font-size:clamp(40px, 12vw, 76px); font-weight:700; letter-spacing:2px; line-height:.95;
  background:linear-gradient(120deg,var(--cyan),var(--pink) 55%,var(--gold));
  -webkit-background-clip:text; background-clip:text; color:transparent;
  filter:drop-shadow(0 3px 0 #2a1460) drop-shadow(0 5px 0 var(--ink)) drop-shadow(0 0 18px rgba(255,95,162,.45));
}
.sub{ font-size:16px; line-height:1.4; color:#dcd6ff; max-width:34ch; font-weight:500; }
.sub b{ color:var(--gold); }
.scoreline{ font-size:18px; font-weight:600; color:#dcd6ff; display:flex; align-items:center; gap:10px; }
.scoreline b{
  color:var(--gold); font-size:30px; min-width:64px; padding:4px 14px; border-radius:12px;
  background:var(--ink); box-shadow:inset 0 0 0 2px rgba(255,210,63,.55), 0 0 18px rgba(255,210,63,.3);
  font-variant-numeric:tabular-nums;
}

/* ===== The wordmark: the cover's lettering, cyan-to-pink and pink-to-gold neon on a deep ink extrusion with a white rim ===== */
.tb-word{ display:flex; flex-direction:column; align-items:flex-start; font-size:clamp(58px, 17vw, 96px); line-height:.86; transform:rotate(-4deg); margin:4px 0 8px; }
.tb-word > span{ position:relative; display:block; font-weight:700; letter-spacing:1px; animation:tb-word-drop .7s var(--bounce) both, tb-letter-bob 3.4s ease-in-out 1.2s infinite; }
.tb-word > span.w2{ margin-left:.4em; animation-delay:.12s, 2.9s; }
.tb-word b{ display:block; font-weight:700; }
.tb-word .ext, .tb-word .rim, .tb-word .gloss{ position:absolute; left:0; top:0; }
.tb-word .ext{ color:#1e0a44; -webkit-text-stroke:.16em #1e0a44;
  text-shadow:0 .05em 0 #1e0a44, 0 .1em 0 #14062e, 0 0 .3em rgba(255,95,162,.55), 0 .18em .2em rgba(0,0,0,.6); }
.tb-word .rim{ color:#fff; -webkit-text-stroke:.06em #fff; }
.tb-word .fill{ position:relative; background:linear-gradient(175deg,#4ff2ef 0%, #22d6e0 30%, #ff4f9a 64%, #ff7a8a 100%); -webkit-background-clip:text; background-clip:text; color:transparent; }
.tb-word .w2 .fill{ background:linear-gradient(175deg,#ff5fa2 0%, #ff6f86 30%, #ff9a3a 66%, #ffd23f 100%); -webkit-background-clip:text; background-clip:text; }
.tb-word .gloss{ color:transparent; background:linear-gradient(180deg,rgba(255,255,255,.55) 0%,rgba(255,255,255,.12) 40%,rgba(255,255,255,0) 52%); -webkit-background-clip:text; background-clip:text; }
@keyframes tb-word-drop{ 0%{ opacity:0; transform:translateY(-120px) scale(.7,1.3); } 60%{ transform:translateY(4px) scale(1.1,.88); } 80%{ transform:scale(.97,1.03); } }
@keyframes tb-letter-bob{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-4px); } }
.tb-kicker{ font-size:12px; letter-spacing:.32em; font-weight:700; color:var(--gold); display:flex; align-items:center; gap:10px; }
.tb-kicker::before, .tb-kicker::after{ content:""; width:22px; height:3px; border-radius:2px; background:linear-gradient(90deg, var(--cyan), var(--pink)); }

/* ===== Big buttons: a long block with an icon cell and a sub-line ===== */
.big-btn{
  pointer-events:auto; font-size:21px; letter-spacing:.06em; text-align:left;
  width:min(100%, 320px); min-height:66px; padding:10px 18px 10px 12px; border-radius:18px;
  display:grid; grid-template-columns:44px 1fr; column-gap:14px; align-items:center;
  line-height:1.1;
}
.big-btn::before{
  content:""; grid-row:1 / 3; width:44px; height:44px; border-radius:11px;
  background:var(--icon, var(--i-play)) center/24px 24px no-repeat,
    linear-gradient(180deg, #fff 0 42%, #e6ecff 42%);
  box-shadow:inset 0 -3px 0 rgba(10,15,44,.18), 0 0 0 2px var(--ink);
}
.big-btn::after{
  content:attr(data-sub); grid-column:2; font-size:13px; font-weight:600; letter-spacing:.01em; opacity:.78; margin-top:2px;
}
.big-btn:not([data-sub])::after{ display:none; }
.big-btn:not([data-sub]){ grid-template-rows:auto; }
/* the primary's sheen, every 3.6s */
#startBtn, #againBtn:not(.quiet), #raceStartBtn, #restartYesBtn{
  background:
    linear-gradient(105deg, transparent 40%, rgba(255,255,255,.55) 50%, transparent 60%) 0 0/300% 100% no-repeat,
    linear-gradient(180deg, rgba(255,255,255,.42) 0 42%, transparent 42%) top/100% 100% no-repeat,
    linear-gradient(180deg, var(--c-hi), var(--c) 46%, var(--c-lo));
  animation:tb-in .45s var(--bounce) both, tb-sheen 3.6s ease-in-out 1s infinite;
  animation-delay:calc(.12s + var(--i, 0) * .06s), 1.2s;
}
@keyframes tb-sheen{ 0%,70%{ background-position:100% 0, top, 0 0; } 100%{ background-position:0% 0, top, 0 0; } }
.big-btn.alt{ --c:var(--pink); color:#fff; }
.big-btn.alt::after{ opacity:.9; }
.big-btn.alt, .big-btn.alt{ text-shadow:0 2px 0 rgba(10,15,44,.35); }
#raceBtn, #raceBtn2{ --icon:var(--i-flag); }
#dailyAgainBtn{ --c:var(--gold); --icon:var(--i-retry); }
#restartYesBtn{ --c:var(--lime); --icon:var(--i-retry); }
#raceStartBtn{ --icon:var(--i-flag); }
.big-btn.off{ display:none; }
/* a lost daily: TRY AGAIN leads; the normal game is a quieter ink block */
.big-btn.quiet{
  --c:#3b3577; color:#fff; font-size:18px; min-height:56px; text-shadow:0 2px 0 rgba(10,15,44,.4);
  box-shadow:inset 0 2px 0 rgba(255,255,255,.2), inset 0 -4px 0 #251f55, 0 0 0 2.5px var(--ink),
    0 var(--ex) 0 0 #1b1640, 0 var(--ex) 0 2.5px var(--ink), 0 calc(var(--ex) + 8px) 18px rgba(0,0,0,.4);
}
.big-btn.quiet::before{ background:var(--i-play-w) center/22px 22px no-repeat, rgba(255,255,255,.12); box-shadow:0 0 0 2px var(--ink); }

/* ===== Small buttons and pickers ===== */
.mini-btn{
  --c:#3b3577; --ex:4px;
  pointer-events:auto; font-size:15px; color:#fff; min-height:46px; padding:10px 16px 10px 12px; border-radius:13px;
  display:inline-flex; align-items:center; gap:8px; white-space:nowrap; text-shadow:0 1.5px 0 rgba(10,15,44,.45);
  box-shadow:inset 0 2px 0 rgba(255,255,255,.22), inset 0 -3px 0 #251f55, inset 0 0 0 1.5px rgba(52,231,228,.35),
    0 0 0 2.5px var(--ink), 0 var(--ex) 0 0 #1b1640, 0 var(--ex) 0 2.5px var(--ink), 0 calc(var(--ex) + 6px) 14px rgba(0,0,0,.4);
}
.mini-btn::before{ content:""; width:20px; height:20px; background:var(--icon, none) center/20px 20px no-repeat; flex:none; }
.mini-btn:not([style*="--icon"]):not(#raceBrowseBtn):not(#raceHistoryBtn):not(#raceBackBtn)::before{ display:none; }
#raceBrowseBtn{ --icon:var(--i-list); }
#raceHistoryBtn{ --icon:var(--i-clock); }
#raceBackBtn{ --icon:var(--i-back); }
.mini-btn.ghost{ background:none; box-shadow:none; opacity:.85; padding-left:8px; }
.mini-btn.ghost:hover{ opacity:1; }
#restartNoBtn{ --icon:var(--i-play-w); }
#restartNoBtn::before{ display:block; background-size:16px 16px; }

#raceMenu .tb-card{ gap:12px; }
.race-label{ font-size:12px; letter-spacing:.26em; font-weight:700; color:var(--gold); margin-top:4px; display:flex; align-items:center; gap:8px; }
.race-label::before{ content:""; width:10px; height:10px; border-radius:3px; background:var(--gold); box-shadow:0 0 0 1.5px var(--ink); }
.seg{ display:flex; gap:12px; justify-content:center; flex-wrap:wrap; }
.pill{
  --c:#3b3577; --ex:5px; color:#fff;
  pointer-events:auto; min-width:58px; min-height:52px; padding:8px 14px; border-radius:14px; font-size:21px;
  text-shadow:0 2px 0 rgba(10,15,44,.45); font-variant-numeric:tabular-nums;
  box-shadow:inset 0 2px 0 rgba(255,255,255,.2), inset 0 -4px 0 #251f55,
    0 0 0 2.5px var(--ink), 0 var(--ex) 0 0 #1b1640, 0 var(--ex) 0 2.5px var(--ink), 0 calc(var(--ex) + 6px) 14px rgba(0,0,0,.4);
}
.pill.small{ font-size:16px; min-width:112px; }
.pill[aria-pressed="true"]{
  --c:var(--gold); color:var(--ink); text-shadow:none;
  box-shadow:inset 0 2px 0 rgba(255,255,255,.55), inset 0 -4px 0 var(--c-lo), 0 0 0 2.5px var(--ink),
    0 var(--ex) 0 0 var(--c-ex), 0 var(--ex) 0 2.5px var(--ink), 0 calc(var(--ex) + 6px) 14px rgba(0,0,0,.4),
    0 0 22px rgba(255,210,63,.55);
  animation:tb-pick .35s var(--bounce);
}
@keyframes tb-pick{ 0%{ transform:scale(.9);} 60%{ transform:scale(1.1);} 100%{ transform:scale(1);} }
.race-note{ font-size:13px; color:#cfc9f5; max-width:min(340px, 82vw); min-height:1.2em; font-weight:500; }
.race-row{ display:flex; gap:12px; justify-content:center; flex-wrap:wrap; }
.race-err{ color:#ffb3c6; font-size:14px; font-weight:600; min-height:1.2em; max-width:min(340px, 82vw); }
.race-err:empty{ display:none; }

/* ===== The transient banner: block-outlined neon words ===== */
#banner{
  position:fixed; left:0; right:0; top:38%; z-index:4; text-align:center; pointer-events:none;
  font-size:clamp(32px,9.5vw,64px); font-weight:700; letter-spacing:1px;
  color:#fff; -webkit-text-stroke:8px var(--ink); paint-order:stroke fill;
  text-shadow:0 5px 0 var(--ink), 0 0 26px rgba(255,95,162,.75), 0 0 48px rgba(52,231,228,.5);
  opacity:0; transform:scale(.6);
}
#banner.show{ animation:bannerPop 1.5s ease forwards; }
@keyframes bannerPop{
  0%{ opacity:0; transform:translateY(-60px) scale(.6) rotate(-4deg);}
  18%{ opacity:1; transform:translateY(0) scale(1.12,.9) rotate(2deg);}
  32%{ transform:scale(1) rotate(0);}
  72%{ opacity:1; transform:scale(1);}
  100%{ opacity:0; transform:scale(1.05);}
}

/* ===== Title idle: tetrominoes drifting down behind the tray, stars twinkling ===== */
.tb-fall{ position:fixed; inset:0; pointer-events:none; overflow:hidden; z-index:-1; }
.tb-fall i{
  position:absolute; top:-80px; width:16px; height:16px; border-radius:4px; opacity:.35;
  --c:var(--cyan); background:var(--c);
  box-shadow:18px 0 0 var(--c), 0 18px 0 var(--c), 18px 18px 0 var(--c);
  animation:tb-fall 14s linear infinite;
}
.tb-fall i:nth-child(1){ left:8%;  animation-delay:-2s; }
.tb-fall i:nth-child(2){ left:24%; --c:var(--pink); box-shadow:18px 0 0 var(--c), 36px 0 0 var(--c), 54px 0 0 var(--c); animation-duration:17s; animation-delay:-9s; }
.tb-fall i:nth-child(3){ left:46%; --c:var(--gold); box-shadow:0 18px 0 var(--c), 0 36px 0 var(--c), 18px 36px 0 var(--c); animation-duration:12s; animation-delay:-5s; }
.tb-fall i:nth-child(4){ left:66%; --c:var(--lime); box-shadow:18px 0 0 var(--c), 18px 18px 0 var(--c), 36px 18px 0 var(--c); animation-duration:15s; animation-delay:-12s; }
.tb-fall i:nth-child(5){ left:84%; --c:var(--violet); box-shadow:18px 0 0 var(--c), 36px 0 0 var(--c), 18px 18px 0 var(--c); animation-duration:13s; animation-delay:-7s; }
.tb-fall i:nth-child(6){ left:92%; --c:var(--orange); box-shadow:0 18px 0 var(--c), 0 36px 0 var(--c), 18px 0 0 var(--c); animation-duration:18s; animation-delay:-1s; }
@keyframes tb-fall{ to{ transform:translateY(calc(100vh + 160px)) rotate(180deg); } }
.tb-fall b{ position:absolute; color:var(--gold); font-size:14px; opacity:0; animation:tb-twinkle 3.4s ease-in-out infinite; text-shadow:0 0 10px var(--gold); }
.tb-fall b:nth-of-type(1){ left:14%; top:22%; }
.tb-fall b:nth-of-type(2){ left:80%; top:30%; animation-delay:-1.2s; }
.tb-fall b:nth-of-type(3){ left:70%; top:76%; animation-delay:-2.3s; }
.tb-fall b:nth-of-type(4){ left:20%; top:68%; animation-delay:-.6s; }
@keyframes tb-twinkle{ 0%,100%{ opacity:0; transform:scale(.5);} 50%{ opacity:.9; transform:scale(1.1);} }

/* ===== Short screens (phone landscape): a tighter tray ===== */
@media (max-height:520px){
  .overlay{ padding-top:max(10px, env(safe-area-inset-top)); padding-bottom:max(10px, env(safe-area-inset-bottom)); padding-left:84px; padding-right:84px; }
  .tb-card{ gap:9px; padding:20px 22px 20px; width:min(100%, 600px); }
  #gameover .tb-card{ width:min(100%, 760px); }
  .tb-word{ flex-direction:row; gap:.3em; font-size:clamp(40px, 12vh, 58px); margin:0 0 4px; }
  .tb-word > span.w2{ margin-left:0; }
  .title{ font-size:clamp(28px, 8vh, 40px); }
  .sub{ font-size:14px; max-width:52ch; }
  #raceMenu .sub, #splash .tb-kicker{ display:none; }
  .overlay .tb-card > .tb-btns{ flex-direction:row; justify-content:center; gap:14px; }
  .tb-btns .big-btn{ font-size:16px; padding-right:12px; column-gap:10px; }
  .tb-btns .big-btn::after{ font-size:11px; }
  .big-btn{ min-height:58px; font-size:18px; }
  .pill{ min-height:46px; }
  /* the race picker as two columns: labels beside their pickers, Start beside the lists */
  #raceMenu .tb-card{ display:grid; grid-template-columns:auto auto; justify-content:center; align-items:center; column-gap:18px; row-gap:10px; }
  #raceMenu .title, #raceMenu .race-note, #raceMenu .mini-btn.ghost, #raceMenu .race-err{ grid-column:1 / -1; justify-self:center; }
  #raceMenu .race-label{ justify-self:end; margin:0; }
  #raceMenu .seg, #raceMenu .race-row{ justify-content:flex-start; flex-wrap:nowrap; }
  #raceMenu .race-note:empty{ display:none; }
  #raceMenu .big-btn{ width:260px; }
  #raceMenu .mini-btn.ghost{ min-height:40px; padding-top:4px; padding-bottom:4px; }
}
@media (min-width:900px) and (min-height:760px){
  .tb-card{ width:480px; padding:36px 30px 32px; gap:18px; }
  .tb-word{ font-size:104px; }
  .big-btn{ width:340px; }
}
.tb-card > .tb-btns{ display:flex; flex-direction:column; align-items:center; gap:16px; width:100%; }
.tb-btns .big-btn{ flex:1 1 0; }

/* ===== Reduced motion: no entrances, no idle loops ===== */
@media (prefers-reduced-motion: reduce){
  body::before, body::after, .tb-card, .tb-card::before, .tb-card > *, .tb-tet, .tb-word > span, .tb-fall, .badge, .ctrl,
  .ctrl.earn, .pill[aria-pressed="true"], .overlay, #startBtn, #againBtn, #raceStartBtn, #restartYesBtn,
  :is(.ctrl, .big-btn, .pill, .mini-btn):is(:focus-visible, [data-hub-focus]){ animation:none !important; }
  .tb-fall{ display:none; }
  #banner.show{ animation:tb-fade-banner 1.5s linear forwards; transform:none; }
  @keyframes tb-fade-banner{ 0%,80%{ opacity:1; } 100%{ opacity:0; } }
}
