{
  "name": "scroll-choreography",
  "type": "registry:ui",
  "dependencies": [],
  "registryDependencies": [],
  "description": "Component for scroll-choreography",
  "files": [
    {
      "path": "components/ui/scroll-choreography.tsx",
      "content": "\"use client\";\n\nimport { motion, useScroll, useSpring, useTransform } from \"framer-motion\";\nimport { useRef } from \"react\";\nimport { cn } from \"@workspace/ui/lib/utils\";\n\ninterface ScrollChoreographyProps {\n  className?: string;\n  images: {\n    topLeft: string;\n    topRight: string;\n    bottomLeft: string;\n    bottomRight: string;\n  };\n}\n\nexport function ScrollChoreography({\n  className,\n  images,\n}: ScrollChoreographyProps) {\n  const containerRef = useRef<HTMLDivElement>(null);\n\n  const { scrollYProgress } = useScroll({\n    target: containerRef,\n    offset: [\"start start\", \"end end\"],\n  });\n\n  const smoothProgress = useSpring(scrollYProgress, {\n    stiffness: 400, // Higher stiffness for a slightly faster snap\n    damping: 50,   // Play with damping to add a little bounce/jerk\n    mass: 1.2,     // Adds a bit more weight to the movement\n    restDelta: 0.001,\n  });\n\n  // Default positions relative to center\n  const xLeft = \"-20vw\";\n  const xRight = \"20vw\";\n  const yTop = \"-14vh\";\n  const yBottom = \"14vh\";\n\n  // Phase 1: 0 - 0.3 (Diagonal movement)\n  // Phase 2: 0.35 - 0.65 (Stack alignment to center)\n  // Phase 3: 0.7 - 0.9 (Top Right expands to full screen)\n\n  // Top Left -> moves to Bottom Left, then to Center\n  const tlX = useTransform(smoothProgress, [0, 0.3, 0.35, 0.65, 1], [xLeft, xLeft, xLeft, \"0vw\", \"0vw\"]);\n  const tlY = useTransform(smoothProgress, [0, 0.3, 0.35, 0.65, 1], [yTop, yBottom, yBottom, \"0vh\", \"0vh\"]);\n\n  // Bottom Right -> moves to Top Right, then to Center\n  const brX = useTransform(smoothProgress, [0, 0.3, 0.35, 0.65, 1], [xRight, xRight, xRight, \"0vw\", \"0vw\"]);\n  const brY = useTransform(smoothProgress, [0, 0.3, 0.35, 0.65, 1], [yBottom, yTop, yTop, \"0vh\", \"0vh\"]);\n\n  // Bottom Left -> stays, then moves to Center\n  const blX = useTransform(smoothProgress, [0, 0.3, 0.35, 0.65, 1], [xLeft, xLeft, xLeft, \"0vw\", \"0vw\"]);\n  const blY = useTransform(smoothProgress, [0, 0.3, 0.35, 0.65, 1], [yBottom, yBottom, yBottom, \"0vh\", \"0vh\"]);\n\n  // Top Right -> stays, then moves to Center, then expands\n  const trX = useTransform(smoothProgress, [0, 0.3, 0.35, 0.65, 1], [xRight, xRight, xRight, \"0vw\", \"0vw\"]);\n  const trY = useTransform(smoothProgress, [0, 0.3, 0.35, 0.65, 1], [yTop, yTop, yTop, \"0vh\", \"0vh\"]);\n\n  // Top Right (Hero) scaling/expansion properties\n  const heroWidth = useTransform(smoothProgress, [0.65, 0.7, 0.9, 1], [\"36vw\", \"36vw\", \"100vw\", \"100vw\"]);\n  const heroHeight = useTransform(smoothProgress, [0.65, 0.7, 0.9, 1], [\"24vh\", \"24vh\", \"100vh\", \"100vh\"]);\n\n  // Opacity fading for images underneath the hero as it expands\n  const underImagesOpacity = useTransform(smoothProgress, [0.75, 0.85], [1, 0]);\n\n  const baseImageClasses =\n    \"absolute left-1/2 top-1/2 w-[36vw] h-[24vh] overflow-hidden -translate-x-1/2 -translate-y-1/2 bg-muted shadow-2xl will-change-transform\";\n\n  return (\n    <div ref={containerRef} className={cn(\"relative h-[300vh] w-full\", className)}>\n      <div className=\"sticky top-0 h-screen w-full overflow-hidden\">\n        <div className=\"absolute inset-0 flex items-center justify-center\">\n\n          {/* Top Left Image */}\n          <motion.div\n            style={{ x: tlX, y: tlY, opacity: underImagesOpacity }}\n            className={cn(baseImageClasses, \"z-10\")}\n          >\n            <img src={images.topLeft} alt=\"Top Left\" className=\"h-full w-full object-cover\" />\n          </motion.div>\n\n          {/* Bottom Right Image */}\n          <motion.div\n            style={{ x: brX, y: brY, opacity: underImagesOpacity }}\n            className={cn(baseImageClasses, \"z-20\")}\n          >\n            <img src={images.bottomRight} alt=\"Bottom Right\" className=\"h-full w-full object-cover\" />\n          </motion.div>\n\n          {/* Bottom Left Image */}\n          <motion.div\n            style={{ x: blX, y: blY, opacity: underImagesOpacity }}\n            className={cn(baseImageClasses, \"z-30\")}\n          >\n            <img src={images.bottomLeft} alt=\"Bottom Left\" className=\"h-full w-full object-cover\" />\n          </motion.div>\n\n          {/* Top Right Image (Hero - expands at the end) */}\n          <motion.div\n            style={{\n              x: trX,\n              y: trY,\n              width: heroWidth,\n              height: heroHeight,\n            }}\n            className={cn(baseImageClasses, \"z-40 origin-center bg-black/5\")}\n          >\n            <img src={images.topRight} alt=\"Top Right (Hero)\" className=\"h-full w-full object-cover\" />\n          </motion.div>\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:ui"
    }
  ]
}