.speaker-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}
.speaker-card-top {
  display: flex;
  justify-content: space-between;
  gap: 15px;
  padding: 18px;
  color: var(--muted);
}
.speaker-card-top .mono-label {
  font-size: 7px;
}
#speaker-view-label {
  color: var(--accent);
}
.speaker-stage {
  position: relative;
  height: 265px;
  overflow: hidden;
  isolation: isolate;
}
.speaker-grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--line) 1px, transparent 1px),
    linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size: 28px 28px;
  opacity: 0.22;
  mask-image: radial-gradient(ellipse, #000, transparent 70%);
}
.speaker-stack {
  position: absolute;
  inset: 0;
  z-index: 2;
}
.speaker-layer {
  width: 136px;
  height: 136px;
  position: absolute;
  left: calc(50% - 68px);
  top: 64px;
  border-radius: 14px;
  transform: rotateX(48deg) rotateZ(-35deg);
  transition: transform 0.85s cubic-bezier(0.22, 1, 0.36, 1);
}
.circuit-layer {
  background: #211b33;
  border: 2px solid #6c5996;
  box-shadow:
    -5px 8px 0 #111015,
    -6px 9px 0 #514166;
  transform: translateY(14px) rotateX(48deg) rotateZ(-35deg);
}
.circuit-layer::before,
.circuit-layer::after {
  content: "";
  position: absolute;
  inset: 18px;
  border: 1px solid #826aaf;
  border-radius: 5px;
}
.circuit-layer::after {
  inset: 35px;
  border-style: dashed;
}
.circuit-layer > span {
  position: absolute;
  width: 27px;
  height: 27px;
  background: #131217;
  border: 2px solid #a18cc4;
  left: 53px;
  top: 53px;
}
.circuit-layer > i {
  position: absolute;
  inset: 8px;
  border: 3px dotted #a18cc4;
  border-radius: 8px;
}
.driver-layer {
  background: #202026;
  border: 2px solid #6f6a7c;
  box-shadow: -4px 6px 0 #131216;
}
.speaker-cone {
  position: absolute;
  inset: 13px;
  border-radius: 50%;
  background: repeating-radial-gradient(
    circle at center,
    #18171d 0 7px,
    #3b3746 8px 10px,
    #222029 11px 14px
  );
  border: 3px solid #0d0c10;
  box-shadow: 0 0 0 2px #51475e;
  display: grid;
  place-items: center;
}
.speaker-cone > span {
  width: 43px;
  height: 43px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #d1bfff, #7e62b5 65%, #4d3970);
  border: 1px solid #d8c7ff;
  box-shadow: 0 5px 8px #0006;
  transform: scale(calc(0.94 + var(--gain) * 0.12));
}
.grille-layer {
  transform: translateY(-7px) rotateX(48deg) rotateZ(-35deg);
  border: 3px solid #8a819b;
  background:
    radial-gradient(#91849f 1px, transparent 1px) 0 0 / 5px 5px,
    #17151bc9;
  box-shadow: -3px 5px 0 #211d29;
}
.grille-layer::before {
  content: "";
  position: absolute;
  inset: 9px;
  border-radius: 50%;
  border: 1px solid #6a5c7e;
}
.grille-layer > span {
  position: absolute;
  width: 15px;
  height: 5px;
  background: #b8a0ff;
  bottom: 5px;
  left: calc(50% - 7px);
  border-radius: 2px;
}
.is-exploded .circuit-layer {
  transform: translate(4px, 65px) rotateX(48deg) rotateZ(-35deg);
}
.is-exploded .driver-layer {
  transform: translateY(0) rotateX(48deg) rotateZ(-35deg);
}
.is-exploded .grille-layer {
  transform: translate(-4px, -65px) rotateX(48deg) rotateZ(-35deg);
}
.part-label {
  position: absolute;
  color: var(--muted);
  font:
    6px "Space Mono",
    monospace;
  opacity: 0;
  transition: opacity 0.45s ease;
}
.is-exploded .part-label {
  opacity: 1;
}
.grille-label {
  left: 15px;
  top: 46px;
}
.driver-label {
  right: 14px;
  top: 133px;
}
.board-label {
  left: 15px;
  bottom: 30px;
}
.signal-ring {
  z-index: 1;
  position: absolute;
  border: 1px solid var(--accent);
  border-radius: 50%;
  left: calc(50% - 90px);
  top: 76px;
  width: 180px;
  height: 100px;
  opacity: calc(0.05 + var(--gain) * 0.15);
  transform: scale(calc(1 + var(--gain) * 0.5));
}
:root:not(.motion-off) .signal-ring {
  animation: speaker-signal 2.4s ease-out infinite;
}
.signal-two {
  animation-delay: -1.2s !important;
}
@keyframes speaker-signal {
  from {
    transform: scale(0.7);
    opacity: calc(var(--gain) * 0.4);
  }
  to {
    transform: scale(calc(1.3 + var(--gain) * 0.8));
    opacity: 0;
  }
}
:root:not(.motion-off) .speaker-cone > span {
  animation: speaker-bass 0.65s ease-in-out infinite alternate;
}
@keyframes speaker-bass {
  to {
    transform: scale(calc(1 + var(--gain) * 0.2));
  }
}
.speaker-controls {
  border-top: 1px solid var(--line);
  padding: 18px;
}
.speaker-controls button {
  background: var(--raised);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 5px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 10px 13px;
  font-size: 11px;
}
.speaker-controls button:hover {
  border-color: var(--accent);
}
.speaker-controls button > span {
  color: var(--accent);
  font-size: 16px;
}
.gain-label {
  display: flex;
  justify-content: space-between;
  margin-top: 19px;
  font-size: 10px;
  color: var(--body);
}
.gain-label output {
  color: var(--accent);
  font:
    9px "Space Mono",
    monospace;
}
#speaker-gain {
  display: block;
  width: 100%;
  accent-color: var(--accent);
  margin: 12px 0;
  cursor: pointer;
}
.speaker-controls > p {
  text-align: center;
  font-size: 8px;
  color: var(--muted);
  margin-top: 10px;
}
/* The same curve scales every effect; animation timing stays steady while dragging. */
.speaker-card {
  --energy: 0.35;
  --rattle: 1.4px;
  --cone-low: 0.965;
  --cone-high: 1.168;
  --spread: 1.76;
  border-color: color-mix(
    in srgb,
    var(--accent) calc(var(--energy) * 65%),
    var(--line)
  );
  box-shadow: 0 0 calc(var(--energy) * 55px)
    rgba(161, 122, 255, calc(var(--energy) * 0.18));
}
.bass-glow {
  position: absolute;
  z-index: 0;
  inset: 25px;
  border-radius: 50%;
  background: radial-gradient(ellipse, #9e72ff77, transparent 70%);
  opacity: calc(var(--energy) * 0.8);
}
.signal-ring {
  border-width: calc(1px + var(--energy) * 1px);
}
:root:not(.motion-off) .signal-ring {
  animation: continuous-signal 1.8s ease-out infinite;
}
.signal-three {
  animation-delay: -0.6s !important;
}
:root:not(.motion-off) .speaker-stack {
  animation: continuous-rattle 0.22s linear infinite alternate;
}
:root:not(.motion-off) .speaker-cone > span {
  animation: continuous-cone 0.35s ease-in-out infinite alternate;
}
@keyframes continuous-signal {
  from {
    transform: scale(0.7);
    opacity: calc(var(--gain) * 0.6);
  }
  to {
    transform: scale(var(--spread));
    opacity: 0;
  }
}
@keyframes continuous-rattle {
  0% {
    translate: calc(var(--rattle) * -0.5) calc(var(--rattle) * 0.25);
  }
  50% {
    translate: calc(var(--rattle) * 0.5) calc(var(--rattle) * -0.25);
  }
  100% {
    translate: calc(var(--rattle) * -0.25) calc(var(--rattle) * -0.5);
  }
}
@keyframes continuous-cone {
  from {
    transform: scale(var(--cone-low));
    box-shadow: 0 0 calc(var(--energy) * 4px) #b8a0ff33;
  }
  to {
    transform: scale(var(--cone-high));
    box-shadow: 0 0 calc(var(--energy) * 35px)
      rgba(184, 160, 255, calc(var(--energy) * 0.6));
  }
}
.bass-meter {
  display: flex;
  height: 28px;
  align-items: center;
  justify-content: center;
  gap: 3px;
  margin: 13px 0 5px;
}
.bass-meter i {
  display: block;
  width: 4px;
  height: calc(2px + var(--gain) * 8px + var(--bar) * var(--energy) * 4px);
  border-radius: 2px;
  background: var(--accent);
  opacity: calc(0.25 + var(--gain) * 0.7);
}
:root:not(.motion-off) .bass-meter i {
  animation: continuous-meter 0.5s ease-in-out infinite alternate;
  animation-delay: var(--delay);
}
@keyframes continuous-meter {
  to {
    scale: 1 calc(1 - var(--gain) * 0.6);
  }
}
