.confetti-piece {
  position: absolute;
  z-index: 2;
  width: 7px;
  height: 12px;
  border-radius: 3px;
  background: var(--confetti-color);
  pointer-events: none;
  transform: translate(-50%, -50%);
  animation: confetti-drop var(--confetti-duration, 5600ms) linear forwards;
}

.disco-party {
  --disco-drop-duration: 460ms;
  position: fixed;
  inset: 0;
  z-index: 101;
  overflow: hidden;
  contain: strict;
  pointer-events: none;
}

.party-dance-floor {
  --party-floor-left: 0px;
  --party-floor-width: 100vw;
  --party-floor-height: 78px;
  position: fixed;
  left: var(--party-floor-left);
  bottom: 0;
  z-index: 9;
  width: var(--party-floor-width);
  height: var(--party-floor-height);
  overflow: hidden;
  border-top: 2px solid color-mix(in srgb, var(--accent) 74%, #ff55d9 26%);
  background: linear-gradient(to bottom, #090516, #03040a 78%);
  box-shadow:
    0 -2px 0 rgba(255, 255, 255, 0.16),
    0 -10px 30px color-mix(in srgb, var(--accent) 22%, transparent);
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px);
  transform-origin: 50% 100%;
  transition: opacity 180ms ease, transform 260ms var(--ios-spring);
  will-change: opacity, transform;
}

body.bottom-nav-collapsed .party-dance-floor {
  opacity: 1;
  transform: translateY(0);
}

.party-dance-floor-grid {
  position: absolute;
  inset: -7px -5% -17px;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: repeat(4, minmax(0, 1fr));
  gap: 3px;
  padding: 3px;
  background: #03040a;
  image-rendering: pixelated;
  transform: perspective(190px) rotateX(18deg) scale(1.04, 1.18);
  transform-origin: 50% 0;
}

.party-dance-floor-tile {
  min-width: 0;
  min-height: 0;
  background: var(--party-tile-color-1);
  box-shadow:
    inset 1px 1px rgba(255, 255, 255, 0.16),
    inset -1px -1px rgba(0, 0, 0, 0.28);
  animation: party-floor-tile-color var(--party-tile-duration, 3200ms) steps(1, end) infinite;
  animation-delay: var(--party-tile-delay, 0ms);
}

.party-dance-floor-message {
  position: absolute;
  top: 49%;
  left: 50%;
  z-index: 2;
  width: min(82%, 324px);
  height: auto;
  overflow: visible;
  filter:
    drop-shadow(2px 3px 0 rgba(1, 2, 7, 0.96))
    drop-shadow(0 0 7px rgba(1, 2, 7, 0.82));
  image-rendering: pixelated;
  shape-rendering: crispEdges;
  transform: translate(-50%, -50%);
}

.party-dance-floor-message-panel {
  fill: rgba(4, 3, 13, 0.9);
  stroke: color-mix(in srgb, var(--accent) 68%, #ff4acb 32%);
  stroke-linejoin: miter;
  stroke-width: 0.35px;
}

.party-dance-floor-message-text {
  fill: #fff;
  stroke: #04030b;
  stroke-linejoin: miter;
  stroke-width: 0.72px;
  paint-order: stroke fill;
}

.party-dance-floor::after {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, 0.16), transparent 14%, rgba(0, 0, 0, 0.32)),
    repeating-linear-gradient(115deg, transparent 0 38px, rgba(255, 255, 255, 0.06) 39px 40px, transparent 41px 76px);
  content: "";
}

body.bottom-nav-collapsed .party-dance-floor.party-dance-floor-ending {
  opacity: 0;
  transform: translateY(8px);
  transition-delay: 820ms;
  transition-duration: 520ms;
}

body.monochrome-mode .party-dance-floor {
  filter: saturate(0);
}

.disco-ball {
  position: absolute;
  left: var(--ball-left);
  top: var(--ball-top);
  width: 26px;
  height: 26px;
  border: 1px solid rgba(255, 255, 255, 0.86);
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 26%, rgba(255, 255, 255, 0.96), transparent 18%),
    linear-gradient(135deg, rgba(255, 255, 255, 0.9), rgba(173, 190, 214, 0.72) 42%, rgba(66, 80, 104, 0.9));
  box-shadow:
    0 0 15px rgba(255, 255, 255, 0.44),
    0 9px 20px rgba(0, 0, 0, 0.28);
  transform: translate(-50%, -36px);
  will-change: transform, opacity;
  animation:
    disco-ball-drop var(--disco-drop-duration) ease-in forwards,
    disco-ball-glint 940ms ease-in-out infinite;
}

.disco-party-ending .disco-ball {
  animation: disco-ball-retract 620ms ease-in forwards;
}

.disco-ball::before {
  position: absolute;
  left: 50%;
  bottom: 100%;
  width: 1px;
  height: 17px;
  background: rgba(255, 255, 255, 0.42);
  content: "";
}

.disco-ball-grid {
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background:
    linear-gradient(90deg, transparent 31%, rgba(255, 255, 255, 0.45) 32% 35%, transparent 36% 63%, rgba(255, 255, 255, 0.32) 64% 67%, transparent 68%),
    linear-gradient(0deg, transparent 30%, rgba(255, 255, 255, 0.36) 31% 34%, transparent 35% 62%, rgba(255, 255, 255, 0.28) 63% 66%, transparent 67%);
  opacity: 0.86;
}

.disco-ray {
  position: absolute;
  left: var(--ball-left);
  top: calc(var(--ball-top) + 13px);
  width: var(--ray-length);
  height: 3px;
  border-radius: 999px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.86), rgba(255, 255, 255, 0.34) 44%, transparent);
  filter: blur(0.4px);
  opacity: 0;
  transform: rotate(var(--ray-angle)) scaleX(0.08);
  transform-origin: 0 50%;
  animation: disco-ray-sweep 1800ms ease-in-out infinite;
  animation-delay: calc(var(--disco-drop-duration) + var(--ray-delay, 0ms));
}

.disco-party-ending .disco-ray {
  opacity: 0;
  animation: none;
}

.party-companion {
  --party-x: -100px;
  --party-y: 0px;
  --party-tilt: 0deg;
  position: fixed;
  inset: 0 auto auto 0;
  z-index: 3;
  width: 70px;
  height: 84px;
  opacity: 0;
  pointer-events: none;
  transform: translate3d(var(--party-x), var(--party-y), 0);
  transition: opacity 90ms linear;
  will-change: transform;
}

.party-companion.is-ready {
  opacity: 1;
}

.party-companion-sprite {
  position: absolute;
  inset: 0;
  background-image: url("../assets/party-skeleton-atlas.png?v=5");
  background-position: var(--party-frame-x, 0%) var(--party-frame-y, 0%);
  background-repeat: no-repeat;
  background-size: 1700% 800%;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.72));
  image-rendering: pixelated;
  transform: rotate(var(--party-tilt));
  transform-origin: 50% 94%;
}

.party-companion[data-party-companion-direction="left"] .party-companion-sprite {
  transform: scaleX(-1) rotate(var(--party-tilt));
}

.party-floor-probe {
  position: fixed;
  left: 0;
  bottom: env(safe-area-inset-bottom, 0px);
  width: 1px;
  height: 1px;
  pointer-events: none;
  visibility: hidden;
}

@media (min-width: 601px) {
  .party-companion {
    width: 78px;
    height: 94px;
  }
}

@keyframes disco-ball-drop {
  0% {
    opacity: 0;
    transform: translate(-50%, -36px);
  }

  100% {
    opacity: 1;
    transform: translate(-50%, 0);
  }
}

@keyframes disco-ball-glint {
  0%,
  100% {
    filter: brightness(1) saturate(120%);
  }

  50% {
    filter: brightness(1.38) saturate(165%);
  }
}

@keyframes disco-ball-retract {
  0% {
    opacity: 1;
    transform: translate(-50%, 0);
  }

  35% {
    opacity: 1;
    transform: translate(-50%, 5px);
  }

  100% {
    opacity: 0;
    transform: translate(-50%, -36px);
  }
}

@keyframes disco-ray-sweep {
  0% {
    opacity: 0;
    transform: rotate(var(--ray-angle)) scaleX(0.08);
  }

  12% {
    opacity: var(--ray-opacity);
    transform: rotate(calc(var(--ray-angle) - 9deg)) scaleX(1);
  }

  52% {
    opacity: calc(var(--ray-opacity) * 0.78);
    transform: rotate(calc(var(--ray-angle) + 13deg)) scaleX(0.86);
  }

  82% {
    opacity: calc(var(--ray-opacity) * 0.6);
    transform: rotate(calc(var(--ray-angle) - 5deg)) scaleX(1.06);
  }

  100% {
    opacity: 0;
    transform: rotate(calc(var(--ray-angle) + 18deg)) scaleX(0.16);
  }
}

@keyframes confetti-drop {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.65) rotate(0deg);
  }
  10% {
    opacity: 1;
  }
  8% {
    opacity: 1;
    transform: translate(calc(-50% + var(--burst-x)), calc(-50% + var(--burst-y))) scale(1.05) rotate(calc(var(--r) * 0.35));
  }
  44% {
    opacity: 1;
    transform: translate(
      calc(-50% + var(--burst-x) + var(--sway-x)),
      calc(-50% + (var(--y) * 0.28))
    ) scale(0.96) rotate(calc(var(--r) * 0.68));
  }
  74% {
    opacity: 0.82;
    transform: translate(
      calc(-50% + ((var(--x) + var(--burst-x)) * 0.5)),
      calc(-50% + (var(--y) * 0.72))
    ) scale(0.9) rotate(calc(var(--r) * 0.86));
  }
  100% {
    opacity: 0;
    transform: translate(calc(-50% + var(--x)), calc(-50% + var(--y))) scale(0.82) rotate(var(--r));
  }
}

@keyframes party-floor-tile-color {
  0%, 22% { background-color: var(--party-tile-color-1); }
  25%, 47% { background-color: var(--party-tile-color-2); }
  50%, 72% { background-color: var(--party-tile-color-3); }
  75%, 97% { background-color: var(--party-tile-color-4); }
  100% { background-color: var(--party-tile-color-1); }
}
