Skip to content
All Taste components

Testimonials

Testimonials — logo wall with a featured quote

A grid of customer logos where one large tile holds a featured quote from one of them.

8 logo tiles · 2 × 2 featured quote tile · hairline grid · 2 columns on small screens

Customers

Studios, shops and clinics that bill with Tallybook

All customer stories
Kestrel Row

“Our retainers bill themselves on the first of the month, and the reminders do the chasing. I haven’t opened a spreadsheet for invoices since.”

Daniel OseiFounder, Kestrel Row
Read the story
Larchfield
Ovenbird
Brasswork
tidepool
Mossgrove
Pinecrest
Northcote
Quarrystone
import { ArrowRight } from "lucide-react";

const featured = {
  company: "Kestrel Row",
  quote: "Our retainers bill themselves on the first of the month, and the reminders do the chasing. I haven’t opened a spreadsheet for invoices since.",
  name: "Daniel Osei",
  role: "Founder, Kestrel Row",
  href: "/customers/kestrel-row",
};

// Replace each with your customers' logo files: <img src="/logos/larchfield.svg" alt="Larchfield" className="h-6 w-auto" />
const logos = ["Larchfield", "Ovenbird", "Brasswork", "Tidepool", "Mossgrove", "Pinecrest", "Northcote", "Quarrystone"];

export function TestimonialsLogoWall() {
  return (
    <section aria-labelledby="wall-title" className="bg-bg px-5 py-12 font-sans sm:px-10 sm:py-20">
      <div className="mx-auto max-w-6xl">
        <div className="mb-10 flex flex-wrap items-end justify-between gap-x-8 gap-y-4">
          <div className="grid gap-3">
            <p className="text-[13px] font-medium text-primary">Customers</p>
            <h2 id="wall-title" className="max-w-xl text-balance text-3xl font-semibold tracking-tight text-fg sm:text-4xl">Studios, shops and clinics that bill with Tallybook</h2>
          </div>
          <a href="/customers" className="inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:underline">
            All customer stories <ArrowRight className="size-4" aria-hidden />
          </a>
        </div>

        <div className="grid grid-cols-2 gap-px overflow-hidden rounded-xl border border-border bg-border md:grid-cols-4">
          <figure className="col-span-2 grid content-between gap-6 bg-surface p-6 md:row-span-2 md:p-8">
            <p className="text-lg font-bold tracking-tight text-fg">{featured.company}</p>
            <blockquote className="text-lg font-medium leading-relaxed tracking-tight text-fg md:text-xl">
              <p>“{featured.quote}”</p>
            </blockquote>
            <figcaption className="flex flex-wrap items-center justify-between gap-x-5 gap-y-3">
              <div className="flex items-center gap-3">
                <span className="grid size-9 place-items-center rounded-full bg-primary-soft text-[13px] font-medium text-primary-soft-fg" aria-hidden>DO</span>
                <div>
                  <p className="text-sm font-semibold text-fg">{featured.name}</p>
                  <p className="text-[13px] text-fg-muted">{featured.role}</p>
                </div>
              </div>
              <a href={featured.href} className="inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:underline">
                Read the story <ArrowRight className="size-4" aria-hidden />
              </a>
            </figcaption>
          </figure>
          {logos.map((name) => (
            <div key={name} className="grid min-h-[104px] place-items-center bg-bg p-4 text-[15px] font-bold tracking-tight text-fg-muted md:min-h-32">
              {name}
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.