{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "testimonial-02",
  "title": "Testimonial 02",
  "description": "Masonry grid wall-of-love section displaying multiple customer reviews in a varied layout. Use it on marketing sites where you have rich social proof and want to display it in a visually engaging way.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "card",
    "avatar",
    "button"
  ],
  "files": [
    {
      "path": "src/registry/blocks/testimonial-02/testimonial.tsx",
      "content": "import { cn } from \"@/lib/utils\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { Button } from \"@/components/ui/button\";\nimport { Star } from \"lucide-react\";\nimport { QuoteIcon } from \"@/components/social-icons\";\n\ninterface Testimonial {\n  type: \"text\" | \"image\" | \"cta\";\n  img?: string;\n  title?: string;\n  content?: string;\n  author?: {\n    name: string;\n    avatar?: string;\n  };\n  rating?: number;\n  button?: { text: string; url: string };\n}\n\ninterface Testimonial02Props {\n  label?: string;\n  title?: string;\n  description?: string;\n  testimonials?: Testimonial[];\n  className?: string;\n}\n\nconst StarRating = ({ rating = 5 }: { rating?: number }) => (\n  <div className=\"flex gap-0.5\">\n    {Array.from({ length: rating }).map((_, i) => (\n      <Star key={i} className=\"size-3.5 fill-yellow-400 text-yellow-400\" />\n    ))}\n  </div>\n);\n\nconst TestimonialCard = ({ testimonial }: { testimonial: Testimonial }) => {\n  if (testimonial.type === \"cta\") {\n    return (\n      <Card className=\"aspect-3/4 h-full bg-primary text-primary-foreground shadow-none\">\n        <CardContent className=\"flex h-full flex-col gap-4 p-6\">\n          <h3 className=\"text-xl font-medium\">{testimonial.title}</h3>\n          <p className=\"flex-1 text-sm opacity-90\">{testimonial.content}</p>\n          <Button variant=\"secondary\" className=\"w-full\" asChild>\n            <a href={testimonial.button?.url || \"#\"}>\n              {testimonial.button?.text}\n            </a>\n          </Button>\n        </CardContent>\n      </Card>\n    );\n  }\n\n  if (testimonial.type === \"image\") {\n    return (\n      <Card className=\"h-full py-0 shadow-none\">\n        <div className=\"aspect-3/4 h-full w-full overflow-hidden rounded-xl bg-muted\">\n          {testimonial.img && (\n            <img\n              src={testimonial.img}\n              alt=\"\"\n              className=\"size-full object-cover\"\n            />\n          )}\n        </div>\n      </Card>\n    );\n  }\n\n  return (\n    <Card className=\"h-full p-4 shadow-none\">\n      <CardContent className=\"flex h-full flex-col justify-between gap-12 p-0\">\n        <div className=\"flex flex-col gap-2\">\n          <QuoteIcon className=\"size-4 dark:invert\" />\n          {testimonial.title && (\n            <h4 className=\"text-2xl leading-tight\">{testimonial.title}</h4>\n          )}\n        </div>\n        <div className=\"flex flex-col gap-4\">\n          {testimonial.content && (\n            <p className=\"flex-1 text-muted-foreground\">\n              {testimonial.content}\n            </p>\n          )}\n          {testimonial.author && (\n            <div className=\"flex items-center gap-3\">\n              <Avatar className=\"size-8\">\n                <AvatarImage\n                  src={testimonial.author.avatar}\n                  alt={testimonial.author.name}\n                  className=\"object-cover\"\n                />\n                <AvatarFallback>\n                  {testimonial.author.name\n                    .split(\" \")\n                    .map((n) => n[0])\n                    .join(\"\")}\n                </AvatarFallback>\n              </Avatar>\n              <div className=\"flex flex-col gap-1\">\n                <StarRating rating={testimonial.rating} />\n                <span className=\"text-sm font-medium text-muted-foreground\">\n                  {testimonial.author.name}\n                </span>\n              </div>\n            </div>\n          )}\n        </div>\n      </CardContent>\n    </Card>\n  );\n};\n\nconst Testimonial02 = ({\n  label = \"Testimonials\",\n  title = \"Wall of Love\",\n  description = \"See what our customers are saying about their experience with our product.\",\n  testimonials = [\n    {\n      type: \"image\",\n      img: \"https://www.shadcnship.com/images/avatars/avatar-1.webp\",\n    },\n    {\n      type: \"text\",\n      title: \"Game Changer for Our Team!\",\n      content:\n        \"Daily support, tailored insights-Halse revolutionized my well-being. A most-have for a healthier life!\",\n      author: {\n        name: \"Emma Thompson\",\n        avatar: \"https://www.shadcnship.com/images/avatars/avatar-1.webp\",\n      },\n      rating: 5,\n    },\n    {\n      type: \"image\",\n      img: \"https://www.shadcnship.com/images/avatars/avatar-2.webp\",\n    },\n    {\n      type: \"text\",\n      title: \"Incredible Support!\",\n      content:\n        \"The customer support team is exceptional. They helped us get set up quickly and answered all our questions.\",\n      author: {\n        name: \"Emily Johnson\",\n        avatar: \"https://www.shadcnship.com/images/avatars/avatar-2.webp\",\n      },\n      rating: 5,\n    },\n    {\n      type: \"text\",\n      title: \"Streamlined Our Workflow!\",\n      content:\n        \"From day one, this tool has made our processes smoother. A game-changer for productivity.\",\n      author: {\n        name: \"Alex Rodriguez\",\n        avatar: \"https://www.shadcnship.com/images/avatars/avatar-3.webp\",\n      },\n      rating: 5,\n    },\n    {\n      type: \"image\",\n      img: \"https://www.shadcnship.com/images/avatars/avatar-3.webp\",\n    },\n    {\n      type: \"text\",\n      title: \"Best Decision We Made!\",\n      content:\n        \"Switching to this platform was the best decision for our business. Highly recommend!\",\n      author: {\n        name: \"Ryan Carter\",\n        avatar: \"https://www.shadcnship.com/images/avatars/avatar-4.webp\",\n      },\n      rating: 5,\n    },\n    {\n      type: \"image\",\n      img: \"https://www.shadcnship.com/images/avatars/avatar-4.webp\",\n    },\n    {\n      type: \"cta\",\n      title: \"Join Our Community\",\n      content:\n        \"Join thousands of happy customers who have transformed their workflow with our product.\",\n      button: { url: \"#\", text: \"Get Started\" },\n    },\n    {\n      type: \"text\",\n      title: \"Exceeded Expectations!\",\n      content:\n        \"We expected good, but got amazing. The features are exactly what we needed.\",\n      author: {\n        name: \"Jasmine Lee\",\n        avatar: \"https://www.shadcnship.com/images/avatars/avatar-5.webp\",\n      },\n      rating: 5,\n    },\n    {\n      type: \"image\",\n      img: \"https://www.shadcnship.com/images/avatars/avatar-5.webp\",\n    },\n    {\n      type: \"text\",\n      title: \"Exceeded Expectations!\",\n      content:\n        \"We expected good, but got amazing. The features are exactly what we needed.\",\n      author: {\n        name: \"Jasmine Lee\",\n        avatar: \"https://www.shadcnship.com/images/avatars/avatar-6.webp\",\n      },\n      rating: 5,\n    },\n  ],\n  className,\n}: Testimonial02Props) => (\n  <section\n    className={cn(\n      \"container mx-auto px-8 py-12 md:py-24 lg:min-w-6xl\",\n      className,\n    )}\n  >\n    <div className=\"mx-auto flex max-w-2xl flex-col items-center gap-4 text-center\">\n      <p className=\"text-sm font-semibold tracking-widest text-muted-foreground uppercase\">\n        {label}\n      </p>\n      <h2 className=\"text-4xl font-medium tracking-tight md:text-5xl\">\n        {title}\n      </h2>\n      <p className=\"text-muted-foreground md:text-lg\">{description}</p>\n    </div>\n    <div className=\"mt-12 grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n      {testimonials.map((testimonial, index) => (\n        <TestimonialCard testimonial={testimonial} key={index} />\n      ))}\n    </div>\n  </section>\n);\n\nexport default Testimonial02;\n",
      "type": "registry:component",
      "target": "components/testimonial-02.tsx"
    }
  ],
  "meta": {
    "image": "/r/previews/testimonial-02.webp",
    "imageDark": "/r/previews/testimonial-02-dark.webp",
    "prose": {
      "about": "Testimonial 02 is a masonry grid wall-of-love section that displays customer testimonials in a varied, Pinterest-style column layout. Cards are distributed across three columns of varying heights, giving each review visual weight proportional to its length. Built with Tailwind CSS column layout and shadcn/ui Card components, it renders as a single column on mobile and expands to three columns on desktop. Each card shows avatar, name, role or company, and review text.",
      "whenToUse": [
        "Products with rich, detailed testimonials that vary in length and deserve to be read in full",
        "Marketing sites where social proof is a primary differentiator and deserves its own dedicated section",
        "Agency or service businesses where named customer quotes carry more weight than anonymous ratings",
        "Pages targeting buyers who conduct thorough research before purchasing and read reviews carefully"
      ],
      "notes": "Use real names, real job titles, and real companies. Generic testimonials ('Great product! — John D.') reduce credibility rather than building it."
    }
  },
  "categories": [
    "social-proof"
  ],
  "type": "registry:block"
}