Klarhimmel UI

Content, policy document

Content, policy document preview

Install

npx shadcn add @klarhimmel/content-legal

Usage

import { Theme } from '@/components/klarhimmel/theme/style';
import { BlockSurface } from '@/components/klarhimmel/blocks/surface';
import ContentLegal from '@/components/klarhimmel/blocks/content-legal';

export default function Section() {
  return (
    <Theme theme="brand">
      <BlockSurface>
        <ContentLegal props={{
          "eyebrow": "Legal",
          "title": "Privacy policy",
          "updated": "Last updated 1 October 2026",
          "intro": "This explains what Exempelhotellet collects when you book a stay, why, and how long we keep it. It is written to be read.",
          "contentsLabel": "On this page",
          "sections": [
            {
              "title": "What we collect",
              "body": "Your name, email address and phone number, the dates of your stay, and the payment reference from our payment provider. We never see or store full card numbers."
            },
            {
              "title": "Why we collect it",
              "body": "To confirm your booking, to contact you if something changes, and to meet accounting and tax rules that require us to keep invoices."
            },
            {
              "title": "How long we keep it",
              "body": "Booking details for two years after your stay, invoices for seven years as the law requires. After that they are deleted automatically."
            },
            {
              "title": "Who else sees it",
              "body": "Our payment provider and our email service, both inside the EU and both bound by a data processing agreement. We never sell data."
            },
            {
              "title": "Your rights",
              "body": "You can ask to see, correct or delete what we hold about you at any time. Write to privacy@example.com and we answer within 30 days."
            }
          ]
        }} />
      </BlockSurface>
    </Theme>
  );
}

Install

Import

import Block from '@/components/klarhimmel/blocks/content-legal';
Also called
  • content/legal
Category
Long-form text and timelines for about and policy pages.

Notes

When to use it

A policy or terms page with a sticky contents list that jumps to numbered sections. For an ordinary article or about page without the contents list, `content-prose` is the simpler choice.

Writing for it

- Section titles are required and hold 80 characters. They become both the contents entries and the numbered h2 headings, so write them to make sense in a short list. - Each body holds 1200 characters in a single block of text, so split a long clause into its own section instead of cramming it in. - Fill the updated line (60 characters) with the date as the reader should see it, such as 'Last updated 3 March 2026'. The contents label (40 characters) is the small caption over the list.

Watch out for

The page title is drawn as the h1 here, not an h2, because a policy page usually has no hero. If a hero above it already carries the h1, set the headingLevel of this block to 2 so the page has only one.

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 ContentLegal from '@/components/klarhimmel/blocks/content-legal';

export default function Section() {
  return (
    <Theme theme="brand">
      <BlockSurface>
        <ContentLegal props={{
          "eyebrow": "Legal",
          "title": "Privacy policy",
          "updated": "Last updated 1 October 2026",
          "intro": "This explains what Exempelhotellet collects when you book a stay, why, and how long we keep it. It is written to be read.",
          "contentsLabel": "On this page",
          "sections": [
            {
              "title": "What we collect",
              "body": "Your name, email address and phone number, the dates of your stay, and the payment reference from our payment provider. We never see or store full card numbers."
            },
            {
              "title": "Why we collect it",
              "body": "To confirm your booking, to contact you if something changes, and to meet accounting and tax rules that require us to keep invoices."
            },
            {
              "title": "How long we keep it",
              "body": "Booking details for two years after your stay, invoices for seven years as the law requires. After that they are deleted automatically."
            },
            {
              "title": "Who else sees it",
              "body": "Our payment provider and our email service, both inside the EU and both bound by a data processing agreement. We never sell data."
            },
            {
              "title": "Your rights",
              "body": "You can ask to see, correct or delete what we hold about you at any time. Write to privacy@example.com and we answer within 30 days."
            }
          ]
        }} />
      </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'Legal'Text, up to 60 characters.
titlestring'Privacy policy'Text, up to 100 characters.
updatedstring'Last updated 1 October 2026'Text, up to 60 characters.
introstring'This explains what Exempelhotellet …'Text, up to 500 characters.
contentsLabelstring'On this page'Text, up to 40 characters.
sections{ title, body }[]5 itemsList of 2 to 8. Each item: title, body.
headingLevel'1' | '2'-One of '1', '2'. Optional; empty is not rendered.