:root{
  --ink:#080b16;
  --ink2:#0e1426;
  --panel:#151c33;
  --panel2:#1c2542;
  --line:#2b3560;
  --gold:#e8c37a;
  --gold-dim:#8d7440;
  --text:#dfe5ff;
  --mute:#8792bd;
  --ruby:#ff3b5c; --ruby2:#ff9aab;
  --amber:#ffa41b; --amber2:#ffd48a;
  --fern:#2fd07a;  --fern2:#9ff0c2;
  --aqua:#29c5f6;  --aqua2:#a3e6ff;
  --violet:#a06bff;--violet2:#d6bcff;
  --pearl:#e9eeff; --pearl2:#ffffff;
  --s:48px;
}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
html,body{height:100%}
body{
  background:
    radial-gradient(1200px 600px at 50% -10%, #1b2547 0%, transparent 60%),
    radial-gradient(800px 500px at 100% 100%, #241a3d 0%, transparent 55%),
    var(--ink);
  color:var(--text);
  font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  font-variant-numeric:tabular-nums;
  display:flex;justify-content:center;
  padding:14px 12px 26px;
  overflow-x:hidden;
}
.app{width:100%;max-width:470px;display:flex;flex-direction:column;gap:12px}

/* ---------- header ---------- */
header{display:flex;flex-direction:column;align-items:center;gap:5px}
/* The pitch, where a first-time visitor actually sees it. Small enough to read
   as a subtitle rather than competing with the board. */
.tagline{font-size:10.5px;letter-spacing:.1em;color:var(--mute);text-align:center;
  line-height:1.35;max-width:330px}
/* NO opacity here. --mute on the header ground is 5.32:1; the .85 opacity this
   used to carry dragged it to 4.25:1, under the 4.5:1 AA floor — and at 10.5px,
   the smallest type on the page, which is where contrast matters most. Fade the
   colour token if it ever needs to sit back further, not the layer. */
.brand{
  font-weight:800;font-size:20px;letter-spacing:.2em;line-height:1;
  background:linear-gradient(100deg,var(--pearl) 0%,var(--gold) 45%,var(--violet2) 90%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  white-space:nowrap;
}
.modes{display:flex;gap:4px;background:var(--ink2);border:1px solid var(--line);
  border-radius:999px;padding:3px;width:100%}
.modes button{flex:1}
.modes button{
  font:inherit;font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--mute);background:none;border:0;border-radius:999px;padding:6px 9px;cursor:pointer;
}
.modes button.on{background:var(--panel2);color:var(--gold);box-shadow:inset 0 0 0 1px var(--line)}

/* ---------- hud ---------- */
.hud{display:grid;grid-template-columns:1fr 1fr 1.4fr;gap:8px}
.stat{background:linear-gradient(180deg,var(--panel) 0%,var(--ink2) 100%);
  border:1px solid var(--line);border-radius:12px;padding:8px 10px;min-width:0}
.stat label{display:block;font-size:9px;letter-spacing:.18em;text-transform:uppercase;color:var(--mute);margin-bottom:2px}
.stat b{font-size:20px;font-weight:800;letter-spacing:-.01em;display:block;line-height:1.1;
  overflow:hidden;text-overflow:ellipsis}
.stat.low b{color:var(--ruby)}

/* ---------- goals ---------- */
.goals{display:flex;gap:8px;flex-wrap:wrap;min-height:0}
.goal{display:flex;align-items:center;gap:7px;background:var(--ink2);border:1px solid var(--line);
  border-radius:10px;padding:5px 10px 5px 6px;font-size:12px;font-weight:700;color:var(--mute)}
.goal svg{width:20px;height:20px;flex:none}
.goal.met,.goal.note{border-color:var(--gold-dim);color:var(--gold)}
.goal.met::after{content:"✓";font-size:12px}
.goal .txt{font-size:11px;letter-spacing:.06em}

.bar{height:5px;border-radius:999px;background:var(--ink2);border:1px solid var(--line);overflow:hidden}
.bar i{display:block;height:100%;width:0%;border-radius:999px;
  background:linear-gradient(90deg,var(--violet),var(--aqua) 55%,var(--gold));
  transition:width .35s cubic-bezier(.2,.8,.3,1)}

/* ---------- board ---------- */
.boardwrap{position:relative;align-self:center;
  padding:9px;border-radius:20px;
  background:linear-gradient(180deg,var(--panel) 0%,#0d1225 100%);
  border:1px solid var(--line);
  box-shadow:0 22px 60px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.05);
}
.boardwrap::before{content:"";position:absolute;inset:4px;border-radius:15px;
  border:1px solid rgba(232,195,122,.16);pointer-events:none}
#board{position:relative;touch-action:none;border-radius:12px;overflow:hidden;
  background:
    repeating-conic-gradient(rgba(255,255,255,.022) 0% 25%, transparent 0% 50%) 0 0/ calc(var(--s)*2) calc(var(--s)*2);
}
.tile{position:absolute;left:0;top:0;width:var(--s);height:var(--s);
  display:grid;place-items:center;will-change:transform;
  transition:transform .28s cubic-bezier(.34,1.3,.5,1);}
.tile svg{width:84%;height:84%;overflow:visible;display:block;
  transition:transform .16s ease, filter .16s ease}
.noanim .tile{transition:none!important}
.tile.sel svg{transform:scale(1.16)}
.tile.sel::after{content:"";position:absolute;inset:7%;border-radius:12px;
  border:2px solid var(--gold);box-shadow:0 0 16px rgba(232,195,122,.45)}
.tile.pop svg{transform:scale(.15) rotate(28deg);filter:brightness(2.4)}
.tile.pop{opacity:0;transition:opacity .22s ease}
.tile.birth svg{animation:birth .42s cubic-bezier(.2,1.6,.4,1)}
.tile.bad svg{animation:bad .3s ease}
@keyframes birth{0%{transform:scale(.2) rotate(-40deg)}60%{transform:scale(1.22)}100%{transform:scale(1)}}
@keyframes bad{0%,100%{transform:translateX(0)}25%{transform:translateX(-16%)}75%{transform:translateX(16%)}}

.spark{position:absolute;width:8px;height:8px;border-radius:50%;pointer-events:none;
  transition:transform .55s cubic-bezier(.2,.7,.3,1),opacity .55s ease}
.beam{position:absolute;pointer-events:none;background:linear-gradient(90deg,transparent,#fff,transparent);
  opacity:.9;animation:beam .4s ease-out forwards}
@keyframes beam{to{opacity:0;filter:blur(4px)}}

.combo{position:absolute;left:50%;top:44%;transform:translate(-50%,-50%);pointer-events:none;
  font-weight:900;letter-spacing:.06em;text-align:center;opacity:0;white-space:nowrap;
  text-shadow:0 4px 24px rgba(0,0,0,.8)}
.combo.go{animation:combo .75s cubic-bezier(.2,.9,.3,1)}
@keyframes combo{0%{opacity:0;transform:translate(-50%,-30%) scale(.6)}
  22%{opacity:1;transform:translate(-50%,-50%) scale(1.12)}
  70%{opacity:1;transform:translate(-50%,-52%) scale(1)}
  100%{opacity:0;transform:translate(-50%,-88%) scale(.94)}}

/* ---------- overlay ---------- */
/* .ov sets display:grid, which outranks the UA [hidden]{display:none} rule —
   without the line below the overlay never hides and covers the whole board. */
.ov[hidden]{display:none}
/* Flex + margin:auto centres short panels but lets tall ones scroll instead of
   spilling out over the footer. place-items:center on a grid clips them. */
.ov{position:absolute;inset:0;z-index:5;display:flex;padding:16px;
  overflow-y:auto;overscroll-behavior:contain;
  background:rgba(6,9,20,.88);backdrop-filter:blur(7px);border-radius:20px;text-align:center;
  animation:fade .28s ease}
.ov > div{margin:auto;width:100%;max-width:340px}
@keyframes fade{from{opacity:0}to{opacity:1}}
.ov h2{font-size:26px;font-weight:900;letter-spacing:.06em;margin-bottom:6px}
.ov p{font-size:13px;color:var(--mute);line-height:1.55;max-width:290px;margin:0 auto 12px}
.ov .big{font-size:34px;font-weight:900;color:var(--gold);letter-spacing:-.02em;margin:2px 0 10px}
.ov ul{text-align:left;font-size:12.5px;color:var(--mute);line-height:1.85;
  max-width:300px;margin:0 auto 16px;list-style:none}
.ov ul b{color:var(--text)}
.row{display:flex;gap:8px;justify-content:center;flex-wrap:wrap}
button.act{font:inherit;font-weight:800;font-size:13px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink);background:linear-gradient(180deg,var(--gold),#c79f56);border:0;border-radius:11px;
  padding:11px 20px;cursor:pointer;box-shadow:0 6px 18px rgba(232,195,122,.24)}
button.act.ghost{background:none;color:var(--mute);box-shadow:none;border:1px solid var(--line)}
button.act:hover{filter:brightness(1.08)}
button.act:active{transform:translateY(1px)}

/* ---------- footer ---------- */
footer{display:flex;gap:8px;justify-content:center;flex-wrap:wrap}
footer button{font:inherit;font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--mute);background:var(--ink2);border:1px solid var(--line);border-radius:9px;
  padding:8px 13px;cursor:pointer}
footer button:hover{color:var(--text);border-color:var(--gold-dim)}
.toast{position:fixed;left:50%;bottom:22px;transform:translateX(-50%) translateY(20px);
  background:var(--panel2);border:1px solid var(--line);color:var(--text);
  padding:10px 16px;border-radius:11px;font-size:12.5px;font-weight:600;opacity:0;
  transition:.3s cubic-bezier(.2,.9,.3,1);pointer-events:none;z-index:20}
.toast.on{opacity:1;transform:translateX(-50%) translateY(0)}
:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;transition-duration:.06s!important}}

/* ---------- provenance strip ---------- */
.seed{
  text-align:center;font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  /* Same trap as .tagline, worse: .65 opacity put this at 3.05:1, and this is
     the board-number line people screenshot and share. Now 5.32:1. */
  color:var(--mute);font-variant-numeric:tabular-nums;
}

/* ---------- landing squash ---------- */
@keyframes land{0%{transform:scaleY(1)}
  32%{transform:scaleY(.76) translateY(11%)}
  66%{transform:scaleY(1.06) translateY(-2%)}
  100%{transform:scaleY(1)}}
.tile.land svg{animation:land .22s cubic-bezier(.3,.9,.4,1)}

/* ---------- idle hint ---------- */
@keyframes hintpulse{0%,100%{transform:scale(1);filter:none}
  50%{transform:scale(1.14);filter:brightness(1.35) drop-shadow(0 0 10px rgba(232,195,122,.75))}}
.tile.hint svg{animation:hintpulse 1.15s ease-in-out infinite}
.tile.hint::after{content:"";position:absolute;inset:8%;border-radius:12px;
  border:2px solid rgba(232,195,122,.55);animation:hintpulse 1.15s ease-in-out infinite}

/* ---------- score fly-up ---------- */
.flyscore{position:fixed;transform:translate(-50%,-50%);z-index:30;pointer-events:none;
  font-weight:900;font-size:17px;letter-spacing:-.01em;color:var(--gold);
  font-variant-numeric:tabular-nums;text-shadow:0 2px 10px rgba(0,0,0,.9);
  transition:transform .62s cubic-bezier(.45,.05,.3,1),opacity .62s ease}

/* ---------- tutorial coach bar ---------- */
/* Same trap as .ov — a class-level display beats the UA [hidden] rule. */
.coach[hidden]{display:none}
.coach{position:absolute;left:9px;right:9px;bottom:9px;z-index:4;
  display:flex;align-items:center;gap:10px;
  background:linear-gradient(180deg,rgba(28,37,66,.97),rgba(13,18,37,.97));
  border:1px solid var(--gold-dim);border-radius:12px;padding:11px 12px;
  font-size:12.5px;line-height:1.45;color:var(--text);
  box-shadow:0 10px 30px rgba(0,0,0,.6);animation:coachIn .35s cubic-bezier(.2,.9,.3,1)}
.coach b{color:var(--gold)}
.coach button{flex:none;font:inherit;font-size:10px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--mute);background:none;border:1px solid var(--line);
  border-radius:8px;padding:6px 9px;cursor:pointer}
.coach button:hover{color:var(--text);border-color:var(--gold-dim)}
@keyframes coachIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}

/* ---------- per-mode identity ----------
   Only the ROOM changes: accent colour, background wash, board panel tint.
   The gems never change shape or colour — those are the game's alphabet, and
   colour-blind players navigate by silhouette. Reskinning them would trade a
   real accessibility win for a cosmetic one. */
body{transition:background .6s ease}

body[data-mode="daily"]{
  --gold:#cfa9ff; --gold-dim:#6f4fa8;
  background:
    radial-gradient(1200px 600px at 50% -10%, #2b1f52 0%, transparent 60%),
    radial-gradient(800px 500px at 100% 100%, #3a1f4d 0%, transparent 55%),
    #0a0714;
}
body[data-mode="daily"] .boardwrap{background:linear-gradient(180deg,#1d1636 0%,#120c22 100%)}

/* Blitz runs hot — embers, tighter glow, a board that feels like it's under pressure */
body[data-mode="blitz"]{
  --gold:#ff9147; --gold-dim:#9c4a1e;
  background:
    radial-gradient(1200px 600px at 50% -10%, #4a2118 0%, transparent 62%),
    radial-gradient(800px 500px at 100% 100%, #3d1230 0%, transparent 55%),
    #120806;
}
body[data-mode="blitz"] .boardwrap{background:linear-gradient(180deg,#2a1510 0%,#150a08 100%)}
body[data-mode="blitz"] .stat.low b{color:#ff5a3d}

/* Zen cools down — deep teal, glacial, nothing urgent */
body[data-mode="zen"]{
  --gold:#71e6d2; --gold-dim:#2f7a70;
  background:
    radial-gradient(1200px 600px at 50% -10%, #0e3a44 0%, transparent 60%),
    radial-gradient(800px 500px at 100% 100%, #14324a 0%, transparent 55%),
    #04101a;
}
body[data-mode="zen"] .boardwrap{background:linear-gradient(180deg,#0e2a35 0%,#061620 100%)}

/* ---------- shareable result grid ---------- */
.cardhint{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;
  color:var(--mute);text-align:center;margin:-4px auto 11px;max-width:250px;line-height:1.4}

/* The drawn card. Its own background is baked into the PNG, so unlike the text
   grid it looks the same in every chat app and every theme. */
/* 210px, not 250. The card is the reward; SUBMIT is the point. On a 411x750
   phone the larger card pushed the name field below the fold, so a finished run
   never reached the leaderboard — the panel looked complete without it. */
.cardimg{display:block;width:100%;max-width:210px;margin:2px auto 9px;
  border-radius:16px;border:1px solid var(--line);
  box-shadow:0 14px 38px rgba(0,0,0,.6)}

/* ---------- score submission + leaderboard ---------- */
.submit{display:flex;gap:7px;justify-content:center;margin:0 auto 11px;max-width:320px}
.submit input{flex:1;min-width:0;font:inherit;font-size:13px;color:var(--text);
  background:var(--ink2);border:1px solid var(--line);border-radius:11px;padding:10px 12px}
.submit input:focus{outline:none;border-color:var(--gold-dim)}
.submit button{flex:none;padding:10px 14px}
.submit button:disabled{opacity:.75;cursor:default}

ol.board{list-style:none;text-align:left;max-width:320px;margin:0 auto 14px;
  font-variant-numeric:tabular-nums}
ol.board li{display:flex;align-items:center;gap:10px;padding:7px 10px;
  border-bottom:1px solid var(--line);font-size:13px}
ol.board li:last-child{border-bottom:0}
ol.board .n{width:22px;color:var(--mute);font-size:11px;text-align:right}
ol.board .w{flex:1;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
ol.board .s{font-weight:800;color:var(--gold)}
ol.board .empty{color:var(--mute);justify-content:center}

/* ---------- stats panel ---------- */
/* Two columns: a seven-row list pushed the Back button below the fold. */
ul.stats{list-style:none;max-width:310px;margin:0 auto 12px;
  display:grid;grid-template-columns:1fr 1fr;gap:6px 10px}
ul.stats li{display:flex;flex-direction:column;align-items:flex-start;gap:0;
  padding:5px 9px;background:rgba(0,0,0,.28);border:1px solid var(--line);border-radius:9px}
ul.stats span{color:var(--mute);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase}
ul.stats b{font-weight:800;font-size:15px;font-variant-numeric:tabular-nums}
.strip{display:flex;gap:3px;justify-content:center;margin:8px auto 10px;max-width:300px}
.strip i{flex:1;height:18px;border-radius:3px;background:var(--ink2);
  border:1px solid var(--line);max-width:8px}
.strip i.on{background:var(--gold);border-color:var(--gold);box-shadow:0 0 7px rgba(232,195,122,.4)}

/* Short viewports: tighten the record panel so less scrolling is needed. */
@media (max-height:820px){
  .ov h2{font-size:22px}
  .strip i{height:14px}
  ul.stats b{font-size:14px}
  ul.stats li{padding:4px 8px}
  .ov ul{line-height:1.6}
}

/* ---------- leaderboard tabs ---------- */
/* Deliberately NOT the pill treatment used by the mode selector at the top of
   the page. When both rows looked identical, players read the highlighted mode
   pill as the leaderboard's selection and thought the board had defaulted to
   Quest. Underline tabs read as "a section of this panel" instead. */
.tabs{display:flex;gap:1px;justify-content:center;margin:0 auto 6px;max-width:320px;
  border-bottom:1px solid var(--line)}
.tabs .tab{flex:1;white-space:nowrap;font:inherit;font-size:9px;font-weight:800;letter-spacing:.03em;
  text-transform:uppercase;color:var(--mute);background:none;border:0;
  border-bottom:2px solid transparent;margin-bottom:-1px;padding:7px 3px;cursor:pointer}
.tabs .tab:hover{color:var(--text)}
.tabs .tab.on{color:var(--gold);border-bottom-color:var(--gold)}

/* While any overlay is open the mode row is not what the player is interacting
   with, so stop it competing for attention. */
body.ovopen .modes{opacity:.3;pointer-events:none;transition:opacity .2s ease}
.ov p.sub{font-size:11px;letter-spacing:.08em;text-transform:uppercase;margin-bottom:10px}
ol.board .m{color:var(--mute);font-size:10.5px;font-weight:700;min-width:38px;text-align:right;letter-spacing:.04em}

.ov p.ask{font-size:11.5px;color:var(--mute);margin:0 auto 7px;max-width:280px;line-height:1.4}

/* ---------- daily archive navigation ---------- */
.daynav{display:flex;align-items:center;justify-content:center;gap:12px;margin:0 auto 4px}
.daynav span{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--text);
  font-weight:700;min-width:104px}
.daynav button{font:inherit;font-size:15px;line-height:1;color:var(--mute);background:var(--ink2);
  border:1px solid var(--line);border-radius:8px;padding:4px 11px;cursor:pointer}
.daynav button:hover:not(:disabled){color:var(--gold);border-color:var(--gold-dim)}
.daynav button:disabled{opacity:.25;cursor:default}

/* ---------- inline result card ---------- */

