{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "card-spotlight",
  "title": "Spotlight Card",
  "description": "Card with a primary-tinted spotlight that follows the pointer while the hairline border brightens beneath it. Touch and keyboard users get a designed fallback glow.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/cards/card-spotlight/card-spotlight.tsx",
      "content": "'use client'\n\nimport { forwardRef, useEffect, useState } from 'react'\nimport { motion, useMotionTemplate, useMotionValue, useReducedMotion } from 'motion/react'\nimport { cn } from '@/lib/utils'\n\nexport interface CardSpotlightProps extends React.HTMLAttributes<HTMLDivElement> {\n  /** spotlight radius in px */\n  radius?: number\n  children: React.ReactNode\n}\n\n/**\n * A card whose surface answers the pointer: a soft primary-tinted spotlight\n * follows the cursor and the hairline border brightens beneath it.\n * Pointer tracking is disabled on touch devices and under reduced motion,\n * keyboard focus shows a centered glow instead.\n */\nexport const CardSpotlight = forwardRef<HTMLDivElement, CardSpotlightProps>(function CardSpotlight(\n  { radius = 260, className, children, ...props },\n  ref\n) {\n  const reduced = useReducedMotion()\n  const [finePointer, setFinePointer] = useState(false)\n  const x = useMotionValue(0)\n  const y = useMotionValue(0)\n  const [hovered, setHovered] = useState(false)\n\n  useEffect(() => {\n    const mq = window.matchMedia('(hover: hover) and (pointer: fine)')\n    setFinePointer(mq.matches)\n    const onChange = (e: MediaQueryListEvent) => setFinePointer(e.matches)\n    mq.addEventListener('change', onChange)\n    return () => mq.removeEventListener('change', onChange)\n  }, [])\n\n  const tracking = finePointer && !reduced\n\n  // shape via mask (black/transparent, representation-neutral), color via\n  // tokenized bg utilities so the effect works on Tailwind v3 AND v4 themes\n  const spotlightMask = useMotionTemplate`radial-gradient(${radius}px circle at ${x}px ${y}px, black, transparent 70%)`\n  const borderGlowMask = useMotionTemplate`radial-gradient(${Math.round(radius * 0.75)}px circle at ${x}px ${y}px, black, transparent 70%)`\n\n  function onPointerMove(e: React.PointerEvent<HTMLDivElement>) {\n    const rect = e.currentTarget.getBoundingClientRect()\n    x.set(e.clientX - rect.left)\n    y.set(e.clientY - rect.top)\n  }\n\n  return (\n    <div\n      ref={ref}\n      onPointerMove={tracking ? onPointerMove : undefined}\n      onPointerEnter={tracking ? () => setHovered(true) : undefined}\n      onPointerLeave={tracking ? () => setHovered(false) : undefined}\n      className={cn(\n        'group relative rounded-2xl border border-border/60 bg-card p-px',\n        'focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background',\n        className\n      )}\n      {...props}\n    >\n      {/* border glow tracks the pointer along the hairline */}\n      <motion.div\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-0 rounded-2xl bg-primary/50 transition-opacity duration-300\"\n        style={{ maskImage: borderGlowMask, WebkitMaskImage: borderGlowMask, opacity: tracking && hovered ? 1 : 0 }}\n      />\n      <div className=\"relative rounded-2xl bg-card\">\n        {/* surface spotlight */}\n        <motion.div\n          aria-hidden=\"true\"\n          className=\"pointer-events-none absolute inset-0 rounded-[inherit] bg-primary/10 transition-opacity duration-300\"\n          style={{ maskImage: spotlightMask, WebkitMaskImage: spotlightMask, opacity: tracking && hovered ? 1 : 0 }}\n        />\n        {/* keyboard/touch fallback: quiet centered glow */}\n        <div\n          aria-hidden=\"true\"\n          className={cn(\n            'pointer-events-none absolute inset-0 rounded-[inherit] bg-primary/10 opacity-0 transition-opacity duration-300',\n            '[mask-image:radial-gradient(400px_circle_at_50%_0%,black,transparent_70%)]',\n            !tracking && 'group-hover:opacity-100 group-focus-within:opacity-100'\n          )}\n        />\n        <div className=\"relative\">{children}</div>\n      </div>\n    </div>\n  )\n})\n",
      "type": "registry:ui"
    }
  ],
  "docs": "Docs & live preview: https://cleverops.com.au/components/cards/card-spotlight",
  "categories": [
    "cards"
  ],
  "type": "registry:ui"
}