/* ============================================================
   The stairs (shared/stairs.js; SPEC «The stairs component», board ZStairs)
   ------------------------------------------------------------
   States are classes. On a step: on (the piano plays it), played, and the
   marks exact / close / off / missed. On a key: lit (listen), live (sing).
   On the svg: singing, traced (the line has a point), done, dim. Colours are
   tokens from style.css; motion is transform and opacity only.
   ============================================================ */
.stairs { display: block; width: 100%; height: 100%; }
.stairs-roll { transition: opacity 0.3s ease; }
.stairs.dim .stairs-roll { opacity: 0.5; }

/* the keys: a name on each white key, lit while the piano plays it, live
   while it is sung */
.stairs-name { fill: var(--paper-ink-3); }
.stairs-key-lit, .stairs-key-live { opacity: 0; }
.stairs-key.lit .stairs-key-lit { opacity: 1; }
.stairs-key.lit .stairs-name { fill: var(--stairs-key-lit-ink); font-weight: 800; }
.stairs-key.live .stairs-key-live { opacity: 1; }
.stairs-key.live .stairs-name { fill: var(--lilac-1); font-weight: 800; }

/* the steps: soft until played, always outlined (they are the path the
   singer follows); the lit one warm with a glow and a pop */
.stairs-pill { fill: var(--stairs-step); stroke: var(--stairs-mark); stroke-width: 1.6; }
.stairs-step.played .stairs-pill { fill: var(--stairs-step-played); }
.stairs.singing .stairs-step.played .stairs-pill { fill: var(--stairs-step-passed); }
.stairs-lit { opacity: 0; transform-box: fill-box; transform-origin: center; }
.stairs-step.on .stairs-lit { opacity: 1; animation: stairs-pop 0.45s ease-out; }
.stairs-exact, .stairs-check { opacity: 0; }

/* done: filled with a check (exact), outlined (close), dashed (off, missed) */
.stairs-step.exact .stairs-exact,
.stairs-step.exact .stairs-check { opacity: 1; }
.stairs-step.exact .stairs-pill { stroke: none; }
.stairs-step.close .stairs-pill,
.stairs-step.off .stairs-pill,
.stairs-step.missed .stairs-pill { fill: var(--art-white); stroke: var(--stairs-mark); stroke-width: 1.6; }
.stairs-step.off .stairs-pill,
.stairs-step.missed .stairs-pill { stroke-dasharray: 3 3; }

/* the sung line, the bead at its end, the playhead */
.stairs-trace { stroke: var(--lilac-1); stroke-width: 3.5; }
.stairs.done .stairs-trace { stroke: var(--stairs-trace-done); stroke-width: 2.2; }
.stairs-bead, .stairs-head { opacity: 0; }
.stairs.singing.traced:not(.done) .stairs-bead { opacity: 1; }
.stairs.singing:not(.done) .stairs-head { opacity: 1; }

@keyframes stairs-pop {
  0% { transform: scale(0.7); opacity: 0; }
  40% { transform: scale(1.14); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .stairs-step.on .stairs-lit { animation: none; }
}

/* the stairs, round 2 (shared/stairs2.js; ZStairs2): nine pill steps, a
   vertical piano of five white keys level with them, and the ball hopping a
   step a beat. Exact is a check on the violet gradient, close an outline,
   a miss a pale pill: the check and the outline carry the meaning, not the
   fill. Transform and opacity only; nothing moves under reduced motion. */
.stairs2 { display: block; width: 100%; height: 100%; transition: opacity 0.3s ease; }
.stairs2.dim { opacity: 0.5; }
.s2-pill { fill: var(--zr-intro-step); stroke: none; }
.s2-step.played .s2-pill { fill: var(--stairs-step-played); }
.s2-label { fill: var(--paper-ink-2); }
.s2-lit, .s2-exact, .s2-check { opacity: 0; }
.s2-lit { transform-box: fill-box; transform-origin: center; }
.s2-check { stroke: var(--art-white); }
.s2-step.on .s2-lit { opacity: 1; animation: s2-pop 0.45s ease-out; }
.s2-step.exact .s2-exact, .s2-step.exact .s2-check { opacity: 1; }
.s2-step.close .s2-pill { fill: var(--art-white); stroke: var(--stairs-mark); stroke-width: 2; }
.s2-step.off .s2-pill, .s2-step.missed .s2-pill { fill: var(--zr-seg-next); stroke: none; }
.s2-key-warm, .s2-key-voice { opacity: 0; }
.s2-key-name { fill: var(--paper-ink-3); }
.s2-key.lit .s2-key-warm { opacity: 1; }
.s2-key.live .s2-key-voice { opacity: 1; }
.s2-key.lit .s2-key-name, .s2-key.live .s2-key-name { fill: var(--art-white); font-weight: 800; }
/* the hop: the travel and the rise take the same 0.24 s from the beat, and the
   ball lands on the middle of its step */
.s2-ball { transition: transform 0.24s linear; }
.stairs2:not(.singing):not(.done) .s2-ball { opacity: 0; }
.s2-hop, .s2-land { transform-box: fill-box; transform-origin: center bottom; }
.s2-hop.go { animation: s2-hop 0.24s linear; }
.s2-land.go { animation: s2-land 0.14s ease-out 0.22s; }
@keyframes s2-pop {
  0% { transform: scale(0.7); opacity: 0; }
  40% { transform: scale(1.14); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes s2-hop {
  0% { transform: translateY(0); animation-timing-function: cubic-bezier(0.2, 0.7, 0.5, 1); }
  48% { transform: translateY(-24px); animation-timing-function: cubic-bezier(0.5, 0, 0.8, 0.3); }
  100% { transform: translateY(0); }
}
@keyframes s2-land {
  0% { transform: scaleY(1); }
  40% { transform: scaleY(0.94); }
  100% { transform: scaleY(1); }
}
@media (prefers-reduced-motion: reduce) {
  .s2-step.on .s2-lit, .s2-hop.go, .s2-land.go { animation: none; }
  .s2-ball, .stairs2 { transition: none; }
}
/* end of the stairs, round 2 */
