{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "testimonial-grid",
  "title": "Testimonial Grid",
  "author": "mrap10",
  "description": "Multi-column testimonial grid with tidy profile cards.",
  "dependencies": ["motion"],
  "files": [
    {
      "path": "registry/default/testimonials/testimonial-grid.tsx",
      "content": "\"use client\";\n\nimport { motion } from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\n\ntype TestimonialQuote = {\n  lead: string;\n  highlight?: string;\n  tail?: string;\n};\n\ntype TestimonialItem = {\n  name: string;\n  imageSrc: string;\n  position: string;\n  company: string;\n  quote: TestimonialQuote | string;\n  imageAlt?: string;\n};\n\ntype TestimonialGridProps = {\n  title?: string | null;\n  items?: TestimonialItem[];\n  className?: string;\n  gridClassName?: string;\n  cardClassName?: string;\n  highlightClassName?: string;\n};\n\ntype TestimonialGridCardProps = TestimonialItem & {\n  className?: string;\n  highlightClassName?: string;\n};\n\nconst DEFAULT_TITLE = \"Here's what others say about Refinery!\";\n\nconst DEFAULT_TESTIMONIALS: TestimonialItem[] = [\n  {\n    name: \"Murdo Aten Alescio\",\n    imageSrc:\n      \"https://images.unsplash.com/photo-1674851993235-f730432c37f8?q=80&w=687\",\n    position: \"Chief Technology Officer\",\n    company: \"Toogle\",\n    quote: {\n      lead: \"I just love Refinery. It\",\n      highlight:\n        \"gives us a refined design system with best-in-class web interactions\",\n      tail: \"we can browse, adopt, and ship quickly.\",\n    },\n  },\n  {\n    name: \"Danielle Porter\",\n    imageSrc:\n      \"https://res.cloudinary.com/dbglon4f7/image/upload/v1777228990/danielle_ilgbqd.png\",\n    position: \"Lead Designer\",\n    company: \"TouYube\",\n    quote: {\n      lead: \"Refinery exceeded my expectations as a design system inspired by the web's best interactions. It\",\n      highlight: \"helps us discover elevated patterns, align design decisions,\",\n      tail: \"and deliver a premium product feel.\",\n    },\n  },\n  {\n    name: \"Monica Witkowska\",\n    imageSrc:\n      \"https://res.cloudinary.com/dbglon4f7/image/upload/v1777228970/monica_yai9gl.png\",\n    position: \"Frontend Engineer\",\n    company: \"Metamine\",\n    quote: {\n      lead: \"Refinery has become essential for our frontend team. We browse interaction patterns and beautifully refined components, then\",\n      highlight: \"integrate Refinery into our product with minimal friction.\",\n    },\n  },\n  {\n    name: \"Tuor Håkansson\",\n    imageSrc:\n      \"https://images.unsplash.com/photo-1631885628726-d60689c330db?q=80&w=685\",\n    position: \"SDE II\",\n    company: \"Z Combinator\",\n    quote: {\n      lead: \"Refinery has been a game-changer for our team. Instead of starting from scratch.\",\n      highlight:\n        \"We explore top interaction patterns and refined UI examples, then implement them with confidence.\",\n    },\n  },\n];\n\nexport function TestimonialGrid({\n  title = DEFAULT_TITLE,\n  items,\n  className,\n  gridClassName,\n  cardClassName,\n  highlightClassName,\n}: TestimonialGridProps) {\n  const resolvedItems = items?.length ? items : DEFAULT_TESTIMONIALS;\n\n  return (\n    <div className={cn(\"flex flex-col gap-5\", className)}>\n      {title ? (\n        <h3 className=\"font-serif text-3xl font-medium tracking-tight text-neutral-700 dark:text-neutral-300\">\n          {title}\n        </h3>\n      ) : null}\n      <div\n        className={cn(\n          \"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\",\n          gridClassName\n        )}\n      >\n        {resolvedItems.map((item, index) => (\n          <motion.div\n            key={`${item.name}-${index}`}\n            initial={{ opacity: 0, y: 12 }}\n            whileInView={{ opacity: 1, y: 0 }}\n            viewport={{ once: true, margin: \"-40px\" }}\n            transition={{\n              duration: 0.4,\n              delay: index * 0.06,\n              ease: [0.22, 1, 0.36, 1],\n            }}\n          >\n            <TestimonialGridCard\n              {...item}\n              className={cardClassName}\n              highlightClassName={highlightClassName}\n            />\n          </motion.div>\n        ))}\n      </div>\n    </div>\n  );\n}\n\nexport function TestimonialGridCard({\n  name,\n  imageSrc,\n  position,\n  company,\n  quote,\n  imageAlt,\n  className,\n  highlightClassName,\n}: TestimonialGridCardProps) {\n  const resolvedQuote = typeof quote === \"string\" ? { lead: quote } : quote;\n  const { lead, highlight, tail } = resolvedQuote;\n  const resolvedAlt = imageAlt ?? name;\n\n  return (\n    <div\n      className={cn(\n        \"group flex h-full flex-col gap-5 rounded-lg bg-neutral-100 px-4 py-4 shadow-[0px_0px_1px_0.5px_rgba(0,0,0,0.1)] hover:shadow-[0px_0px_1px_1px_rgba(0,0,0,0.1)] dark:bg-neutral-900\",\n        className\n      )}\n    >\n      <div className=\"flex gap-4\">\n        <img\n          src={imageSrc}\n          alt={resolvedAlt}\n          width={56}\n          height={56}\n          loading=\"lazy\"\n          decoding=\"async\"\n          className=\"aspect-square rounded-md object-cover grayscale-100 group-hover:grayscale-0\"\n        />\n        <div className=\"flex flex-col gap-px\">\n          <h3 className=\"text-sm font-medium text-neutral-900 dark:text-neutral-100\">\n            {name}\n          </h3>\n          <p className=\"text-xs text-neutral-600 dark:text-neutral-500\">\n            {position}\n          </p>\n          <span className=\"text-xs text-neutral-400 dark:text-neutral-400\">\n            {company}\n          </span>\n        </div>\n      </div>\n      <q className=\"text-lg leading-7 font-medium text-neutral-600/70 transition-colors duration-200 group-hover:text-neutral-800 dark:text-neutral-400/70 dark:group-hover:text-neutral-200\">\n        {lead}\n        {highlight ? (\n          <>\n            {\" \"}\n            <span\n              className={cn(\n                \"text-neutral-700 group-hover:text-neutral-800 dark:text-neutral-300 dark:group-hover:text-neutral-200\",\n                highlightClassName\n              )}\n            >\n              {highlight}\n            </span>\n          </>\n        ) : null}\n        {tail ? <> {tail}</> : null}\n      </q>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "categories": ["testimonials"],
  "type": "registry:component"
}
