:root {
  /* Key width is SOLVED from the space available rather than guessed, so the
     keyboard always fills the screen exactly: viewport, minus the page edges,
     minus the piano case, minus the gaps, divided by the number of white
     keys. --white-count is set by piano.js from the real key range. */
  --edge: 16px;                 /* page side padding */
  --case: 14px;                 /* piano case side padding */
  --gap: 2px;                   /* between white keys */
  --white-count: 10;

  --white-w: min(58px, calc(
    (100vw - 2 * var(--edge) - 2 * var(--case)
     - (var(--white-count) - 1) * var(--gap)) / var(--white-count)));
  /* Floor the height: when keys get narrow on a phone, keeping them tall is
     what keeps them tappable -- the area below the black keys is full width. */
  --white-h: clamp(190px, calc(var(--white-w) * 4.06), 260px);
  --black-w: calc(var(--white-w) * 0.66);
  --black-h: calc(var(--white-h) * 0.635);

  --ink: #d7dce6;
  --dim: #8b93a3;
  --good: #4ade80;
  --bad: #f87171;
  --accent: #6ea8fe;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 0;
  padding: 10px var(--edge) 24px;
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  background: radial-gradient(circle at 50% 0%, #2a2f3a, #14161c 70%);
  color: var(--ink);
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

.day {
  font-size: 11px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--accent); font-weight: 700;
}
.headline h1 { margin: 0; font-size: clamp(22px, 6vw, 34px); font-weight: 700; }
.composer { font-size: 13px; color: var(--dim); margin-top: -6px; }

/* --- board ------------------------------------------------------------ */
/* Everything except the day bar, centred in the remaining height. */
.stage {
  flex: 1;
  width: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px;
}

/* Title, composer, replay button -- deliberately tight so the button reads as
   part of the title block rather than a separate control. */
.headline { display: flex; flex-direction: column; align-items: center; gap: 10px; }

/* Tiles, progress bar and keyboard as one stack, so the tiles sit on top of
   the keys instead of floating away from them. */
.play-area {
  width: 100%; max-width: 620px;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}

.tiles { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }

.tile {
  width: 46px; height: 46px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  border: 2px solid #3a3f4b;
  background: #232733;
  font-size: 12px; font-weight: 600; color: var(--dim);
  transition: background 120ms, border-color 120ms, transform 120ms, color 120ms;
}
.tile.lit {
  background: linear-gradient(#2f6b45, #245239);
  border-color: var(--good);
  color: #d6ffe6;
}
.tile.demo { transform: translateY(-5px); border-color: var(--accent); }
/* Staggered off --i so the tiles fire left-to-right like a run up the
   keyboard, rather than all jumping at once. */
.tiles.won .tile {
  animation: winpop 560ms cubic-bezier(.22, .9, .3, 1.3) both;
  animation-delay: calc(var(--i, 0) * 60ms);
}
.tiles.shake { animation: shake 300ms ease; }

@keyframes winpop {
  40% {
    transform: translateY(-14px) scale(1.12);
    background: linear-gradient(#ffd97a, #f2b134);
    border-color: #ffe9a8;
    color: #3a2c05;
    box-shadow: 0 10px 22px rgba(242, 177, 52, .45);
  }
  100% { transform: translateY(0) scale(1); }
}
@keyframes shake {
  25% { transform: translateX(-6px); } 75% { transform: translateX(6px); }
}

.track {
  width: 100%; height: 5px; border-radius: 999px;
  background: #232733; overflow: hidden;
}
.bar {
  height: 100%; width: 0;
  background: linear-gradient(90deg, var(--accent), var(--good));
  transition: width 160ms ease;
}

.stats {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 6px 18px; font-size: 12px; color: var(--dim);
}
.stats strong { color: var(--ink); font-variant-numeric: tabular-nums; }


button {
  font: inherit; font-size: 14px; font-weight: 600;
  padding: 10px 18px; border-radius: 999px; cursor: pointer;
  border: 1px solid #3a3f4b; background: #272b36; color: var(--ink);
  transition: background 120ms, transform 80ms;
}
/* These chrome styles must NOT reach the piano keys: .key is a <button>, and
   `button:hover` outranks `.white`, which left a tapped key stuck dark. Touch
   devices keep :hover after a tap, so it read as a key held down. */
button:disabled { opacity: .5; cursor: default; }
button.primary { background: var(--accent); border-color: var(--accent); color: #10233f; }

@media (hover: hover) {
  button:not(.key):hover:not(:disabled) { background: #313644; }
  button.primary:hover:not(:disabled) { background: #8bbcff; }
}
button:not(.key):active:not(:disabled) { transform: translateY(1px); }

/* --- piano ------------------------------------------------------------ */
.piano {
  position: relative; display: flex;
  padding: 12px var(--case) 16px; border-radius: 10px;
  background: linear-gradient(#3a3f4b, #23262e);
  box-shadow: 0 20px 50px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.08);
}
.keys { position: relative; display: flex; }

.key {
  position: relative; border: 0; padding: 0; cursor: pointer; font: inherit;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  transition: background 40ms linear, transform 40ms linear;
}
.key .label { font-size: clamp(7px, 1.5vw, 10px); padding-bottom: 8px; pointer-events: none; }
.key .letter {
  font-size: clamp(7px, 1.4vw, 9px); opacity: .5;
  padding-bottom: 8px; pointer-events: none;
}

.white {
  width: var(--white-w); height: var(--white-h);
  background: linear-gradient(#ffffff, #ecedf1 82%, #d5d7de);
  border-radius: 0 0 6px 6px;
  box-shadow: inset -2px 0 3px rgba(0,0,0,.14), 0 4px 6px rgba(0,0,0,.35);
  color: #7b8291;
}
.white + .white { margin-left: var(--gap); }

.black {
  position: absolute; top: 0;
  width: var(--black-w); height: var(--black-h);
  background: linear-gradient(#4a4f5c, #15171c 70%);
  border-radius: 0 0 5px 5px;
  box-shadow: 0 5px 8px rgba(0,0,0,.6), inset 0 -3px 0 rgba(255,255,255,.07);
  color: #9aa2b3; z-index: 2;
}

.key.good  { background: linear-gradient(#7ee6a6, #35a86a); transform: translateY(2px); }
.key.bad   { background: linear-gradient(#ffb0b0, #d24d4d); transform: translateY(2px); }
.key.demo  { background: linear-gradient(#cfe3ff, #6ea8fe); transform: translateY(2px); }

/* --- overlay ---------------------------------------------------------- */
.overlay {
  position: fixed; inset: 0; display: none;
  align-items: center; justify-content: center;
  background: rgba(8,10,14,.72); backdrop-filter: blur(4px); z-index: 50;
}
.overlay.show { display: flex; }
.modal {
  width: min(360px, 88vw); text-align: center; padding: 28px 24px;
  border-radius: 16px; border: 1px solid #3a3f4b;
  background: linear-gradient(#2b303c, #1e222b);
  box-shadow: 0 30px 70px rgba(0,0,0,.6);
}
.modal h2 { margin: 0 0 6px; font-size: 24px; }
.modal .bigscore {
  font-size: 56px; font-weight: 800; line-height: 1;
  color: #ffd166; margin-bottom: 8px; font-variant-numeric: tabular-nums;
}
.modal p { margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: var(--dim); }
.modal-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* --- day switcher ------------------------------------------------------ */
.days {
  width: 100%;
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 6px;
  padding-bottom: 4px;
}
.days-label {
  font-size: 11px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--dim); font-weight: 700; margin-right: 4px;
}
.day-chip {
  width: 32px; height: 32px; padding: 0;
  border-radius: 9px; font-size: 13px; font-weight: 700;
  border: 1px solid #3a3f4b; background: #232733; color: var(--dim);
}
.day-chip:hover:not(.active) { background: #313644; color: var(--ink); }
.day-chip.active {
  background: var(--accent); border-color: var(--accent); color: #10233f;
}
/* A dot marks the real calendar day, so switching around never loses it. */
.day-chip.today::after {
  content: ''; position: absolute; margin: 26px 0 0 -4px;
  width: 4px; height: 4px; border-radius: 50%; background: var(--good);
}
.day-chip.today { position: relative; }

/* --- the win moment ---------------------------------------------------- */
.confetti {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;   /* never blocks the modal buttons underneath */
  z-index: 60;            /* falls in front of the result card */
}

.overlay.show .modal { animation: modalIn 340ms cubic-bezier(.2, .9, .3, 1.25) both; }
.overlay.show .bigscore { animation: scorePop 460ms cubic-bezier(.2, .9, .3, 1.4) 120ms both; }

@keyframes modalIn {
  from { opacity: 0; transform: translateY(18px) scale(.92); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes scorePop {
  from { opacity: 0; transform: scale(.5); }
  to   { opacity: 1; transform: scale(1); }
}

/* Respect a reduced-motion preference: keep the result, drop the movement. */
@media (prefers-reduced-motion: reduce) {
  .tiles.won .tile,
  .overlay.show .modal,
  .overlay.show .bigscore { animation: none; }
}

/* --- phones ------------------------------------------------------------
   Claw back horizontal space so the keys themselves can grow: thinner page
   edges, a thinner case, and a hairline gap. Every pixel saved here goes
   straight into key width. */
@media (max-width: 560px) {
  :root {
    --edge: 5px;
    --case: 6px;
    --gap: 1px;
  }

  body { padding-top: 6px; }
  .stage { gap: 14px; }
  .play-area { gap: 8px; }

  /* Sized so a 9-note song still fits on one row at 375px rather than
     spilling a single tile onto a second line. */
  .tile { width: 34px; height: 34px; font-size: 10px; }
  .tiles { gap: 3px; }

  /* Note names sit under the black keys where there is no room on a phone;
     the letter hints are desktop-only anyway. */
  .key .letter { display: none; }
  .key .label { padding-bottom: 6px; }
}

/* Short viewports (landscape phones): the keyboard must not eat the screen,
   so drop the tall-key floor and scale to the height that is actually there. */
@media (max-height: 560px) {
  :root { --white-h: clamp(120px, 34vh, 190px); }
  body { padding-top: 4px; }
  .stage { gap: 10px; }
}
