{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "shake-testimonial-card",
  "title": "Shake Testimonial Card",
  "description": "An eye-catching testimonial card with playful animations.",
  "dependencies": [
    "motion",
    "@hugeicons/core-free-icons",
    "@hugeicons/react",
    "clsx",
    "tailwind-merge"
  ],
  "files": [
    {
      "path": "registry/default/example/shake-testimonial-card.tsx",
      "content": "\"use client\";\n\nimport React, { useState, useEffect, useCallback } from \"react\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\n\ninterface Testimonial {\n  id: number;\n  name: string;\n  role: string;\n  avatar: string;\n  content: string;\n  color: string;\n  textColor: string;\n}\n\n// Change Here\nconst testimonials: Testimonial[] = [\n  {\n    id: 1,\n    name: \"Marcus Thorne\",\n    role: \"Head of Product, EcoStream\",\n    avatar: \"/ui/memoji/1.svg\",\n    content:\n      \"The interface is so intuitive that our team was up and running in hours. Highly recommended for fast-moving startups.\",\n    color: \"#E0F2FE\",\n    textColor: \"#1E3A8A\",\n  },\n  {\n    id: 2,\n    name: \"Elena Rodriguez\",\n    role: \"Director of UX, CreativeFlow\",\n    avatar: \"/ui/memoji/6.svg\",\n    content:\n      \"We've tried dozens of tools, but this one stands out for its elegant design. It's a game-changer for our workflow.\",\n    color: \"#F3E8FF\",\n    textColor: \"#581C87\",\n  },\n  {\n    id: 3,\n    name: \"Sarah Jenkins\",\n    role: \"CEO, TechNova\",\n    avatar: \"/ui/memoji/4.svg\",\n    content:\n      \"Scaling our infrastructure used to be a nightmare until we found this platform. Now we can focus on building features.\",\n    color: \"#DCFCE7\",\n    textColor: \"#064E3B\",\n  },\n  {\n    id: 4,\n    name: \"David Kim\",\n    role: \"CTO, NextGen Solutions\",\n    avatar: \"/ui/memoji/6.svg\",\n    content:\n      \"The security features alone are worth every penny. Our clients feel safer knowing their data is protected by encryption.\",\n    color: \"#FEF9C3\",\n    textColor: \"#713F12\",\n  },\n];\n\nexport default function ShakeTestimonial() {\n  const [cards, setCards] = useState(testimonials);\n  const [isAnimating, setIsAnimating] = useState(false);\n\n  const handleNext = useCallback(() => {\n    if (isAnimating) return;\n    setIsAnimating(true);\n\n    setTimeout(() => {\n      setCards((prev) => {\n        const [first, ...rest] = prev;\n        return [...rest, first];\n      });\n      setIsAnimating(false);\n    }, 600);\n  }, [isAnimating]);\n\n  useEffect(() => {\n    const interval = setInterval(() => {\n      handleNext();\n    }, 1500);\n    return () => clearInterval(interval);\n  }, [handleNext]);\n\n  return (\n    <div className=\"flex items-center justify-center w-full bg-transparent p-4 overflow-hidden py-4 min-h-[650px] max-sm:min-h-[500px]\">\n      <div\n        className=\"relative w-full max-w-[370px] h-[240px] lg:max-w-[440px] lg:h-[310px] md:h-[320px]\"\n        style={{ perspective: \"1200px\" }}\n      >\n        <AnimatePresence mode=\"popLayout\">\n          {cards.map((card, index) => {\n            const isTop = index === 0;\n\n            return (\n              <motion.div\n                key={card.id}\n                layout\n                style={{\n                  backgroundColor: card.color,\n                  zIndex: testimonials.length - index,\n                  position: \"absolute\",\n                  top: 0,\n                  left: 0,\n                  transformOrigin: \"center center\",\n                  borderColor: `${card.textColor}20`,\n                }}\n                initial={{\n                  scale: 0.7,\n                  opacity: 0,\n                  y: 40,\n                  rotateX: -20,\n                }}\n                animate={{\n                  scale:\n                    isTop && isAnimating\n                      ? [1, 1.05, 1, 1.05, 1, 1, 0.9]\n                      : 1 - index * 0.05,\n                  y:\n                    isTop && isAnimating\n                      ? [0, 0, 0, 0, 0, 0, -300]\n                      : index * 15,\n                  rotateX:\n                    isTop && isAnimating ? [0, 0, 0, 0, 0, 0, 15] : -index * 2,\n                  x: isTop && isAnimating ? [0, -12, 12, -12, 12, 0, 0] : 0,\n                  rotate: isTop && isAnimating ? [0, -2, 2, -2, 2, 0, -5] : 0,\n\n                  opacity: index < 4 ? 1 : 0,\n\n                  transition:\n                    isTop && isAnimating\n                      ? {\n                          duration: 0.6,\n                          times: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 1],\n                          ease: \"easeOut\",\n                        }\n                      : {\n                          type: \"spring\",\n                          stiffness: 400,\n                          damping: 30,\n                          mass: 0.6,\n                        },\n                }}\n                className={cn(\n                  \"w-full h-full rounded-[48px] p-8 md:p-10  shadow-[0_12px_20px_rgba(0,0,0,0.03)]\",\n                  \"border flex flex-col justify-between overflow-hidden\",\n                  \"cursor-pointer select-none ring-1 ring-black/5 backdrop-blur-3xl\",\n                  \"preserve-3d transition-shadow duration-500 hover:shadow-[0_13px_60px_rgba(0,0,0,0.1)]\"\n                )}\n                onClick={handleNext}\n              >\n                <div className=\"flex flex-col gap-4 md:gap-6 \">\n                  <div className=\"flex items-center gap-3\">\n                    <div className=\"flex items-center justify-center w-12 h-12 bg-white/50 rounded-2xl shadow-inner border border-black/5 overflow-hidden shrink-0 lg:w-14 lg:h-14 max-sm:rounded-xl\">\n                      <img\n                        src={card.avatar}\n                        className=\"w-full h-full object-contain\"\n                        alt={card.name}\n                      />\n                    </div>\n\n                    <div className=\"flex flex-col justify-center\">\n                      <h3\n                        className=\"font-bold text-lg md:text-xl leading-tight !p-0 !m-0 max-sm:text-base \"\n                        style={{ color: card.textColor }}\n                      >\n                        {card.name}\n                      </h3>\n                      <p\n                        className=\"text-xs lg:text-sm opacity-60  !p-0 !m-0  max-sm:text-xss\"\n                        style={{ color: card.textColor }}\n                      >\n                        {card.role}\n                      </p>\n                    </div>\n                  </div>\n                  <p\n                    className=\"text-xl font-serif font-medium leading-[1.3] tracking-tight italic  lg:text-2xl md:text-2xl max-sm:text-lg !p-0 !m-0\"\n                    style={{ color: card.textColor }}\n                  >\n                    \"{card.content}\"\n                  </p>\n                </div>\n              </motion.div>\n            );\n          })}\n        </AnimatePresence>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}