{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "backgroundmeteors",
  "type": "registry:ui",
  "title": "Background Meteors",
  "description": "Grid Background with Meteors.",
  "author": "Ahdeetai <https://aditya.is-cool.dev>",
  "registryDependencies": [],
  "dependencies": ["motion"],
  "files": [
    {
      "type": "registry:ui",
      "path": "components/ui/backgroundmeteors.tsx",
      "content": "'use client';\nimport React, { useEffect, useState, ReactNode } from 'react';\nimport { motion } from 'motion/react';\n\ninterface Beam {\n  id: number;\n  x: number;\n  duration: number;\n}\n\ninterface BackgroundMeteorsProps {\n  children?: ReactNode;\n}\n\nexport default function BackgroundMeteors({\n  children,\n}: BackgroundMeteorsProps) {\n  const [beams, setBeams] = useState<Beam[]>([]);\n  const gridSize = 40;\n  const totalLines = 35;\n\n  const generateSafeGridPositions = (count: number): number[] => {\n    const available: number[] = [];\n    for (let i = 0; i < totalLines - 1; i++) {\n      available.push(i);\n    }\n\n    const selected: number[] = [];\n    while (available.length > 0 && selected.length < count) {\n      const idx = Math.floor(Math.random() * available.length);\n      const value = available[idx];\n      selected.push(value);\n      available.splice(\n        0,\n        available.length,\n        ...available.filter((v) => Math.abs(v - value) > 1),\n      );\n    }\n\n    return selected.map((line) => line * gridSize);\n  };\n\n  useEffect(() => {\n    const generateBeams = () => {\n      const count = Math.floor(Math.random() * 2) + 3;\n      const xPositions = generateSafeGridPositions(count);\n\n      const newBeams: Beam[] = xPositions.map((x) => ({\n        id: Math.random(),\n        x,\n        duration: 4 + Math.random() * 1.5,\n      }));\n\n      setBeams(newBeams);\n\n      const maxDuration = Math.max(...newBeams.map((b) => b.duration));\n      setTimeout(generateBeams, (maxDuration - 0.5) * 1000);\n    };\n\n    generateBeams();\n  }, []);\n\n  return (\n    <div className='relative flex h-screen w-full items-center justify-center overflow-hidden bg-white dark:bg-black'>\n      <div\n        className='absolute inset-0'\n        style={{\n          backgroundSize: `${gridSize}px ${gridSize}px`,\n          backgroundImage:\n            'linear-gradient(to right, #e4e4e7 1px, transparent 1px), linear-gradient(to bottom, #e4e4e7 1px, transparent 1px)',\n        }}\n      />\n      <div\n        className='absolute inset-0 dark:block hidden'\n        style={{\n          backgroundSize: `${gridSize}px ${gridSize}px`,\n          backgroundImage:\n            'linear-gradient(to right, #262626 1px, transparent 1px), linear-gradient(to bottom, #024e6b  1px, transparent 1px)',\n        }}\n      />\n      <div\n        className='pointer-events-none absolute inset-0 flex items-center justify-center bg-white dark:bg-black \n        mask-[radial-gradient(ellipse_at_center,transparent_20%,black)]'\n      />\n      {beams.map((b) => (\n        <motion.div\n          key={b.id}\n          className='absolute top-0'\n          style={{ left: b.x, zIndex: 2 }}\n          initial={{ y: -150 }}\n          animate={{ y: '100vh' }}\n          transition={{\n            duration: b.duration,\n            ease: 'linear',\n          }}\n        >\n          <div\n            className='h-14 w-px rounded-full\n              bg-linear-to-t from-black to-transparent\n              dark:from-indigo-500 dark:via-teal-500 dark:to-transparent'\n            style={{ margin: '0 auto' }}\n          />\n        </motion.div>\n      ))}\n\n      <div className='absolute inset-0 z-10 flex items-center justify-center'>\n        {children}\n      </div>\n    </div>\n  );\n}\n"
    }
  ]
}
