Testimonials

Testimonial Card Grid

Heading and description above a three-column grid of six muted quote cards, each with a short quote, a greyscale Cloud Shape avatar, name and role.

Free, MIT licenseOpen in Browse
import { Heading } from "@/components/editorial/heading"
import {
  Quote,
  QuoteAuthor,
  QuoteAuthorAvatar,
  QuoteAuthorName,
  QuoteAuthorRole,
  QuoteFigure,
  QuoteGroup,
} from "@/components/editorial/quote"
import {
  Section,
  SectionContent,
  SectionDescription,
  SectionHeader,
  SectionTitleGroup,
} from "@/components/editorial/section"
import {
  CloudShape,
  type CloudPalette,
} from "@/components/graphics/cloud-shapes"

// The copy: change text here, not in the markup.
const COPY = {
  title: "What our customers are saying",
  body: "Six teams that moved their support desk to Orbcore this year.",
} as const

const TESTIMONIALS = [
  {
    body: "Orbcore put every conversation in one queue. For the first time the whole team can see what is waiting and who has it.",
    author: { name: "Mae Jemison", role: "Head of Support, Zaira" },
  },
  {
    body: "We wrote each answer once in the knowledge base. Replies that took ten minutes now take one.",
    author: { name: "Sally Ride", role: "Founder, Isidora" },
  },
  {
    body: "Routing sends billing questions to billing and bugs to engineering. Nobody forwards a ticket by hand any more.",
    author: { name: "Kalpana Chawla", role: "Operations Lead, Despina" },
  },
  {
    body: "The response targets made the slow days visible. We fixed the rota in a week and kept it fixed.",
    author: { name: "Peggy Whitson", role: "Support Manager, Zobeide" },
  },
  {
    body: "Our customers noticed before we did. The same people stopped writing in twice about the same order.",
    author: { name: "Christina Koch", role: "CEO, Armilla" },
  },
  {
    body: "Reporting answers the questions our board used to ask in every meeting, so they stopped asking.",
    author: { name: "Jessica Watkins", role: "COO, Octavia" },
  },
] as const

// Knob: the orb's shading; zero chroma keeps it greyscale.
const ORB: CloudPalette = {
  main: "oklch(0.55 0 0)",
  accent: "oklch(0.7 0 0)",
}

export default function TestimonialGrid01() {
  return (
    <Section>
      <SectionHeader>
        <SectionTitleGroup>
          <Heading>{COPY.title}</Heading>
        </SectionTitleGroup>
        <SectionDescription>{COPY.body}</SectionDescription>
      </SectionHeader>
      <SectionContent>
        <QuoteGroup cols={3} className="gap-(--tile-gap)">
          {TESTIMONIALS.map((testimonial) => (
            <QuoteFigure key={testimonial.author.name} variant="muted">
              <Quote>
                <p>{testimonial.body}</p>
              </Quote>
              <QuoteAuthor>
                <QuoteAuthorAvatar>
                  <CloudShape palette={ORB} width={48} height={48} />
                </QuoteAuthorAvatar>
                <QuoteAuthorName>{testimonial.author.name}</QuoteAuthorName>
                <QuoteAuthorRole>{testimonial.author.role}</QuoteAuthorRole>
              </QuoteAuthor>
            </QuoteFigure>
          ))}
        </QuoteGroup>
      </SectionContent>
    </Section>
  )
}

Installation

pnpm dlx shadcn add @01orbital/testimonial-grid-01
npx shadcn add @01orbital/testimonial-grid-01
yarn shadcn add @01orbital/testimonial-grid-01
bunx --bun shadcn add @01orbital/testimonial-grid-01

Free under the MIT license. Add the @01orbital registry to components.json once (install guide), then run the command.

It lands at components/blocks/testimonials/testimonial-grid-01/index.tsx, as source you own and edit.

Usage

import TestimonialGrid01 from "@/components/blocks/testimonials/testimonial-grid-01"

export default function Example() {
  return <TestimonialGrid01 />
}

Dependencies

Registry pieces it installs with it: