Quote

apps/www/src/sections/Quote.astro · 46 lines · group Testimonials

Quote — a single quote CARD: logo, the words, and a brand footer with the author's face. It is a card, not a section: it drops into a <Prose> aside, a grid cell or anywhere else without dragging a background of its own (a full section there would frame it in a white rectangle). The card is a flex column: when several stand side by side and one has fewer words, the brand footer still sits on the bottom edge of every card.

In the fleet

Used on 1 site built with this engine.

Samples 1

sampleshown inside <Quotes>

What they told us after the season

We used to argue about whether it was colder in the lower field. Now we know, and we plan the night around it.

Jakub Novak Farm owner, Orsa Berry

The alert names the field. That one detail is why the crew trusts it.

Sara Adeyemi Operations lead, Vinland Greens
MDX of this sample
<Quotes title="What they told us after the season" columns={2}>
  <Quote quote="We used to argue about whether it was colder in the lower field. Now we know, and we plan the night around it." name="Jakub Novak" role="Farm owner, Orsa Berry" />
  <Quote quote="The alert names the field. That one detail is why the crew trusts it." name="Sara Adeyemi" role="Operations lead, Vinland Greens" />
</Quotes>

Props

NameTypeRequiredDefaultDescription
namestring
rolestring
quotestring
avatarstring
logostring

Source apps/www/src/sections/Quote.astro @ gitt.one

---
/**
 * Quote — a single quote CARD: logo, the words, and a brand footer with the
 * author's face. It is a card, not a section: it drops into a <Prose> aside,
 * a grid cell or anywhere else without dragging a background of its own
 * (a full section there would frame it in a white rectangle).
 * The card is a flex column: when several stand side by side and one has
 * fewer words, the brand footer still sits on the bottom edge of every card.
 */
import { Image } from 'astro:assets';
import { resolveImage } from '../lib/images';

interface Props {
  name?: string;
  role?: string;
  quote?: string;
  avatar?: string;
  logo?: string;
}
const { name, role, quote, avatar, logo } = Astro.props;
const avatarImg = avatar ? await resolveImage(avatar) : undefined;
const logoImg = logo ? await resolveImage(logo) : undefined;
---

<blockquote class="not-prose relative flex h-full flex-col rounded-lg bg-white text-gray-900 shadow-lg ring-1 ring-gray-900/5">
  <div class="flex-1 px-6 py-8 sm:px-10">
    {logoImg && <Image src={logoImg} alt="" widths={[400]} class="max-h-10 w-auto max-w-[12rem]" />}
    <div class:list={['relative text-lg font-medium text-gray-700', logoImg && 'mt-6']}>
      <svg class="absolute left-0 top-0 h-8 w-8 -translate-x-3 -translate-y-2 text-gray-200" fill="currentColor" viewBox="0 0 32 32" aria-hidden="true"><path d="M9.352 4C4.456 7.456 1 13.12 1 19.36c0 5.088 3.072 8.064 6.624 8.064 3.36 0 5.856-2.688 5.856-5.856 0-3.168-2.208-5.472-5.088-5.472-.576 0-1.344.096-1.536.192.48-3.264 3.552-7.104 6.624-9.024L9.352 4zm16.512 0c-4.8 3.456-8.256 9.12-8.256 15.36 0 5.088 3.072 8.064 6.624 8.064 3.264 0 5.856-2.688 5.856-5.856 0-3.168-2.304-5.472-5.184-5.472-.576 0-1.248.096-1.44.192.48-3.264 3.456-7.104 6.528-9.024L25.864 4z"></path></svg>
      {quote ? <p class="relative">{quote}</p> : <div class="relative"><slot /></div>}
    </div>
  </div>
  {(name || role || avatarImg) && (
    <cite class="relative flex items-center rounded-b-lg bg-primary-800 px-6 py-5 not-italic sm:mt-8 sm:items-start sm:pl-12 sm:pr-10">
      {avatarImg && (
        <span class="relative rounded-full border-2 border-white sm:absolute sm:top-0 sm:-translate-y-1/2">
          <Image src={avatarImg} alt="" widths={[400]} class="h-12 w-12 rounded-full object-cover sm:h-20 sm:w-20" />
        </span>
      )}
      <span class:list={['relative ml-4 font-semibold leading-6 text-primary-100', avatarImg && 'sm:ml-24 sm:pl-1']}>
        {name && <span class="text-white">{name}</span>}{role && <span> {role}</span>}
      </span>
    </cite>
  )}
</blockquote>

Source links point to engine-astro@38c294d9. Samples are demo content: the components are the real ones, the copy and the pictures are made up.