{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "magic-bento",
  "type": "registry:block",
  "title": "Magic bento",
  "description": "Magic bento",
  "files": [
    {
      "path": "components/usages/magicbentousage.tsx",
      "content": "\"use client\";\n\nimport React from \"react\";\n\nimport MagicBento from \"@/registry/open-source/magic-bento\";\n\nexport default function Usage() {\n\treturn (\n\t\t<div className=\"relative w-full flex items-center justify-center\">\n\t\t\t<MagicBento\n\t\t\t\ttextAutoHide={true}\n\t\t\t\tenableStars={true}\n\t\t\t\tenableSpotlight={true}\n\t\t\t\tenableBorderGlow={true}\n\t\t\t\tenableTilt={true}\n\t\t\t\tenableMagnetism={true}\n\t\t\t\tclickEffect={true}\n\t\t\t\tspotlightRadius={300}\n\t\t\t\tparticleCount={12}\n\t\t\t\tglowColor=\"132, 0, 255\"\n\t\t\t/>\n\t\t</div>\n\t);\n}\n",
      "type": "registry:block",
      "target": "~/example.tsx"
    },
    {
      "path": "components/usages/magicbentousage.tsx",
      "content": "\"use client\";\n\nimport React from \"react\";\n\nimport MagicBento from \"@/registry/open-source/magic-bento\";\n\nexport default function Usage() {\n\treturn (\n\t\t<div className=\"relative w-full flex items-center justify-center\">\n\t\t\t<MagicBento\n\t\t\t\ttextAutoHide={true}\n\t\t\t\tenableStars={true}\n\t\t\t\tenableSpotlight={true}\n\t\t\t\tenableBorderGlow={true}\n\t\t\t\tenableTilt={true}\n\t\t\t\tenableMagnetism={true}\n\t\t\t\tclickEffect={true}\n\t\t\t\tspotlightRadius={300}\n\t\t\t\tparticleCount={12}\n\t\t\t\tglowColor=\"132, 0, 255\"\n\t\t\t/>\n\t\t</div>\n\t);\n}\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/open-source/magic-bento.tsx",
      "content": "import React, { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { gsap } from \"gsap\";\n\n// Credit:\n// https://reactbits.dev/components/magic-bento\n\nexport interface BentoCardProps {\n\tcolor?: string;\n\ttitle?: string;\n\tdescription?: string;\n\tlabel?: string;\n\ttextAutoHide?: boolean;\n\tdisableAnimations?: boolean;\n}\n\nexport interface BentoProps {\n\ttextAutoHide?: boolean;\n\tenableStars?: boolean;\n\tenableSpotlight?: boolean;\n\tenableBorderGlow?: boolean;\n\tdisableAnimations?: boolean;\n\tspotlightRadius?: number;\n\tparticleCount?: number;\n\tenableTilt?: boolean;\n\tglowColor?: string;\n\tclickEffect?: boolean;\n\tenableMagnetism?: boolean;\n}\n\nconst DEFAULT_PARTICLE_COUNT = 12;\nconst DEFAULT_SPOTLIGHT_RADIUS = 300;\nconst DEFAULT_GLOW_COLOR = \"132, 0, 255\";\nconst MOBILE_BREAKPOINT = 768;\n\nconst cardData: BentoCardProps[] = [\n\t{\n\t\tcolor: \"#060010\",\n\t\ttitle: \"Analytics\",\n\t\tdescription: \"Track user behavior\",\n\t\tlabel: \"Insights\",\n\t},\n\t{\n\t\tcolor: \"#060010\",\n\t\ttitle: \"Dashboard\",\n\t\tdescription: \"Centralized data view\",\n\t\tlabel: \"Overview\",\n\t},\n\t{\n\t\tcolor: \"#060010\",\n\t\ttitle: \"Collaboration\",\n\t\tdescription: \"Work together seamlessly\",\n\t\tlabel: \"Teamwork\",\n\t},\n\t{\n\t\tcolor: \"#060010\",\n\t\ttitle: \"Automation\",\n\t\tdescription: \"Streamline workflows\",\n\t\tlabel: \"Efficiency\",\n\t},\n\t{\n\t\tcolor: \"#060010\",\n\t\ttitle: \"Integration\",\n\t\tdescription: \"Connect favorite tools\",\n\t\tlabel: \"Connectivity\",\n\t},\n\t{\n\t\tcolor: \"#060010\",\n\t\ttitle: \"Security\",\n\t\tdescription: \"Enterprise-grade protection\",\n\t\tlabel: \"Protection\",\n\t},\n];\n\nconst createParticleElement = (\n\tx: number,\n\ty: number,\n\tcolor: string = DEFAULT_GLOW_COLOR\n): HTMLDivElement => {\n\tconst el = document.createElement(\"div\");\n\tel.className = \"particle\";\n\tel.style.cssText = `\n    position: absolute;\n    width: 4px;\n    height: 4px;\n    border-radius: 50%;\n    background: rgba(${color}, 1);\n    box-shadow: 0 0 6px rgba(${color}, 0.6);\n    pointer-events: none;\n    z-index: 100;\n    left: ${x}px;\n    top: ${y}px;\n  `;\n\treturn el;\n};\n\nconst calculateSpotlightValues = (radius: number) => ({\n\tproximity: radius * 0.5,\n\tfadeDistance: radius * 0.75,\n});\n\nconst updateCardGlowProperties = (\n\tcard: HTMLElement,\n\tmouseX: number,\n\tmouseY: number,\n\tglow: number,\n\tradius: number\n) => {\n\tconst rect = card.getBoundingClientRect();\n\tconst relativeX = ((mouseX - rect.left) / rect.width) * 100;\n\tconst relativeY = ((mouseY - rect.top) / rect.height) * 100;\n\n\tcard.style.setProperty(\"--glow-x\", `${relativeX}%`);\n\tcard.style.setProperty(\"--glow-y\", `${relativeY}%`);\n\tcard.style.setProperty(\"--glow-intensity\", glow.toString());\n\tcard.style.setProperty(\"--glow-radius\", `${radius}px`);\n};\n\nconst ParticleCard: React.FC<{\n\tchildren: React.ReactNode;\n\tclassName?: string;\n\tdisableAnimations?: boolean;\n\tstyle?: React.CSSProperties;\n\tparticleCount?: number;\n\tglowColor?: string;\n\tenableTilt?: boolean;\n\tclickEffect?: boolean;\n\tenableMagnetism?: boolean;\n}> = ({\n\tchildren,\n\tclassName = \"\",\n\tdisableAnimations = false,\n\tstyle,\n\tparticleCount = DEFAULT_PARTICLE_COUNT,\n\tglowColor = DEFAULT_GLOW_COLOR,\n\tenableTilt = true,\n\tclickEffect = false,\n\tenableMagnetism = false,\n}) => {\n\tconst cardRef = useRef<HTMLDivElement>(null);\n\tconst particlesRef = useRef<HTMLDivElement[]>([]);\n\tconst timeoutsRef = useRef<NodeJS.Timeout[]>([]);\n\tconst isHoveredRef = useRef(false);\n\tconst memoizedParticles = useRef<HTMLDivElement[]>([]);\n\tconst particlesInitialized = useRef(false);\n\tconst magnetismAnimationRef = useRef<gsap.core.Tween | null>(null);\n\n\tconst initializeParticles = useCallback(() => {\n\t\tif (particlesInitialized.current || !cardRef.current) return;\n\n\t\tconst { width, height } = cardRef.current.getBoundingClientRect();\n\t\tmemoizedParticles.current = Array.from({ length: particleCount }, () =>\n\t\t\tcreateParticleElement(\n\t\t\t\tMath.random() * width,\n\t\t\t\tMath.random() * height,\n\t\t\t\tglowColor\n\t\t\t)\n\t\t);\n\t\tparticlesInitialized.current = true;\n\t}, [particleCount, glowColor]);\n\n\tconst clearAllParticles = useCallback(() => {\n\t\ttimeoutsRef.current.forEach(clearTimeout);\n\t\ttimeoutsRef.current = [];\n\t\tmagnetismAnimationRef.current?.kill();\n\n\t\tparticlesRef.current.forEach((particle) => {\n\t\t\tgsap.to(particle, {\n\t\t\t\tscale: 0,\n\t\t\t\topacity: 0,\n\t\t\t\tduration: 0.3,\n\t\t\t\tease: \"back.in(1.7)\",\n\t\t\t\tonComplete: () => {\n\t\t\t\t\tparticle.parentNode?.removeChild(particle);\n\t\t\t\t},\n\t\t\t});\n\t\t});\n\t\tparticlesRef.current = [];\n\t}, []);\n\n\tconst animateParticles = useCallback(() => {\n\t\tif (!cardRef.current || !isHoveredRef.current) return;\n\n\t\tif (!particlesInitialized.current) {\n\t\t\tinitializeParticles();\n\t\t}\n\n\t\tmemoizedParticles.current.forEach((particle, index) => {\n\t\t\tconst timeoutId = setTimeout(() => {\n\t\t\t\tif (!isHoveredRef.current || !cardRef.current) return;\n\n\t\t\t\tconst clone = particle.cloneNode(true) as HTMLDivElement;\n\t\t\t\tcardRef.current.appendChild(clone);\n\t\t\t\tparticlesRef.current.push(clone);\n\n\t\t\t\tgsap.fromTo(\n\t\t\t\t\tclone,\n\t\t\t\t\t{ scale: 0, opacity: 0 },\n\t\t\t\t\t{ scale: 1, opacity: 1, duration: 0.3, ease: \"back.out(1.7)\" }\n\t\t\t\t);\n\n\t\t\t\tgsap.to(clone, {\n\t\t\t\t\tx: (Math.random() - 0.5) * 100,\n\t\t\t\t\ty: (Math.random() - 0.5) * 100,\n\t\t\t\t\trotation: Math.random() * 360,\n\t\t\t\t\tduration: 2 + Math.random() * 2,\n\t\t\t\t\tease: \"none\",\n\t\t\t\t\trepeat: -1,\n\t\t\t\t\tyoyo: true,\n\t\t\t\t});\n\n\t\t\t\tgsap.to(clone, {\n\t\t\t\t\topacity: 0.3,\n\t\t\t\t\tduration: 1.5,\n\t\t\t\t\tease: \"power2.inOut\",\n\t\t\t\t\trepeat: -1,\n\t\t\t\t\tyoyo: true,\n\t\t\t\t});\n\t\t\t}, index * 100);\n\n\t\t\ttimeoutsRef.current.push(timeoutId);\n\t\t});\n\t}, [initializeParticles]);\n\n\tuseEffect(() => {\n\t\tif (disableAnimations || !cardRef.current) return;\n\n\t\tconst element = cardRef.current;\n\n\t\tconst handleMouseEnter = () => {\n\t\t\tisHoveredRef.current = true;\n\t\t\tanimateParticles();\n\n\t\t\tif (enableTilt) {\n\t\t\t\tgsap.to(element, {\n\t\t\t\t\trotateX: 5,\n\t\t\t\t\trotateY: 5,\n\t\t\t\t\tduration: 0.3,\n\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t\ttransformPerspective: 1000,\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\tconst handleMouseLeave = () => {\n\t\t\tisHoveredRef.current = false;\n\t\t\tclearAllParticles();\n\n\t\t\tif (enableTilt) {\n\t\t\t\tgsap.to(element, {\n\t\t\t\t\trotateX: 0,\n\t\t\t\t\trotateY: 0,\n\t\t\t\t\tduration: 0.3,\n\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (enableMagnetism) {\n\t\t\t\tgsap.to(element, {\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: 0,\n\t\t\t\t\tduration: 0.3,\n\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\tconst handleMouseMove = (e: MouseEvent) => {\n\t\t\tif (!enableTilt && !enableMagnetism) return;\n\n\t\t\tconst rect = element.getBoundingClientRect();\n\t\t\tconst x = e.clientX - rect.left;\n\t\t\tconst y = e.clientY - rect.top;\n\t\t\tconst centerX = rect.width / 2;\n\t\t\tconst centerY = rect.height / 2;\n\n\t\t\tif (enableTilt) {\n\t\t\t\tconst rotateX = ((y - centerY) / centerY) * -10;\n\t\t\t\tconst rotateY = ((x - centerX) / centerX) * 10;\n\n\t\t\t\tgsap.to(element, {\n\t\t\t\t\trotateX,\n\t\t\t\t\trotateY,\n\t\t\t\t\tduration: 0.1,\n\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t\ttransformPerspective: 1000,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (enableMagnetism) {\n\t\t\t\tconst magnetX = (x - centerX) * 0.05;\n\t\t\t\tconst magnetY = (y - centerY) * 0.05;\n\n\t\t\t\tmagnetismAnimationRef.current = gsap.to(element, {\n\t\t\t\t\tx: magnetX,\n\t\t\t\t\ty: magnetY,\n\t\t\t\t\tduration: 0.3,\n\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\tconst handleClick = (e: MouseEvent) => {\n\t\t\tif (!clickEffect) return;\n\n\t\t\tconst rect = element.getBoundingClientRect();\n\t\t\tconst x = e.clientX - rect.left;\n\t\t\tconst y = e.clientY - rect.top;\n\n\t\t\tconst maxDistance = Math.max(\n\t\t\t\tMath.hypot(x, y),\n\t\t\t\tMath.hypot(x - rect.width, y),\n\t\t\t\tMath.hypot(x, y - rect.height),\n\t\t\t\tMath.hypot(x - rect.width, y - rect.height)\n\t\t\t);\n\n\t\t\tconst ripple = document.createElement(\"div\");\n\t\t\tripple.style.cssText = `\n        position: absolute;\n        width: ${maxDistance * 2}px;\n        height: ${maxDistance * 2}px;\n        border-radius: 50%;\n        background: radial-gradient(circle, rgba(${glowColor}, 0.4) 0%, rgba(${glowColor}, 0.2) 30%, transparent 70%);\n        left: ${x - maxDistance}px;\n        top: ${y - maxDistance}px;\n        pointer-events: none;\n        z-index: 1000;\n      `;\n\n\t\t\telement.appendChild(ripple);\n\n\t\t\tgsap.fromTo(\n\t\t\t\tripple,\n\t\t\t\t{\n\t\t\t\t\tscale: 0,\n\t\t\t\t\topacity: 1,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tscale: 1,\n\t\t\t\t\topacity: 0,\n\t\t\t\t\tduration: 0.8,\n\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t\tonComplete: () => ripple.remove(),\n\t\t\t\t}\n\t\t\t);\n\t\t};\n\n\t\telement.addEventListener(\"mouseenter\", handleMouseEnter);\n\t\telement.addEventListener(\"mouseleave\", handleMouseLeave);\n\t\telement.addEventListener(\"mousemove\", handleMouseMove);\n\t\telement.addEventListener(\"click\", handleClick);\n\n\t\treturn () => {\n\t\t\tisHoveredRef.current = false;\n\t\t\telement.removeEventListener(\"mouseenter\", handleMouseEnter);\n\t\t\telement.removeEventListener(\"mouseleave\", handleMouseLeave);\n\t\t\telement.removeEventListener(\"mousemove\", handleMouseMove);\n\t\t\telement.removeEventListener(\"click\", handleClick);\n\t\t\tclearAllParticles();\n\t\t};\n\t}, [\n\t\tanimateParticles,\n\t\tclearAllParticles,\n\t\tdisableAnimations,\n\t\tenableTilt,\n\t\tenableMagnetism,\n\t\tclickEffect,\n\t\tglowColor,\n\t]);\n\n\treturn (\n\t\t<div\n\t\t\tref={cardRef}\n\t\t\tclassName={`${className} relative overflow-hidden`}\n\t\t\tstyle={{ ...style, position: \"relative\", overflow: \"hidden\" }}\n\t\t>\n\t\t\t{children}\n\t\t</div>\n\t);\n};\n\nconst GlobalSpotlight: React.FC<{\n\tgridRef: React.RefObject<HTMLDivElement | null>;\n\tdisableAnimations?: boolean;\n\tenabled?: boolean;\n\tspotlightRadius?: number;\n\tglowColor?: string;\n}> = ({\n\tgridRef,\n\tdisableAnimations = false,\n\tenabled = true,\n\tspotlightRadius = DEFAULT_SPOTLIGHT_RADIUS,\n\tglowColor = DEFAULT_GLOW_COLOR,\n}) => {\n\tconst spotlightRef = useRef<HTMLDivElement | null>(null);\n\tconst isInsideSection = useRef(false);\n\n\tuseEffect(() => {\n\t\tif (disableAnimations || !gridRef?.current || !enabled) return;\n\n\t\tconst spotlight = document.createElement(\"div\");\n\t\tspotlight.className = \"global-spotlight\";\n\t\tspotlight.style.cssText = `\n      position: fixed;\n      width: 800px;\n      height: 800px;\n      border-radius: 50%;\n      pointer-events: none;\n      background: radial-gradient(circle,\n        rgba(${glowColor}, 0.15) 0%,\n        rgba(${glowColor}, 0.08) 15%,\n        rgba(${glowColor}, 0.04) 25%,\n        rgba(${glowColor}, 0.02) 40%,\n        rgba(${glowColor}, 0.01) 65%,\n        transparent 70%\n      );\n      z-index: 200;\n      opacity: 0;\n      transform: translate(-50%, -50%);\n      mix-blend-mode: screen;\n    `;\n\t\tdocument.body.appendChild(spotlight);\n\t\tspotlightRef.current = spotlight;\n\n\t\tconst handleMouseMove = (e: MouseEvent) => {\n\t\t\tif (!spotlightRef.current || !gridRef.current) return;\n\n\t\t\tconst section = gridRef.current.closest(\".bento-section\");\n\t\t\tconst rect = section?.getBoundingClientRect();\n\t\t\tconst mouseInside =\n\t\t\t\trect &&\n\t\t\t\te.clientX >= rect.left &&\n\t\t\t\te.clientX <= rect.right &&\n\t\t\t\te.clientY >= rect.top &&\n\t\t\t\te.clientY <= rect.bottom;\n\n\t\t\tisInsideSection.current = mouseInside || false;\n\t\t\tconst cards = gridRef.current.querySelectorAll(\".card\");\n\n\t\t\tif (!mouseInside) {\n\t\t\t\tgsap.to(spotlightRef.current, {\n\t\t\t\t\topacity: 0,\n\t\t\t\t\tduration: 0.3,\n\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t});\n\t\t\t\tcards.forEach((card) => {\n\t\t\t\t\t(card as HTMLElement).style.setProperty(\"--glow-intensity\", \"0\");\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { proximity, fadeDistance } =\n\t\t\t\tcalculateSpotlightValues(spotlightRadius);\n\t\t\tlet minDistance = Infinity;\n\n\t\t\tcards.forEach((card) => {\n\t\t\t\tconst cardElement = card as HTMLElement;\n\t\t\t\tconst cardRect = cardElement.getBoundingClientRect();\n\t\t\t\tconst centerX = cardRect.left + cardRect.width / 2;\n\t\t\t\tconst centerY = cardRect.top + cardRect.height / 2;\n\t\t\t\tconst distance =\n\t\t\t\t\tMath.hypot(e.clientX - centerX, e.clientY - centerY) -\n\t\t\t\t\tMath.max(cardRect.width, cardRect.height) / 2;\n\t\t\t\tconst effectiveDistance = Math.max(0, distance);\n\n\t\t\t\tminDistance = Math.min(minDistance, effectiveDistance);\n\n\t\t\t\tlet glowIntensity = 0;\n\t\t\t\tif (effectiveDistance <= proximity) {\n\t\t\t\t\tglowIntensity = 1;\n\t\t\t\t} else if (effectiveDistance <= fadeDistance) {\n\t\t\t\t\tglowIntensity =\n\t\t\t\t\t\t(fadeDistance - effectiveDistance) /\n\t\t\t\t\t\t(fadeDistance - proximity);\n\t\t\t\t}\n\n\t\t\t\tupdateCardGlowProperties(\n\t\t\t\t\tcardElement,\n\t\t\t\t\te.clientX,\n\t\t\t\t\te.clientY,\n\t\t\t\t\tglowIntensity,\n\t\t\t\t\tspotlightRadius\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tgsap.to(spotlightRef.current, {\n\t\t\t\tleft: e.clientX,\n\t\t\t\ttop: e.clientY,\n\t\t\t\tduration: 0.1,\n\t\t\t\tease: \"power2.out\",\n\t\t\t});\n\n\t\t\tconst targetOpacity =\n\t\t\t\tminDistance <= proximity\n\t\t\t\t\t? 0.8\n\t\t\t\t\t: minDistance <= fadeDistance\n\t\t\t\t\t\t? ((fadeDistance - minDistance) /\n\t\t\t\t\t\t\t\t(fadeDistance - proximity)) *\n\t\t\t\t\t\t\t0.8\n\t\t\t\t\t\t: 0;\n\n\t\t\tgsap.to(spotlightRef.current, {\n\t\t\t\topacity: targetOpacity,\n\t\t\t\tduration: targetOpacity > 0 ? 0.2 : 0.5,\n\t\t\t\tease: \"power2.out\",\n\t\t\t});\n\t\t};\n\n\t\tconst handleMouseLeave = () => {\n\t\t\tisInsideSection.current = false;\n\t\t\tgridRef.current?.querySelectorAll(\".card\").forEach((card) => {\n\t\t\t\t(card as HTMLElement).style.setProperty(\"--glow-intensity\", \"0\");\n\t\t\t});\n\t\t\tif (spotlightRef.current) {\n\t\t\t\tgsap.to(spotlightRef.current, {\n\t\t\t\t\topacity: 0,\n\t\t\t\t\tduration: 0.3,\n\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\tdocument.addEventListener(\"mousemove\", handleMouseMove);\n\t\tdocument.addEventListener(\"mouseleave\", handleMouseLeave);\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"mousemove\", handleMouseMove);\n\t\t\tdocument.removeEventListener(\"mouseleave\", handleMouseLeave);\n\t\t\tspotlightRef.current?.parentNode?.removeChild(spotlightRef.current);\n\t\t};\n\t}, [gridRef, disableAnimations, enabled, spotlightRadius, glowColor]);\n\n\treturn null;\n};\n\nconst BentoCardGrid: React.FC<{\n\tchildren: React.ReactNode;\n\tgridRef?: React.RefObject<HTMLDivElement | null>;\n}> = ({ children, gridRef }) => (\n\t<div\n\t\tclassName=\"bento-section grid gap-2 p-3 max-w-216 select-none relative\"\n\t\tstyle={{ fontSize: \"clamp(1rem, 0.9rem + 0.5vw, 1.5rem)\" }}\n\t\tref={gridRef}\n\t>\n\t\t{children}\n\t</div>\n);\n\nconst useMobileDetection = () => {\n\tconst [isMobile, setIsMobile] = useState(false);\n\n\tuseEffect(() => {\n\t\tconst checkMobile = () =>\n\t\t\tsetIsMobile(window.innerWidth <= MOBILE_BREAKPOINT);\n\n\t\tcheckMobile();\n\t\twindow.addEventListener(\"resize\", checkMobile);\n\n\t\treturn () => window.removeEventListener(\"resize\", checkMobile);\n\t}, []);\n\n\treturn isMobile;\n};\n\nconst MagicBento: React.FC<BentoProps> = ({\n\ttextAutoHide = true,\n\tenableStars = true,\n\tenableSpotlight = true,\n\tenableBorderGlow = true,\n\tdisableAnimations = false,\n\tspotlightRadius = DEFAULT_SPOTLIGHT_RADIUS,\n\tparticleCount = DEFAULT_PARTICLE_COUNT,\n\tenableTilt = false,\n\tglowColor = DEFAULT_GLOW_COLOR,\n\tclickEffect = true,\n\tenableMagnetism = true,\n}) => {\n\tconst gridRef = useRef<HTMLDivElement>(null);\n\tconst isMobile = useMobileDetection();\n\tconst shouldDisableAnimations = disableAnimations || isMobile;\n\n\treturn (\n\t\t<>\n\t\t\t<style>\n\t\t\t\t{`\n          .bento-section {\n            --glow-x: 50%;\n            --glow-y: 50%;\n            --glow-intensity: 0;\n            --glow-radius: 200px;\n            --glow-color: ${glowColor};\n            --border-color: #392e4e;\n            --background-dark: #060010;\n            --white: hsl(0, 0%, 100%);\n            --purple-primary: rgba(132, 0, 255, 1);\n            --purple-glow: rgba(132, 0, 255, 0.2);\n            --purple-border: rgba(132, 0, 255, 0.8);\n          }\n          \n          .card-responsive {\n            grid-template-columns: 1fr;\n            width: 90%;\n            margin: 0 auto;\n            padding: 0.5rem;\n          }\n          \n          @media (min-width: 600px) {\n            .card-responsive {\n              grid-template-columns: repeat(2, 1fr);\n            }\n          }\n          \n          @media (min-width: 1024px) {\n            .card-responsive {\n              grid-template-columns: repeat(4, 1fr);\n            }\n            \n            .card-responsive .card:nth-child(3) {\n              grid-column: span 2;\n              grid-row: span 2;\n            }\n            \n            .card-responsive .card:nth-child(4) {\n              grid-column: 1 / span 2;\n              grid-row: 2 / span 2;\n            }\n            \n            .card-responsive .card:nth-child(6) {\n              grid-column: 4;\n              grid-row: 3;\n            }\n          }\n          \n          .card--border-glow::after {\n            content: '';\n            position: absolute;\n            inset: 0;\n            padding: 6px;\n            background: radial-gradient(var(--glow-radius) circle at var(--glow-x) var(--glow-y),\n                rgba(${glowColor}, calc(var(--glow-intensity) * 0.8)) 0%,\n                rgba(${glowColor}, calc(var(--glow-intensity) * 0.4)) 30%,\n                transparent 60%);\n            border-radius: inherit;\n            mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n            mask-composite: subtract;\n            -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n            -webkit-mask-composite: xor;\n            pointer-events: none;\n            transition: opacity 0.3s ease;\n            z-index: 1;\n          }\n          \n          .card--border-glow:hover::after {\n            opacity: 1;\n          }\n          \n          .card--border-glow:hover {\n            box-shadow: 0 4px 20px rgba(46, 24, 78, 0.4), 0 0 30px rgba(${glowColor}, 0.2);\n          }\n          \n          .particle::before {\n            content: '';\n            position: absolute;\n            top: -2px;\n            left: -2px;\n            right: -2px;\n            bottom: -2px;\n            background: rgba(${glowColor}, 0.2);\n            border-radius: 50%;\n            z-index: -1;\n          }\n          \n          .particle-container:hover {\n            box-shadow: 0 4px 20px rgba(46, 24, 78, 0.2), 0 0 30px rgba(${glowColor}, 0.2);\n          }\n          \n          .text-clamp-1 {\n            display: -webkit-box;\n            -webkit-box-orient: vertical;\n            -webkit-line-clamp: 1;\n            line-clamp: 1;\n            overflow: hidden;\n            text-overflow: ellipsis;\n          }\n          \n          .text-clamp-2 {\n            display: -webkit-box;\n            -webkit-box-orient: vertical;\n            -webkit-line-clamp: 2;\n            line-clamp: 2;\n            overflow: hidden;\n            text-overflow: ellipsis;\n          }\n          \n          @media (max-width: 599px) {\n            .card-responsive {\n              grid-template-columns: 1fr;\n              width: 90%;\n              margin: 0 auto;\n              padding: 0.5rem;\n            }\n            \n            .card-responsive .card {\n              width: 100%;\n              min-height: 180px;\n            }\n          }\n        `}\n\t\t\t</style>\n\n\t\t\t{enableSpotlight && (\n\t\t\t\t<GlobalSpotlight\n\t\t\t\t\tgridRef={gridRef}\n\t\t\t\t\tdisableAnimations={shouldDisableAnimations}\n\t\t\t\t\tenabled={enableSpotlight}\n\t\t\t\t\tspotlightRadius={spotlightRadius}\n\t\t\t\t\tglowColor={glowColor}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t<BentoCardGrid gridRef={gridRef}>\n\t\t\t\t<div className=\"card-responsive grid gap-2\">\n\t\t\t\t\t{cardData.map((card, index) => {\n\t\t\t\t\t\tconst baseClassName = `card flex flex-col justify-between relative aspect-4/3 min-h-[200px] w-full max-w-full p-5 rounded-[20px] border border-solid font-light overflow-hidden transition-shadow duration-300 ease-in-out hover:-translate-y-0.5 hover:shadow-[0_8px_25px_rgba(0,0,0,0.15)] ${\n\t\t\t\t\t\t\tenableBorderGlow ? \"card--border-glow\" : \"\"\n\t\t\t\t\t\t}`;\n\n\t\t\t\t\t\tconst cardStyle = {\n\t\t\t\t\t\t\tbackgroundColor: card.color || \"var(--background-dark)\",\n\t\t\t\t\t\t\tborderColor: \"var(--border-color)\",\n\t\t\t\t\t\t\tcolor: \"var(--white)\",\n\t\t\t\t\t\t\t\"--glow-x\": \"50%\",\n\t\t\t\t\t\t\t\"--glow-y\": \"50%\",\n\t\t\t\t\t\t\t\"--glow-intensity\": \"0\",\n\t\t\t\t\t\t\t\"--glow-radius\": \"200px\",\n\t\t\t\t\t\t} as React.CSSProperties;\n\n\t\t\t\t\t\tif (enableStars) {\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<ParticleCard\n\t\t\t\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\t\t\t\tclassName={baseClassName}\n\t\t\t\t\t\t\t\t\tstyle={cardStyle}\n\t\t\t\t\t\t\t\t\tdisableAnimations={shouldDisableAnimations}\n\t\t\t\t\t\t\t\t\tparticleCount={particleCount}\n\t\t\t\t\t\t\t\t\tglowColor={glowColor}\n\t\t\t\t\t\t\t\t\tenableTilt={enableTilt}\n\t\t\t\t\t\t\t\t\tclickEffect={clickEffect}\n\t\t\t\t\t\t\t\t\tenableMagnetism={enableMagnetism}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<div className=\"card__header flex justify-between gap-3 relative text-foreground\">\n\t\t\t\t\t\t\t\t\t\t<span className=\"card__label text-base\">\n\t\t\t\t\t\t\t\t\t\t\t{card.label}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<div className=\"card__content flex flex-col relative text-foreground\">\n\t\t\t\t\t\t\t\t\t\t<h3\n\t\t\t\t\t\t\t\t\t\t\tclassName={`card__title font-normal text-base m-0 mb-1 ${textAutoHide ? \"text-clamp-1\" : \"\"}`}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{card.title}\n\t\t\t\t\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\t\t\t\tclassName={`card__description text-xs leading-5 opacity-90 ${textAutoHide ? \"text-clamp-2\" : \"\"}`}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{card.description}\n\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</ParticleCard>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\t\t\tclassName={baseClassName}\n\t\t\t\t\t\t\t\tstyle={cardStyle}\n\t\t\t\t\t\t\t\tref={(el) => {\n\t\t\t\t\t\t\t\t\tif (!el) return;\n\n\t\t\t\t\t\t\t\t\tconst handleMouseMove = (e: MouseEvent) => {\n\t\t\t\t\t\t\t\t\t\tif (shouldDisableAnimations) return;\n\n\t\t\t\t\t\t\t\t\t\tconst rect = el.getBoundingClientRect();\n\t\t\t\t\t\t\t\t\t\tconst x = e.clientX - rect.left;\n\t\t\t\t\t\t\t\t\t\tconst y = e.clientY - rect.top;\n\t\t\t\t\t\t\t\t\t\tconst centerX = rect.width / 2;\n\t\t\t\t\t\t\t\t\t\tconst centerY = rect.height / 2;\n\n\t\t\t\t\t\t\t\t\t\tif (enableTilt) {\n\t\t\t\t\t\t\t\t\t\t\tconst rotateX =\n\t\t\t\t\t\t\t\t\t\t\t\t((y - centerY) / centerY) * -10;\n\t\t\t\t\t\t\t\t\t\t\tconst rotateY = ((x - centerX) / centerX) * 10;\n\n\t\t\t\t\t\t\t\t\t\t\tgsap.to(el, {\n\t\t\t\t\t\t\t\t\t\t\t\trotateX,\n\t\t\t\t\t\t\t\t\t\t\t\trotateY,\n\t\t\t\t\t\t\t\t\t\t\t\tduration: 0.1,\n\t\t\t\t\t\t\t\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t\t\t\t\t\t\t\t\ttransformPerspective: 1000,\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif (enableMagnetism) {\n\t\t\t\t\t\t\t\t\t\t\tconst magnetX = (x - centerX) * 0.05;\n\t\t\t\t\t\t\t\t\t\t\tconst magnetY = (y - centerY) * 0.05;\n\n\t\t\t\t\t\t\t\t\t\t\tgsap.to(el, {\n\t\t\t\t\t\t\t\t\t\t\t\tx: magnetX,\n\t\t\t\t\t\t\t\t\t\t\t\ty: magnetY,\n\t\t\t\t\t\t\t\t\t\t\t\tduration: 0.3,\n\t\t\t\t\t\t\t\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\t\tconst handleMouseLeave = () => {\n\t\t\t\t\t\t\t\t\t\tif (shouldDisableAnimations) return;\n\n\t\t\t\t\t\t\t\t\t\tif (enableTilt) {\n\t\t\t\t\t\t\t\t\t\t\tgsap.to(el, {\n\t\t\t\t\t\t\t\t\t\t\t\trotateX: 0,\n\t\t\t\t\t\t\t\t\t\t\t\trotateY: 0,\n\t\t\t\t\t\t\t\t\t\t\t\tduration: 0.3,\n\t\t\t\t\t\t\t\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif (enableMagnetism) {\n\t\t\t\t\t\t\t\t\t\t\tgsap.to(el, {\n\t\t\t\t\t\t\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\t\t\t\t\t\t\ty: 0,\n\t\t\t\t\t\t\t\t\t\t\t\tduration: 0.3,\n\t\t\t\t\t\t\t\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\t\tconst handleClick = (e: MouseEvent) => {\n\t\t\t\t\t\t\t\t\t\tif (!clickEffect || shouldDisableAnimations)\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t\t\t\t\tconst rect = el.getBoundingClientRect();\n\t\t\t\t\t\t\t\t\t\tconst x = e.clientX - rect.left;\n\t\t\t\t\t\t\t\t\t\tconst y = e.clientY - rect.top;\n\n\t\t\t\t\t\t\t\t\t\tconst maxDistance = Math.max(\n\t\t\t\t\t\t\t\t\t\t\tMath.hypot(x, y),\n\t\t\t\t\t\t\t\t\t\t\tMath.hypot(x - rect.width, y),\n\t\t\t\t\t\t\t\t\t\t\tMath.hypot(x, y - rect.height),\n\t\t\t\t\t\t\t\t\t\t\tMath.hypot(x - rect.width, y - rect.height)\n\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\tconst ripple = document.createElement(\"div\");\n\t\t\t\t\t\t\t\t\t\tripple.style.cssText = `\n                      position: absolute;\n                      width: ${maxDistance * 2}px;\n                      height: ${maxDistance * 2}px;\n                      border-radius: 50%;\n                      background: radial-gradient(circle, rgba(${glowColor}, 0.4) 0%, rgba(${glowColor}, 0.2) 30%, transparent 70%);\n                      left: ${x - maxDistance}px;\n                      top: ${y - maxDistance}px;\n                      pointer-events: none;\n                      z-index: 1000;\n                    `;\n\n\t\t\t\t\t\t\t\t\t\tel.appendChild(ripple);\n\n\t\t\t\t\t\t\t\t\t\tgsap.fromTo(\n\t\t\t\t\t\t\t\t\t\t\tripple,\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tscale: 0,\n\t\t\t\t\t\t\t\t\t\t\t\topacity: 1,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tscale: 1,\n\t\t\t\t\t\t\t\t\t\t\t\topacity: 0,\n\t\t\t\t\t\t\t\t\t\t\t\tduration: 0.8,\n\t\t\t\t\t\t\t\t\t\t\t\tease: \"power2.out\",\n\t\t\t\t\t\t\t\t\t\t\t\tonComplete: () => ripple.remove(),\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\t\tel.addEventListener(\"mousemove\", handleMouseMove);\n\t\t\t\t\t\t\t\t\tel.addEventListener(\"mouseleave\", handleMouseLeave);\n\t\t\t\t\t\t\t\t\tel.addEventListener(\"click\", handleClick);\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div className=\"card__header flex justify-between gap-3 relative text-foreground\">\n\t\t\t\t\t\t\t\t\t<span className=\"card__label text-base\">\n\t\t\t\t\t\t\t\t\t\t{card.label}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"card__content flex flex-col relative text-foreground\">\n\t\t\t\t\t\t\t\t\t<h3\n\t\t\t\t\t\t\t\t\t\tclassName={`card__title font-normal text-base m-0 mb-1 ${textAutoHide ? \"text-clamp-1\" : \"\"}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{card.title}\n\t\t\t\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\t\t\tclassName={`card__description text-xs leading-5 opacity-90 ${textAutoHide ? \"text-clamp-2\" : \"\"}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{card.description}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t</BentoCardGrid>\n\t\t</>\n\t);\n};\n\nexport default MagicBento;\n",
      "type": "registry:ui"
    }
  ]
}