{"name":"animated-card","title":"Animated Card","description":"A content card with a pointer-following spotlight, a spring lift on hover and a nudging arrow.","type":"component","dependencies":["clsx","framer-motion","lucide-react","tailwind-merge"],"registryDependencies":[],"files":[{"path":"components/ui/animated-card.tsx","type":"component","content":"import type { PointerEvent, ReactNode } from \"react\";\nimport { motion, useMotionTemplate, useMotionValue, useReducedMotion } from \"framer-motion\";\nimport { ArrowUpRight, Sparkles } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface AnimatedCardProps {\n  title?: string;\n  description?: string;\n  /** Small label shown in the top-right corner. */\n  eyebrow?: string;\n  /** When set, the action is rendered as a link. */\n  href?: string;\n  actionLabel?: string;\n  className?: string;\n  children?: ReactNode;\n}\n\nconst actionClassName =\n  \"relative mt-6 inline-flex items-center gap-1.5 rounded-md text-sm font-medium text-zinc-100 outline-none focus-visible:ring-2 focus-visible:ring-white/60\";\n\n/**\n * A content card with a pointer-following spotlight, a spring lift on hover\n * and a nudging arrow. Honors `prefers-reduced-motion`.\n */\nexport function AnimatedCard({\n  title = \"Animated card\",\n  description = \"A card with a spotlight that follows the pointer.\",\n  eyebrow,\n  href,\n  actionLabel = \"Learn more\",\n  className,\n  children,\n}: AnimatedCardProps) {\n  const reduceMotion = useReducedMotion();\n  const pointerX = useMotionValue(0);\n  const pointerY = useMotionValue(0);\n  const spotlight = useMotionTemplate`radial-gradient(260px circle at ${pointerX}px ${pointerY}px, rgba(255, 255, 255, 0.1), transparent 70%)`;\n\n  function handlePointerMove(event: PointerEvent<HTMLElement>) {\n    const bounds = event.currentTarget.getBoundingClientRect();\n    pointerX.set(event.clientX - bounds.left);\n    pointerY.set(event.clientY - bounds.top);\n  }\n\n  const action = (\n    <>\n      {actionLabel}\n      <ArrowUpRight\n        className=\"size-4 transition-transform duration-200 group-hover:-translate-y-0.5 group-hover:translate-x-0.5\"\n        aria-hidden=\"true\"\n      />\n    </>\n  );\n\n  return (\n    <motion.article\n      onPointerMove={handlePointerMove}\n      initial={reduceMotion ? false : { opacity: 0, y: 12 }}\n      animate={{ opacity: 1, y: 0 }}\n      whileHover={reduceMotion ? undefined : { y: -4 }}\n      transition={{ type: \"spring\", stiffness: 300, damping: 24 }}\n      className={cn(\n        \"group relative w-full max-w-sm overflow-hidden rounded-2xl border border-white/10 bg-zinc-950 p-5 text-left shadow-lg shadow-black/30 sm:p-6\",\n        className,\n      )}\n    >\n      <motion.div\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-0 opacity-0 transition-opacity duration-300 group-hover:opacity-100\"\n        style={{ background: spotlight }}\n      />\n\n      <div className=\"relative flex items-start justify-between gap-4\">\n        <span className=\"flex size-10 items-center justify-center rounded-xl border border-white/10 bg-white/5 text-zinc-100 transition-colors duration-300 group-hover:border-white/20\">\n          <Sparkles className=\"size-5\" aria-hidden=\"true\" />\n        </span>\n        {eyebrow ? (\n          <span className=\"rounded-full border border-white/10 px-2.5 py-1 text-[11px] font-medium uppercase tracking-wider text-zinc-400\">\n            {eyebrow}\n          </span>\n        ) : null}\n      </div>\n\n      <h3 className=\"relative mt-5 text-lg font-semibold tracking-tight text-zinc-50 sm:text-xl\">{title}</h3>\n      <p className=\"relative mt-2 text-sm leading-6 text-zinc-400\">{description}</p>\n\n      {children ? <div className=\"relative mt-4\">{children}</div> : null}\n\n      {href ? (\n        <a href={href} className={actionClassName}>\n          {action}\n        </a>\n      ) : (\n        <span className={actionClassName}>{action}</span>\n      )}\n    </motion.article>\n  );\n}\n\nexport default AnimatedCard;\n"}],"examples":[],"cssRequirements":[],"tailwindRequirements":[],"meta":{"componentName":"AnimatedCard","importPath":"@/components/ui/animated-card","tags":["animated","interactive","dark","responsive","hover","icons"],"sourceUrl":null,"sourceName":"Component Library","author":"Component Library","license":"MIT","publishedAt":"2026-10-12T11:32:24.251Z","updatedAt":"2026-10-12T13:22:42.175Z"}}