Skip to content
FreeSocial Proof

Testimonial Stack

Use this component when you want social proof to feel tactile without adding a heavy carousel. It works well beside hero copy, case-study sections, and sales pages.

ReactTailwind CSSMotionTestimonials

"The weekly demos made the entire build feel under control."

Ava, founder

"They turned our vague idea into a working product fast."

Noah, operator

"Clean code, calm process, and a launch we could trust."

Mia, product lead

Overview

A layered testimonial card stack for founder quotes and customer proof.

Framework

React

Styling

Tailwind CSS

Animation

Motion

Create a Vite React project

bash
npm create vite@latest my-ui-app -- --template react-ts
cd my-ui-app
npm install

Create a Next.js project

bash
npx create-next-app@latest my-ui-app --typescript --tailwind --eslint
cd my-ui-app

Add Tailwind CSS to Vite

bash
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

Install dependencies

bash
npm install framer-motion

Usage

tsx
<TestimonialStack />

Testimonial Stack.tsx

tsx
"use client";

import { motion } from "framer-motion";

const testimonials = [
  {
    quote: "The weekly demos made the entire build feel under control.",
    name: "Ava, founder",
  },
  {
    quote: "They turned our vague idea into a working product fast.",
    name: "Noah, operator",
  },
  {
    quote: "Clean code, calm process, and a launch we could trust.",
    name: "Mia, product lead",
  },
];

export function TestimonialStack() {
  return (
    <div className="relative min-h-[260px] overflow-hidden rounded-xl border border-white/10 bg-zinc-950 p-5 text-white">
      <div className="absolute inset-x-8 top-9 h-36 rounded-full bg-sky-400/10 blur-3xl" />
      <div className="relative mx-auto mt-5 h-48 max-w-sm">
        {testimonials.map((item, index) => (
          <motion.div
            key={item.name}
            animate={{ y: index * 18, scale: 1 - index * 0.04 }}
            transition={{ duration: 0.4 }}
            className="absolute inset-x-0 rounded-xl border border-white/10 bg-white/[0.04] p-5 shadow-xl shadow-black/20"
            style={{ zIndex: testimonials.length - index }}
          >
            <p className="text-sm leading-relaxed">"{item.quote}"</p>
            <p className="mt-4 text-xs font-semibold text-lime-300">{item.name}</p>
          </motion.div>
        ))}
      </div>
    </div>
  );
}