Testimonials

Testimonials 03 — Evidence Ledger

Minimal Swiss evidence ledger: golden-ratio hairline frame with a 3D-tilt featured case study over a masked mesh backdrop, two animated result metrics and two compact quote cells with quantified outcomes.

$ npx shadcn@latest add @ludusvibe/testimonials-03
Open in v0

Code

Installed to components/sections/testimonials-03.tsx — it's yours to edit.

"use client"

import * as React from "react"
import { motion } from "motion/react"

import { AnimatedNumber } from "@/components/ludus/animated-number"
import { Grain } from "@/components/ludus/grain"
import { MeshBackdrop } from "@/components/ludus/mesh-backdrop"
import { TiltCard } from "@/components/ludus/tilt-card"
import { fadeUp, stagger, viewport } from "@/lib/motion"
import { cn } from "@/lib/utils"

type Author = { name: string; role: string }

type FeaturedMetric = {
  value: number
  prefix?: string
  suffix?: string
  /** Intl.NumberFormat options, e.g. `{ notation: "compact" }`. */
  format?: Intl.NumberFormatOptions
  label: string
}

type FeaturedCase = {
  quote: string
  author: Author
  metrics: FeaturedMetric[]
}

type TestimonialItem = {
  quote: string
  author: Author
  metric: string
  metricLabel: string
}

export type Testimonials03Props = {
  index?: string
  label?: string
  note?: string
  featured?: FeaturedCase
  items?: TestimonialItem[]
  className?: string
}

const DEFAULT_FEATURED: FeaturedCase = {
  quote:
    "We treated conversion as a design problem for years. Lumen treated it as an evidence problem — two weeks in, we knew exactly which three screens were costing us money, and why.",
  author: { name: "Amara Osei", role: "VP Growth, Northwind" },
  metrics: [
    { value: 41, prefix: "+", suffix: "%", label: "Checkout conversion" },
    {
      value: 480000,
      prefix: "$",
      suffix: "/yr",
      format: { notation: "compact", maximumFractionDigits: 0 },
      label: "Revenue recovered",
    },
  ],
}

const DEFAULT_ITEMS: TestimonialItem[] = [
  {
    quote: "Paid for itself before the first invoice cleared.",
    author: { name: "Jonas Weber", role: "CEO, Ferrostudio" },
    metric: "11 days",
    metricLabel: "to payback",
  },
  {
    quote: "First tool our engineers and marketers both trust.",
    author: { name: "Priya Nair", role: "CTO, Halcyon" },
    metric: "+28%",
    metricLabel: "trial-to-paid",
  },
]

function initials(name: string) {
  return name
    .split(" ")
    .map((part) => part[0])
    .filter(Boolean)
    .slice(0, 2)
    .join("")
    .toUpperCase()
}

function AuthorRow({ author }: { author: Author }) {
  return (
    <div className="flex items-center gap-3">
      <span
        aria-hidden
        className="flex size-9 shrink-0 items-center justify-center bg-primary/10 text-xs font-medium text-primary"
      >
        {initials(author.name)}
      </span>
      <div className="text-sm">
        <p className="font-medium">{author.name}</p>
        <p className="text-muted-foreground">{author.role}</p>
      </div>
    </div>
  )
}

export function Testimonials03({
  index = "04",
  label = "Evidence",
  note = "Real customers, audited numbers",
  featured = DEFAULT_FEATURED,
  items = DEFAULT_ITEMS,
  className,
}: Testimonials03Props) {
  return (
    <section className={cn("relative overflow-hidden bg-background", className)}>
      <Grain />

      <motion.div
        initial="hidden"
        whileInView="visible"
        viewport={viewport}
        variants={stagger(0.09)}
        className="relative mx-auto max-w-6xl px-6 py-20 md:py-28"
      >
        {/* Swiss index bar */}
        <motion.div
          variants={fadeUp}
          className="flex items-baseline justify-between border-b pb-3 text-xs tracking-[0.2em] text-muted-foreground uppercase"
        >
          <span>
            <span className="text-primary">{index}</span> — {label}
          </span>
          <span className="hidden sm:block">{note}</span>
        </motion.div>

        {/* Evidence ledger: golden split */}
        <motion.div
          variants={fadeUp}
          className="mt-12 grid gap-px border bg-border lg:grid-cols-[1.618fr_1fr]"
        >
          {/* Featured case */}
          <div className="bg-background">
            <TiltCard maxTilt={3} className="h-full overflow-hidden">
              <MeshBackdrop
                intensity={0.3}
                className="opacity-60 [mask-image:linear-gradient(to_top,black,transparent_60%)]"
              />
              <figure className="relative flex h-full flex-col justify-between p-6 md:p-10">
                <blockquote className="max-w-[60ch] text-[clamp(1.5rem,3vw,2.25rem)] leading-snug font-medium tracking-tight text-pretty">
                  {featured.quote}
                </blockquote>

                <figcaption className="mt-8">
                  <AuthorRow author={featured.author} />
                </figcaption>

                <div className="mt-8 grid grid-cols-2 gap-6 border-t pt-6">
                  {featured.metrics.map((m) => (
                    <div key={m.label}>
                      <p className="font-heading text-3xl font-medium tracking-tight md:text-4xl">
                        <AnimatedNumber
                          value={m.value}
                          prefix={m.prefix}
                          suffix={m.suffix}
                          format={m.format}
                        />
                      </p>
                      <p className="mt-1 text-xs tracking-[0.2em] text-muted-foreground uppercase">
                        {m.label}
                      </p>
                    </div>
                  ))}
                </div>
              </figure>
            </TiltCard>
          </div>

          {/* Compact quote ledger */}
          <div className="grid grid-rows-2 gap-px bg-border">
            {items.map((item) => (
              <figure
                key={item.author.name}
                className="flex flex-col justify-between gap-5 bg-background p-6"
              >
                <blockquote className="max-w-[60ch] text-sm text-pretty text-muted-foreground">
                  &ldquo;{item.quote}&rdquo;
                </blockquote>
                <div className="flex items-end justify-between gap-4">
                  <figcaption className="text-xs">
                    <p className="font-medium text-foreground">{item.author.name}</p>
                    <p className="text-muted-foreground">{item.author.role}</p>
                  </figcaption>
                  <div className="text-right">
                    <p className="text-lg font-medium tracking-tight text-primary tabular-nums">
                      {item.metric}
                    </p>
                    <p className="text-[10px] tracking-[0.2em] text-muted-foreground/70 uppercase">
                      {item.metricLabel}
                    </p>
                  </div>
                </div>
              </figure>
            ))}
          </div>
        </motion.div>
      </motion.div>
    </section>
  )
}