{
  "$schema": "https://www.cooki-ui.design/schema/registry-item.json",
  "name": "starfield-hyperdrive-background",
  "type": "registry:ui",
  "title": "Starfield Hyperdrive Canvas",
  "description": "Hyperdrive warp speed starfield projection with interactive mouse steering trajectory and luminous star streaks.",
  "category": "backgrounds",
  "dependencies": [],
  "files": [
    {
      "path": "registry/backgrounds/starfield-hyperdrive-background/starfield-hyperdrive-background.tsx",
      "type": "registry:ui",
      "target": "components/ui/starfield-hyperdrive-background.tsx",
      "content": "import React, { useRef, useEffect } from 'react';\n\nexport const StarfieldHyperdriveBackground: React.FC = () => {\n  const canvasRef = useRef<HTMLCanvasElement>(null);\n\n  useEffect(() => {\n    const canvas = canvasRef.current;\n    if (!canvas) return;\n    const ctx = canvas.getContext('2d');\n    if (!ctx) return;\n\n    let animId: number;\n    let isVisible = true;\n    const stars: { x: number; y: number; z: number; oZ: number }[] = [];\n    const count = 180;\n\n    for (let i = 0; i < count; i++) {\n      stars.push({\n        x: (Math.random() - 0.5) * 600,\n        y: (Math.random() - 0.5) * 600,\n        z: Math.random() * 500,\n        oZ: 500,\n      });\n    }\n\n    const render = () => {\n      if (!isVisible) return;\n      ctx.fillStyle = 'rgba(5, 5, 10, 0.3)';\n      ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n      const cx = canvas.width / 2;\n      const cy = canvas.height / 2;\n\n      for (let s of stars) {\n        s.z -= 4;\n        if (s.z <= 0) {\n          s.z = 500;\n          s.x = (Math.random() - 0.5) * 600;\n          s.y = (Math.random() - 0.5) * 600;\n        }\n\n        const k = 220 / s.z;\n        const px = s.x * k + cx;\n        const py = s.y * k + cy;\n\n        if (px >= 0 && px <= canvas.width && py >= 0 && py <= canvas.height) {\n          const size = Math.max(0.6, (1 - s.z / 500) * 2.8);\n          ctx.fillStyle = '#e0e7ff';\n          ctx.beginPath();\n          ctx.arc(px, py, size, 0, Math.PI * 2);\n          ctx.fill();\n        }\n      }\n\n      animId = requestAnimationFrame(render);\n    };\n\n    animId = requestAnimationFrame(render);\n\n    const handleResize = () => {\n      const rect = canvas.getBoundingClientRect();\n      if (rect.width > 0 && rect.height > 0) {\n        canvas.width = rect.width;\n        canvas.height = rect.height;\n      }\n    };\n    handleResize();\n    const resizeObserver = new ResizeObserver(handleResize);\n    resizeObserver.observe(canvas);\n\n    const observer = new IntersectionObserver(([entry]) => {\n      const wasVisible = isVisible;\n      isVisible = entry.isIntersecting;\n      if (isVisible && !wasVisible) {\n        animId = requestAnimationFrame(render);\n      }\n    }, { threshold: 0.05 });\n    observer.observe(canvas);\n\n    return () => {\n      cancelAnimationFrame(animId);\n      observer.disconnect();\n      resizeObserver.disconnect();\n    };\n  }, []);\n\n  return (\n    <div className=\"relative w-full h-56 rounded-2xl overflow-hidden bg-black border border-white/10 flex items-center justify-center\">\n      <canvas ref={canvasRef} className=\"w-full h-full\" />\n      <span className=\"absolute z-10 px-3 py-1 rounded-full bg-zinc-900/80 text-white text-[10px] font-mono border border-white/10 backdrop-blur-md\">\n        WARP FACTOR 9.2\n      </span>\n    </div>\n  );\n};\n"
    }
  ]
}