{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "feature-tour",
  "type": "registry:component",
  "title": "Feature Tour",
  "description": "A premium guided tour component with blur animations, shining titles, and intuitive navigation.",
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "files": [
    {
      "path": "components/watermelon/feature-tour.tsx",
      "type": "registry:component",
      "content": "\"use client\";\n\nimport React, { useState, useEffect, useRef, useCallback } from \"react\";\nimport {\n    motion,\n    AnimatePresence,\n    useReducedMotion,\n    type Transition,\n} from \"motion/react\";\nimport { X } from \"lucide-react\";\n\nexport interface TourStep {\n    id: string;\n    title: string;\n    description: string;\n    icon: React.ReactNode;\n}\n\ninterface FeatureTourProps {\n    steps: TourStep[];\n    onClose: () => void;\n    onLearnMore?: (step: TourStep) => void;\n    className?: string;\n    loop?: boolean;\n    closeOnBackdrop?: boolean;\n}\n\n/* ─────────────────────────\n   Typed Motion Curves\n───────────────────────── */\n\nconst EASE_OUT = [0.16, 1, 0.3, 1] as const;\nconst FAST_OUT = [0.22, 1, 0.36, 1] as const;\n\nconst SPRING_ICON: Transition = {\n    type: \"spring\",\n    stiffness: 420,\n    damping: 34,\n    mass: 0.7,\n};\n\nconst SPRING_BG: Transition = {\n    type: \"spring\",\n    stiffness: 340,\n    damping: 30,\n    mass: 0.8,\n};\n\nexport const FeatureTour: React.FC<FeatureTourProps> = ({\n    steps,\n    onClose,\n    onLearnMore,\n    className = \"\",\n    loop = false,\n    closeOnBackdrop = true,\n}) => {\n    const shouldReduceMotion = useReducedMotion();\n    const containerRef = useRef<HTMLDivElement>(null);\n    const [currentIndex, setCurrentIndex] = useState(0);\n\n\n    const goToStep = useCallback((index: number) => {\n        setCurrentIndex((prev) => (index === prev ? prev : index));\n    }, []);\n\n    const goNext = useCallback(() => {\n        setCurrentIndex((prev) =>\n            prev === steps.length - 1 ? (loop ? 0 : prev) : prev + 1\n        );\n    }, [loop, steps.length]);\n\n    const goPrev = useCallback(() => {\n        setCurrentIndex((prev) =>\n            prev === 0 ? (loop ? steps.length - 1 : prev) : prev - 1\n        );\n    }, [loop, steps.length]);\n\n    useEffect(() => {\n        const handleKeyDown = (e: KeyboardEvent) => {\n            if (e.key === \"ArrowRight\") goNext();\n            if (e.key === \"ArrowLeft\") goPrev();\n            if (e.key === \"Escape\") onClose();\n        };\n        window.addEventListener(\"keydown\", handleKeyDown);\n        return () => window.removeEventListener(\"keydown\", handleKeyDown);\n    }, [goNext, goPrev, onClose]);\n\n    useEffect(() => {\n        const btn = containerRef.current?.querySelector(\"button\");\n        btn?.focus();\n    }, []);\n\n    const currentStep = steps[currentIndex];\n\n    if (!steps || steps.length === 0) return null;\n\n    return (\n        <div\n            className=\"flex items-center justify-center\"\n            onClick={closeOnBackdrop ? onClose : undefined}\n            role=\"dialog\"\n            aria-modal=\"true\"\n        >\n            <motion.div\n                ref={containerRef}\n                onClick={(e) => e.stopPropagation()}\n                initial={{\n                    opacity: 0,\n                    scale: 0.96,\n                    y: 16,\n                    filter: \"blur(4px)\",\n                }}\n                animate={{\n                    opacity: 1,\n                    scale: 1,\n                    y: 0,\n                    filter: \"blur(0px)\",\n                }}\n                exit={{\n                    opacity: 0,\n                    scale: 0.98,\n                    y: 12,\n                }}\n                transition={{\n                    duration: 0.18,\n                    ease: EASE_OUT,\n                }}\n                className={`relative w-full max-w-[400px] sm:aspect-[1/1.3] min-h-[520px] sm:min-h-0 rounded-[34px] border shadow-sm p-6 sm:p-8 flex flex-col items-center overflow-hidden transition-colors duration-300 bg-white border-neutral-200 dark:bg-neutral-900 dark:border-neutral-800 ${className}`}\n            >\n                <button\n                    onClick={onClose}\n                    aria-label=\"Close tour\"\n                    className=\"absolute top-6 right-6 p-2 rounded-full transition-colors z-50 bg-neutral-300 hover:bg-neutral-400 dark:bg-neutral-800 dark:hover:bg-neutral-700\"\n                >\n                    <X\n                        size={20}\n                        strokeWidth={3}\n                        className=\"text-white dark:text-neutral-200\"\n                    />\n                </button>\n\n                <div className=\"flex-1 w-full flex flex-col items-center justify-center relative\">\n\n                    {/* Icon Morph */}\n                    <AnimatePresence mode=\"wait\">\n                        <motion.div\n                            key={currentStep.id}\n                            initial={{\n                                opacity: 0,\n                                scale: 0.92,\n                                y: 8,\n                                filter: \"blur(3px)\",\n                            }}\n                            animate={{\n                                opacity: 1,\n                                scale: 1,\n                                y: 0,\n                                filter: \"blur(0px)\",\n                            }}\n                            exit={{\n                                opacity: 0,\n                                scale: 0.92,\n                                y: -6,\n                                filter: \"blur(3px)\",\n                            }}\n                            transition={{\n                                duration: 0.16,\n                                ease: FAST_OUT,\n                            }}\n                            className=\"relative flex items-center justify-center min-h-[120px]\"\n                        >\n                            <motion.div\n                                layoutId=\"tour-icon-bg\"\n                                transition={SPRING_BG}\n                                className=\"absolute w-24 h-24 rounded-3xl\n                           bg-neutral-100 dark:bg-neutral-800\n                           shadow-inner dark:shadow-black/40\"\n                            />\n\n                            <motion.div\n                                layoutId=\"tour-icon\"\n                                transition={SPRING_ICON}\n                                className=\"relative text-neutral-700 dark:text-neutral-200\n                           drop-shadow-[0_4px_12px_rgba(0,0,0,0.12)]\n                           dark:drop-shadow-[0_4px_16px_rgba(255,255,255,0.12)]\"\n                            >\n                                {currentStep.icon}\n                            </motion.div>\n                        </motion.div>\n                    </AnimatePresence>\n\n                    {/* Content Slide */}\n                    <AnimatePresence mode=\"wait\">\n                        <motion.div\n                            key={`content-${currentStep.id}`}\n                            initial={{\n                                opacity: 0,\n                                y: shouldReduceMotion ? 0 : 20,\n                            }}\n                            animate={{\n                                opacity: 1,\n                                y: 0,\n                            }}\n                            exit={{\n                                opacity: 0,\n                                y: shouldReduceMotion ? 0 : -14,\n                            }}\n                            transition={{\n                                duration: 0.16,\n                                ease: EASE_OUT,\n                            }}\n                            className=\"space-y-2 px-4 mt-8 sm:mt-12 text-center\"\n                        >\n                            <h2 className=\"text-[26px] font-bold text-neutral-900 dark:text-white\">\n                                {currentStep.title}\n                            </h2>\n\n                            <p className=\"text-[20px] font-medium leading-tight text-neutral-500 dark:text-neutral-400\">\n                                {currentStep.description}\n                            </p>\n\n                            {onLearnMore && (\n                                <motion.button\n                                    whileHover={{ scale: 1.03 }}\n                                    whileTap={{ scale: 0.97 }}\n                                    transition={{\n                                        type: \"spring\",\n                                        stiffness: 400,\n                                        damping: 30,\n                                    }}\n                                    onClick={() => onLearnMore(currentStep)}\n                                    className=\"mt-6 sm:mt-10 px-10 py-3 rounded-full font-semibold text-lg transition-colors bg-neutral-100 text-neutral-700 hover:bg-neutral-200 dark:bg-neutral-800 dark:text-white dark:hover:bg-neutral-700\"\n                                >\n                                    Learn More\n                                </motion.button>\n                            )}\n                        </motion.div>\n                    </AnimatePresence>\n                </div>\n\n                {/* Dots */}\n                <div className=\"mt-6 sm:mt-8 flex items-center gap-3\" role=\"tablist\">\n                    {steps.map((step, index) => (\n                        <button\n                            key={step.id}\n                            role=\"tab\"\n                            aria-selected={index === currentIndex}\n                            aria-label={`Go to ${step.title}`}\n                            onClick={() => goToStep(index)}\n                            className=\"relative h-2 focus:outline-none\"\n                        >\n                            <motion.div\n                                animate={{\n                                    scale: index === currentIndex ? 1.2 : 1,\n                                }}\n                                transition={{\n                                    type: \"spring\",\n                                    stiffness: 300,\n                                    damping: 20,\n                                }}\n                                className={`h-[12px] w-[12px] rounded-full ${index === currentIndex\n                                    ? \"bg-neutral-500 dark:bg-neutral-200\"\n                                    : \"bg-neutral-200 dark:bg-neutral-700\"\n                                    }`}\n                            />\n                        </button>\n                    ))}\n                </div>\n\n                <div className=\"absolute inset-0 pointer-events-none rounded-[40px] bg-linear-to-br from-white/20 via-transparent to-black/5 dark:from-white/5 dark:via-transparent dark:to-black/40\" />\n            </motion.div>\n        </div>\n    );\n};"
    }
  ]
}
