Stats & values
Values List
Small section header above numbered rows of values: number, title and description.
Layout and motion from the Nitip template — see it in contextimport { cn } from "@/lib/utils";
/*
* Values List — a small section header (title, divider, lead at the right) above numbered rows: number, title and
* description.
* Source: marcframe/nitip → components/sections/ValuesSection.tsx (+ design-system SectionHeader size small,
* ValueList).
*
* Layout kept from Framer: rows stack below 768px; from 768px number, title and description share a row (the
* description 300px wide); from 1024px the columns spread apart (title 352px, description 400px). Each row has a
* divider on top. The lead reaches up to 56rem at the right edge. No motion, as on Framer.
*/
export type ValueItem = { title: string; description: string };
export type ValuesListProps = {
title?: string;
lead?: string;
values?: ValueItem[];
className?: string;
};
const defaults = {
title: "Our values",
lead: "The few principles behind every decision we make — how we treat our clients, our work and each other.",
values: [
{
title: "Honest work",
description: "We say what we think, report what we see and never dress up a number to look better than it is.",
},
{
title: "Curiosity first",
description: "Every brief starts with questions. The best ideas come from understanding the business behind it.",
},
{
title: "Clients as partners",
description: "We work beside your team, not for a report. Your goals set our priorities, week after week.",
},
{
title: "Better together",
description: "Strategy, creative and data sit at one table, so nothing gets lost between handovers.",
},
],
};
export function ValuesList({
title = defaults.title,
lead = defaults.lead,
values = defaults.values,
className,
}: ValuesListProps) {
return (
<section className={cn("py-(--section-y)", className)}>
<div className="mx-auto flex max-w-(--container) flex-col gap-12 px-(--gutter) md:gap-16 lg:gap-20">
<div className="flex flex-col gap-5">
<h2 className="font-heading text-h3 font-semibold tracking-tight">{title}</h2>
<hr className="border-border" />
{lead && <p className="w-full max-w-4xl self-end text-h3 font-medium text-pretty">{lead}</p>}
</div>
<ol>
{values.map((value, i) => (
<li
key={value.title}
className="flex flex-col gap-5 border-t border-border py-8 md:flex-row md:items-start md:py-10 lg:justify-between lg:py-12"
>
<span className="shrink-0 font-heading text-h3 font-semibold text-muted-foreground tabular-nums md:w-12">
{String(i + 1).padStart(2, "0")}
</span>
<h3 className="font-heading text-h3 font-semibold tracking-tight md:flex-1 lg:w-88 lg:flex-none">
{value.title}
</h3>
<p className="shrink-0 text-muted-foreground md:w-75 lg:w-100">{value.description}</p>
</li>
))}
</ol>
</div>
</section>
);
}Installation
$ npx shadcn@latest add https://framebrick.co/r/blocks/values-list.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/values-list.tsx.import { cn } from "@/lib/utils"; /* * Values List — a small section header (title, divider, lead at the right) above numbered rows: number, title and * description. * Source: marcframe/nitip → components/sections/ValuesSection.tsx (+ design-system SectionHeader size small, * ValueList). * * Layout kept from Framer: rows stack below 768px; from 768px number, title and description share a row (the * description 300px wide); from 1024px the columns spread apart (title 352px, description 400px). Each row has a * divider on top. The lead reaches up to 56rem at the right edge. No motion, as on Framer. */ export type ValueItem = { title: string; description: string }; export type ValuesListProps = { title?: string; lead?: string; values?: ValueItem[]; className?: string; }; const defaults = { title: "Our values", lead: "The few principles behind every decision we make — how we treat our clients, our work and each other.", values: [ { title: "Honest work", description: "We say what we think, report what we see and never dress up a number to look better than it is.", }, { title: "Curiosity first", description: "Every brief starts with questions. The best ideas come from understanding the business behind it.", }, { title: "Clients as partners", description: "We work beside your team, not for a report. Your goals set our priorities, week after week.", }, { title: "Better together", description: "Strategy, creative and data sit at one table, so nothing gets lost between handovers.", }, ], }; export function ValuesList({ title = defaults.title, lead = defaults.lead, values = defaults.values, className, }: ValuesListProps) { return ( <section className={cn("py-(--section-y)", className)}> <div className="mx-auto flex max-w-(--container) flex-col gap-12 px-(--gutter) md:gap-16 lg:gap-20"> <div className="flex flex-col gap-5"> <h2 className="font-heading text-h3 font-semibold tracking-tight">{title}</h2> <hr className="border-border" /> {lead && <p className="w-full max-w-4xl self-end text-h3 font-medium text-pretty">{lead}</p>} </div> <ol> {values.map((value, i) => ( <li key={value.title} className="flex flex-col gap-5 border-t border-border py-8 md:flex-row md:items-start md:py-10 lg:justify-between lg:py-12" > <span className="shrink-0 font-heading text-h3 font-semibold text-muted-foreground tabular-nums md:w-12"> {String(i + 1).padStart(2, "0")} </span> <h3 className="font-heading text-h3 font-semibold tracking-tight md:flex-1 lg:w-88 lg:flex-none"> {value.title} </h3> <p className="shrink-0 text-muted-foreground md:w-75 lg:w-100">{value.description}</p> </li> ))} </ol> </div> </section> ); }
Usage
import { ValuesList } from "@/components/values-list";
<ValuesList
title="Our values"
values={[
{ title: "Honest work", description: "We say what we think and report what we see." },
{ title: "Curiosity first", description: "Every brief starts with questions." },
]}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | Our values | Section heading (h2), set small as on Framer. |
| lead | string | — | Large text at the right under the divider (up to 56rem). |
| values | { title, description }[] | 4 values | Rows, numbered 01, 02… in an ordered list; titles are h3. |
| className | string | — | Classes for the <section>. |
- Rows stack below 768px; from 768px number, title and description share a row; from 1024px the columns spread apart.
- No motion, as on Framer.
AI prompt
Paste into v0, Lovable, Bolt or Claude to rebuild this block in your own project.
Create a React + Tailwind CSS block called ValuesList. - <section className="py-(--section-y)">, container mx-auto max-w-(--container) px-(--gutter), column gap-12 / md:gap-16 / lg:gap-20. - Header: a small h2 (font-heading text-h3 semibold), an <hr>, a lead (text-h3 font-medium) up to max-w-4xl aligned right. - An <ol> of rows with border-t, py-8 / md:py-10 / lg:py-12: a muted two-digit number (w-12 from 768px), an h3 title (font-heading text-h3 semibold; flex-1, 352px from 1024px) and a muted description (300px from 768px, 400px from 1024px); stacked on phones, a row from 768px, justify-between from 1024px. - Only shadcn variables and block tokens. No motion.











