"use client"; /** * Process — "The Feedback Loop". The intro column pins (sticky) while the four * steps scroll past; each step lights up as it reaches the viewport center, and * a serif count in the sticky column advances with it. This is the * scrollytelling beat. Degrades to a plain stacked list under reduced-motion * (all steps shown active, no pin behaviour) and on narrow screens. */ import { useEffect, useRef, useState } from "react"; import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import { processSteps } from "../content"; gsap.registerPlugin(ScrollTrigger); export default function Process() { const root = useRef(null); const [active, setActive] = useState(0); useEffect(() => { const el = root.current; if (!el) return; if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setActive(processSteps.length - 1); return; } const ctx = gsap.context(() => { gsap.utils.toArray(".pstep").forEach((step, i) => { ScrollTrigger.create({ trigger: step, start: "top 60%", end: "bottom 60%", onToggle: (self) => { if (self.isActive) setActive(i); }, }); }); }, el); return () => ctx.revert(); }, []); return (

How it works

The Feedback Loop.

    {processSteps.map((p, i) => (
  1. {p.n}

    {p.name}

    {p.desc}

  2. ))}
); }