{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dvd-screensaver",
  "title": "DVD Screensaver",
  "author": "mrap10",
  "description": "Bouncing logo screensaver with color shifts on bounce.",
  "dependencies": ["motion"],
  "files": [
    {
      "path": "registry/default/screen-savers/dvd-screensaver.tsx",
      "content": "\"use client\";\n\nimport { motion, useAnimationFrame } from \"motion/react\";\nimport { useRef, useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nconst COLORS = [\n  \"#FF4444\",\n  \"#44AAFF\",\n  \"#44FF88\",\n  \"#FFCC44\",\n  \"#CC44FF\",\n  \"#FF8844\",\n  \"#44FFEE\",\n];\n\ninterface DVDScreensaverProps {\n  text?: string;\n  subText?: string;\n  speed?: number;\n  className?: string;\n}\n\nexport default function DVDScreensaver({\n  text = \"Refinery\",\n  subText = \"UI Vault\",\n  speed = 2,\n  className = \"\",\n}: DVDScreensaverProps) {\n  const containerRef = useRef<HTMLDivElement>(null);\n  const logoRef = useRef<HTMLDivElement>(null);\n\n  const pos = useRef({ x: 80, y: 80 });\n  const vel = useRef({ vx: speed, vy: speed });\n  const colorIdxRef = useRef(0);\n\n  const [color, setColor] = useState(COLORS[0]);\n  const [bounces, setBounces] = useState(0);\n  const [corners, setCorners] = useState(0);\n  const [cornerFlashKey, setCornerFlashKey] = useState(0);\n\n  useAnimationFrame(() => {\n    const container = containerRef.current;\n    const logo = logoRef.current;\n    if (!container || !logo) return;\n\n    const cW = container.clientWidth;\n    const cH = container.clientHeight;\n    const lW = logo.offsetWidth;\n    const lH = logo.offsetHeight;\n\n    pos.current.x += vel.current.vx;\n    pos.current.y += vel.current.vy;\n\n    let hitX = false;\n    let hitY = false;\n\n    if (pos.current.x <= 0) {\n      pos.current.x = 0;\n      vel.current.vx = Math.abs(vel.current.vx);\n      hitX = true;\n    } else if (pos.current.x + lW >= cW) {\n      pos.current.x = cW - lW;\n      vel.current.vx = -Math.abs(vel.current.vx);\n      hitX = true;\n    }\n\n    if (pos.current.y <= 0) {\n      pos.current.y = 0;\n      vel.current.vy = Math.abs(vel.current.vy);\n      hitY = true;\n    } else if (pos.current.y + lH >= cH) {\n      pos.current.y = cH - lH;\n      vel.current.vy = -Math.abs(vel.current.vy);\n      hitY = true;\n    }\n\n    if (hitX || hitY) {\n      if (hitX) vel.current.vx += (Math.random() - 0.5) * 0.4;\n      if (hitY) vel.current.vy += (Math.random() - 0.5) * 0.4;\n\n      const mag = Math.sqrt(vel.current.vx ** 2 + vel.current.vy ** 2);\n      vel.current.vx = (vel.current.vx / mag) * speed;\n      vel.current.vy = (vel.current.vy / mag) * speed;\n\n      colorIdxRef.current = (colorIdxRef.current + 1) % COLORS.length;\n      setColor(COLORS[colorIdxRef.current]);\n      setBounces((b) => b + 1);\n\n      if (hitX && hitY) {\n        setCorners((c) => c + 1);\n        setCornerFlashKey((k) => k + 1);\n      }\n    }\n\n    logo.style.transform = `translate(${Math.round(pos.current.x)}px, ${Math.round(pos.current.y)}px)`;\n  });\n\n  return (\n    <div\n      ref={containerRef}\n      className={cn(\n        \"relative h-full w-full overflow-hidden bg-neutral-900 select-none\",\n        className\n      )}\n    >\n      <motion.div\n        key={cornerFlashKey}\n        initial={{ opacity: 0 }}\n        animate={{ opacity: [0, 0.2, 0] }}\n        transition={{ duration: 0.5, ease: \"easeInOut\" }}\n        className=\"pointer-events-none absolute inset-0 bg-neutral-50\"\n      />\n\n      <div\n        ref={logoRef}\n        className=\"absolute flex flex-col items-center gap-px will-change-transform\"\n      >\n        <motion.span\n          animate={{ color, textShadow: `0 0 24px ${color}66` }}\n          transition={{ duration: 0.15 }}\n          className=\"font-serif text-3xl tracking-tight\"\n        >\n          {text}\n        </motion.span>\n        <motion.span\n          animate={{ backgroundColor: color }}\n          transition={{ duration: 0.15 }}\n          className=\"rounded-full px-3 py-0.5 text-center text-[10px] font-semibold tracking-widest text-black uppercase\"\n        >\n          {subText}\n        </motion.span>\n      </div>\n\n      <div className=\"absolute bottom-3 left-4 font-mono text-xs leading-relaxed text-neutral-500\">\n        bounces: {bounces} <br />\n        corners: {corners}\n      </div>\n\n      <div className=\"absolute inset-0 flex items-center justify-center\">\n        <span className=\"font-mono text-sm text-white opacity-40\">\n          (move your mouse to exit screensaver)\n        </span>\n      </div>\n\n      {corners > 0 && (\n        <motion.div\n          key={cornerFlashKey}\n          initial={{ opacity: 0, y: -4 }}\n          animate={{ opacity: [0, 1, 1, 0], y: 0 }}\n          transition={{ duration: 1.4, times: [0, 0.1, 0.8, 1] }}\n          className=\"absolute top-3 right-4 font-mono text-xs font-bold text-neutral-300\"\n        >\n          CORNERRRRRRRRRR!\n        </motion.div>\n      )}\n    </div>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "categories": ["screensavers"],
  "type": "registry:component"
}
