/* Motion: load + scroll reveals and page transitions.
   Hidden states only apply under .js, so content is never stuck invisible without JavaScript. */

/* Page enter / leave */
.js body { animation: page-in 700ms var(--ease) both; }
@keyframes page-in { from { opacity: 0; } to { opacity: 1; } }
.page-leaving body { opacity: 0; transform: translateY(-12px); transition: opacity 280ms var(--ease), transform 280ms var(--ease); }

/* Default: rise + fade */
.js [data-reveal] {
  opacity: 0; transform: translateY(32px);
  transition: opacity 900ms var(--ease), transform 1000ms var(--ease-out);
  transition-delay: var(--delay, 0ms);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

.js [data-reveal="down"] { transform: translateY(-20px); }
.js [data-reveal="fade"] { transform: none; }

/* Blur-in for large copy */
.js [data-reveal="soft"] { filter: blur(10px); transform: translateY(18px); transition-property: opacity, transform, filter; }
.js [data-reveal="soft"].is-in { filter: none; }

/* Mask: child slides up out of a clipped box (big display type) */
.js [data-reveal="mask"] { opacity: 1; transform: none; overflow: hidden; }
.js [data-reveal="mask"] > * { transform: translateY(105%); transition: transform 1300ms var(--ease-out); transition-delay: var(--delay, 0ms); }
.js [data-reveal="mask"].is-in > * { transform: none; }

/* Media: unveils from an inset clip while the image settles from a slight zoom */
.js [data-reveal="media"] { opacity: 1; transform: none; clip-path: inset(10% 10% 10% 10%); transition: clip-path 1300ms var(--ease-out); transition-delay: var(--delay, 0ms); }
.js [data-reveal="media"].is-in { clip-path: inset(0 0 0 0); }
.js [data-reveal="media"] img, .js [data-reveal="media"] .placeholder, .js [data-reveal="media"] video { transform: scale(1.18); transition: transform 1600ms var(--ease-out) !important; transition-delay: var(--delay, 0ms) !important; }
.js [data-reveal="media"].is-in img, .js [data-reveal="media"].is-in .placeholder, .js [data-reveal="media"].is-in video { transform: none; }

/* Rule: top border draws left→right, then contents rise */
.js [data-reveal="rule"] { opacity: 1; transform: none; position: relative; border-top-color: transparent; }
.js [data-reveal="rule"]::before {
  content: ""; position: absolute; left: 0; right: 0; top: -1px; height: 1px; background: var(--rule);
  transform: scaleX(0); transform-origin: left; transition: transform 1200ms var(--ease-out); transition-delay: var(--delay, 0ms);
}
.js [data-reveal="rule"].is-in::before { transform: scaleX(1); }
.js [data-reveal="rule"] > * { opacity: 0; transform: translateY(24px); transition: opacity 800ms var(--ease), transform 900ms var(--ease-out); transition-delay: calc(var(--delay, 0ms) + 200ms); }
.js [data-reveal="rule"].is-in > * { opacity: 1; transform: none; }

/* Words: each word rises out of its own line mask, staggered (JS splits the text) */
.js [data-reveal="words"] { opacity: 1; transform: none; }
.w { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .08em; margin-bottom: -.08em; }
.w > .wi { display: inline-block; }
.js [data-reveal="words"] .wi { transform: translateY(110%); transition: transform 900ms var(--ease-out); transition-delay: calc(var(--delay, 0ms) + var(--wi, 0) * 45ms); }
.js [data-reveal="words"].is-in .wi { transform: none; }

/* Scroll progress */
.progress { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 80; pointer-events: none; background: var(--yellow); transform: scaleX(0); transform-origin: left; }

/* Reduced motion: keep gentle fades, drop movement */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js [data-reveal], .js [data-reveal] > *, .js [data-reveal] .wi, .js [data-reveal]::before,
  .js [data-reveal="media"] img, .js [data-reveal="media"] .placeholder {
    transform: none !important; clip-path: none !important; filter: none !important;
  }
  .js [data-reveal="words"], .js [data-reveal="mask"], .js [data-reveal="media"] { opacity: 0; transition: opacity 900ms var(--ease); }
  .js [data-reveal].is-in { opacity: 1; }
  .js [data-reveal="rule"] { border-top-color: var(--rule); }
  .page-leaving body { transform: none; }
  .doodle--wiggle, .doodle--point { animation: none; }
  .row::before, .btn::before, .cursor { transition-duration: 200ms !important; }
}
