{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "word-rotate",
  "title": "Word Rotate",
  "description": "Swaps a single word on a quiet vertical roll.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "src/components/velora/word-rotate.tsx",
      "content": "\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\n\nimport { cn } from \"@/lib/utils\";\n\ninterface WordRotateProps {\n  words: string[];\n  /** Seconds each word is held */\n  interval?: number;\n  className?: string;\n}\n\n/**\n * Swaps a single word on a vertical roll. Lighter than Flip Words — no blur,\n * no spring — for headlines that need the effect to stay quiet.\n */\nexport function WordRotate({\n  words,\n  interval = 2.5,\n  className,\n}: WordRotateProps) {\n  const [index, setIndex] = useState(0);\n  const reducedMotion = useReducedMotion();\n  // Held while hovered or focused so the word can be read (WCAG 2.2.2).\n  const paused = useRef(false);\n\n  useEffect(() => {\n    // Reduced motion: no rotation at all, the first word stays put.\n    if (words.length < 2 || reducedMotion !== false) return;\n    const id = window.setInterval(() => {\n      if (paused.current || document.hidden) return;\n      setIndex((i) => (i + 1) % words.length);\n    }, interval * 1000);\n    return () => window.clearInterval(id);\n  }, [words.length, interval, reducedMotion]);\n\n  const pause = () => {\n    paused.current = true;\n  };\n  const resume = () => {\n    paused.current = false;\n  };\n\n  return (\n    <span\n      data-slot=\"word-rotate\"\n      onMouseEnter={pause}\n      onMouseLeave={resume}\n      onFocus={pause}\n      onBlur={resume}\n      className=\"inline-grid overflow-hidden align-bottom\"\n    >\n      <span className=\"sr-only\">{words.join(\", \")}</span>\n      <AnimatePresence mode=\"wait\" initial={false}>\n        <motion.span\n          key={index}\n          aria-hidden\n          initial={{ y: \"100%\", opacity: 0 }}\n          animate={{ y: 0, opacity: 1 }}\n          exit={{ y: \"-100%\", opacity: 0 }}\n          transition={{\n            duration: reducedMotion ? 0 : 0.32,\n            ease: [0.22, 1, 0.36, 1],\n          }}\n          className={cn(\"col-start-1 row-start-1\", className)}\n        >\n          {words[index]}\n        </motion.span>\n      </AnimatePresence>\n    </span>\n  );\n}\n",
      "type": "registry:ui",
      "target": "components/velora/word-rotate.tsx"
    }
  ],
  "type": "registry:ui"
}