{
	"$schema": "https://ui.shadcn.com/schema/registry-item.json",
	"name": "ChromaGrid-JS-TW",
	"title": "ChromaGrid",
	"description": "A responsive grid of grayscale tiles. Hovering the grid reaveals their colors.",
	"type": "registry:component",
	"files": [
		{
			"type": "registry:component",
			"path": "ChromaGrid/ChromaGrid.jsx",
			"content": "'use client';\n\nimport { useRef, useEffect } from 'react';\nimport { gsap } from 'gsap';\n\nconst ChromaGrid = ({ items, className = '', radius = 300, columns = 3, rows = 2, damping = 0.45, fadeOut = 0.6, ease = 'power3.out' }) => {\n  const rootRef = useRef(null);\n  const fadeRef = useRef(null);\n  const setX = useRef(null);\n  const setY = useRef(null);\n  const pos = useRef({ x: 0, y: 0 });\n\n  const demo = [\n    {\n      image: 'https://i.pravatar.cc/300?img=8',\n      title: 'Alex Rivera',\n      subtitle: 'Full Stack Developer',\n      handle: '@alexrivera',\n      borderColor: '#4F46E5',\n      gradient: 'linear-gradient(145deg,#4F46E5,#000)',\n      url: 'https://github.com/'\n    },\n    {\n      image: 'https://i.pravatar.cc/300?img=11',\n      title: 'Jordan Chen',\n      subtitle: 'DevOps Engineer',\n      handle: '@jordanchen',\n      borderColor: '#10B981',\n      gradient: 'linear-gradient(210deg,#10B981,#000)',\n      url: 'https://linkedin.com/in/'\n    },\n    {\n      image: 'https://i.pravatar.cc/300?img=3',\n      title: 'Morgan Blake',\n      subtitle: 'UI/UX Designer',\n      handle: '@morganblake',\n      borderColor: '#F59E0B',\n      gradient: 'linear-gradient(165deg,#F59E0B,#000)',\n      url: 'https://dribbble.com/'\n    },\n    {\n      image: 'https://i.pravatar.cc/300?img=16',\n      title: 'Casey Park',\n      subtitle: 'Data Scientist',\n      handle: '@caseypark',\n      borderColor: '#EF4444',\n      gradient: 'linear-gradient(195deg,#EF4444,#000)',\n      url: 'https://kaggle.com/'\n    },\n    {\n      image: 'https://i.pravatar.cc/300?img=25',\n      title: 'Sam Kim',\n      subtitle: 'Mobile Developer',\n      handle: '@thesamkim',\n      borderColor: '#8B5CF6',\n      gradient: 'linear-gradient(225deg,#8B5CF6,#000)',\n      url: 'https://github.com/'\n    },\n    {\n      image: 'https://i.pravatar.cc/300?img=60',\n      title: 'Tyler Rodriguez',\n      subtitle: 'Cloud Architect',\n      handle: '@tylerrod',\n      borderColor: '#06B6D4',\n      gradient: 'linear-gradient(135deg,#06B6D4,#000)',\n      url: 'https://aws.amazon.com/'\n    }\n  ];\n\n  const data = items?.length ? items : demo;\n\n  useEffect(() => {\n    const el = rootRef.current;\n    if (!el) return;\n    setX.current = gsap.quickSetter(el, '--x', 'px');\n    setY.current = gsap.quickSetter(el, '--y', 'px');\n    const { width, height } = el.getBoundingClientRect();\n    pos.current = { x: width / 2, y: height / 2 };\n    setX.current(pos.current.x);\n    setY.current(pos.current.y);\n  }, []);\n\n  const moveTo = (x, y) => {\n    gsap.to(pos.current, {\n      x,\n      y,\n      duration: damping,\n      ease,\n      onUpdate: () => {\n        setX.current?.(pos.current.x);\n        setY.current?.(pos.current.y);\n      },\n      overwrite: true\n    });\n  };\n\n  const handleMove = e => {\n    const r = rootRef.current.getBoundingClientRect();\n    moveTo(e.clientX - r.left, e.clientY - r.top);\n    gsap.to(fadeRef.current, { opacity: 0, duration: 0.25, overwrite: true });\n  };\n\n  const handleLeave = () => {\n    gsap.to(fadeRef.current, {\n      opacity: 1,\n      duration: fadeOut,\n      overwrite: true\n    });\n  };\n\n  const handleCardClick = url => {\n    if (url) window.open(url, '_blank', 'noopener,noreferrer');\n  };\n\n  const handleCardMove = e => {\n    const c = e.currentTarget;\n    const rect = c.getBoundingClientRect();\n    c.style.setProperty('--mouse-x', `${e.clientX - rect.left}px`);\n    c.style.setProperty('--mouse-y', `${e.clientY - rect.top}px`);\n  };\n\n  return (\n    <div\n      ref={rootRef}\n      onPointerMove={handleMove}\n      onPointerLeave={handleLeave}\n      className={`relative w-full h-full grid justify-center gap-3 ${className}`}\n      style={{\n        '--r': `${radius}px`,\n        '--cols': columns,\n        '--rows': rows,\n        '--x': '50%',\n        '--y': '50%',\n        gridTemplateColumns: `repeat(${columns}, 320px)`,\n        gridAutoRows: 'auto',\n        maxWidth: '1200px',\n        margin: '0 auto',\n        padding: '1rem',\n        boxSizing: 'border-box'\n      }}\n    >\n      {data.map((c, i) => (\n        <article\n          key={i}\n          onMouseMove={handleCardMove}\n          onClick={() => handleCardClick(c.url)}\n          className=\"group relative flex flex-col w-[300px] rounded-[20px] overflow-hidden border-2 border-transparent transition-colors duration-300 cursor-pointer\"\n          style={{\n            '--card-border': c.borderColor || 'transparent',\n            background: c.gradient,\n            '--spotlight-color': 'rgba(255,255,255,0.3)'\n          }}\n        >\n          <div\n            className=\"absolute inset-0 pointer-events-none transition-opacity duration-500 z-20 opacity-0 group-hover:opacity-100\"\n            style={{\n              background:\n                'radial-gradient(circle at var(--mouse-x) var(--mouse-y), var(--spotlight-color), transparent 70%)'\n            }}\n          />\n          <div className=\"relative z-10 flex-1 p-[10px] box-border\">\n            <img src={c.image} alt={c.title} loading=\"lazy\" className=\"w-full h-full object-cover rounded-[10px]\" />\n          </div>\n          <footer className=\"relative z-10 p-3 text-white font-sans grid grid-cols-[1fr_auto] gap-x-3 gap-y-1\">\n            <h3 className=\"m-0 text-[1.05rem] font-semibold\">{c.title}</h3>\n            {c.handle && <span className=\"text-[0.95rem] opacity-80 text-right\">{c.handle}</span>}\n            <p className=\"m-0 text-[0.85rem] opacity-85\">{c.subtitle}</p>\n            {c.location && <span className=\"text-[0.85rem] opacity-85 text-right\">{c.location}</span>}\n          </footer>\n        </article>\n      ))}\n      <div\n        className=\"absolute inset-0 pointer-events-none z-30\"\n        style={{\n          backdropFilter: 'grayscale(1) brightness(0.78)',\n          WebkitBackdropFilter: 'grayscale(1) brightness(0.78)',\n          background: 'rgba(0,0,0,0.001)',\n          maskImage:\n            'radial-gradient(circle var(--r) at var(--x) var(--y),transparent 0%,transparent 15%,rgba(0,0,0,0.10) 30%,rgba(0,0,0,0.22)45%,rgba(0,0,0,0.35)60%,rgba(0,0,0,0.50)75%,rgba(0,0,0,0.68)88%,white 100%)',\n          WebkitMaskImage:\n            'radial-gradient(circle var(--r) at var(--x) var(--y),transparent 0%,transparent 15%,rgba(0,0,0,0.10) 30%,rgba(0,0,0,0.22)45%,rgba(0,0,0,0.35)60%,rgba(0,0,0,0.50)75%,rgba(0,0,0,0.68)88%,white 100%)'\n        }}\n      />\n      <div\n        ref={fadeRef}\n        className=\"absolute inset-0 pointer-events-none transition-opacity duration-[250ms] z-40\"\n        style={{\n          backdropFilter: 'grayscale(1) brightness(0.78)',\n          WebkitBackdropFilter: 'grayscale(1) brightness(0.78)',\n          background: 'rgba(0,0,0,0.001)',\n          maskImage:\n            'radial-gradient(circle var(--r) at var(--x) var(--y),white 0%,white 15%,rgba(255,255,255,0.90)30%,rgba(255,255,255,0.78)45%,rgba(255,255,255,0.65)60%,rgba(255,255,255,0.50)75%,rgba(255,255,255,0.32)88%,transparent 100%)',\n          WebkitMaskImage:\n            'radial-gradient(circle var(--r) at var(--x) var(--y),white 0%,white 15%,rgba(255,255,255,0.90)30%,rgba(255,255,255,0.78)45%,rgba(255,255,255,0.65)60%,rgba(255,255,255,0.50)75%,rgba(255,255,255,0.32)88%,transparent 100%)',\n          opacity: 1\n        }}\n      />\n    </div>\n  );\n};\n\nexport default ChromaGrid;\n"
		}
	],
	"registryDependencies": [],
	"dependencies": [
		"gsap@^3.13.0"
	]
}