{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "layered-stack",
  "type": "registry:ui",
  "title": "Layered Stack",
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Component for layered-stack",
  "files": [
    {
      "path": "components/ui/layered-stack.tsx",
      "content": "\"use client\";\n\nimport { ComponentProps, useCallback, useEffect, useRef } from \"react\";\nimport gsap from \"gsap\";\nimport { cn } from \"@/lib/utils\";\n\nexport type LayeredStackProps = ComponentProps<\"div\">;\n\nexport const LayeredStack = ({ children, className, ...props }: LayeredStackProps) => {\n    const containerRef = useRef<HTMLDivElement>(null);\n    const isStacked = useRef(true);\n\n    const stackCards = useCallback((animate = true) => {\n        const container = containerRef.current;\n        if (!container) return;\n\n        isStacked.current = true;\n        const cards = Array.from(container.children) as HTMLElement[];\n\n        // First clear all transforms so offsetLeft/offsetTop reflect true grid positions\n        cards.forEach((card) => {\n            gsap.killTweensOf(card);\n        });\n\n        if (!animate) {\n            // Instant reposition: clear transforms, recalculate, set immediately\n            cards.forEach((card) => gsap.set(card, { x: 0, y: 0, rotate: 0 }));\n            // Wait a frame so the browser recalculates layout\n            requestAnimationFrame(() => {\n                const container = containerRef.current;\n                if (!container || !isStacked.current) return;\n                const cards = Array.from(container.children) as HTMLElement[];\n                cards.forEach((card, i) => {\n                    const offsetX = container.clientWidth / 2 - card.offsetWidth / 2 - card.offsetLeft;\n                    const offsetY = container.clientHeight / 2 - card.offsetHeight / 2 - card.offsetTop;\n                    gsap.set(card, {\n                        x: offsetX,\n                        y: offsetY,\n                        rotate: gsap.utils.random(-10, 10),\n                        zIndex: 100 - i,\n                    });\n                });\n            });\n            return;\n        }\n\n        // Animated: first clear, then after layout recalc, animate to center\n        cards.forEach((card) => gsap.set(card, { x: 0, y: 0, rotate: 0 }));\n        requestAnimationFrame(() => {\n            const container = containerRef.current;\n            if (!container || !isStacked.current) return;\n            const cards = Array.from(container.children) as HTMLElement[];\n            cards.forEach((card, i) => {\n                const offsetX = container.clientWidth / 2 - card.offsetWidth / 2 - card.offsetLeft;\n                const offsetY = container.clientHeight / 2 - card.offsetHeight / 2 - card.offsetTop;\n                gsap.to(card, {\n                    x: offsetX,\n                    y: offsetY,\n                    rotate: gsap.utils.random(-10, 10),\n                    zIndex: 100 - i,\n                    duration: 0.8,\n                    ease: \"expo.out\",\n                    overwrite: true,\n                });\n            });\n        });\n    }, []);\n\n    const resetCards = useCallback(() => {\n        const container = containerRef.current;\n        if (!container) return;\n\n        isStacked.current = false;\n        const cards = Array.from(container.children) as HTMLElement[];\n\n        gsap.to(cards, {\n            x: 0,\n            y: 0,\n            zIndex: (i: number) => 100 - i,\n            duration: 0.8,\n            rotate: 0,\n            ease: \"expo.out\",\n            stagger: {\n                amount: 0.1,\n                from: \"start\",\n            },\n            overwrite: true,\n        });\n    }, []);\n\n    useEffect(() => {\n        const container = containerRef.current;\n        if (!container) return;\n\n        // Initial z-index setup\n        const cards = Array.from(container.children) as HTMLElement[];\n        cards.forEach((card, i) => {\n            gsap.set(card, { zIndex: 100 - i });\n        });\n\n        stackCards();\n\n        // Re-run current state on resize\n        const ro = new ResizeObserver(() => {\n            if (isStacked.current) {\n                stackCards(false);\n            }\n            // If expanded (reset), transforms are already 0 so nothing to fix\n        });\n        ro.observe(container);\n\n        return () => ro.disconnect();\n    }, [stackCards]);\n\n    return (\n        <div\n            ref={containerRef}\n            onMouseEnter={resetCards}\n            onMouseLeave={() => stackCards(true)}\n            className={cn(\"relative\", className)}\n            {...props}>\n            {children}\n        </div>\n    );\n};\n",
      "type": "registry:ui"
    }
  ]
}