Client names as wordmarks in a ruled grid, then three numbers that roll up once.
src/registry/eased/templates/agency/clients.tsx
"use client";
import { useInView } from "motion/react";
import { useRef } from "react";
import { NumberRoll } from "../../number-roll/number-roll";
import { clients } from "./content";
import { Reveal, Section } from "./kit";
const TYPE = {
sans: "font-sans font-semibold tracking-[-0.03em]",
serif: "font-serif",
mono: "font-mono",
} as const;
/**
* Who the studio has worked for: the clients' names set as wordmarks in a ruled grid, each in
* its own kind of type, then three numbers that roll up once, the first time they are seen
* (rule 115).
*/
export function Clients() {
const ref = useRef<HTMLDListElement>(null);
const seen = useInView(ref, { once: true, amount: 0.5 });
return (
<Section id="clients" label={clients.label} className="flex flex-col gap-group">
<Reveal>
<p className="max-w-2xl font-display text-display-3xl font-medium tracking-display text-balance text-text">{clients.title}</p>
</Reveal>
<Reveal index={1}>
<ul className="grid grid-cols-2 border-t border-l border-line-subtle md:grid-cols-4">
{clients.names.map((c) => (
<li
key={c.name}
className={`flex h-28 items-center justify-center border-r border-b border-line-subtle px-in text-display-xl text-text-secondary sm:h-36 sm:text-display-2xl ${TYPE[c.style]}`}
>
{c.name}
</li>
))}
</ul>
</Reveal>
<dl ref={ref} className="grid gap-pad-lg sm:grid-cols-3">
{clients.numbers.map((n, i) => (
<Reveal key={n.label} index={i} className="flex flex-col gap-1">
<dt className="text-ui text-pretty text-text-secondary">{n.label}</dt>
{/* The number reads first; the term stays first in the markup, as a dl needs. */}
<dd className="order-first font-display text-display-5xl font-medium tracking-display text-text tabular-nums">
<NumberRoll value={seen ? n.value : 0} locale="en-US" />
</dd>
</Reveal>
))}
</dl>
</Section>
);
}