{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "spotlight-card",
  "title": "Spotlight Card",
  "description": "Card with a radial spotlight and glowing border that track the cursor.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/new-york/spotlight-card/spotlight-card.tsx",
      "content": "\"use client\"\n\nimport { motion, useMotionValue, useSpring, type MotionValue } from \"motion/react\"\nimport { cn } from \"@/lib/utils\"\n\nexport interface SpotlightCardProps extends React.HTMLAttributes<HTMLDivElement> {\n  children: React.ReactNode\n  /** Spotlight radius in px. Default: 280 */\n  size?: number\n  /** Spotlight color (any CSS color). Default: 10% foreground */\n  color?: string\n  /** Also light up the card border. Default: true */\n  border?: boolean\n  /** Border highlight color. Default: 50% foreground */\n  borderColor?: string\n}\n\nexport function SpotlightCard({\n  children,\n  size = 280,\n  color = \"color-mix(in oklab, var(--foreground) 10%, transparent)\",\n  border = true,\n  borderColor = \"color-mix(in oklab, var(--foreground) 50%, transparent)\",\n  className,\n  onPointerMove,\n  onPointerEnter,\n  onPointerLeave,\n  ...props\n}: SpotlightCardProps) {\n  const x = useMotionValue(-size)\n  const y = useMotionValue(-size)\n  const opacity = useSpring(0, { stiffness: 200, damping: 30 })\n\n  // Flat, hard-edged light disc; its visible radius roughly matches the old soft falloff.\n  const disc = size * 1.1\n\n  return (\n    <div\n      {...props}\n      className={cn(\n        \"group relative overflow-hidden rounded-2xl border bg-card text-card-foreground\",\n        className\n      )}\n      onPointerMove={(e) => {\n        const rect = e.currentTarget.getBoundingClientRect()\n        x.set(e.clientX - rect.left)\n        y.set(e.clientY - rect.top)\n        onPointerMove?.(e)\n      }}\n      onPointerEnter={(e) => {\n        opacity.set(1)\n        onPointerEnter?.(e)\n      }}\n      onPointerLeave={(e) => {\n        opacity.set(0)\n        onPointerLeave?.(e)\n      }}\n    >\n      {border && (\n        // Masked to a 1px ring so only the border lights up.\n        // Alpha mask made of solid, hard-edged layers (content-box cut-out), not a color gradient.\n        <motion.div\n          aria-hidden=\"true\"\n          className=\"pointer-events-none absolute inset-0 overflow-hidden rounded-[inherit] p-px\"\n          style={{\n            opacity,\n            WebkitMask: \"linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0)\",\n            mask: \"linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0)\",\n          }}\n        >\n          <Disc x={x} y={y} diameter={disc} color={borderColor} />\n        </motion.div>\n      )}\n      <motion.div aria-hidden=\"true\" className=\"pointer-events-none absolute inset-0 overflow-hidden\" style={{ opacity }}>\n        <Disc x={x} y={y} diameter={disc} color={color} />\n      </motion.div>\n      <div className=\"relative\">{children}</div>\n    </div>\n  )\n}\n\n/** Solid circle centred on the pointer. */\nfunction Disc({ x, y, diameter, color }: { x: MotionValue<number>; y: MotionValue<number>; diameter: number; color: string }) {\n  return (\n    <motion.div className=\"absolute top-0 left-0 size-0\" style={{ x, y }}>\n      <div\n        className=\"absolute -translate-x-1/2 -translate-y-1/2 rounded-full\"\n        style={{ width: diameter, height: diameter, backgroundColor: color }}\n      />\n    </motion.div>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "docs": "Docs, live playground and every prop: https://trytweenly.vercel.app/docs/components/spotlight-card",
  "type": "registry:component"
}