Block Testimonials — React Page Block
Testimonials with a featured quote plus a field-note grid. The built-in quotes are fictional and visibly marked — swap in real customers via props and clear the marker.

Usage
import { BlockTestimonials } from "@/components/BlockTestimonials";
export function Voices() {
return (
<BlockTestimonials
title="The teams who ship weekly, talk like this."
testimonials={[
{
quote: "The replay is the status update.",
name: "Mara Ellison",
role: "Head of Platform, Fieldnote",
href: "/customers/fieldnote",
},
]}
{...{
title: "Built around the people who build.",
featured: true,
accent: "#d5ed9a",
scheme: "dark"
}}
/>
);
}Implementation notes & API
Purpose: testimonial/case-study wall. Copy it, ship it — every string, link and color arrives through props. Runtime: pure DOM + CSS. No WebGPU, canvas, animation library or external assets; SSR-safe on first render. Theming: root custom properties (--vb-bg, --vb-fg, --vb-accent, --vb-border, --vb-radius, --vb-container) or the accent/scheme/className/style props. scheme flips the dark default to light. Guardrails: responsive via container queries down to 320px; interactive behavior degrades on touch; prefers-reduced-motion drops entrance/scroll motion while content stays complete. Default content is invented on purpose and says so on screen — never ship it as real social proof.
| Property | Type | Notes / default |
|---|---|---|
eyebrow / title / description | ReactNode | Section header |
testimonials | readonly Testimonial[] | { quote, name, role?, href?, linkLabel?, avatar? } |
featured | boolean | true; enlarges the first quote |
demoNote | ReactNode | null | Fictional-content marker; pass null once your quotes are real |
scheme | "dark" | "light" | dark |
accent | string (hex) | Sets --vb-accent for the whole block |
className / style | string / CSSProperties | Applied to the section root |
children | ReactNode | Replaces the default content entirely |