Klarhimmel UI

Case study, proof

Case study, proof preview

Install

npx shadcn add @klarhimmel/case-study-proof

Usage

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';
Also called
  • 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.

section.tsx
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.

PropTypeDefaultDescription
eyebrowstring'Proof'Text, up to 60 characters. Optional; empty is not rendered.
clientstring'Fjordhus Apartment Hotels'Text, up to 60 characters. Optional; empty is not rendered.
titlestring'Door codes made from bookings, buil…'Text, up to 140 characters.
dateLinestring'In use since 9 Sep 2026'Text, up to 60 characters.
storystring'Guests used to wait for a code that…'Text, up to 700 characters.
timeline{ time, text }[]4 itemsList of 3 to 6. Each item: time, text.
outcomesstring[]3 itemsList of 2 to 4.
outcomesTitlestring'What changed'Text, up to 40 characters.
timelineTitlestring'How it went'Text, up to 40 characters.
mediaMedia{…}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.
fullSizeLink{…}Optional; empty is not rendered.
captionstring'Illustrative demo with fictional da…'Text, up to 160 characters. Optional; empty is not rendered.
sourceLink{…}Optional; empty is not rendered.
headingLevel'1' | '2'-One of '1', '2'. Optional; empty is not rendered.