{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "how-it-works-section-v2",
  "title": "How It Works Section v2",
  "description": "Timeline-style three-step process section with a GSAP ScrollTrigger beam that travels between week badges as you scroll, revealing each step.",
  "dependencies": [
    "gsap"
  ],
  "registryDependencies": [
    "badge"
  ],
  "files": [
    {
      "path": "registry/new-york/blocks/how-it-works-section-v2/page.tsx",
      "content": "import HowItWorksSectionV2 from \"./components/how-it-works-section-v2\"\n\nexport default function Page() {\n  return <HowItWorksSectionV2 />\n}\n",
      "type": "registry:page",
      "target": "app/how-it-works-section-v2/page.tsx"
    },
    {
      "path": "registry/new-york/blocks/how-it-works-section-v2/components/how-it-works-section-v2.tsx",
      "content": "\"use client\"\n\nimport StepsGrid from \"./steps-grid\"\n\nexport default function HowItWorksSectionV2() {\n  return (\n    <section className=\"py-4 md:py-6 lg:py-8\">\n      <StepsGrid\n        title={\n          <h2 className=\"text-4xl leading-tight font-light tracking-tight sm:text-5xl lg:text-6xl\">\n            How It Works\n          </h2>\n        }\n      />\n    </section>\n  )\n}\n",
      "type": "registry:component",
      "target": "app/how-it-works-section-v2/components/how-it-works-section-v2.tsx"
    },
    {
      "path": "registry/new-york/blocks/how-it-works-section-v2/components/steps-grid.tsx",
      "content": "\"use client\"\n\nimport type { ReactNode } from \"react\"\nimport { useRef } from \"react\"\n\nimport { Badge } from \"@/components/ui/badge\"\n\nimport { useHiw2V2Animations } from \"../hooks/use-hiw2-v2-animations\"\nimport { STEP_LABEL_BADGE_VARIANT, steps } from \"../lib/steps\"\nimport StepCard from \"./step-card\"\n\ntype StepsGridProps = {\n  title: ReactNode\n}\n\nexport default function StepsGrid({ title }: StepsGridProps) {\n  const titleRef = useRef<HTMLDivElement>(null)\n  const cardRefs = useRef<(HTMLDivElement | null)[]>([])\n\n  useHiw2V2Animations({\n    title: titleRef,\n    cards: cardRefs,\n  })\n\n  return (\n    <div className=\"mx-auto max-w-6xl px-4\">\n      <div ref={titleRef} className=\"mb-12 md:mb-16\">\n        {title}\n      </div>\n\n      <div className=\"grid grid-cols-1 gap-10 md:grid-cols-3 md:gap-8 lg:gap-14\">\n        {steps.map((step, i) => (\n          <div\n            key={step.id}\n            ref={(el) => {\n              cardRefs.current[i] = el\n            }}\n          >\n            <Badge variant={STEP_LABEL_BADGE_VARIANT} className=\"uppercase\">\n              {step.label}\n            </Badge>\n\n            <StepCard step={step} />\n          </div>\n        ))}\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "app/how-it-works-section-v2/components/steps-grid.tsx"
    },
    {
      "path": "registry/new-york/blocks/how-it-works-section-v2/components/step-card.tsx",
      "content": "import { CheckCircle2 } from \"lucide-react\"\n\nimport type { Step } from \"../lib/steps\"\n\ntype Props = {\n  step: Step\n}\n\nexport default function StepCard({ step }: Props) {\n  return (\n    <div className=\"flex flex-col gap-4 pt-4\">\n      <h3 className=\"text-xl leading-snug font-medium tracking-tight text-foreground\">\n        {step.title}\n      </h3>\n\n      <ul className=\"flex flex-col gap-3\">\n        {step.features.map((feature, index) => (\n          <li\n            key={index}\n            data-hiw2-feature=\"\"\n            className=\"flex items-start gap-3 text-sm leading-relaxed text-muted-foreground\"\n          >\n            <CheckCircle2 className=\"mt-0.5 h-4 w-4 shrink-0 fill-foreground stroke-background text-foreground\" />\n            <span>{feature}</span>\n          </li>\n        ))}\n      </ul>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "app/how-it-works-section-v2/components/step-card.tsx"
    },
    {
      "path": "registry/new-york/blocks/how-it-works-section-v2/hooks/use-hiw2-v2-animations.ts",
      "content": "\"use client\"\n\nimport { type RefObject, useLayoutEffect, useRef } from \"react\"\n\nimport gsap from \"gsap\"\nimport { ScrollTrigger } from \"gsap/ScrollTrigger\"\n\ngsap.registerPlugin(ScrollTrigger)\n\nexport type Hiw2V2Refs = {\n  title: RefObject<HTMLElement | null>\n  cards: RefObject<(HTMLDivElement | null)[]>\n}\n\nexport function useHiw2V2Animations(refs: Hiw2V2Refs) {\n  const refsRef = useRef(refs)\n  useLayoutEffect(() => {\n    refsRef.current = refs\n  })\n\n  useLayoutEffect(() => {\n    let ctx: gsap.Context | null = null\n    const r = () => refsRef.current\n\n    const cardEls = (r().cards.current ?? []).filter(Boolean) as HTMLElement[]\n    if (!cardEls.length) return\n\n    if (window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) {\n      const titleEl = r().title.current\n      const allFeatures = cardEls.flatMap((card) =>\n        Array.from(card.querySelectorAll<HTMLElement>(\"[data-hiw2-feature]\"))\n      )\n      gsap.set([titleEl, ...cardEls, ...allFeatures].filter(Boolean), {\n        clearProps: \"all\",\n      })\n      return\n    }\n\n    ctx = gsap.context(() => {\n      const titleEl = r().title.current\n\n      if (titleEl) {\n        gsap.set(titleEl, { y: 28, opacity: 0 })\n        gsap.to(titleEl, {\n          y: 0,\n          opacity: 1,\n          duration: 0.8,\n          ease: \"power3.out\",\n          scrollTrigger: {\n            trigger: titleEl,\n            start: \"top 88%\",\n            once: true,\n                      },\n        })\n      }\n\n      cardEls.forEach((card) => {\n        gsap.set(card, { y: 20, opacity: 0 })\n        gsap.to(card, {\n          y: 0,\n          opacity: 1,\n          duration: 0.6,\n          ease: \"power3.out\",\n          scrollTrigger: {\n            trigger: card,\n            start: \"top 84%\",\n            once: true,\n          },\n        })\n      })\n\n      cardEls.forEach((card, i) => {\n        const features = Array.from(\n          card.querySelectorAll<HTMLElement>(\"[data-hiw2-feature]\")\n        )\n        if (!features.length) return\n\n        gsap.set(features, { x: -12, opacity: 0 })\n        gsap.to(features, {\n          x: 0,\n          opacity: 1,\n          stagger: 0.075,\n          duration: 0.44,\n          ease: \"power2.out\",\n          delay: 0.2 + i * 0.08,\n          scrollTrigger: {\n            trigger: card,\n            start: \"top 84%\",\n            once: true,\n                      },\n        })\n      })\n\n      requestAnimationFrame(() => {\n        ScrollTrigger.refresh()\n      })\n    })\n\n    return () => {\n      ctx?.revert()\n    }\n  }, [])\n}\n",
      "type": "registry:hook",
      "target": "app/how-it-works-section-v2/hooks/use-hiw2-v2-animations.ts"
    },
    {
      "path": "registry/new-york/blocks/how-it-works-section-v2/lib/steps.ts",
      "content": "export const STEP_LABEL_BADGE_VARIANT = \"outline\" as const\n\nexport type StepFeature = string\n\nexport type Step = {\n  id: string\n  label: string\n  title: string\n  features: StepFeature[]\n}\n\nexport const steps: Step[] = [\n  {\n    id: \"step-1\",\n    label: \"Step 1\",\n    title: \"Create your project\",\n    features: [\n      \"Scaffold a new Next.js app with a single command\",\n      \"Choose Tailwind CSS and App Router when prompted\",\n      \"TypeScript support included out of the box\",\n    ],\n  },\n  {\n    id: \"step-2\",\n    label: \"Step 2\",\n    title: \"Initialize shadcn/ui\",\n    features: [\n      \"Run the shadcn CLI to configure your project\",\n      \"Sets up components.json with your preferred style\",\n      \"Adds the necessary Tailwind and import alias config\",\n    ],\n  },\n  {\n    id: \"step-3\",\n    label: \"Step 3\",\n    title: \"Add components\",\n    features: [\n      \"Install only the components you actually need\",\n      \"Code is copied directly into your project\",\n      \"Fully customizable — no black-box dependencies\",\n    ],\n  },\n]\n",
      "type": "registry:lib",
      "target": "app/how-it-works-section-v2/lib/steps.ts"
    }
  ],
  "type": "registry:block"
}