registry
@automindzsheets 01–77shadcn 4.x
SHEET 34

Testimonial Wall

block / marketing

Social proof in three arrangements off one typed list — a masonry column wall, two opposed marquee rows, and a featured lead quote.

type
block
files
2
registry deps
card, skeleton, @automindz/content-card, @automindz/motion-primitives, @automindz/render-link
npm deps
lucide-react

installs

  • lib/automindz/testimonials.ts
  • components/automindz/testimonial-wall.tsx
  • A row's cards are one height; the byline sits at the floor, not mid-card.
  • columns stays masonry: natural heights, but column reading order.
  • Every card answers hover; only the linked ones lift.
  • Stars are aria-hidden; one sr-only line carries the rating.
  • The bottom fade is off by default — nothing is cut, so nothing is dimmed.

Edit lib/automindz/testimonials.ts, not the component — the nine defaults are invented placeholders and carry no avatar on purpose, because a default headshot path renders a broken image in every install (the wall typesets initials instead). layout changes everything: columns is CSS multi-column, so cards keep their natural height and **reading order runs down each column** — correct for unordered social proof, wrong for anything ordered; marquee reuses Marquee from @automindz/motion-primitives as two opposed rows and **needs import "@/styles/automindz-motion.css" once in your root layout**, without which the rows are static and scrollable rather than frozen; featured leads with the quote flagged featured one step up the type scale over a primary rule and rows the rest. In marquee and featured every card in a row is the same height and the byline sits at the card's floor — the wall sets no height on a card, so never add h-full to one. Quotes are never clamped: a truncated testimonial is worse than an uneven one. Every card answers hover and keyboard focus; only the ones with an href add a lift and underline the name. The bottom fade is **off by default**: this wall renders every quote it is given, so a fade promises content below a cut that is not there and only washes out the last card in the tallest column. Turn it on when you have clipped the wall yourself. rating prints glyphs plus an sr-only "Rated n out of 5", never colour alone. An empty list renders nothing at all. Pass renderLink for next/link. @automindz/content-card is here for CardGrid only — styles/automindz-card.css is not needed.

Variations

one state per section

01

Columns, nine quotes

CSS multi-column, not a grid, and the one layout where uneven heights are the answer rather than the bug: every card is its natural height, so a two-line quote next to a six-line one leaves no hole. The price is that reading order runs down each column rather than across — fine for social proof, wrong for anything ordered. Every quote here is fully rendered: the bottom fade is off by default, because a fade over nothing just washes out the last card in the tallest column.

fluid
Rated 5 out of 5
“We had three teams keeping their own copy of the same onboarding flow, and every one of them had drifted. Consolidating took a fortnight and we have not touched it since — the support tickets about the second step just stopped arriving.”
Rated 5 out of 5
“The part I did not expect was the audit trail. Our SOC 2 evidence collection went from a week of screenshots to an export, which is a week our security lead got back every quarter.”
Rated 4 out of 5
“Rolling out SSO to 400 people is normally a fortnight of resets. This was an afternoon, and the account-linking prompt handled every person who had already signed up with a personal address.”
Tolu Oyelaran
IT Director, Northbay Health
Rated 5 out of 5
“Billing was the thing we kept putting off. Seat changes prorate correctly, the portal fails closed when a session cannot resolve the customer, and finance stopped asking me to reconcile anything by hand.”
Rated 5 out of 5
“Our designers stopped filing tickets about empty states, because there were none left to file.”
Jonah Freeman
Design Lead, Atlas Retail
Rated 5 out of 5
“Two engineers, six weeks, and we shipped the workspace model we had been sketching for a year. The invitations expiring properly is a small thing that we would definitely have got wrong.”
Sana Abadi
Co-founder, Kestrel Labs
“I was sceptical about adopting someone else's components — we have been burned by that before. The difference is that the states are all there. Loading, empty, failed, disabled, the lot, so nothing came back to us three sprints later.”
Rated 4 out of 5
“Procurement asked for a keyboard-accessibility statement and we answered it the same day. That has never once been true here.”
Daniel Okonkwo
Product Manager, Verity Analytics
Rated 5 out of 5
“The dashboards shipped with honest axes and an empty state that is not the same thing as a failed load. Our customers noticed the difference before we told them about it.”
Rin Tanaka
Head of Data, Solstice
02

Two columns, mixed set

Point at any card, linked or not: every one answers with a ground and a ring, and only the four that carry an href add the lift and the underline under the name — a static card that rises under the cursor is promising a click it will not honour. Nobody in the default list has a headshot, so every portrait is typeset initials, and the Meridian quote carries no rating rather than five empty stars.

fluid
Rated 5 out of 5
“Our designers stopped filing tickets about empty states, because there were none left to file.”
Jonah Freeman
Design Lead, Atlas Retail
Rated 5 out of 5
“Two engineers, six weeks, and we shipped the workspace model we had been sketching for a year. The invitations expiring properly is a small thing that we would definitely have got wrong.”
Sana Abadi
Co-founder, Kestrel Labs
“I was sceptical about adopting someone else's components — we have been burned by that before. The difference is that the states are all there. Loading, empty, failed, disabled, the lot, so nothing came back to us three sprints later.”
Rated 4 out of 5
“Procurement asked for a keyboard-accessibility statement and we answered it the same day. That has never once been true here.”
Daniel Okonkwo
Product Manager, Verity Analytics
Rated 5 out of 5
“The dashboards shipped with honest axes and an empty state that is not the same thing as a failed load. Our customers noticed the difference before we told them about it.”
Rin Tanaka
Head of Data, Solstice
03

Marquee, two rows

Every card in a row is the same height — the cards set no height of their own, so the row stretches them, and the byline is pinned to the floor by mt-auto so a short quote gets air rather than a hole. Two rows in opposite directions at slightly different speeds so they never lock into phase. Hover a row to pause it; tab into one and it pauses whether you asked for that or not.

fluid
Rated 5 out of 5
“We had three teams keeping their own copy of the same onboarding flow, and every one of them had drifted. Consolidating took a fortnight and we have not touched it since — the support tickets about the second step just stopped arriving.”
Rated 4 out of 5
“Rolling out SSO to 400 people is normally a fortnight of resets. This was an afternoon, and the account-linking prompt handled every person who had already signed up with a personal address.”
Tolu Oyelaran
IT Director, Northbay Health
Rated 5 out of 5
“Our designers stopped filing tickets about empty states, because there were none left to file.”
Jonah Freeman
Design Lead, Atlas Retail
“I was sceptical about adopting someone else's components — we have been burned by that before. The difference is that the states are all there. Loading, empty, failed, disabled, the lot, so nothing came back to us three sprints later.”
Rated 5 out of 5
“The dashboards shipped with honest axes and an empty state that is not the same thing as a failed load. Our customers noticed the difference before we told them about it.”
Rin Tanaka
Head of Data, Solstice
Rated 5 out of 5
“The part I did not expect was the audit trail. Our SOC 2 evidence collection went from a week of screenshots to an export, which is a week our security lead got back every quarter.”
Rated 5 out of 5
“Billing was the thing we kept putting off. Seat changes prorate correctly, the portal fails closed when a session cannot resolve the customer, and finance stopped asking me to reconcile anything by hand.”
Rated 5 out of 5
“Two engineers, six weeks, and we shipped the workspace model we had been sketching for a year. The invitations expiring properly is a small thing that we would definitely have got wrong.”
Sana Abadi
Co-founder, Kestrel Labs
Rated 4 out of 5
“Procurement asked for a keyboard-accessibility statement and we answered it the same day. That has never once been true here.”
Daniel Okonkwo
Product Manager, Verity Analytics
05

Loading, same layout, same count

Skeletons in the arrangement the real quotes will land in, one per entry — six when the list is still empty, which is the usual case. Each line is h-[1lh] of the type it stands in for, so the rating row, three lines of quote and the byline reserve exactly the height the copy will take and the page does not settle when the data arrives. One sr-only "Loading testimonials" for the wall, not six.

fluid
Loading testimonials
06

No testimonials

Two walls are rendered here and only the first is on the page: an empty list returns null rather than an EmptyState. Nobody arrives at a marketing page looking for the testimonials that are missing, and a dashed box reading "No testimonials yet" is an admission printed at the width of the page.

fluid
Rated 5 out of 5
“We had three teams keeping their own copy of the same onboarding flow, and every one of them had drifted. Consolidating took a fortnight and we have not touched it since — the support tickets about the second step just stopped arriving.”
Rated 5 out of 5
“The part I did not expect was the audit trail. Our SOC 2 evidence collection went from a week of screenshots to an export, which is a week our security lead got back every quarter.”