{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "scroll-split-card",
  "type": "registry:ui",
  "title": "Scroll Split Card",
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Component for scroll-split-card",
  "files": [
    {
      "path": "components/ui/scroll-split-card.tsx",
      "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { motion, useScroll, useTransform, useMotionTemplate } from \"framer-motion\";\nimport { useRef } from \"react\";\n\ninterface ScrollSplitCardItem {\n  title: string;\n  description: string;\n  bgColor: string;\n  textColor: string;\n  icon?: React.ReactNode;\n}\n\ninterface ScrollSplitCardProps {\n  className?: string;\n  imageSrc: string;\n  cards: ScrollSplitCardItem[];\n  containerRef?: React.RefObject<HTMLElement | null>;\n}\n\nexport function ScrollSplitCard({\n  className,\n  imageSrc,\n  cards,\n  containerRef: externalContainerRef,\n}: ScrollSplitCardProps) {\n  const containerRef = useRef<HTMLDivElement>(null);\n\n  const { scrollYProgress } = useScroll({\n    target: containerRef,\n    container: externalContainerRef,\n    offset: [\"start start\", \"end end\"],\n  });\n\n  // Stage 1 to 2: Separation (0 to 0.4), then Stage 2 to 3: Overlap closer (0.4 to 0.8)\n  const leftX = useTransform(scrollYProgress, [0, 0.4, 0.8], [0, -48, -24]);\n  const rightX = useTransform(scrollYProgress, [0, 0.4, 0.8], [0, 48, 24]);\n  const scale = useTransform(scrollYProgress, [0, 0.4], [1, 0.9]);\n\n  // Stage 2 to 3: Flip (0.4 to 0.8)\n  const rotateY = useTransform(scrollYProgress, [0.4, 0.8], [0, 180]);\n  // Due to 180deg Y flip, positive Z becomes visual counter-clockwise, negative Z becomes visual clockwise\n  const rotateZLeft = useTransform(scrollYProgress, [0.4, 0.8], [0, 6]);\n  const rotateZRight = useTransform(scrollYProgress, [0.4, 0.8], [0, -6]);\n\n  // Dynamic borders/radii so it looks like ONE flat image initially\n  const borderRadiusLeft = useTransform(scrollYProgress, [0, 0.2], [\"16px 0px 0px 16px\", \"16px 16px 16px 16px\"]);\n  const borderRadiusMiddle = useTransform(scrollYProgress, [0, 0.2], [\"0px 0px 0px 0px\", \"16px 16px 16px 16px\"]);\n  const borderRadiusRight = useTransform(scrollYProgress, [0, 0.2], [\"0px 16px 16px 0px\", \"16px 16px 16px 16px\"]);\n  const borderOpacity = useTransform(scrollYProgress, [0, 0.2], [0, 0.2]);\n  const shadowOpacity = useTransform(scrollYProgress, [0, 0.2], [0, 0.4]);\n  const boxShadow = useMotionTemplate`inset 0 1px 1px rgba(255, 255, 255, ${borderOpacity}), inset 0 -24px 48px rgba(0, 0, 0, ${shadowOpacity}), 0 25px 50px -12px rgba(0, 0, 0, ${shadowOpacity})`;\n\n  // Cards move up in the last viewport\n  const cardsY = useTransform(scrollYProgress, [0.8, 1], [0, -200]);\n\n  // Text appearance at the end in the sticky viewport\n  const textOpacity = useTransform(scrollYProgress, [0.8, 1], [0, 1]);\n  const textY = useTransform(scrollYProgress, [0.8, 1], [40, 0]);\n\n  // Indicator text appearance at the start\n  const startTextOpacity = useTransform(scrollYProgress, [0, 0.1], [1, 0]);\n  const startTextY = useTransform(scrollYProgress, [0, 0.1], [0, 20]);\n\n  return (\n    <div\n      ref={containerRef}\n      className={cn(\"relative h-[500vh] w-full\", className)}\n    >\n      <div className=\"sticky top-0 flex h-screen w-full items-center justify-center overflow-hidden [perspective:1200px]\">\n        {/* Starting Text indicator */}\n        <motion.div\n          className=\"absolute top-[20%] left-0 right-0 text-center\"\n          style={{\n            opacity: startTextOpacity,\n            y: startTextY,\n          }}\n        >\n          <p className=\"text-sm font-medium tracking-widest text-foreground/50 uppercase\">\n            Scroll down\n          </p>\n        </motion.div>\n\n        <motion.div\n          style={{ scale, y: cardsY, transformStyle: \"preserve-3d\" }}\n          className=\"flex h-[400px] w-full max-w-4xl px-4 relative\"\n        >\n          {cards.slice(0, 3).map((card, i) => (\n            <motion.div\n              key={i}\n              className=\"relative h-full flex-1\"\n              style={{\n                x: i === 0 ? leftX : i === 2 ? rightX : 0,\n                rotateY,\n                rotateZ: i === 0 ? rotateZLeft : i === 2 ? rotateZRight : 0,\n                zIndex: i, // Ensures Left is under Middle, and Right is above Middle\n                transformStyle: \"preserve-3d\",\n              }}\n            >\n              {/* Front Side: Original Image Split */}\n              <motion.div\n                className=\"absolute inset-0 overflow-hidden [backface-visibility:hidden]\"\n                style={{\n                  zIndex: 2, // Ensure front stays above initially\n                  borderRadius: i === 0 ? borderRadiusLeft : i === 2 ? borderRadiusRight : borderRadiusMiddle,\n                  boxShadow,\n                }}\n              >\n                <div\n                  className=\"absolute inset-0 h-full w-[300%]\"\n                  style={{\n                    left: `${-100 * i}%`,\n                    backgroundImage: `url(${imageSrc})`,\n                    backgroundSize: \"100% 100%\",\n                    backgroundPosition: \"center\",\n                  }}\n                />\n              </motion.div>\n\n              {/* Back Side: New Content Card */}\n              <motion.div\n                className={cn(\n                  \"absolute inset-0 overflow-hidden flex flex-col justify-end p-8 [backface-visibility:hidden] will-change-transform\",\n                  \"border border-white/5 bg-gradient-to-br from-white/10 to-transparent\",\n                  \"shadow-[inset_0_1px_1px_rgba(255,255,255,0.1),inset_0_-24px_48px_rgba(0,0,0,0.2)]\"\n                )}\n                style={{\n                  backgroundColor: card.bgColor,\n                  color: card.textColor,\n                  transform: \"rotateY(180deg)\",\n                  zIndex: 1, // Ensure back is behind before flip\n                  borderRadius: i === 0 ? borderRadiusLeft : i === 2 ? borderRadiusRight : borderRadiusMiddle,\n                  boxShadow,\n                }}\n              >\n                {/* Grainy Noise Overlay */}\n                <div\n                  className=\"pointer-events-none absolute inset-0 opacity-20 mix-blend-overlay\"\n                  style={{\n                    backgroundImage: `url(\"https://framerusercontent.com/images/6mcf62RlDfRfU61Yg5vb2pefpi4.png?width=256&height=256\")`,\n                    backgroundRepeat: \"repeat\",\n                  }}\n                />\n\n                <div className=\"relative z-10 mb-auto\">{card.icon}</div>\n                <h3 className=\"relative z-10 mb-4 text-2xl font-medium leading-tight\">\n                  {card.title}\n                </h3>\n                <p className=\"relative z-10 text-sm opacity-80\">{card.description}</p>\n              </motion.div>\n            </motion.div>\n          ))}\n        </motion.div>\n\n        {/* Ending Text fixed in the sticky viewport */}\n        <motion.div\n          className=\"absolute bottom-[20%] left-0 right-0 text-center\"\n          style={{\n            opacity: textOpacity,\n            y: textY,\n          }}\n        >\n          <p className=\"text-3xl font-medium tracking-tight text-foreground/80 font-serif italic\">\n            So cool, right?\n          </p>\n        </motion.div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:ui"
    }
  ]
}