{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "bento-grid",
  "title": "Bento Grid",
  "description": "A premium interactive Bento Grid component",
  "dependencies": [
    "framer-motion",
    "lucide-react"
  ],
  "files": [
    {
      "path": "app/registry/bento-grid/bento-grid.tsx",
      "content": "import { cn } from \"@/lib/utils\"\nimport { motion } from \"framer-motion\"\nimport React, { ReactNode } from \"react\"\n\nexport interface BentoGridProps {\n  className?: string\n  children?: ReactNode\n}\n\nconst containerVariants = {\n  hidden: {},\n  visible: {\n    transition: {\n      staggerChildren: 0.1,\n    },\n  },\n}\n\nexport function BentoGrid({ className, children }: BentoGridProps) {\n  return (\n    <motion.div\n      variants={containerVariants}\n      initial=\"hidden\"\n      whileInView=\"visible\"\n      viewport={{ once: true, margin: \"-50px\" }}\n      className={cn(\n        \"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 w-full max-w-7xl mx-auto\",\n        className\n      )}\n    >\n      {children}\n    </motion.div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/spectrumui/bento-grid.tsx"
    },
    {
      "path": "app/registry/bento-grid/bento-card.tsx",
      "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { motion, useMotionValue, useSpring, useTransform, type Transition } from \"framer-motion\"\nimport React, { ReactNode, useRef, useState } from \"react\"\nimport { Spotlight } from \"./spotlight\"\nimport { BorderBeam } from \"./border-beam\"\n\nconst SPRING_TACTILE: Transition = {\n  type: \"spring\",\n  stiffness: 400,\n  damping: 25,\n  mass: 1,\n}\n\nconst SPRING_ENTRANCE: Transition = {\n  type: \"spring\",\n  stiffness: 260,\n  damping: 20,\n}\n\nexport interface BentoCardProps {\n  className?: string\n  children?: ReactNode\n  title?: ReactNode\n  description?: ReactNode\n  icon?: ReactNode\n  background?: ReactNode\n  colSpan?: number\n  rowSpan?: number\n  tilt?: boolean\n  spotlight?: boolean\n  borderAnim?: boolean\n}\n\nconst itemVariants = {\n  hidden: { opacity: 0, y: 12, scale: 0.98 },\n  visible: { \n    opacity: 1, \n    y: 0, \n    scale: 1, \n    transition: SPRING_ENTRANCE \n  },\n  hover: {\n    scale: 1.01,\n    y: -4,\n    transition: SPRING_TACTILE\n  }\n}\n\nexport function BentoCard({\n  className,\n  children,\n  title,\n  description,\n  icon,\n  background,\n  colSpan = 1,\n  rowSpan = 1,\n  tilt = false,\n  spotlight = true,\n  borderAnim = true,\n}: BentoCardProps) {\n  const ref = useRef<HTMLDivElement>(null)\n  const [isHovered, setIsHovered] = useState(false)\n\n  const spotlightX = useMotionValue(0)\n  const spotlightY = useMotionValue(0)\n\n  const tiltX = useMotionValue(0)\n  const tiltY = useMotionValue(0)\n\n  // Smooth springs for tilt\n  const smoothTiltX = useSpring(tiltX, { stiffness: 300, damping: 30 })\n  const smoothTiltY = useSpring(tiltY, { stiffness: 300, damping: 30 })\n\n  const rotateX = useTransform(smoothTiltY, [-150, 150], [5, -5])\n  const rotateY = useTransform(smoothTiltX, [-150, 150], [-5, 5])\n\n  function handleMouseMove(e: React.MouseEvent<HTMLDivElement>) {\n    if (!ref.current) return\n    const rect = ref.current.getBoundingClientRect()\n    \n    // For Spotlight (relative to top left)\n    spotlightX.set(e.clientX - rect.left)\n    spotlightY.set(e.clientY - rect.top)\n\n    // For Tilt (relative to center)\n    if (tilt) {\n      const centerX = rect.width / 2\n      const centerY = rect.height / 2\n      tiltX.set(e.clientX - rect.left - centerX)\n      tiltY.set(e.clientY - rect.top - centerY)\n    }\n  }\n\n  function handleMouseEnter() {\n    setIsHovered(true)\n  }\n\n  function handleMouseLeave() {\n    setIsHovered(false)\n    if (tilt) {\n      tiltX.set(0)\n      tiltY.set(0)\n    }\n  }\n\n  // Calculate CSS grid spans\n  const colSpanClass = {\n    1: \"md:col-span-1\",\n    2: \"md:col-span-2\",\n    3: \"md:col-span-3\",\n    4: \"md:col-span-4\",\n  }[colSpan] || \"md:col-span-1\"\n\n  const rowSpanClass = {\n    1: \"row-span-1\",\n    2: \"row-span-2\",\n    3: \"row-span-3\",\n  }[rowSpan] || \"row-span-1\"\n\n  return (\n    <motion.div\n      ref={ref}\n      variants={itemVariants}\n      onMouseMove={handleMouseMove}\n      onMouseEnter={handleMouseEnter}\n      onMouseLeave={handleMouseLeave}\n      whileHover=\"hover\"\n      whileTap={{ scale: 0.98 }}\n      transition={SPRING_TACTILE}\n      style={{\n        ...(tilt && { rotateX, rotateY }),\n        transformStyle: \"preserve-3d\",\n      }}\n      className={cn(\n        \"group relative flex flex-col justify-between overflow-hidden rounded-2xl\",\n        \"bg-neutral-50 dark:bg-[#0C0C0C]\",\n        \"border border-neutral-200 dark:border-neutral-800\",\n        \"shadow-xs transition-shadow duration-300 hover:shadow-lg hover:shadow-neutral-200/50 dark:hover:shadow-black/50\",\n        \"col-span-1\",\n        colSpanClass,\n        rowSpanClass,\n        className\n      )}\n    >\n      {/* Spotlight Effect */}\n      {spotlight && (\n        <Spotlight \n          mouseX={spotlightX} \n          mouseY={spotlightY} \n          isHovered={isHovered} \n        />\n      )}\n\n      {/* Border Beam */}\n      {borderAnim && <BorderBeam isHovered={isHovered} />}\n\n      {/* Background Effect */}\n      {background && (\n        <div className=\"absolute inset-0 z-0 opacity-50 transition-opacity duration-300 group-hover:opacity-100\">\n          {background}\n        </div>\n      )}\n\n      {/* Content Container */}\n      <div className=\"relative z-10 flex h-full flex-col justify-between p-4 sm:p-5 xl:p-6\">\n        {/* Render children first if it's the main visual */}\n        <div className=\"flex-1\">{children}</div>\n\n        {/* Header / Footer text area */}\n        {(title || description || icon) && (\n          <div className={cn(\"flex items-start space-x-4\", children ? \"mt-4 sm:mt-6\" : \"\")}>\n            {icon && (\n              <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-neutral-200/50 dark:bg-neutral-800/50 text-neutral-900 dark:text-neutral-100\">\n                {icon}\n              </div>\n            )}\n            <div>\n              {title && (\n                <h3 className=\"text-lg font-medium tracking-tight text-neutral-900 dark:text-neutral-100\">\n                  {title}\n                </h3>\n              )}\n              {description && (\n                <p className=\"mt-1 text-sm text-neutral-500 dark:text-neutral-400\">\n                  {description}\n                </p>\n              )}\n            </div>\n          </div>\n        )}\n      </div>\n    </motion.div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/spectrumui/bento-card.tsx"
    },
    {
      "path": "app/registry/bento-grid/spotlight.tsx",
      "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { motion, MotionValue, useMotionTemplate } from \"framer-motion\"\nimport React from \"react\"\n\nexport interface SpotlightProps {\n  className?: string\n  mouseX: MotionValue<number>\n  mouseY: MotionValue<number>\n  isHovered: boolean\n  color?: string\n}\n\nexport function Spotlight({\n  className,\n  mouseX,\n  mouseY,\n  isHovered,\n  color = \"rgba(255, 255, 255, 0.06)\",\n}: SpotlightProps) {\n  const background = useMotionTemplate`\n    radial-gradient(\n      350px circle at ${mouseX}px ${mouseY}px,\n      ${color},\n      transparent 80%\n    )\n  `\n\n  return (\n    <motion.div\n      className={cn(\n        \"pointer-events-none absolute -inset-px z-0 transition-opacity duration-300\",\n        isHovered ? \"opacity-100\" : \"opacity-0\",\n        className\n      )}\n      style={{ background }}\n    />\n  )\n}\n",
      "type": "registry:component",
      "target": "components/spectrumui/spotlight.tsx"
    },
    {
      "path": "app/registry/bento-grid/border-beam.tsx",
      "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { motion } from \"framer-motion\"\nimport React from \"react\"\n\nexport interface BorderBeamProps {\n  className?: string\n  duration?: number\n  borderWidth?: number\n  colorFrom?: string\n  colorTo?: string\n  isHovered?: boolean\n}\n\nexport function BorderBeam({\n  className,\n  duration = 8,\n  borderWidth = 1.5,\n  colorFrom = \"rgba(163, 163, 163, 0)\",\n  colorTo = \"rgba(163, 163, 163, 0.4)\",\n  isHovered = false,\n}: BorderBeamProps) {\n  return (\n    <div\n      className={cn(\n        \"pointer-events-none absolute inset-0 z-0 rounded-[inherit] border border-transparent\",\n        \"[mask-clip:padding-box,border-box]! mask-intersect! [mask:linear-gradient(transparent,transparent),linear-gradient(white,white)]\",\n        className\n      )}\n      style={{\n        borderWidth: borderWidth,\n      }}\n    >\n      <motion.div\n        className=\"absolute left-1/2 top-1/2 aspect-square w-[250%] -translate-x-1/2 -translate-y-1/2\"\n        style={{\n          background: `conic-gradient(from 0deg, ${colorFrom} 0%, ${colorTo} 50%, ${colorFrom} 100%)`,\n          opacity: isHovered ? 1 : 0.3,\n          transition: \"opacity 0.3s ease\",\n        }}\n        animate={{ rotate: 360 }}\n        transition={{\n          repeat: Infinity,\n          ease: \"linear\",\n          duration: duration,\n        }}\n      />\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/spectrumui/border-beam.tsx"
    }
  ],
  "type": "registry:component"
}
