All Taste components
Testimonials
Testimonials — three cards with headlines
Three customer cards, each led by a short headline drawn from the quote, under a left-aligned heading.
3 cards · headline per quote · person footer · link to more stories
Customer stories
Small businesses, paid on time
“Reminders do the chasing”
I used to send awkward follow-up emails every Friday. Now Tallybook nudges clients for me, politely, and I haven’t written one since March.
Grace WhitfieldCopywriter
“Our books match the bank”
Payments land already matched to the right invoice. Our accountant spends an afternoon on us now instead of a week.
Omar HaddadCo-owner, Cedar & Salt Café
“Quotes become invoices”
The quote a client approves on Monday turns into the invoice on Friday. Nothing to retype, nothing missed.
Julia BrandtBrandt Landscaping
import { ArrowRight } from "lucide-react";
const stories = [
{ headline: "Reminders do the chasing", quote: "I used to send awkward follow-up emails every Friday. Now Tallybook nudges clients for me, politely, and I haven’t written one since March.", name: "Grace Whitfield", role: "Copywriter" },
{ headline: "Our books match the bank", quote: "Payments land already matched to the right invoice. Our accountant spends an afternoon on us now instead of a week.", name: "Omar Haddad", role: "Co-owner, Cedar & Salt Café" },
{ headline: "Quotes become invoices", quote: "The quote a client approves on Monday turns into the invoice on Friday. Nothing to retype, nothing missed.", name: "Julia Brandt", role: "Brandt Landscaping" },
];
const initials = (name: string) => name.split(" ").map((w) => w[0]).join("").slice(0, 2);
export function TestimonialsThreeCards() {
return (
<section aria-labelledby="stories-title" className="bg-surface px-5 py-16 font-sans sm:px-10 sm:py-20">
<div className="mx-auto max-w-6xl">
<div className="flex flex-wrap items-end justify-between gap-4">
<div>
<p className="text-[13px] font-medium text-primary">Customer stories</p>
<h2 id="stories-title" className="mt-3 text-3xl font-semibold tracking-tight text-fg sm:text-4xl">Small businesses, paid on time</h2>
</div>
<a href="/customers" className="inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:underline">
Read all stories <ArrowRight className="size-4" aria-hidden />
</a>
</div>
<div className="mt-10 grid gap-4 md:grid-cols-3">
{stories.map((s) => (
<figure key={s.name} className="flex flex-col justify-between gap-7 rounded-xl border border-border bg-bg p-7">
<div className="grid gap-3">
<h3 className="text-lg font-semibold tracking-tight text-fg">“{s.headline}”</h3>
<blockquote className="text-[14.5px] leading-relaxed text-fg-muted"><p>{s.quote}</p></blockquote>
</div>
<figcaption className="flex items-center gap-3 border-t border-border pt-5">
<span className="grid size-9 place-items-center rounded-full bg-primary-soft text-[13px] font-medium text-primary-soft-fg" aria-hidden>{initials(s.name)}</span>
<div>
<p className="text-sm font-semibold text-fg">{s.name}</p>
<p className="text-[13px] text-fg-muted">{s.role}</p>
</div>
</figcaption>
</figure>
))}
</div>
</div>
</section>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.