{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "page-transition",
  "type": "registry:ui",
  "title": "Page Transition",
  "description": "Dynamic fullscreen page transition animation.",
  "dependencies": [
    "framer-motion"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/ui/transitions/page-transition.tsx",
      "type": "registry:ui",
      "target": "components/amicro/page-transition.tsx",
      "content": "import React, { useEffect, useRef } from 'react';\r\nimport { motion, Variants } from 'framer-motion';\r\n\r\nexport type TransitionType =\r\n  | 'double-stairs'\r\n  | 'shutter-stairs'\r\n  | 'split-stairs'\r\n  | 'horizontal-split'\r\n  | 'vertical-split'\r\n  | 'slash'\r\n  | 'lattice'\r\n  | 'curtain-shred'\r\n  | 'pixel'\r\n  | 'pixel-wave'\r\n  | 'pixel-spiral'\r\n  | 'vortex'\r\n  | 'cross-fade'\r\n  | 'expand-grow'\r\n  | 'push-slide'\r\n  | 'pop-over'\r\n  | 'depth-forward'\r\n  | 'liquid-wave';\r\n\r\nexport interface PageTransitionProps {\r\n  type?: TransitionType;\r\n  isVisible: boolean;\r\n  onComplete?: () => void;\r\n  className?: string;\r\n}\r\n\r\nexport const PageTransition: React.FC<PageTransitionProps> = ({\r\n  type = 'double-stairs',\r\n  isVisible,\r\n  onComplete,\r\n  className = '',\r\n}) => {\r\n  const pathRefs = useRef<(SVGPathElement | null)[]>([]);\r\n\r\n  useEffect(() => {\r\n    if (type !== 'liquid-wave' || !isVisible) return;\r\n    let animId: number;\r\n    const numPoints = 12;\r\n    const numPaths = 3;\r\n    const startTime = performance.now();\r\n\r\n    const delays = Array.from({ length: numPaths }, (_, i) =>\r\n      Array.from({ length: numPoints }, () => i * 0.08 + Math.random() * 0.15)\r\n    );\r\n\r\n    const animateFrame = (now: number) => {\r\n      const elapsedSec = (now - startTime) / 1000;\r\n      pathRefs.current.forEach((path, i) => {\r\n        if (!path) return;\r\n        const stepX = 100 / (numPoints - 1);\r\n        const pointsY = delays[i].map((delay) => {\r\n          const rawProgress = Math.max(0, Math.min(1, (elapsedSec - delay) / 0.65));\r\n          const easeProgress =\r\n            rawProgress < 0.5\r\n              ? 2 * rawProgress * rawProgress\r\n              : 1 - Math.pow(-2 * rawProgress + 2, 2) / 2;\r\n          return 100 - easeProgress * 110;\r\n        });\r\n\r\n        let d = `M 0 100 V ${pointsY[0]}`;\r\n        for (let j = 0; j < numPoints - 1; j++) {\r\n          const currentX = j * stepX;\r\n          const nextX = (j + 1) * stepX;\r\n          const cpX = currentX + stepX * 0.5;\r\n          d += ` C ${cpX} ${pointsY[j]} ${cpX} ${pointsY[j + 1]} ${nextX} ${pointsY[j + 1]}`;\r\n        }\r\n        d += ` V 100 H 0 Z`;\r\n        path.setAttribute('d', d);\r\n      });\r\n\r\n      if (now - startTime < 1300) {\r\n        animId = requestAnimationFrame(animateFrame);\r\n      } else if (onComplete) {\r\n        onComplete();\r\n      }\r\n    };\r\n\r\n    animId = requestAnimationFrame(animateFrame);\r\n    return () => cancelAnimationFrame(animId);\r\n  }, [isVisible, type, onComplete]);\r\n\r\n  if (!isVisible && type !== 'liquid-wave') return null;\r\n\r\n  if (type === 'double-stairs') {\r\n    const COLUMNS = 5;\r\n    const variants: Variants = {\r\n      initial: (i: number) => ({ y: i % 2 === 0 ? '-100%' : '100%' }),\r\n      enter: (i: number) => ({\r\n        y: '0%',\r\n        transition: { duration: 0.8, ease: [0.76, 0, 0.24, 1], delay: i * 0.05 },\r\n      }),\r\n      exit: (i: number) => ({\r\n        y: i % 2 === 0 ? '100%' : '-100%',\r\n        transition: { duration: 0.8, ease: [0.76, 0, 0.24, 1], delay: i * 0.05 },\r\n      }),\r\n    };\r\n\r\n    return (\r\n      <motion.div\r\n        className={`fixed inset-0 z-50 flex h-screen w-screen pointer-events-none ${className}`}\r\n        initial=\"initial\"\r\n        animate={isVisible ? 'enter' : 'exit'}\r\n        onAnimationComplete={() => {\r\n          if (onComplete) onComplete();\r\n        }}\r\n      >\r\n        {[...Array(COLUMNS)].map((_, i) => (\r\n          <motion.div\r\n            key={i}\r\n            variants={variants}\r\n            custom={i}\r\n            className=\"relative h-full flex-1 bg-neutral-900 border-r border-neutral-800 last:border-r-0\"\r\n          />\r\n        ))}\r\n      </motion.div>\r\n    );\r\n  }\r\n\r\n  if (type === 'liquid-wave') {\r\n    return (\r\n      <svg\r\n        className={`fixed inset-0 w-full h-full pointer-events-none z-50 ${className}`}\r\n        viewBox=\"0 0 100 100\"\r\n        preserveAspectRatio=\"none\"\r\n      >\r\n        <path ref={(el) => { pathRefs.current[0] = el; }} fill=\"#3f3f46\" style={{ opacity: 0.4 }} />\r\n        <path ref={(el) => { pathRefs.current[1] = el; }} fill=\"#27272a\" style={{ opacity: 0.75 }} />\r\n        <path ref={(el) => { pathRefs.current[2] = el; }} fill=\"#09090b\" />\r\n      </svg>\r\n    );\r\n  }\r\n\r\n  return (\r\n    <motion.div\r\n      className={`fixed inset-0 z-50 bg-neutral-900 pointer-events-none ${className}`}\r\n      initial={{ opacity: 0 }}\r\n      animate={isVisible ? { opacity: 1 } : { opacity: 0 }}\r\n      transition={{ duration: 0.4 }}\r\n    />\r\n  );\r\n};\r\n"
    }
  ]
}