{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "folder-preview",
  "type": "registry:ui",
  "dependencies": [
    "framer-motion"
  ],
  "files": [
    {
      "path": "components/ui/folder-preview.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { motion } from \"framer-motion\";\nimport { cn } from \"@/lib/utils\";\n\n// ============================================\n// SVG Icon Components\n// ============================================\n\nconst FolderBackIcon = ({ className }: { className?: string }) => (\n    <svg viewBox=\"0 0 20 16\" className={cn(\"w-full h-full fill-current\", className)}>\n        <path d=\"M7.5,0C7.4,0,2,0,2,0C0.9,0,0,0.9,0,2l0,12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V4c0-1.1-0.9-2-2-2c0,0-7.5,0-8,0C9,2,9.9,0,7.5,0z\" />\n    </svg>\n);\n\nconst FolderCoverIcon = ({ className }: { className?: string }) => (\n    <svg viewBox=\"0 0 20 16\" className={cn(\"w-full h-full fill-current\", className)}>\n        <path d=\"M2,2h16c1.1,0,2,0.9,2,2v10c0,1.1-0.9,2-2,2H2c-1.1,0-2-0.9-2-2V4C0,2.9,0.9,2,2,2z\" />\n    </svg>\n);\n\nconst UsersIcon = ({ className }: { className?: string }) => (\n    <svg viewBox=\"0 0 24 24\" className={cn(\"w-full h-full fill-current\", className)}>\n        <path\n            opacity=\"0.3\"\n            d=\"M22.2,17.7l-4-2c-0.5-0.3-0.8-0.8-0.8-1.3v-1.6c0.1-0.1,0.2-0.3,0.4-0.5c0.5-0.8,0.9-1.6,1.2-2.5c0.5-0.2,0.9-0.6,0.9-1.2V7c0-0.4-0.2-0.7-0.4-0.9V3.7c0,0,0.5-3.7-4.6-3.7c-5,0-4.6,3.7-4.6,3.7v2.4C10.1,6.3,9.9,6.7,9.9,7v1.7c0,0.4,0.2,0.8,0.6,1c0.4,1.8,1.5,3.1,1.5,3.1v1.5c0,0.6-0.3,1.1-0.8,1.3l-3.7,2c-1.1,0.6-1.7,1.7-1.7,2.9v1.3H24v-1.3C24,19.4,23.3,18.3,22.2,17.7z\"\n        />\n        <path\n            opacity=\"0.5\"\n            d=\"M7.5,17.7l2.5-1.3c0,0,0,0,0,0l1.2-0.7c0.5-0.3,0.8-0.8,0.8-1.3v-1.5c0,0-0.4-0.5-0.9-1.4l0,0c0,0,0,0,0,0c-0.1-0.1-0.1-0.2-0.2-0.3c0,0,0,0,0-0.1c-0.1-0.1-0.1-0.3-0.2-0.4c0,0,0,0,0,0c0-0.1-0.1-0.2-0.1-0.4c0,0,0-0.1,0-0.1c0-0.1-0.1-0.3-0.1-0.4c-0.3-0.2-0.6-0.6-0.6-1V7c0-0.4,0.2-0.7,0.4-0.9V3.8C9.8,3.3,8.9,2.9,7.4,2.9c-4,0-4.1,3.3-4.1,3.3v2.1C3.1,8.5,2.9,8.8,2.9,9.1v1.4c0,0.4,0.2,0.7,0.5,0.9c0.4,1.6,1.6,2.7,1.6,2.7v1.3c0,0.5-0.3,0.9-0.7,1.1l-2.8,1.7C0.6,18.8,0,19.7,0,20.8v1.2h5.8v-1.3C5.8,19.4,6.5,18.3,7.5,17.7z\"\n        />\n    </svg>\n);\n\nconst GlobeIcon = ({ className }: { className?: string }) => (\n    <svg viewBox=\"0 0 24 24\" className={cn(\"w-full h-full fill-current\", className)}>\n        <circle cx=\"12\" cy=\"12\" r=\"10\" opacity=\"0.3\" />\n        <path d=\"M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M12,20c-4.4,0-8-3.6-8-8s3.6-8,8-8s8,3.6,8,8S16.4,20,12,20z\" />\n    </svg>\n);\n\nconst PadlockIcon = ({ className }: { className?: string }) => (\n    <svg viewBox=\"0 0 24 33.6\" className={cn(\"w-full h-full fill-current\", className)}>\n        <path d=\"M23,13.5h-1.7V9.4C21.4,4.2,17.2,0,12,0C6.8,0,2.6,4.2,2.6,9.4v4.1H1c-0.5,0-1,0.4-1,1v18.2c0,0.5,0.4,1,1,1H23c0.5,0,1-0.4,1-1V14.4C24,13.9,23.6,13.5,23,13.5z M13.5,24.5v3.9c0,0.3-0.3,0.6-0.6,0.6h-1.8c-0.3,0-0.6-0.3-0.6-0.6v-3.9c-0.7-0.5-1.1-1.3-1.1-2.1c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C14.6,23.3,14.2,24.1,13.5,24.5z M16.9,13.5H7.1V9.4c0-2.7,2.2-4.9,4.9-4.9c2.7,0,4.9,2.2,4.9,4.9V13.5z\" />\n    </svg>\n);\n\nconst CloudIcon = ({ className }: { className?: string }) => (\n    <svg viewBox=\"0 0 24 22.2\" className={cn(\"w-full h-full fill-current\", className)}>\n        <path d=\"M19.5,5.8c-0.3-1.5-1-2.9-2.2-4c-1.3-1.2-3-1.8-4.7-1.8C11.3,0,10,0.4,8.9,1.1C8,1.7,7.2,2.5,6.6,3.5c-0.2,0-0.5-0.1-0.7-0.1c-2.1,0-3.8,1.7-3.8,3.8c0,0.3,0,0.5,0.1,0.8C0.8,9,0,10.6,0,12.3C0,13.6,0.5,15,1.4,16c1,1.1,2.2,1.7,3.6,1.8c0,0,0,0,0,0h4.2c0.4,0,0.7-0.3,0.7-0.7s-0.3-0.7-0.7-0.7H5c-2-0.1-3.7-2-3.7-4.2c0-1.4,0.8-2.7,2-3.4c0.3-0.2,0.4-0.5,0.3-0.8C3.5,7.8,3.4,7.5,3.4,7.2c0-1.4,1.1-2.5,2.5-2.5c0.3,0,0.6,0,0.8,0.1c0.3,0.1,0.7,0,0.8-0.3c0.9-2,2.9-3.2,5.1-3.2c2.9,0,5.3,2.2,5.6,5.1c0,0.3,0.3,0.5,0.6,0.6c2.2,0.4,3.9,2.4,3.9,4.7c0,2.5-1.9,4.6-4.3,4.8h-3.6c-0.4,0-0.7,0.3-0.7,0.7s0.3,0.7,0.7,0.7h3.7c0,0,0,0,0,0c1.5-0.1,2.9-0.8,4-2c1-1.1,1.6-2.6,1.6-4.1C24,8.9,22.1,6.5,19.5,5.8z M16,12.9c0.3-0.3,0.3-0.7,0-0.9l-3.5-3.5c-0.1-0.1-0.3-0.2-0.5-0.2c-0.2,0-0.3,0.1-0.5,0.2L8,12c-0.3,0.3-0.3,0.7,0,0.9c0.1,0.1,0.3,0.2,0.5,0.2c0.2,0,0.3-0.1,0.5-0.2l2.4-2.4v11c0,0.4,0.3,0.7,0.7,0.7s0.7-0.3,0.7-0.7v-11l2.4,2.4C15.3,13.2,15.7,13.2,16,12.9z\" />\n    </svg>\n);\n\nconst FileIcon = ({ className }: { className?: string }) => (\n    <svg viewBox=\"0 0 20 26.8\" className={cn(\"w-full h-full fill-current\", className)}>\n        <path d=\"M2.3,0C1,0,0,1,0,2.3v22.2c0,1.2,1,2.3,2.3,2.3h15.4c1.2,0,2.3-1,2.3-2.3V6l-6-6H2.3z\" />\n        <path opacity=\"0.1\" d=\"M13.9,3.7V0l6,6h-3.7C14.9,6,13.9,5,13.9,3.7z\" />\n    </svg>\n);\n\n// ============================================\n// Types & Interfaces\n// ============================================\n\nexport type FolderVariant =\n    | \"devi\"\n    | \"rudras\"\n    | \"ardra\"\n    | \"shakti\"\n    | \"kubera\"\n    | \"hari\"\n    | \"ravi\"\n    | \"durga\"\n    | \"nandi\";\n\nexport interface FolderPreviewProps {\n    variant?: FolderVariant;\n    images?: string[];\n    files?: { name: string; type?: \"txt\" | \"gif\" | \"mp3\" | \"default\" }[];\n    label?: string;\n    size?: \"sm\" | \"md\" | \"lg\";\n    className?: string;\n    onClick?: () => void;\n}\n\n// ============================================\n// Color Schemes for Each Variant\n// ============================================\n\nconst variantColors: Record<\n    FolderVariant,\n    {\n        back: string;\n        cover: string;\n        deco: string;\n        caption: string;\n        bg: string;\n    }\n> = {\n    devi: {\n        back: \"text-gray-500\",\n        cover: \"text-gray-400\",\n        deco: \"text-gray-400 brightness-125\",\n        caption: \"text-gray-800 dark:text-gray-200\",\n        bg: \"bg-gray-100 dark:bg-gray-900\",\n    },\n    rudras: {\n        back: \"text-gray-700 dark:text-gray-600\",\n        cover: \"text-gray-600 dark:text-gray-500\",\n        deco: \"text-gray-400\",\n        caption: \"text-blue-600 dark:text-blue-400\",\n        bg: \"bg-slate-200 dark:bg-slate-800\",\n    },\n    ardra: {\n        back: \"text-blue-800 dark:text-blue-700\",\n        cover: \"text-blue-600 dark:text-blue-500\",\n        deco: \"text-blue-700 dark:text-blue-600\",\n        caption: \"text-blue-500 dark:text-blue-400\",\n        bg: \"bg-gray-800 dark:bg-gray-950\",\n    },\n    shakti: {\n        back: \"text-indigo-800\",\n        cover: \"text-indigo-700\",\n        deco: \"text-indigo-800\",\n        caption: \"text-green-400\",\n        bg: \"bg-blue-600 dark:bg-blue-800\",\n    },\n    kubera: {\n        back: \"text-gray-900\",\n        cover: \"text-gray-700\",\n        deco: \"text-gray-600\",\n        caption: \"text-gray-900 dark:text-gray-100\",\n        bg: \"bg-emerald-400 dark:bg-emerald-600\",\n    },\n    hari: {\n        back: \"text-blue-800\",\n        cover: \"text-blue-700\",\n        deco: \"text-blue-800\",\n        caption: \"text-yellow-400\",\n        bg: \"bg-sky-500 dark:bg-sky-700\",\n    },\n    ravi: {\n        back: \"text-gray-900\",\n        cover: \"text-gray-700\",\n        deco: \"text-black dark:text-white\",\n        caption: \"text-gray-900 dark:text-gray-100\",\n        bg: \"bg-gray-200 dark:bg-gray-800\",\n    },\n    durga: {\n        back: \"text-green-600\",\n        cover: \"text-green-500\",\n        deco: \"text-green-600\",\n        caption: \"text-green-400 font-mono\",\n        bg: \"bg-gray-900 dark:bg-black\",\n    },\n    nandi: {\n        back: \"text-amber-500\",\n        cover: \"text-amber-400\",\n        deco: \"text-amber-500\",\n        caption: \"text-gray-900 dark:text-gray-100\",\n        bg: \"bg-green-100 dark:bg-green-950\",\n    },\n};\n\n// ============================================\n// Size Configuration\n// ============================================\n\nconst sizeConfig = {\n    sm: {\n        folder: \"w-16\",\n        thumb: \"w-10 h-10\",\n        deco: \"w-4 h-4\",\n        caption: \"text-xs\",\n    },\n    md: {\n        folder: \"w-24\",\n        thumb: \"w-14 h-14\",\n        deco: \"w-6 h-6\",\n        caption: \"text-sm\",\n    },\n    lg: {\n        folder: \"w-32\",\n        thumb: \"w-20 h-20\",\n        deco: \"w-8 h-8\",\n        caption: \"text-base\",\n    },\n};\n\n// ============================================\n// Animation Variants\n// ============================================\n\nconst createCircularPositions = (count: number, radius: number = 120) => {\n    return Array.from({ length: count }, (_, i) => {\n        const startAngle = Math.PI / count;\n        const angle = startAngle / 2 + startAngle * i;\n        return {\n            x: Math.round(radius * Math.cos(angle)),\n            y: Math.round(-radius * Math.sin(angle)),\n        };\n    });\n};\n\n// ============================================\n// Individual Folder Components for each Variant\n// ============================================\n\nconst DeviFolder: React.FC<{\n    images: string[];\n    isHovered: boolean;\n    colors: typeof variantColors.devi;\n    sizes: typeof sizeConfig.md;\n    label?: string;\n}> = ({ images, isHovered, colors, sizes, label }) => {\n    const positions = createCircularPositions(images.length, 80);\n\n    return (\n        <div className=\"relative\">\n            {/* Previews - positioned from folder center */}\n            <div className=\"absolute inset-0 flex items-center justify-center pointer-events-none z-10\">\n                {images.map((img, i) => (\n                    <motion.img\n                        key={i}\n                        src={img}\n                        alt=\"\"\n                        className=\"absolute w-12 h-12 object-cover rounded-full border-2 border-white shadow-md\"\n                        initial={{ opacity: 0, scale: 0.7, x: 0, y: 0 }}\n                        animate={\n                            isHovered\n                                ? {\n                                    opacity: 1,\n                                    scale: 1,\n                                    x: positions[i]?.x || 0,\n                                    y: positions[i]?.y || 0,\n                                }\n                                : { opacity: 0, scale: 0.7, x: 0, y: 0 }\n                        }\n                        transition={{\n                            duration: 0.6,\n                            delay: (images.length - i - 1) * 0.04,\n                            ease: [0.2, 1, 0.3, 1],\n                        }}\n                    />\n                ))}\n            </div>\n\n            {/* Folder */}\n            <div className=\"relative cursor-pointer aspect-[20/16]\" style={{ perspective: \"800px\" }}>\n                {/* Back */}\n                <div className={cn(\"absolute inset-0 transition-colors duration-150\", colors.back)}>\n                    <FolderBackIcon />\n                </div>\n\n                {/* Cover */}\n                <motion.div\n                    className={cn(\n                        \"relative transition-colors duration-150\",\n                        isHovered ? \"text-gray-600\" : colors.cover\n                    )}\n                >\n                    <FolderCoverIcon />\n                    <div\n                        className={cn(\n                            \"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\",\n                            sizes.deco,\n                            colors.deco\n                        )}\n                    >\n                        <UsersIcon />\n                    </div>\n                </motion.div>\n            </div>\n\n            {label && (\n                <h3 className={cn(\"mt-3 font-medium text-center\", sizes.caption, colors.caption)}>\n                    {label}\n                </h3>\n            )}\n        </div>\n    );\n};\n\n\nconst RudrasFolder: React.FC<{\n    images: string[];\n    isHovered: boolean;\n    colors: typeof variantColors.rudras;\n    sizes: typeof sizeConfig.md;\n    label?: string;\n}> = ({ images, isHovered, colors, sizes, label }) => {\n    const positions = createCircularPositions(images.length, 80);\n\n    return (\n        <div className=\"relative\">\n            {/* Previews - positioned from folder center */}\n            <div className=\"absolute inset-0 flex items-center justify-center pointer-events-none z-10\">\n                {images.map((img, i) => (\n                    <motion.img\n                        key={i}\n                        src={img}\n                        alt=\"\"\n                        className=\"absolute w-12 h-12 object-cover rounded-full border-2 border-white shadow-md\"\n                        initial={{ opacity: 0, scale: 0, x: 0, y: 0 }}\n                        animate={\n                            isHovered\n                                ? {\n                                    opacity: 1,\n                                    scale: 1,\n                                    x: -positions[i]?.x || 0,\n                                    y: positions[i]?.y || 0,\n                                }\n                                : { opacity: 0, scale: 0, x: 0, y: 0 }\n                        }\n                        transition={{\n                            duration: 0.8,\n                            delay: (images.length - i - 1) * 0.08,\n                            type: \"spring\",\n                            stiffness: 200,\n                            damping: 15,\n                        }}\n                    />\n                ))}\n            </div>\n\n            {/* Folder */}\n            <div className=\"relative cursor-pointer aspect-[20/16]\" style={{ perspective: \"800px\" }}>\n                {/* Back */}\n                <div className={cn(\"absolute inset-0\", colors.back)}>\n                    <FolderBackIcon />\n                </div>\n\n                {/* Paper Sheet Deco */}\n                <div className=\"absolute bottom-0.5 left-0.5 right-0.5 h-3/4 bg-white dark:bg-gray-200 rounded-lg\" />\n\n                {/* Cover */}\n                <motion.div\n                    className={cn(\"relative\", colors.cover)}\n                    style={{ transformOrigin: \"50% 100%\", transformStyle: \"preserve-3d\" }}\n                    animate={isHovered ? { rotateX: -30 } : { rotateX: 0 }}\n                    transition={{ duration: 0.3, ease: [0.16, 1, 0.3, 1] }}\n                >\n                    <FolderCoverIcon />\n                    <div\n                        className={cn(\n                            \"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\",\n                            sizes.deco,\n                            colors.deco\n                        )}\n                    >\n                        <UsersIcon />\n                    </div>\n                </motion.div>\n            </div>\n\n            {label && (\n                <h3 className={cn(\"mt-3 font-medium text-center\", sizes.caption, colors.caption)}>\n                    {label}\n                </h3>\n            )}\n        </div>\n    );\n};\n\n\nconst ArdraFolder: React.FC<{\n    images: string[];\n    isHovered: boolean;\n    colors: typeof variantColors.ardra;\n    sizes: typeof sizeConfig.md;\n    label?: string;\n}> = ({ images, isHovered, colors, sizes, label }) => {\n    const [randomPositions] = React.useState(() =>\n        images.map((_, i) => {\n            const radius = 60 + Math.random() * 20;\n            const angle = (2 * (i + 1) * Math.PI) / images.length;\n            return {\n                x: Math.round(radius * Math.cos(angle)),\n                y: Math.round(radius * Math.sin(angle)),\n                rotate: Math.random() * 6 - 3,\n            };\n        })\n    );\n\n    return (\n        <div className=\"relative\">\n            {/* Feedback Circle */}\n            <motion.div\n                className=\"absolute inset-0 flex items-center justify-center pointer-events-none\"\n                initial={{ opacity: 0 }}\n                animate={isHovered ? { opacity: 1 } : { opacity: 0 }}\n            >\n                <motion.div\n                    className=\"w-10 h-10 rounded-full bg-gray-900/50\"\n                    initial={{ scale: 1 }}\n                    animate={\n                        isHovered ? { opacity: [1, 0], scale: [1, 6] } : { opacity: 0, scale: 1 }\n                    }\n                    transition={{ duration: 0.9, ease: [0.1, 1, 0.3, 1] }}\n                />\n            </motion.div>\n\n            {/* Previews - positioned from folder center */}\n            <div className=\"absolute inset-0 flex items-center justify-center pointer-events-none z-10\">\n                {images.map((img, i) => (\n                    <motion.img\n                        key={i}\n                        src={img}\n                        alt=\"\"\n                        className=\"absolute w-10 h-10 object-cover rounded-full border-2 border-white shadow-lg\"\n                        initial={{ opacity: 0, scale: 0.4, x: 0, y: 0, rotate: 0 }}\n                        animate={\n                            isHovered\n                                ? {\n                                    opacity: 1,\n                                    scale: 1,\n                                    x: randomPositions[i]?.x || 0,\n                                    y: randomPositions[i]?.y || 0,\n                                    rotate: randomPositions[i]?.rotate || 0,\n                                }\n                                : { opacity: 0, scale: 0.4, x: 0, y: 0, rotate: 0 }\n                        }\n                        transition={{ duration: 0.5, ease: [0.1, 1, 0.3, 1] }}\n                    />\n                ))}\n            </div>\n\n            {/* Folder */}\n            <motion.div\n                className=\"relative cursor-pointer aspect-[20/16]\"\n                animate={isHovered ? { scale: 0.85 } : { scale: 1 }}\n                transition={{ duration: 0.5, ease: [0.1, 1, 0.3, 1] }}\n            >\n                {/* Back */}\n                <div className={cn(\"absolute inset-0\", colors.back)}>\n                    <FolderBackIcon />\n                </div>\n\n                {/* Cover */}\n                <div className={cn(\"relative\", colors.cover)}>\n                    <FolderCoverIcon />\n                    <div\n                        className={cn(\n                            \"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\",\n                            sizes.deco,\n                            colors.deco\n                        )}\n                    >\n                        <GlobeIcon />\n                    </div>\n                </div>\n            </motion.div>\n\n            {label && (\n                <h3 className={cn(\"mt-3 font-medium text-center\", sizes.caption, colors.caption)}>\n                    {label}\n                </h3>\n            )}\n        </div>\n    );\n};\n\nconst ShaktiFolder: React.FC<{\n    images: string[];\n    isHovered: boolean;\n    colors: typeof variantColors.shakti;\n    sizes: typeof sizeConfig.md;\n    label?: string;\n}> = ({ images, isHovered, colors, sizes, label }) => {\n    return (\n        <motion.div\n            className=\"relative\"\n            animate={isHovered ? { y: 15 } : { y: 0 }}\n            transition={{ duration: 0.4, ease: [0.2, 1, 0.3, 1] }}\n        >\n            <div className=\"relative cursor-pointer\">\n                {/* Back */}\n                <div className={cn(\"absolute inset-0\", colors.back)}>\n                    <FolderBackIcon />\n                </div>\n\n                {/* Previews - Fan animation */}\n                <div className={cn(\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\", sizes.thumb)}>\n                    {images.map((img, i) => (\n                        <motion.img\n                            key={i}\n                            src={img}\n                            alt=\"\"\n                            className=\"absolute w-12 h-16 object-cover rounded shadow-lg origin-[-600%_50%]\"\n                            initial={{ opacity: 0, rotate: 0 }}\n                            animate={\n                                isHovered\n                                    ? { opacity: 1, rotate: -10 * (images.length - i - 1) - 15 }\n                                    : { opacity: 0, rotate: 0 }\n                            }\n                            transition={{\n                                duration: 0.5,\n                                delay: i * 0.08,\n                                ease: [0.1, 1, 0.3, 1],\n                            }}\n                        />\n                    ))}\n                </div>\n\n                {/* Cover */}\n                <div className={cn(\"relative\", colors.cover)}>\n                    <FolderCoverIcon />\n                    <div\n                        className={cn(\n                            \"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 mt-1\",\n                            sizes.deco,\n                            colors.deco\n                        )}\n                    >\n                        <PadlockIcon />\n                    </div>\n                </div>\n            </div>\n\n            {label && (\n                <h3 className={cn(\"mt-3 font-medium text-center\", sizes.caption, colors.caption)}>\n                    {label}\n                </h3>\n            )}\n        </motion.div>\n    );\n};\n\nconst KuberaFolder: React.FC<{\n    images: string[];\n    isHovered: boolean;\n    colors: typeof variantColors.kubera;\n    sizes: typeof sizeConfig.md;\n    label?: string;\n}> = ({ images, isHovered, colors, sizes, label }) => {\n    const floatingMotions = React.useMemo(\n        () =>\n            images.map((_, i) => ({\n                y: -200 - ((i * 17) % 50),\n                x: ((i * 29) % 50) - 25,\n                rotate: ((i * 19) % 40) - 20,\n            })),\n        [images]\n    );\n\n    return (\n        <div className=\"relative\">\n            <div className=\"relative cursor-pointer\" style={{ perspective: \"800px\" }}>\n                {/* Back */}\n                <div className={cn(\"absolute inset-0\", colors.back)}>\n                    <FolderBackIcon />\n                </div>\n\n                {/* Paper Sheet Deco */}\n                <div className=\"absolute bottom-0.5 left-0.5 right-0.5 h-3/4 bg-white dark:bg-gray-200 rounded-lg\" />\n\n                {/* Floating Previews */}\n                <div className={cn(\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\", sizes.thumb)}>\n                    {images.map((img, i) => (\n                        <motion.img\n                            key={i}\n                            src={img}\n                            alt=\"\"\n                            className=\"absolute w-full h-full object-cover rounded-lg shadow-lg\"\n                            initial={{ opacity: 0 }}\n                            animate={\n                                isHovered\n                                    ? {\n                                        opacity: [1, 0],\n                                        y: [0, floatingMotions[i]?.y ?? -200],\n                                        x: floatingMotions[i]?.x ?? 0,\n                                        rotate: floatingMotions[i]?.rotate ?? 0,\n                                    }\n                                    : { opacity: 0 }\n                            }\n                            transition={{\n                                duration: 0.4,\n                                delay: i * 0.3,\n                                repeat: isHovered ? Infinity : 0,\n                                ease: \"linear\",\n                            }}\n                        />\n                    ))}\n                </div>\n\n                {/* Cover */}\n                <motion.div\n                    className={cn(\"relative\", colors.cover)}\n                    style={{ transformOrigin: \"50% 100%\", transformStyle: \"preserve-3d\" }}\n                    animate={isHovered ? { rotateX: -40 } : { rotateX: 0 }}\n                    transition={{ duration: 0.4, ease: [0.16, 1, 0.3, 1] }}\n                >\n                    <FolderCoverIcon />\n                    <div\n                        className={cn(\n                            \"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 mt-1\",\n                            sizes.deco,\n                            colors.deco\n                        )}\n                    >\n                        <CloudIcon />\n                    </div>\n                </motion.div>\n            </div>\n\n            {label && (\n                <h3 className={cn(\"mt-3 font-medium text-center\", sizes.caption, colors.caption)}>\n                    {label}\n                </h3>\n            )}\n        </div>\n    );\n};\n\nconst HariFolder: React.FC<{\n    images: string[];\n    isHovered: boolean;\n    colors: typeof variantColors.hari;\n    sizes: typeof sizeConfig.md;\n    label?: string;\n}> = ({ images, isHovered, colors, sizes, label }) => {\n    const positions = createCircularPositions(images.length, 120);\n\n    return (\n        <div className=\"relative\">\n            {/* Feedback Circle */}\n            <motion.div\n                className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-14 h-14 rounded-full bg-sky-500\"\n                initial={{ opacity: 0, scale: 1 }}\n                animate={\n                    isHovered ? { opacity: [1, 0], scale: [1, 15] } : { opacity: 0, scale: 1 }\n                }\n                transition={{ duration: 1.1, delay: 0.2, ease: [0.1, 1, 0.3, 1] }}\n            />\n\n            {/* Jumping Previews */}\n            <div className={cn(\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\", sizes.thumb)}>\n                {images.map((img, i) => (\n                    <motion.img\n                        key={i}\n                        src={img}\n                        alt=\"\"\n                        className=\"absolute w-12 h-16 object-cover rounded shadow-lg\"\n                        initial={{ opacity: 0, scale: 0.5, x: 0, y: 0 }}\n                        animate={\n                            isHovered\n                                ? {\n                                    opacity: 1,\n                                    scale: 1,\n                                    x: -positions[i]?.x || 0,\n                                    y: -positions[i]?.y || 0,\n                                }\n                                : { opacity: 0, scale: 0.5, x: 0, y: 0 }\n                        }\n                        transition={{\n                            duration: 0.8,\n                            delay: 0.2,\n                            type: \"spring\",\n                            stiffness: 200,\n                            damping: 15,\n                        }}\n                    />\n                ))}\n            </div>\n\n            <motion.div\n                className=\"relative cursor-pointer\"\n                style={{ perspective: \"800px\", transformOrigin: \"50% 100%\" }}\n                animate={\n                    isHovered\n                        ? { y: -20, scaleX: 0.9, scaleY: 0.9 }\n                        : { y: 0, scaleX: 1, scaleY: 1 }\n                }\n                transition={{\n                    duration: 0.8,\n                    type: \"spring\",\n                    stiffness: 200,\n                    damping: 15,\n                }}\n            >\n                {/* Back */}\n                <div className={cn(\"absolute inset-0\", colors.back)}>\n                    <FolderBackIcon />\n                </div>\n\n                {/* Paper Sheet Deco */}\n                <div className=\"absolute bottom-0.5 left-0.5 right-0.5 h-3/4 bg-white/80 rounded-lg\" />\n\n                {/* Cover */}\n                <motion.div\n                    className={cn(\"relative\", colors.cover)}\n                    style={{ transformOrigin: \"50% 100%\", transformStyle: \"preserve-3d\" }}\n                    animate={isHovered ? { rotateX: -25 } : { rotateX: 0 }}\n                    transition={{ duration: 0.4, delay: 0.2, ease: [0.16, 1, 0.3, 1] }}\n                >\n                    <FolderCoverIcon />\n                    <div\n                        className={cn(\n                            \"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 mt-1\",\n                            sizes.deco,\n                            colors.deco\n                        )}\n                    >\n                        <GlobeIcon />\n                    </div>\n                </motion.div>\n            </motion.div>\n\n            <motion.h3\n                className={cn(\"mt-3 font-medium text-center\", sizes.caption, colors.caption)}\n                animate={isHovered ? { opacity: 0 } : { opacity: 1 }}\n                transition={{ delay: isHovered ? 0.3 : 0 }}\n            >\n                {label}\n            </motion.h3>\n        </div>\n    );\n};\n\nconst RaviFolder: React.FC<{\n    images: string[];\n    isHovered: boolean;\n    colors: typeof variantColors.ravi;\n    sizes: typeof sizeConfig.md;\n    label?: string;\n}> = ({ images, isHovered, colors, sizes, label }) => {\n    // Reorder images for card-spread effect\n    const reorder = (arr: string[]) => {\n        const result: string[] = [];\n        let i = Math.ceil(arr.length / 2);\n        let j = i - 1;\n        while (j >= 0) {\n            result.push(arr[j--]);\n            if (i < arr.length) result.push(arr[i++]);\n        }\n        return result;\n    };\n\n    const orderedImages = React.useMemo(() => reorder(images), [images]);\n\n    return (\n        <div className=\"relative\">\n            {/* Feedback Circle */}\n            <motion.div\n                className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-14 h-14 rounded-full bg-white\"\n                initial={{ opacity: 0, scale: 1 }}\n                animate={\n                    !isHovered ? { opacity: [1, 0], scale: [1, 5] } : { opacity: 0, scale: 1 }\n                }\n                transition={{ duration: 0.8, delay: 0.35, ease: [0.1, 1, 0.3, 1] }}\n            />\n\n            <div className=\"relative cursor-pointer\" style={{ perspective: \"800px\" }}>\n                {/* Back */}\n                <div className={cn(\"absolute inset-0\", colors.back)}>\n                    <FolderBackIcon />\n                </div>\n\n                {/* Paper Sheet */}\n                <div className=\"absolute bottom-0.5 left-0.5 right-0.5 h-3/4 bg-white rounded-lg\" />\n\n                {/* Card Spread Previews */}\n                <div className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[75px] h-[65px]\">\n                    {orderedImages.map((img, i) => {\n                        const interval = 60;\n                        const c = orderedImages.length;\n                        const x =\n                            -interval * Math.floor(c / 2) + interval * i + (c % 2 === 0 ? interval / 2 : 0);\n                        const rotateInterval = 20;\n                        const rotate =\n                            -rotateInterval * Math.floor(c / 2) +\n                            rotateInterval * i +\n                            (c % 2 === 0 ? rotateInterval / 2 : 0);\n\n                        return (\n                            <motion.img\n                                key={i}\n                                src={img}\n                                alt=\"\"\n                                className=\"absolute w-full h-full object-cover rounded shadow-lg\"\n                                initial={{ opacity: 0, x: 0, y: 0, rotate: 0, scale: 1 }}\n                                animate={\n                                    isHovered\n                                        ? { opacity: 1, y: -70, x, rotate }\n                                        : { opacity: 0, x: 0, y: 0, rotate: 0, scale: 0.5 }\n                                }\n                                transition={{\n                                    duration: isHovered ? 0.4 : 0.3,\n                                    ease: isHovered ? [0.1, 1, 0.3, 1] : \"easeInOut\",\n                                }}\n                            />\n                        );\n                    })}\n                </div>\n\n                {/* Cover */}\n                <motion.div\n                    className={cn(\"relative\", colors.cover)}\n                    style={{ transformOrigin: \"50% 100%\", transformStyle: \"preserve-3d\" }}\n                    animate={isHovered ? { rotateX: -30 } : { rotateX: 0 }}\n                    transition={{\n                        duration: 0.4,\n                        delay: isHovered ? 0 : 0.3,\n                        ease: [0.16, 1, 0.3, 1],\n                    }}\n                >\n                    <FolderCoverIcon />\n                    <div\n                        className={cn(\n                            \"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 mt-1\",\n                            sizes.deco,\n                            colors.deco\n                        )}\n                    >\n                        <PadlockIcon />\n                    </div>\n                </motion.div>\n            </div>\n\n            {label && (\n                <h3 className={cn(\"mt-3 font-medium text-center\", sizes.caption, colors.caption)}>\n                    {label}\n                </h3>\n            )}\n        </div>\n    );\n};\n\nconst DurgaFolder: React.FC<{\n    files: { name: string; type?: string }[];\n    isHovered: boolean;\n    colors: typeof variantColors.durga;\n    sizes: typeof sizeConfig.md;\n    label?: string;\n}> = ({ files, isHovered, colors, sizes, label }) => {\n    return (\n        <div className=\"relative\">\n            {/* Text Preview - shows file list inside a tooltip bubble */}\n            <motion.div\n                className=\"absolute -right-2 top-0 bg-gray-800 dark:bg-gray-900 rounded-lg px-3 py-2 shadow-lg z-20 min-w-[100px]\"\n                initial={{ opacity: 0, x: -10, scale: 0.9 }}\n                animate={isHovered ? { opacity: 1, x: 0, scale: 1 } : { opacity: 0, x: -10, scale: 0.9 }}\n                transition={{ duration: 0.3, ease: [0.16, 1, 0.3, 1] }}\n                style={{ transform: 'translateX(100%)' }}\n            >\n                {files.slice(0, 6).map((file, i) => (\n                    <motion.div\n                        key={i}\n                        className=\"text-gray-100 font-mono text-xs py-0.5 whitespace-nowrap\"\n                        initial={{ opacity: 0 }}\n                        animate={{ opacity: isHovered ? 1 : 0 }}\n                        transition={{ duration: 0.05, delay: i * 0.03 }}\n                    >\n                        {file.name}\n                    </motion.div>\n                ))}\n            </motion.div>\n\n            {/* Folder */}\n            <div className=\"relative cursor-pointer aspect-[20/16]\" style={{ perspective: \"800px\" }}>\n                {/* Back */}\n                <div className={cn(\"absolute inset-0\", colors.back)}>\n                    <FolderBackIcon />\n                </div>\n\n                {/* Paper Sheet */}\n                <div className=\"absolute bottom-0.5 left-0.5 right-0.5 h-3/4 bg-white dark:bg-gray-200 rounded-lg\" />\n\n                {/* Cover */}\n                <motion.div\n                    className={cn(\"relative\", colors.cover)}\n                    style={{ transformOrigin: \"50% 100%\", transformStyle: \"preserve-3d\" }}\n                    animate={isHovered ? { rotateX: -30 } : { rotateX: 0 }}\n                    transition={{ duration: 0.3, ease: [0.16, 1, 0.3, 1] }}\n                >\n                    <FolderCoverIcon />\n                    <div\n                        className={cn(\n                            \"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\",\n                            sizes.deco,\n                            colors.deco\n                        )}\n                    >\n                        <GlobeIcon />\n                    </div>\n                </motion.div>\n            </div>\n\n            {label && (\n                <h3 className={cn(\"mt-3 font-medium text-center\", sizes.caption, colors.caption)}>\n                    {label}\n                </h3>\n            )}\n        </div>\n    );\n};\n\nconst NandiFolder: React.FC<{\n    files: { name: string; type?: string }[];\n    isHovered: boolean;\n    colors: typeof variantColors.nandi;\n    sizes: typeof sizeConfig.md;\n    label?: string;\n}> = ({ files, isHovered, colors, sizes, label }) => {\n    const fileColorMap: Record<string, string> = {\n        txt: \"fill-blue-300\",\n        gif: \"fill-teal-400\",\n        mp3: \"fill-amber-400\",\n        default: \"fill-gray-400\",\n    };\n\n    return (\n        <div className=\"relative\">\n            {/* Magnifier Preview - compact bubble above folder */}\n            <motion.div\n                className=\"absolute left-1/2 -translate-x-1/2 bg-white dark:bg-gray-100 rounded-2xl shadow-xl z-20 p-3 grid grid-cols-3 gap-2\"\n                style={{ bottom: '100%', marginBottom: '8px', minWidth: '120px' }}\n                initial={{ opacity: 0, scale: 0.8, y: 10 }}\n                animate={\n                    isHovered\n                        ? { opacity: 1, scale: 1, y: 0 }\n                        : { opacity: 0, scale: 0.8, y: 10 }\n                }\n                transition={{ duration: 0.3, ease: [0.16, 1, 0.3, 1] }}\n            >\n                {files.slice(0, 6).map((file, i) => (\n                    <div key={i} className=\"text-center\">\n                        <FileIcon\n                            className={cn(\"w-5 h-5 mx-auto\", fileColorMap[file.type || \"default\"])}\n                        />\n                        <span className=\"text-[8px] text-gray-600 block mt-0.5 truncate max-w-[35px]\">\n                            {file.name}\n                        </span>\n                    </div>\n                ))}\n            </motion.div>\n\n            {/* Folder */}\n            <div className=\"relative cursor-pointer aspect-[20/16]\" style={{ perspective: \"800px\" }}>\n                {/* Back */}\n                <div className={cn(\"absolute inset-0\", colors.back)}>\n                    <FolderBackIcon />\n                </div>\n\n                {/* Paper Sheet */}\n                <div className=\"absolute bottom-0.5 left-0.5 right-0.5 h-3/4 bg-white dark:bg-gray-200 rounded-lg\" />\n\n                {/* Cover */}\n                <motion.div\n                    className={cn(\"relative\", colors.cover)}\n                    style={{ transformOrigin: \"50% 100%\", transformStyle: \"preserve-3d\" }}\n                    animate={isHovered ? { rotateX: -30 } : { rotateX: 0 }}\n                    transition={{ duration: 0.3, ease: [0.16, 1, 0.3, 1] }}\n                >\n                    <FolderCoverIcon />\n                    <div\n                        className={cn(\n                            \"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\",\n                            sizes.deco,\n                            colors.deco\n                        )}\n                    >\n                        <CloudIcon />\n                    </div>\n                </motion.div>\n            </div>\n\n            {label && (\n                <h3 className={cn(\"mt-3 font-medium text-center\", sizes.caption, colors.caption)}>\n                    {label}\n                </h3>\n            )}\n        </div>\n    );\n};\n\n// ============================================\n// Main FolderPreview Component\n// ============================================\n\nexport const FolderPreview = React.forwardRef<HTMLDivElement, FolderPreviewProps>(\n    (\n        {\n            variant = \"devi\",\n            images = [],\n            files = [],\n            label,\n            size = \"md\",\n            className,\n            onClick,\n        },\n        ref\n    ) => {\n        const [isHovered, setIsHovered] = React.useState(false);\n        const colors = variantColors[variant];\n        const sizes = sizeConfig[size];\n\n        const defaultImages = [\n            \"/folder-preview/user1.svg\",\n            \"/folder-preview/user2.svg\",\n            \"/folder-preview/user3.svg\",\n            \"/folder-preview/user4.svg\",\n            \"/folder-preview/user5.svg\",\n        ];\n\n        const defaultFiles = [\n            { name: \"docs\", type: \"default\" as const },\n            { name: \"template\", type: \"default\" as const },\n            { name: \"readme.md\", type: \"txt\" as const },\n            { name: \"app.js\", type: \"txt\" as const },\n            { name: \"test.sh\", type: \"txt\" as const },\n            { name: \"package.json\", type: \"txt\" as const },\n            { name: \"logo.svg\", type: \"default\" as const },\n            { name: \"...\", type: \"default\" as const },\n        ];\n\n        const imageList = images.length > 0 ? images : defaultImages;\n        const fileList = files.length > 0 ? files : defaultFiles;\n\n        const renderFolder = () => {\n            const props = { isHovered, colors, sizes, label };\n\n            switch (variant) {\n                case \"devi\":\n                    return <DeviFolder images={imageList} {...props} />;\n                case \"rudras\":\n                    return <RudrasFolder images={imageList} {...props} />;\n                case \"ardra\":\n                    return <ArdraFolder images={imageList} {...props} />;\n                case \"shakti\":\n                    return <ShaktiFolder images={imageList} {...props} />;\n                case \"kubera\":\n                    return <KuberaFolder images={imageList} {...props} />;\n                case \"hari\":\n                    return <HariFolder images={imageList} {...props} />;\n                case \"ravi\":\n                    return <RaviFolder images={imageList} {...props} />;\n                case \"durga\":\n                    return <DurgaFolder files={fileList} {...props} />;\n                case \"nandi\":\n                    return <NandiFolder files={fileList} {...props} />;\n                default:\n                    return <DeviFolder images={imageList} {...props} />;\n            }\n        };\n\n        return (\n            <div\n                ref={ref}\n                className={cn(\"inline-flex flex-col items-center overflow-visible\", sizes.folder, className)}\n                onMouseEnter={() => setIsHovered(true)}\n                onMouseLeave={() => setIsHovered(false)}\n                onClick={onClick}\n            >\n                {renderFolder()}\n            </div>\n        );\n    }\n);\n\nFolderPreview.displayName = \"FolderPreview\";\n\nexport default FolderPreview;\n",
      "type": "registry:ui",
      "target": "components/ui/folder-preview.tsx"
    }
  ]
}
