/* ==========================================================================
   animations.css — scroll-scrubbed reveal + parallax (driven by --p from
   reveal.js) plus the few load/loop animations. Only transform / opacity /
   filter are animated.
   ========================================================================== */

/* --- Scrubbed reveal: opacity + offset interpolated by --p (0..1) --------- */
[data-reveal] {
  opacity: var(--p, 0);
  transform: translateY(calc((1 - var(--p, 0)) * 22px));
  /* No CSS transition here: reveal.js lerp-smooths --p toward its scroll target every
     frame (exponential ease-out), so --p maps straight through. A CSS transition on top
     would low-pass an already-smoothed value and add visible lag. */
  will-change: opacity, transform;
}
[data-reveal="left"] {
  transform: translateX(calc((1 - var(--p, 0)) * -32px));
}
[data-reveal="right"] {
  transform: translateX(calc((1 - var(--p, 0)) * 32px));
}
[data-reveal="scale"] {
  transform: scale(calc(0.94 + var(--p, 0) * 0.06));
}
[data-reveal="fade"] {
  transform: none;
}

/* --- Parallax: drift by pass-through progress (0.5 = neutral/centered) ----- */
[data-parallax] {
  transform: translateY(calc((0.5 - var(--p, 0.5)) * var(--par, 32px)));
  /* Smoothed in JS (same lerp loop as reveals). */
  will-change: transform;
}

/* --- Hero headline word rise (on load; hero is above the fold) ------------ */
.word {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.5em);
  animation: word-rise var(--dur-slow) var(--ease) forwards;
  animation-delay: calc(var(--w, 0) * var(--stagger) + 120ms);
}
@keyframes word-rise {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* --- Ambient hero glow ---------------------------------------------------- */
@keyframes float-soft {
  0%,
  100% {
    transform: translateY(0) scale(1);
  }
  50% {
    transform: translateY(-10px) scale(1.02);
  }
}

/* --- Stepper progress line: drawn by the section's own --p ---------------- */
.stepline__fill {
  transform: scaleX(var(--p, 0));
  transform-origin: left center;
}

/* --- Transport-ladder loop (bento tile) ----------------------------------- */
.ladder-step {
  transition: color var(--dur-med) var(--ease-std),
    background-color var(--dur-med) var(--ease-std),
    border-color var(--dur-med) var(--ease-std);
}
.ladder-step.is-active {
  color: var(--accent-text);
  background: var(--accent-muted);
  border-color: transparent;
}
.ladder-step.is-active .ladder-dot {
  background: var(--accent);
  box-shadow: 0 0 8px 1px var(--accent-glow);
}

/* --- Floating-pill ambient backdrop (Connectivity section) ---------------
   Decorative gradient lozenges that drift behind the bento. Kept low-opacity
   and blurred so nothing competes with card/text contrast. Emerald leads; the
   indigo/teal/pink hues are the "hint of multicolor". */
#features {
  isolation: isolate; /* contain the pill stacking context */
}
#features > .container {
  position: relative;
  z-index: 1;
}
.pill-field {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.pill {
  position: absolute;
  width: clamp(220px, 26vw, 420px);
  aspect-ratio: 5 / 2;
  border-radius: 999px;
  filter: blur(34px);
  opacity: 0.2;
  transform: rotate(var(--rot, 0deg));
  will-change: transform;
  animation: pill-drift var(--dur, 28s) var(--ease-std) infinite alternate;
  animation-delay: var(--delay, 0s);
}
[data-theme="light"] .pill {
  opacity: 0.12;
}
@keyframes pill-drift {
  from {
    transform: translate3d(0, 0, 0) rotate(var(--rot, 0deg));
  }
  to {
    transform: translate3d(var(--dx, 40px), var(--dy, -24px), 0)
      rotate(calc(var(--rot, 0deg) + 3deg));
  }
}
/* Placement, hue, angle and cadence per pill (emerald-dominant mix). */
.pill:nth-child(1) {
  top: 4%;
  left: -8%;
  background: linear-gradient(120deg, var(--accent), var(--hue-teal));
  --rot: -18deg;
  --dx: 52px;
  --dy: 30px;
  --dur: 26s;
}
.pill:nth-child(2) {
  top: 56%;
  left: 2%;
  background: linear-gradient(120deg, var(--hue-indigo), var(--accent));
  --rot: -26deg;
  --dx: 40px;
  --dy: -34px;
  --dur: 32s;
  --delay: -8s;
}
.pill:nth-child(3) {
  top: -6%;
  left: 38%;
  background: linear-gradient(120deg, var(--hue-teal), var(--accent));
  --rot: 14deg;
  --dx: -30px;
  --dy: 42px;
  --dur: 28s;
  --delay: -4s;
}
.pill:nth-child(4) {
  top: 60%;
  left: 46%;
  background: linear-gradient(120deg, var(--accent), var(--hue-indigo));
  --rot: 20deg;
  --dx: 46px;
  --dy: -28px;
  --dur: 30s;
  --delay: -12s;
}
.pill:nth-child(5) {
  top: 8%;
  right: 2%;
  background: linear-gradient(120deg, var(--hue-pink), var(--hue-indigo));
  opacity: 0.14;
  --rot: -12deg;
  --dx: -44px;
  --dy: 32px;
  --dur: 34s;
  --delay: -6s;
}
.pill:nth-child(6) {
  top: 66%;
  right: 6%;
  background: linear-gradient(120deg, var(--accent), var(--hue-teal));
  --rot: 22deg;
  --dx: -38px;
  --dy: -30px;
  --dur: 27s;
  --delay: -2s;
}
.pill:nth-child(7) {
  top: 28%;
  right: 28%;
  background: linear-gradient(120deg, var(--hue-indigo), var(--accent));
  --rot: -8deg;
  --dx: 30px;
  --dy: 36px;
  --dur: 31s;
  --delay: -14s;
}

/* --- Reduced motion: snap everything to its final frame ------------------- */
@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
  [data-parallax] {
    transform: none !important;
  }
  .word {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
  .stepline__fill {
    transform: scaleX(1) !important;
  }
  .pill {
    animation: none !important;
  }
}
