{
  "$schema": "https://www.cooki-ui.design/schema/registry-item.json",
  "name": "scratch-to-reveal-card",
  "type": "registry:ui",
  "title": "Scratch to Reveal Card",
  "description": "Interactive HTML5 canvas scratch card where user drags cursor or finger to scrape away silver coating and reveal reward code.",
  "category": "cards",
  "dependencies": [
    "@phosphor-icons/react"
  ],
  "files": [
    {
      "path": "registry/cards/scratch-to-reveal-card/scratch-to-reveal-card.tsx",
      "type": "registry:ui",
      "target": "components/ui/scratch-to-reveal-card.tsx",
      "content": "import React, { useRef, useEffect, useState } from 'react';\nimport { Gift, ArrowClockwise } from '@phosphor-icons/react';\n\nexport const ScratchToRevealCard: React.FC = () => {\n  const canvasRef = useRef<HTMLCanvasElement>(null);\n  const [isScratched, setIsScratched] = useState(false);\n\n  const initCanvas = () => {\n    const canvas = canvasRef.current;\n    if (!canvas) return;\n    const ctx = canvas.getContext('2d');\n    if (!ctx) return;\n\n    canvas.width = 280;\n    canvas.height = 140;\n\n    ctx.fillStyle = '#71717a';\n    ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n    ctx.fillStyle = '#a1a1aa';\n    ctx.font = '12px monospace';\n    ctx.textAlign = 'center';\n    ctx.fillText('SCRATCH TO REVEAL CODE', canvas.width / 2, canvas.height / 2 + 4);\n    setIsScratched(false);\n  };\n\n  useEffect(() => {\n    initCanvas();\n  }, []);\n\n  const scratchAtPoint = (clientX: number, clientY: number) => {\n    const canvas = canvasRef.current;\n    if (!canvas) return;\n    const ctx = canvas.getContext('2d');\n    if (!ctx) return;\n\n    const rect = canvas.getBoundingClientRect();\n    if (rect.width === 0 || rect.height === 0) return;\n    const scaleX = canvas.width / rect.width;\n    const scaleY = canvas.height / rect.height;\n    const x = (clientX - rect.left) * scaleX;\n    const y = (clientY - rect.top) * scaleY;\n\n    ctx.globalCompositeOperation = 'destination-out';\n    ctx.beginPath();\n    ctx.arc(x, y, 18, 0, Math.PI * 2);\n    ctx.fill();\n    setIsScratched(true);\n  };\n\n  const handleMouseMove = (e: React.MouseEvent<HTMLCanvasElement>) => {\n    if (e.buttons === 1) scratchAtPoint(e.clientX, e.clientY);\n  };\n\n  const handleTouchMove = (e: React.TouchEvent<HTMLCanvasElement>) => {\n    if (e.touches.length > 0) {\n      scratchAtPoint(e.touches[0].clientX, e.touches[0].clientY);\n    }\n  };\n\n  return (\n    <div className=\"flex flex-col items-center gap-3 p-5 rounded-3xl border border-zinc-200 dark:border-white/10 bg-white dark:bg-zinc-950 shadow-xl\">\n      <div className=\"relative w-[280px] h-[140px] rounded-2xl overflow-hidden border border-zinc-200 dark:border-white/10 select-none\">\n        {/* Hidden Content Underneath */}\n        <div className=\"absolute inset-0 flex flex-col items-center justify-center bg-gradient-to-br from-indigo-950 to-zinc-900 text-center p-4\">\n          <Gift size={24} className=\"text-amber-400 mb-1\" weight=\"fill\" />\n          <span className=\"font-mono text-sm font-bold text-white tracking-widest\">\n            COOKI-PRO-VIP99\n          </span>\n          <span className=\"text-[10px] text-zinc-400 font-mono mt-0.5\">\n            100% OFF PRO REGISTRY\n          </span>\n        </div>\n\n        {/* Scratch Surface Canvas */}\n        <canvas\n          ref={canvasRef}\n          onMouseMove={handleMouseMove}\n          onTouchMove={handleTouchMove}\n          onTouchStart={handleTouchMove}\n          onClick={(e) => scratchAtPoint(e.clientX, e.clientY)}\n          className=\"absolute inset-0 w-full h-full cursor-crosshair touch-none\"\n        />\n      </div>\n\n      <button\n        onClick={initCanvas}\n        className=\"flex items-center gap-1.5 px-3 py-1 rounded-lg bg-zinc-100 dark:bg-zinc-800 text-xs font-mono text-zinc-700 dark:text-zinc-300 hover:text-zinc-900 dark:hover:text-white transition-colors cursor-pointer\"\n      >\n        <ArrowClockwise size={12} />\n        <span>Reset Surface</span>\n      </button>\n    </div>\n  );\n};\n"
    }
  ]
}