Sections
Case study preview
Case studies as cards, optionally promoting one.
Installation
npx shadcn@latest add http://localhost:3000/r/case-study-preview.jsonMKT UI is not published yet, so this points at your local development server. Set NEXT_PUBLIC_REGISTRY_URL to the deployed origin to show the public command.
Also installs: container, section, section-heading, media-frame, metric.
Usage
import { CaseStudyPreview } from "@/components/case-study-preview";
<CaseStudyPreview
eyebrow="Selected work"
title="Recent projects"
layout="featured"
caseStudies={[
{
id: "c1",
client: "Basin & Bloom",
title: "Rebuilt a florist's site around same-day delivery",
summary: "The old site buried the cut-off time. We led with it.",
image: { src: "/work/basin.jpg", alt: "The rebuilt product page" },
href: "/work/basin-and-bloom",
metrics: [{ value: "3.2x", label: "Same-day orders", context: "vs. prior 6 months" }],
tags: ["Research", "Design", "Build"],
},
]}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title (required) | ReactNode | — | Section heading. |
| caseStudies (required) | CaseStudyItem[] | — | Each needs `id`, `client`, and `title`. |
| layout | "cards" | "featured" | "cards" | `featured` promotes the first study to a full-width split and lists the rest beneath. |
| linkLabel | string | "Read the case study" | Link text on each card. |
| action | ReactNode | — | Action under the grid, e.g. "See all work". |
| surface | "default" | "muted" | "brand" | "inverted" | "default" | Background treatment. |
CaseStudyItem
| Prop | Type | Default | Description |
|---|---|---|---|
| id (required) | string | — | Stable key. |
| client (required) | ReactNode | — | Who the work was for. |
| title (required) | ReactNode | — | What the project was, in a line. |
| summary | ReactNode | — | The problem, what you did, what changed. |
| metrics | CaseStudyMetric[] | — | One or two headline results. More than two and none of them land. |
| image | { src, alt } | — | Project image. |
| href | string | — | Turns the whole card into one link. |
| tags | string[] | — | Short labels, e.g. the services involved. |
Behaviour
Metrics carry a context field and you should fill it in. "3.2x more enquiries"
with no timeframe and no baseline is not a result, it is a number. context is where
"vs. the prior six months" goes.
A card with href is a single link. One tab stop per card rather than several, and
a much larger tap target on a phone.
Renders on the server.
Limitations
- No filtering, tag navigation, or pagination.
- No full case-study page layout yet — this is the preview, not the article.
metricsrenders at most two per card before the layout gets cramped.