:root {
  --ink: #1b233e;
  --muted: #65728f;
  --bg: #eef1f5;
  --tray-bg: #ffffff;
  --tray-line: #d9e3f3;
  --teal: #099695;
  --teal-dark: #007777;

  /* Prodigies bell palette */
  --c-color:  #e72829;
  --d-color:  #f39422;
  --e-color:  #f1e606;
  --f-color:  #6abb4a;
  --g-color:  #099695;
  --a-color:  #7b569e;
  --b-color:  #ea6ba3;
  --c5-color: #e72829;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
}

body {
  min-height: 100vh;
  min-height: 100svh;
  color: var(--ink);
  font-family: "Nunito", "Avenir Next Rounded", "Trebuchet MS", "Verdana", sans-serif;
  overflow-x: hidden;
  overscroll-behavior: contain;
  -webkit-tap-highlight-color: transparent;
}

body.is-dragging {
  overflow: hidden;
  touch-action: none;
}



.app {
  width: min(720px, 100%);
  margin: 0 auto;
}

.screen {
  min-height: 100vh;
  min-height: 100svh;
  padding: calc(56px + env(safe-area-inset-top)) 14px calc(28px + env(safe-area-inset-bottom));
  display: grid;
  align-content: start;
  gap: 14px;
  position: relative;
}

.game-head {
  text-align: center;
  display: grid;
  gap: 8px;
}

.app-title {
  margin: 0;
  font-size: clamp(1.6rem, 6vw, 2.1rem);
  font-weight: 900;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.prompt {
  margin: 0;
  color: var(--muted);
  font-size: clamp(0.96rem, 3.7vw, 1.05rem);
  line-height: 1.3;
  font-weight: 800;
  padding: 0 6px;
}

.level-row {
  display: inline-flex;
  align-self: center;
  background: #fff;
  border: 1px solid var(--tray-line);
  border-radius: 999px;
  padding: 4px;
  gap: 4px;
  box-shadow: 0 4px 10px rgba(27, 35, 62, 0.08);
}

.level-btn {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 7px 14px;
  border-radius: 999px;
  font-weight: 900;
  font-size: 0.85rem;
  color: var(--muted);
  cursor: pointer;
}

.level-btn.is-active {
  background: var(--teal);
  color: #fff;
  box-shadow: 0 3px 8px rgba(9, 150, 149, 0.32);
}

/* ---------- Sort tray ---------- */

.tray-wrap { position: relative; }

.sort-tray {
  position: relative;
  background: linear-gradient(180deg, #fbfdff 0%, #f3f7fd 100%);
  border: 1px solid var(--tray-line);
  border-radius: 22px;
  padding: 14px 12px 16px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  box-shadow: 0 10px 24px rgba(27, 49, 95, 0.1), inset 0 2px 0 rgba(255, 255, 255, 0.9);
}

@media (min-width: 560px) {
  .sort-tray {
    grid-template-columns: repeat(8, 1fr);
    gap: 8px;
    padding: 16px 14px 18px;
  }
}

.slot {
  position: relative;
  aspect-ratio: 1 / 1.22;
  min-height: 84px;
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.7);
  border: 2px dashed rgba(132, 152, 188, 0.46);
  display: grid;
  place-items: center;
  padding: 6px 4px;
  transition: background 160ms ease, border-color 160ms ease, box-shadow 200ms ease;
}

.slot[data-pos="0"] { --slot-tint: var(--c-color); }
.slot[data-pos="1"] { --slot-tint: var(--d-color); }
.slot[data-pos="2"] { --slot-tint: var(--e-color); }
.slot[data-pos="3"] { --slot-tint: var(--f-color); }
.slot[data-pos="4"] { --slot-tint: var(--g-color); }
.slot[data-pos="5"] { --slot-tint: var(--a-color); }
.slot[data-pos="6"] { --slot-tint: var(--b-color); }
.slot[data-pos="7"] { --slot-tint: var(--c5-color); }

.slot-inner {
  position: absolute;
  inset: 6px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  pointer-events: none;
  color: rgba(27, 35, 62, 0.55);
  font-weight: 900;
}

.slot-letter {
  font-size: clamp(0.92rem, 3.6vw, 1.05rem);
  line-height: 1;
}

/* Level 1: color-tinted slots with label */
.sort-tray[data-level="1"] .slot {
  background: color-mix(in srgb, var(--slot-tint) 11%, #fff 89%);
  border-color: color-mix(in srgb, var(--slot-tint) 55%, transparent);
}

.sort-tray[data-level="1"] .slot-inner {
  color: color-mix(in srgb, var(--slot-tint) 70%, #1b233e 30%);
}

.sort-tray[data-level="1"] .slot[data-pos="2"] .slot-letter {
  color: #6b5a07;
}

/* Level 2: letter only, no tint */
.sort-tray[data-level="2"] .slot {
  background: rgba(255, 255, 255, 0.78);
  border-color: rgba(132, 152, 188, 0.46);
}

.sort-tray[data-level="2"] .slot-inner {
  color: rgba(27, 35, 62, 0.55);
}

/* Level 3: blank slots with very faint rainbow */
.sort-tray[data-level="3"] .slot {
  background: color-mix(in srgb, var(--slot-tint) 14%, #fff 86%);
  border-color: rgba(132, 152, 188, 0.32);
}

.sort-tray[data-level="3"] .slot-inner {
  display: none;
}

/* ── Level 4, Expert: every visual cue gone ──────────────────────────────────
   Hard still leaves a 14% rainbow wash on each slot, so the tray itself spells
   out the answer to anyone who looks closely. Expert takes the colour off the
   slots AND off the bells, hides the letters on both, and drops the high-C
   badge, which was the last thing distinguishing the two Cs by sight.

   Tapping a bell still rings it (playBell fires on pointerdown), so the level
   is demanding, not unfair: it is the same puzzle solved with ears instead of
   eyes. Everything here is presentation only — the notes, the drop logic and
   the win check are untouched, so a card still knows which slot it belongs to.
*/
.sort-tray[data-level="4"] .slot {
  background: rgba(255, 255, 255, 0.7);
  border-color: rgba(132, 152, 188, 0.34);
}

.sort-tray[data-level="4"] .slot-inner {
  display: none;
}

/* The bells go grey. `grayscale(1)` keeps the drawing and its shading, so they
   still read as Prodigies bells rather than silhouettes — they just stop
   announcing their note. The border and glow follow, or the card frame would
   leak the chroma the art no longer shows. */
.bell-sort-page[data-level="4"] .bell-art {
  filter: grayscale(1) drop-shadow(0 2px 1px rgba(27, 35, 62, 0.16));
}

.bell-sort-page[data-level="4"] .bell-card {
  border-color: rgba(132, 152, 188, 0.55);
}

.bell-sort-page[data-level="4"] .bell-label,
.bell-sort-page[data-level="4"] .bell-high-badge {
  display: none;
}

/* Once a bell is home it has been earned, so let its colour come back. That is
   the reward for hearing it, and it turns the finished tray into the rainbow
   the easier levels hand you for free. */
.bell-sort-page[data-level="4"] .bell-card.is-locked .bell-art {
  filter: drop-shadow(0 2px 1px rgba(27, 35, 62, 0.16));
}

.bell-sort-page[data-level="4"] .bell-card.is-locked {
  border-color: var(--note-color, #c9d7f5);
}

/* Expert: even the drag-hover must not leak. The generic rule below tints the
   slot under your finger with that slot's own note colour, which would hand you
   the answer for the price of hovering across the tray. Neutral teal instead —
   it still says "this one is live", without saying which note lives here. */
.sort-tray[data-level="4"] .slot.is-hover {
  background: rgba(9, 150, 149, 0.14);
  border-color: rgba(9, 150, 149, 0.6);
}

/* Hover during drag */
.slot.is-hover {
  background: color-mix(in srgb, var(--slot-tint) 28%, #fff 72%);
  border-color: var(--slot-tint);
  border-style: solid;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--slot-tint) 35%, transparent);
}

/* Slot rejection flash on wrong drop */
.slot.is-reject {
  animation: slotReject 260ms ease-out;
}

@keyframes slotReject {
  0%   { box-shadow: 0 0 0 0 rgba(231, 40, 41, 0.55); border-color: #e72829; }
  100% { box-shadow: 0 0 0 12px transparent; }
}

.slot.is-correct .slot-inner { opacity: 0; }
.slot.is-correct { border-style: solid; border-color: transparent; background: transparent; }

/* Slot glow on correct */
.slot.flash {
  animation: slotFlash 480ms ease-out;
}

@keyframes slotFlash {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--slot-tint) 55%, transparent); }
  100% { box-shadow: 0 0 0 14px transparent; }
}

/* ---------- Bank ---------- */

.bank-wrap {
  margin-top: 4px;
  transition: opacity 280ms ease, transform 280ms ease;
}

.bank-wrap.is-empty {
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  max-height: 0;
  overflow: hidden;
  margin-top: 0;
}

.bank-grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  padding: 14px 10px 16px;
  background: rgba(255, 255, 255, 0.65);
  border: 1px solid var(--tray-line);
  border-radius: 20px;
  box-shadow: 0 6px 18px rgba(27, 49, 95, 0.08);
}

@media (min-width: 560px) {
  .bank-grid {
    grid-template-columns: repeat(8, 1fr);
    gap: 10px;
  }
}

.bank-cell {
  position: relative;
  aspect-ratio: 1 / 1.22;
  min-height: 88px;
}

/* ---------- Bell card (PNG + colored border, like Melody Memory) ---------- */

.bell-card {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding: 6px 6px 6px;
  border-radius: 18px;
  background: #ffffff;
  border: 3px solid var(--note-color, #c9d7f5);
  color: #1f3668;
  font-weight: 900;
  box-shadow: 0 6px 14px rgba(27, 35, 62, 0.16);
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
  cursor: grab;
  will-change: transform;
  transition: transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 180ms ease;
}

.bell-card:active { cursor: grabbing; }

.bell-art {
  width: 100%;
  height: 78%;
  object-fit: contain;
  margin-top: -2px;
  pointer-events: none;
  filter: drop-shadow(0 2px 1px rgba(27, 35, 62, 0.16));
}

.bell-label {
  margin-top: auto;
  padding: 0 4px 2px;
  font-size: clamp(0.72rem, 2.7vw, 0.85rem);
  line-height: 1;
  color: #223e75;
  letter-spacing: 0.02em;
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.66);
  pointer-events: none;
}

.bell-high-badge {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--note-color, #c9d7f5);
  color: var(--note-color, #1f3668);
  font-size: 0.72rem;
  font-weight: 900;
  display: grid;
  place-items: center;
  box-shadow: 0 2px 5px rgba(27, 35, 62, 0.2);
  pointer-events: none;
}

.bell-card.is-dragging {
  cursor: grabbing;
  z-index: 200;
  transform: scale(1.08) rotate(-2deg);
  box-shadow: 0 18px 30px rgba(27, 35, 62, 0.28);
  transition: none;
}

.bell-card.is-floating {
  position: fixed;
  pointer-events: none;
  width: var(--card-w, 80px);
  height: var(--card-h, 96px);
  inset: auto;
}

.bell-card.is-locked {
  cursor: default;
  touch-action: auto;
}

.bell-card.is-returning {
  pointer-events: none;
}

.bell-card.is-pop {
  animation: bellPop 360ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.bell-card.is-ring {
  animation: bellRing 260ms ease-out;
}

@keyframes bellPop {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.12) rotate(-2deg); }
  100% { transform: scale(1) rotate(0); }
}

@keyframes bellRing {
  0%   { transform: scale(1) rotate(0); }
  35%  { transform: scale(1.07) rotate(-5deg); }
  65%  { transform: scale(1.04) rotate(4deg); }
  100% { transform: scale(1) rotate(0); }
}

/* Star burst */
.star-burst {
  position: fixed;
  pointer-events: none;
  z-index: 250;
  width: 0;
  height: 0;
}

.star-burst span {
  position: absolute;
  left: 0;
  top: 0;
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: var(--star, #ffd25b);
  box-shadow: 0 0 6px rgba(255, 210, 91, 0.7);
  animation: starFly 620ms cubic-bezier(0.32, 0.72, 0.42, 1) forwards;
}

@keyframes starFly {
  0%   { transform: translate(0, 0) scale(0.6); opacity: 1; }
  100% { transform: translate(var(--dx, 0), var(--dy, 0)) scale(0.1); opacity: 0; }
}

/* ---------- Action row + success ---------- */

.action-row {
  display: flex;
  justify-content: center;
  margin-top: 8px;
}

.action-btn {
  appearance: none;
  border: 0;
  background: var(--teal);
  color: #fff;
  font-weight: 900;
  font-size: 1rem;
  padding: 14px 26px;
  border-radius: 999px;
  box-shadow: 0 8px 16px rgba(9, 150, 149, 0.28), inset 0 -4px 0 rgba(0, 0, 0, 0.14);
  cursor: pointer;
}

.action-btn:active {
  transform: translateY(2px);
  box-shadow: 0 4px 8px rgba(9, 150, 149, 0.25), inset 0 -2px 0 rgba(0, 0, 0, 0.14);
}

.success-banner {
  position: fixed;
  left: 50%;
  top: 30%;
  transform: translate(-50%, -50%) scale(0.6);
  z-index: 220;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  border-radius: 999px;
  background: linear-gradient(180deg, #ffffff 0%, #fff7df 100%);
  border: 2px solid #ffd25b;
  color: #1b233e;
  font-size: clamp(1rem, 4vw, 1.2rem);
  font-weight: 900;
  box-shadow: 0 18px 30px rgba(27, 35, 62, 0.25);
  opacity: 0;
  transition: opacity 240ms ease, transform 360ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.success-banner.show {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.success-emoji { font-size: 1.3em; }

/* Confetti */
.confetti-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 210;
}

.confetti-piece {
  position: absolute;
  top: -20px;
  width: 10px;
  height: 14px;
  border-radius: 2px;
  opacity: 0.95;
  animation: confettiFall var(--confetti-duration, 2400ms) linear forwards;
}

@keyframes confettiFall {
  0%   { transform: translate(0, 0) rotate(0deg); opacity: 1; }
  100% { transform: translate(var(--confetti-x, 0), 110vh) rotate(720deg); opacity: 0.85; }
}

/* Tiny phone tweaks */
@media (max-width: 360px) {
  .screen { padding-left: 10px; padding-right: 10px; }
  .sort-tray { padding: 12px 8px; gap: 6px; }
  .bank-grid { padding: 12px 8px; gap: 8px; }
  .slot      { min-height: 72px; }
  .bank-cell { min-height: 78px; }
}
