{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "3d-book",
  "title": "3D Book",
  "description": "An interactive 3D book component with page flip animations.",
  "dependencies": [
    "motion",
    "clsx",
    "tailwind-merge"
  ],
  "files": [
    {
      "path": "registry/default/example/3d-book.tsx",
      "content": "\"use client\";\n\nimport { useRef, useState } from \"react\";\n\nexport default function InteractiveBook() {\n  const bookRef = useRef<HTMLDivElement>(null);\n  const [progress, setProgress] = useState(0);\n  const [isDragging, setIsDragging] = useState(false);\n\n  // Linear interpolation function\n  const lerp = (a: number, b: number, t: number) => a + (b - a) * t;\n\n  const handlePointerMove = (e: React.PointerEvent<HTMLDivElement>) => {\n    if (!bookRef.current) return;\n\n    const rect = bookRef.current.getBoundingClientRect();\n    const cursorX = e.clientX;\n    const bookCenterX = rect.left + rect.width / 2;\n\n    // Calculate how far cursor is from center (-1 to 1)\n    const distanceFromCenter = (cursorX - bookCenterX) / (rect.width / 2);\n\n    // Map cursor position to progress\n    // Left side (negative) = open (1), Right side (positive) = closed (0)\n    const targetProgress = lerp(1, 0, (distanceFromCenter + 1) / 2);\n\n    // Clamp between 0 and 1\n    setProgress(Math.max(0, Math.min(1, targetProgress)));\n  };\n\n  const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n    setIsDragging(true);\n    handlePointerMove(e);\n  };\n\n  const handlePointerUp = () => {\n    setIsDragging(false);\n    setProgress(0);\n  };\n\n  const handlePointerLeave = () => {\n    // Close book when cursor leaves (only if not dragging on mobile)\n    if (!isDragging) {\n      setProgress(0);\n    }\n  };\n\n  // Generate pages - all at same size and position\n  const totalPages = 15;\n  const pages = [];\n\n  // All pages same size, different rotation angles\n  for (let i = 1; i <= totalPages; i++) {\n    const rotationAngle = (i + 1) * 10; // -20, -30, -40... -160\n\n    pages.push(\n      <div\n        key={i}\n        className=\"absolute h-48 md:h-72 w-32 md:w-52 rounded-lg md:rounded-2xl border border-border bg-background light\"\n        style={\n          {\n            transformStyle: \"preserve-3d\",\n            transformOrigin: \"left\",\n            transform: `rotateY(calc(var(--book-progress) * ${-rotationAngle}deg))`,\n            zIndex: 50 + i,\n            backfaceVisibility: \"visible\",\n            \"--book-progress\": progress,\n          } as React.CSSProperties\n        }\n      />\n    );\n  }\n\n  return (\n    <div className=\"flex w-full h-full items-center justify-center  \">\n      <div\n        ref={bookRef}\n        className=\"w-32 md:w-52 h-48 md:h-72 will-change-transform translate-x-16 md:translate-x-24 touch-none\"\n        onPointerMove={handlePointerMove}\n        onPointerDown={handlePointerDown}\n        onPointerUp={handlePointerUp}\n        onPointerLeave={handlePointerLeave}\n        style={\n          {\n            perspective: \"1500px\",\n            transformStyle: \"preserve-3d\",\n            \"--book-progress\": progress,\n          } as React.CSSProperties\n        }\n      >\n        {/* Back Cover (underneath all pages) */}\n        <div\n          className=\"absolute h-48 md:h-72 w-32 md:w-52 rounded-lg md:rounded-2xl border-2 border-border\"\n          style={{\n            transformStyle: \"preserve-3d\",\n            transformOrigin: \"left\",\n            background:\n              \"radial-gradient(hsl(var(--muted)) 0 1px, hsl(var(--background)) 1px 100%) 0 0 / 4px 4px\",\n            boxShadow: \"0 5px 15px rgba(0,0,0,0.1)\",\n            zIndex: 1,\n          }}\n        />\n\n        {/* Pages - all same size, different rotations */}\n        {pages}\n\n        {/* Front Cover */}\n        <div\n          className=\"absolute h-48 md:h-72 w-32 md:w-52 bg-muted overflow-hidden\"\n          style={\n            {\n              transformStyle: \"preserve-3d\",\n              transformOrigin: \"left center\",\n              transform: `rotateY(calc(var(--book-progress) * -165deg))`,\n              boxShadow: \"0 4px 8px rgba(0, 0, 0, 0.1)\",\n              borderRadius: \"0 8px 8px 0\",\n              zIndex: 200,\n              \"--book-progress\": progress,\n            } as React.CSSProperties\n          }\n        >\n          {/* Cover shadow overlay */}\n          <div\n            className=\"absolute inset-0 pointer-events-none z-30\"\n            style={{\n              borderRadius: \"0 8px 8px 0\",\n              boxShadow:\n                \"0 0 0 0.85px rgba(0, 0, 0, 0.1) inset, 2px 0 1px 0 rgba(0, 0, 0, 0.1) inset, -1.5px 0 1px 0 rgba(0, 0, 0, 0.1) inset, 0 2px 2px 0 rgba(255, 255, 255, 0.1) inset, 0 8px 16px 0 rgba(0, 0, 0, 0.05)\",\n            }}\n          />\n\n          {/* Red top section */}\n          <div\n            className=\"absolute top-0 left-0 right-0 h-[40%] z-10 p-1.5 md:p-3 pl-2 md:pl-4\"\n            style={{\n              backgroundColor: \"rgb(187, 1, 58)\",\n            }}\n          />\n\n          {/* Spine edge */}\n          <div className=\"absolute top-0 left-0 bottom-0 w-2 md:w-3.5 z-30 flex flex-row justify-end\">\n            <div className=\"w-0.5 h-full bg-background/25\" />\n            <div className=\"w-0.5 h-full bg-foreground/15\" />\n          </div>\n\n          {/* Title */}\n          <div\n            className=\"absolute bottom-1.5 left-3 md:left-6 right-1.5 text-sm md:text-2xl font-medium pointer-events-none select-none z-20 text-muted-foreground/30\"\n            style={{\n              textShadow: \"0 0 2px hsl(var(--background))\",\n              backfaceVisibility: \"hidden\",\n            }}\n          >\n            Notebook\n          </div>\n\n          {/* Back label */}\n          <div\n            className=\"absolute top-1/2 right-1/2 text-xs md:text-base font-semibold text-center text-primary\"\n            style={{\n              transform: \"translate(50%, -50%) rotateY(180deg) scaleX(-1)\",\n              backfaceVisibility: \"hidden\",\n            }}\n          >\n            Back Page\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}