{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "glow-card-grid",
  "title": "Glow Card Grid",
  "author": "ncdai <dai@chanhdai.com>",
  "description": "Display cards with glowing border and background effects.",
  "files": [
    {
      "path": "src/registry/components/glow-card-grid/glow-card-grid.tsx",
      "content": "\"use client\"\n\nimport { useEffect, useRef } from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport type GlowCardGridProps = React.ComponentPropsWithoutRef<\"div\"> & {\n  // Card parameters\n  cardRadius?: number\n\n  // Icon parameters\n  iconBlur?: number\n  iconSaturate?: number\n  iconBrightness?: number\n  iconScale?: number\n  iconOpacity?: number\n\n  // Border parameters\n  borderWidth?: number\n  borderBlur?: number\n  borderSaturate?: number\n  borderBrightness?: number\n  borderContrast?: number\n\n  children: React.ReactNode\n}\n\nexport function GlowCardGrid({\n  cardRadius = 16,\n\n  iconBlur = 25,\n  iconSaturate = 5.0,\n  iconBrightness = 1.3,\n  iconScale = 4,\n  iconOpacity = 0.3,\n\n  borderWidth = 3,\n  borderBlur = 10,\n  borderSaturate = 4.2,\n  borderBrightness = 2.5,\n  borderContrast = 2.5,\n\n  className,\n  style,\n  ...props\n}: GlowCardGridProps) {\n  const gridRef = useRef<HTMLDivElement>(null)\n\n  useEffect(() => {\n    const handlePointerMove = (event: PointerEvent) => {\n      if (!gridRef.current) return\n\n      const cards = gridRef.current.querySelectorAll<HTMLElement>(\n        \"[data-slot='glow-card']\"\n      )\n\n      cards.forEach((card) => {\n        const rect = card.getBoundingClientRect()\n\n        const centerX = rect.left + rect.width / 2\n        const centerY = rect.top + rect.height / 2\n\n        const x = (event.clientX - centerX) / (rect.width / 2)\n        const y = (event.clientY - centerY) / (rect.height / 2)\n\n        card.style.setProperty(\"--pointer-x\", x.toFixed(3))\n        card.style.setProperty(\"--pointer-y\", y.toFixed(3))\n      })\n    }\n\n    document.addEventListener(\"pointermove\", handlePointerMove)\n\n    return () => document.removeEventListener(\"pointermove\", handlePointerMove)\n  }, [])\n\n  return (\n    <div\n      ref={gridRef}\n      className={cn(\n        \"grid w-full gap-4 sm:grid-cols-2 md:grid-cols-3\",\n        className\n      )}\n      style={\n        {\n          \"--card-radius\": `${cardRadius}px`,\n          \"--card-icon-blur\": `${iconBlur}px`,\n          \"--card-icon-saturate\": iconSaturate,\n          \"--card-icon-brightness\": iconBrightness,\n          \"--card-icon-scale\": iconScale,\n          \"--card-icon-opacity\": iconOpacity,\n          \"--card-border-width\": `${borderWidth}px`,\n          \"--card-border-blur\": `${borderBlur}px`,\n          \"--card-border-saturate\": borderSaturate,\n          \"--card-border-brightness\": borderBrightness,\n          \"--card-border-contrast\": borderContrast,\n          ...style,\n        } as React.CSSProperties\n      }\n      {...props}\n    />\n  )\n}\n\nexport type GlowCardProps = {\n  name: string\n  handle: string\n  avatar: string\n  className?: string\n}\n\nexport function GlowCard({ name, handle, avatar, className }: GlowCardProps) {\n  return (\n    <div\n      data-slot=\"glow-card\"\n      className={cn(\n        \"@container-size relative h-52 w-full overflow-hidden rounded-(--card-radius) ring-1 ring-border transition-[translate,scale] select-none active:scale-[0.98]\",\n        className\n      )}\n    >\n      <div className=\"flex size-full overflow-hidden rounded-(--card-radius) [clip-path:inset(0_round_var(--card-radius))]\">\n        <div\n          className={cn(\n            \"pointer-events-none absolute inset-0 flex items-center justify-center\",\n            \"translate-x-[calc(var(--pointer-x,-10)*50cqi)] translate-y-[calc(var(--pointer-y,-10)*50cqh)] translate-z-0 scale-(--card-icon-scale)\",\n            \"blur-(--card-icon-blur) brightness-(--card-icon-brightness) saturate-(--card-icon-saturate)\",\n            \"opacity-(--card-icon-opacity) will-change-[transform,filter]\"\n          )}\n        >\n          <img className=\"size-20\" src={avatar} alt={name} />\n        </div>\n\n        <div className=\"z-1 flex flex-1 flex-col items-center justify-center gap-4\">\n          <img className=\"size-20 rounded-full\" src={avatar} alt={name} />\n\n          <div className=\"flex flex-col items-center gap-1\">\n            <h2 className=\"text-base leading-none font-semibold text-foreground\">\n              {name}\n            </h2>\n            <p className=\"text-sm leading-none text-foreground/50\">{handle}</p>\n          </div>\n        </div>\n      </div>\n\n      <div\n        className={cn(\n          \"pointer-events-none absolute inset-0 translate-z-0 rounded-(--card-radius)\",\n          \"border-(length:--card-border-width) border-solid border-transparent\",\n          \"backdrop-blur-(--card-border-blur) backdrop-brightness-(--card-border-brightness) backdrop-contrast-(--card-border-contrast) backdrop-saturate-(--card-border-saturate)\",\n          \"[clip-path:inset(0_round_var(--card-radius))]\"\n        )}\n        style={\n          {\n            maskImage:\n              \"linear-gradient(#fff 0 100%), linear-gradient(#fff 0 100%)\",\n            maskOrigin: \"border-box, padding-box\",\n            maskClip: \"border-box, padding-box\",\n            maskComposite: \"exclude\",\n            WebkitMaskComposite: \"xor\",\n          } as React.CSSProperties\n        }\n      />\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "@components/glow-card-grid.tsx"
    }
  ],
  "categories": [
    "effects"
  ],
  "type": "registry:component"
}