Case study, proof
Install
npx shadcn add @klarhimmel/case-study-proofUsage
import { Theme } from '@/components/klarhimmel/theme/style';
import { BlockSurface } from '@/components/klarhimmel/blocks/surface';
import CaseStudyProof from '@/components/klarhimmel/blocks/case-study-proof';
export default function Section() {
return (
<Theme theme="brand">
<BlockSurface>
<CaseStudyProof props={{
"eyebrow": "Proof",
"client": "Fjordhus Apartment Hotels",
"title": "Door codes made from bookings, built in four days",
"dateLine": "In use since 9 Sep 2026",
"story": "Guests used to wait for a code that someone typed in by hand. Now a booking creates its own door code, sends it to the guest and removes it after check-out. Reception stopped handling codes the week it went live.",
"timeline": [
{
"time": "Day 1",
"text": "Scope agreed on one call; a fixed estimate sent the same afternoon."
},
{
"time": "Day 2",
"text": "Booking feed read and the first code created in a test unit."
},
{
"time": "Day 4",
"text": "Live in every apartment, tested with real check-ins."
},
{
"time": "Day 34",
"text": "Thirty days of support ended with nothing open."
}
],
"outcomes": [
"Codes are created and removed without anyone touching them.",
"Late arrivals no longer phone reception.",
"Built and live in four days."
],
"outcomesTitle": "What changed",
"timelineTitle": "How it went",
"media": {
"src": "",
"alt": "A booking list with a door code beside each booking"
},
"mediaRatio": "4/3",
"fullSize": {
"label": "View full size",
"href": ""
},
"caption": "Illustrative demo with fictional data.",
"source": {
"label": "Verified from the git history",
"href": "#proof-source"
}
}} />
</BlockSurface>
</Theme>
);
}Install
Import
import Block from '@/components/klarhimmel/blocks/case-study-proof';- case-study/proof
- About
- One dated case in one block: client, a date line, a short story, a timeline of three to six dated steps, two to four outcome facts, a picture with a visible caption (not only alt text) and an optional source link.
- Category
- One customer story: the problem, the work, the result.
Notes
When to use it
One dated case in a single block, with a short story, three to six timed steps, two to four outcome facts and a captioned picture. Use it where claims must be checkable; for a lighter result use `case-study-before-after`.
Writing for it
- Fill the dateLine (60 characters) with a concrete date such as 'In use since 9 Sep 2026'. It is the line that makes the case a dated fact. - Each timeline step has a 30 character time and a 140 character text. Write them in the order things happened, three to six of them. - Add a source link when the facts can be checked, such as a repository history. Its label can be emptied to drop the link entirely.
Watch out for
The caption under the picture is drawn only when the media has a src. With no picture neither the image nor the caption appears, and a tall mediaRatio of 3/4 or 9/16 also moves the outcomes under the timeline in the left column.
Usage
The block in a page, with its default content (long lists shortened). Every prop is in the table below.
import { Theme } from '@/components/klarhimmel/theme/style';
import { BlockSurface } from '@/components/klarhimmel/blocks/surface';
import CaseStudyProof from '@/components/klarhimmel/blocks/case-study-proof';
export default function Section() {
return (
<Theme theme="brand">
<BlockSurface>
<CaseStudyProof props={{
"eyebrow": "Proof",
"client": "Fjordhus Apartment Hotels",
"title": "Door codes made from bookings, built in four days",
"dateLine": "In use since 9 Sep 2026",
"story": "Guests used to wait for a code that someone typed in by hand. Now a booking creates its own door code, sends it to the …",
"timelineTitle": "How it went",
"timeline": [
{
"time": "Day 1",
"text": "Scope agreed on one call; a fixed estimate sent the same afternoon."
},
{
"time": "Day 2",
"text": "Booking feed read and the first code created in a test unit."
}
],
"outcomesTitle": "What changed",
"outcomes": [
"Codes are created and removed without anyone touching them.",
"Late arrivals no longer phone reception."
],
"media": {
"src": "",
"alt": "A booking list with a door code beside each booking"
},
"mediaRatio": "4/3",
"fullSize": {
"label": "View full size",
"href": ""
},
"caption": "Illustrative demo with fictional data.",
"source": {
"label": "Verified from the git history",
"href": "#proof-source"
}
}} />
</BlockSurface>
</Theme>
);
}Props
The type, default and text limit of every prop. On a real page, over-limit text is kept and checkSections flags it (Installation, Check a page before you ship); this live preview shows the default until it fits. The panel above edits all props.
| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | 'Proof' | Text, up to 60 characters. Optional; empty is not rendered. |
client | string | 'Fjordhus Apartment Hotels' | Text, up to 60 characters. Optional; empty is not rendered. |
title | string | 'Door codes made from bookings, buil…' | Text, up to 140 characters. |
dateLine | string | 'In use since 9 Sep 2026' | Text, up to 60 characters. |
story | string | 'Guests used to wait for a code that…' | Text, up to 700 characters. |
timeline | { time, text }[] | 4 items | List of 3 to 6. Each item: time, text. |
outcomes | string[] | 3 items | List of 2 to 4. |
outcomesTitle | string | 'What changed' | Text, up to 40 characters. |
timelineTitle | string | 'How it went' | Text, up to 40 characters. |
media | Media | {…} | See the type. |
mediaRatio | '4/3' | '1/1' | '3/4' | '9/16' | '4/3' | One of '4/3', '1/1', '3/4', '9/16'. Optional; empty is not rendered. |
fullSize | Link | {…} | Optional; empty is not rendered. |
caption | string | 'Illustrative demo with fictional da…' | Text, up to 160 characters. Optional; empty is not rendered. |
source | Link | {…} | Optional; empty is not rendered. |
headingLevel | '1' | '2' | - | One of '1', '2'. Optional; empty is not rendered. |