/* =========================================================
   ANIMATIONS — CSS utility classes used alongside GSAP
   ========================================================= */

[data-reveal]{
  opacity: 0;
  transform: translateY(36px);
  will-change: transform, opacity;
}
[data-reveal].is-revealed{
  animation: revealUp 1s cubic-bezier(.22,1,.36,1) forwards;
}
@keyframes revealUp{
  to{ opacity:1; transform: translateY(0); }
}

[data-reveal-scale]{ opacity:0; transform: scale(.94); }
[data-reveal-scale].is-revealed{ animation: revealScale 1s cubic-bezier(.22,1,.36,1) forwards; }
@keyframes revealScale{ to{ opacity:1; transform: scale(1); } }

.float-slow{ animation: floatY 7s ease-in-out infinite; }
.float-slower{ animation: floatY 10s ease-in-out infinite; }
@keyframes floatY{
  0%, 100%{ transform: translateY(0px); }
  50%{ transform: translateY(-18px); }
}

.spin-slow{ animation: spin 30s linear infinite; }
@keyframes spin{ to{ transform: rotate(360deg); } }

.pulse-glow{ animation: pulseGlow 3.4s ease-in-out infinite; }
@keyframes pulseGlow{
  0%, 100%{ opacity: .55; }
  50%{ opacity: 1; }
}

.grain{
  position:absolute; inset:0; pointer-events:none; opacity:.035; mix-blend-mode:multiply; z-index:1;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media (prefers-reduced-motion: reduce){
  [data-reveal], [data-reveal-scale]{ opacity:1; transform:none; animation:none; }
  .float-slow, .float-slower, .spin-slow, .pulse-glow{ animation:none; }
}
