/* Game surfaces on the Playtime design system (dark charcoal + coral). Colors come
   from app.css :root variables; the playful game elements keep their pop. */

/* ===== Tempo Rush ===== */
.rush-lobby { max-width: 900px; margin: 0 auto; }
.rush-panels { display: grid; grid-template-columns: 1fr 1.4fr; gap: 18px; margin-top: 14px; }
@media (max-width: 760px) { .rush-panels { grid-template-columns: 1fr; } }
.rush-panel { border: 1px solid var(--outline); border-radius: var(--radius); padding: 20px; background: var(--surface); }
.rush-panel label { display: block; margin: 12px 0 4px; font-weight: 600; }
.rush-panel select, .code-input { padding: 10px; border: 1px solid var(--outline); border-radius: var(--radius-sm);
  background: var(--surface-elevated); color: var(--text); font-family: var(--font); }
.code-input { text-transform: uppercase; letter-spacing: 4px; font-size: 1.2em; width: 10ch; }
.tier-row { display: flex; flex-wrap: wrap; gap: 8px; }
.tier-chip { border: 2px solid var(--outline); background: var(--surface-elevated); color: var(--text);
  border-radius: 12px; padding: 8px 12px; cursor: pointer; font-family: var(--font); }
.tier-chip small { display: block; color: var(--text-muted); }
.tier-chip.selected { border-color: var(--primary); background: var(--primary-soft); box-shadow: 0 3px 0 var(--primary-dark); }

.rush-room { max-width: 980px; margin: 0 auto; }
.rush-header { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
.rush-game { font-size: 1.2em; font-weight: 700; }
.rush-code { color: var(--text-muted); }
.join-code.big { font-size: 1.6em; padding: 4px 12px; }
.rush-stage { text-align: center; padding: 18px 14px 30px; position: relative;
  border-radius: var(--radius); background: var(--surface); border: 1px solid var(--outline); }
.big-button { font-size: 1.2em; padding: 14px 26px; }
.hint-line { color: var(--text-muted); }

/* The track keeps its daylight look — a game board sitting on the dark UI,
   like the phone app's game cards. */
.race-track { border: 3px solid #0d0d0c; border-radius: 14px; padding: 6px 0; margin-bottom: 14px;
  background: linear-gradient(180deg, #bfe3ff 0 22%, #8ed081 22%); position: relative;
  box-shadow: 0 6px 18px rgba(0,0,0,.35); }
.race-track::after { content: ""; position: absolute; top: 0; bottom: 0; right: 10px; width: 12px;
  background: repeating-conic-gradient(#2b2620 0 25%, #fff 0 50%) 0 0 / 12px 12px; opacity: .85; border-radius: 4px; }
.race-lane { position: relative; height: 40px; border-bottom: 2px dashed rgba(255,255,255,.6); }
.race-lane:last-child { border-bottom: none; }
.racer { position: absolute; top: 2px; transition: left 1s cubic-bezier(.2,.8,.3,1.1); display: flex; align-items: center; gap: 6px; }
.racer-emoji { font-size: 26px; }
.racer-name { font-size: .8em; font-weight: 700; color: #2b2620; }
.racer-score { font-size: .8em; color: #4a453d; }
.racer-name, .racer-score { background: rgba(255,255,255,.8); border-radius: 6px; padding: 0 5px; }

.lobby-players { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin: 18px 0; }
.lobby-player { border: 1px solid var(--primary); border-radius: 999px; padding: 8px 16px;
  background: var(--primary-soft); color: var(--text); font-weight: 600; animation: bob 1.6s ease-in-out infinite; }
.lobby-player span { margin-right: 6px; }
.lobby-player:nth-child(2n) { animation-delay: .4s; }
.lobby-player:nth-child(3n) { animation-delay: .8s; }
@keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }

.countdown-digit { font-size: 84px; animation: pulse .8s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.25); } }

.question-top { display: flex; justify-content: space-between; align-items: center; color: var(--text-muted); }
.replay-button { border: 1px solid var(--outline); background: var(--surface-elevated); color: var(--text);
  border-radius: 999px; padding: 6px 14px; cursor: pointer; font-family: var(--font); }
.replay-button:hover { border-color: var(--primary); }
.timer-bar { height: 10px; background: var(--surface-elevated); border-radius: 999px; overflow: hidden; margin: 10px 0 4px;
  border: 1px solid var(--outline); }
.timer-fill { height: 100%; width: 100%; border-radius: 999px;
  background: linear-gradient(90deg, #7FA97F, #E0A458 60%, #E06A5B);
  animation-name: drain; animation-timing-function: linear; animation-fill-mode: forwards; }
@keyframes drain { from { width: 100%; } to { width: 0%; } }
.question-prompt { margin: 18px 0; }
.option-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; max-width: 720px; margin: 0 auto; }
@media (max-width: 600px) { .option-grid { grid-template-columns: 1fr; } }
.option { border: none; border-radius: 14px; padding: 20px 14px; font-size: 1.15em; font-weight: 700;
  color: #fff; cursor: pointer; transition: transform .08s ease; font-family: var(--font);
  box-shadow: 0 4px 0 rgba(0,0,0,.4); }
.option:hover:not(:disabled) { transform: scale(1.03) translateY(-2px); }
.option:disabled { opacity: .45; cursor: default; }
.option.picked { opacity: 1; outline: 3px solid var(--text); }
.option-0 { background: #C75048; }
.option-1 { background: #3E6E9E; }
.option-2 { background: #C98A34; }
.option-3 { background: #4E9159; }
.locked-in { font-weight: 700; margin-top: 14px; animation: pulse 1.2s ease-in-out infinite; }

.reveal-list { max-width: 640px; margin: 0 auto; display: flex; flex-direction: column; gap: 8px; }
.reveal-row { display: grid; grid-template-columns: 44px 36px 1fr 90px 70px; align-items: center; gap: 8px;
  padding: 10px 14px; border-radius: 12px; text-align: left; opacity: 0;
  animation: slide-in .45s ease forwards; }
@keyframes slide-in { from { opacity: 0; transform: translateX(-30px); } to { opacity: 1; transform: none; } }
.reveal-row.correct { background: rgba(127, 169, 127, 0.14); border: 1px solid var(--success); }
.reveal-row.wrong { background: rgba(224, 106, 91, 0.12); border: 1px solid rgba(224, 106, 91, .5); }
.reveal-rank { font-size: 1.3em; }
.reveal-time { font-variant-numeric: tabular-nums; color: var(--text-muted); text-align: right; }
.reveal-points { font-weight: 800; text-align: right; }
.explanation { margin-top: 16px; color: var(--text-muted); }

.podium { display: flex; justify-content: center; align-items: flex-end; gap: 12px; margin: 22px 0 26px; }
.podium-step { display: flex; flex-direction: column; align-items: center; gap: 2px; border-radius: 12px 12px 0 0;
  padding: 14px 22px; color: var(--text); }
.podium-avatar { font-size: 40px; }
.place-1 { background: linear-gradient(180deg, #ffd70055, #ffd70022); border: 1px solid #ffd70088; order: 2; padding-bottom: 56px; }
.place-2 { background: linear-gradient(180deg, #c0c0c055, #c0c0c022); border: 1px solid #c0c0c088; order: 1; padding-bottom: 34px; }
.place-3 { background: linear-gradient(180deg, #cd7f3255, #cd7f3222); border: 1px solid #cd7f3288; order: 3; padding-bottom: 20px; }

.confetti { pointer-events: none; position: absolute; inset: 0; overflow: hidden; border-radius: var(--radius); }
.confetti-piece { position: absolute; top: -12px; width: 10px; height: 16px; border-radius: 2px;
  background: var(--primary); animation: fall 2.8s linear infinite; }
.confetti-piece:nth-child(3n) { background: var(--teal); width: 8px; }
.confetti-piece:nth-child(4n) { background: var(--success); height: 12px; }
.confetti-piece:nth-child(5n) { background: var(--tertiary); }
@keyframes fall { to { transform: translateY(110vh) rotate(540deg); } }

/* ===== The Maestro (animated host character) ===== */
.maestro-corner { position: relative; display: flex; justify-content: flex-start; min-height: 150px; margin-bottom: 4px; }
.maestro-host { position: relative; display: flex; align-items: flex-end; gap: 6px; }
.maestro-svg { width: 120px; height: 140px; animation: maestro-bob 2.6s ease-in-out infinite; transform-origin: 50% 95%; }
@keyframes maestro-bob {
  0%, 100% { transform: translateY(0) rotate(-1deg) scale(1, 1); }
  50% { transform: translateY(-5px) rotate(1.5deg) scale(.99, 1.02); }
}

/* Both arms conduct: gently at rest, big happy waves when the mood lifts. */
.maestro-arm { transform-origin: 84px 76px; animation: conduct 2.6s ease-in-out infinite; }
.maestro-arm-left { transform-origin: 36px 76px; animation: conduct-left 2.6s ease-in-out infinite; }
@keyframes conduct {
  0%, 100% { transform: rotate(0); } 25% { transform: rotate(-14deg); }
  50% { transform: rotate(-5deg); } 75% { transform: rotate(-18deg); }
}
@keyframes conduct-left {
  0%, 100% { transform: rotate(0); } 25% { transform: rotate(9deg); }
  50% { transform: rotate(3deg); } 75% { transform: rotate(12deg); }
}
.mood-excited .maestro-arm, .mood-celebrate .maestro-arm { animation: baton-wave .5s ease-in-out infinite; }
.mood-excited .maestro-arm-left, .mood-celebrate .maestro-arm-left { animation: arm-cheer .5s ease-in-out infinite .12s; }
.mood-thinking .maestro-arm { animation: baton-tap 1.4s ease-in-out infinite; }
.mood-thinking .maestro-arm-left { animation: none; }
.mood-sad .maestro-arm, .mood-sad .maestro-arm-left { animation: none; }
@keyframes baton-wave { 0%, 100% { transform: rotate(6deg); } 50% { transform: rotate(-44deg); } }
@keyframes arm-cheer { 0%, 100% { transform: rotate(-4deg); } 50% { transform: rotate(26deg); } }
@keyframes baton-tap { 0%, 100% { transform: rotate(0); } 50% { transform: rotate(-12deg); } }

/* The left shoe taps along with the idle conducting. */
.maestro-foot { transform-origin: 52px 134px; animation: foot-tap 1.3s ease-in-out infinite; }
@keyframes foot-tap { 0%, 100% { transform: rotate(0); } 30% { transform: rotate(-9deg) translateY(-1.5px); } }
.mood-sad .maestro-foot { animation: none; }

.mood-celebrate .maestro-svg { animation: maestro-hop .6s ease-in-out infinite; }
@keyframes maestro-hop {
  0%, 100% { transform: translateY(0) scale(1, 1); }
  30% { transform: translateY(-13px) rotate(-3deg); }
  60% { transform: translateY(0) scale(1, 1); }
  72% { transform: translateY(0) scale(1.06, .93); }
}
.mood-sad .maestro-svg { animation: maestro-droop 3s ease-in-out infinite; }
@keyframes maestro-droop { 0%, 100% { transform: translateY(2px) rotate(-2.5deg); } 50% { transform: translateY(4px) rotate(-1deg); } }
.mood-gasp .maestro-svg { animation: maestro-shake .18s linear 5; }
@keyframes maestro-shake { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-4px); } }

.maestro-eyes .eye { animation: blink 4.2s infinite; transform-origin: center; }
@keyframes blink { 0%, 94%, 100% { transform: scaleY(1); } 96% { transform: scaleY(.08); } }

/* The commander helmet's antenna light blinks. */
.baton-spark-dot { animation: sparkle 1.1s ease-in-out infinite; }
@keyframes sparkle { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }

/* Music notes float up when the Maestro gets going. */
.maestro-note { opacity: 0; }
.mood-excited .maestro-note, .mood-celebrate .maestro-note { animation: note-float 1.6s ease-out infinite; }
.mood-excited .note-2, .mood-celebrate .note-2 { animation-delay: .45s; }
.mood-excited .note-3, .mood-celebrate .note-3 { animation-delay: .9s; }
@keyframes note-float {
  0% { opacity: 0; transform: translateY(8px) scale(.6); }
  25% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-26px) rotate(16deg) scale(1.05); }
}

/* Mood extras: the sweat drop slides, the tear wells up and drips. */
.maestro-sweat { animation: sweat-slide .9s ease-in infinite; }
@keyframes sweat-slide { 0% { opacity: 0; transform: translateY(-3px); } 30% { opacity: 1; } 100% { opacity: 0; transform: translateY(7px); } }
.maestro-tear { animation: tear-drip 2.2s ease-in infinite; }
@keyframes tear-drip { 0%, 35% { opacity: 0; transform: translateY(0) scale(.5); } 55% { opacity: 1; transform: translateY(2px) scale(1); } 100% { opacity: 0; transform: translateY(14px) scale(.9); } }

/* Speech bubbles stay paper-white so they read like comic panels on the dark UI. */
.maestro-bubble { position: relative; align-self: flex-start; max-width: 300px; background: #fff; color: #2b2620;
  border: 2px solid #0d0d0c; border-radius: 16px; padding: 10px 14px; font-weight: 600;
  animation: bubble-pop .35s cubic-bezier(.3,1.6,.5,1) both; box-shadow: 3px 3px 0 rgba(0,0,0,.4); }
/* Cartoon speech tail off the bottom-right corner: dark outline + white fill,
   swung nearly sideways so the tip lands on the Maestro's mouth. */
.maestro-bubble::before { content: ""; position: absolute; right: -4px; bottom: -9px;
  width: 0; height: 0; border-top: 32px solid #0d0d0c; border-left: 16px solid transparent;
  transform: rotate(-64deg); transform-origin: top right; }
.maestro-bubble::after { content: ""; position: absolute; right: -1px; bottom: -3px;
  width: 0; height: 0; border-top: 23px solid #fff; border-left: 11px solid transparent;
  transform: rotate(-64deg); transform-origin: top right; }
@keyframes bubble-pop { from { opacity: 0; transform: scale(.6) translateY(8px); } to { opacity: 1; transform: none; } }

/* Side-tail variant: the tail sits mid-height on the bubble's RIGHT edge and
   points straight at the Maestro's mouth beside it. */
.bubble-right .maestro-bubble { align-self: center; }
.bubble-right .maestro-bubble::before { right: -22px; bottom: auto; top: 50%;
  transform: translateY(-50%); border: solid transparent; border-width: 12px 0 12px 24px;
  border-left-color: #0d0d0c; }
.bubble-right .maestro-bubble::after { right: -16px; bottom: auto; top: 50%;
  transform: translateY(-50%); border: solid transparent; border-width: 8px 0 8px 17px;
  border-left-color: #fff; }

/* ===== TA (teaching assistant) + Lesson/Curriculum studios ===== */
.ta-panel { border: 2px solid var(--outline, #3a3733); border-radius: 16px; padding: 12px 14px;
  background: var(--surface-elevated, #211f1c); }
.ta-head .maestro-svg { width: 90px; height: 105px; }
.ta-head .maestro-bubble { max-width: 260px; font-size: .9em; }
/* Miles stands to the RIGHT of a bubble that runs to three lines, and the
   default tail hangs off the bubble's bottom corner — so the longer he talks,
   the further down it slides, until it's pointing at his belly. Anchor it to
   the right edge a fixed distance from the TOP instead: his mouth sits at
   y≈54 of the 140-unit viewBox, which on the 105px figure is ~40px down, and
   the bubble is top-aligned with him. Now it finds his mouth whatever he says. */
.ta-head .maestro-bubble::before { right: -22px; bottom: auto; top: 28px;
  border: solid transparent; border-width: 12px 0 12px 24px;
  border-left-color: #0d0d0c; transform: none; }
.ta-head .maestro-bubble::after { right: -16px; bottom: auto; top: 32px;
  border: solid transparent; border-width: 8px 0 8px 17px;
  border-left-color: #fff; transform: none; }
.ta-connect { display: flex; flex-direction: column; gap: 8px; }
.ta-connect input { padding: 9px 12px; border-radius: 10px; }
.ta-chat { display: flex; flex-direction: column; gap: 8px; max-height: 460px; overflow-y: auto;
  margin: 10px 0; padding-right: 4px; }
.ta-turn { border-radius: 12px; padding: 8px 12px; max-width: 92%; }
.ta-turn.mine { align-self: flex-end; background: rgba(217,119,87,.18); border: 1px solid var(--primary, #d97757); }
.ta-turn.tas { align-self: flex-start; background: rgba(95,176,164,.10); border: 1px solid var(--outline, #3a3733); }
.ta-turn p { margin: 4px 0; }
.ta-turn h4 { margin: 8px 0 2px; }
.ta-li { margin: 2px 0 2px 8px; }
.ta-use { margin-top: 6px; }
.ta-linklike { background: none; border: none; padding: 0; color: var(--primary, #d97757);
  cursor: pointer; text-decoration: underline; font-size: inherit; }

.lesson-studio { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(280px, 1fr); gap: 18px; align-items: start; }
@media (max-width: 980px) { .lesson-studio { grid-template-columns: 1fr; } }
.ls-side { position: sticky; top: 12px; }
.lesson-block { border: 1px solid var(--outline, #3a3733); border-radius: 12px; padding: 10px 12px; margin: 8px 0;
  background: var(--surface-elevated, #211f1c); }
.lb-bar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.lesson-block textarea, .lesson-block input, .lesson-block select { border-radius: 8px; padding: 7px 10px; }
.lesson-view-block { margin: 10px 0; }
.lesson-view-block .tile { max-width: 460px; }

.curriculum-stage { border: 1px solid var(--outline, #3a3733); border-radius: 14px; padding: 12px 16px; margin: 12px 0;
  background: var(--surface-elevated, #211f1c); }
.cs-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.grid-units { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 10px; margin-top: 8px; }
.unit-card { border: 1px solid var(--outline, #3a3733); border-radius: 12px; padding: 10px 12px;
  display: flex; flex-direction: column; gap: 4px; }
.unit-concepts { color: var(--text-muted); }
.unit-links { display: flex; flex-direction: column; gap: 2px; }
.unit-links a { font-size: .9em; }

/* ===== Video lessons: scheduler calendar + the room ===== */
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; margin: 10px 0 18px; }
.cal-day { border: 1px solid var(--outline, #3a3733); border-radius: 10px; min-height: 74px;
  padding: 6px; display: flex; flex-direction: column; gap: 4px; background: var(--surface-elevated, #211f1c); }
.cal-day.today { border-color: var(--primary, #d97757); }
.cal-day small { color: var(--text-muted); }
.cal-chip { border-radius: 8px; padding: 2px 6px; font-size: .78em; text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-chip.open { background: rgba(89,176,78,.2); border: 1px solid #59b04e; }
.cal-chip.one { background: rgba(217,119,87,.2); border: 1px solid var(--primary, #d97757); }
.cal-chip.cls { background: rgba(63,158,199,.2); border: 1px solid #3f9ec7; }
.cal-chip.canceled { opacity: .45; text-decoration: line-through; }
@media (max-width: 900px) { .cal-grid { grid-template-columns: repeat(4, 1fr); } }

.video-frame { width: 100%; aspect-ratio: 16 / 9; border: 3px solid #0d0d0c; border-radius: 14px;
  background: #000; }

/* Playtime app promo: the Academy trains your head, the app sits on the stand. */
.playtime-promo { border: 2px solid var(--primary, #d97757); border-radius: 16px; padding: 14px 18px;
  margin: 18px 0; background: linear-gradient(145deg, rgba(217,119,87,.10), rgba(95,176,164,.08)); }
.pp-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pp-logo { font-size: 1.8em; }
.pp-head b { display: block; font-size: 1.1em; }
.pp-head small { color: var(--text-muted); font-style: italic; }
.pp-cta { margin-left: auto; padding: 8px 18px; border-radius: 10px; text-decoration: none;
  background: var(--primary, #d97757); color: #fff; font-weight: 700; }
.pp-cta:hover { filter: brightness(1.1); }
.pp-benefits { list-style: none; margin: 10px 0 6px; padding: 0; display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 6px 18px; }
.pp-benefits li { font-size: .95em; }
.pp-note { color: var(--text-muted); }

/* The invite link shown beside the copy button — one tap selects the whole thing. */
.share-url { background: rgba(0,0,0,.35); border: 1px solid var(--outline); border-radius: 8px;
  padding: 3px 8px; font-size: .82em; user-select: all; overflow-wrap: anywhere; }

.commander-float { position: absolute; top: 6px; right: 8px; z-index: 5; display: flex; }
.commander-float .maestro-host { flex-direction: row-reverse; align-items: flex-start; }
.commander-float .maestro-svg { width: 84px; height: 98px; }
.commander-float .maestro-bubble { max-width: 240px; margin-top: 10px; font-size: .85em; }
/* Commander layout mirrors: he floats left of the bubble, so the tail flips. */
.commander-float .maestro-bubble::before { right: auto; left: 8px; border-left: none;
  border-right: 16px solid transparent; transform: rotate(30deg); transform-origin: top left; }
.commander-float .maestro-bubble::after { right: auto; left: 11px; border-left: none;
  border-right: 11px solid transparent; transform: rotate(30deg); transform-origin: top left; }

/* ===== Live Games: gallery, avatars, stages, finale ===== */

/* Game gallery cards, each wearing its theme gradient. */
.game-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.game-card { position: relative; display: flex; flex-direction: column; gap: 4px; align-items: flex-start;
  text-align: left; border: 2px solid var(--outline); border-radius: 16px; padding: 14px;
  color: var(--text); cursor: pointer; font-family: var(--font); overflow: hidden;
  transition: transform .1s ease; background: var(--surface); }
.game-card:hover { transform: translateY(-3px); }
.game-card.selected { border-color: var(--primary); box-shadow: 0 4px 0 var(--primary-dark); }
.game-card small { color: var(--text-muted); }
.gc-emoji { font-size: 2em; animation: bob 2.4s ease-in-out infinite; }
.game-card:nth-child(2n) .gc-emoji { animation-delay: .5s; }
.game-card:nth-child(3n) .gc-emoji { animation-delay: 1s; }
.gc-badges { display: flex; gap: 6px; margin-top: 4px; }
.gc-badge { font-size: .68em; font-weight: 800; border-radius: 999px; padding: 2px 8px; }
.gc-badge.team { background: rgba(95,176,164,.25); border: 1px solid var(--teal); }
.gc-badge.coop { background: rgba(127,169,127,.25); border: 1px solid var(--success); }
.gc-badge.hard { background: rgba(224,106,91,.25); border: 1px solid var(--danger); }

.theme-rush { background: linear-gradient(145deg, #262624, #33302a); }
.theme-balloons { background: linear-gradient(145deg, #1d2a38, #274a63); }
.theme-disco { background: linear-gradient(145deg, #2a1d38, #4a2763); }
.theme-tug { background: linear-gradient(145deg, #29321d, #3d5427); }
.theme-rocket { background: linear-gradient(145deg, #1d2038, #272d63); }
.theme-zombies { background: linear-gradient(145deg, #22301f, #2f4a24); }
.theme-kraken { background: linear-gradient(145deg, #14303a, #1a4a56); }
.theme-heist { background: linear-gradient(145deg, #30271d, #543c27); }
.theme-showdown { background: linear-gradient(145deg, #382a1d, #634527); }
.theme-crown { background: linear-gradient(145deg, #383218, #635a1f); }
.theme-bass { background: linear-gradient(145deg, #16323b, #1f5a4a); }
.theme-splat { background: linear-gradient(145deg, #2d1d38, #7a2757 60%, #27637a); }

/* Party avatars: color body + emoji face + instrument in hand. */
.party-avatar { position: relative; display: inline-block; }
.pa-body { border-radius: 50%; border: 2.5px solid rgba(0,0,0,.4); box-shadow: inset -4px -6px 0 rgba(0,0,0,.18); }
.pa-face { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.pa-instrument { position: absolute; filter: drop-shadow(1px 2px 1px rgba(0,0,0,.45)); }
.pa-crown { position: absolute; top: -0.75em; left: 50%; transform: translateX(-50%) rotate(-12deg); }
.party-avatar.zombified .pa-body { filter: grayscale(.9) brightness(.8); }
.party-avatar.zombified .pa-instrument { filter: grayscale(.9); }
.party-avatar.jamming { animation: jam-rock .5s ease-in-out infinite; transform-origin: 50% 90%; }
.party-avatar.jamming .pa-instrument { animation: jam-strum .25s ease-in-out infinite; }
@keyframes jam-rock { 0%, 100% { transform: rotate(-7deg) translateY(0); } 50% { transform: rotate(7deg) translateY(-8px); } }
@keyframes jam-strum { 0%, 100% { transform: rotate(-6deg); } 50% { transform: rotate(9deg); } }

/* Avatar builder */
.avatar-builder { display: flex; gap: 22px; align-items: flex-start; justify-content: center; flex-wrap: wrap; text-align: left; }
.ab-preview { padding: 18px 26px 30px; border: 2px dashed var(--outline); border-radius: 16px; }
.ab-controls { max-width: 460px; }
.ab-controls input { width: 100%; box-sizing: border-box; padding: 10px 12px; font-size: 1.05em; border-radius: 10px; }
.ab-row { display: flex; flex-wrap: wrap; gap: 6px; }
.ab-pick { border: 2px solid var(--outline); background: var(--surface-elevated); border-radius: 10px;
  font-size: 1.25em; padding: 4px 8px; cursor: pointer; line-height: 1.3; }
.ab-pick.selected { border-color: var(--primary); box-shadow: 0 2px 0 var(--primary-dark); }
.ab-pick.swatch { width: 34px; height: 34px; padding: 0; }
.ab-pick.inst { padding: 3px; }

.lobby-chip { display: flex; flex-direction: column; align-items: center; gap: 2px; font-weight: 600;
  animation: bob 1.8s ease-in-out infinite; }
.lobby-chip:nth-child(2n) { animation-delay: .35s; }
.lobby-chip:nth-child(3n) { animation-delay: .7s; }
.team-lobby { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 14px 0; }
.team-column { border-radius: 14px; padding: 12px; display: flex; flex-direction: column; gap: 8px; align-items: center; }
.team-column.team-1 { background: rgba(95,176,164,.12); border: 2px solid var(--teal); }
.team-column.team-2 { background: rgba(217,119,87,.12); border: 2px solid var(--primary); }

/* Stages */
.live-stage { margin-bottom: 12px; }

.balloon-sky { position: relative; height: 240px; border-radius: 16px; overflow: hidden;
  background: linear-gradient(180deg, #274a63 0%, #3a6e8e 70%, #8ed081 96%); border: 3px solid #0d0d0c; }
.balloon-rider { position: absolute; display: flex; flex-direction: column; align-items: center;
  transition: bottom 1s cubic-bezier(.3,.9,.4,1.1); animation: balloon-bob 2.6s ease-in-out infinite; }
.balloon { width: 34px; height: 40px; border-radius: 50% 50% 48% 48%; border: 2px solid rgba(0,0,0,.35);
  margin-bottom: -4px; box-shadow: inset -5px -6px 0 rgba(0,0,0,.15); }
.balloon::after { content: ""; display: block; width: 1.5px; height: 12px; background: #f4f2ec; margin: 40px auto 0; }
.balloon-rider small { background: rgba(0,0,0,.45); border-radius: 6px; padding: 0 5px; white-space: nowrap; }
@keyframes balloon-bob { 0%, 100% { margin-bottom: 0; } 50% { margin-bottom: 8px; } }
.cloud { position: absolute; font-size: 26px; opacity: .8; animation: cloud-drift 14s linear infinite; }
.cloud.c1 { top: 12%; } .cloud.c2 { top: 40%; animation-delay: 5s; } .cloud.c3 { top: 66%; animation-delay: 9s; }
@keyframes cloud-drift { from { left: -10%; } to { left: 105%; } }
.finish-line { position: absolute; top: 6px; right: 10px; font-weight: 800; }

.disco-floor { border-radius: 16px; padding: 10px; background: #170f1e; border: 3px solid #0d0d0c;
  display: flex; flex-direction: column; gap: 8px; }
.disco-lane { position: relative; display: flex; gap: 4px; height: 46px; align-items: center; }
.disco-tile { flex: 1; height: 40px; border-radius: 6px; opacity: .8; animation: disco-pulse 1.2s ease-in-out infinite; }
.disco-tile.t-0 { background: #c75ac0; } .disco-tile.t-1 { background: #3f9ec7; animation-delay: .3s; }
.disco-tile.t-2 { background: #e5c02b; animation-delay: .6s; } .disco-tile.t-3 { background: #59b04e; animation-delay: .9s; }
@keyframes disco-pulse { 0%, 100% { filter: brightness(.55); } 50% { filter: brightness(1.15); } }
.disco-dancer { position: absolute; top: -4px; display: flex; flex-direction: column; align-items: center;
  transition: left .9s cubic-bezier(.3,.9,.4,1.2); animation: jam-rock .7s ease-in-out infinite; transform-origin: 50% 90%; }
.disco-dancer.frozen { animation: none; filter: saturate(.4) brightness(1.3); }
.disco-dancer small { background: rgba(0,0,0,.5); border-radius: 6px; padding: 0 5px; }

.tug-stage { position: relative; border-radius: 16px; padding: 14px; border: 3px solid #0d0d0c;
  background: linear-gradient(180deg, #3d5427, #29321d); display: grid;
  grid-template-columns: auto 1fr auto; gap: 10px; align-items: center; }
.tug-side { display: flex; gap: 4px; flex-wrap: wrap; max-width: 130px; }
.tug-side.left .party-avatar { animation: tug-lean-l 1s ease-in-out infinite; }
.tug-side.right .party-avatar { animation: tug-lean-r 1s ease-in-out infinite; }
@keyframes tug-lean-l { 0%, 100% { transform: rotate(-12deg); } 50% { transform: rotate(-4deg) translateX(-3px); } }
@keyframes tug-lean-r { 0%, 100% { transform: rotate(12deg); } 50% { transform: rotate(4deg) translateX(3px); } }
.tug-rope { position: relative; height: 8px; background: repeating-linear-gradient(90deg, #c49a6c 0 12px, #8a6244 12px 24px);
  border-radius: 4px; }
.tug-knot { position: absolute; top: -16px; font-size: 26px; transform: translateX(-50%);
  transition: left .9s cubic-bezier(.3,.9,.4,1.2); }
.tug-scores { grid-column: 1 / -1; display: flex; justify-content: space-between; }
.tug-scores .team1 { color: var(--teal); } .tug-scores .team2 { color: var(--primary); }

.rocket-stage { position: relative; height: 250px; border-radius: 16px; border: 3px solid #0d0d0c;
  background: linear-gradient(180deg, #0d1026 0%, #272d63 100%); display: flex; justify-content: space-around; overflow: hidden; }
.rocket-lane { position: relative; width: 40%; display: flex; flex-direction: column; align-items: center;
  justify-content: flex-end; padding-bottom: 8px; color: #f4f2ec; }
.rocket-lane .rocket { position: absolute; font-size: 40px; transition: bottom 1s cubic-bezier(.3,.9,.4,1.1);
  animation: rocket-shake .3s linear infinite; }
.rocket-lane .rocket-flame { position: absolute; font-size: 18px; transition: bottom 1s cubic-bezier(.3,.9,.4,1.1);
  animation: flame-flicker .18s linear infinite; }
@keyframes rocket-shake { 0%, 100% { transform: translateX(-1px); } 50% { transform: translateX(1px); } }
@keyframes flame-flicker { 0%, 100% { opacity: 1; } 50% { opacity: .5; } }
.moon { position: absolute; top: 8px; left: 50%; transform: translateX(-50%); font-size: 34px; }
.rocket-lane b { z-index: 1; } .rocket-lane small { z-index: 1; opacity: .85; }

.zombie-stage { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; border-radius: 16px;
  border: 3px solid #0d0d0c; padding: 14px; background: linear-gradient(180deg, #2f4a24, #1c2c16); }
.zombie-slot { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.zombie-slot .zombified { animation: zombie-lurch 1.6s ease-in-out infinite; }
@keyframes zombie-lurch { 0%, 100% { transform: rotate(-6deg) translateY(0); } 50% { transform: rotate(4deg) translateY(3px); } }

.kraken-stage { position: relative; border-radius: 16px; border: 3px solid #0d0d0c; padding: 12px;
  background: linear-gradient(180deg, #1a4a56 0%, #14303a 100%); text-align: center; }
.kraken { font-size: 56px; animation: kraken-loom 2.2s ease-in-out infinite; display: inline-block; }
.tentacle { position: relative; font-size: 30px; display: inline-block; animation: tentacle-wave 1.4s ease-in-out infinite; }
.tentacle.t2 { animation-delay: .5s; }
@keyframes kraken-loom { 0%, 100% { transform: scale(1) rotate(-3deg); } 50% { transform: scale(1.08) rotate(3deg); } }
@keyframes tentacle-wave { 0%, 100% { transform: rotate(-16deg) translateY(0); } 50% { transform: rotate(14deg) translateY(-6px); } }
.hp-bar { height: 14px; border-radius: 999px; background: rgba(0,0,0,.5); overflow: hidden; margin: 6px auto; max-width: 420px; }
.hp-fill { height: 100%; background: linear-gradient(90deg, #e06a5b, #c75ac0); transition: width .9s ease; }
.kraken-stage .ship { margin-top: 8px; font-size: 24px; display: flex; gap: 4px; align-items: center; justify-content: center;
  animation: ship-rock 3s ease-in-out infinite; }
@keyframes ship-rock { 0%, 100% { transform: rotate(-2deg); } 50% { transform: rotate(2deg); } }

.heist-stage { border-radius: 16px; border: 3px solid #0d0d0c; padding: 12px;
  background: linear-gradient(180deg, #543c27, #30271d); display: flex; flex-direction: column; gap: 8px; }
.heist-row { display: flex; align-items: center; gap: 10px; }
.heist-name { min-width: 110px; font-weight: 700; }
.locks { letter-spacing: 3px; font-size: 1.2em; }
.locks .picked { animation: lock-pop .5s ease; }
@keyframes lock-pop { 0% { transform: scale(.4); } 70% { transform: scale(1.4); } 100% { transform: scale(1); } }
.alarm { margin-left: auto; font-weight: 700; }
.alarm.a-2 { animation: alarm-flash .5s linear infinite; color: #ff6b5e; }
@keyframes alarm-flash { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

.showdown-stage { position: relative; border-radius: 16px; border: 3px solid #0d0d0c; padding: 18px 12px 12px;
  background: linear-gradient(180deg, #a9744633 0%, #634527 100%); display: flex; flex-wrap: wrap; gap: 16px;
  justify-content: center; overflow: hidden; }
.duelist { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.round-wins { color: #ffd700; letter-spacing: 2px; min-height: 1.2em; }
.tumbleweed { position: absolute; bottom: 4px; font-size: 22px; animation: tumble 9s linear infinite; }
@keyframes tumble { from { left: -8%; transform: rotate(0); } to { left: 106%; transform: rotate(1080deg); } }

.crown-stage { position: relative; border-radius: 16px; border: 3px solid #0d0d0c; padding: 12px;
  background: linear-gradient(180deg, #635a1f, #383218); display: flex; flex-wrap: wrap; gap: 16px; justify-content: center; }
.crown-stage .hill { position: absolute; right: 10px; bottom: 4px; font-size: 40px; opacity: .5; }
.crown-slot { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.crown-points { color: #ffd700; } .crown-points em { color: var(--text-muted); font-style: normal; font-size: .8em; }

.bass-stage { position: relative; border-radius: 16px; border: 3px solid #0d0d0c; padding: 14px 14px 20px;
  background: linear-gradient(180deg, #1f5a4a 0%, #16323b 45%, #10404f 46%, #0c2a36 100%);
  display: flex; flex-direction: column; gap: 10px; overflow: hidden; }
.bass-waves { position: absolute; left: 0; right: 0; top: 42%; display: flex; justify-content: space-around;
  font-size: 18px; opacity: .55; pointer-events: none; }
.bass-waves span { animation: wave-bob 2.4s ease-in-out infinite; }
.bass-waves span:nth-child(2) { animation-delay: .6s; } .bass-waves span:nth-child(3) { animation-delay: 1.2s; }
@keyframes wave-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
.bass-slot { position: relative; display: flex; align-items: center; gap: 10px; }
.bass-angler { position: relative; }
.bass-rod { position: absolute; right: -14px; top: -6px; font-size: 18px; animation: rod-cast 2.8s ease-in-out infinite; transform-origin: 20% 80%; }
@keyframes rod-cast { 0%, 100% { transform: rotate(0); } 45% { transform: rotate(-24deg); } 55% { transform: rotate(8deg); } }
.bass-info { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.bucket-bar { height: 12px; border-radius: 6px; background: rgba(0,0,0,.4); border: 1.5px solid rgba(0,0,0,.5); overflow: hidden; }
.bucket-fill { height: 100%; border-radius: 6px; background: linear-gradient(90deg, #59b04e, #e5c02b);
  transition: width 1s cubic-bezier(.3,.9,.4,1.1); }
.bass-lbs { color: var(--text-muted); }
.last-catch { background: rgba(0,0,0,.5); border-radius: 8px; padding: 2px 8px; font-size: .85em;
  white-space: nowrap; animation: catch-pop .5s cubic-bezier(.3,1.6,.5,1) both; }
@keyframes catch-pop { from { opacity: 0; transform: scale(.4) rotate(-8deg); } to { opacity: 1; transform: none; } }

.splat-stage { border-radius: 16px; border: 3px solid #0d0d0c; padding: 12px;
  background: #1c1620; display: flex; flex-direction: column; gap: 10px; }
.splat-board { display: grid; grid-template-columns: repeat(9, 1fr); gap: 5px; }
.splat-tile { height: 30px; border-radius: 30% 70% 62% 38% / 55% 40% 60% 45%; background: rgba(255,255,255,.07);
  transition: background .5s ease, transform .5s cubic-bezier(.3,1.6,.5,1); transform: scale(.82); }
.splat-tile.owner-1 { background: var(--teal, #5fb0a4); transform: scale(1) rotate(6deg);
  box-shadow: 0 0 10px rgba(95,176,164,.5); }
.splat-tile.owner-2 { background: var(--primary, #d97757); transform: scale(1) rotate(-6deg);
  box-shadow: 0 0 10px rgba(217,119,87,.5); }
.splat-tile:nth-child(2n) { border-radius: 60% 40% 35% 65% / 42% 60% 40% 58%; }
.splat-tile:nth-child(3n) { border-radius: 45% 55% 70% 30% / 60% 35% 65% 40%; }

/* The jam finale: fireworks + winners rocking out. */
.jam-finale { position: relative; text-align: center; border-radius: var(--radius); overflow: hidden;
  padding: 26px 14px 40px; background: radial-gradient(ellipse at 50% 100%, #33224a 0%, #17131f 70%);
  border: 1px solid var(--outline); }
.jam-finale.defeat { background: radial-gradient(ellipse at 50% 100%, #143038 0%, #101a1e 70%); }
.finale-title { font-size: clamp(1.6rem, 4vw, 2.6rem); animation: title-pop .6s cubic-bezier(.3,1.6,.5,1) both; }
.finale-subtitle { color: var(--text-muted); }
@keyframes title-pop { from { opacity: 0; transform: scale(.5); } to { opacity: 1; transform: none; } }

.fireworks { pointer-events: none; position: absolute; inset: 0; }
.firework { position: absolute; width: 4px; height: 4px; animation: fw-cycle 2.1s ease-out infinite; }
.firework .spark { position: absolute; left: 0; top: 0; width: 3px; height: 26px; border-radius: 2px;
  background: currentColor; transform-origin: 50% 0; animation: fw-spark 2.1s ease-out infinite; animation-delay: inherit; }
.fw-0 { color: #ffd700; } .fw-1 { color: #ff6b5e; } .fw-2 { color: #6bd0ff; } .fw-3 { color: #7cf29c; } .fw-4 { color: #d98cff; }
@keyframes fw-cycle { 0%, 12% { opacity: 0; } 16% { opacity: 1; } 70% { opacity: 1; } 100% { opacity: 0; } }
@keyframes fw-spark { 0%, 14% { transform: rotate(var(--a)) scaleY(0); opacity: 0; }
  18% { opacity: 1; } 60% { transform: rotate(var(--a)) scaleY(1) translateY(26px); opacity: .9; }
  100% { transform: rotate(var(--a)) scaleY(.4) translateY(48px); opacity: 0; } }
.fw-rocket { position: absolute; bottom: -6px; width: 4px; height: 16px; border-radius: 2px; background: #ffe9a8;
  animation: fw-rise 2.8s ease-in infinite; }
@keyframes fw-rise { 0% { transform: translateY(0); opacity: 1; } 55% { transform: translateY(-52vh); opacity: 1; }
  60%, 100% { opacity: 0; } }

.jam-stage { display: flex; gap: 30px; justify-content: center; align-items: flex-end;
  margin: 26px 0 8px; min-height: 150px; flex-wrap: wrap; }
.jam-spot { display: flex; flex-direction: column; align-items: center; gap: 10px;
  animation: title-pop .7s cubic-bezier(.3,1.6,.5,1) both; }
.jam-name { font-size: 1.15em; text-shadow: 0 2px 8px rgba(0,0,0,.6); }
.kraken-victor { font-size: 90px; animation: kraken-loom 2.2s ease-in-out infinite; }
.stage-lights { pointer-events: none; position: absolute; inset: 0; }
.stage-lights span { position: absolute; bottom: 0; left: 50%; width: 120px; height: 100%;
  background: linear-gradient(0deg, rgba(255,215,0,.14), transparent 70%);
  transform-origin: 50% 100%; animation: light-sweep 3.4s ease-in-out infinite; }
.stage-lights span:nth-child(2) { background: linear-gradient(0deg, rgba(107,208,255,.12), transparent 70%); animation-delay: 1.1s; }
.stage-lights span:nth-child(3) { background: linear-gradient(0deg, rgba(255,107,94,.12), transparent 70%); animation-delay: 2.2s; }
@keyframes light-sweep { 0%, 100% { transform: translateX(-50%) rotate(-24deg); } 50% { transform: translateX(-50%) rotate(24deg); } }

/* ===== Staff glyphs, note ladders, journey map ===== */
.staff-glyph { color: #f5efe6; display: block; }
.staff-stage { display: flex; justify-content: center; margin: 8px 0 4px; }
.staff-stage .staff-glyph { width: 190px; }
.staff-ladder { overflow-x: auto; padding: 6px 0 2px; }
.staff-ladder .staff-glyph { min-width: 620px; }
.module-emoji { font-size: 1.4em; }

/* Message compose fields: full-width and roomy. */
.compose-field { width: 100%; box-sizing: border-box; font-size: 1.05em;
  padding: 12px 14px; border-radius: 10px; }
textarea.compose-body { min-height: 190px; resize: vertical; line-height: 1.45; }
.rush-panel.your-clef { border: 2px solid #e8834f; box-shadow: 0 0 14px rgba(232, 131, 79, .22); }
.your-clef-badge { background: #e8834f; color: #17130f; border-radius: 10px;
  padding: 2px 10px; font-size: .72em; font-weight: 800; margin-left: 8px; white-space: nowrap; }

.journey-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; }
.level-node { display: flex; flex-direction: column; align-items: center; gap: 3px;
  width: 150px; padding: 12px 8px; border-radius: 14px; border: 2px solid var(--outline, #444);
  background: rgba(255,255,255,.04); color: inherit; cursor: pointer; font: inherit; }
.level-node:hover:not(:disabled) { border-color: var(--primary, #d97757); transform: translateY(-2px); }
.level-node.boss { border-color: #a33b2e; background: rgba(163,59,46,.14); }
.level-node.locked { opacity: .45; cursor: not-allowed; }
.level-icon { font-size: 1.6em; }
.level-stars { color: #ffd700; letter-spacing: 2px; }
.level-stars.big { font-size: 2.2em; letter-spacing: 6px; }

.option.correct { border-color: #3fae6a; background: rgba(63,174,106,.25); }
.option.wrong { border-color: #a33b2e; background: rgba(163,59,46,.25); }
.final-score { font-size: 1.3em; }
a.button { display: inline-block; padding: 10px 18px; border-radius: 12px;
  border: 2px solid var(--outline, #444); color: inherit; text-decoration: none; }
a.button:hover { border-color: var(--primary, #d97757); }

/* ===== Practice room ===== */
.practice-room { max-width: 1040px; margin: 0 auto; }
.practice-toolbar { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; margin: 12px 0 18px; }
.upload-label { border: 2px dashed var(--outline); border-radius: 12px; padding: 10px 16px; cursor: pointer;
  background: var(--surface); color: var(--text); }
.upload-label:hover { border-color: var(--primary); }
.upload-label input[type=file] { display: none; }
.practice-piece { border: 1px solid var(--outline); border-radius: var(--radius); background: var(--surface); padding: 16px; }
.piece-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; flex-wrap: wrap; margin-bottom: 10px; }
.piece-header h2 { margin: 0; }
.piece-header small { color: var(--text-muted); }
.piece-controls { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.piece-controls .primary { margin-top: 0; }
.piece-controls input[type=range] { width: 180px; accent-color: var(--primary); }

/* App-style player row: clef, transpose, count-in, loop. */
.player-controls { display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  background: var(--surface-elevated, #211f1c); border: 1px solid var(--outline, #3a3733);
  border-radius: 12px; padding: 10px 14px; margin: 10px 0 14px; }
.pc-group { display: inline-flex; align-items: center; gap: 8px; }
.pc-group label { color: var(--text-muted); }
.pc-value { min-width: 44px; text-align: center; }
.pc-num { width: 62px; padding: 6px 8px; border-radius: 8px; }
/* Sheet music is paper — it stays white, framed like a page on a music stand. */
.score-page { width: 100%; border: 1px solid #0d0d0c; border-radius: 10px; background: #fff; margin-bottom: 12px;
  box-shadow: 0 6px 18px rgba(0,0,0,.45); }

/* ===== Interval Invaders ===== */
.invaders { max-width: 760px; margin: 0 auto; text-align: center; }
.invaders-sky { position: relative; height: 380px; border-radius: var(--radius); overflow: hidden;
  background: linear-gradient(#0b1030, #26124a 70%, #3a1d33); border: 1px solid var(--outline); }
.invaders-star { position: absolute; width: 2px; height: 2px; background: #fff; border-radius: 50%; opacity: .8; }
.invader { position: absolute; top: -70px; left: 50%; transform: translateX(-50%);
  font-size: 54px; animation-name: descend; animation-timing-function: linear; animation-fill-mode: forwards; }
@keyframes descend { from { top: -70px; } to { top: 320px; } }
.invader.zapped { animation-play-state: paused; }
.invader .speech { position: absolute; top: -6px; left: 60px; font-size: 14px; background: #fff;
  border-radius: 10px; padding: 3px 8px; white-space: nowrap; color: #2b2620; }
.explosion { position: absolute; left: 50%; transform: translateX(-50%); font-size: 64px;
  animation: boomfade .5s ease-out forwards; }
@keyframes boomfade { from { opacity: 1; transform: translateX(-50%) scale(.6); }
  to { opacity: 0; transform: translateX(-50%) scale(1.8); } }
.laser { position: absolute; bottom: 0; left: 50%; width: 4px; transform: translateX(-50%);
  background: linear-gradient(#7cf, #fff); animation: beam .18s ease-out forwards; }
@keyframes beam { from { height: 0; opacity: 1; } to { height: 100%; opacity: 0; } }
.invaders-city { position: absolute; bottom: 0; width: 100%; font-size: 26px; letter-spacing: 6px; }
.invaders-hud { display: flex; justify-content: space-between; align-items: center; margin: 10px 2px; font-weight: 700; }
.cannon-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 10px; margin-top: 10px; }
.cannon { border: 1px solid var(--outline); background: var(--surface-elevated); color: var(--text);
  border-radius: 12px; padding: 12px 6px; font-weight: 700; cursor: pointer; font-family: var(--font); }
.cannon:hover:not(:disabled) { border-color: var(--primary); background: var(--primary-soft); transform: translateY(-2px); }
.cannon:disabled { opacity: .5; }
.cannon small { color: var(--text-muted); font-weight: 600; }
.wave-banner { font-size: 1.4em; font-weight: 800; animation: pulse 1s ease-in-out infinite; }

/* ===== Practice analytics ===== */
.analytics { max-width: 1040px; margin: 0 auto; }
.analytics .card { margin-top: 16px; }
.analytics-avatar { font-size: .8em; }
.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; margin-top: 14px; }
.stat .big { font-size: 2.1rem; font-weight: 800; color: var(--primary); line-height: 1.1; }
.stat .small { color: var(--text); font-weight: 600; }
.stat .small .muted { font-weight: 400; font-size: .82em; }

.feedback-card { display: flex; gap: 16px; align-items: flex-start;
  background: linear-gradient(120deg, var(--primary-soft), var(--surface)); border-color: var(--primary); }
.feedback-maestro .maestro-svg { width: 90px; height: 105px; }
.feedback-text { font-size: 1.05em; }

.day-bars { display: flex; gap: 6px; align-items: flex-end; height: 120px; padding-top: 8px; }
.day-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 4px; height: 100%; }
.day-bar { width: 100%; max-width: 34px; border-radius: 6px 6px 2px 2px;
  background: linear-gradient(180deg, var(--tertiary), var(--primary)); transition: height .4s ease; }
.day-label { font-size: .72em; color: var(--text-muted); }

.analytics-columns { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 820px) { .analytics-columns { grid-template-columns: 1fr; } }

.game-rows { display: flex; flex-direction: column; }
.game-row { display: grid; grid-template-columns: 34px 1fr 120px 52px; gap: 10px; align-items: center; padding: 8px 0;
  border-bottom: 1px solid var(--outline); }
.game-row:last-child { border-bottom: none; }
.game-emoji { font-size: 22px; }
.game-name b { font-size: .98em; }
.acc-bar { height: 10px; background: var(--surface-elevated); border: 1px solid var(--outline); border-radius: 999px; overflow: hidden; }
.acc-fill { height: 100%; border-radius: 999px; }
.acc-good { background: var(--success); }
.acc-mid { background: var(--tertiary); }
.acc-low { background: var(--danger); }
.acc-num { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }

.sparkline { width: 100%; height: 90px; background: var(--surface-elevated); border: 1px solid var(--outline); border-radius: var(--radius-sm); }
.spark-legend { display: flex; justify-content: space-between; font-size: .8em; }

/* ===== Test users ===== */
.cred-table { width: 100%; border-collapse: collapse; font-size: .95em; }
.cred-table th, .cred-table td { text-align: left; padding: 7px 8px; border-bottom: 1px solid var(--outline); }
.cred-table thead th { font-size: .85rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); }
.cred-table code { background: var(--surface-elevated); border: 1px solid var(--outline); padding: 1px 6px; border-radius: 6px; }

/* ===== Rhythm games (Groove Reader, Rhythm Repeat, Don't Drop the Beat) =====
   The transport (js/rhythm.js) drives --rp (playhead 0→1) and --rp-on, and owns
   the .rp-marks layer's children for the length of a take. */
.rp-game { max-width: 680px; margin: 0 auto; }
.rp-options { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 10px; }
.rp-gap { width: 14px; }
.rp-wrap { margin: 10px 0; }
.rp-track { position: relative; border: 2px solid var(--outline); border-radius: 10px; padding: 6px; }
.rp-flow { display: flex; gap: 0; }
.rp-measure { display: flex; flex-basis: 0; border-right: 2px solid var(--outline); padding: 0 2px; }
.rp-measure:last-child { border-right: none; }
.rp-slot { display: flex; flex-direction: column; align-items: center; justify-content: center;
           flex-basis: 0; min-width: 18px; padding: 4px 0; }
.rp-slot.rest { opacity: .55; }
.rp-slot small { color: var(--text-muted); font-size: .72rem; font-weight: 700; }
.rp-veiled { flex: 1; text-align: center; padding: 22px 0; color: var(--text-muted); font-weight: 700; }
.rp-marks { position: absolute; inset: 0; pointer-events: none; }
.rp-mark { position: absolute; top: 8%; bottom: 8%; width: 3px; border-radius: 2px; transform: translateX(-1px); }
.rp-mark.perfect { background: var(--teal); }
.rp-mark.close { background: var(--tertiary); }
.rp-mark.off { background: var(--danger); }
.rp-head { position: absolute; top: 2%; bottom: 2%; width: 2.5px; border-radius: 2px;
           background: var(--primary); left: calc(var(--rp, 0) * 100%);
           opacity: var(--rp-on, 0); transition: opacity .15s; }
.rp-countin { min-height: 30px; text-align: center; }
.rp-count { font-size: 1.5rem; font-weight: 800; color: var(--primary); }
.rp-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 10px 0; }
.rp-space-hint { color: var(--text-muted); font-size: .85rem; }
.rp-space-hint kbd { border: 1px solid var(--outline); border-bottom-width: 2.5px; border-radius: 6px;
                     padding: 1px 8px; font-weight: 700; background: var(--surface-elevated); }
.rp-verdict { margin-top: 12px; text-align: left; }
.rp-drift { color: var(--text-muted); }

/* ---- Meter Explorer: the conducting stand ---- */
.mtr-game { margin: 12px 0; }
.mtr-options { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 10px; }
.mtr-sep { width: 1px; align-self: stretch; background: var(--outline); margin: 0 4px; }
.mtr-stage { display: flex; flex-wrap: wrap; gap: 16px; align-items: center;
             border: 1px solid var(--outline); border-radius: var(--radius);
             background: var(--surface); padding: 12px; }
.mtr-svg { width: 240px; max-width: 100%; flex-shrink: 0; }
.mtr-path { fill: none; stroke: var(--text-muted); stroke-width: 2.5; stroke-linecap: round;
            stroke-dasharray: 1 6; opacity: .8; }
.mtr-ictus { fill: var(--surface-elevated); stroke: var(--text-muted); stroke-width: 2; }
.mtr-ictus.big { fill: var(--primary); stroke: var(--primary); }
.mtr-num { fill: var(--text-muted); font-size: 13px; font-weight: 800; text-anchor: middle;
           font-family: var(--font); }
.mtr-dot { fill: var(--tertiary); }
.mtr-facts { flex: 1; min-width: 220px; }
.mtr-facts p { margin: 6px 0; }
.mtr-count b { display: inline-block; min-width: 1.4em; text-align: center;
               color: var(--text-muted); font-weight: 600; }
.mtr-count b.big { color: var(--primary); font-weight: 800; font-size: 1.25em; }
.mtr-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 12px 0; }
.mtr-duel { margin-top: 12px; }
.mtr-duel-rows { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.mtr-duel-row { display: flex; align-items: center; gap: 12px; }
.mtr-cells { display: inline-flex; align-items: center; gap: 7px; }
.mtr-cells i { width: 9px; height: 9px; border-radius: 50%; background: var(--text-muted);
               opacity: .6; }
.mtr-cells i.big { width: 15px; height: 15px; background: var(--primary); opacity: 1; }
.mtr-card { margin-top: 12px; }

/* ---- Symbol Lab: the A/B listening deck ---- */
.sym-deck { margin: 12px 0; }
.sym-family { margin: 18px 0 8px; font-size: 1.05rem; color: var(--text-muted);
              text-transform: uppercase; letter-spacing: .06em; }
/* 320px, not 240: these cards carry two engraved bars, and at four across the
   staff was narrower than a readable measure. Three to a row on a desktop. */
.sym-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 12px; }
.sym-card { position: relative; border: 1px solid var(--outline); border-radius: var(--radius);
            background: var(--surface); padding: 14px; display: flex; flex-direction: column; gap: 6px; }
.sym-card.heard { border-color: var(--primary); }
.sym-glyph { font-family: Georgia, "Times New Roman", serif; font-style: italic; font-weight: 700;
             font-size: 1.9rem; line-height: 1.1; color: var(--primary); }
.sym-card p { margin: 0; flex: 1; }
.sym-ab { display: flex; gap: 8px; flex-wrap: wrap; }
.sym-with { font-weight: 700; }
.sym-check { position: absolute; top: 10px; right: 12px; color: var(--primary); font-weight: 800; }
.sym-trophy { margin-top: 16px; }

/* ---- Score Lab: click-a-measure analysis in the practice room ---- */
.score-page-wrap { position: relative; margin: 10px 0; }
.score-page-wrap .score-page { display: block; width: 100%; }
.score-overlay { position: absolute; inset: 0; width: 100%; height: 100%; }
.score-hot { fill: transparent; stroke: none; cursor: pointer; pointer-events: all; }
.score-hot:hover { fill: rgba(95, 176, 164, .12); }
.score-hot.sel { fill: rgba(95, 176, 164, .10); stroke: var(--tertiary); stroke-width: 3; }
.score-hot.glow { fill: rgba(249, 220, 200, .45); } /* the follow-along light, PNG-free */
.lab-panel { border: 1px solid var(--tertiary); border-radius: var(--radius);
             background: var(--surface); padding: 14px 16px; margin: 12px 0; }
.lab-head { display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
            justify-content: space-between; }
.lab-head h3 { margin: 0; }
.lab-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.lab-notes ul { margin: 4px 0 10px; padding-left: 22px; }
.lab-count { color: var(--primary); min-width: 1.4em; display: inline-block; }
.lab-countline b { font-size: 1.15em; letter-spacing: .12em; color: var(--primary); }
.lab-clap { margin-top: 10px; border-top: 1px dashed var(--outline); padding-top: 10px; }

/* ---- /read hub: the eight-stage reading path ---- */
.read-path { list-style: none; margin: 16px 0; padding: 0; display: flex;
             flex-direction: column; gap: 10px; counter-reset: stage; }
.read-stage a { display: flex; gap: 14px; align-items: center; text-decoration: none;
                color: var(--text); border: 1px solid var(--outline);
                border-radius: var(--radius); background: var(--surface); padding: 12px 16px;
                transition: transform .08s ease; }
.read-stage a:hover { transform: translateX(4px); }
.read-stage.done a { border-color: var(--tertiary); opacity: .85; }
.read-stage.next a { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
.read-badge { font-size: 1.5rem; width: 2.2rem; text-align: center; flex-shrink: 0; }
.read-stage.done .read-badge { color: var(--tertiary); font-weight: 800; }
.read-body { display: flex; flex-direction: column; gap: 2px; }
.read-body small { color: var(--text-muted); }
.read-progress { font-variant-numeric: tabular-nums; }
.read-stage.next .read-progress { color: var(--primary); }

/* ---- Journey rhythm levels: tuplet brackets, status strip, polyrhythm coda ---- */
.rp-tuplet { display: flex; flex-direction: column; align-items: stretch; min-width: 0; }
.rp-tuplet-num { text-align: center; color: var(--text-muted); font-weight: 800;
                 line-height: 1; border-top: 1.5px solid var(--text-muted);
                 border-left: 1.5px solid var(--text-muted); border-right: 1.5px solid var(--text-muted);
                 border-radius: 4px 4px 0 0; padding-top: 1px; margin: 0 3px 2px; font-size: .7rem; }
.rp-tuplet-notes { display: flex; flex: 1; align-items: flex-end; }
.rp-tuplet > small:last-child { text-align: center; color: var(--text-muted); }
.rl-status { display: flex; justify-content: flex-end; margin-bottom: 6px; }

/* Two-voice strip: a dot row per hand, and tap marks that land in their own
   hand's lane (rhythm.js tags marks v0/v1 in two-voice takes). */
.rp-poly { display: flex; flex-direction: column; gap: 8px; width: 100%; padding: 10px 6px; }
.rp-poly-voice { position: relative; height: 30px; border-radius: 8px;
                 background: color-mix(in srgb, var(--surface-elevated) 70%, transparent); }
.rp-poly-voice > b { position: absolute; left: 8px; top: 50%; transform: translateY(-50%);
                     color: var(--text-muted); font-size: .8rem; }
.rp-poly-onset { position: absolute; top: 50%; width: 12px; height: 12px; margin-left: -6px;
                 border-radius: 50%; transform: translateY(-50%); }
.rp-poly-onset.top { background: var(--tertiary); }
.rp-poly-onset.bottom { background: var(--primary); }
/* The worked example hears one voice at a time: the lane you're hearing lights,
   the one resting recedes. Transitioned so a movement change reads as a move. */
.rp-poly-voice { transition: opacity .25s ease, box-shadow .25s ease; }
.rp-poly-voice.dim { opacity: .25; }
.rp-poly-voice.lit { box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 60%, transparent); }
.rl-demo { margin: 8px 0 0; text-align: center; color: var(--text); font-weight: 600; }
.rp-mark.v0 { top: 6%; height: 40%; }
.rp-mark.v1 { top: 54%; height: 40%; }
.rl-coda { text-align: left; }
.rl-poly { display: flex; flex-direction: column; gap: 10px; margin: 12px 0; }
.rl-poly-row { display: flex; align-items: center; gap: 14px; }
.rl-poly-row small { color: var(--text-muted); }
.rl-poly-dot { width: 18px; height: 18px; border-radius: 50%; background: var(--outline); }
.rl-poly-dot.three.live { background: var(--tertiary); animation: rl-pulse infinite; }
.rl-poly-dot.two.live { background: var(--primary); width: 22px; height: 22px; animation: rl-pulse infinite; }
@keyframes rl-pulse {
  0%, 8% { transform: scale(1.45); filter: brightness(1.5); }
  16%, 100% { transform: scale(1); filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  .rl-poly-dot.live { animation: none; }
}

/* ---- Practice room: the app sheet-music shelf ---- */
.app-shelf { border: 1px dashed var(--outline); border-radius: var(--radius);
             padding: 10px 14px; margin: 10px 0; display: flex; flex-direction: column; gap: 6px; }
.app-shelf-row { display: flex; flex-wrap: wrap; gap: 8px; }

/* ---- /features: the public tour ---- */
.feat-page { max-width: 1080px; margin: 0 auto; }
.feat-hero { text-align: center; margin: 20px 0 8px; }
.feat-hero .muted { max-width: 46em; margin: 0 auto; }
.feat-locked { border: 2px solid var(--primary); border-radius: var(--radius);
               background: var(--surface); padding: 18px 20px; margin: 16px 0; }
.feat-locked h2 { margin-top: 0; }
.feat-policy { border: 1px solid var(--outline); border-radius: var(--radius);
               background: var(--surface); padding: 16px 20px; margin: 22px 0; }
.feat-policy h2 { margin-top: 0; }
.feat-policy-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
                    gap: 12px; margin: 10px 0; }
.feat-pass { border: 1px solid var(--outline); border-radius: 12px; padding: 12px 14px;
             display: flex; flex-direction: column; gap: 4px; }
.feat-pass span { font-size: 1.6rem; }
.feat-pass small { color: var(--text-muted); }
.feat-pass.free { border-color: var(--tertiary); }
.feat-pass.paid { border-color: var(--primary); }
.feat-section { display: flex; gap: 24px; align-items: center; margin: 34px 0; }
.feat-section:nth-of-type(even) { flex-direction: row-reverse; }
.feat-copy { flex: 1; min-width: 260px; }
.feat-copy h2 { margin-top: 0; }
.feat-links a { font-weight: 700; }
.feat-shot { flex: 1.1; min-width: 280px; display: block; border-radius: var(--radius);
             overflow: hidden; border: 1px solid var(--outline);
             transition: transform .12s ease; }
.feat-shot:hover { transform: translateY(-3px); }
.feat-shot img { display: block; width: 100%; }
.feat-demo { flex: 1.3; min-width: 300px; border: 1px solid var(--outline);
             border-radius: var(--radius); background: var(--surface); padding: 12px; }
.feat-live, .feat-section.feat-live { flex-wrap: wrap; }
.feat-miles { border-top: 1px dashed var(--outline); padding-top: 18px; }
.feat-cta { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
.feat-cta-final { justify-content: center; margin: 30px 0 40px; }
@media (max-width: 760px) {
  .feat-section, .feat-section:nth-of-type(even) { flex-direction: column; }
}

/* Touch devices tap the strip itself (rhythm.js pointerdown pad); this hint
   surfaces there and at phone widths, where the SPACE key hint would mislead. */
.rp-wrap { touch-action: none; } /* a tap on the pad must never become a scroll */
.rp-needs-keys { display: none; }
@media (hover: none) and (pointer: coarse), (max-width: 640px) {
  .rp-space-hint { display: none; }
  .rp-needs-keys { display: block; flex-basis: 100%; color: var(--text-muted);
                   font-size: .9rem; border: 1px dashed var(--outline);
                   border-radius: 10px; padding: 8px 12px; }
}

/* The repo's first reduced-motion block: rhythm.js already quantizes the
   playhead to beat steps under this query; the CSS drops the remaining motion. */
@media (prefers-reduced-motion: reduce) {
    .rp-head { transition: none; }
    .rp-mark { animation: none; }
}

/* ===== Pitch Match tuner (/play/pitch-match) ===== */
/* A needle on a scale: centre is the target, one semitone either side. The
   fill underneath is how long you've held it — banking a note takes a steady
   second, so a glide through the right pitch doesn't score. */
.pm-tuner { position: relative; margin: 18px auto 6px; max-width: 420px;
            border: 1px solid var(--outline); border-radius: var(--radius);
            background: var(--surface); padding: 18px 16px 10px; }
.pm-tuner.locked { border-color: var(--teal); box-shadow: 0 0 0 2px rgba(95,176,164,.25); }

.pm-scale { position: relative; height: 46px; }
.pm-scale::before { content: ""; position: absolute; left: 0; right: 0; top: 50%;
                    height: 2px; background: var(--outline); }
.pm-mark { position: absolute; top: 50%; transform: translateY(-50%);
           color: var(--text-muted); font-size: 1.1rem; }
.pm-mark.flat { left: 2px; }
.pm-mark.sharp { right: 2px; }
.pm-target { position: absolute; left: 50%; top: 6px; bottom: 6px; width: 2px;
             margin-left: -1px; background: var(--teal); }

.pm-needle { position: absolute; top: 2px; bottom: 2px; width: 4px; margin-left: -2px;
             border-radius: 2px; background: var(--primary);
             transition: left .08s linear; }
.pm-tuner.locked .pm-needle { background: var(--teal); }

.pm-hold { height: 6px; margin-top: 8px; border-radius: 3px;
           background: var(--teal); transition: width .1s linear; }

.pm-verdict { text-align: center; font-weight: 600; margin: 10px 0 4px; min-height: 1.5em; }

@media (prefers-reduced-motion: reduce) {
    .pm-needle, .pm-hold { transition: none; }
}

/* ===== Symbol Lab notation (/play/symbols) ===== */
/* The engraved phrase scales to whatever width its card gives it, so the two
   bars always fit whole — you should never scroll to find the mark the card is
   about. It was fixed-height with a 340px floor inside a 240px card, which is
   exactly the scrollbar this removes; the cards widened to match. A phone gets
   one card per row, so the staff is wider there than it was at four across. */
.sym-notation { margin: 10px 0 12px; }
.sym-staff { display: block; width: 100%; height: auto; color: var(--text); }
.sym-caption { display: block; margin-top: 2px; color: var(--text-muted); font-size: .82rem; }

@media (prefers-reduced-motion: reduce) {
    .sym-staff { transition: none; }
}

/* ===== Reading Journey clock (/journey) ===== */
/* The countdown reads as a number as well as a bar: under prefers-reduced-motion
   the drain animation is suppressed, and a frozen bar would be a lie. */
.jrn-clock { font-variant-numeric: tabular-nums; min-width: 3.4em; text-align: center; }
.jrn-clock.urgent { border-color: var(--danger); color: var(--danger); }
.jrn-timeout { border-left: 3px solid var(--danger); padding-left: 10px; }

@media (prefers-reduced-motion: reduce) {
    .timer-fill { animation: none; }
}
.jrn-yours { margin-left: 8px; color: var(--primary); font-size: .72rem;
             text-transform: uppercase; letter-spacing: .06em; font-weight: 700; }
