/* Layout: one narrow column built like a desk calculator. The physical parts
   (keys, LCD, paper tape) look the same in both themes; the room around them changes. */
:root {
  /* room */
  --bg: #e5e6df;
  --panel: #f4f4ef;
  --line: #c8cac0;
  --ink: #1b1d19;
  --muted: #5f6358;
  /* calculator body */
  --body: #2c2e29;
  --body-2: #3a3d36;
  --body-ink: #eceee6;
  --body-muted: #a3a798;
  /* keys */
  --key: #fbfbf6;
  --key-ink: #1b1d19;
  --key-edge: #b3b5aa;
  --op: #3b3e36;
  --op-ink: #f2f3ec;
  --op-edge: #1c1e1a;
  --yellow: #f3b80c;
  --yellow-edge: #b48600;
  --yellow-ink: #1b1d19;
  --ring: #c08f00;
  /* display and tape */
  --lcd: #b3bf9b;
  --lcd-ink: #1e2617;
  --lcd-ghost: rgba(30, 38, 23, 0.09);
  --paper: #fcfbf4;
  --paper-ink: #2a2a25;
  --paper-muted: #8b897c;
  --paper-red: #bf3326;
  --paper-rule: #e2dfd0;
  /* meaning */
  --good: #2e8a4f;
  --good-edge: #1d6136;
  --star: #b07d00;
  --backdrop: rgba(20, 22, 18, 0.5);
  --shadow: rgba(20, 22, 18, 0.12);
  --error: #bf3326;
  /* desk surface (skins.css swaps these) */
  --card: #f0f0ea;
  --tex: none;
  --tex-size: auto;
  /* type */
  --f-ui: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --f-tape: "Courier Prime", "Courier New", Courier, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #151613;
    --panel: #1f211c;
    --line: #34372f;
    --ink: #ebece4;
    --muted: #9b9f92;
    --body: #23251f;
    --body-2: #30332b;
    --body-ink: #eceee6;
    --body-muted: #9b9f92;
    --key: #e3e3da;
    --key-ink: #1b1d19;
    --key-edge: #7d8075;
    --op: #44473e;
    --op-ink: #f2f3ec;
    --op-edge: #0b0c0a;
    --yellow: #f5bd1f;
    --yellow-edge: #a87e00;
    --yellow-ink: #1b1d19;
    --ring: #f5bd1f;
    --lcd: #9dab86;
    --lcd-ink: #1a2213;
    --lcd-ghost: rgba(26, 34, 19, 0.1);
    --paper: #e2dfd0;
    --paper-ink: #22221e;
    --paper-muted: #6f6d62;
    --paper-red: #ad2c20;
    --paper-rule: #cbc7b6;
    --good: #4cb874;
    --good-edge: #2b7a48;
    --star: #f5bd1f;
    --backdrop: rgba(0, 0, 0, 0.65);
    --shadow: rgba(0, 0, 0, 0.4);
    --error: #ff8f80;
    --card: #1c1e19;
    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --bg: #151613;
  --panel: #1f211c;
  --line: #34372f;
  --ink: #ebece4;
  --muted: #9b9f92;
  --body: #23251f;
  --body-2: #30332b;
  --body-ink: #eceee6;
  --body-muted: #9b9f92;
  --key: #e3e3da;
  --key-ink: #1b1d19;
  --key-edge: #7d8075;
  --op: #44473e;
  --op-ink: #f2f3ec;
  --op-edge: #0b0c0a;
  --yellow: #f5bd1f;
  --yellow-edge: #a87e00;
  --yellow-ink: #1b1d19;
  --ring: #f5bd1f;
  --lcd: #9dab86;
  --lcd-ink: #1a2213;
  --lcd-ghost: rgba(26, 34, 19, 0.1);
  --paper: #e2dfd0;
  --paper-ink: #22221e;
  --paper-muted: #6f6d62;
  --paper-red: #ad2c20;
  --paper-rule: #cbc7b6;
  --good: #4cb874;
  --good-edge: #2b7a48;
  --star: #f5bd1f;
  --backdrop: rgba(0, 0, 0, 0.65);
  --shadow: rgba(0, 0, 0, 0.4);
  --error: #ff8f80;
  --card: #1c1e19;
  color-scheme: dark;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
/* No double-tap-to-zoom: on phones it swallowed the second of two quick taps
   (like confirming Finish, or tapping a number twice). Pinch zoom still works. */
html { -webkit-text-size-adjust: 100%; touch-action: manipulation; }
button { touch-action: manipulation; }

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  /* the desk: its texture stays still while you scroll (phones that don't support that just scroll it) */
  background-color: var(--bg);
  background-image: var(--tex);
  background-size: var(--tex-size);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--f-ui);
  font-size: 15px;
  line-height: 1.45;
}

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }

h1, h2, h3 { text-wrap: balance; }
.muted { color: var(--muted); }

.app {
  max-width: 460px;
  margin: 0 auto;
  padding-block: 18px 32px;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.label, .eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.label { color: var(--muted); }

/* ---------- Keys (every button is a calculator key) ---------- */
.btn {
  --k: var(--key);
  --ki: var(--key-ink);
  --ke: var(--key-edge);
  height: 50px;
  padding: 0 14px;
  border: none;
  border-radius: 10px;
  background: var(--k);
  color: var(--ki);
  box-shadow: 0 3px 0 var(--ke), 0 5px 10px var(--shadow);
  font-size: 15px;
  font-weight: 700;
  white-space: nowrap;
  transition: transform 0.06s, box-shadow 0.06s, background-color 0.15s;
}
.btn:not(:disabled):active { transform: translateY(3px); box-shadow: 0 0 0 var(--ke), 0 1px 2px var(--shadow); }
.btn.primary { --k: var(--yellow); --ki: var(--yellow-ink); --ke: var(--yellow-edge); }
.btn.dark, .btn.armed { --k: var(--op); --ki: var(--op-ink); --ke: var(--op-edge); }
.btn.ghost { background: transparent; box-shadow: none; color: var(--muted); }
.btn.big { width: 100%; height: 52px; font-size: 16px; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.icon-btn {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: transparent;
  font-size: 17px;
  font-weight: 800;
}
.icon-btn svg { width: 20px; height: 20px; }

/* ---------- LCD with seven-segment digits ---------- */
.lcd {
  padding: 8px 12px 12px;
  border-radius: 6px;
  background: var(--lcd);
  color: var(--lcd-ink);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.28), inset 0 0 0 1px rgba(0, 0, 0, 0.18);
}
.annun { display: flex; gap: 14px; min-height: 12px; }
.ann {
  font-size: 10px;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.13;
}
.ann.on { opacity: 0.9; }
#exactAnn { margin-left: auto; }
.lcd.dual { display: grid; grid-template-columns: auto 1fr; gap: 0 18px; }
.lcd.dual .reg + .reg { padding-left: 16px; border-left: 1px solid var(--lcd-ghost); }
.segs { display: flex; justify-content: flex-end; gap: 7px; height: 52px; margin-top: 6px; }
.segs.big { height: 84px; gap: 9px; }
.segs svg { height: 100%; width: auto; overflow: visible; }
.segs .s { fill: var(--lcd-ghost); }
.segs .s.on { fill: var(--lcd-ink); }

/* ---------- Menu ---------- */
.home-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; padding-top: 6px; }
/* ---------- Logo: a little calculator showing "6 TALLY" ----------
   Built from the calculator colors, so it matches whichever calculator the player has on.
   Sized in em: change .logo's font-size to scale the whole thing. */
.logo { margin: 0; min-width: 0; font-size: clamp(21px, 6.6vw, 27px); line-height: 1; }
.logo-body {
  display: inline-block;
  padding: 0.2em;
  border-radius: 0.4em;
  background: var(--body);
  box-shadow: 0 3px 8px var(--shadow);
}
.logo-lcd {
  display: flex;
  align-items: center;
  gap: 0.28em;
  padding: 0.24em 0.5em 0.24em 0.36em;
  border-radius: 0.22em;
  background: var(--lcd);
  color: var(--lcd-ink);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.28), inset 0 0 0 1px rgba(0, 0, 0, 0.18);
}
.logo-six { height: 1.3em; width: auto; overflow: visible; }
.logo-six .ghost { fill: var(--lcd-ghost); }
.logo-six .lit { fill: var(--lcd-ink); stroke: var(--lcd-ink); stroke-width: 3.5; stroke-linejoin: round; } /* the stroke thickens it to match the bold letters */
.logo-word { font-size: 1.12em; font-weight: 900; font-stretch: 112%; letter-spacing: 0.03em; }
.logo-word span { display: inline-block; }

/* Switching on, once per page load: the screen flickers on, the 6 draws itself segment by
   segment, TALLY types in like digits, then the display blinks twice like a finished sum. */
/* Each piece only hides while it waits (fill "backwards"), so the logo always ends fully lit
   even if a phone cuts the animation short. The delays are plain values, because an iPhone
   left the first piece of each group dark when they were worked out with calc(). */
@media (prefers-reduced-motion: no-preference) {
  .logo-lcd { animation: logo-power 0.45s steps(1) backwards; }
  .logo-six .lit polygon, .logo-word span { animation: logo-key 0.1s steps(1) 0.4s backwards; }
  .logo-six .lit polygon:nth-child(2) { animation-delay: 0.47s; }
  .logo-six .lit polygon:nth-child(3) { animation-delay: 0.54s; }
  .logo-six .lit polygon:nth-child(4) { animation-delay: 0.61s; }
  .logo-six .lit polygon:nth-child(5) { animation-delay: 0.68s; }
  .logo-six .lit polygon:nth-child(6) { animation-delay: 0.75s; }
  .logo-word span:nth-child(1) { animation-delay: 0.85s; }
  .logo-word span:nth-child(2) { animation-delay: 0.94s; }
  .logo-word span:nth-child(3) { animation-delay: 1.03s; }
  .logo-word span:nth-child(4) { animation-delay: 1.12s; }
  .logo-word span:nth-child(5) { animation-delay: 1.21s; }
  .logo-six .lit, .logo-word { animation: logo-blink 0.56s steps(1) 1.4s backwards; }
  /* Back from a game: the logo is already on (game.js, showHome) */
  .logo.played .logo-body * { animation: none; }
}
@keyframes logo-power {
  0% { filter: brightness(0.55) saturate(0.6); }
  25% { filter: brightness(1.08); }
  45% { filter: brightness(0.7) saturate(0.7); }
  70%, 100% { filter: none; }
}
@keyframes logo-key { from { opacity: 0; } to { opacity: 1; } }
@keyframes logo-blink {
  0%, 50% { opacity: 1; }
  25%, 75% { opacity: 0.12; }
  100% { opacity: 1; }
}
.head-links { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: none; }
.links-row { display: flex; gap: 2px; }
.head-links button {
  padding: 6px 8px;
  border: none;
  background: none;
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.head-links .acct {
  max-width: 100px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--ink);
  text-decoration: none;
}
.head-links .acct.in::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--good);
  vertical-align: 1px;
}
.lede { margin: -6px 0 0; max-width: 34ch; color: var(--muted); font-size: 16px; }

.banner { padding: 10px 12px; border-radius: 8px; border: 1px solid var(--ring); font-size: 14px; }
.banner a { color: inherit; font-weight: 700; }

.daily {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  border-radius: 18px;
  background: var(--body);
  color: var(--body-ink);
  box-shadow: 0 10px 24px var(--shadow);
}
.daily-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 13px; color: var(--body-muted); }
.daily .eyebrow { color: var(--body-accent, var(--yellow)); }
.daily-status { margin: 0; color: var(--body-muted); }
.daily-status b { color: var(--body-ink); font-variant-numeric: tabular-nums; }
.dots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.dots span {
  padding: 6px 4px;
  border-radius: 6px;
  background: var(--body-2);
  color: var(--body-muted);
  font-size: 12px;
  font-weight: 600;
  text-align: center;
}
.dots span.done { color: var(--body-accent, var(--yellow)); letter-spacing: 1px; }

/* Each mode is a card lying on the desk */
.mode {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px;
  border-radius: 14px;
  background: var(--card);
  box-shadow: 0 0 0 1px var(--line), 0 6px 16px var(--shadow);
}
.mode-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.mode h2 { margin: 0; font-size: 20px; font-weight: 800; font-stretch: 112%; }
.mode p { margin: 0; color: var(--muted); }
.best { font-size: 13px; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }

.row { display: flex; gap: 10px; margin-top: 4px; }
.row .btn.big { flex: 1; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ---------- Menu: each mode is a different object on the desk ---------- */

/* Endless: a strip of adding-machine tape, torn at both ends (it follows the player's tape) */
.tape-card { filter: drop-shadow(0 6px 10px var(--shadow)); }
.tape-paper {
  --zz: 12px; /* width of one torn tooth */
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 22px 18px 24px;
  background-color: var(--paper);
  background-image: var(--paper-tex, none);
  background-size: var(--paper-tex-size, auto);
  color: var(--paper-ink);
  font-family: var(--f-tape);
  -webkit-mask:
    conic-gradient(from 135deg at top, #0000, #000 1deg 89deg, #0000 90deg) top / var(--zz) 51% repeat-x,
    conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) bottom / var(--zz) 51% repeat-x;
  mask:
    conic-gradient(from 135deg at top, #0000, #000 1deg 89deg, #0000 90deg) top / var(--zz) 51% repeat-x,
    conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) bottom / var(--zz) 51% repeat-x;
}
.tape-head { display: flex; justify-content: space-between; align-items: center; padding-bottom: 8px; border-bottom: 2px solid var(--paper-ink); }
.tape-head h2 { margin: 0; font-family: var(--f-ui); font-size: 20px; font-weight: 800; font-stretch: 112%; letter-spacing: 0.06em; text-transform: uppercase; }
.tape-inf { font-family: var(--f-ui); font-size: 30px; font-weight: 800; line-height: 0.8; color: var(--paper-red); }
.tape-lines { display: flex; flex-direction: column; gap: 7px; margin: 0; padding: 0; list-style: none; font-size: 14px; font-weight: 700; text-transform: uppercase; }
.tape-lines li { display: flex; justify-content: space-between; gap: 10px; padding-bottom: 6px; border-bottom: 1px dashed var(--paper-rule); }
.tape-lines .dim { color: var(--paper-muted); font-weight: 400; }
.tape-total { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding-top: 6px; border-top: 2px solid var(--paper-ink); color: var(--paper-red); font-size: 14px; font-weight: 700; text-transform: uppercase; }
.tape-total b { font-size: 28px; line-height: 1; font-variant-numeric: tabular-nums; }
.tape-paper .btn { font-family: var(--f-ui); }
/* new lines print in one after another, like the tape in a game */
@media (prefers-reduced-motion: no-preference) {
  .tape-lines.fresh li { animation: print 0.35s steps(14) calc(var(--p0, 0s) + var(--i) * 0.18s) both; }
}

/* Rush: a kitchen timer in the calculator's own yellow (the = key), with a black LED window.
   It's a physical object, so it looks the same in both themes. */
.timer-card {
  --t-body: #f3b80c;
  --t-edge: #b48600;
  --t-ink: #1b1d19;
  --t-muted: rgba(27, 29, 25, 0.74);
  --t-well: rgba(110, 76, 0, 0.2);
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 8px;
  padding: 16px 16px 20px;
  border-radius: 22px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0) 38%), var(--t-body);
  color: var(--t-ink);
  box-shadow: inset 0 -5px 0 var(--t-edge), 0 10px 22px var(--shadow);
}
.timer-card::before { /* the knob on top */
  content: "";
  position: absolute;
  top: -9px;
  left: 50%;
  width: 60px;
  height: 14px;
  margin-left: -30px;
  border-radius: 7px 7px 2px 2px;
  background: linear-gradient(180deg, #4a4d45, #2c2e29);
}
.timer-card h2 { margin: 0; font-size: 20px; font-weight: 800; font-stretch: 112%; letter-spacing: 0.06em; text-transform: uppercase; }
.timer-card .best { color: var(--t-muted); }
.timer-card p { margin: 0; color: var(--t-muted); }
.timer-lcd {
  --lcd-ink: #ffc933;
  --lcd-ghost: rgba(255, 201, 51, 0.08);
  display: flex;
  justify-content: center;
  padding: 14px 10px 16px;
  border-radius: 12px;
  background: #151612;
  box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.6), 0 0 0 3px var(--t-edge);
}
.timer-lcd .segs { height: 62px; margin: 0; gap: 8px; justify-content: center; }
.timer-lcd .s.on { filter: drop-shadow(0 0 3px rgba(255, 190, 40, 0.45)); }
.timer-lcd .colon { display: flex; flex-direction: column; justify-content: center; gap: 16px; margin: 0 2px; }
.timer-lcd .colon::before, .timer-lcd .colon::after { content: ""; width: 8px; height: 8px; border-radius: 2px; background: var(--lcd-ink); transform: skewX(-6deg); }
.timer-card.live .colon { animation: blink 1s steps(2, jump-none) infinite; }
.timer-card .len-pick { background: var(--t-well); }
.timer-card .len-pick button { color: var(--t-ink); }
.timer-card .len-pick button.on { background: #2c2e29; color: #f2f3ec; }
.timer-card .stepper small { color: var(--t-muted); }
.timer-card .btn.dark { --k: #2c2e29; --ki: #f2f3ec; --ke: #10110e; }
.timer-card .btn:not(.dark) { --k: #fbfbf6; --ki: #1b1d19; --ke: var(--t-edge); }

/* Leaderboard: a black card in both themes, with today's top three on a podium of calculator keys */
.board-card {
  --card: #141512;
  --line: #2e3129;
  --ink: #ebece4;
  --muted: #9b9f92;
  --key: #e3e3da;
  --key-ink: #1b1d19;
  --key-edge: #7d8075;
  --yellow: #f5bd1f;
  --yellow-edge: #a87e00;
  --yellow-ink: #1b1d19;
  --ring: #f5bd1f;
  --star: #f5bd1f;
  color: var(--ink);
  color-scheme: dark;
  box-shadow: 0 0 0 1px var(--line), 0 10px 24px rgba(10, 11, 9, 0.28);
}
.board-card .podium .key, .board-card .btn { --shadow: rgba(0, 0, 0, 0.45); }
.board-card h2, .shop-card h2 { letter-spacing: 0.06em; text-transform: uppercase; }
.podium { display: grid; grid-template-columns: repeat(3, 1fr); align-items: end; gap: 8px; margin: 6px 0 0; padding: 0; list-style: none; }
.podium li { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
.podium .who { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 700; line-height: 1.3; text-align: center; }
.podium .who small { display: block; color: var(--muted); font-family: var(--f-tape); font-size: 12px; font-weight: 400; white-space: normal; }
.podium .me .who { color: var(--ring); }
.podium .p1 .who::before { content: "★"; display: block; color: var(--star); font-size: 16px; }
.podium .key {
  width: 100%;
  display: grid;
  place-items: center;
  padding-bottom: 5px;
  border-radius: 10px 10px 4px 4px;
  background: var(--key);
  color: var(--key-ink);
  box-shadow: inset 0 -5px 0 var(--key-edge), 0 4px 8px var(--shadow);
  font-size: 26px;
  font-weight: 900;
  font-stretch: 112%;
}
.podium .p1 .key { height: 84px; background: var(--yellow); color: var(--yellow-ink); box-shadow: inset 0 -5px 0 var(--yellow-edge), 0 4px 8px var(--shadow); }
.podium .p2 .key { height: 62px; }
.podium .p3 .key { height: 46px; }

/* Shop: calculators from the shop on a shelf, each with a paper price tag hanging from the edge */
.shelf { display: grid; grid-template-columns: repeat(3, 1fr); align-items: start; margin: 6px 0 2px; }
.shelf-item { display: flex; flex-direction: column; align-items: center; min-width: 0; }
.shelf-item .pv { display: flex; justify-content: center; align-self: stretch; padding: 0 9px; }
.shelf-item .mini { width: 100%; max-width: 96px; }
.ledge { /* one piece of the shelf; the three meet in a single plank */
  align-self: stretch;
  height: 9px;
  background: var(--key-edge);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.35), 0 4px 6px var(--shadow);
}
.shelf-item:first-child .ledge { border-radius: 3px 0 0 3px; }
.shelf-item:last-child .ledge { border-radius: 0 3px 3px 0; }
.tag {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  max-width: calc(100% - 12px);
  margin-top: 9px;
  padding: 7px 8px 6px;
  border-radius: 3px;
  background: var(--paper);
  color: var(--paper-muted);
  box-shadow: 0 2px 5px var(--shadow);
  font-family: var(--f-tape);
  font-size: 11px;
  line-height: 1.2;
  text-align: center;
  text-transform: uppercase;
  transform: rotate(var(--r, 0deg));
  transform-origin: 50% -9px;
}
.tag::before { /* the string it hangs from */
  content: "";
  position: absolute;
  bottom: 100%;
  left: 50%;
  width: 1.5px;
  height: 10px;
  background: var(--paper-muted);
}
.tag::after { /* the punched hole */
  content: "";
  position: absolute;
  top: 3px;
  left: 50%;
  width: 4px;
  height: 4px;
  margin-left: -1.25px;
  border-radius: 50%;
  background: var(--card);
}
.tag b { display: inline-flex; align-items: center; gap: 4px; color: var(--paper-ink); font-size: 14px; }
.tag.owned b { color: var(--good); }
@media (prefers-reduced-motion: no-preference) {
  .shelf-item .mini, .tag { transition: transform 0.25s; }
  .shop-card:hover .shelf-item .mini { transform: translateY(-3px); }
  .shop-card:hover .tag { transform: rotate(calc(var(--r, 0deg) * -1)); }
}

/* ---------- Game: top bar ---------- */
#gameView { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
.bar {
  position: sticky;
  top: 0;
  z-index: 10;
  width: 100%;
  max-width: 460px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 40px 1fr 40px;
  align-items: center;
  gap: 12px;
  padding-block: 10px;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.bar-title { display: flex; flex-direction: column; align-items: center; line-height: 1.2; min-width: 0; }
.bar-title b { font-size: 16px; font-weight: 800; font-stretch: 112%; }
.bar-title span { font-size: 13px; color: var(--muted); }

.app.game { flex: 1; width: 100%; padding-top: 2px; padding-bottom: 20px; gap: 12px; }
/* The game is pinned to the visible screen, so the keys never get pushed down and the top bar
   (with the way back to the menu) can't end up scrolled out of reach. The tape takes the room
   that's left and scrolls (game.js keeps its newest line in view); if even that isn't enough,
   the middle part scrolls. Very short screens just scroll the page. */
@media (min-height: 560px) {
  /* --vv-top / --vv-h: the visible area, kept up to date by game.js (falls back to the whole window) */
  #gameView { position: fixed; left: 0; right: 0; top: var(--vv-top, 0px); height: var(--vv-h, 100%); min-height: 0; overflow: hidden; }
  /* While a game is open the page underneath doesn't scroll (dragging it made the browser's
     toolbars grow and shrink, which jolted the game). Only the tape, and the middle if it's
     ever too tall, scroll. */
  html.in-game, html.in-game body { overflow: hidden; overscroll-behavior: none; }
  html.in-game body { height: 100%; min-height: 0; }
  .app.game { min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
  .app.game > * { flex-shrink: 0; }
  .app.game > .tape-wrap { flex-shrink: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; }
  .tape-wrap::-webkit-scrollbar { display: none; }
}

/* Progress */
.progress { display: flex; gap: 6px; flex-wrap: wrap; }
.seg {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 5px 6px;
  line-height: 1.3;
  white-space: nowrap;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--card);
  font-size: 12px;
  color: var(--muted);
}
.seg b { color: var(--ink); font-weight: 700; }
.seg .s { color: var(--star); letter-spacing: 1px; }
.seg.current { border-color: var(--ink); }
.chip {
  padding: 5px 10px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--card);
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.chip.level-chip { border-color: var(--ink); }

/* Rush: the clock chip and a bar that drains as time runs out */
.rush-clock { min-width: 58px; text-align: center; font-family: var(--f-tape); font-weight: 700; border-color: var(--ink); }
.rush-clock.hurry { color: var(--error); border-color: var(--error); animation: blink 1s steps(2, jump-none) infinite; }
.rush-bar { flex: 1 0 100%; height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
.rush-bar i { display: block; height: 100%; border-radius: 3px; background: var(--yellow); transition: width 0.2s linear; }
.rush-eyebrow { margin: 0; color: var(--error); }
.rush-lcd { text-align: left; }
.rush-lcd .segs { justify-content: center; }
#boardTabs { grid-template-columns: repeat(5, 1fr); }

/* Rush length picker: a row of keys, the chosen one lit */
.len-pick { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; padding: 4px; border-radius: 10px; background: var(--bg); }
.len-pick.small { grid-template-columns: repeat(3, 1fr); }
.len-pick button {
  height: 38px;
  padding: 0 4px;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
}
.len-pick button.on { background: var(--op); color: var(--op-ink); }
.len-pick.small button { height: 32px; }
.stepper { display: grid; grid-template-columns: 48px 1fr 48px; align-items: center; gap: 10px; }
.stepper .btn { height: 44px; padding: 0; font-size: 22px; }
.stepper span { display: flex; flex-direction: column; align-items: center; line-height: 1.2; }
.stepper b { font-family: var(--f-tape); font-size: 22px; font-variant-numeric: tabular-nums; }
.stepper small { font-size: 12px; color: var(--muted); }

/* Calculator body holding the display */
.machine {
  position: relative;
  padding: 12px 12px 16px;
  border-radius: 16px 16px 10px 10px;
  background: var(--body);
  color: var(--body-ink);
  box-shadow: 0 8px 20px var(--shadow);
}
/* the slot the paper comes out of */
.machine::after {
  content: "";
  position: absolute;
  left: 22px;
  right: 22px;
  bottom: 6px;
  height: 4px;
  border-radius: 2px;
  background: #000;
  opacity: 0.55;
}
.twist { margin: 10px 2px 0; font-size: 13px; font-weight: 600; color: var(--body-accent, var(--yellow)); }

/* ---------- Paper tape ---------- */
.tape-wrap { margin: -14px 26px 0; filter: drop-shadow(0 2px 2px var(--shadow)); }
.tape {
  margin: 0;
  padding: 14px 14px 20px;
  list-style: none;
  background-color: var(--paper);
  background-image: var(--paper-tex, none);
  background-size: var(--paper-tex-size, auto);
  color: var(--paper-ink);
  font-family: var(--f-tape);
  font-size: 19px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  -webkit-mask: conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) 50% / 14px 100%;
  mask: conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) 50% / 14px 100%;
}
.tape li {
  display: grid;
  grid-template-columns: 1.6em 1fr auto;
  align-items: baseline;
  gap: 6px;
  padding: 5px 0;
  border-bottom: 1px dashed var(--paper-rule);
}
.tape li:last-child { border-bottom: none; }
.tape .n { font-size: 13px; color: var(--paper-muted); }
.tape .x { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tape .r { text-align: right; white-space: nowrap; }
.tape .now .r { color: var(--paper-muted); }
.tape .now .x:empty::after, .caret {
  content: "";
  display: inline-block;
  width: 0.55em;
  height: 3px;
  vertical-align: baseline;
  background: var(--paper-ink);
  animation: caret 1s steps(2, jump-none) infinite;
}
.tape .total { color: var(--paper-red); border-top: 2px solid var(--paper-ink); border-bottom: none; margin-top: 2px; padding-top: 7px; }
.tape .total .n { color: var(--paper-red); font-size: 17px; }
.tape .total .x { font-size: 15px; text-transform: uppercase; letter-spacing: 0.06em; }
.tape .fresh { animation: print 0.35s steps(10, end); }
.tape.small { font-size: 16px; padding: 10px 12px 18px; }

.hint { margin: 2px 0 0; min-height: 1.45em; text-align: center; font-size: 15px; color: var(--muted); }
.hint b { color: var(--ink); }

/* ---------- Keypad ---------- */
.keypad { display: flex; flex-direction: column; gap: 12px; }
.tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.tile {
  --k: var(--key);
  --ki: var(--key-ink);
  --ke: var(--key-edge);
  height: 64px;
  border: none;
  border-radius: 12px;
  background: var(--k);
  color: var(--ki);
  box-shadow: 0 4px 0 var(--ke), 0 6px 12px var(--shadow);
  font-size: 30px;
  font-weight: 800;
  font-stretch: 110%;
  font-variant-numeric: tabular-nums;
  transition: transform 0.06s, box-shadow 0.06s, background-color 0.15s;
}
.tile:not(:disabled):active { transform: translateY(4px); box-shadow: 0 0 0 var(--ke), 0 1px 2px var(--shadow); }
.tile.long { font-size: 24px; }
.tile.sel { --k: var(--yellow); --ki: var(--yellow-ink); --ke: var(--yellow-edge); transform: translateY(2px); box-shadow: 0 2px 0 var(--ke); }
.tile.ready { outline: 2px solid var(--ring); outline-offset: 3px; }
.tile.hit { --k: var(--good); --ki: #fff; --ke: var(--good-edge); }
.tile.empty { background: transparent; box-shadow: inset 0 2px 5px var(--shadow), inset 0 0 0 1.5px var(--line); cursor: default; }
.tile:disabled { cursor: default; }

.ops { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.op {
  --k: var(--op);
  --ki: var(--op-ink);
  --ke: var(--op-edge);
  position: relative;
  height: 52px;
  border: none;
  border-radius: 12px;
  background: var(--k);
  color: var(--ki);
  box-shadow: 0 4px 0 var(--ke), 0 6px 12px var(--shadow);
  font-size: 27px;
  font-weight: 600;
  transition: transform 0.06s, box-shadow 0.06s, background-color 0.15s;
}
.op:not(:disabled):active { transform: translateY(4px); box-shadow: 0 0 0 var(--ke); }
.op.sel { --k: var(--yellow); --ki: var(--yellow-ink); --ke: var(--yellow-edge); transform: translateY(2px); box-shadow: 0 2px 0 var(--ke); }
.op.ready { outline: 2px solid var(--ring); outline-offset: 3px; }
.op.banned { opacity: 0.35; }
.op.banned::after {
  content: "";
  position: absolute;
  left: 22%;
  right: 22%;
  top: 50%;
  height: 3px;
  border-radius: 2px;
  background: currentColor;
  transform: rotate(-35deg);
}

/* ---------- Bottom action bar ---------- */
.action-bar {
  position: sticky;
  bottom: 0;
  z-index: 10;
  padding-top: 12px;
  padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--line);
}
.actions { max-width: 428px; margin: 0 auto; display: grid; grid-template-columns: 1fr 1fr 1.5fr; gap: 10px; }
.actions.two { grid-template-columns: 1fr 1.5fr; }
.actions .btn { height: 54px; }
.finish { display: flex; flex-direction: column; justify-content: center; align-items: center; line-height: 1.15; }
.finish b { font-size: 15px; }
.finish small { font-size: 12px; font-weight: 600; opacity: 0.8; }

/* ---------- Toast ---------- */
/* Messages pop up near the bottom, just above the keys they're usually about */
.toast {
  position: fixed;
  bottom: calc(92px + env(safe-area-inset-bottom, 0px));
  left: 50%;
  z-index: 50;
  width: max-content;
  max-width: calc(100% - 32px);
  padding: 10px 16px;
  border-radius: 8px;
  background: var(--ink);
  color: var(--bg);
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 12px);
  transition: opacity 0.2s, transform 0.2s;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---------- Dialogs ---------- */
dialog {
  width: min(420px, calc(100% - 32px));
  max-height: calc(100% - 32px);
  padding: 0;
  border: none;
  border-radius: 16px;
  background: var(--panel);
  color: var(--ink);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
  overflow-x: hidden; /* bits from a burst fly past the edge; don't flash a sideways scrollbar */
  overscroll-behavior: contain; /* scrolling to the end of a pop-up doesn't carry on into the page */
}
dialog::backdrop { background: var(--backdrop); }
/* On touch screens the page behind an open pop-up stays still (dragging it made the menu scroll
   underneath and the browser's toolbars jump). Mouse scrolling is already kept in by the line above. */
@media (pointer: coarse) {
  html:has(dialog[open]) { overflow: hidden; overscroll-behavior: none; }
}
dialog[open] { animation: rise 0.22s ease-out; }
.sheet { position: relative; padding: 22px 20px 18px; display: flex; flex-direction: column; gap: 12px; }
.sheet.center { text-align: center; }
.sheet h2 { margin: 0; padding-right: 36px; font-size: 22px; font-weight: 800; font-stretch: 112%; }
.sheet.center h2 { padding-right: 0; }
.sheet h3 { margin: 6px 0 0; font-size: 11px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.sheet p { margin: 0; }
.close-x {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 34px;
  height: 34px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  font-size: 20px;
  line-height: 1;
}
.how { margin: 0; padding-left: 20px; display: grid; gap: 8px; }
.rules { margin: 0; padding-left: 18px; display: grid; gap: 6px; font-size: 14px; color: var(--muted); }
.rules b { color: var(--ink); }
.example { display: flex; flex-direction: column; gap: 8px; }
.example-q { font-size: 14px; color: var(--muted); }
.example-q b { color: var(--ink); font-family: var(--f-tape); font-size: 15px; word-spacing: 0.15em; }
.example .tape { filter: drop-shadow(0 1px 2px var(--shadow)); }
.star { color: var(--star); letter-spacing: 1px; }

.big-stars { font-size: 40px; letter-spacing: 6px; color: var(--star); line-height: 1; }
.extra { padding: 10px; border-radius: 8px; border: 1px solid var(--line); font-weight: 600; }
/* How you compare */
.report {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  border-radius: 12px;
  border: 1px solid var(--line);
  text-align: left;
}
.vs { font-size: 16px; font-weight: 600; line-height: 1.3; }
.vs b { font-size: 20px; font-weight: 800; font-stretch: 112%; font-variant-numeric: tabular-nums; }
.vs.quiet { font-size: 14px; font-weight: 500; color: var(--muted); }
.meter { height: 8px; border-radius: 4px; background: var(--line); overflow: hidden; }
.meter i { display: block; height: 100%; border-radius: 4px; background: var(--yellow); transition: width 0.6s ease-out; }
.you-grid { display: grid; grid-template-columns: repeat(3, 1fr); text-align: center; }
.you-grid div { display: flex; flex-direction: column; padding: 2px 4px; }
.you-grid div + div { border-left: 1px solid var(--line); }
.you-grid b { font-size: 22px; font-weight: 800; font-stretch: 112%; font-variant-numeric: tabular-nums; line-height: 1.2; }
.you-grid span { font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.you-grid small { margin-top: 2px; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.vs-note { font-size: 12px; color: var(--muted); }

/* Sign-in nudge for guests: one small line above the buttons */
.nudge { margin: 0; font-size: 14px; line-height: 1.4; color: var(--muted); text-wrap: balance; }
.nudge-btn {
  padding: 0;
  border: none;
  background: none;
  color: var(--ink);
  font: inherit;
  font-weight: 800;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--yellow);
  text-underline-offset: 3px;
  cursor: pointer;
}
.sheet.revealing .nudge { animation: rise 0.35s ease-out 1.2s backwards; }

.route { text-align: left; }
.route summary {
  padding: 4px 0;
  color: var(--muted);
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  list-style: none;
}
.route summary::-webkit-details-marker { display: none; }
.route[open] summary { margin-bottom: 8px; }
.route .tape { filter: drop-shadow(0 1px 2px var(--shadow)); }

.sum-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
}
.sum-row:last-of-type { border-bottom: none; }
.sum-row .star { font-size: 18px; }
.sum-total { text-align: center; color: var(--muted); }
.sum-total b { color: var(--ink); font-size: 22px; font-stretch: 112%; }
.sum-note { color: var(--muted); font-size: 14px; }
.sum-note a { color: inherit; font-weight: 700; }

.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); text-align: center; border: 1px solid var(--line); border-radius: 10px; }
.stat-grid.three { grid-template-columns: repeat(3, 1fr); }
.stat-grid div { padding: 10px 4px; }
.stat-grid div + div { border-left: 1px solid var(--line); }
.stat-grid b { display: block; font-size: 22px; font-weight: 800; font-stretch: 112%; font-variant-numeric: tabular-nums; }
.stat-grid span { font-size: 11px; color: var(--muted); }
.next { text-align: center; font-size: 14px; color: var(--muted); }
.next b { color: var(--ink); font-variant-numeric: tabular-nums; }

/* ---------- Account ---------- */
.account { display: flex; flex-direction: column; gap: 12px; }
.account h2 { margin: 0; padding-right: 36px; font-size: 22px; font-weight: 800; font-stretch: 112%; overflow-wrap: anywhere; }
.auth { display: flex; flex-direction: column; gap: 6px; }
.auth label { font-size: 13px; font-weight: 700; }
.field-row { display: flex; gap: 8px; }
.field-row input {
  flex: 1;
  min-width: 0;
  height: 48px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
}
.field-row input:focus { outline: 2px solid var(--ring); outline-offset: 1px; }
.field-row .btn { height: 48px; flex: none; }
.code-input { font-family: var(--f-tape); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.hint-sm { font-size: 13px; color: var(--muted); }
.form-error { font-size: 14px; font-weight: 600; color: var(--error); }
/* Google's own sign-in button sits in here; it's an iframe sized to the box */
.g-btn { display: flex; justify-content: center; min-height: 44px; color-scheme: normal; }
.g-add { display: flex; flex-direction: column; gap: 8px; }
.or { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 12px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
.or::before, .or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.code-box {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 2px 10px;
  padding: 12px 14px;
  border-radius: 6px;
  background: var(--paper);
  color: var(--paper-ink);
  box-shadow: 0 1px 3px var(--shadow);
}
.code-box .label { grid-column: 1; color: var(--paper-muted); }
.code-box code { grid-column: 1; font-family: var(--f-tape); font-size: 19px; font-weight: 700; letter-spacing: 0.02em; white-space: nowrap; user-select: all; }
.code-box .btn { grid-column: 2; grid-row: 1 / span 2; height: 42px; }
.code-box.fresh { outline: 2px solid var(--ring); outline-offset: 2px; }

/* ---------- Leaderboard ---------- */
.tabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; padding: 4px; border-radius: 10px; background: var(--bg); }
.tabs button {
  height: 36px;
  padding: 0 4px;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
}
.tabs button.on { background: var(--op); color: var(--op-ink); }
.board-cap { font-size: 13px; color: var(--muted); }
.board { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; max-height: 46vh; overflow-y: auto; }
.board li {
  display: grid;
  grid-template-columns: 30px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 9px 4px;
  border-bottom: 1px solid var(--line);
}
.board li:last-child { border-bottom: none; }
.board .rk { font-family: var(--f-tape); font-weight: 700; color: var(--muted); text-align: center; font-variant-numeric: tabular-nums; }
.board .podium .rk { border-radius: 6px; background: var(--yellow); color: var(--yellow-ink); }
.board .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.board .nm em { margin-left: 4px; font-style: normal; font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.board .vl { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.2; }
.board .vl b { font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
.board .vl small { font-size: 12px; color: var(--muted); white-space: nowrap; }
.board li.me { margin: 0 -4px; padding-left: 8px; padding-right: 8px; border-radius: 8px; border-bottom-color: transparent; background: var(--bg); box-shadow: inset 0 0 0 1.5px var(--ink); }
.board li.gap { display: block; padding: 2px 0; border-bottom: none; text-align: center; color: var(--muted); }
.board li.board-msg { display: block; padding: 16px 4px; border-bottom: none; color: var(--muted); text-align: center; }
.board-foot { display: flex; flex-direction: column; gap: 10px; text-align: center; font-size: 14px; color: var(--muted); }
.board-foot:empty { display: none; }
.board-foot b { color: var(--ink); }

/* ---------- Coins ---------- */
/* A brass coin. It's a physical object, so the same colors work in both themes. */
.coin {
  display: inline-block;
  flex: none;
  width: 1em;
  height: 1em;
  border-radius: 50%;
  vertical-align: -0.14em;
  background: radial-gradient(circle at 34% 30%, #fff1b0 0 10%, #f3c534 40%, #c98e00 100%);
  box-shadow: inset 0 0 0 0.08em rgba(120, 78, 0, 0.6), inset 0 0 0 0.19em rgba(255, 236, 160, 0.55);
}
.coins-tag { display: inline-flex; align-items: center; gap: 6px; color: var(--ink); font-weight: 800; }
.coins-won {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--bg);
}
.coins-won b { display: inline-flex; align-items: center; gap: 7px; font-size: 18px; font-weight: 800; font-stretch: 112%; }
.coins-won small { font-size: 12px; color: var(--muted); text-wrap: balance; }
.coins-won.fresh .coin { animation: flip 0.6s ease-out; }

/* ---------- Shop ---------- */
.wallet { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 10px; background: var(--bg); }
.wallet .coin { font-size: 28px; }
.wallet b { font-size: 26px; font-weight: 900; font-stretch: 112%; font-variant-numeric: tabular-nums; line-height: 1; }
.wallet span:last-child { flex: 1; min-width: 0; font-size: 13px; line-height: 1.3; color: var(--muted); }
.tabs.two { grid-template-columns: 1fr 1fr; }
.shop-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.item {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 6px 6px 8px;
  border: none;
  border-radius: 12px;
  background: transparent;
  text-align: left;
  box-shadow: inset 0 0 0 1px var(--line);
}
.item.on { box-shadow: inset 0 0 0 2px var(--ink); }
.item.pick { box-shadow: inset 0 0 0 2px var(--ring); }
.item-meta { display: flex; justify-content: space-between; align-items: center; gap: 6px; padding: 0 3px; }
.item-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 700; }
.item-state {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: none;
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.item.on .item-state { color: var(--ink); }
.item.short .item-state { opacity: 0.6; }
.item-state .lock { width: 11px; height: 11px; }
#shopTabs button { padding: 0 2px; font-size: 12.5px; }

/* Coin packs bought with real money */
.pack-note { margin: 0; font-size: 14px; color: var(--muted); }
.packs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.pack {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 18px 4px 10px;
  border: none;
  border-radius: 12px;
  background: var(--bg);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--line);
  font: inherit;
  cursor: pointer;
}
.pack:hover { box-shadow: inset 0 0 0 2px var(--ink); }
.pack.busy { opacity: 0.6; }
.pack-coins { display: inline-flex; align-items: center; gap: 5px; font-size: 17px; font-weight: 900; font-stretch: 112%; font-variant-numeric: tabular-nums; }
.pack-price {
  width: 100%;
  padding: 5px 0;
  border-radius: 7px;
  background: var(--yellow);
  color: var(--yellow-ink);
  font-size: 14px;
  font-weight: 800;
}
.pack-tag {
  position: absolute;
  top: -8px;
  left: 50%;
  transform: translateX(-50%);
  padding: 2px 7px;
  border-radius: 4px;
  background: var(--ink);
  color: var(--bg);
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}
#shopDlg .hint-sm a, .site-foot a { color: inherit; text-underline-offset: 3px; }

/* Ads: a labelled box at the bottom of the menu and the result card. Empty or unfilled ads stay invisible. */
.ad-box {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 6px;
  padding: 8px;
  border-radius: 12px;
  background: var(--card);
  box-shadow: 0 0 0 1px var(--line);
}
.ad-box[hidden], .ad-box:has(ins[data-ad-status="unfilled"]) { display: none; }
.ad-head { display: flex; justify-content: space-between; align-items: center; font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.ad-remove { padding: 2px 0; border: none; background: none; color: var(--muted); font: inherit; letter-spacing: 0.04em; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
#resultDlg .ad-box { margin-top: 16px; }
/* Until an ad actually arrives, the box takes no space (it keeps its width so the ad can size itself) */
.ad-box:not(:has(ins[data-ad-status="filled"])),
#resultDlg .ad-box:not(:has(ins[data-ad-status="filled"])) { gap: 0; margin-top: 0; padding: 0; background: none; box-shadow: none; }
.ad-box:not(:has(ins[data-ad-status="filled"])) .ad-head { display: none; }
.site-foot { display: flex; justify-content: center; gap: 18px; padding: 4px 0 8px; font-size: 13px; color: var(--muted); }

/* Rarity badge in the corner of a preview. Badges carry their own colors, so they read on any desk. */
.tier {
  position: absolute;
  top: 5px;
  left: 5px;
  z-index: 1;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.4;
  color: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}
.t-rare { background: #2f6fd6; }
.t-epic { background: #7c3aed; }
.t-legendary { background: linear-gradient(135deg, #f7d774, #d99a1e 55%, #f3c94b); color: #3a2400; }
.t-trophy { background: #161616; color: #f3c94b; box-shadow: inset 0 0 0 1px #f3c94b; }

/* A strip of paper tape for the Tape tab */
.mini-tape {
  width: 62%;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 7px 8px 11px;
  background-color: var(--paper);
  background-image: var(--paper-tex, none);
  background-size: var(--paper-tex-size, auto);
  color: var(--paper-ink);
  font-family: var(--f-tape);
  font-size: 11px;
  font-weight: 700;
  box-shadow: 0 3px 8px var(--shadow);
  -webkit-mask: conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) 50% / 8px 100%;
  mask: conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) 50% / 8px 100%;
}
.mini-tape i { display: flex; justify-content: space-between; font-style: normal; padding-bottom: 2px; border-bottom: 1px dashed var(--paper-rule); }
.mini-tape i.t { color: var(--paper-red); border-bottom: none; border-top: 1.5px solid var(--paper-ink); padding-top: 2px; }
.mini-tape b { font-weight: 700; }

/* Effects: shapes for the shop preview (.fxp, frozen) and for real bursts (.burst i) */
.scene { position: relative; }
.scene .fxp { position: absolute; margin: -5px 0 0 -4px; }
.fxp, .burst i { width: 8px; height: 10px; border-radius: 1px; background: var(--c); }
.fxp.dot, .burst i.dot { width: 8px; height: 8px; border-radius: 50%; }
.fxp.star, .burst i.star {
  width: 13px;
  height: 13px;
  border-radius: 0;
  clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
.fxp.coinp, .burst i.coinp {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, #fff1b0 0 10%, #f3c534 40%, #c98e00 100%);
  box-shadow: inset 0 0 0 1px rgba(120, 78, 0, 0.6);
}
.fxp.digit, .burst i.digit {
  width: auto;
  height: auto;
  background: none;
  box-shadow: none;
  color: var(--c);
  font-family: var(--f-ui);
  font-size: 17px;
  font-weight: 900;
  font-stretch: 112%;
  line-height: 1;
}
.fxp.heart, .burst i.heart {
  width: 13px;
  height: 12px;
  border-radius: 0;
  box-shadow: none;
  clip-path: path('M6.5 12 L1.2 6.6 A3.2 3.2 0 0 1 6.5 1.9 A3.2 3.2 0 0 1 11.8 6.6 Z');
}
.fxp.bubble, .burst i.bubble {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 30%, rgba(255, 255, 255, 0.95) 0 14%, rgba(150, 215, 255, 0.28) 38%, rgba(150, 215, 255, 0.08) 70%);
  box-shadow: inset 0 0 0 1.5px rgba(140, 205, 255, 0.85);
}
.fxp.spark, .burst i.spark { width: 5px; height: 5px; border-radius: 50%; box-shadow: 0 0 6px 1px var(--c); }
.fxp.bolt, .burst i.bolt {
  width: 10px;
  height: 17px;
  border-radius: 0;
  clip-path: polygon(55% 0, 0 58%, 42% 58%, 30% 100%, 100% 38%, 58% 38%);
  filter: drop-shadow(0 0 3px #ffd23f);
}
/* Text bits: math symbols, music notes, emoji */
.fxp.glyph, .burst i.glyph {
  width: auto;
  height: auto;
  background: none;
  box-shadow: none;
  color: var(--c);
  font-family: var(--f-ui);
  font-size: 18px;
  font-weight: 900;
  line-height: 1;
}
.fxp.pixel, .burst i.pixel { width: 7px; height: 7px; border-radius: 0; box-shadow: none; }
.fxp.petal, .burst i.petal { width: 10px; height: 10px; border-radius: 50% 0 50% 50%; box-shadow: none; }
.fxp.ring, .burst i.ring { width: 12px; height: 12px; border-radius: 50%; background: none; box-shadow: inset 0 0 0 2.5px var(--c); }
.fxp.leaf, .burst i.leaf {
  width: 11px;
  height: 14px;
  border-radius: 0 100% 0 100%;
  box-shadow: none;
  background: linear-gradient(135deg, transparent 46%, rgba(0, 0, 0, 0.28) 50%, transparent 54%), var(--c);
}
.fxp.blob, .burst i.blob { width: 13px; height: 12px; border-radius: 45% 55% 62% 38% / 55% 42% 58% 45%; box-shadow: none; }
.fxp.bill, .burst i.bill {
  width: 17px;
  height: 9px;
  border-radius: 1px;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.55) 0 2px, transparent 2.5px), var(--c);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.4), 0 0 0 1px rgba(0, 0, 0, 0.15);
}
.fxp.gem, .burst i.gem {
  width: 11px;
  height: 13px;
  border-radius: 0;
  box-shadow: none;
  clip-path: polygon(50% 0, 100% 35%, 50% 100%, 0 35%);
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.8) 0 20%, transparent 45%), var(--c);
}
.fxp.sparkle, .burst i.sparkle {
  width: 14px;
  height: 14px;
  border-radius: 0;
  box-shadow: none;
  clip-path: polygon(50% 0, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0 50%, 40% 40%);
}
.fxp.moon, .burst i.moon { width: 13px; height: 13px; border-radius: 50%; background: none; box-shadow: inset 4px -2px 0 0 var(--c); }
.fxp.flame, .burst i.flame {
  width: 10px;
  height: 15px;
  border-radius: 0;
  box-shadow: none;
  clip-path: path('M5 0C7 4 10 6.5 10 10A5 5 0 0 1 0 10C0 6.5 3 4 5 0Z');
  background: radial-gradient(circle at 50% 72%, #fff3a0 0 22%, var(--c) 62%);
}

/* A tiny calculator on a patch of desk */
.scene {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  max-width: 100%;
  border-radius: 8px;
  overflow: hidden;
  background-color: var(--bg);
  background-image: var(--tex);
  background-size: var(--tex-size);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}
.mini {
  width: 60%;
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 6px;
  border-radius: 7px;
  background: var(--body);
  box-shadow: 0 4px 10px var(--shadow);
}
.mini .lcd { padding: 3px 5px; border-radius: 3px; }
.mini .segs { height: 15px; margin: 0; gap: 2px; }
.mini-keys { display: grid; grid-template-columns: repeat(4, 1fr); gap: 3px; }
.mini-keys i { height: 7px; border-radius: 2px; background: var(--key); box-shadow: 0 1.5px 0 var(--key-edge); }
.mini-keys i.o { background: var(--op); box-shadow: 0 1.5px 0 var(--op-edge); }
.mini-keys i.a { background: var(--yellow); box-shadow: 0 1.5px 0 var(--yellow-edge); }

.buy-bar {
  position: sticky;
  bottom: -18px;
  z-index: 1;
  margin: 0 -20px -18px;
  padding: 12px 20px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--panel);
  border-top: 1px solid var(--line);
}
.buy-bar div { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.buy-bar b { font-size: 15px; }
.buy-bar span { font-size: 13px; color: var(--muted); }
.buy-bar .btn { flex: none; display: inline-flex; align-items: center; gap: 6px; }

/* ---------- Menu header: shop chip, theme and sound switches ---------- */
.top-row { display: flex; align-items: center; gap: 6px; }
.head-links .shop-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 9px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  color: var(--ink);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
}
.shop-chip svg { width: 17px; height: 17px; flex: none; }
.shop-chip .coin { font-size: 14px; }
.shop-chip.pop { animation: pop 0.35s ease-out; }
.links-row button { padding-left: 5px; padding-right: 5px; }
.head-links .icon-link { display: grid; place-items: center; padding: 4px 5px; text-decoration: none; }
/* Small phones: a slightly smaller logo keeps it clear of the buttons */
@media (max-width: 359px) {
  .logo { font-size: 18px; }
  .links-row button, .head-links .icon-link { padding-left: 3px; padding-right: 3px; }
}
.icon-link svg { width: 20px; height: 20px; }
.sound-btn .mute { display: none; }
.sound-btn.off .waves { display: none; }
.sound-btn.off .mute { display: inline; }
.theme-btn .sun { display: none; }
.theme-btn.dark .moon { display: none; }
.theme-btn.dark .sun { display: inline; }

/* ---------- Motion ---------- */
/* Menu cards slide in one after another */
.view.enter .app > * { animation: rise 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) backwards; }
.view.enter .app > :nth-child(2) { animation-delay: 0.04s; }
.view.enter .app > :nth-child(3) { animation-delay: 0.08s; }
.view.enter .app > :nth-child(4) { animation-delay: 0.12s; }
.view.enter .app > :nth-child(5) { animation-delay: 0.17s; }
.view.enter .app > :nth-child(6) { animation-delay: 0.22s; }
.view.enter .app > :nth-child(7) { animation-delay: 0.27s; }
.view.enter .app > :nth-child(8) { animation-delay: 0.32s; }

/* First visit: each menu card arrives like the object it is, the first time it scrolls into
   view (game.js, playIntro). --d is the card's wait, so cards on screen together arrive in turn. */
.podium .p3 { --k: 0; }
.podium .p2 { --k: 1; }
.podium .p1 { --k: 2; }
@media (prefers-reduced-motion: no-preference) {
  .home.intro [data-intro]:not(.shown) { opacity: 0; }
  .home.intro .lede { animation: rise 0.6s cubic-bezier(0.2, 0.8, 0.2, 1) 0.3s backwards; }

  /* Daily: the calculator is set down and its screen switches on (the numbers then spin) */
  .home.intro .daily.shown { animation: set-down 0.6s cubic-bezier(0.2, 0.8, 0.2, 1) var(--d) backwards; }
  .home.intro .daily.shown .lcd { animation: logo-power 0.5s steps(1) calc(var(--d) + 0.2s) backwards; }

  /* Endless: the paper feeds out of the machine, then its lines print */
  .home.intro .tape-card.shown { animation: feed 0.55s steps(16) var(--d) backwards; }

  /* Rush: the timer is dropped on the desk, wobbles to a stop, then winds up */
  .home.intro .timer-card.shown { transform-origin: 50% 100%; animation: drop-wobble 0.8s cubic-bezier(0.3, 0.7, 0.4, 1) var(--d) backwards; }

  /* Leaderboard: the podium keys rise one after another and the star lands on first place */
  .home.intro .board-card.shown { animation: set-down 0.55s cubic-bezier(0.2, 0.8, 0.2, 1) var(--d) backwards; }
  .home.intro .board-card.shown .podium .key { transform-origin: 50% 100%; animation: grow 0.5s cubic-bezier(0.3, 1.5, 0.5, 1) calc(var(--d) + 0.25s + var(--k) * 0.12s) backwards; }
  .home.intro .board-card.shown .podium .who { animation: rise 0.4s ease-out calc(var(--d) + 0.45s + var(--k) * 0.12s) backwards; }
  .home.intro .board-card.shown .podium .p1 .who::before { animation: stamp 0.45s ease-out calc(var(--d) + 0.95s) backwards; }

  /* Shop: the calculators drop onto the shelf and their price tags swing */
  .home.intro .shop-card.shown { animation: set-down 0.55s cubic-bezier(0.2, 0.8, 0.2, 1) var(--d) backwards; }
  .home.intro .shop-card.shown .shelf-item .mini { animation: drop-in 0.5s cubic-bezier(0.3, 1.4, 0.5, 1) calc(var(--d) + 0.25s + var(--n) * 0.1s) backwards; }
  .home.intro .shop-card.shown .tag { animation: swing 1.4s ease-out calc(var(--d) + 0.5s + var(--n) * 0.1s) backwards; }

  /* First visit: everything waits behind the Rules box and plays once it's closed (game.js) */
  .home.held .logo-body *, .home.held .lede { animation-play-state: paused; }
}
@keyframes set-down { from { opacity: 0; transform: translateY(28px) scale(0.97); } to { opacity: 1; transform: none; } }
@keyframes feed { from { clip-path: inset(0 -24px 100% -24px); } to { clip-path: inset(0 -24px -40px -24px); } }
@keyframes drop-wobble {
  0% { opacity: 0; transform: translateY(-36px) rotate(-4deg); }
  45% { opacity: 1; transform: translateY(5px) rotate(2deg); }
  65% { transform: translateY(-3px) rotate(-1.2deg); }
  82% { transform: translateY(1px) rotate(0.5deg); }
  100% { transform: none; }
}
@keyframes grow { from { transform: scaleY(0.05); } to { transform: none; } }
@keyframes drop-in { from { opacity: 0; transform: translateY(-28px); } to { opacity: 1; transform: none; } }
@keyframes swing {
  0% { opacity: 0; transform: rotate(calc(var(--r, 0deg) + 28deg)); }
  12% { opacity: 1; }
  35% { transform: rotate(calc(var(--r, 0deg) - 16deg)); }
  58% { transform: rotate(calc(var(--r, 0deg) + 8deg)); }
  78% { transform: rotate(calc(var(--r, 0deg) - 3deg)); }
  100% { transform: rotate(var(--r, 0deg)); }
}

/* A new puzzle deals its keys onto the keypad */
.tiles.deal .tile, .ops.deal .op { animation: deal 0.42s cubic-bezier(0.2, 0.9, 0.3, 1.25) backwards; }
.tiles.deal .tile:nth-child(2) { animation-delay: 0.04s; }
.tiles.deal .tile:nth-child(3) { animation-delay: 0.08s; }
.tiles.deal .tile:nth-child(4) { animation-delay: 0.12s; }
.tiles.deal .tile:nth-child(5) { animation-delay: 0.16s; }
.tiles.deal .tile:nth-child(6) { animation-delay: 0.2s; }
.ops.deal .op:nth-child(1) { animation-delay: 0.24s; }
.ops.deal .op:nth-child(2) { animation-delay: 0.27s; }
.ops.deal .op:nth-child(3) { animation-delay: 0.3s; }
.ops.deal .op:nth-child(4) { animation-delay: 0.33s; }

/* Result card: stars stamp down like a rubber stamp, then the rest prints in */
.big-stars .st { display: inline-block; }
.big-stars .st.off { opacity: 0.35; }
.big-stars.stamping .st { animation: stamp 0.34s cubic-bezier(0.2, 0.9, 0.3, 1.3) backwards; }
.sheet.revealing #resTitle { animation: rise 0.35s ease-out 0.62s backwards; }
.sheet.revealing #resQuip { animation: type 0.5s steps(24, end) 0.75s backwards; }
.sheet.revealing #resSub { animation: rise 0.35s ease-out 0.8s backwards; }
.sheet.revealing #resExtra, .sheet.revealing #resCoins { animation: rise 0.35s ease-out 0.9s backwards; }
.sheet.revealing .coins-won .coin { animation-delay: 1s; }
.sheet.revealing .report { animation: rise 0.35s ease-out 0.68s backwards; }
.sheet.revealing .meter i { transition-delay: 1.1s; }
.sheet.revealing .route, .sheet.revealing #resNext, .sheet.revealing #resHome { animation: rise 0.35s ease-out 1.05s backwards; }
.quip {
  margin: -4px 0 0;
  font-family: var(--f-tape);
  font-size: 15px;
  font-weight: 700;
  color: var(--muted);
  text-wrap: balance;
}

/* Paper chits that fly out of an exact hit */
.burst { position: fixed; z-index: 40; width: 0; height: 0; pointer-events: none; }
.burst i {
  position: absolute;
  left: -4px;
  top: -5px;
  width: 8px;
  height: 10px;
  border-radius: 1px;
  background: var(--c);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12);
  animation: chit 0.9s cubic-bezier(0.15, 0.7, 0.3, 1) both;
}

.item.pop, .wallet b.pop { animation: pop 0.35s ease-out; }

/* ---------- Animations ---------- */
@keyframes deal { from { opacity: 0; transform: translateY(16px) scale(0.85); } to { opacity: 1; transform: none; } }
@keyframes stamp {
  from { opacity: 0; transform: scale(2.4) rotate(-16deg); }
  65% { opacity: 1; transform: scale(0.9) rotate(3deg); }
  to { opacity: 1; transform: none; }
}
@keyframes type { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes chit {
  0% { opacity: 1; transform: translate(0, 0) rotate(0); }
  60% { opacity: 1; transform: translate(var(--dx), var(--dy)) rotate(calc(var(--r) * 0.7)); }
  100% { opacity: 0; transform: translate(calc(var(--dx) * 1.1), calc(var(--dy) + 70px)) rotate(var(--r)); }
}
@keyframes flip { 0% { transform: rotateY(0) scale(0.6); } 60% { transform: rotateY(540deg) scale(1.15); } 100% { transform: rotateY(720deg) scale(1); } }
@keyframes pop { 0% { transform: scale(0.7); } 60% { transform: scale(1.08); } 100% { transform: scale(1); } }
@keyframes shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }
@keyframes blink { 0% { opacity: 1; } 50% { opacity: 0.15; } }
@keyframes caret { 50% { opacity: 0; } }
@keyframes print { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.pop { animation: pop 0.25s ease-out; }
.shake { animation: shake 0.3s; }

@media (max-width: 360px) {
  .tile { height: 56px; font-size: 26px; }
  .segs.big { height: 68px; }
  .tape { font-size: 17px; }
  .actions { grid-template-columns: 1fr 1fr 1.4fr; gap: 8px; }
  .actions .btn { padding: 0 8px; }
}
/* Shorter phones: a more compact game screen leaves the tape room for about three lines */
@media (min-height: 560px) and (max-height: 760px) {
  .app.game { gap: 8px; padding-bottom: 12px; }
  .game .segs.big { height: 62px; }
  .tiles { gap: 8px; }
  .tile { height: 54px; }
  .ops { gap: 8px; }
  .op { height: 46px; }
  .keypad { gap: 10px; }
  .action-bar { padding-top: 8px; padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)); }
  .actions .btn { height: 48px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
