/* A strike used to draw a bar of light lying ON the strike line: a 13px rounded pill, one key
   wide, in the hand's colour, standing for as long as the key was held. It is gone. Read the
   strike area top to bottom and it had become four statements of the same fact stacked in about
   20px — the tile landing, the pink gradient rule, the white dome over the key, and this pill —
   and a pill with a hard rounded edge sitting above the key reads as a coloured square laid on
   the keyboard, not as light. The key going down in the hand's colour says it once.
   What survives is the part that was never redundant: the paws. They are the only thing in the
   strike that is not also said by the tile or the key, and they are the brand.
   Deleted with the pill: plume-rise, plume-fade, the --lit custom property that timed the
   fade, and the plus-lighter blend (there is nothing left to sum). .plume is now only a
   positioning box - the key's column, 13px of height for the paws to break out of.
   check.py fails if a .plume::before rule comes back. */
.plume {
  position: absolute; bottom: 0; z-index: 4;   /* over the falling bars, under the top fade */
  height: 13px;
  transform: translateX(-50%);
  pointer-events: none;
}

/* The signature: three prints breaking out of the strike point as the note dies, cream but
   glowing in the hand's colour, each with its own drift, spin and delay so a chord does not
   stamp the same three paws three times. 22px, not 15: at 15 the toe pads were sub-pixel and
   the mark read as a spark rather than as a paw. */
.plume i {
  position: absolute; top: 0; left: 50%; width: 22px; aspect-ratio: 40 / 38;
  opacity: 0; animation: plume-paw 760ms ease-out forwards;
}
.plume i img { width: 100%; height: 100%;
  filter: drop-shadow(0 0 7px color-mix(in srgb, var(--hand) 80%, transparent)); }
@keyframes plume-paw {
  0%   { opacity: 0; transform: translate(-50%, 12px) rotate(0) scale(.45); }
  28%  { opacity: .9; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), var(--dy)) rotate(var(--spin)) scale(1); }
}

/* Streak: only climbs while someone is actually playing along, so it reads 0 for a passive
   listen. Warms the key halo rather than the paw, to leave the left-blue / right-green hand
   cue intact. */
.streak {
  /* Clear of the floating header, which shares this corner with the transport. */
  position: absolute; top: calc(var(--header-h) + 10px); right: 14px; z-index: 10; pointer-events: none;
  padding: 5px 12px; border-radius: 999px;
  font-size: var(--text-md); font-weight: 850; letter-spacing: .02em;
  color: #2a1723; background: linear-gradient(145deg, #ffe08a, #ffb02e);
  box-shadow: 0 6px 18px rgba(255,176,46,.35);
}
.streak.bump { animation: streak-bump .32s cubic-bezier(.3,1.5,.5,1); }
@keyframes streak-bump { 0%,100% { transform: scale(1); } 42% { transform: scale(1.22); } }

/* Finale: the score runs out and rains paw prints instead of just stopping dead. */
.confetti-paw {
  position: absolute; top: -46px; width: 30px; aspect-ratio: 40 / 38;
  pointer-events: none; opacity: 0;
  animation: confetti-fall 2.1s cubic-bezier(.35,.15,.6,1) forwards;
}
.confetti-paw img { width: 100%; height: 100%;
  filter: drop-shadow(0 0 6px rgba(255,145,191,.6)); }
@keyframes confetti-fall {
  0%   { opacity: 0; transform: translate(0,0) rotate(0) scale(.7); }
  12%  { opacity: .95; }
  100% { opacity: 0; transform: translate(var(--drift), calc(var(--fall, 400px) + 70px)) rotate(var(--spin)) scale(1); }
}
