{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "text-reveal",
  "title": "Text Reveal",
  "description": "Word-by-word blur reveal on scroll.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "src/components/velora/text-reveal.tsx",
      "content": "\"use client\";\n\nimport { motion, useReducedMotion } from \"motion/react\";\n\nimport { cn } from \"@/lib/utils\";\n\ninterface TextRevealProps {\n  /** Plain text — revealed word by word */\n  text: string;\n  className?: string;\n  as?: \"h1\" | \"h2\" | \"h3\" | \"p\" | \"span\";\n  delay?: number;\n  /** Seconds between each word */\n  stagger?: number;\n  once?: boolean;\n}\n\nexport function TextReveal({\n  text,\n  className,\n  as: Tag = \"span\",\n  delay = 0,\n  stagger = 0.045,\n  once = true,\n}: TextRevealProps) {\n  const reducedMotion = useReducedMotion();\n  const words = text.split(\" \");\n\n  // Same markup on server and client. Under reduced motion the CSS\n  // overrides keep every word visible (even before hydration) and the\n  // JS transition is instant.\n  return (\n    <Tag data-slot=\"text-reveal\" className={cn(className)}>\n      <span className=\"sr-only\">{text}</span>\n      <motion.span\n        aria-hidden\n        initial=\"hidden\"\n        whileInView=\"visible\"\n        viewport={{ once, margin: \"0px 0px -10% 0px\" }}\n        transition={{ staggerChildren: stagger, delayChildren: delay }}\n        className=\"inline\"\n      >\n        {words.map((word, i) => (\n          <motion.span\n            key={`${word}-${i}`}\n            className=\"inline-block will-change-transform motion-reduce:transform-none! motion-reduce:opacity-100! motion-reduce:[filter:none]!\"\n            variants={{\n              hidden: { opacity: 0, y: 12, filter: \"blur(8px)\" },\n              visible: {\n                opacity: 1,\n                y: 0,\n                filter: \"blur(0px)\",\n                transition: reducedMotion\n                  ? { duration: 0 }\n                  : { duration: 0.45, ease: [0.21, 0.47, 0.32, 0.98] },\n              },\n            }}\n          >\n            {word}\n            {i < words.length - 1 && \" \"}\n          </motion.span>\n        ))}\n      </motion.span>\n    </Tag>\n  );\n}\n",
      "type": "registry:ui",
      "target": "components/velora/text-reveal.tsx"
    }
  ],
  "type": "registry:ui"
}