/* Closed Form Labs scroll engine, mockup v4: the layout and motion half of
   cf-scroll.js. Nothing here hides content unless the script has booted
   (.cf-ready) and someone can see the motion (.cf-anim). */

/* ---------- pinned acts (desktop only) ---------- */
.cf-pin [data-act="pin"],
.cf-pin [data-act="pan"] { position: relative; height: calc(var(--span, 1) * 100svh); }
.cf-pin [data-act="pin"] > .stage,
.cf-pin [data-act="pan"] > .stage { position: sticky; top: 0; height: 100svh; overflow: hidden; }
.cf-pin [data-rail] { display: flex; width: max-content; will-change: transform; }

/* Cues: --v is 0..1 visibility, --dir is 1 while entering and -1 while leaving. */
.cf-pin.cf-ready [data-act] [data-cue] {
  opacity: var(--v, 0);
  transform: translate3d(0, calc((1 - var(--v, 0)) * 34px * var(--dir, 1)), 0);
  filter: blur(calc((1 - var(--v, 0)) * 6px));
  will-change: opacity, transform;
}
.cf-pin [data-cue].cf-off { visibility: hidden; }

/* Unpinned (phones, reduced motion): acts are ordinary sections and rails are
   native swipe strips that move under the thumb. */
.cf-flow [data-act] > .stage { position: relative; }
.cf-flow [data-rail] {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.cf-flow [data-rail]::-webkit-scrollbar { display: none; }
.cf-flow [data-rail] > * { scroll-snap-align: start; }

/* ---------- timed reveals ---------- */
.cf-ready.cf-anim [data-reveal]:not(.is-in),
.cf-flow.cf-ready.cf-anim [data-cue]:not(.is-in) { opacity: 0; transform: translate3d(0, 36px, 0); }
.cf-ready.cf-anim [data-reveal="blur"]:not(.is-in) { filter: blur(14px); transform: translate3d(0, 18px, 0) scale(.985); }
.cf-ready.cf-anim [data-reveal].is-in,
.cf-flow.cf-ready.cf-anim [data-cue].is-in {
  transition: opacity .9s var(--ease), transform 1s var(--ease), filter 1s var(--ease);
  transition-delay: calc(var(--d, 0) * 90ms);
}

/* ---------- split lines: slide up from behind a clean edge ---------- */
.is-split .ln { display: block; overflow: hidden; padding-bottom: .08em; margin-bottom: -.08em; }
.is-split .ln-i { display: block; }
.cf-ready.cf-anim .is-split:not(.is-in) .ln-i { transform: translate3d(0, 108%, 0); }
.cf-ready.cf-anim .is-split.is-in .ln-i {
  transition: transform 1s var(--ease);
  transition-delay: calc(var(--i, 0) * 85ms + var(--d, 0) * 90ms);
}
.is-split .w { display: inline-block; }

/* ---------- pointer physics ---------- */
[data-magnet] { transform: translate3d(var(--mx, 0px), var(--my, 0px), 0); transition: transform .5s var(--ease); }
[data-magnet]:hover { transition-duration: .15s; }
[data-tilt] { transform: perspective(1100px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); transition: transform .6s var(--ease); transform-style: preserve-3d; }
[data-tilt]:hover { transition-duration: .12s; }

/* ---------- reading progress ---------- */
[data-progress] { transform-origin: 0 50%; transform: scaleX(var(--sp, 0)); }

@media (prefers-reduced-motion: reduce) {
  [data-magnet], [data-tilt] { transform: none !important; transition: none !important; }
  [data-reveal], [data-cue], .is-split .ln-i { opacity: 1 !important; transform: none !important; filter: none !important; transition: none !important; }
}
