{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "text-reveal",
  "type": "registry:component",
  "title": "Text reveal",
  "description": "A paragraph that lights up word by word as it scrolls through the viewport, from muted to full ink, using Motion scroll progress. Still text for reduced motion.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/premium/text-reveal.tsx",
      "type": "registry:ui",
      "target": "components/ui/text-reveal.tsx",
      "content": "\"use client\"\nimport * as React from \"react\"\nimport { motion, useReducedMotion, useScroll, useTransform, type MotionValue } from \"motion/react\"\nimport { cn } from \"@/lib/utils\"\n\n/**\n * A paragraph that lights up word by word as it scrolls through the\n * viewport, from muted to full ink. The words are real text in order, so\n * search engines and screen readers read it normally.\n */\ntype TextRevealProps = {\n  text?: string\n  className?: string\n}\n\nfunction Word({ word, progress, range }: { word: string; progress: MotionValue<number>; range: [number, number] }) {\n  const opacity = useTransform(progress, range, [0.18, 1])\n  return (\n    <motion.span style={{ opacity }} className=\"inline-block\">\n      {word}&nbsp;\n    </motion.span>\n  )\n}\n\nfunction TextReveal({\n  text = \"Most interfaces are assembled. The good ones are drawn: every border, shadow and word placed on purpose, so the product feels calm even when the work is hard.\",\n  className,\n}: TextRevealProps) {\n  const reduce = useReducedMotion()\n  const ref = React.useRef<HTMLParagraphElement>(null)\n  const { scrollYProgress } = useScroll({ target: ref, offset: [\"start 0.85\", \"end 0.4\"] })\n  const words = text.split(\" \")\n  return (\n    <p ref={ref} data-slot=\"text-reveal\" className={cn(\"max-w-2xl text-2xl leading-[1.35] font-medium tracking-[-0.03em] text-fg sm:text-3xl\", className)}>\n      {reduce\n        ? text\n        : words.map((w, i) => <Word key={i} word={w} progress={scrollYProgress} range={[i / words.length, (i + 1) / words.length]} />)}\n    </p>\n  )\n}\n\nexport { TextReveal }\nexport type { TextRevealProps }\n"
    }
  ]
}
