{
	"$schema": "https://ui.shadcn.com/schema/registry-item.json",
	"name": "GradientText-TS-CSS",
	"title": "GradientText",
	"description": "Animated gradient sweep across live text with speed and color control.",
	"type": "registry:component",
	"files": [
		{
			"type": "registry:file",
			"path": "GradientText.css",
			"target": "@components/GradientText.css",
			"content": ".animated-gradient-text {\n  position: relative;\n  margin: 0 auto;\n  display: flex;\n  max-width: fit-content;\n  flex-direction: row;\n  align-items: center;\n  justify-content: center;\n  border-radius: 1.25rem;\n  font-weight: 500;\n  backdrop-filter: blur(10px);\n  transition: box-shadow 0.5s ease-out;\n  overflow: hidden;\n  cursor: pointer;\n}\n\n.gradient-overlay {\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  background-size: 300% 100%;\n  animation: gradient linear infinite;\n  border-radius: inherit;\n  z-index: 0;\n  pointer-events: none;\n}\n\n.gradient-overlay::before {\n  content: '';\n  position: absolute;\n  left: 0;\n  top: 0;\n  border-radius: inherit;\n  width: calc(100% - 2px);\n  height: calc(100% - 2px);\n  left: 50%;\n  top: 50%;\n  transform: translate(-50%, -50%);\n  background-color: #120F17;\n  z-index: -1;\n}\n\n@keyframes gradient {\n  0% {\n    background-position: 0% 50%;\n  }\n\n  50% {\n    background-position: 100% 50%;\n  }\n\n  100% {\n    background-position: 0% 50%;\n  }\n}\n\n.text-content {\n  display: inline-block;\n  position: relative;\n  z-index: 2;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  color: transparent;\n  animation: gradient linear infinite;\n}\n"
		},
		{
			"type": "registry:component",
			"path": "GradientText.tsx",
			"content": "import { useState, useCallback, useEffect, useRef, type ReactNode } from 'react';\nimport { motion, useMotionValue, useAnimationFrame, useTransform } from 'motion/react';\nimport './GradientText.css';\n\ninterface GradientTextProps {\n  children: ReactNode;\n  className?: string;\n  colors?: string[];\n  animationSpeed?: number;\n  showBorder?: boolean;\n  direction?: 'horizontal' | 'vertical' | 'diagonal';\n  pauseOnHover?: boolean;\n  yoyo?: boolean;\n}\n\nexport default function GradientText({\n  children,\n  className = '',\n  colors = ['#5227FF', '#FF9FFC', '#B497CF'],\n  animationSpeed = 8,\n  showBorder = false,\n  direction = 'horizontal',\n  pauseOnHover = false,\n  yoyo = true\n}: GradientTextProps) {\n  const [isPaused, setIsPaused] = useState(false);\n  const progress = useMotionValue(0);\n  const elapsedRef = useRef(0);\n  const lastTimeRef = useRef<number | null>(null);\n\n  const animationDuration = animationSpeed * 1000;\n\n  useAnimationFrame(time => {\n    if (isPaused) {\n      lastTimeRef.current = null;\n      return;\n    }\n\n    if (lastTimeRef.current === null) {\n      lastTimeRef.current = time;\n      return;\n    }\n\n    const deltaTime = time - lastTimeRef.current;\n    lastTimeRef.current = time;\n    elapsedRef.current += deltaTime;\n\n    if (yoyo) {\n      const fullCycle = animationDuration * 2;\n      const cycleTime = elapsedRef.current % fullCycle;\n\n      if (cycleTime < animationDuration) {\n        progress.set((cycleTime / animationDuration) * 100);\n      } else {\n        progress.set(100 - ((cycleTime - animationDuration) / animationDuration) * 100);\n      }\n    } else {\n      // Continuously increase position for seamless looping\n      progress.set((elapsedRef.current / animationDuration) * 100);\n    }\n  });\n\n  useEffect(() => {\n    elapsedRef.current = 0;\n    progress.set(0);\n  }, [animationSpeed, yoyo]);\n\n  const backgroundPosition = useTransform(progress, p => {\n    if (direction === 'horizontal') {\n      return `${p}% 50%`;\n    } else if (direction === 'vertical') {\n      return `50% ${p}%`;\n    } else {\n      // For diagonal, move only horizontally to avoid interference patterns\n      return `${p}% 50%`;\n    }\n  });\n\n  const handleMouseEnter = useCallback(() => {\n    if (pauseOnHover) setIsPaused(true);\n  }, [pauseOnHover]);\n\n  const handleMouseLeave = useCallback(() => {\n    if (pauseOnHover) setIsPaused(false);\n  }, [pauseOnHover]);\n\n  const gradientAngle =\n    direction === 'horizontal' ? 'to right' : direction === 'vertical' ? 'to bottom' : 'to bottom right';\n  // Duplicate first color at the end for seamless looping\n  const gradientColors = [...colors, colors[0]].join(', ');\n\n  const gradientStyle = {\n    backgroundImage: `linear-gradient(${gradientAngle}, ${gradientColors})`,\n    backgroundSize: direction === 'horizontal' ? '300% 100%' : direction === 'vertical' ? '100% 300%' : '300% 300%',\n    backgroundRepeat: 'repeat'\n  };\n\n  return (\n    <motion.div\n      className={`animated-gradient-text ${showBorder ? 'with-border' : ''} ${className}`}\n      onMouseEnter={handleMouseEnter}\n      onMouseLeave={handleMouseLeave}\n    >\n      {showBorder && <motion.div className=\"gradient-overlay\" style={{ ...gradientStyle, backgroundPosition }} />}\n      <motion.div className=\"text-content\" style={{ ...gradientStyle, backgroundPosition }}>\n        {children}\n      </motion.div>\n    </motion.div>\n  );\n}\n"
		}
	],
	"registryDependencies": [],
	"dependencies": [
		"motion@^12.23.12"
	]
}