{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "gradient-text",
  "title": "Gradient Text",
  "description": "Text with a living highlight: a drifting shimmer or a pointer spotlight.",
  "dependencies": [
    "radix-ui"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.cuelark.com/r/theme.json",
    "https://ui.cuelark.com/r/motion.json"
  ],
  "files": [
    {
      "path": "src/registry/cuelark/ui/gradient-text.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Slot } from \"radix-ui\";\n\nimport { gsap, motionScale, useGSAP } from \"@/lib/motion\";\nimport { cn } from \"@/lib/utils\";\n\ntype GradientTextProps = React.ComponentProps<\"span\"> & {\n  asChild?: boolean;\n  /**\n   * `drift`: a slow, endless shimmer through the words.\n   * `spotlight`: the color lives under the pointer, as if lighting the text with a torch (falls back to drift on touch).\n   */\n  variant?: \"drift\" | \"spotlight\";\n  /** Highlight color; defaults to `--ring`: the signal at a strength that stays readable on light backgrounds. */\n  color?: string;\n  /** Seconds per sweep (drift). */\n  duration?: number;\n};\n\n/**\n * Text with a living highlight: a shimmer that drifts through it, or a spotlight that follows the pointer\n * (GSAP). The base color is your foreground, so it always reads; the text stays real, selectable and indexed.\n */\nfunction GradientText({\n  asChild,\n  variant = \"drift\",\n  color = \"var(--ring)\",\n  duration = 3.2,\n  className,\n  style,\n  onPointerMove,\n  onPointerLeave,\n  ...props\n}: GradientTextProps) {\n  const ref = React.useRef<HTMLSpanElement>(null);\n\n  useGSAP(\n    () => {\n      const el = ref.current;\n      if (!el || !motionScale(el)) return;\n      if (variant === \"drift\") {\n        gsap.fromTo(el, { \"--gx\": \"-30%\" }, { \"--gx\": \"130%\", duration, ease: \"power1.inOut\", repeat: -1, repeatDelay: 0.6 });\n      } else {\n        gsap.set(el, { \"--go\": 0, \"--gx\": \"50%\" });\n      }\n    },\n    { scope: ref, dependencies: [variant, duration] },\n  );\n\n  const Comp = asChild ? Slot.Root : \"span\";\n  return (\n    <Comp\n      ref={ref}\n      data-slot=\"gradient-text\"\n      data-variant={variant}\n      className={cn(\"bg-clip-text text-transparent [-webkit-background-clip:text]\", className)}\n      style={{\n        backgroundImage: `radial-gradient(${variant === \"drift\" ? \"38% 180%\" : \"28% 200%\"} at var(--gx, 50%) 50%, color-mix(in oklch, ${color} calc(var(--go, 1) * 100%), var(--foreground)) 0%, color-mix(in oklch, ${color} calc(var(--go, 1) * 100%), var(--foreground)) 30%, var(--foreground) 100%)`,\n        ...style,\n      }}\n      onPointerMove={(e: React.PointerEvent<HTMLSpanElement>) => {\n        onPointerMove?.(e);\n        if (variant !== \"spotlight\" || !motionScale(e.currentTarget)) return;\n        const r = e.currentTarget.getBoundingClientRect();\n        gsap.to(e.currentTarget, { \"--gx\": `${((e.clientX - r.left) / r.width) * 100}%`, \"--go\": 1, duration: 0.35, ease: \"cue\", overwrite: \"auto\" });\n      }}\n      onPointerLeave={(e: React.PointerEvent<HTMLSpanElement>) => {\n        onPointerLeave?.(e);\n        if (variant === \"spotlight\") gsap.to(e.currentTarget, { \"--go\": 0, duration: 0.3, ease: \"cue\", overwrite: \"auto\" });\n      }}\n      {...props}\n    />\n  );\n}\n\nexport { GradientText };\nexport type { GradientTextProps };\n",
      "type": "registry:ui"
    }
  ],
  "docs": "Docs and examples: https://ui.cuelark.com/components/gradient-text",
  "categories": [
    "effects"
  ],
  "type": "registry:ui"
}