Testimonial Card Wall
Masonry grid of testimonial cards with avatars, star ratings, and quotes.
Preview
Source
tsx
"use client";
import { Star } from "lucide-react";
import { testimonials } from "@/lib/placeholders";
function StarRating({ rating }: { rating: number }) {
return (
<div className="flex gap-0.5">
{Array.from({ length: 5 }).map((_, i) => (
<Star
key={i}
className={`w-4 h-4 ${
i < rating
? "fill-amber-400 text-amber-400"
: "fill-muted text-muted"
}`}
/>
))}
</div>
);
}
export default function TestimonialCardWall() {
return (
<section className="py-20 px-4 sm:px-6 bg-background">
<div className="max-w-6xl mx-auto">
{/* Header */}
<div className="text-center mb-14">
<span className="inline-block text-xs font-semibold uppercase tracking-widest text-primary bg-primary/10 border border-primary/20 rounded-full px-4 py-1.5 mb-4">
Testimonials
</span>
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-extrabold tracking-tight text-foreground mb-4">
Loved by teams everywhere
</h2>
<p className="text-lg text-muted-foreground max-w-xl mx-auto">
Don't take our word for it — here's what our clients have to say.
</p>
</div>
{/* Masonry grid */}
<div className="columns-1 sm:columns-2 lg:columns-3 gap-6 space-y-0">
{testimonials.map((t) => (
<div
key={t.id}
className="break-inside-avoid mb-6 bg-card border border-border rounded-2xl p-6 shadow-sm hover:shadow-md transition-shadow duration-300"
>
<StarRating rating={t.rating} />
<blockquote className="mt-4 text-foreground leading-relaxed text-sm sm:text-base">
"{t.text}"
</blockquote>
<div className="mt-5 flex items-center gap-3">
<img
src={t.avatar}
alt={t.name}
className="w-10 h-10 rounded-full object-cover ring-2 ring-border"
/>
<div>
<p className="font-semibold text-sm text-foreground">{t.name}</p>
<p className="text-xs text-muted-foreground">{t.role}</p>
</div>
</div>
</div>
))}
</div>
</div>
</section>
);
} Claude Code Instructions
CLI Install
npx innovations add card-wallWhere to use it
Place this section after your features or case studies section on a landing page.
In Astro:
import TestimonialCardWall from '../components/innovations/testimonials/card-wall';
<TestimonialCardWall client:load />
(or client:visible for below-the-fold lazy loading)
In Next.js:
import TestimonialCardWall from '@/components/innovations/testimonials/card-wall';
// Add below the features section in your page component
Pass custom testimonials via the optional 'testimonials' prop, or edit the imported data in src/lib/placeholders.ts.