{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "cyber-glitch-text",
  "type": "registry:ui",
  "dependencies": [
    "framer-motion"
  ],
  "files": [
    {
      "path": "components/ui/cyber-glitch-text.tsx",
      "content": "\"use client\";\n\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { motion } from \"framer-motion\";\n\nconst CHARS = \"!<>-_\\\\/[]{}—=+*^?#_\";\n\ninterface CyberGlitchTextProps {\n  text: string;\n  className?: string;\n  scrambleOnMount?: boolean;\n  scrambleDuration?: number;\n}\n\nexport function CyberGlitchText({\n  text,\n  className,\n  scrambleOnMount = true,\n  scrambleDuration = 40,\n}: CyberGlitchTextProps) {\n  const [displayText, setDisplayText] = useState(text);\n  const [isHovered, setIsHovered] = useState(false);\n  const intervalRef = useRef<NodeJS.Timeout | null>(null);\n\n  const scramble = () => {\n    let iteration = 0;\n    clearInterval(intervalRef.current as NodeJS.Timeout);\n\n    intervalRef.current = setInterval(() => {\n      setDisplayText((currentText) =>\n        text\n          .split(\"\")\n          .map((letter, index) => {\n            if (index < iteration) {\n              return text[index];\n            }\n            return CHARS[Math.floor(Math.random() * CHARS.length)];\n          })\n          .join(\"\")\n      );\n\n      if (iteration >= text.length) {\n        clearInterval(intervalRef.current as NodeJS.Timeout);\n      }\n\n      iteration += 1 / 3;\n    }, scrambleDuration);\n  };\n\n  useEffect(() => {\n    if (scrambleOnMount) {\n      scramble();\n    }\n    return () => clearInterval(intervalRef.current as NodeJS.Timeout);\n  }, [text, scrambleOnMount]);\n\n  return (\n    <div\n      className={cn(\"relative inline-block group\", className)}\n      onMouseEnter={() => {\n        setIsHovered(true);\n        scramble();\n      }}\n      onMouseLeave={() => setIsHovered(false)}\n    >\n      {/* Base Text */}\n      <span className=\"relative z-10\">{displayText}</span>\n\n      {/* Glitch Layers for Chromatic Aberration */}\n      {isHovered && (\n        <>\n          <motion.span\n            className=\"absolute top-0 left-[-2px] z-0 text-red-500 opacity-70 mix-blend-screen\"\n            initial={{ x: 0, opacity: 0 }}\n            animate={{ x: [-2, 2, -1, 3, 0], opacity: [0, 0.8, 0.4, 0.9, 0] }}\n            transition={{ duration: 0.2, repeat: Infinity, repeatType: \"mirror\" }}\n            aria-hidden=\"true\"\n          >\n            {displayText}\n          </motion.span>\n          <motion.span\n            className=\"absolute top-0 left-[2px] z-0 text-blue-500 opacity-70 mix-blend-screen\"\n            initial={{ x: 0, opacity: 0 }}\n            animate={{ x: [2, -2, 1, -3, 0], opacity: [0, 0.8, 0.4, 0.9, 0] }}\n            transition={{ duration: 0.2, repeat: Infinity, repeatType: \"mirror\", delay: 0.05 }}\n            aria-hidden=\"true\"\n          >\n            {displayText}\n          </motion.span>\n          \n          {/* Slice Glitch Overlay */}\n          <motion.div\n            className=\"absolute inset-0 bg-white/10 dark:bg-black/10 z-20 pointer-events-none mix-blend-overlay\"\n            initial={{ top: \"0%\", height: \"0%\" }}\n            animate={{ top: [\"0%\", \"40%\", \"80%\", \"0%\"], height: [\"2px\", \"5px\", \"1px\", \"0px\"] }}\n            transition={{ duration: 0.3, repeat: Infinity }}\n          />\n        </>\n      )}\n    </div>\n  );\n}\n",
      "type": "registry:ui",
      "target": "components/ui/cyber-glitch-text.tsx"
    }
  ]
}