{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "reveal",
  "type": "registry:component",
  "title": "Reveal",
  "description": "Fades + lifts children into view on scroll via IntersectionObserver. Dependency-free, respects reduced-motion.",
  "dependencies": [],
  "registryDependencies": [],
  "tier": "free",
  "note": "Requires the .reveal / .reveal.in transition rules from globals.css — copy them into your global stylesheet, or children render but never animate in.",
  "files": [
    {
      "path": "components/prism/Reveal.tsx",
      "content": "\"use client\";\n\nimport { useEffect, useRef } from \"react\";\n\n/**\n * Reveal — fades + lifts its children into view on scroll via IntersectionObserver.\n * Robust and dependency-free (no scroll-sync edge cases). The `.reveal/.in`\n * styling lives in globals.css and respects prefers-reduced-motion.\n */\nexport function Reveal({\n  children,\n  className = \"\",\n  delay = 0,\n}: {\n  children: React.ReactNode;\n  className?: string;\n  delay?: number;\n}) {\n  const ref = useRef<HTMLDivElement>(null);\n\n  useEffect(() => {\n    const el = ref.current;\n    if (!el) return;\n    const io = new IntersectionObserver(\n      (entries) => {\n        for (const e of entries) {\n          if (e.isIntersecting) {\n            el.classList.add(\"in\");\n            io.unobserve(el);\n          }\n        }\n      },\n      { threshold: 0.15, rootMargin: \"0px 0px -8% 0px\" }\n    );\n    io.observe(el);\n    return () => io.disconnect();\n  }, []);\n\n  return (\n    <div ref={ref} className={`reveal ${className}`} style={{ transitionDelay: `${delay}s` }}>\n      {children}\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/prism/Reveal.tsx"
    }
  ]
}