Quote Wall
Principles, not testimonials. A full-width social-proof wall of short, unattributed product principles laid out as a varied bento grid — some cards wider or taller than others — each with a large decorative quotation glyph, revealed with a scroll-triggered stagger.
- Use it for
- A trust section for a product that would rather state what it stands for than fabricate a customer quote — between a features section and a final CTA.
- Themes
- Light + dark
- License
- Commercial use
What we won't ship around
No names, no numbers — just the rules this product is built against.
Ship what you'd be proud to explain.
Slow trust beats fast growth.
Default to transparent.
Simple scales. Clever doesn't.
Every shortcut is a future apology.
Build the thing you'd want to inherit.
Good defaults are a form of respect.
Say no early, not sorry later.
Make the hard path the honest one.
Trust is a feature, not a tagline.
Write it down so no one has to ask twice.
Small and sharp beats big and blurry.
"use client";
import * as React from "react";
import { motion, useInView, useReducedMotion } from "framer-motion";
import { cn } from "@/lib/utils";
function useReducedMotionSafe() {
const prefersReduced = useReducedMotion();
const [mounted, setMounted] = React.useState(false);
React.useEffect(() => setMounted(true), []);
return mounted ? !!prefersReduced : false;
}
/**
* Full-width social-proof wall of short, unattributed product principles laid
* out as a varied bento/masonry grid — some cards wider or taller than others,
* each carrying a large decorative quotation-mark glyph. Cards fade and slide
* up with a per-index stagger as they enter the viewport (useInView), and sit
* fully settled already if the whole section happens to be in view on mount.
*/
export interface QuoteWallProps {The rest is in Pro.
Full source, the rebuild prompt and registry install unlock with Pro or Lifetime.
Get ProHow it behaves
- →Card sizing (normal / wide / tall) comes from a fixed, deterministic pattern array keyed by index — never Math.random() — so the grid is stable across renders and server/client.
- →Each card is its own useInView (framer-motion) observer with once: true; it fades and slides up 22px with a delay of index * staggerDelay, so cards already near the top reveal first.
- →If the whole grid is already inside the viewport at mount (e.g. a small zoomed-out preview), useInView resolves true on the first observer callback and every card settles into place without requiring a scroll event.
- →The grid is CSS Grid with auto-rows-[minmax(9.5rem,auto)]; row/col spans only apply from the sm breakpoint up, so narrow viewports fall back to a single stable column with no overflow.
- →prefers-reduced-motion skips the fade/slide entirely and renders every card already in its resting opacity-1/y-0 state.
- →Quote text is never attributed — no name, role, company or avatar is rendered anywhere in the card.
Accessibility
- ✓The decorative quotation-mark glyph and the small signal underline are aria-hidden; the quote text itself is the only content a screen reader announces per card.
- ✓Cards are plain, non-interactive <div>s (no fake buttons or links), matching their role as a read-only statement wall.
- ✓Heading hierarchy stays a single <h2> under the section eyebrow; quote cards don't introduce extra heading levels.
- ✓Honours prefers-reduced-motion.