/* Polyvale: low-poly pastel. One deliberate light look; every color is set explicitly. */
:root {
  color-scheme: light;
  --ink: #2B3445;
  --ink-2: #566175;
  --ink-3: #8A93A6;
  --paper: #FBFDFF;
  --line: #DCE4EE;
  --edge: #D3DCE8;
  --sky-1: #CDEAF6;
  --sky-2: #E7F5EE;
  --mint: #8FD6AE;
  --mint-deep: #4FAF80;
  --coral: #FF7E6B;
  --coral-deep: #DE5F4D;
  --peach: #FFB38A;
  --sky: #7FC4EE;
  --sky-deep: #3E97CF;
  --gold: #F7C04A;
  --gold-deep: #D69A1C;
  --lilac: #A895EE;
  --lilac-deep: #7B66D1;
  --r-lg: 22px;
  --r-md: 14px;
  --spring: cubic-bezier(.34, 1.56, .64, 1);
  --f-display: "Bricolage Grotesque", "Figtree", system-ui, sans-serif;
  --f-ui: "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;
}

[hidden] { display: none !important; }
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; overscroll-behavior: none; }
html { touch-action: manipulation; }
body {
  margin: 0;
  -webkit-touch-callout: none;
  background: linear-gradient(180deg, var(--sky-1) 0%, var(--sky-2) 100%);
  color: var(--ink);
  font: 500 14px/1.45 var(--f-ui);
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}
button { font: inherit; color: inherit; }
.ic { width: 1.15em; height: 1.15em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.star-ic { fill: var(--gold); stroke: var(--gold-deep); stroke-width: 1.4; }
.coin {
  display: inline-block; width: 1em; height: 1em; border-radius: 50%; flex: none;
  background: radial-gradient(circle at 36% 30%, #FFEDB5 0 16%, #F7C04A 17% 60%, #E0A21F 61%);
  box-shadow: inset 0 -1px 0 rgba(43, 52, 69, .18);
  vertical-align: -0.14em;
}

/* ---------- layout ---------- */
#app {
  position: relative;
  height: 100%;
  height: 100dvh;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
  padding-block: max(10px, env(safe-area-inset-top)) max(10px, env(safe-area-inset-bottom));
  padding-inline: max(16px, env(safe-area-inset-left)) max(16px, env(safe-area-inset-right));
}
#app:not(.mode-game) .hud, #app:not(.mode-game) .dock { display: none; }
#app:not(.mode-game) { padding-block: 0; padding-inline: 0; }
.stage { position: relative; min-height: 0; grid-row: 2; }
#app:not(.mode-game) { gap: 0; }
#view { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: none; display: block; }

/* ---------- buttons ---------- */
.btn {
  --c: #FFFFFF; --c-edge: var(--edge); --c-ink: var(--ink);
  appearance: none; border: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 16px; border-radius: var(--r-md);
  font: 700 14px/1.1 var(--f-ui); color: var(--c-ink); background: var(--c);
  box-shadow: 0 4px 0 var(--c-edge), 0 8px 18px rgba(43, 52, 69, .10);
  transition: transform .2s var(--spring), box-shadow .2s, filter .15s, background .15s;
}
@media (hover: hover) {
  .btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 6px 0 var(--c-edge), 0 12px 22px rgba(43, 52, 69, .13); }
}
.btn:active:not(:disabled) { transform: translateY(3px); box-shadow: 0 1px 0 var(--c-edge), 0 4px 10px rgba(43, 52, 69, .10); }
.btn:focus-visible, .tb:focus-visible, .node:focus-visible, .map-card:focus-visible, .ability:focus-visible, .link-btn:focus-visible, .seg button:focus-visible {
  outline: 3px solid var(--sky-deep); outline-offset: 3px;
}
.btn:disabled { cursor: not-allowed; filter: saturate(.35); opacity: .6; }
.btn.primary { --c: var(--coral); --c-edge: var(--coral-deep); --c-ink: #FFFFFF; }
.btn.lilac { --c: var(--lilac); --c-edge: var(--lilac-deep); --c-ink: #FFFFFF; }
.btn.ghost { --c: rgba(255, 255, 255, .6); --c-edge: rgba(211, 220, 232, .8); }
.btn.danger { --c: #FFE3DE; --c-edge: #F4B5AA; --c-ink: var(--coral-deep); }
.btn.big { padding: 13px 20px; font-size: 15px; }
.btn.xl { padding: 16px 26px; font-size: 18px; border-radius: 18px; }
.btn.small { padding: 8px 12px; font-size: 13px; }
.icon-btn { padding: 0; width: 42px; height: 42px; font-size: 18px; }
.icon-btn .ic { width: 20px; height: 20px; }
.btn.speed { font: 800 15px/1 var(--f-display); width: 52px; }
.btn.speed.fast { --c: #EAF6FE; --c-edge: #B9DDF4; color: var(--sky-deep); }
.link-btn {
  appearance: none; border: 0; background: none; padding: 4px 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px; color: var(--ink-2); font-weight: 700;
}
@media (hover: hover) { .link-btn:hover { color: var(--ink); } }

/* ---------- HUD ---------- */
.hud { grid-row: 1; min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.hud-group { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pill {
  display: inline-flex; align-items: center; gap: 7px;
  background: #FFFFFF; border-radius: 999px; padding: 6px 14px 6px 8px; height: 40px;
  box-shadow: 0 3px 0 var(--edge), 0 6px 14px rgba(43, 52, 69, .07);
  font-variant-numeric: tabular-nums;
}
.pill b { font: 800 18px/1 var(--f-display); letter-spacing: -.01em; }
.pill .coin { width: 22px; height: 22px; }
.pill-ic { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; }
.pill-ic .ic { width: 16px; height: 16px; }
.pill-lives .pill-ic { background: #FFE3DE; color: var(--coral); }
.pill-lives .pill-ic .ic { fill: var(--coral); stroke: none; }
.pill-lives.low { background: #FFF0EC; }
.pill-lives.low b { color: var(--coral-deep); }
.pill-lives.hit { animation: shake .35s; }
.pill-stars .pill-ic { background: #FFF3D6; }
.pill-wave { padding-left: 14px; }
.pill-wave .lbl { font-size: 11px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.pill-wave .of { color: var(--ink-3); font-weight: 700; }
/* ---------- the band: sequencer, mix meter, drop ---------- */
.band {
  flex: 1; min-width: 0; max-width: 560px; display: flex; align-items: center; gap: 12px;
  background: #FFFFFF; border-radius: 18px; padding: 7px 8px 7px 12px;
  box-shadow: 0 3px 0 var(--edge), 0 6px 14px rgba(43, 52, 69, .07);
}
.seq { width: 208px; height: 50px; flex: none; display: block; }
.mixer { flex: 1; min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 5px; }
.mix-top { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; overflow: hidden; min-width: 0; }
.mix-lbl { font-size: 11px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.mix-top b { font-size: 13px; font-weight: 800; overflow: hidden; text-overflow: ellipsis; }
.mix-bar { position: relative; height: 12px; border-radius: 6px; background: linear-gradient(90deg, #E8EDF3, #E8EDF3 70%, #FFD9D2); overflow: hidden; }
.mix-zone {
  position: absolute; top: 0; bottom: 0; left: var(--lo, 0%); width: calc(var(--hi, 0%) - var(--lo, 0%));
  background: #C9F0D8; box-shadow: inset 0 0 0 2px #8FD6AE; border-radius: 6px; transition: left .4s, width .4s, bottom .4s, height .4s;
}
.mix-fill { position: absolute; left: 0; top: 3px; bottom: 3px; width: var(--fill, 0%); border-radius: 3px; background: var(--ink-2); transition: width .25s var(--spring), height .25s var(--spring), background .2s; }
.mixer[data-state="groove"] .mix-fill { background: var(--mint-deep); }
.mixer[data-state="groove"] .mix-top b { color: var(--mint-deep); }
.mixer[data-state="clip"] .mix-fill { background: var(--coral); }
.mixer[data-state="clip"] .mix-top b { color: var(--coral-deep); }
.mixer[data-state="clip"] .mix-bar { animation: shake .4s infinite; }
.drop {
  --p: 0;
  position: relative; flex: none; appearance: none; border: 0; cursor: pointer;
  width: 50px; height: 50px; border-radius: 50%; display: grid; place-items: center;
  background: conic-gradient(#FF9ECF calc(var(--p) * 360deg), #EEF2F6 0);
  font: 800 9px/1 var(--f-ui); letter-spacing: .02em; text-transform: uppercase; color: var(--ink-2);
  transition: transform .2s var(--spring);
}
.drop span { width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; background: #FFFFFF; }
.drop .ab-key { font-style: normal; }
.drop.ready { color: #FFFFFF; animation: dropReady 1s ease-in-out infinite; }
.drop.ready span { background: #FF7FB8; }
.drop.playing span { background: var(--ink); color: #FFFFFF; }
@media (hover: hover) { .drop:hover { transform: scale(1.06); } }
.drop:active { transform: scale(.94); }
.drop:focus-visible { outline: 3px solid var(--sky-deep); outline-offset: 3px; }
@keyframes dropReady { 50% { box-shadow: 0 0 0 6px rgba(255, 127, 184, .25); transform: scale(1.06); } }
.bpm { font: 800 12px/1 var(--f-ui); color: var(--ink-3); letter-spacing: .04em; white-space: nowrap; font-variant-numeric: tabular-nums; }

.pat { display: grid; grid-template-columns: repeat(16, 1fr); gap: 2px; }
.pat i { height: 10px; border-radius: 2px; background: #EDF1F5; }
.pat i.beat { background: #DDE4EC; }
.pat i.on { background: var(--tc, var(--ink-2)); }
.pat i.hold { background: var(--tc, var(--ink-2)); opacity: .45; }
.branch-card .pat i.on, .branch-card .pat i.hold { background: var(--bc); }
.tooltip .pat { margin: 8px 0; }
.tooltip .pat i { background: #465167; }
.tooltip .pat i.on { background: #FFFFFF; }
.tooltip .pat i.hold { background: #FFFFFF; opacity: .5; }
.tp-mute { width: 34px; height: 34px; --c: rgba(255, 255, 255, .8); --c-edge: rgba(43, 52, 69, .1); }
.tp-mute.on { --c: var(--ink); --c-edge: #11161F; color: #FFFFFF; }
.tp-wait { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 12px; border-radius: 14px; background: #F1ECFF; color: var(--lilac-deep); font-weight: 800; animation: bob 0.6s ease-in-out infinite; }
.banner.drop .bn-title { color: #FFE3F1; text-shadow: 0 2px 0 #F5A3C8, 0 4px 0 #EA86B4, 0 6px 0 #D96A9E, 0 14px 24px rgba(120, 40, 80, .3); }

@keyframes shake { 20% { transform: translateX(-4px); } 40% { transform: translateX(4px); } 60% { transform: translateX(-3px); } 80% { transform: translateX(2px); } }

/* ---------- dock ---------- */
.dock {
  grid-row: 3;
  min-width: 0;
  display: flex; align-items: center; gap: 12px;
  background: rgba(255, 255, 255, .72);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-radius: var(--r-lg); padding: 10px;
  box-shadow: 0 10px 30px rgba(43, 52, 69, .10);
}
.build-bar { display: flex; gap: 7px; min-width: 0; }
.tb {
  position: relative; appearance: none; border: 0; cursor: pointer; flex: none;
  width: 68px; height: 86px; border-radius: 16px; background: #FFFFFF;
  display: grid; justify-items: center; align-content: center; gap: 1px; padding: 4px 2px 6px;
  box-shadow: 0 4px 0 var(--edge);
  transition: transform .2s var(--spring), box-shadow .2s, background .15s;
}
@media (hover: hover) { .tb:hover { transform: translateY(-3px); } }
.tb:active { transform: translateY(2px); }
.tb.active { transform: translateY(-4px); background: #FFF4F1; box-shadow: 0 4px 0 #F2B3A5, inset 0 0 0 2.5px var(--coral); }
.tb-key { position: absolute; top: 5px; left: 7px; font: 800 10px/1 var(--f-ui); color: var(--ink-3); }
.tb-name { font-weight: 800; font-size: 12px; line-height: 1.1; }
.tb-cost { display: inline-flex; align-items: center; gap: 3px; font-weight: 800; font-size: 12px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.tb-cost .ic { width: 11px; height: 11px; }
.tb.cant .tb-cost { color: var(--coral-deep); }
.tb.cant canvas { opacity: .55; }
.tb.locked { width: 46px; background: #EEF2F6; box-shadow: 0 4px 0 #DCE3EC; }
.tb.locked canvas { filter: grayscale(1); opacity: .4; }
.tb-lock { position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%); width: 14px; height: 14px; color: var(--ink-3); }
/* Phones fold the locked towers into one lock with a count. */
.tb-more { display: none; }
.tb.tb-more { width: 40px; background: #EEF2F6; box-shadow: 0 4px 0 #DCE3EC; color: var(--ink-3); gap: 3px; }
.tb-more .tb-lock { position: static; transform: none; width: 16px; height: 16px; }
.tb-more b { font: 800 12px/1 var(--f-display); font-variant-numeric: tabular-nums; }
/* A row of towers wider than the dock fades out where it goes on. */
.build-bar.fade-r { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent); }
.build-bar.fade-l { -webkit-mask-image: linear-gradient(90deg, transparent, #000 28px); mask-image: linear-gradient(90deg, transparent, #000 28px); }
.build-bar.fade-l.fade-r {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 28px), transparent);
  mask-image: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 28px), transparent);
}

.abilities { display: flex; gap: 8px; padding-left: 12px; border-left: 2px dashed var(--line); }
.ability {
  --p: 0;
  position: relative; appearance: none; border: 0; cursor: pointer;
  width: 52px; height: 52px; border-radius: 50%;
  background: linear-gradient(160deg, #FFFFFF, #F1ECFF); color: var(--lilac-deep);
  box-shadow: 0 4px 0 #D8CFF7; display: grid; place-items: center;
  transition: transform .2s var(--spring);
}
.ability .ic { width: 24px; height: 24px; }
.ability::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: conic-gradient(rgba(43, 52, 69, .38) calc(var(--p) * 360deg), transparent 0);
}
@media (hover: hover) { .ability:hover { transform: translateY(-3px); } }
.ability:active { transform: translateY(2px); }
.ability.aiming { background: var(--coral); color: #FFFFFF; box-shadow: 0 4px 0 var(--coral-deep); }
.ability.cooling { cursor: default; }
.ab-key { position: absolute; bottom: -4px; right: -2px; background: var(--ink); color: #FFFFFF; font: 800 10px/1 var(--f-ui); padding: 3px 5px; border-radius: 6px; }

.wave-box { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.wave-preview { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; max-width: 280px; }
.wp-label { font-size: 11px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); margin-right: 2px; }
.wp-chip { display: inline-flex; align-items: center; gap: 2px; background: #FFFFFF; border-radius: 999px; padding: 2px 9px 2px 3px; box-shadow: 0 2px 0 var(--edge); font-variant-numeric: tabular-nums; }
.wp-chip b { font: 800 13px/1 var(--f-display); }
.wp-chip.boss { background: #F1ECFF; box-shadow: 0 2px 0 #D8CFF7; color: var(--lilac-deep); }
.wp-chip.new { background: #FFF4D6; box-shadow: 0 2px 0 #F2D58E; }
/* The wave switch: a coral knob in a sunken track. Tap the knob to send the next wave; slide it
   over (or tap the far end) and it stays there, sending every wave on its own. */
.wave-switch {
  --end: 46px; --pad: 4px; --k: 0;
  position: relative; flex: none; display: flex; border-radius: 18px;
  padding: var(--pad) calc(var(--end) + var(--pad)) var(--pad) var(--pad);
  background: #E6ECF3; box-shadow: inset 0 2px 4px rgba(43, 52, 69, .12), 0 1px 0 #FFFFFF;
  touch-action: none; transition: background .3s;
}
.wave-switch.auto { --k: 1; background: #FFE1DA; }
.ws-track {
  position: absolute; inset: 0; margin: 0; padding: 0 var(--pad); appearance: none; border: 0; border-radius: inherit;
  background: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; color: var(--ink-3);
}
.ws-track:focus-visible { outline: 3px solid var(--sky-deep); outline-offset: 3px; }
.ws-end { width: var(--end); align-self: stretch; display: grid; place-items: center; transition: opacity .25s, color .2s, transform .3s var(--spring); }
.ws-end .ic { width: 20px; height: 20px; }
.ws-once .ic { width: 15px; height: 15px; fill: currentColor; stroke: none; }
.ws-once, .wave-switch.auto .ws-loop { opacity: 0; }
.wave-switch.auto .ws-once { opacity: .85; }
.wave-switch.dragging .ws-loop { opacity: calc(1 - var(--k) * .6); }
.wave-switch.over .ws-loop { color: var(--coral); transform: scale(1.15); }
@media (hover: hover) { .ws-track:hover .ws-end { color: var(--ink-2); } }

.wave-switch .ws-knob.btn {
  position: relative; z-index: 1; min-width: 168px;
  transform: translate(calc(var(--k) * var(--end)), var(--lift, 0px));
  transition: transform .45s var(--spring), box-shadow .2s, filter .2s, opacity .2s, background .15s;
}
@media (hover: hover) { .wave-switch .ws-knob.btn:hover:not(.busy) { --lift: -2px; } }
.wave-switch .ws-knob.btn:active { --lift: 3px; }
.wave-switch.dragging .ws-knob.btn { transition: none; --lift: 0px; cursor: grabbing; }
.ws-knob.busy { cursor: default; filter: saturate(.35); opacity: .6; box-shadow: 0 2px 0 var(--c-edge); }
.wave-switch.auto .ws-knob.busy, .wave-switch.dragging .ws-knob.busy { filter: none; opacity: 1; box-shadow: 0 4px 0 var(--c-edge), 0 8px 18px rgba(43, 52, 69, .10); }
.ws-ic { display: grid; }
.ws-ic .ic { grid-area: 1 / 1; width: 16px; height: 16px; }
.ws-play { fill: currentColor; stroke: none; }
.ws-spin, .wave-switch.auto:not(.dragging) .ws-play, .wave-switch.over .ws-play { display: none; }
.wave-switch.auto:not(.dragging) .ws-spin, .wave-switch.over .ws-spin { display: block; }
.wave-switch.auto .ws-spin { animation: spin 2.4s linear infinite; }
/* Until someone finds it: the knob leans toward the far end and springs back. */
.wave-switch.peek .ws-knob.btn { animation: wsPeek 1.4s ease-in-out; }
.wave-switch.peek .ws-loop { animation: wsGlow 1.4s ease-in-out; }
@keyframes wsPeek { 25%, 40% { transform: translateX(calc(var(--end) * .5)); } 60% { transform: translateX(-2px); } 75% { transform: translateX(calc(var(--end) * .2)); } }
@keyframes wsGlow { 25%, 75% { color: var(--coral); transform: scale(1.2); } }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- floating panels ---------- */
.panel {
  background: rgba(251, 253, 255, .97); border-radius: var(--r-lg);
  box-shadow: 0 5px 0 var(--edge), 0 18px 40px rgba(43, 52, 69, .16);
}
.tower-panel {
  position: absolute; top: 12px; right: 12px; width: 300px; max-height: calc(100% - 24px);
  overflow: auto; padding: 0 14px 14px; z-index: 6;
  display: grid; gap: 12px; align-content: start;
  animation: panelIn .35s var(--spring);
}
.tower-panel.left { right: auto; left: 12px; }
@keyframes panelIn { from { transform: translateY(10px) scale(.97); opacity: 0; } }
.tp-head {
  display: flex; align-items: center; gap: 10px; margin: 0 -14px; padding: 12px 12px 12px 10px;
  background: var(--tc-soft); border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.tp-art { flex: none; }
.tp-title { flex: 1; min-width: 0; }
.tp-name { font: 800 20px/1.1 var(--f-display); letter-spacing: -.01em; }
.tp-sub { font-size: 12px; font-weight: 700; color: var(--ink-2); }
.tp-close { width: 34px; height: 34px; --c: rgba(255, 255, 255, .8); --c-edge: rgba(43, 52, 69, .1); }
.tier-track { display: grid; grid-template-columns: repeat(5, 1fr); gap: 4px; }
.tier-track i { height: 6px; border-radius: 3px; background: #E5EAF1; }
.tier-track i.on { background: var(--ink-2); }
.tier-track i.on.br { background: var(--tc); }
.tp-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin: 0; }
.tp-stats div { background: #F2F5F9; border-radius: 10px; padding: 6px 9px; }
.tp-stats dt { font-size: 11px; font-weight: 700; color: var(--ink-2); }
.tp-stats dd { margin: 0; font: 800 16px/1.2 var(--f-display); font-variant-numeric: tabular-nums; }
.tp-note, .tp-record { font-size: 12px; font-weight: 700; color: var(--ink-2); display: flex; align-items: center; gap: 6px; }
.tp-note { color: var(--mint-deep); }
.seg { display: grid; grid-template-columns: repeat(4, 1fr); background: #EEF2F6; border-radius: 12px; padding: 3px; gap: 2px; }
.seg button { appearance: none; border: 0; background: none; padding: 7px 0; border-radius: 9px; font-weight: 700; font-size: 12px; cursor: pointer; color: var(--ink-2); }
.seg button.on { background: #FFFFFF; color: var(--ink); box-shadow: 0 2px 0 var(--edge); }
.tp-up { display: grid; gap: 8px; background: #F6F8FB; border-radius: 16px; padding: 10px; }
.tp-up-head { font-size: 11px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.diff { list-style: none; margin: 0; padding: 0; display: grid; gap: 3px; }
.diff li { display: flex; justify-content: space-between; gap: 8px; font-size: 13px; }
.diff b { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--ink-2); }
.diff em { font-style: normal; color: var(--mint-deep); font-weight: 800; }
.up-btn { width: 100%; }
.up-btn .coin { width: 15px; height: 15px; }
.tp-branches { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.branch-card {
  display: grid; justify-items: center; text-align: center; gap: 4px; padding: 10px 8px;
  border-radius: 16px; background: #FFFFFF; border: 2px solid var(--bc);
  box-shadow: 0 3px 0 var(--bc);
}
.bc-name { font: 800 15px/1.1 var(--f-display); }
.bc-desc { margin: 0; font-size: 12px; color: var(--ink-2); flex: 1; }
.branch-card .pat { justify-self: stretch; }
.branch-btn { --c: var(--bc); --c-edge: rgba(43, 52, 69, .25); --c-ink: #FFFFFF; margin-top: 4px; padding: 9px 10px; width: 100%; text-shadow: 0 1px 0 rgba(43, 52, 69, .2); }
.tp-lock { margin: 0; display: flex; gap: 8px; align-items: flex-start; font-size: 13px; color: var(--ink-2); }
.tp-lock .ic { margin-top: 2px; color: var(--lilac-deep); }
.tp-max { display: flex; align-items: center; gap: 8px; justify-content: center; font-weight: 800; padding: 10px; background: #FFF6DE; border-radius: 14px; color: var(--gold-deep); }
.tp-actions { display: grid; gap: 12px; }
/* Gold Records: the metal tints the card; the discs fill in, the next one waits outlined. */
.rec-up { background: linear-gradient(135deg, color-mix(in srgb, var(--rc) 28%, #FFFFFF), #FFFFFF 70%); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--rc) 70%, #FFFFFF); }
.rec-up .tp-up-head { color: var(--rd); }
.rec-discs { display: flex; gap: 6px; justify-content: center; }
.rec-discs i { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; color: rgba(43, 52, 69, .18); }
.rec-discs i .ic { width: 22px; height: 22px; }
.rec-discs i.on { color: var(--rd); background: radial-gradient(circle at 35% 30%, #FFFFFF, var(--rc) 60%); animation: recShine 2.4s ease-in-out infinite; }
.rec-discs i.next { color: var(--rd); opacity: .55; }
.rec-discs i.on:nth-child(2) { animation-delay: .3s; }
.rec-discs i.on:nth-child(3) { animation-delay: .6s; }
@keyframes recShine { 0%, 70%, 100% { filter: brightness(1); } 80% { filter: brightness(1.35); } }
.rec-btn { --c: var(--rc); --c-edge: var(--rd); --c-ink: #2B3445; gap: 6px; background: linear-gradient(115deg, var(--rc) 0%, #FFFFFF 38%, var(--rc) 55%, color-mix(in srgb, var(--rc) 70%, var(--rd)) 100%); }
.rec-btn > .ic { width: 18px; height: 18px; }
.rec-max { background: linear-gradient(135deg, color-mix(in srgb, var(--rc) 40%, #FFFFFF), #FFFFFF); }
.rec-max .rec-discs i { width: 30px; height: 30px; }
@media (prefers-reduced-motion: reduce) { .rec-discs i.on { animation: none; } }
.sell-btn { --c: #F2F5F9; --c-edge: #DCE3EC; width: 100%; color: var(--ink-2); }

.tooltip {
  position: absolute; bottom: 10px; width: 250px; z-index: 7; pointer-events: none;
  background: var(--ink); color: #FFFFFF; border-radius: 16px; padding: 12px 14px;
  box-shadow: 0 12px 30px rgba(43, 52, 69, .3);
}
.tooltip b { font: 800 16px/1.2 var(--f-display); }
.tooltip p { margin: 4px 0 8px; color: #D5DCE8; font-size: 13px; }
.tip-stats { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 12px; color: #B7C1D2; }
.tip-stats b { font: 700 12px var(--f-ui); color: #FFFFFF; }
.tip-lock { display: flex; align-items: center; gap: 6px; color: #D9CFFF !important; margin-bottom: 0 !important; }

/* Strong / weak: rows of critter (or tower) icons on green and red dots. */
/* Labels in one column, icons in the next: icons that wrap stay under icons. */
.vs { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 4px 6px; }
.vs-row { display: contents; }
.vs-lbl { font-size: 11px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.vs-ico { display: flex; flex-wrap: wrap; gap: 3px; }
.vs-row canvas { border-radius: 50%; padding: 2px; box-sizing: content-box; }
.vs-row.good .vs-lbl { color: var(--mint-deep); }
.vs-row.bad .vs-lbl { color: var(--coral-deep); }
.vs-row.good canvas { background: #E2F5E9; }
.vs-row.bad canvas { background: #FDE6E1; }
.tooltip .vs { margin-top: 10px; }
.tooltip .vs-row.good .vs-lbl { color: #9FE3BD; }
.tooltip .vs-row.bad .vs-lbl { color: #FFB3A5; }
.tooltip .vs-row.good canvas { background: #3E5B52; }
.tooltip .vs-row.bad canvas { background: #5F4750; }

.toasts { position: absolute; top: 12px; left: 50%; transform: translateX(-50%); display: grid; gap: 6px; justify-items: center; pointer-events: none; z-index: 8; width: max-content; max-width: calc(100% - 24px); }
.toast {
  background: var(--ink); color: #FFFFFF; font-weight: 700; padding: 9px 16px; border-radius: 999px;
  box-shadow: 0 8px 20px rgba(43, 52, 69, .25); animation: toastIn .35s var(--spring); transition: opacity .35s, transform .35s;
  text-align: center;
}
.toast.tip { background: #FFFFFF; color: var(--ink); box-shadow: 0 3px 0 var(--edge), 0 10px 24px rgba(43, 52, 69, .14); }
.toast.out, .foe.out { opacity: 0; transform: translateY(-8px); }
/* A new critter's card: placed by script wherever it hides the least road. */
.foe {
  position: absolute; z-index: 8; pointer-events: none; max-width: calc(100% - 24px);
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 8px 14px 8px 8px; border-radius: 18px;
  background: #FFFFFF; color: var(--ink); font-weight: 700; box-shadow: 0 3px 0 #F2D58E, 0 10px 24px rgba(43, 52, 69, .14);
  transition: opacity .35s, transform .35s;
}
.foe.show { animation: toastIn .35s var(--spring); }
.foe.stack { display: grid; grid-template-columns: auto 1fr; }
.foe.stack .vs { grid-column: 1 / -1; }
.foe > canvas { flex: none; background: #FFF4D6; border-radius: 12px; padding: 4px; box-sizing: content-box; }
.foe-name { display: grid; font-size: 12px; font-weight: 600; color: var(--ink-2); }
.foe-name b { font: 800 16px/1.1 var(--f-display); color: var(--ink); }
.foe.boss { box-shadow: 0 3px 0 #D8CFF7, 0 10px 24px rgba(60, 40, 120, .16); }
.foe.boss > canvas { background: #F1ECFF; }
.foe.boss .foe-name b { color: var(--lilac-deep); }
@keyframes toastIn { from { transform: translateY(-10px) scale(.9); opacity: 0; } }

/* The next wave, waiting beside the road where it comes in (when the dock has no room for it). */
.gates { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.gate {
  position: absolute; display: flex; gap: 3px; padding: 3px; border-radius: 999px;
  background: #FFFFFF; box-shadow: 0 3px 0 var(--edge), 0 8px 18px rgba(43, 52, 69, .14);
  animation: gateBob 2.4s ease-in-out infinite;
}
.gate::before { content: ""; position: absolute; width: 10px; height: 10px; border-radius: 2px; background: inherit; transform: rotate(45deg); }
.gate.t-up::before { top: -4px; left: calc(var(--at) - 5px); }
.gate.t-down::before { bottom: -4px; left: calc(var(--at) - 5px); }
.gate.t-left::before { left: -4px; top: calc(var(--at) - 5px); }
.gate.t-right::before { right: -4px; top: calc(var(--at) - 5px); }
.gate.t-up { transform-origin: var(--at) 0; }
.gate.t-down { transform-origin: var(--at) 100%; }
.gate.t-left { transform-origin: 0 var(--at); }
.gate.t-right { transform-origin: 100% var(--at); }
.gp { position: relative; display: inline-flex; align-items: center; gap: 1px; padding: 1px 8px 1px 2px; border-radius: 999px; background: #F2F5F9; }
.gp b { font: 800 13px/1 var(--f-display); font-variant-numeric: tabular-nums; }
.gp.new { background: #FFEFC2; }
.gate.boss { background: #F1ECFF; box-shadow: 0 3px 0 #D8CFF7, 0 8px 18px rgba(60, 40, 120, .16); }
.gate.boss .gp { background: #FFFFFF; }
.gp.boss { color: var(--lilac-deep); }
.gates.show .gate { animation: gateIn .55s var(--spring) both, gateBob 2.4s ease-in-out .55s infinite; }
.gates.out .gate { animation: none; opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.85); transition: opacity .3s, transform .4s; }
@keyframes gateIn { from { opacity: 0; transform: scale(.5); } }
@keyframes gateBob { 50% { transform: translateY(-2px); } }

.banner { position: absolute; left: 50%; top: 18%; transform: translateX(-50%); text-align: center; pointer-events: none; z-index: 4; white-space: nowrap; }
.banner.show { animation: bannerIn 1.9s both; }
.bn-title {
  font: 800 clamp(34px, 6vw, 56px)/1 var(--f-display); letter-spacing: -.03em; color: #FFFFFF;
  text-shadow: 0 2px 0 #B9C7D8, 0 4px 0 #A8B7CA, 0 6px 0 #97A7BC, 0 14px 24px rgba(43, 52, 69, .25);
}
.banner.boss .bn-title { color: #F1ECFF; text-shadow: 0 2px 0 #B5A6EE, 0 4px 0 #9C8AE4, 0 6px 0 #8773D6, 0 14px 24px rgba(60, 40, 120, .3); }
.banner.clear .bn-title { font-size: clamp(26px, 4.4vw, 40px); }
.bn-sub { margin-top: 10px; display: inline-block; background: rgba(43, 52, 69, .82); color: #FFFFFF; font-weight: 800; padding: 6px 14px; border-radius: 999px; }
@keyframes bannerIn {
  0% { opacity: 0; transform: translateX(-50%) translateY(14px) scale(.8); }
  14% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1.04); }
  22% { transform: translateX(-50%) scale(1); }
  82% { opacity: 1; transform: translateX(-50%) scale(1); }
  100% { opacity: 0; transform: translateX(-50%) translateY(-10px) scale(.98); }
}

/* ---------- screens ---------- */
.screen { position: absolute; inset: 0; z-index: 20; overflow: auto; }
.screen-inner {
  width: min(1080px, 100%); margin: 0 auto;
  padding-block: max(22px, env(safe-area-inset-top)) max(22px, env(safe-area-inset-bottom));
  padding-inline: max(16px, env(safe-area-inset-left)) max(16px, env(safe-area-inset-right));
}
.screen-head { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
.screen-head h2 { margin: 0; font: 800 clamp(26px, 4vw, 36px)/1.05 var(--f-display); letter-spacing: -.02em; flex: 1; text-wrap: balance; }

.screen-title {
  display: grid; align-items: center; justify-items: start;
  padding-block: 24px; padding-inline: clamp(16px, 6vw, 88px);
  background: linear-gradient(90deg, rgba(247, 251, 253, .94) 0%, rgba(247, 251, 253, .8) 30%, rgba(247, 251, 253, 0) 52%);
}
.title-card { max-width: 440px; display: grid; gap: 18px; animation: rise .7s var(--spring) both; }
@keyframes rise { from { transform: translateY(18px); opacity: 0; } }
.logo { display: flex; align-items: center; gap: 12px; }
.logo-gem { width: clamp(44px, 6vw, 64px); height: auto; filter: drop-shadow(0 8px 10px rgba(233, 122, 146, .35)); animation: float 3.5s ease-in-out infinite; }
@keyframes float { 50% { transform: translateY(-6px) rotate(3deg); } }
.logo h1 {
  margin: 0; font: 800 clamp(56px, 7.2vw, 104px)/.9 var(--f-display); letter-spacing: -.045em; color: var(--ink);
  text-shadow: 0 2px 0 #CAD5E2, 0 4px 0 #BCC8D7, 0 6px 0 #AFBCCD, 0 8px 0 #A3B1C3, 0 18px 28px rgba(43, 52, 69, .2);
}
.tagline { margin: 0; font-size: 18px; line-height: 1.45; color: var(--ink-2); max-width: 32ch; text-wrap: pretty; }
.title-actions { display: flex; gap: 12px; flex-wrap: wrap; }
.badge { display: inline-flex; align-items: center; gap: 4px; background: #FFF3D6; color: var(--gold-deep); border-radius: 999px; padding: 4px 9px 4px 6px; font: 800 14px/1 var(--f-display); font-variant-numeric: tabular-nums; }
.badge .ic { width: 15px; height: 15px; }
.records { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; max-width: 300px; }
.records li { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; color: var(--ink-2); border-bottom: 1px dashed var(--line); padding-bottom: 4px; }
.records b { color: var(--ink); font-variant-numeric: tabular-nums; }
.records .moon-ic { margin-left: 5px; vertical-align: -2px; }
.title-foot { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.keys { font-size: 12px; color: var(--ink-3); font-weight: 600; }
/* Phones: play full screen from the Home Screen. */
.a2hs {
  display: flex; align-items: center; gap: 12px; padding: 10px; border-radius: 18px;
  background: #FFFFFF; box-shadow: 0 4px 0 var(--edge), 0 12px 26px rgba(43, 52, 69, .10);
  animation: rise .7s var(--spring) .3s both; transition: opacity .25s, transform .3s;
}
.a2hs.out { opacity: 0; transform: translateY(8px) scale(.97); }
.a2hs-icon { width: 44px; height: 44px; border-radius: 12px; flex: none; box-shadow: 0 2px 0 rgba(43, 52, 69, .08), 0 4px 10px rgba(233, 122, 146, .25); }
.a2hs-body { flex: 1; min-width: 0; display: grid; gap: 5px; justify-items: start; }
.a2hs-body > b { font: 800 16px/1.05 var(--f-display); letter-spacing: -.01em; }
.a2hs-how { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; font-size: 13px; font-weight: 700; color: var(--ink-2); }
.a2hs-key { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 8px; background: #EAF6FE; color: var(--sky-deep); font-style: normal; }
.a2hs-key .ic { width: 16px; height: 16px; }
.a2hs-to { width: 13px; height: 13px; color: var(--ink-3); stroke-width: 2.6; }
.a2hs-go { padding: 7px 12px; gap: 6px; }
.a2hs-go .ic { width: 16px; height: 16px; }
.a2hs-x {
  appearance: none; border: 0; cursor: pointer; flex: none; align-self: flex-start;
  width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; background: #F2F5F9; color: var(--ink-3);
}
.a2hs-x .ic { width: 14px; height: 14px; stroke-width: 2.4; }
.a2hs-x:focus-visible { outline: 3px solid var(--sky-deep); outline-offset: 2px; }
/* After the first win on a computer: the gem drops into the dock, again and again. */
.m-install { display: flex; align-items: center; gap: 12px; padding: 8px 10px 8px 8px; border-radius: 16px; background: #F2F5F9; }
.dock-art { display: block; flex: none; width: 112px; height: 36px; overflow: visible; }
.dock-gem { transform-box: fill-box; transform-origin: 50% 100%; animation: dockDrop 2.8s var(--spring) infinite; }
@keyframes dockDrop {
  0% { transform: translateY(-30px); opacity: 0; }
  12% { opacity: 1; }
  34% { transform: translateY(0) scale(1.08, .9); }
  44%, 88% { transform: translateY(0) scale(1); opacity: 1; }
  100% { transform: translateY(0) scale(1); opacity: 0; }
}
.m-install b { flex: 1; font: 800 16px/1.1 var(--f-display); }
.m-install .btn { gap: 6px; }
.m-install .btn .ic { width: 16px; height: 16px; }

.screen-maps, .screen-tree { background: rgba(236, 246, 250, .86); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.stars-btn { gap: 6px; font-variant-numeric: tabular-nums; }
.stars-btn .ic { width: 18px; height: 18px; }
.stars-btn > span:nth-child(2) { font: 800 17px/1 var(--f-display); }
.sb-lbl { margin-left: 6px; padding-left: 10px; border-left: 2px solid var(--line); color: var(--ink-2); }
.map-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: 18px; }
.map-card {
  appearance: none; border: 0; cursor: pointer; text-align: left; padding: 10px;
  background: #FFFFFF; border-radius: var(--r-lg); display: grid; gap: 4px; align-content: start;
  box-shadow: 0 5px 0 var(--edge), 0 16px 34px rgba(43, 52, 69, .10);
  transition: transform .25s var(--spring), box-shadow .25s;
}
@media (hover: hover) {
  .map-card:hover:not(:disabled) { transform: translateY(-5px) rotate(-.4deg); box-shadow: 0 9px 0 var(--edge), 0 22px 40px rgba(43, 52, 69, .14); }
}
.map-card:active:not(:disabled) { transform: scale(.98); }
.map-card:disabled { cursor: not-allowed; }
.mc-art { position: relative; border-radius: 16px; overflow: hidden; aspect-ratio: 20 / 12; max-width: 100%; background: #DDEFE5; }
.mc-art canvas { display: block; width: 100%; height: 100%; }
.mc-badge { position: absolute; top: 10px; left: 10px; display: inline-flex; align-items: center; gap: 4px; background: #FFFFFF; font-weight: 800; font-size: 12px; padding: 5px 10px 5px 7px; border-radius: 999px; box-shadow: 0 2px 0 var(--edge); }
.mc-lock {
  position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; gap: 8px; text-align: center; padding: 16px;
  background: rgba(238, 242, 246, .82); -webkit-backdrop-filter: grayscale(1) blur(2px); backdrop-filter: grayscale(1) blur(2px);
  color: var(--ink-2); font-weight: 700;
}
.mc-lock .ic { width: 28px; height: 28px; }
.mc-body { padding: 8px 6px 4px; display: grid; gap: 8px; }
.mc-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.mc-top h3 { margin: 0; font: 800 23px/1.1 var(--f-display); letter-spacing: -.015em; }
.mc-num { font: 800 14px/1 var(--f-display); color: var(--ink-3); letter-spacing: .06em; }
.mc-body p { margin: 0; color: var(--ink-2); }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { display: inline-flex; align-items: center; gap: 4px; background: #F1F5F9; border-radius: 999px; padding: 4px 10px; font-size: 12px; font-weight: 700; color: var(--ink-2); }
.chip .ic { width: 13px; height: 13px; }
.chip-star { background: #FFF6DE; color: var(--gold-deep); }
.chip-music { background: #F1ECFF; color: var(--lilac-deep); }
.mc-best { font-size: 12px; font-weight: 700; color: var(--ink-3); }

/* Night: a map's B-side. The moon sits in the card's corner: a price in stars, then a switch. */
.mc-slot { position: relative; display: grid; perspective: 900px; }
.mc-moon {
  position: absolute; top: 18px; right: 18px; z-index: 3; appearance: none; border: 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px; height: 36px; min-width: 36px; padding: 0 9px; border-radius: 999px;
  font: 800 13px/1 var(--f-ui); color: #FFF3C4; background: #232A5C;
  box-shadow: 0 3px 0 #141838, 0 6px 16px rgba(16, 20, 56, .35);
  transition: transform .2s var(--spring), background .2s, color .2s;
}
.mc-moon .ic { width: 18px; height: 18px; }
.mc-moon span { display: inline-flex; align-items: center; gap: 2px; }
.mc-moon .star-ic { width: 13px; height: 13px; color: var(--gold); fill: var(--gold); stroke: none; }
.mc-moon.buy .ic:first-child { animation: moonGlow 2.6s ease-in-out infinite; }
.mc-moon.poor { color: #A7AFD6; }
.mc-moon.poor .star-ic { color: #8E97C2; fill: #8E97C2; }
.mc-moon.on { background: #FFFFFF; color: var(--gold-deep); box-shadow: 0 3px 0 var(--edge), 0 6px 16px rgba(16, 20, 56, .25); }
@media (hover: hover) { .mc-moon:hover { transform: translateY(-2px) rotate(-8deg); } }
.mc-moon:active { transform: scale(.94); }
.mc-moon:focus-visible { outline: 3px solid var(--lilac); outline-offset: 2px; }
.mc-moon.bad { animation: shake .4s; }
@keyframes moonGlow { 50% { filter: drop-shadow(0 0 5px #FFE58A); } }
.mc-slot.bought .mc-moon { animation: pop .5s var(--spring); }

.map-card.flip { animation: flipCard .36s ease-in-out; }
@keyframes flipCard { 0% { transform: rotateY(0); } 50% { transform: rotateY(90deg) scale(.97); } 100% { transform: rotateY(0); } }
.map-card.night { background: #1E2452; color: #EEF0FF; box-shadow: 0 5px 0 #11153A, 0 16px 34px rgba(16, 20, 56, .3); }
@media (hover: hover) { .map-card.night:hover:not(:disabled) { box-shadow: 0 9px 0 #11153A, 0 22px 40px rgba(16, 20, 56, .36); } }
.map-card.night .mc-art { background: #1A1F48; }
.map-card.night .mc-num, .map-card.night .mc-best { color: #8E97C2; }
.map-card.night .mc-body p { color: #B9C0E4; }
.map-card.night .chip { background: rgba(255, 255, 255, .1); color: #D5DAF5; }
.map-card.night .chip-music { color: #FFE58A; }
.map-card.night .chip-star { background: rgba(247, 192, 74, .16); color: var(--gold); }
.map-card.night .chip-hard { background: rgba(255, 126, 107, .2); color: #FFB3A6; }
.map-card.night .mc-badge { background: #FFF3C4; color: #232A5C; }
.moon-ic { width: 14px; height: 14px; color: #6E5BC4; }
/* Night on preview: a veil over the night card says what night is, and sells it. */
.night-veil {
  position: absolute; inset: 0; z-index: 1; border-radius: var(--r-lg); cursor: pointer;
  display: grid; place-content: center; justify-items: center; gap: 10px; padding: 16px; text-align: center;
  background: radial-gradient(circle at 50% 40%, rgba(30, 36, 92, .62), rgba(16, 20, 56, .86));
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); color: #EEF0FF;
  animation: veilIn .32s ease-out both;
}
.night-veil.out { animation: veilOut .2s ease-in both; }
@keyframes veilIn { from { opacity: 0; transform: scale(.97); } }
@keyframes veilOut { to { opacity: 0; transform: scale(.97); } }
.nv-moon .ic { width: 44px; height: 44px; color: #FFE58A; fill: rgba(255, 229, 138, .18); filter: drop-shadow(0 0 12px rgba(255, 229, 138, .55)); animation: float 3.5s ease-in-out infinite; }
.nv-title { font: 800 24px/1 var(--f-display); letter-spacing: .02em; }
.nv-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }
.nv-chips .chip { background: rgba(255, 126, 107, .2); color: #FFC2B8; font-size: 13px; padding: 5px 11px; }
.nv-chips .chip .ic { width: 14px; height: 14px; }
.nv-buy { --c: #FFE58A; --c-edge: #C9A23A; --c-ink: #232A5C; gap: 6px; margin-top: 4px; min-width: 132px; }
.nv-buy .ic { width: 18px; height: 18px; }
.nv-buy span { display: inline-flex; align-items: center; gap: 3px; }
.nv-buy .star-ic { width: 15px; height: 15px; color: #C98A10; fill: #C98A10; stroke: none; }
.nv-buy.poor { --c: #3A4170; --c-edge: #262C55; --c-ink: #A7AFD6; }
.nv-buy.poor .star-ic { color: #8E97C2; fill: #8E97C2; }
.nv-buy.bad { animation: shake .4s; }
@media (prefers-reduced-motion: reduce) { .night-veil, .night-veil.out, .nv-moon .ic { animation: none; } }
@media (prefers-reduced-motion: reduce) { .map-card.flip, .mc-moon.buy .ic:first-child, .mc-slot.bought .mc-moon { animation: none; } }

/* The map still to come: a "???" card; tapping it opens the sign-up. */
.mc-next .mc-art, .nx-art { background: #E4DDFB; }
.mc-q {
  position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none;
  font: 800 clamp(64px, 7vw, 92px)/1 var(--f-display); color: #F1ECFF;
  text-shadow: 0 2px 0 #B5A6EE, 0 4px 0 #9C8AE4, 0 6px 0 #8773D6, 0 8px 0 #7B66D1, 0 18px 28px rgba(60, 40, 120, .32);
  animation: float 3.5s ease-in-out infinite;
}
.mc-next .mc-top h3 { color: var(--lilac-deep); letter-spacing: .06em; }
.mc-joined { color: var(--mint-deep); }
.mc-joined .ic { width: 14px; height: 14px; stroke-width: 3; }
.nx-art { position: relative; border-radius: 16px; overflow: hidden; aspect-ratio: 20 / 8; }
.nx-art canvas { display: block; width: 100%; height: 100%; }
.nx-slot { display: grid; }
.nx-art .mc-q { font-size: 76px; }
.modal.next h2 { color: var(--lilac-deep); }
.modal.next.joined .mc-q { animation: pop .5s var(--spring), float 3.5s ease-in-out .5s infinite; }
.notify { display: flex; gap: 8px; }
/* 16px: iPhones zoom into any smaller field. */
.notify input {
  flex: 1; width: 100%; min-width: 0; font: 600 16px var(--f-ui); color: var(--ink); padding: 11px 14px;
  background: #F7F5FF; border: 2px solid #E4DDFB; border-radius: var(--r-md); outline: none;
  transition: border-color .2s, box-shadow .2s, background .2s;
}
.notify input::placeholder { color: #A9A2C8; }
.notify input:focus { border-color: var(--lilac); background: #FFFFFF; box-shadow: 0 0 0 4px rgba(168, 149, 238, .22); }
.notify input.bad { border-color: var(--coral); animation: shake .4s; }
.notify .btn { flex: none; gap: 6px; }
.notify .ic { width: 18px; height: 18px; }
.notify-done {
  appearance: none; border: 0; cursor: pointer; justify-self: center; display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 18px 11px 14px; border-radius: 999px; background: #E3F6EC; color: var(--mint-deep);
  font: 800 16px/1 var(--f-display); animation: pop .45s var(--spring); transition: background .2s, color .2s;
}
.notify-done .ic { width: 20px; height: 20px; stroke-width: 3; }
.nd-on, .nd-off { display: inline-flex; align-items: center; gap: 8px; }
.nd-off { display: none; }
.notify-done:focus-visible { outline: 3px solid var(--lilac); outline-offset: 3px; }
.notify-done:focus-visible .nd-on { display: none; }
.notify-done:focus-visible .nd-off { display: inline-flex; }
@media (hover: hover) {
  .notify-done:hover:not(.danger) { background: #FFE9E4; color: var(--coral-deep); }
  .notify-done:hover .nd-on { display: none; }
  .notify-done:hover .nd-off { display: inline-flex; }
}
.notify-done.danger { background: var(--coral); color: #FFFFFF; }
.notify-done.bad { animation: shake .4s; }
.notify-privacy { font-size: 12px; font-weight: 700; color: var(--ink-3); justify-self: center; }

/* A sign-up map is a present for joining the new-map list: gift-wrapped, in full color. */
.map-card.gift { cursor: pointer; }
.map-card.gift .mc-art canvas { filter: saturate(.85) brightness(.97); }
.ribbon { position: absolute; inset: 0; pointer-events: none; }
.ribbon i { position: absolute; display: block; transition: transform .55s cubic-bezier(.6, -0.3, .7, 1), opacity .55s; }
.rb-v { top: 0; bottom: 0; left: 50%; width: 10%; transform: translateX(-50%); background: linear-gradient(90deg, #EE6B9C, #FF9CC3 35%, #FFC2DA 50%, #FF9CC3 65%, #EE6B9C); box-shadow: 0 0 14px rgba(140, 40, 90, .25); }
.rb-h { left: 0; right: 0; top: 40%; height: 14%; transform: translateY(-50%); background: linear-gradient(180deg, #EE6B9C, #FF9CC3 35%, #FFC2DA 50%, #FF9CC3 65%, #EE6B9C); box-shadow: 0 0 14px rgba(140, 40, 90, .25); }
.bow {
  position: absolute; left: 50%; top: 40%; width: 27%; max-width: 132px; transform: translate(-50%, -58%);
  filter: drop-shadow(0 5px 6px rgba(120, 40, 90, .32)); transform-origin: 50% 45%; animation: bow 3.2s ease-in-out infinite;
  transition: opacity .5s .1s;
}
@keyframes bow { 0%, 100% { rotate: 0deg; } 50% { rotate: 4deg; scale: 1.04; } }
@media (hover: hover) { .map-card.gift:hover .bow { animation-duration: .7s; } }
.mc-unwrap {
  position: absolute; left: 50%; bottom: 10px; transform: translateX(-50%); white-space: nowrap;
  display: inline-flex; align-items: center; gap: 6px; padding: 8px 15px 8px 12px; border-radius: 999px;
  background: var(--lilac); color: #FFFFFF; font: 800 15px/1 var(--f-display); box-shadow: 0 3px 0 var(--lilac-deep), 0 8px 18px rgba(60, 40, 120, .25);
  transition: transform .25s var(--spring);
}
.mc-unwrap .ic { width: 17px; height: 17px; }
@media (hover: hover) { .map-card.gift:hover .mc-unwrap { transform: translateX(-50%) translateY(-2px) scale(1.04); } }
/* The sign-up with a present: the wrapped map, unwrapped the moment you join. */
.nx-art.nx-gift { aspect-ratio: 20 / 12; background: #D8D0F2; }
.nx-gift canvas { transition: filter .6s; filter: saturate(.85); }
.modal.gift.joined .nx-gift canvas { filter: none; }
.modal.gift.joined .rb-v { transform: translateX(-50%) translateY(105%); }
.modal.gift.joined .rb-h { transform: translateY(-50%) translateX(105%); }
.modal.gift.joined .bow { opacity: 0; animation: bowOff .7s var(--spring) forwards; }
@keyframes bowOff { 40% { translate: 0 -18%; scale: 1.25; rotate: -8deg; } 100% { translate: 0 -40%; scale: .6; rotate: 12deg; } }
.nx-play { gap: 8px; animation: pop .45s var(--spring) .25s both; }
.nx-play .ic { width: 18px; height: 18px; }

/* ---------- skill tree ---------- */
.tree-wrap { height: 100%; display: grid; grid-template-rows: auto minmax(0, 1fr); width: min(1280px, 100%); }
.tree-bank { display: flex; align-items: center; gap: 10px; }
.pill.big b { font-size: 22px; }
.spent { font-size: 12px; font-weight: 700; color: var(--ink-3); }
#tree-reset .ic { width: 16px; height: 16px; }
.tree-layout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 16px; min-height: 0; }
.tree-board {
  position: relative; overflow: auto; border-radius: var(--r-lg); display: flex; padding: 8px;
  background-color: #F5F9FB;
  background-image: radial-gradient(#D6E0EA 1.2px, transparent 1.4px);
  background-size: 22px 22px;
  box-shadow: inset 0 0 0 2px #E3EBF2;
}
.tree-inner { margin: auto; position: relative; flex: none; }
.tree-canvas { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.tree-links { position: absolute; inset: 0; overflow: visible; }
.tree-links .orbit { fill: none; stroke: #DCE5EE; stroke-width: 1.5; stroke-dasharray: 3 7; }
.tree-links line { stroke-linecap: round; }
.tree-links .track { stroke: #FFFFFF; stroke-width: 12; }
.tree-links .dim { stroke: #D9E1EA; stroke-width: 6; }
.tree-links .open { stroke: var(--lc); stroke-width: 5; stroke-dasharray: 2 9; opacity: .8; }
.tree-links .lit { stroke: var(--lc); stroke-width: 7; }
.branch-label {
  position: absolute; transform: translate(-50%, -50%); white-space: nowrap;
  font: 800 13px/1 var(--f-ui); letter-spacing: .14em; text-transform: uppercase; color: var(--bc);
  background: #FFFFFF; padding: 7px 12px; border-radius: 999px; box-shadow: 0 3px 0 var(--edge);
}

.node {
  --fill: #E8EDF3; --side: #CBD4DF; --ink: #A2ABBB; --ring: transparent;
  position: absolute; width: 60px; height: 66px; margin: -33px 0 0 -30px; padding: 0;
  appearance: none; border: 0; background: none; cursor: pointer;
  transition: transform .22s var(--spring);
}
@media (hover: hover) { .node:hover { transform: translateY(-3px) scale(1.05); } }
.node .hex { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.hx-side { fill: var(--side); }
.hx-top { fill: var(--fill); stroke: var(--ring); stroke-width: 3; }
.node-ic { position: absolute; left: 50%; top: 46%; transform: translate(-50%, -50%); width: 26px; height: 26px; color: var(--ink); stroke-width: 2.1; }
.node.avail, .node.partial { --fill: #FFFFFF; --side: #D5DEE9; --ink: var(--bc); --ring: var(--bc); }
.node.partial { --fill: var(--bcs); }
.node.maxed { --fill: var(--bc); --side: var(--bcd); --ink: #FFFFFF; --ring: transparent; }
/* Forks: the side you didn't pick greys out with a lock; picking outlines what you'd lose. */
.node.blocked { --fill: #EEF1F5; --side: #D9DFE7; --ink: #C3CAD6; }
.node-lock { position: absolute; top: -3px; right: -3px; width: 20px; height: 20px; padding: 3px; border-radius: 50%; background: #FFFFFF; color: var(--ink-3); box-shadow: 0 2px 0 var(--edge); stroke-width: 2.4; }
.node.rival .hx-top { stroke: var(--coral); stroke-width: 3; stroke-dasharray: 5 4; }
.np-fork { margin: 0; display: flex; gap: 6px; align-items: center; font-size: 13px; color: var(--coral-deep); }
.np-fork .ic { width: 15px; height: 15px; }
.node.root { --fill: #FF9EB2; --side: #E27A90; --ink: #FFFFFF; --ring: transparent; }
.node.key { width: 72px; height: 80px; margin: -40px 0 0 -36px; }
.node.key .node-ic { width: 30px; height: 30px; }
.node.key.maxed .hx-top { stroke: #F7C04A; stroke-width: 3; }
.node.can .hex { animation: bob 1.8s ease-in-out infinite; }
.node.can::after {
  content: ""; position: absolute; top: -4px; right: -4px; width: 14px; height: 14px; border-radius: 50%;
  background: var(--gold); box-shadow: 0 0 0 3px #FFFFFF;
}
.node.sel::before {
  content: ""; position: absolute; inset: -12px; border-radius: 50%;
  background: radial-gradient(closest-side, var(--bcs, #FFE3E8), transparent);
}
.node.pop { animation: pop .55s var(--spring); }
@keyframes bob { 50% { transform: translateY(-3px); } }
@keyframes pop { 0% { transform: scale(.7); } 60% { transform: scale(1.18); } 100% { transform: scale(1); } }
.pips { position: absolute; bottom: -9px; left: 50%; transform: translateX(-50%); display: flex; gap: 3px; padding: 3px 5px; background: #FFFFFF; border-radius: 999px; box-shadow: 0 2px 0 var(--edge); }
.pips i { width: 6px; height: 6px; border-radius: 50%; background: #D5DDE7; }
.pips i.on { background: var(--bc); }

.node-panel { padding: 18px; align-self: start; display: grid; gap: 12px; max-height: 100%; overflow: auto; }
.np-head { display: flex; align-items: center; gap: 12px; }
.np-icon { width: 52px; height: 52px; border-radius: 16px; display: grid; place-items: center; background: var(--bcs); color: var(--bc); flex: none; }
.np-icon .ic { width: 28px; height: 28px; }
.np-branch { font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--bc); }
.np-head h3 { margin: 2px 0 0; font: 800 24px/1.05 var(--f-display); letter-spacing: -.015em; }
.np-rank { display: flex; justify-content: space-between; align-items: baseline; background: #F2F5F9; border-radius: 12px; padding: 8px 12px; font-weight: 700; color: var(--ink-2); }
.np-rank b { font: 800 18px/1 var(--f-display); color: var(--ink); font-variant-numeric: tabular-nums; }
.np-desc { margin: 0; font-size: 15px; line-height: 1.5; max-width: 40ch; }
.np-now { margin: -4px 0 0; font-size: 13px; color: var(--ink-3); }
.np-buy { width: 100%; }
.np-buy .ic { width: 18px; height: 18px; }
.np-note { margin: 0; font-size: 13px; color: var(--ink-2); }
.np-lock { margin: 0; display: flex; gap: 8px; align-items: flex-start; color: var(--ink-2); }
.np-lock .ic { margin-top: 2px; }
.np-maxed { display: flex; align-items: center; gap: 8px; justify-content: center; font-weight: 800; padding: 10px; background: #FFF6DE; border-radius: 14px; color: var(--gold-deep); }

/* ---------- modal ---------- */
.modal-wrap { position: absolute; inset: 0; z-index: 50; display: grid; place-items: center; padding: 16px; background: rgba(43, 52, 69, .28); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.modal { width: min(460px, 100%); padding: 26px; display: grid; gap: 14px; animation: modalIn .4s var(--spring); max-height: 100%; overflow: auto; }
@keyframes modalIn { from { transform: translateY(16px) scale(.94); opacity: 0; } }
.modal h2 { margin: 0; font: 800 34px/1.02 var(--f-display); letter-spacing: -.025em; text-wrap: balance; }
.modal.win h2 { color: var(--mint-deep); }
.modal.lose h2 { color: var(--coral-deep); }
.m-sub { margin: -4px 0 0; color: var(--ink-2); font-size: 15px; }
.m-note { margin: 0; color: var(--ink-2); }
.m-note .ic { width: 16px; height: 16px; vertical-align: -3px; margin-right: 2px; }
.end-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.end-stats div { background: #F2F5F9; border-radius: 14px; padding: 10px; display: grid; gap: 2px; }
.end-stats b { font: 800 26px/1 var(--f-display); font-variant-numeric: tabular-nums; }
.end-stats span { font-size: 12px; font-weight: 700; color: var(--ink-2); }
.end-stats .st { background: #FFF6DE; }
.end-stats .st b { color: var(--gold-deep); }
.m-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 4px; }
.m-actions .btn:first-child { grid-column: 1 / -1; }
.m-actions:empty { display: none; }
.m-actions .ic { width: 18px; height: 18px; }
.ic-solid { fill: currentColor; }
.m-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.m-corner { flex: none; margin-bottom: -10px; }
.m-corner.off { --c: var(--ink); --c-edge: #11161F; --c-ink: #FFFFFF; }
.pz-run { display: flex; align-items: center; gap: 12px; background: #F2F5F9; border-radius: 14px; padding: 10px 12px; }
.pz-lives { display: inline-flex; align-items: center; gap: 4px; }
.pz-lives .ic { width: 18px; height: 18px; fill: var(--coral); stroke: none; }
.pz-lives.low b { color: var(--coral-deep); }
.pz-lives b, .pz-wave { font: 800 20px/1 var(--f-display); font-variant-numeric: tabular-nums; }
.pz-wave span { font-size: 14px; color: var(--ink-3); margin-left: 1px; }
.pz-track { flex: 1; min-width: 0; display: grid; grid-template-columns: repeat(var(--n), 1fr); align-items: center; gap: 3px; }
.pz-track i { height: 10px; border-radius: 3px; background: var(--line); }
.pz-track i.boss { height: 16px; background: #E4DDFB; }
.pz-track i.on { background: var(--mint-deep); }
.pz-track i.boss.on { background: var(--lilac-deep); }
.pz-track i.now { background: var(--coral); animation: pzNow 1.2s ease-in-out infinite; }
@keyframes pzNow { 50% { opacity: .35; } }

/* ---------- Endless cards ----------
   Three cards: art, name, the up (green) and the down (red). A note in the art's corner says the card
   has a sound: trying the card lifts it, the note turns into a dancing equalizer, and a check confirms it. */
.modal.pick { width: min(660px, 100%); }
.modal.pick .m-head { align-items: center; }
.hand-gold {
  flex: none; display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px 6px 8px; border-radius: 999px;
  background: #FFF6DE; color: var(--gold-deep); font: 800 17px/1 var(--f-display); font-variant-numeric: tabular-nums;
}
.hand-gold .coin { width: 20px; height: 20px; }
.hand { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; padding-bottom: 8px; perspective: 900px; }
.hand-card {
  position: relative; appearance: none; border: 0; cursor: pointer; text-align: left; color: var(--ink);
  display: grid; gap: 6px; align-content: start; padding: 10px 10px 14px; border-radius: 18px; background: #FFFFFF;
  box-shadow: 0 4px 0 var(--cc-deep), inset 0 0 0 2px var(--cc-soft), 0 12px 24px rgba(43, 52, 69, .12);
  transition: transform .25s var(--spring), box-shadow .2s;
  animation: dealIn .5s var(--spring) both;
}
.hand-card:nth-child(2) { animation-delay: .07s; }
.hand-card:nth-child(3) { animation-delay: .14s; }
@keyframes dealIn { from { opacity: 0; transform: translateY(28px) rotate(-5deg) scale(.9); } }
.hand.flip .hand-card { animation-name: flipIn; animation-duration: .45s; }
@keyframes flipIn { from { transform: rotateY(90deg); } }
@media (hover: hover) { .hand-card:hover { transform: translateY(-6px) rotate(-1deg); } }
.hand-card.on { transform: translateY(-6px); box-shadow: 0 6px 0 var(--cc-deep), inset 0 0 0 3px var(--cc), 0 16px 30px rgba(43, 52, 69, .18); }
.hand-card:focus-visible { outline: 3px solid var(--sky-deep); outline-offset: 3px; }
.cd-art {
  position: relative; display: grid; place-items: center; height: 72px; border-radius: 12px; color: #FFFFFF;
  background: linear-gradient(160deg, var(--cc), var(--cc-deep));
}
.cd-art > .ic { width: 40px; height: 40px; stroke-width: 1.9; filter: drop-shadow(0 2px 0 rgba(43, 52, 69, .2)); }
.cd-n { position: absolute; top: 7px; left: 7px; padding: 3px 6px; border-radius: 999px; background: #FFFFFF; color: var(--cc-deep); font: 800 12px/1 var(--f-display); font-style: normal; }
.cd-play { position: absolute; top: 7px; right: 7px; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; background: rgba(255, 255, 255, .26); transition: background .2s; }
.cd-play > * { grid-area: 1 / 1; transition: opacity .2s, transform .25s var(--spring); }
.cd-note { width: 15px; height: 15px; stroke-width: 2.4; }
.cd-eq { height: 13px; display: flex; align-items: flex-end; gap: 2px; opacity: 0; transform: scale(.4); }
.cd-eq b { width: 3px; height: 30%; border-radius: 2px; background: #FFFFFF; animation: eq .5s ease-in-out infinite alternate; }
.cd-eq b:nth-child(2) { animation-delay: -.2s; }
.cd-eq b:nth-child(3) { animation-delay: -.35s; }
.hand-card.on .cd-play { background: rgba(255, 255, 255, .38); }
.hand-card.on .cd-note { opacity: 0; transform: scale(.4); }
.hand-card.on .cd-eq { opacity: 1; transform: none; }
/* Nothing playing yet: the notes nod along, asking to be tried. */
.hand:not(:has(.on)) .cd-note { animation: nod 1.2s ease-in-out infinite; }
.hand:not(:has(.on)) .hand-card:nth-child(2) .cd-note { animation-delay: .4s; }
.hand:not(:has(.on)) .hand-card:nth-child(3) .cd-note { animation-delay: .8s; }
@keyframes nod { 0%, 60%, 100% { transform: none; } 30% { transform: translateY(-2px) rotate(-10deg) scale(1.12); } }
@keyframes eq { to { height: 100%; } }
.cd-name { font: 800 17px/1.1 var(--f-display); letter-spacing: -.01em; }
.cd-line { display: flex; align-items: center; gap: 6px; min-height: 26px; padding: 3px 8px; border-radius: 10px; font-size: 12.5px; font-weight: 800; line-height: 1.15; }
.cd-line > span { display: flex; align-items: center; flex-wrap: wrap; gap: 2px 3px; min-width: 0; }
.cd-line .ic { width: 15px; height: 15px; flex: none; }
.cd-line canvas { flex: none; }
.cd-up { background: #E3F6EC; color: var(--mint-deep); }
.cd-down { background: #FDE6E1; color: var(--coral-deep); }
.cd-mark { flex: none; width: 0; height: 0; border-inline: 5px solid transparent; }
.cd-up .cd-mark { border-bottom: 7px solid currentColor; }
.cd-down .cd-mark { border-top: 7px solid currentColor; }
.cd-heart { fill: var(--coral); stroke: none; }
.cd-go {
  position: absolute; left: 50%; bottom: -13px; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  background: var(--cc); color: #FFFFFF; box-shadow: 0 3px 0 var(--cc-deep); transform: translateX(-50%) scale(0); transition: transform .25s var(--spring);
}
.cd-go .ic { width: 18px; height: 18px; stroke-width: 3; }
.hand-card.on .cd-go { transform: translateX(-50%) scale(1); }
@media (hover: hover) { .hand-card:hover .cd-go { transform: translateX(-50%) scale(1); } }
.modal.pick .m-actions { display: flex; justify-content: center; margin-top: 0; }
.btn.reroll { gap: 6px; font-variant-numeric: tabular-nums; }
.btn.reroll .coin { width: 16px; height: 16px; }
.btn.reroll.bad { animation: shake .4s; }
/* The cards a run has: in the hand, the pause and the end of the run. */
.owned { display: flex; flex-wrap: wrap; gap: 6px; }
.own { position: relative; width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; color: #FFFFFF; background: var(--cc); box-shadow: 0 2px 0 var(--cc-deep); }
.own .ic { width: 17px; height: 17px; }
.own b { position: absolute; top: -5px; right: -5px; padding: 2px 4px; border-radius: 6px; background: var(--ink); color: #FFFFFF; font: 800 10px/1 var(--f-ui); }
.bn-sub .bn-ic { width: 15px; height: 15px; vertical-align: -2px; margin-right: 2px; color: #FFB37A; }
.banner.card .bn-title { color: #FFFFFF; text-shadow: 0 2px 0 var(--cc), 0 4px 0 var(--cc-deep), 0 6px 0 var(--cc-deep), 0 14px 24px rgba(43, 52, 69, .3); }
/* Narrow screens: one card per row, the art beside the lines, the check at the end. */
@media (max-width: 560px) {
  .hand { grid-template-columns: minmax(0, 1fr); gap: 10px; padding-bottom: 0; }
  .hand-card { grid-template-columns: 58px minmax(0, 1fr); column-gap: 10px; row-gap: 4px; padding: 8px 12px 8px 8px; }
  .modal.pick h2 { font-size: 26px; }
  .hand-card > :not(.cd-art):not(.cd-go) { grid-column: 2; }
  .cd-art { grid-row: 1 / span 3; height: auto; min-height: 76px; }
  .cd-art > .ic { width: 30px; height: 30px; margin-bottom: 22px; }
  .cd-play { top: auto; right: auto; bottom: 7px; left: 50%; width: 22px; height: 22px; margin-left: -11px; }
  .cd-note { width: 13px; height: 13px; }
  .cd-name { font-size: 16px; }
  .cd-line { min-height: 22px; padding: 2px 7px; font-size: 12px; }
  .cd-go { left: auto; right: -8px; bottom: auto; top: 50%; transform: translateY(-50%) scale(0); }
  .hand-card.on .cd-go { transform: translateY(-50%) scale(1); }
  @media (hover: hover) { .hand-card:hover .cd-go { transform: translateY(-50%) scale(1); } }
}

/* ---------- responsive ---------- */
@media (max-width: 1360px) {
  .tb { width: 60px; height: 80px; }
  .build-bar { gap: 6px; }
}
@media (max-width: 1100px) {
  .wave-preview { display: none; }
  .seq { display: none; }
  .band { max-width: 360px; }
}
@media (max-width: 860px) {
  #app { gap: 8px; padding-block: max(8px, env(safe-area-inset-top)) max(8px, env(safe-area-inset-bottom)); }
  .dock { flex-wrap: wrap; gap: 8px; padding: 8px; }
  /* The row scrolls, so it clips: room above for a picked tower to lift into, taken back with the margin. */
  .build-bar { width: 100%; overflow-x: auto; padding-top: 5px; margin-top: -5px; padding-bottom: 4px; }
  .tb { width: 62px; height: 76px; flex: none; }
  .wave-box { margin-left: 0; flex: 1; justify-content: flex-end; }
  .abilities { padding-left: 0; border-left: 0; }
  .pill { height: 36px; padding: 4px 12px 4px 6px; }
  .pill b { font-size: 16px; }
  .tree-layout { grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr) auto; }
  .node-panel { max-height: 42vh; }
}

/* Phones upright: one row of pills on top with the mix meter under it, the towers, Drop and the
   wave switch at the thumb, the tall board between. */
@media (max-width: 720px) {
  #app {
    gap: 5px;
    padding-block: max(6px, env(safe-area-inset-top)) max(6px, env(safe-area-inset-bottom));
    padding-inline: max(8px, env(safe-area-inset-left)) max(8px, env(safe-area-inset-right));
  }
  .hud { gap: 5px; flex-wrap: wrap; }
  .hud-group { gap: 5px; flex-wrap: nowrap; }
  .pill { height: 34px; gap: 5px; padding: 3px 10px 3px 5px; box-shadow: 0 3px 0 var(--edge); }
  .pill b { font-size: 16px; }
  .pill .coin { width: 20px; height: 20px; }
  .pill-ic { width: 24px; height: 24px; }
  .pill-wave { padding-left: 10px; }
  .pill-stars, .bpm, .pill-wave .lbl { display: none; }
  .hud .icon-btn { width: 36px; height: 36px; }
  .btn.speed { width: 44px; font-size: 14px; }
  /* The mix meter: a slim capsule, its state on the left. */
  .band { order: 3; max-width: none; flex: 1 1 200px; height: 30px; gap: 10px; padding: 0 13px 0 12px; border-radius: 999px; box-shadow: 0 3px 0 var(--edge); }
  .mixer { grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 10px; }
  .mix-lbl { display: none; }
  .mix-top { max-width: 62vw; }
  .mix-top b { font-size: 12px; }
  .mix-bar { height: 10px; }
  /* Meteor and Half Time sit at the end of the mix meter's row. */
  .hud > .abilities { order: 3; flex: none; gap: 5px; padding: 0; border: 0; }
  .hud > .abilities .ability { width: 32px; height: 32px; box-shadow: 0 3px 0 #D8CFF7; }
  .hud > .abilities .ability .ic { width: 17px; height: 17px; }

  .dock { flex-wrap: nowrap; align-items: center; gap: 6px; padding: 4px 5px 4px 4px; border-radius: 20px; }
  .build-bar { flex: 1; width: auto; gap: 5px; padding: 5px 1px 5px; margin-top: -4px; scrollbar-width: none; overscroll-behavior-x: contain; }
  .build-bar::-webkit-scrollbar { display: none; }
  .tb { width: 50px; height: 52px; border-radius: 14px; padding: 2px 1px 3px; gap: 0; }
  .tb canvas { width: 32px !important; height: 32px !important; }
  .tb-name { display: none; }
  .tb-cost { font-size: 11.5px; }
  .tb.tb-more { width: 40px; }
  .dock > .drop { width: 48px; height: 48px; margin-bottom: 1px; }
  .dock > .drop span { width: 38px; height: 38px; }
  .wave-box { flex: none; margin: 0; }
  .wave-switch { --end: 30px; --pad: 3px; border-radius: 17px; }
  .wave-switch .ws-knob.btn { min-width: 0; width: 50px; height: 48px; padding: 0; border-radius: 14px; }
  .ws-ic .ic { width: 20px; height: 20px; }
  .ws-end .ic { width: 17px; height: 17px; }
  .ws-once .ic { width: 13px; height: 13px; }
  #btn-wave-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

  .title-card { max-width: none; gap: 14px; }
  .logo h1 { font-size: min(64px, 16vw); }
  .tagline { font-size: 16px; }
  .title-actions { display: grid; grid-template-columns: 1fr; gap: 10px; }
  .screen-inner { padding-block: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-bottom)); }
}
/* Upright screens: the tall diorama stands behind; the title sits at the bottom, by the thumb. */
@media (orientation: portrait) and (max-width: 1100px) {
  .screen-title {
    align-items: end; justify-items: stretch;
    padding-block: 24px max(20px, env(safe-area-inset-bottom));
    background: linear-gradient(0deg, rgba(247, 251, 253, .97) 0%, rgba(247, 251, 253, .9) 42%, rgba(247, 251, 253, 0) 72%);
  }
}
@keyframes sheetIn { from { transform: translateY(14px); opacity: 0; } }
@media (max-width: 420px) {
  .m-actions { grid-template-columns: 1fr; }
  .modal { padding: 20px; }
  .modal h2 { font-size: 30px; }
  .modal.pause .m-actions { grid-template-columns: 1fr 1fr; }
  .modal.pause .m-actions .btn { padding-inline: 10px; white-space: nowrap; }
}
@media (max-width: 370px) {
  .pill { padding-right: 8px; }
  .pill b { font-size: 15px; }
  .hud-group { gap: 4px; }
  .btn.speed { width: 40px; }
  .hud .icon-btn { width: 34px; height: 34px; }
}

/* Phones on their side: HUD down the left, towers down the right, the board gets the middle. */
@media (orientation: landscape) and (max-height: 520px) {
  #app.mode-game {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-rows: minmax(0, 1fr);
    gap: 8px;
    padding-block: max(6px, env(safe-area-inset-top)) max(6px, env(safe-area-inset-bottom));
    padding-inline: max(8px, env(safe-area-inset-left)) max(8px, env(safe-area-inset-right));
  }
  .mode-game .hud, .mode-game .stage, .mode-game .dock { grid-row: 1; }
  .mode-game .stage { grid-column: 2; }

  .hud { grid-column: 1; width: 88px; flex-direction: column; flex-wrap: nowrap; align-items: stretch; justify-content: flex-start; gap: 6px; }
  .hud-group { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 5px; }
  .hud-group:last-child { flex-direction: row; justify-content: space-between; }
  .pill { height: 32px; gap: 5px; padding: 3px 8px 3px 4px; box-shadow: 0 3px 0 var(--edge); }
  .pill b { font-size: 15px; }
  .pill .coin { width: 20px; height: 20px; }
  .pill-ic { width: 22px; height: 22px; }
  .pill-wave { padding-left: 10px; }
  .pill-stars, .bpm, .pill-wave .lbl { display: none; }
  .hud .icon-btn { width: 40px; height: 36px; }
  .btn.speed { width: 40px; font-size: 14px; }

  /* The mix meter stands up like a level meter; the drop sits on top of it. */
  .band {
    order: 0; flex: 1 1 0; min-height: 0; max-width: none; flex-basis: 0; height: auto;
    flex-direction: column; gap: 8px; padding: 8px 6px 6px; border-radius: 16px;
  }
  .seq { display: none; }
  .mixer { flex: 1; min-height: 0; width: 100%; grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; align-items: stretch; justify-items: center; gap: 6px; }
  .mix-bar { order: 1; width: 16px; height: auto; min-height: 30px; border-radius: 8px; background: linear-gradient(0deg, #E8EDF3, #E8EDF3 70%, #FFD9D2); }
  .mix-zone { top: auto; left: 0; width: auto; right: 0; bottom: var(--lo, 0%); height: calc(var(--hi, 0%) - var(--lo, 0%)); border-radius: 8px; }
  .mix-fill { top: auto; left: 3px; right: 3px; bottom: 3px; width: auto; height: max(0px, calc(var(--fill, 0%) - 6px)); }
  .mix-top { order: 2; display: block; width: 100%; max-width: none; text-align: center; white-space: normal; }
  .mix-lbl { display: none; }
  .mix-top b { display: block; font-size: 11px; line-height: 1.15; }
  .drop { width: 44px; height: 44px; }
  .drop span { width: 36px; height: 36px; }

  .dock {
    grid-column: 3; width: 136px; flex-direction: column; flex-wrap: nowrap; align-items: stretch;
    gap: 6px; padding: 6px; border-radius: 18px;
  }
  .build-bar {
    flex: 1; min-height: 0; width: auto; display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: 58px;
    align-content: start; gap: 6px; overflow-x: hidden; overflow-y: auto; padding: 5px 1px 5px; margin-top: -4px; scrollbar-width: none; overscroll-behavior-y: contain;
  }
  .build-bar::-webkit-scrollbar { display: none; }
  .tb, .tb.locked, .tb.tb-more { width: auto; height: auto; border-radius: 14px; padding: 2px 1px 4px; }
  .tb canvas { width: 32px !important; height: 32px !important; }
  .tb-name { display: none; }
  .tb-cost { font-size: 11px; }
  .abilities { justify-content: center; gap: 8px; padding: 0; border: 0; }
  .ability { width: 44px; height: 44px; }
  .wave-box { flex: none; margin: 0; }
  .wave-switch { --end: 38px; --pad: 3px; width: 100%; border-radius: 17px; }
  .wave-switch .ws-knob.btn { flex: 1; min-width: 0; width: auto; height: 44px; padding: 0; border-radius: 14px; }
  .ws-ic .ic { width: 20px; height: 20px; }
  #btn-wave-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

  .toasts { top: 6px; }
  .banner { top: 12%; }
  .bn-title { font-size: 34px; }

  /* Menus: shorter, so everything fits above the fold. */
  .title-card { gap: 10px; max-width: min(380px, 42vw); }
  .a2hs { gap: 8px; padding: 6px 6px 6px 8px; border-radius: 14px; }
  .a2hs-icon, .a2hs-body > b { display: none; }
  .a2hs-how { flex-wrap: nowrap; white-space: nowrap; }
  .a2hs-x { align-self: center; width: 28px; height: 28px; }
  .logo h1 { font-size: 52px; }
  .logo-gem { width: 40px; }
  .tagline { font-size: 15px; }
  .btn.xl { padding: 12px 20px; font-size: 16px; }
  .screen-title { padding-block: max(10px, env(safe-area-inset-top)) max(10px, env(safe-area-inset-bottom)); padding-inline: max(20px, env(safe-area-inset-left)) 20px; }
  .screen-inner { padding-block: 10px; padding-inline: max(16px, env(safe-area-inset-left)) max(16px, env(safe-area-inset-right)); }
  .screen-head { margin-bottom: 10px; }
  .screen-head h2 { font-size: 26px; }
  .tree-layout { grid-template-columns: minmax(0, 1fr) 260px; grid-template-rows: minmax(0, 1fr); gap: 10px; }
  .node-panel { max-height: 100%; padding: 14px; gap: 10px; }
  .np-icon { width: 42px; height: 42px; }
  .np-head h3 { font-size: 20px; }
  .np-desc { font-size: 14px; }
  .modal-wrap { padding: 8px; }
  .modal { padding: 18px 20px; gap: 10px; }
  .modal h2 { font-size: 28px; }
  .end-stats b { font-size: 22px; }
  .m-actions { grid-template-columns: repeat(3, 1fr); }
  .m-actions .btn:first-child { grid-column: auto; }
  .modal.pause .m-actions { grid-template-columns: 1.4fr 1fr 1fr; }
}

/* Phones: a tower's controls are a small sheet over the dock, so the board and its range stay in
   view. Name and pips, then upgrade and sell. Tap or pull up the head for everything else. */
.tp-grab, .tp-pips { display: none; }
@media (max-width: 720px), (orientation: landscape) and (max-height: 520px) {
  .dock { position: relative; z-index: 5; }
  .tb.locked { display: none; }
  .tb.tb-more { display: grid; }
  .tower-panel, .tower-panel.left, .tower-panel.up {
    top: auto; right: 0; bottom: 0; left: 0; width: auto; max-height: none; overflow: hidden;
    gap: 8px; padding: 0 8px 8px; border-radius: 20px; z-index: 6;
    box-shadow: 0 -10px 28px rgba(43, 52, 69, .16), 0 4px 0 var(--edge);
    animation: sheetIn .42s var(--spring);
  }
  .tower-panel.open { max-height: min(72vh, calc(100dvh - 90px)); overflow: auto; overscroll-behavior: contain; scrollbar-width: none; }
  .tower-panel { background: var(--paper); }
  /* Unfolded at a fork: the two paths get the full width, Sell goes under them. */
  .tower-panel.open .tp-actions > .tp-branches { grid-column: 1 / -1; }
  .tower-panel.open .tp-actions > .tp-branches ~ .sell-btn { grid-column: 1 / -1; grid-row: 2; width: 100%; }
  .tower-panel.open::-webkit-scrollbar { display: none; }
  .tp-head {
    order: -2; position: relative; margin: 0 -8px; padding: 10px 8px 8px 9px; gap: 9px;
    border-radius: 20px 20px 0 0; cursor: pointer; touch-action: none;
  }
  .tower-panel.open .tp-head { position: sticky; top: 0; z-index: 2; }
  .tp-grab { display: block; position: absolute; top: 4px; left: 50%; width: 34px; height: 4px; margin-left: -17px; border-radius: 2px; background: rgba(43, 52, 69, .2); transition: background .2s; }
  .tower-panel.open .tp-grab { background: rgba(43, 52, 69, .32); }
  .tp-art { width: 36px !important; height: 36px !important; }
  .tp-name { font-size: 17px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tp-sub { font-size: 11px; line-height: 1.2; }
  .tp-pips { display: flex; gap: 3px; margin-top: 5px; }
  .tp-pips i { width: 13px; height: 4px; border-radius: 2px; background: rgba(43, 52, 69, .13); }
  .tp-pips i.on { background: var(--ink-2); }
  .tp-pips i.on.br { background: var(--tc); }
  .tier-track { display: none; }
  .tp-mute, .tp-close { width: 36px; height: 36px; }
  .tp-stats { grid-template-columns: repeat(3, 1fr); gap: 4px; }
  .tp-stats div { padding: 4px 7px; }
  .tp-stats dd { font-size: 14px; }

  /* Folded: only the head and the actions. */
  .tower-panel:not(.open) > :not(.tp-head):not(.tp-actions),
  .tower-panel:not(.open) .tp-actions :is(.tp-up-head, .pat, .diff, .bc-desc) { display: none; }

  .tp-actions { order: -1; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 8px; }
  .tp-actions .tp-up { display: contents; }
  .tp-actions > *, .tp-actions .tp-up > * { grid-column: 1 / -1; }
  .tp-actions > .tp-up-head { display: none; }
  .tp-actions .tp-up > .up-btn, .tp-actions > .tp-branches, .tp-actions > .tp-max, .tp-actions > .tp-wait,
  .tp-actions .tp-up.locked > .tp-lock { grid-column: 1; grid-row: 1; }
  .tp-actions > .sell-btn { grid-column: 2; grid-row: 1; width: auto; padding-inline: 14px; align-self: stretch; }
  .tp-up.locked > .tp-lock { min-height: 40px; align-items: center; padding: 0 12px; border-radius: 14px; background: #F1ECFF; color: var(--lilac-deep); font-weight: 700; }
  .tp-up.locked > .tp-lock .ic { margin: 0; }
  .tp-max, .tp-wait { padding: 9px; }
  .sell-for { display: none; }

  /* Two paths: side by side, art beside name and price. Unfolded they show what they do. */
  .tp-branches { gap: 6px; }
  .branch-card { padding: 6px 6px 7px; gap: 3px; }
  .bc-art { width: 30px !important; height: 30px !important; }
  .bc-name { font-size: 14px; }
  .bc-desc { font-size: 11px; line-height: 1.3; }
  .branch-btn { margin-top: 2px; padding: 7px 8px; }
  .tower-panel:not(.open) .branch-card {
    grid-template-columns: auto minmax(0, 1fr); justify-items: stretch; align-items: center; text-align: left;
    column-gap: 6px; row-gap: 3px; padding: 5px 6px 6px;
  }
  .tower-panel:not(.open) .bc-art { grid-row: 1 / 3; }
  .tower-panel:not(.open) .bc-name { grid-column: 2; font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tower-panel:not(.open) .branch-btn { grid-column: 2; margin: 0; padding: 6px 4px; font-size: 13px; }
}
/* Phones on their side: the sheet fills the tower column, one thing per row; unfolded it reaches into the board. */
@media (orientation: landscape) and (max-height: 520px) {
  .tower-panel, .tower-panel.left, .tower-panel.up { top: 0; padding: 0 6px 6px; gap: 6px; }
  .tower-panel.open { left: auto; width: 290px; max-height: none; }
  .tp-head { margin: 0 -6px; }
  .tower-panel:not(.open) .tp-head {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "art mute close" "title title title";
    gap: 6px 4px; padding: 10px 6px 6px;
  }
  .tower-panel:not(.open) .tp-art { grid-area: art; }
  .tower-panel:not(.open) .tp-title { grid-area: title; }
  .tower-panel:not(.open) .tp-mute { grid-area: mute; justify-self: end; }
  .tower-panel:not(.open) .tp-close { grid-area: close; }
  .tower-panel:not(.open) .tp-name { font-size: 15px; white-space: normal; }
  .tp-art { width: 32px !important; height: 32px !important; }
  .tp-mute, .tp-close { width: 34px; height: 34px; }
  .tp-stats { grid-template-columns: repeat(2, 1fr); }
  .tower-panel:not(.open) .tp-actions { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .tower-panel:not(.open) .tp-actions > .sell-btn { grid-column: 1; grid-row: 2; }
  .tower-panel:not(.open) .tp-branches { grid-template-columns: 1fr; }
  .up-btn, .sell-btn { font-size: 13px; padding-inline: 8px; gap: 5px; white-space: nowrap; }
}

/* iPhone and iPad full screen: the system's exit button covers the top-left corner. Keep it clear. */
.fs-x .hud::before, .fs-x .screen-head::before { content: ''; flex: none; width: 70px; height: 47px; }
@media (max-width: 1100px) { .fs-x .bpm { display: none; } }
/* Upright phones: it sits beside the mix meter and the pills drop to the second row. */
@media (max-width: 720px) and (orientation: portrait) {
  .fs-x .hud::before { order: 1; }
  .fs-x .band { order: 2; flex: 1 1 120px; align-self: center; }
  .fs-x .hud > .abilities { order: 2; }
  .fs-x .hud-group { order: 3; }
}
/* Phones on their side: it sits on top of the HUD column. */
@media (orientation: landscape) and (max-height: 520px) {
  .fs-x .hud::before { width: auto; height: 42px; }
}

/* Touch: no keyboard, so no key hints. */
@media (hover: none) and (pointer: coarse) {
  .tb-key, .ab-key, .keys { display: none; }
}
/* Narrow phones, and the narrow column on their side: the email gets a row of its own. */
@media (max-width: 420px), (orientation: landscape) and (max-height: 520px) {
  .notify { flex-wrap: wrap; }
  .notify input, .notify .btn { flex: 1 1 100%; }
}
/* Phones on their side: three short cards in a row. */
@media (orientation: landscape) and (max-height: 520px) {
  .modal.pick { gap: 8px; }
  .hand { gap: 10px; }
  .hand-card { gap: 4px; padding: 8px 8px 12px; }
  .cd-art { height: 44px; }
  .cd-art > .ic { width: 28px; height: 28px; }
  .cd-name { font-size: 15px; }
  .cd-line { min-height: 22px; padding: 2px 7px; font-size: 11.5px; }
}
/* Phones on their side: the present beside the sign-up, so the whole dialog fits the screen. */
@media (orientation: landscape) and (max-height: 520px) {
  .modal.gift { width: min(720px, 100%); grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 10px 20px; align-content: center; padding: 18px; }
  .modal.gift > * { grid-column: 2; }
  .modal.gift > .nx-gift { grid-column: 1; grid-row: 1 / span 4; align-self: center; }
  .modal.gift h2 { font-size: 26px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}
