{
	"$schema": "https://ui.shadcn.com/schema/registry-item.json",
	"name": "BounceCards-TS-CSS",
	"title": "BounceCards",
	"description": "Cards bounce that bounce in on mount.",
	"type": "registry:component",
	"files": [
		{
			"type": "registry:component",
			"path": "BounceCards/BounceCards.css",
			"content": ".bounceCardsContainer {\n  position: relative;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  width: 400px;\n  height: 400px;\n}\n\n.card {\n  position: absolute;\n  width: 200px;\n  aspect-ratio: 1;\n  border: 5px solid #fff;\n  border-radius: 25px;\n  overflow: hidden;\n  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);\n}\n\n.card .image {\n  width: 100%;\n  height: 100%;\n  object-fit: cover;\n}\n"
		},
		{
			"type": "registry:component",
			"path": "BounceCards/BounceCards.tsx",
			"content": "import { useEffect, useRef } from 'react';\nimport { gsap } from 'gsap';\nimport './BounceCards.css';\n\ninterface BounceCardsProps {\n  className?: string;\n  images?: string[];\n  containerWidth?: number;\n  containerHeight?: number;\n  animationDelay?: number;\n  animationStagger?: number;\n  easeType?: string;\n  transformStyles?: string[];\n  enableHover?: boolean;\n}\n\nexport default function BounceCards({\n  className = '',\n  images = [],\n  containerWidth = 400,\n  containerHeight = 400,\n  animationDelay = 0.5,\n  animationStagger = 0.06,\n  easeType = 'elastic.out(1, 0.8)',\n  transformStyles = [\n    'rotate(10deg) translate(-170px)',\n    'rotate(5deg) translate(-85px)',\n    'rotate(-3deg)',\n    'rotate(-10deg) translate(85px)',\n    'rotate(2deg) translate(170px)'\n  ],\n  enableHover = false\n}: BounceCardsProps) {\n  const containerRef = useRef<HTMLDivElement>(null);\n\n  useEffect(() => {\n    const ctx = gsap.context(() => {\n      gsap.fromTo(\n        '.card',\n        { scale: 0 },\n        {\n          scale: 1,\n          stagger: animationStagger,\n          ease: easeType,\n          delay: animationDelay\n        }\n      );\n    }, containerRef);\n    return () => ctx.revert();\n  }, [animationStagger, easeType, animationDelay]);\n\n  const getNoRotationTransform = (transformStr: string): string => {\n    const hasRotate = /rotate\\([\\s\\S]*?\\)/.test(transformStr);\n    if (hasRotate) {\n      return transformStr.replace(/rotate\\([\\s\\S]*?\\)/, 'rotate(0deg)');\n    } else if (transformStr === 'none') {\n      return 'rotate(0deg)';\n    } else {\n      return `${transformStr} rotate(0deg)`;\n    }\n  };\n\n  const getPushedTransform = (baseTransform: string, offsetX: number): string => {\n    const translateRegex = /translate\\(([-0-9.]+)px\\)/;\n    const match = baseTransform.match(translateRegex);\n    if (match) {\n      const currentX = parseFloat(match[1]);\n      const newX = currentX + offsetX;\n      return baseTransform.replace(translateRegex, `translate(${newX}px)`);\n    } else {\n      return baseTransform === 'none' ? `translate(${offsetX}px)` : `${baseTransform} translate(${offsetX}px)`;\n    }\n  };\n\n  const pushSiblings = (hoveredIdx: number) => {\n    if (!enableHover || !containerRef.current) return;\n    const q = gsap.utils.selector(containerRef);\n    images.forEach((_, i) => {\n      const selector = q(`.card-${i}`);\n      gsap.killTweensOf(selector);\n\n      const baseTransform = transformStyles[i] || 'none';\n\n      if (i === hoveredIdx) {\n        const noRotation = getNoRotationTransform(baseTransform);\n        gsap.to(selector, {\n          transform: noRotation,\n          duration: 0.4,\n          ease: 'back.out(1.4)',\n          overwrite: 'auto'\n        });\n      } else {\n        const offsetX = i < hoveredIdx ? -160 : 160;\n        const pushedTransform = getPushedTransform(baseTransform, offsetX);\n\n        const distance = Math.abs(hoveredIdx - i);\n        const delay = distance * 0.05;\n\n        gsap.to(selector, {\n          transform: pushedTransform,\n          duration: 0.4,\n          ease: 'back.out(1.4)',\n          delay,\n          overwrite: 'auto'\n        });\n      }\n    });\n  };\n\n  const resetSiblings = () => {\n    if (!enableHover || !containerRef.current) return;\n    const q = gsap.utils.selector(containerRef);\n    images.forEach((_, i) => {\n      const selector = q(`.card-${i}`);\n      gsap.killTweensOf(selector);\n      const baseTransform = transformStyles[i] || 'none';\n      gsap.to(selector, {\n        transform: baseTransform,\n        duration: 0.4,\n        ease: 'back.out(1.4)',\n        overwrite: 'auto'\n      });\n    });\n  };\n\n  return (\n    <div\n      className={`bounceCardsContainer ${className}`}\n      ref={containerRef}\n      style={{\n        position: 'relative',\n        width: containerWidth,\n        height: containerHeight\n      }}\n    >\n      {images.map((src, idx) => (\n        <div\n          key={idx}\n          className={`card card-${idx}`}\n          style={{ transform: transformStyles[idx] ?? 'none' }}\n          onMouseEnter={() => pushSiblings(idx)}\n          onMouseLeave={resetSiblings}\n        >\n          <img className=\"image\" src={src} alt={`card-${idx}`} />\n        </div>\n      ))}\n    </div>\n  );\n}\n"
		}
	],
	"registryDependencies": [],
	"dependencies": [
		"gsap@^3.13.0"
	]
}