@import url('https://fonts.googleapis.com/css2?family=Fredoka+One&family=Nunito:wght@400;700&display=swap');

:root {
  --bg: #0d0d1a;
  --grid-gap: 10px;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  min-height: 100dvh;
  background: var(--bg);
  font-family: 'Nunito', sans-serif;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 16px 8px;
  overflow-x: hidden;
  position: relative;
}

/* ── Stars background ── */
.stars {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}
.star {
  position: absolute;
  border-radius: 50%;
  background: #fff;
  opacity: 0;
  animation: twinkle var(--d) ease-in-out infinite var(--delay);
}
@keyframes twinkle {
  0%, 100% { opacity: 0; transform: scale(1); }
  50%       { opacity: var(--op); transform: scale(1.4); }
}


/* ── Grid ── */
.grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--grid-gap);
  width: 100%;
  max-width: 480px;
}

/* ── Buttons ── */
.sound-btn {
  aspect-ratio: 1 / 1;
  border: none;
  border-radius: 18px;
  cursor: pointer;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  transition: transform 0.08s ease, box-shadow 0.15s ease, filter 0.15s ease;
  box-shadow: 0 4px 16px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.2);
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.sound-btn svg {
  width: 36%;
  height: 36%;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.4));
  pointer-events: none;
  flex-shrink: 0;
}

/* Each button gets a unique hue via JS --hue custom property */
.sound-btn {
  background: linear-gradient(145deg,
    hsl(var(--hue), 90%, 55%),
    hsl(calc(var(--hue) + 40), 85%, 42%)
  );
}

.sound-btn::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, rgba(255,255,255,0.25) 0%, transparent 60%);
  border-radius: inherit;
  pointer-events: none;
}

.sound-btn:active,
.sound-btn.pressing {
  transform: scale(0.92);
  box-shadow: 0 2px 8px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.1);
}

/* Playing state */
.sound-btn.playing {
  animation: pulse-glow 0.45s ease-in-out infinite alternate;
  filter: brightness(1.3) saturate(1.4);
  z-index: 2;
}
@keyframes pulse-glow {
  from { box-shadow: 0 0 10px 2px hsl(var(--hue), 90%, 60%), 0 4px 16px rgba(0,0,0,0.4); }
  to   { box-shadow: 0 0 26px 8px hsl(var(--hue), 90%, 70%), 0 4px 16px rgba(0,0,0,0.4); }
}

/* Ripple */
.ripple {
  position: absolute;
  border-radius: 50%;
  background: rgba(255,255,255,0.45);
  transform: scale(0);
  animation: ripple-anim 0.55s linear forwards;
  pointer-events: none;
}
@keyframes ripple-anim {
  to { transform: scale(4); opacity: 0; }
}


/* ── Confetti pieces ── */
.confetti {
  position: fixed;
  top: -20px;
  width: 10px;
  height: 14px;
  border-radius: 2px;
  opacity: 1;
  z-index: 200;
  pointer-events: none;
  animation: confetti-fall var(--fall-d) ease-in var(--fall-delay) forwards;
}
@keyframes confetti-fall {
  0%   { transform: translateY(0) rotate(0deg)  translateX(0); opacity: 1; }
  100% { transform: translateY(110vh) rotate(720deg) translateX(var(--drift)); opacity: 0; }
}

/* ── Morse reveal glow on winning button ── */
.sound-btn.morse-found {
  animation: morse-victory 0.6s ease-in-out infinite alternate !important;
  filter: brightness(1.6) saturate(2) !important;
}
@keyframes morse-victory {
  from { box-shadow: 0 0 20px 6px #fff, 0 0 40px 12px #ffb347; transform: scale(1.05); }
  to   { box-shadow: 0 0 40px 16px #fff, 0 0 80px 30px #ff6fd8; transform: scale(1.1) rotate(2deg); }
}
