/* ============================================================
   SCROLL-DRIVEN ANIMATIONS — clip-path masks, no time-based fade
   ============================================================ */

/* progressive enhancement; if no JS or no IO, all visible */
.reveal {
  --reveal-delay: 0ms;
  opacity: 1;
  transform: translateY(0);
  transition: opacity .8s var(--ease-out), transform .8s var(--ease-out);
  transition-delay: var(--reveal-delay);
}
.js .reveal { opacity: 0; transform: translateY(28px); }
.js .reveal.is-in { opacity: 1; transform: translateY(0); }

.mask-up { clip-path: inset(0 0 0 0); transition: clip-path 1s var(--ease-out); }
.js .mask-up { clip-path: inset(100% 0 0 0); }
.js .mask-up.is-in { clip-path: inset(0 0 0 0); }

/* line by line type reveal */
.split-line { display: inline-block; overflow: hidden; vertical-align: bottom; }
.split-line > span { display: inline-block; transform: translateY(105%); transition: transform .9s var(--ease-out); transition-delay: var(--reveal-delay, 0ms); }
.js .reveal-lines.is-in .split-line > span { transform: translateY(0); }
.no-js .split-line > span { transform: none; }

/* staggered children */
.stagger > * { transition-delay: calc(var(--i, 0) * 90ms); }

/* progress underline drawn on scroll */
@keyframes drawLine { from { transform: scaleX(0); } to { transform: scaleX(1); } }
