/* ==========================================================================
   ZARREL — Animations
   Keyframes + entrance/idle motion classes. Kept separate from layout so
   motion can be tuned (or disabled) independently. All motion is subtle and
   gated behind prefers-reduced-motion at the bottom of this file.
   ========================================================================== */

/* --- Keyframes ----------------------------------------------------------- */
@keyframes zr-fade-up {
  from {
    opacity: 0;
    transform: translateY(22px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes zr-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Slow drifting glow behind the hero fallback for subtle life */
@keyframes zr-glow-drift {
  0%, 100% { opacity: 0.5; transform: translate3d(-2%, 0, 0) scale(1); }
  50% { opacity: 0.85; transform: translate3d(2%, -2%, 0) scale(1.06); }
}

/* --- Entrance orchestration --------------------------------------------
   Elements start hidden (.reveal). js/animations.js adds .is-visible when
   the page is ready, triggering a staggered fade-up. If JS is unavailable,
   the no-js fallback at the end keeps everything visible.

   will-change is applied ONLY while the entrance is pending/running, then
   cleared by animations.js on animationend. Keeping it permanent (especially
   on the video card) forces standing compositor layers that can make the
   looping hero video stutter. */
.reveal {
  opacity: 0;
}

.reveal:not(.is-animated) {
  will-change: opacity, transform;
}

.reveal.is-visible {
  animation: zr-fade-up var(--dur-slow) var(--ease-out) both;
  animation-delay: var(--reveal-delay, 0s);
}

/* Once the entrance finishes we drop the compositor hint. */
.reveal.is-animated {
  will-change: auto;
}

/* Navbar + hero card fade in gently (no vertical shift for the sticky nav) */
.navbar.reveal.is-visible {
  animation: zr-fade-in var(--dur-slow) var(--ease-out) both;
}

/* --- Idle / ambient motion (only when the video is absent) -------------- */
.hero.is-video-error .hero__fallback::after {
  content: "";
  position: absolute;
  inset: -10%;
  background: radial-gradient(
    40% 40% at 40% 40%,
    rgba(37, 99, 235, 0.28) 0%,
    rgba(37, 99, 235, 0) 70%
  );
  animation: zr-glow-drift 14s var(--ease-in-out) infinite;
  pointer-events: none;
}

/* --- No-JS fallback: keep content visible if scripts fail --------------- */
@media (scripting: none) {
  .reveal {
    opacity: 1;
    transform: none;
  }
}

/* --- Reduced motion: honor user preference ------------------------------ */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .reveal {
    opacity: 1 !important;
    transform: none !important;
  }
}
