{
  "name": "glow-effect-card-mode",
  "type": "registry:ui",
  "componentName": "glow-effect-card-mode",
  "description": "Card with various glow effect modes and customization.",
  "files": [
    {
      "path": "glow-effect-card-mode.tsx",
      "content": "'use client';\nimport { motion } from 'motion/react';\nimport { TextMorph } from '@/components/core/text-morph';\nimport { GlowEffect } from '@/components/core/glow-effect';\nimport { useState } from 'react';\n\nexport function GlowEffectCardMode() {\n  const [isVisible, setIsVisible] = useState(false);\n\n  const handleLoad = () => {\n    if (isVisible) {\n      setIsVisible(false);\n      return;\n    }\n\n    setIsVisible(true);\n  };\n\n  return (\n    <div className='relative h-[200px] w-[300px]'>\n      <motion.div\n        className='pointer-events-none absolute inset-0'\n        animate={{\n          opacity: isVisible ? 1 : 0,\n        }}\n        transition={{\n          duration: 0.2,\n          ease: 'easeOut',\n        }}\n      >\n        <GlowEffect\n          colors={['#0894FF', '#C959DD', '#FF2E54', '#FF9004']}\n          mode='colorShift'\n          blur='medium'\n          duration={4}\n        />\n      </motion.div>\n      <div className='relative flex h-full flex-col items-end justify-end rounded-md border border-zinc-300/40 bg-zinc-100 px-4 py-3 dark:border-zinc-700/40 dark:bg-zinc-900'>\n        <button\n          className='relative ml-1 flex h-8 scale-100 select-none appearance-none items-center justify-center overflow-hidden rounded-lg border border-zinc-950/10 bg-white px-2 text-sm text-zinc-950 focus-visible:ring-2 active:scale-[0.96] dark:border-zinc-50/10'\n          type='button'\n          aria-label='Load'\n          onClick={handleLoad}\n        >\n          <TextMorph>{isVisible ? 'Submitting...' : 'Submit'}</TextMorph>\n        </button>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/core/glow-effect.tsx",
      "content": "'use client';\nimport { cn } from '@/lib/utils';\nimport { motion, type TargetAndTransition, type Transition } from 'motion/react';\n\nexport type GlowEffectProps = {\n  className?: string;\n  style?: React.CSSProperties;\n  colors?: string[];\n  mode?:\n    | 'rotate'\n    | 'pulse'\n    | 'breathe'\n    | 'colorShift'\n    | 'flowHorizontal'\n    | 'static';\n  blur?:\n    | number\n    | 'softest'\n    | 'soft'\n    | 'medium'\n    | 'strong'\n    | 'stronger'\n    | 'strongest'\n    | 'none';\n  transition?: Transition;\n  scale?: number;\n  duration?: number;\n};\n\nexport function GlowEffect({\n  className,\n  style,\n  colors = ['#FF5733', '#33FF57', '#3357FF', '#F1C40F'],\n  mode = 'rotate',\n  blur = 'medium',\n  transition,\n  scale = 1,\n  duration = 5,\n}: GlowEffectProps) {\n  const BASE_TRANSITION: Transition = {\n    repeat: Infinity,\n    duration: duration,\n    ease: 'linear',\n  };\n\n  const animations: Record<\n    NonNullable<GlowEffectProps['mode']>,\n    TargetAndTransition\n  > = {\n    rotate: {\n      background: [\n        `conic-gradient(from 0deg at 50% 50%, ${colors.join(', ')})`,\n        `conic-gradient(from 360deg at 50% 50%, ${colors.join(', ')})`,\n      ],\n      transition: {\n        ...(transition ?? BASE_TRANSITION),\n      },\n    },\n    pulse: {\n      background: colors.map(\n        (color) =>\n          `radial-gradient(circle at 50% 50%, ${color} 0%, transparent 100%)`\n      ),\n      scale: [1 * scale, 1.1 * scale, 1 * scale],\n      opacity: [0.5, 0.8, 0.5],\n      transition: {\n        ...(transition ?? {\n          ...BASE_TRANSITION,\n          repeatType: 'mirror',\n        }),\n      },\n    },\n    breathe: {\n      background: [\n        ...colors.map(\n          (color) =>\n            `radial-gradient(circle at 50% 50%, ${color} 0%, transparent 100%)`\n        ),\n      ],\n      scale: [1 * scale, 1.05 * scale, 1 * scale],\n      transition: {\n        ...(transition ?? {\n          ...BASE_TRANSITION,\n          repeatType: 'mirror',\n        }),\n      },\n    },\n    colorShift: {\n      background: colors.map((color, index) => {\n        const nextColor = colors[(index + 1) % colors.length];\n        return `conic-gradient(from 0deg at 50% 50%, ${color} 0%, ${nextColor} 50%, ${color} 100%)`;\n      }),\n      transition: {\n        ...(transition ?? {\n          ...BASE_TRANSITION,\n          repeatType: 'mirror',\n        }),\n      },\n    },\n    flowHorizontal: {\n      background: colors.map((color) => {\n        const nextColor = colors[(colors.indexOf(color) + 1) % colors.length];\n        return `linear-gradient(to right, ${color}, ${nextColor})`;\n      }),\n      transition: {\n        ...(transition ?? {\n          ...BASE_TRANSITION,\n          repeatType: 'mirror',\n        }),\n      },\n    },\n    static: {\n      background: `linear-gradient(to right, ${colors.join(', ')})`,\n    },\n  };\n\n  const getBlurClass = (blur: GlowEffectProps['blur']) => {\n    if (typeof blur === 'number') {\n      return `blur-[${blur}px]`;\n    }\n\n    const presets = {\n      softest: 'blur-xs',\n      soft: 'blur-sm',\n      medium: 'blur-md',\n      strong: 'blur-lg',\n      stronger: 'blur-xl',\n      strongest: 'blur-xl',\n      none: 'blur-none',\n    };\n\n    return presets[blur as keyof typeof presets];\n  };\n\n  return (\n    <motion.div\n      style={\n        {\n          ...style,\n          '--scale': scale,\n          willChange: 'transform',\n          backfaceVisibility: 'hidden',\n        } as React.CSSProperties\n      }\n      animate={animations[mode]}\n      className={cn(\n        'pointer-events-none absolute inset-0 h-full w-full',\n        'scale-[var(--scale)] transform-gpu',\n        getBlurClass(blur),\n        className\n      )}\n    />\n  );\n}\n",
      "type": "registry:ui"
    },
    {
      "path": "components/core/text-morph.tsx",
      "content": "'use client';\nimport { cn } from '@/lib/utils';\nimport { AnimatePresence, motion, Transition, Variants } from 'motion/react';\nimport { useMemo, useId } from 'react';\n\nexport type TextMorphProps = {\n  children: string;\n  as?: React.ElementType;\n  className?: string;\n  style?: React.CSSProperties;\n  variants?: Variants;\n  transition?: Transition;\n};\n\nexport function TextMorph({\n  children,\n  as: Component = 'p',\n  className,\n  style,\n  variants,\n  transition,\n}: TextMorphProps) {\n  const uniqueId = useId();\n\n  const characters = useMemo(() => {\n    const charCounts: Record<string, number> = {};\n\n    return children.split('').map((char) => {\n      const lowerChar = char.toLowerCase();\n      charCounts[lowerChar] = (charCounts[lowerChar] || 0) + 1;\n\n      return {\n        id: `${uniqueId}-${lowerChar}${charCounts[lowerChar]}`,\n        label: char === ' ' ? '\\u00A0' : char,\n      };\n    });\n  }, [children, uniqueId]);\n\n  const defaultVariants: Variants = {\n    initial: { opacity: 0 },\n    animate: { opacity: 1 },\n    exit: { opacity: 0 },\n  };\n\n  const defaultTransition: Transition = {\n    type: 'spring',\n    stiffness: 280,\n    damping: 18,\n    mass: 0.3,\n  };\n\n  return (\n    <Component className={cn(className)} aria-label={children} style={style}>\n      <AnimatePresence mode='popLayout' initial={false}>\n        {characters.map((character) => (\n          <motion.span\n            key={character.id}\n            layoutId={character.id}\n            className='inline-block'\n            aria-hidden='true'\n            initial='initial'\n            animate='animate'\n            exit='exit'\n            variants={variants || defaultVariants}\n            transition={transition || defaultTransition}\n          >\n            {character.label}\n          </motion.span>\n        ))}\n      </AnimatePresence>\n    </Component>\n  );\n}\n",
      "type": "registry:ui"
    }
  ]
}