:root {
  --bg: #241858;
  --bg-deep: #170e3a;
  --surface: #3b2a86;
  --surface-lo: #241a5c;
  --pop: #ffd23f;
  --right: #35d98a;
  --right-lo: #1c9c5e;
  --wrong: #ff5b5b;
  --wrong-lo: #b62f2f;
  --ink: #ffffff;
  --dim: #a99ede;

  color-scheme: dark;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-block-size: 100dvh;
  background: radial-gradient(130% 100% at 50% 0%, var(--bg) 0%, var(--bg-deep) 70%);
  color: var(--ink);
  font-family: ui-rounded, "SF Pro Rounded", system-ui, sans-serif;
  overflow: hidden;
  /* Added to the home screen this runs with no browser chrome, so the page has
     to behave like an app: no rubber-band scroll under the fixed layout, no
     grey flash on every tap, and no text selection from drumming on a pad. */
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* Double-tap-to-zoom costs about 300ms of delay on every press, which a mode
   graded in fractions of a beat cannot afford. */
button { touch-action: manipulation; }

.flash {
  position: fixed;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  opacity: 0;
  background: var(--right);
}

.flash.is-on {
  animation: flash .42s ease-out;
}

.flash.is-bad { background: var(--wrong); }

@keyframes flash {
  0%   { opacity: .55; }
  100% { opacity: 0; }
}

.app {
  max-inline-size: 42rem;
  margin-inline: auto;
  /* Keeps clear of the notch and the home indicator when launched standalone,
     and collapses to nothing in a normal browser tab. */
  padding: calc(clamp(1rem, 4vw, 2rem) + env(safe-area-inset-top))
           calc(clamp(1rem, 4vw, 2rem) + env(safe-area-inset-right))
           calc(clamp(1rem, 4vw, 2rem) + env(safe-area-inset-bottom))
           calc(clamp(1rem, 4vw, 2rem) + env(safe-area-inset-left));
  min-block-size: 100dvh;
  display: grid;
  align-content: center;
}

.app.is-shaking { animation: shake .32s; }

@keyframes shake {
  0%, 100% { translate: 0 0; }
  20% { translate: -9px 0; }
  40% { translate: 8px 0; }
  60% { translate: -5px 0; }
  80% { translate: 3px 0; }
}

.screen[hidden] { display: none; }

.intro { display: grid; justify-items: center; gap: 1.1rem; text-align: center; }

/* Three modes need telling apart before you commit to one, so the menu is a
   card each: what it is called, what you do in it, and a picture of its shape. */
.menu {
  display: grid;
  gap: .7rem;
  inline-size: min(100%, 26rem);
  margin-block-start: .4rem;
}

.card {
  display: grid;
  grid-template-columns: 3.2rem 1fr;
  align-items: center;
  gap: 1.1rem;
  padding: .95rem 1.2rem;
  text-align: start;
}

.card-text { display: grid; gap: .15rem; }
.card-text b { font-size: 1.35rem; font-weight: 800; letter-spacing: -.01em; }
.card-text small { font-size: .8rem; color: var(--dim); font-weight: 600; }

.card-solo { --art: var(--pop); --shadow: #b8890a; background: #4a3596; }
.card-radio { --art: var(--right); --shadow: #1c9c5e; background: #2f3f7e; }

.art {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .18rem;
  inline-size: 3.2rem;
  block-size: 3.2rem;
  border-radius: .8rem;
  background: rgba(0, 0, 0, .22);
  color: var(--art);
}

.art-solo i { font-style: normal; font-size: 1.2rem; translate: 2px 0; }

.art-radio { align-items: flex-end; padding-block-end: .9rem; }

.art-radio i {
  inline-size: .26rem;
  block-size: 1.4rem;
  border-radius: 99px;
  background: currentColor;
  transform-origin: bottom;
  animation: eq 1.05s ease-in-out infinite;
}

.art-radio i:nth-child(2) { animation-delay: .18s; }
.art-radio i:nth-child(3) { animation-delay: .42s; }
.art-radio i:nth-child(4) { animation-delay: .28s; }

@keyframes eq {
  0%, 100% { scale: 1 .35; }
  50% { scale: 1 1; }
}

/* Every mode is reachable from every other one; nothing is a one-way door. */
.home {
  position: fixed;
  inset-block-start: calc(clamp(.6rem, 3vw, 1.1rem) + env(safe-area-inset-top));
  inset-inline-start: calc(clamp(.6rem, 3vw, 1.1rem) + env(safe-area-inset-left));
  z-index: 9;
  inline-size: 2.6rem;
  block-size: 2.6rem;
  display: grid;
  place-items: center;
  padding: 0 .15rem .15rem 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .1);
  color: var(--ink);
  font: inherit;
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: background .15s, scale .15s;
}

.home:hover { background: rgba(255, 255, 255, .22); }
.home:active { scale: .92; }
.home[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .art-radio i { animation: none; scale: 1 .7; }
}

.kicker {
  margin: 0;
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--pop);
}

h1 {
  margin: 0;
  font-size: clamp(3.5rem, 14vw, 6rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.03em;
}

h1 em {
  font-style: normal;
  font-size: .34em;
  font-weight: 700;
  color: var(--dim);
  padding-inline: .5rem;
  vertical-align: .35em;
}

.lede {
  margin: 0 0 .6rem;
  font-size: 1.15rem;
  color: var(--dim);
}

.tip { margin: 0; font-size: .82rem; color: var(--dim); opacity: .75; }

.btn {
  --shadow: var(--surface-lo);
  padding: 0;
  border: 0;
  border-radius: 1.15rem;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 7px 0 var(--shadow);
  transition: translate .07s ease, box-shadow .07s ease, background .12s;
}

.btn:active:not(:disabled) {
  translate: 0 5px;
  box-shadow: 0 2px 0 var(--shadow);
}

.btn:disabled { opacity: .5; cursor: default; }

.btn-face {
  display: grid;
  place-items: center;
  gap: .35rem;
  padding: 1.15rem 1.5rem;
}

.btn-go {
  --shadow: #b8890a;
  background: var(--pop);
  color: #2b1d00;
  padding: 1rem 3rem;
  font-size: 1.25rem;
}

.play {
  display: grid;
  grid-template-rows: auto auto auto auto;
  gap: clamp(1.25rem, 4vw, 2.25rem);
  align-content: center;
  justify-items: stretch;
}

.hud {
  display: flex;
  align-items: center;
  gap: clamp(.75rem, 4vw, 2rem);
}

.combo {
  display: flex;
  gap: 4px;
  margin-inline-end: auto;
}

.seg {
  inline-size: 1.5rem;
  block-size: .55rem;
  border-radius: 99px;
  background: rgba(255, 255, 255, .16);
  transition: background .15s, scale .15s;
}

.seg.is-lit { background: var(--pop); }

.tally { display: grid; justify-items: center; gap: .1rem; }

.tally-num {
  font-size: 1.5rem;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.tally-num.is-pop { animation: pop .3s ease-out; }

@keyframes pop {
  0% { scale: 1; }
  45% { scale: 1.35; color: var(--pop); }
  100% { scale: 1; }
}

.tally-lbl {
  font-size: .64rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--dim);
}

.playwrap {
  justify-self: center;
  display: grid;
  justify-items: center;
  gap: .5rem;
}

.stake {
  font-size: .95rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--pop);
  transition: color .15s;
}

.btn-play {
  justify-self: center;
  inline-size: 7rem;
  block-size: 7rem;
  margin-block: clamp(.5rem, 3vw, 1.5rem);
  border-radius: 50%;
  font-size: 2.1rem;
}

.btn-play .btn-face { padding: 0; translate: 3px 0; }

.btn-play.is-playing { background: #4c37a8; }

.choices {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(.75rem, 3vw, 1.25rem);
}

.btn-choice { --shadow: #241a5c; }

.btn-choice .word {
  font-size: clamp(1.4rem, 5.5vw, 2.15rem);
  font-weight: 800;
  letter-spacing: -.02em;
}

.btn-choice kbd {
  font-family: inherit;
  font-size: .7rem;
  color: currentColor;
  opacity: .45;
}

.choices.is-locked .btn-choice { pointer-events: none; }

.btn-choice.is-sounding {
  outline: 4px solid var(--pop);
  outline-offset: 4px;
  scale: 1.045;
  transition: scale .12s ease;
}

.btn-choice.is-right {
  --shadow: var(--right-lo);
  background: var(--right);
  color: #06301c;
}

.btn-choice.is-wrong {
  --shadow: var(--wrong-lo);
  background: var(--wrong);
  color: #3d0808;
}

/* Fixed rows, not centred content: otherwise the word and hint shuffle every
   time the Next button appears. */
.reveal {
  display: grid;
  grid-template-rows: 2.3rem 1.4rem 1.2rem 3.4rem;
  align-items: center;
  justify-items: center;
  text-align: center;
}

.reveal-word {
  margin: 0;
  font-size: 1.6rem;
  font-weight: 800;
  opacity: 0;
  transition: opacity .15s;
}

.reveal-word.is-on { opacity: 1; }

.reveal-word b { color: var(--pop); font-weight: 800; }

.reveal-gloss {
  margin: 0;
  font-size: .92rem;
  color: var(--ink);
  opacity: 0;
  transition: opacity .15s;
  max-inline-size: 34rem;
}

.reveal-gloss.is-on { opacity: .82; }

.reveal-hint {
  margin: 0;
  font-size: .78rem;
  color: var(--dim);
  min-block-size: 1rem;
}

/* Arrow keys and space are gameplay controls here, so a focus ring on every
   press reads as an error. Rings return the moment someone actually tabs. */
:focus, :focus-visible { outline: none; }

body.is-tabbing :focus-visible {
  outline: 3px solid var(--pop);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .app.is-shaking { animation: none; }
  .flash.is-on { animation-duration: .18s; }
  .tally-num.is-pop { animation: none; }
}

@media (max-width: 26rem) {
  .seg { inline-size: 1rem; }
}

.fx {
  position: fixed;
  inset: 0;
  z-index: 6;
  pointer-events: none;
}

.poplayer {
  position: fixed;
  inset: 0;
  z-index: 7;
  pointer-events: none;
}

.pop {
  position: absolute;
  translate: -50% -50%;
  font-size: 2.4rem;
  font-weight: 800;
  color: var(--pop);
  text-shadow: 0 3px 0 rgba(0, 0, 0, .35);
  animation: rise 1s cubic-bezier(.2, .9, .3, 1) forwards;
  white-space: nowrap;
}

.pop.is-big { font-size: 3.4rem; color: var(--right); }
.pop.is-bad { color: var(--wrong); font-size: 1.9rem; }

.pop.is-layer {
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--dim);
  text-shadow: none;
}

.pop.is-layer.is-bad { color: var(--wrong); font-size: 1.1rem; }

@keyframes rise {
  0%   { opacity: 0; scale: .5; }
  25%  { opacity: 1; scale: 1.18; }
  100% { opacity: 0; scale: 1; translate: -50% -180%; }
}

.banner {
  position: fixed;
  inset-block-start: 26%;
  inset-inline: 0;
  z-index: 8;
  margin: 0;
  text-align: center;
  font-size: clamp(2.2rem, 9vw, 4.5rem);
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--pop);
  text-shadow: 0 4px 0 rgba(0, 0, 0, .4);
  pointer-events: none;
  opacity: 0;
}

.banner.is-on { animation: slam .95s cubic-bezier(.2, .9, .3, 1); }

@keyframes slam {
  0%   { opacity: 0; scale: 2.6; rotate: -8deg; }
  22%  { opacity: 1; scale: 1; rotate: -3deg; }
  70%  { opacity: 1; scale: 1.03; }
  100% { opacity: 0; scale: 1.12; }
}

.tally-score .tally-num { font-size: 2rem; color: var(--pop); }

.streak-1 .tally-num#streak { color: var(--pop); }
.streak-2 .tally-num#streak { color: #ff9b3f; }
.streak-3 .tally-num#streak { color: var(--wrong); }

.btn-choice.is-hit { animation: squash .3s ease-out; }

@keyframes squash {
  0%   { scale: 1 1; }
  35%  { scale: 1.07 .93; }
  70%  { scale: .98 1.02; }
  100% { scale: 1 1; }
}

.btn-next {
  --shadow: #b8890a;
  justify-self: center;
  background: var(--pop);
  color: #2b1d00;
  font-size: 1rem;
}

.btn-next {
  visibility: hidden;
  align-self: center;
}

.btn-next.is-on {
  visibility: visible;
  animation: nextIn .28s cubic-bezier(.2, 1.4, .4, 1);
}

@keyframes nextIn {
  from { opacity: 0; scale: .7; }
  to   { opacity: 1; scale: 1; }
}

.btn-next .btn-face { padding: .7rem 1.6rem; grid-auto-flow: column; gap: .5rem; }

.btn-next kbd {
  font-family: inherit;
  font-size: .68rem;
  opacity: .5;
}

@media (prefers-reduced-motion: reduce) {
  .pop, .banner.is-on, .btn-choice.is-hit { animation-duration: .2s; }
}

.shock {
  position: fixed;
  z-index: 6;
  inline-size: 12px;
  block-size: 12px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  border: 5px solid var(--right);
  pointer-events: none;
  animation: shock .6s cubic-bezier(.1, .8, .3, 1) forwards;
}

.shock.is-bad { border-color: var(--wrong); }

@keyframes shock {
  0%   { opacity: .9; scale: 1; }
  100% { opacity: 0; scale: 34; border-width: 1px; }
}

.app.is-punch { animation: punch .26s cubic-bezier(.2, 1.5, .4, 1); }

@keyframes punch {
  0%   { scale: 1; }
  40%  { scale: 1.025; }
  100% { scale: 1; }
}

body.is-hot { animation: hotpulse .5s ease-out; }

@keyframes hotpulse {
  0%   { background-color: #2f1d70; }
  100% { background-color: transparent; }
}

.multi {
  position: fixed;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  z-index: 8;
  translate: -50% -50%;
  font-size: clamp(4rem, 18vw, 9rem);
  font-weight: 800;
  color: var(--pop);
  text-shadow: 0 6px 0 rgba(0, 0, 0, .35);
  pointer-events: none;
  opacity: 0;
}

.multi.is-on { animation: multiIn .7s cubic-bezier(.2, 1.3, .3, 1); }

@keyframes multiIn {
  0%   { opacity: 0; scale: .2; rotate: -14deg; }
  30%  { opacity: .95; scale: 1.1; rotate: 4deg; }
  100% { opacity: 0; scale: 1.5; rotate: 0deg; }
}

.streak-0 .seg.is-lit { background: var(--pop); }
.streak-1 .seg.is-lit { background: #ff9b3f; }
.streak-2 .seg.is-lit { background: var(--wrong); }
.streak-3 .seg.is-lit { background: #ff5bd0; box-shadow: 0 0 10px #ff5bd0; }

.streak-2 .tally-num#streak,
.streak-3 .tally-num#streak { animation: throb .7s ease-in-out infinite; }

@keyframes throb {
  0%, 100% { scale: 1; }
  50% { scale: 1.12; }
}

@media (prefers-reduced-motion: reduce) {
  .shock, .app.is-punch, .multi.is-on, body.is-hot,
  .streak-2 .tally-num#streak, .streak-3 .tally-num#streak { animation: none; }
}

.modes {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  justify-content: center;
}

.btn-alt {
  --shadow: #1c9c5e;
  background: var(--right);
  color: #06301c;
}

.modehint {
  margin: .2rem 0 0;
  font-size: .78rem;
  color: var(--dim);
  opacity: .8;
}

/* One-character answers need far more presence than a whole word does. */
.play.is-drill .btn-choice .word {
  font-size: clamp(2.6rem, 11vw, 4.2rem);
  line-height: 1;
}

.creditlink {
  margin-block-start: .4rem;
  border: 0;
  background: none;
  color: var(--dim);
  font: inherit;
  font-size: .78rem;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.creditlink:hover { color: var(--ink); }

.listen {
  display: grid;
  justify-items: center;
  gap: 1.4rem;
  text-align: center;
}

.track {
  margin: 0;
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--pop);
}

.pair {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  justify-content: center;
  gap: .3rem;
  margin: 0;
  font-size: clamp(1.8rem, 8vw, 3.2rem);
  font-weight: 800;
  letter-spacing: -.02em;
}

.lw-vs {
  font-size: .34em;
  font-weight: 700;
  color: var(--dim);
  padding-inline: .5rem;
}

.lw {
  color: var(--dim);
  padding-inline: .35rem;
  border-radius: .5rem;
  transition: color .28s ease, background .28s ease, scale .28s ease;
}

.lw b { color: var(--ink); font-weight: 800; }
.lw.is-said b { color: inherit; }

/* Snaps on when the word is said, then eases back out, so the beat reads. */
.lw.is-said {
  color: #2b1d00;
  background: var(--pop);
  scale: 1.06;
  transition: none;
}

.note {
  margin: 0;
  font-size: .82rem;
  color: var(--dim);
  opacity: .8;
}

@media (prefers-reduced-motion: reduce) {
  .lw, .lw.is-said { transition: none; scale: 1; }
}

.kitwords {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .35rem .5rem;
  margin: 0;
  max-inline-size: 26rem;
}

.kw {
  font-size: .82rem;
  font-weight: 700;
  color: var(--dim);
  opacity: .55;
  padding: .1rem .45rem;
  border-radius: .4rem;
  transition: color .3s ease, opacity .3s ease, translate .3s ease, scale .3s ease;
}

/* Lifts and brightens on the hit, then falls back, so the pattern is readable
   as movement rather than a row of flickering labels. */
.kw.is-hit {
  color: var(--pop);
  opacity: 1;
  translate: 0 -7px;
  scale: 1.22;
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  .kw, .kw.is-hit { translate: none; scale: 1; transition: opacity .2s; }
}

.introlinks {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.4rem;
  margin: 0;
}


.sfx[aria-pressed="true"] {
  color: var(--pop);
  text-decoration: none;
}

.sfx[aria-pressed="true"]::before {
  content: "";
  display: inline-block;
  inline-size: .45rem;
  block-size: .45rem;
  margin-inline-end: .4rem;
  border-radius: 99px;
  background: currentColor;
  animation: pulse 1.15s steps(2, jump-none) infinite;
}

@keyframes pulse {
  0%   { opacity: 1; }
  100% { opacity: .25; }
}

.credits {
  max-inline-size: 34rem;
  inline-size: calc(100vw - 2rem);
  max-block-size: 80dvh;
  border: 0;
  border-radius: 1.15rem;
  padding: 1.75rem;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
}

.credits::backdrop { background: rgba(10, 6, 30, .72); }

.credits h2 { margin: 0 0 .6rem; font-size: 1.3rem; }

.credits p {
  margin: 0 0 1rem;
  font-size: .88rem;
  line-height: 1.55;
  color: var(--dim);
}

.credits ul {
  margin: 0 0 1.25rem;
  padding: 0;
  list-style: none;
  display: grid;
  gap: .3rem;
  font-size: .82rem;
  max-block-size: 40dvh;
  overflow-y: auto;
}

.credits li { display: flex; justify-content: space-between; gap: 1rem; }
.credits li span:last-child { color: var(--dim); white-space: nowrap; }

.play.is-review .btn-play {
  --shadow: #b8890a;
  background: var(--pop);
  color: #2b1d00;
  animation: nextPulse .4s cubic-bezier(.2, 1.4, .4, 1);
}

@keyframes nextPulse {
  0%   { scale: .82; }
  60%  { scale: 1.06; }
  100% { scale: 1; }
}

.play.is-review .btn-choice { cursor: pointer; }

/* Only one of the two was ever recorded, so the other must not look playable. */
.play.is-review .choices.is-solo .btn-choice:not(.is-right) {
  pointer-events: none;
  opacity: .45;
}

/* The separate Next button is redundant once the play button becomes Next. */
.play.is-review .btn-next { visibility: hidden; }

/* Karaoke ---------------------------------------------------------------- */

/* Where you are in the run. Filling these is the progression, so they sit right
   under the track name where the eye already is. */
.setlist { display: flex; gap: .32rem; margin: 0; }
.setlist[hidden] { display: none; }

.setlist i {
  inline-size: .5rem;
  block-size: .5rem;
  border-radius: 99px;
  background: rgba(255, 255, 255, .16);
  transition: background .35s ease, scale .35s ease;
}

.setlist i.is-done { background: var(--right); }
.setlist i.is-now { background: var(--pop); scale: 1.45; }

@media (prefers-reduced-motion: reduce) {
  .setlist i, .setlist i.is-now { scale: 1; }
}


/* Which word it is has to stay a secret, but when it lands cannot be one, or
   there is nothing to play along to. So the notes carry no identity at all:
   they only say a word is coming and exactly when it arrives. */
.lane {
  position: relative;
  inline-size: min(100%, 30rem);
  block-size: 3.2rem;
  border-radius: .9rem;
  background: rgba(0, 0, 0, .26);
  overflow: hidden;
}

.lane[hidden] { display: none; }

.hitline {
  position: absolute;
  inset-block: .45rem;
  inset-inline-start: 2.4rem;
  inline-size: 4px;
  margin-inline-start: -2px;
  border-radius: 99px;
  background: rgba(255, 255, 255, .3);
  transition: background .25s ease, box-shadow .25s ease;
}

.lane.is-ring .hitline {
  background: var(--pop);
  box-shadow: 0 0 14px rgba(255, 210, 63, .7);
  transition: none;
}

.blip {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 0;
  inline-size: 1.4rem;
  block-size: 1.4rem;
  margin: -.7rem 0 0 -.7rem;
  border-radius: 50%;
  background: var(--dim);
  will-change: translate;
  transition: background .18s ease, scale .18s ease;
}

.blip.is-good { background: var(--right); scale: 1.45; }
.blip.is-wrong { background: var(--wrong); scale: 1.2; }

@media (prefers-reduced-motion: reduce) {
  .blip.is-good, .blip.is-wrong { scale: 1; }
}

.pads {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(.75rem, 3vw, 1.25rem);
  inline-size: min(100%, 24rem);
}

.pads[hidden] { display: none; }

.pad { --shadow: #241a5c; }
.pad .btn-face { padding: .9rem .75rem .7rem; gap: .4rem; }

/* A ü is a u wearing two dots, so the pads show the mark rather than name it.
   Drawn rather than typed, because the glyph bakes the dots into the letter. */
.pad-tile {
  position: relative;
  display: grid;
  align-content: end;
  justify-items: center;
  inline-size: 3rem;
  block-size: 3rem;
}

.pad-tile b { font-size: 2.4rem; font-weight: 800; line-height: .95; }

.pad-tile .dot {
  position: absolute;
  inset-block-start: .1rem;
  inline-size: .5rem;
  block-size: .5rem;
  border-radius: 50%;
  background: currentColor;
}

.pad-tile .dot:nth-of-type(1) { inset-inline-start: .62rem; }
.pad-tile .dot:nth-of-type(2) { inset-inline-start: 1.6rem; }

.pad kbd { font-family: inherit; font-size: .7rem; color: currentColor; opacity: .45; }

.pad.is-hit { animation: squash .26s ease-out; }

.pad.is-good { --shadow: var(--right-lo); background: var(--right); color: #06301c; }
.pad.is-wrong { --shadow: var(--wrong-lo); background: var(--wrong); color: #3d0808; }

.kscore {
  margin: 0;
  font-size: .82rem;
  font-weight: 700;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}

.kscore[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .pad.is-hit { animation: none; }
}
