/* ================================================================
   animations.css — Reusable animation primitives, element preset
   entrances, parallax tilt containers, scroll reveal classes.
   ================================================================ */

/* ===================== ELEMENT ENTRY ===================== */
.el {
  animation: elIn var(--dur-slow) var(--ease-spring);
}

@keyframes elIn {
  from { opacity: 0; transform: translateY(8px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Disable replay animation after load via JS-added class on canvas */
.canvas.loaded .el { animation: none; }

/* ===================== SHIMMER (for loading images) ===================== */
@keyframes shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position: 400px 0; }
}

.shimmer {
  background:
    linear-gradient(90deg,
      rgba(255,255,255,.03) 0%,
      rgba(255,255,255,.08) 50%,
      rgba(255,255,255,.03) 100%);
  background-size: 800px 100%;
  animation: shimmer 1.6s linear infinite;
}

/* ===================== PARALLAX TILT (hover) ===================== */
.el {
  transform-style: preserve-3d;
  transform:
    perspective(1200px)
    rotateX(var(--tilt-x, 0deg))
    rotateY(var(--tilt-y, 0deg))
    translateY(var(--tilt-z, 0px));
  transition: transform var(--dur-slow) var(--ease-out), box-shadow var(--transition);
}

/* Disable tilt during drag / when locked */
.el.dragging,
.el.locked {
  --tilt-x: 0deg; --tilt-y: 0deg; --tilt-z: 0px;
}

/* ===================== PRESET: anim-* classes are applied to
   canvas elements; JSON serialization persists which preset is active.
   The exported HTML inlines these same keyframes + observer JS so
   the effect reproduces in the final site.
   ===================== */

/* Reveal-ready: sits invisible until .is-visible toggles */
.anim-ready[data-anim="fadeUp"]   { opacity: 0; transform: translateY(30px); }
.anim-ready[data-anim="slideIn"]  { opacity: 0; transform: translateX(-40px); }
.anim-ready[data-anim="scale"]    { opacity: 0; transform: scale(.85); }
.anim-ready[data-anim="blurIn"]   { opacity: 0; filter: blur(12px); }
.anim-ready[data-anim="rotate"]   { opacity: 0; transform: rotate(-4deg) scale(.92); }

.anim-ready[data-anim] {
  transition:
    opacity 900ms var(--ease-out),
    transform 900ms var(--ease-out),
    filter 900ms var(--ease-out);
}

.anim-ready[data-anim].is-visible {
  opacity: 1;
  transform: none;
  filter: none;
}

/* Ambient continuous animations (don't require reveal) */
.anim-ready[data-anim="float"] {
  animation: floatY 4s var(--ease-in-out) infinite alternate;
}

@keyframes floatY {
  from { transform: translateY(-4px); }
  to   { transform: translateY(4px); }
}

.anim-ready[data-anim="pulse"] {
  animation: pulseGlow 2.4s var(--ease-in-out) infinite;
}

@keyframes pulseGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(78,161,255,0); }
  50%      { box-shadow: 0 0 0 12px rgba(78,161,255,.14); }
}

/* ===================== DRAG SHINE ===================== */
.el.dragging {
  box-shadow: 0 20px 60px rgba(78, 161, 255, .30) !important;
}

/* ===================== SMOOTH SCROLL ===================== */
html { scroll-behavior: smooth; }

/* ===================== FOCUS RING ===================== */
:focus-visible {
  outline: 2px solid var(--brand-blue);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ===================== REDUCED MOTION ===================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .el { --tilt-x: 0deg !important; --tilt-y: 0deg !important; }
}
