function useFairxMotion(rootRef, view) {
  React.useLayoutEffect(() => {
    const root = rootRef.current;
    const gsap = window.gsap;
    const ScrollTrigger = window.ScrollTrigger;

    if (!root || !gsap || !ScrollTrigger) return undefined;

    gsap.registerPlugin(ScrollTrigger);

    const matchMedia = gsap.matchMedia();

    matchMedia.add(
      {
        reduceMotion: "(prefers-reduced-motion: reduce)",
        desktop: "(min-width: 701px)",
        mobile: "(max-width: 700px)",
      },
      (context) => {
        const { reduceMotion, desktop } = context.conditions;
        if (reduceMotion) return;

        const distance = desktop ? 22 : 14;
        const duration = desktop ? 0.56 : 0.42;
        const intro = gsap.timeline({
          defaults: { duration, ease: "power3.out" },
        });

        const home = root.querySelector(".site-screen");
        const marketing = root.querySelector(".marketing-screen");
        const workspace = root.querySelector(".dapp-screen");
        const explorer = root.querySelector(".explorer-screen");

        if (home) {
          intro
            .from(".site-nav > *", { y: -8, stagger: 0.045 }, 0)
            .from(".hero-copy > *", { y: distance, stagger: 0.055 }, 0.04)
            .from(".hero-oracle-hud", { y: 18, scale: 0.985 }, 0.14)
            .from(".hero-quote-tape > span", { y: 10, stagger: 0.035 }, 0.2);

          if (desktop) {
            const stageLabel = root.querySelector(".story-kicker b");
            gsap.set(".story-step", { opacity: 0.28 });
            gsap.set(".step-source", { opacity: 1 });
            gsap.set(".source-lines i", { scaleX: 0.16, transformOrigin: "left center" });
            gsap.set(".consensus-core", { scale: 0.82, opacity: 0.58 });
            gsap.set(".settlement-beam span", { scaleX: 0, transformOrigin: "left center" });
            gsap.set(".settlement-block", { x: 22, opacity: 0.16 });
            gsap.set(".proof-seal", { y: 14, scale: 0.82, opacity: 0 });

            const storyTimeline = gsap.timeline({
              defaults: { ease: "none" },
              scrollTrigger: {
                trigger: ".oracle-story",
                start: "top top",
                end: "bottom bottom",
                scrub: 0.72,
                invalidateOnRefresh: true,
                onUpdate: (self) => {
                  if (!stageLabel) return;
                  const stage = Math.min(4, Math.floor(self.progress * 4) + 1);
                  stageLabel.textContent = `0${stage} / 04`;
                },
              },
            });

            storyTimeline
              .to(".source-lines i", { scaleX: 1, stagger: 0.035, duration: 0.18 }, 0)
              .to(".oracle-source", { x: 54, stagger: 0.025, duration: 0.2 }, 0.04)
              .to(".step-source", { opacity: 0.28, duration: 0.08 }, 0.2)
              .to(".step-filter", { opacity: 1, duration: 0.08 }, 0.2)
              .to(".oracle-source", { opacity: 0.48, y: (index) => (index - 1.5) * 5, duration: 0.18 }, 0.22)
              .to(".consensus-core", { scale: 1, opacity: 1, duration: 0.2 }, 0.3)
              .to(".consensus-halo", { scale: 1.1, opacity: 0.62, stagger: 0.04, duration: 0.18 }, 0.32)
              .to(".step-filter", { opacity: 0.28, duration: 0.08 }, 0.46)
              .to(".step-consensus", { opacity: 1, duration: 0.08 }, 0.46)
              .to(".settlement-beam span", { scaleX: 1, duration: 0.2 }, 0.52)
              .to(".settlement-block", { x: 0, opacity: 1, duration: 0.18 }, 0.6)
              .to(".step-consensus", { opacity: 0.28, duration: 0.08 }, 0.69)
              .to(".step-settlement", { opacity: 1, duration: 0.08 }, 0.69)
              .to(".proof-seal", { y: 0, scale: 1, opacity: 1, duration: 0.18 }, 0.76)
              .to(".settlement-block", { scale: 1.025, duration: 0.16 }, 0.8);
          }

          if (!desktop) {
            const stageLabel = root.querySelector(".story-kicker b");
            const mobileSteps = gsap.utils.toArray(".story-step");
            const progressFills = gsap.utils.toArray(".mobile-story-progress i span");

            gsap.set(mobileSteps, { opacity: 0, y: 14 });
            gsap.set(mobileSteps[0], { opacity: 1, y: 0 });
            gsap.set(progressFills, { scaleX: 0, transformOrigin: "left center" });
            gsap.set(".oracle-source", { x: 0, y: 0, scale: 1, opacity: 1 });
            gsap.set(".consensus-core", { scale: 0.76, opacity: 0.16 });
            gsap.set(".settlement-beam span", { scaleX: 0, transformOrigin: "left center" });
            gsap.set(".settlement-block", { y: 18, scale: 0.96, opacity: 0 });
            gsap.set(".proof-seal", { y: 8, scale: 0.9, opacity: 0 });

            gsap.to(".hero-copy", {
              y: -12,
              ease: "none",
              scrollTrigger: {
                trigger: ".site-hero",
                start: "top top",
                end: "bottom top",
                scrub: 0.55,
              },
            });

            gsap.to(".hero-oracle-hud", {
              y: -22,
              ease: "none",
              scrollTrigger: {
                trigger: ".site-hero",
                start: "top top",
                end: "bottom top",
                scrub: 0.65,
              },
            });

            ScrollTrigger.create({
              trigger: ".oracle-story",
              start: "top 72%",
              end: "max",
              toggleClass: { targets: ".mobile-site-dock", className: "is-visible" },
            });

            const mobileStoryTimeline = gsap.timeline({
              defaults: { ease: "none" },
              scrollTrigger: {
                trigger: ".oracle-story",
                start: "top top+=64",
                end: "bottom bottom",
                scrub: 0.52,
                pin: ".oracle-story-sticky",
                pinSpacing: false,
                anticipatePin: 1,
                invalidateOnRefresh: true,
                onUpdate: (self) => {
                  if (!stageLabel) return;
                  const stage = Math.min(4, Math.floor(self.progress * 4) + 1);
                  stageLabel.textContent = `0${stage} / 04`;
                },
              },
            });

            mobileStoryTimeline
              .to(progressFills[0], { scaleX: 1, duration: 0.18 }, 0)
              .to(mobileSteps[0], { opacity: 0, y: -10, duration: 0.08 }, 0.2)
              .to(mobileSteps[1], { opacity: 1, y: 0, duration: 0.1 }, 0.21)
              .to(progressFills[1], { scaleX: 1, duration: 0.18 }, 0.22)
              .to(".oracle-source", {
                y: (index) => index < 2 ? 16 : -16,
                x: (index) => index % 2 === 0 ? 8 : -8,
                scale: 0.94,
                opacity: 0.72,
                stagger: 0.015,
                duration: 0.18,
              }, 0.24)
              .to(".consensus-core", { scale: 0.9, opacity: 0.52, duration: 0.15 }, 0.33)
              .to(mobileSteps[1], { opacity: 0, y: -10, duration: 0.08 }, 0.45)
              .to(mobileSteps[2], { opacity: 1, y: 0, duration: 0.1 }, 0.46)
              .to(progressFills[2], { scaleX: 1, duration: 0.18 }, 0.47)
              .to(".oracle-source", { scale: 0.86, opacity: 0.2, duration: 0.16 }, 0.48)
              .to(".consensus-core", { scale: 1, opacity: 1, duration: 0.18 }, 0.5)
              .to(".consensus-halo", { scale: 1.12, opacity: 0.68, stagger: 0.03, duration: 0.15 }, 0.52)
              .to(".settlement-beam span", { scaleX: 1, duration: 0.16 }, 0.58)
              .to(mobileSteps[2], { opacity: 0, y: -10, duration: 0.08 }, 0.7)
              .to(mobileSteps[3], { opacity: 1, y: 0, duration: 0.1 }, 0.71)
              .to(progressFills[3], { scaleX: 1, duration: 0.18 }, 0.72)
              .to(".consensus-core", { scale: 0.9, opacity: 0.24, duration: 0.15 }, 0.73)
              .to(".settlement-block", { y: 0, scale: 1, opacity: 1, duration: 0.18 }, 0.74)
              .to(".proof-seal", { y: 0, scale: 1, opacity: 1, duration: 0.16 }, 0.82);
          }

          gsap.from(".proof-band-head > *", {
            y: distance,
            autoAlpha: 0,
            duration,
            stagger: 0.06,
            ease: "power3.out",
            scrollTrigger: { trigger: ".proof-band", start: "top 84%", once: true },
          });
          gsap.from(".evidence-card", {
            y: distance,
            autoAlpha: 0,
            duration,
            stagger: 0.08,
            ease: "power3.out",
            scrollTrigger: { trigger: ".evidence-grid", start: "top 86%", once: true },
          });
          gsap.from(".evidence-connector span", {
            scaleX: 0,
            transformOrigin: "left center",
            duration: 0.45,
            stagger: 0.08,
            ease: "power2.out",
            scrollTrigger: { trigger: ".evidence-grid", start: "top 86%", once: true },
          });
        }

        if (marketing) {
          intro
            .from(".marketing-nav > *", { y: -10, autoAlpha: 0, stagger: 0.05 }, 0)
            .from(".marketing-hero-copy > *", { y: distance, autoAlpha: 0, stagger: 0.07 }, 0.08)
            .from(".marketing-visual", { y: distance, scale: 0.985, autoAlpha: 0 }, 0.18);

          root.querySelectorAll(".marketing-section").forEach((section) => {
            const targets = section.querySelectorAll([
              ".section-heading",
              ".section-copy",
              ".principle-card",
              ".process-rail article",
              ".module-grid article",
              ".metric",
              ".audit-strip > span",
              ".risk-ladder > div",
              ".oracle-ledger > div",
              ".outcome-risk-grid > span",
              ".isolation-diagram > *",
              ".formula-card > *",
              ".boundary-card",
              ".order-preview-card",
              ".endpoint-card",
            ].join(","));

            if (!targets.length) return;

            gsap.from(targets, {
              y: desktop ? 24 : 14,
              autoAlpha: 0,
              duration,
              stagger: desktop ? 0.045 : 0.025,
              ease: "power3.out",
              scrollTrigger: { trigger: section, start: "top 82%", once: true },
            });
          });
        }

        if (workspace || explorer) {
          const headingTargets = root.querySelectorAll([
            ".workspace-page-topbar > *",
            ".app-topbar > *",
            ".explorer-topbar > *",
            ".market-title-row > *",
            ".explorer-title-row > *",
            ".explorer-home-hero > *",
          ].join(","));
          const metricTargets = root.querySelectorAll([
            ".dashboard-metrics .metric",
            ".stock-market-facts .metric",
            ".market-metrics-row .metric",
            ".explorer-home-metrics .metric",
          ].join(","));
          const surfaceTargets = Array.from(root.querySelectorAll([
            ".panel",
            ".market-launch-grid > button",
            ".network-health-card",
            ".claim-card",
            ".contracts-card",
            ".portfolio-summary > article",
            ".explorer-list-card",
            ".verified-markets > button",
            ".proof-check-card",
          ].join(","))).slice(0, 18);

          if (headingTargets.length) {
            intro.from(headingTargets, { y: desktop ? 14 : 10, autoAlpha: 0, stagger: 0.045 }, 0);
          }
          if (metricTargets.length) {
            intro.from(metricTargets, { y: distance, autoAlpha: 0, stagger: 0.045 }, 0.08);
          }
          if (surfaceTargets.length) {
            intro.from(surfaceTargets, { y: distance, autoAlpha: 0, stagger: 0.035 }, 0.16);
          }
        }

        const chartBars = root.querySelectorAll(".chart-bars span, .risk-result-chart > div > span");
        if (chartBars.length) {
          gsap.from(chartBars, {
            scaleY: 0,
            transformOrigin: "bottom center",
            duration: desktop ? 0.62 : 0.46,
            stagger: desktop ? 0.018 : 0.01,
            ease: "power3.out",
            delay: 0.16,
          });
        }

        const progressFills = root.querySelectorAll(".progress-fill");
        if (progressFills.length) {
          gsap.from(progressFills, {
            scaleX: 0,
            transformOrigin: "left center",
            duration: 0.62,
            stagger: 0.06,
            ease: "power3.out",
            delay: 0.18,
          });
        }
      },
      root,
    );

    return () => matchMedia.revert();
  }, [rootRef, view]);
}

window.useFairxMotion = useFairxMotion;
