Workspace / block / social-proof
Split Testimonial
paxfx add blocks/block-social-proof-split-12local onlyTier: low. Reduced motion: Fully static layout.
"use client";
import { cn, useInView, useReducedMotion, type BlockCopy } from "@pax-sh/blocks";
export interface SocialProofSplitProps {
copy?: BlockCopy;
className?: string;
}
const DEFAULT_COPY: BlockCopy = {
eyebrow: "Customer story",
title:
"We migrated eleven services in a quarter without a single missed page. The tool disappeared into the workflow, which is the highest compliment infrastructure can earn. Six months later the on-call rotation is quieter and nobody can name the last false alarm.",
description: "Maya Okonkwo",
};
/**
* One substantial customer story with the full editorial treatment:
* oversized hanging quote marks, a pull quote that flows into two columns
* at md and up, and a named author with an initials avatar. Fully static
* under reduced motion.
*/
export function SocialProofSplit({ copy = DEFAULT_COPY, className }: SocialProofSplitProps) {
const reduced = useReducedMotion();
const [ref, inView] = useInView<HTMLDivElement>({ threshold: 0.2 });
const settled = reduced || inView;
const author = copy.description ?? "Maya Okonkwo";
const initials = author
.split(/\s+/)
.slice(0, 2)
.map((part) => part.charAt(0).toUpperCase())
.join("");
const enter = (step: number) =>
reduced
? undefined
: ({
opacity: settled ? 1 : 0,
transform: settled ? "translateY(0)" : "translateY(14px)",
transition: `opacity 0.55s ease ${step * 0.1}s, transform 0.6s cubic-bezier(0.22, 1, 0.36, 1) ${step * 0.1}s`,
} as const);
return (
<section
className={cn(
"bg-[var(--pax-paper,#f6f2ea)] px-6 py-20 text-[var(--pax-ink,#12110f)] md:px-10 md:py-28",
className,
)}
data-pax-asset="block-social-proof-split-12"
>
<div ref={ref} className="mx-auto max-w-6xl">
{copy.eyebrow ? (
<div className="flex items-center gap-4" style={enter(0)}>
<span className="h-px w-10 bg-current opacity-40" aria-hidden="true" />
<p className="m-0 text-xs font-medium uppercase tracking-[0.22em] text-[var(--pax-mute,#6b645c)]">
{copy.eyebrow}
</p>
</div>
) : null}
<figure className="m-0 mt-10">
<div className="relative">
<span
className="pointer-events-none absolute -left-2 -top-10 select-none font-serif text-[7rem] leading-none text-[var(--pax-acid,#c8ff00)] md:-left-6 md:text-[9rem]"
aria-hidden="true"
>
“
</span>
<blockquote
className="relative m-0 text-xl font-medium leading-snug tracking-tight [text-wrap:pretty] md:columns-2 md:gap-12 md:text-2xl"
style={enter(1)}
>
{copy.title}
</blockquote>
</div>
<figcaption className="mt-10 flex items-center gap-4" style={enter(2)}>
<span
className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-[var(--pax-ink,#12110f)] text-sm font-bold text-[var(--pax-acid,#c8ff00)]"
aria-hidden="true"
>
{initials}
</span>
<div>
<p className="m-0 text-sm font-semibold">{author}</p>
<p className="m-0 mt-0.5 text-xs text-[var(--pax-mute,#6b645c)]">
VP Engineering, Ferrostack
</p>
</div>
</figcaption>
</figure>
</div>
</section>
);
}