Stats & values
History Timeline
Milestones on a line — four columns on wide screens, a vertical timeline below.
Layout and motion from the Findit template — see it in contextimport { cn } from "@/lib/utils";
/*
* History Timeline — a centered heading above milestones on a line: year, label and a short text for each.
* Source: marcframe/findit → components/sections/HistorySection.tsx (+ design-system Timeline).
*
* Layout kept from Framer: from 1024px four equal columns — year and label, then the line with a marker 20px from the
* left, then the text. Below 1024px the milestones stack along a vertical line (up to 32rem wide, centered from 768px),
* the marker 30px down each row and the texts 30px to its right. The band sits on the muted surface. No motion.
* The marker is a ring with a dot in the primary color (Findit's yellow). Dropped: the dotted, uppercase label.
*/
export type Milestone = { year: string; label: string; text: string };
export type HistoryTimelineProps = {
/** Small line above the heading. */
label?: string;
title?: string;
lead?: string;
milestones?: Milestone[];
className?: string;
};
const defaults = {
label: "Our history",
title: "Twenty years of helping people move home",
lead: "From a two-person office to a team across the city, the same idea has guided us: honest advice, local knowledge.",
milestones: [
{ year: "2005", label: "Founded", text: "Two agents open a small office with one promise: to know every street they sell on." },
{ year: "2011", label: "First 500 homes", text: "Word of mouth carries us across the city, with a team of twelve." },
{ year: "2018", label: "Rentals and management", text: "We add lettings and property care, so owners have one partner for everything." },
{ year: "2025", label: "Digital first", text: "Video viewings and online offers make moving simpler, wherever our clients live." },
],
};
function Marker() {
return (
<span aria-hidden className="flex size-4 shrink-0 items-center justify-center rounded-full border border-primary">
<span className="size-2.5 rounded-full bg-primary" />
</span>
);
}
export function HistoryTimeline({
label = defaults.label,
title = defaults.title,
lead = defaults.lead,
milestones = defaults.milestones,
className,
}: HistoryTimelineProps) {
return (
<section className={cn("bg-muted py-(--section-y)", className)}>
<div className="mx-auto flex max-w-(--container) flex-col items-center gap-16 px-(--gutter) md:gap-20 lg:gap-24">
<div className="flex w-full max-w-xl flex-col items-center gap-5 text-center">
<div className="flex flex-col items-center gap-2.5">
{label && <p className="text-sm font-medium text-foreground/65">{label}</p>}
<h2 className="font-heading text-h2 font-semibold tracking-tight text-balance">{title}</h2>
</div>
{lead && <p className="max-w-lg text-pretty text-foreground/65">{lead}</p>}
</div>
<ol className="flex w-full flex-col md:max-w-lg lg:max-w-none lg:flex-row">
{milestones.map((milestone) => (
<li key={milestone.year + milestone.label} className="flex gap-7 lg:flex-1 lg:flex-col">
<div className="hidden flex-col gap-2.5 pr-7 pl-5 lg:flex">
<h3 className="font-heading text-h3 font-semibold tracking-tight">{milestone.year}</h3>
<p className="text-sm font-medium text-foreground/65">{milestone.label}</p>
</div>
<span aria-hidden className="flex w-5 shrink-0 flex-col items-center lg:w-auto lg:flex-row">
<span className="h-7 w-0.5 bg-foreground/15 lg:h-0.5 lg:w-5" />
<Marker />
<span className="w-0.5 flex-1 bg-foreground/15 lg:h-0.5 lg:w-auto" />
</span>
<div className="flex flex-1 flex-col gap-2.5 py-5 lg:py-0 lg:pr-7 lg:pl-5">
<div className="flex flex-col gap-2.5 lg:hidden">
<h3 className="font-heading text-h3 font-semibold tracking-tight">{milestone.year}</h3>
<p className="text-sm font-medium text-foreground/65">{milestone.label}</p>
</div>
<p className="text-foreground/65">{milestone.text}</p>
</div>
</li>
))}
</ol>
</div>
</section>
);
}Installation
$ npx shadcn@latest add https://framebrick.co/r/blocks/history-timeline.json1. Add the block tokens to
app/globals.cssonce (theming).npx shadcn@latest add https://framebrick.co/r/blocks/tokens.json2. Copy the block into
components/history-timeline.tsx.import { cn } from "@/lib/utils"; /* * History Timeline — a centered heading above milestones on a line: year, label and a short text for each. * Source: marcframe/findit → components/sections/HistorySection.tsx (+ design-system Timeline). * * Layout kept from Framer: from 1024px four equal columns — year and label, then the line with a marker 20px from the * left, then the text. Below 1024px the milestones stack along a vertical line (up to 32rem wide, centered from 768px), * the marker 30px down each row and the texts 30px to its right. The band sits on the muted surface. No motion. * The marker is a ring with a dot in the primary color (Findit's yellow). Dropped: the dotted, uppercase label. */ export type Milestone = { year: string; label: string; text: string }; export type HistoryTimelineProps = { /** Small line above the heading. */ label?: string; title?: string; lead?: string; milestones?: Milestone[]; className?: string; }; const defaults = { label: "Our history", title: "Twenty years of helping people move home", lead: "From a two-person office to a team across the city, the same idea has guided us: honest advice, local knowledge.", milestones: [ { year: "2005", label: "Founded", text: "Two agents open a small office with one promise: to know every street they sell on." }, { year: "2011", label: "First 500 homes", text: "Word of mouth carries us across the city, with a team of twelve." }, { year: "2018", label: "Rentals and management", text: "We add lettings and property care, so owners have one partner for everything." }, { year: "2025", label: "Digital first", text: "Video viewings and online offers make moving simpler, wherever our clients live." }, ], }; function Marker() { return ( <span aria-hidden className="flex size-4 shrink-0 items-center justify-center rounded-full border border-primary"> <span className="size-2.5 rounded-full bg-primary" /> </span> ); } export function HistoryTimeline({ label = defaults.label, title = defaults.title, lead = defaults.lead, milestones = defaults.milestones, className, }: HistoryTimelineProps) { return ( <section className={cn("bg-muted py-(--section-y)", className)}> <div className="mx-auto flex max-w-(--container) flex-col items-center gap-16 px-(--gutter) md:gap-20 lg:gap-24"> <div className="flex w-full max-w-xl flex-col items-center gap-5 text-center"> <div className="flex flex-col items-center gap-2.5"> {label && <p className="text-sm font-medium text-foreground/65">{label}</p>} <h2 className="font-heading text-h2 font-semibold tracking-tight text-balance">{title}</h2> </div> {lead && <p className="max-w-lg text-pretty text-foreground/65">{lead}</p>} </div> <ol className="flex w-full flex-col md:max-w-lg lg:max-w-none lg:flex-row"> {milestones.map((milestone) => ( <li key={milestone.year + milestone.label} className="flex gap-7 lg:flex-1 lg:flex-col"> <div className="hidden flex-col gap-2.5 pr-7 pl-5 lg:flex"> <h3 className="font-heading text-h3 font-semibold tracking-tight">{milestone.year}</h3> <p className="text-sm font-medium text-foreground/65">{milestone.label}</p> </div> <span aria-hidden className="flex w-5 shrink-0 flex-col items-center lg:w-auto lg:flex-row"> <span className="h-7 w-0.5 bg-foreground/15 lg:h-0.5 lg:w-5" /> <Marker /> <span className="w-0.5 flex-1 bg-foreground/15 lg:h-0.5 lg:w-auto" /> </span> <div className="flex flex-1 flex-col gap-2.5 py-5 lg:py-0 lg:pr-7 lg:pl-5"> <div className="flex flex-col gap-2.5 lg:hidden"> <h3 className="font-heading text-h3 font-semibold tracking-tight">{milestone.year}</h3> <p className="text-sm font-medium text-foreground/65">{milestone.label}</p> </div> <p className="text-foreground/65">{milestone.text}</p> </div> </li> ))} </ol> </div> </section> ); }
Usage
import { HistoryTimeline } from "@/components/history-timeline";
<HistoryTimeline
title="Twenty years of helping people move home"
milestones={[
{ year: "2005", label: "Founded", text: "Two agents open a small office." },
{ year: "2025", label: "Digital first", text: "Video viewings and online offers." },
]}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | Our history | Small muted line above the heading. |
| title / lead | string | — | Centered heading (h2) and lead. |
| milestones | { year, label, text }[] | 4 milestones | An ordered list; years are h3. Four fill the row from 1024px. |
| className | string | — | Classes for the <section>. |
- From 1024px: equal columns — year and label, the line with its marker, the text. Below: a vertical line (centered, up to 32rem from 768px) with the texts beside it.
- The marker is a ring with a dot in the primary color. The band sits on the muted surface. No motion.
AI prompt
Paste into v0, Lovable, Bolt or Claude to rebuild this block in your own project.
Create a React + Tailwind CSS block called HistoryTimeline. - <section className="bg-muted py-(--section-y)">, container centered, gap-16 / 20 / 24: a centered title (small muted label, h2 font-heading text-h2 semibold, muted lead up to max-w-lg). - An <ol> of milestones. From 1024px a row of equal columns: year (h3, font-heading text-h3) and label (text-sm muted) with pl-5 pr-7, then a horizontal 2px line (foreground/15) with a marker 20px from the left, then the muted text. Below 1024px (max-w-lg, centered from 768px): each row has a 20px column with a vertical 2px line — 28px, the marker, then the rest — and, 28px to its right, the year, label and text with py-5. - Marker: a 16px ring (border-primary) with a 10px dot (bg-primary). - Only shadcn variables and block tokens (secondary text on bg-muted is text-foreground/65: muted-foreground falls under 4.5:1 there). No motion.











