/* ==========================================================================
   Cinematic motion helpers (GSAP drives most motion; CSS for loops/polish)
   ========================================================================== */

@keyframes grain-shift {
  0% { transform: translate(0, 0); }
  25% { transform: translate(-1.5%, 1%); }
  50% { transform: translate(1%, -1.5%); }
  75% { transform: translate(-0.5%, 0.5%); }
  100% { transform: translate(0, 0); }
}

@keyframes wave {
  0%, 100% { height: 6px; opacity: 0.35; }
  50% { height: 22px; opacity: 0.85; }
}

@keyframes typing-dot {
  0%, 80%, 100% { transform: translateY(0); opacity: 0.35; }
  40% { transform: translateY(-4px); opacity: 0.9; }
}

@keyframes fog-drift {
  0% { transform: translateX(-4%); }
  100% { transform: translateX(4%); }
}

@keyframes heartbeat-pulse {
  0%, 100% { transform: scale(1); opacity: 0.15; }
  14% { transform: scale(1.04); opacity: 0.28; }
  28% { transform: scale(1); opacity: 0.15; }
  42% { transform: scale(1.03); opacity: 0.22; }
}

.grain.is-alive {
  animation: grain-shift 0.45s steps(2) infinite;
}

.phone.is-active .phone__waves span {
  animation: wave 1.1s ease-in-out infinite;
}

.phone.is-active .phone__waves span:nth-child(2) { animation-delay: 0.12s; }
.phone.is-active .phone__waves span:nth-child(3) { animation-delay: 0.24s; }
.phone.is-active .phone__waves span:nth-child(4) { animation-delay: 0.36s; }
.phone.is-active .phone__waves span:nth-child(5) { animation-delay: 0.48s; }

.chat__typing.is-active span {
  animation: typing-dot 1s ease-in-out infinite;
}

.chat__typing.is-active span:nth-child(2) { animation-delay: 0.15s; }
.chat__typing.is-active span:nth-child(3) { animation-delay: 0.3s; }

.forest__fog--back {
  animation: fog-drift 18s ease-in-out infinite alternate;
}

.forest__fog--front {
  animation: fog-drift 12s ease-in-out infinite alternate-reverse;
}

.scene__stage--black.is-heartbeat::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 50%, rgba(196, 107, 58, 0.12), transparent 45%);
  animation: heartbeat-pulse 1.35s ease-in-out infinite;
  pointer-events: none;
}

/* Utility states driven by JS */

.is-blurred {
  filter: blur(8px);
}

.is-sharp {
  filter: blur(0);
}

.text-reveal {
  filter: blur(12px);
  opacity: 0;
  transform: translateY(12px);
}

/* Film motion blur helper during rewind */

.scene__stage--rewind.is-spinning {
  filter: contrast(1.05) saturate(0.9);
}

.scene__stage--rewind.is-spinning .rewind__faces {
  filter: blur(2px);
}

.scene__stage--rewind.is-spinning .chromatic,
body.is-rewinding .chromatic {
  opacity: 0.55;
}

/* Soft camera shake class (GSAP preferred; fallback) */

@keyframes soft-shake {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(1px, -1px); }
  50% { transform: translate(-1px, 1px); }
  75% { transform: translate(1px, 0); }
}

.is-shaking {
  animation: soft-shake 0.35s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .grain.is-alive,
  .forest__fog--back,
  .forest__fog--front,
  .phone.is-active .phone__waves span,
  .chat__typing.is-active span,
  .scene__stage--black.is-heartbeat::before,
  .is-shaking {
    animation: none !important;
  }
}
