/* =========================================================
   KEYFRAMES
   ========================================================= */
@keyframes rise { to { opacity: 1; transform: translateY(0); } }
@keyframes fadeIn { to { opacity: 1; } }
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes text-reveal { to { transform: translateY(0); } }
@keyframes cue {
  0% { opacity: 1; transform: translateY(0); }
  70% { opacity: 0; transform: translateY(10px); }
  100% { opacity: 0; }
}
@keyframes count-fade {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* =========================================================
   SCROLL REVEAL (generic, JS toggles .is-visible via IntersectionObserver)
   ========================================================= */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
}
.reveal.is-visible { opacity: 1; transform: translateY(0); }

/* Stagger: JS sets --stagger-index on each item in a grid; reveal
   transition-delay is derived from it for a cascading entrance. */
.reveal[style*="--stagger-index"] {
  transition-delay: calc(var(--stagger-index, 0) * 90ms);
}

/* Process step numbers: brief count-in emphasis on reveal */
.process-list__num.is-visible { animation: count-fade 0.5s var(--ease-out) forwards; }

/* =========================================================
   MOUSE-FOLLOW GLOW
   JS updates --mx / --my (0-100%) on mousemove; a radial-gradient
   overlay tracks the cursor. Subtle - opacity stays low.
   ========================================================= */
.glow-surface { position: relative; overflow: hidden; }
.glow-surface::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%),
              rgba(201,161,118,0.16), transparent 70%);
  opacity: 0;
  transition: opacity var(--dur-fast) ease;
  pointer-events: none;
}
.glow-surface:hover::before { opacity: 1; }

/* =========================================================
   MAGNETIC BUTTONS
   JS sets a small translate() on mousemove within a radius;
   this transition smooths it back to rest on mouseleave.
   ========================================================= */
.btn--magnetic { transition: transform 0.25s var(--ease-out); }

/* =========================================================
   PARALLAX
   JS applies translateY based on scroll position; kept small
   so it reads as depth, not motion sickness.
   ========================================================= */
.parallax { will-change: transform; }
