Klarhimmel UI

CTA, offer

CTA, offer preview

Install

npx shadcn add @klarhimmel/cta-offer

Usage

import { Theme } from '@/components/klarhimmel/theme/style';
import { BlockSurface } from '@/components/klarhimmel/blocks/surface';
import CtaOffer from '@/components/klarhimmel/blocks/cta-offer';

export default function Section() {
  return (
    <Theme theme="brand">
      <BlockSurface>
        <CtaOffer props={{
          "eyebrow": "Free this week",
          "title": "A free review of your website",
          "description": "We read your site as a visitor would and tell you what we would change, in writing.",
          "points": [
            "A page-by-page note on what works and what does not",
            "A plan for the pages we would rebuild, as a picture you can click through",
            "An honest answer on whether we are the right people"
          ],
          "pointsTitle": "What you get",
          "turnaround": "Within 24 hours",
          "turnaroundLabel": "Turnaround",
          "limit": "Five reviews this week",
          "limitLabel": "This week",
          "mode": "form",
          "link": {
            "label": "Ask for a review",
            "href": "#review"
          },
          "form": {
            "fieldLabel": "Your site's address",
            "fieldType": "domain",
            "submit": "Ask for a free review",
            "note": "We only use the address to read your site and reply to you."
          },
          "messages": {
            "sent": "Thank you. We have your address and will send the review within 24 hours.",
            "error": "Something went wrong. Please try again, or email us."
          },
          "errors": {
            "required": "Fill in this field.",
            "email": "Enter an email address like [email protected].",
            "url": "Enter an address that starts with https://, like https://example.com.",
            "domain": "Enter a site address like yourcompany.se."
          }
        }} />
      </BlockSurface>
    </Theme>
  );
}

Install

Import

import Block from '@/components/klarhimmel/blocks/cta-offer';
Also called
  • cta/offer
About
The offer of the week as one block: what you get in three to five points, how fast (text), this week's limit (text), and one primary action that is either a link or a one-field form.
Category
One clear next step near the end of a page.

Notes

When to use it

This week's offer as one block: three to five points of what you get, a turnaround, a limit, and either a link button or a one-field form. For a general closing call without an offer, `cta-card` is simpler.

Writing for it

- Points need three to five entries of up to 120 characters each; write what the person receives, as nouns, not what you do. - Turnaround (60) and limit (60) are plain text with their own labels. Write 'Within 24 hours' and 'Five reviews this week', and change the text when the offer changes. - In form mode, fieldType decides keyboard and validation: domain accepts yourcompany.se or a full address, while url insists on a scheme. Pick the one your owners will really type.

Watch out for

Both the form and the link button are always in the markup; mode only hides the other one, and both stay visible in the editor. The sent and error messages appear only when a host sets status, so the block alone never shows a success state.

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 CtaOffer from '@/components/klarhimmel/blocks/cta-offer';

export default function Section() {
  return (
    <Theme theme="brand">
      <BlockSurface>
        <CtaOffer props={{
          "eyebrow": "Free this week",
          "title": "A free review of your website",
          "description": "We read your site as a visitor would and tell you what we would change, in writing.",
          "pointsTitle": "What you get",
          "points": [
            "A page-by-page note on what works and what does not",
            "A plan for the pages we would rebuild, as a picture you can click through"
          ],
          "turnaroundLabel": "Turnaround",
          "turnaround": "Within 24 hours",
          "limitLabel": "This week",
          "limit": "Five reviews this week",
          "mode": "form",
          "link": {
            "label": "Ask for a review",
            "href": "#review"
          },
          "errors": {
            "required": "Fill in this field.",
            "email": "Enter an email address like [email protected].",
            "url": "Enter an address that starts with https://, like https://example.com.",
            "domain": "Enter a site address like yourcompany.se."
          },
          "messages": {
            "sent": "Thank you. We have your address and will send the review within 24 hours.",
            "error": "Something went wrong. Please try again, or email us."
          },
          "form": {
            "fieldLabel": "Your site's address",
            "fieldType": "domain",
            "submit": "Ask for a free review",
            "note": "We only use the address to read your site and reply to you."
          }
        }} />
      </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'Free this week'Text, up to 60 characters. Optional; empty is not rendered.
titlestring'A free review of your website'Text, up to 120 characters.
descriptionstring'We read your site as a visitor woul…'Text, up to 300 characters. Optional; empty is not rendered.
pointsstring[]3 itemsList of 3 to 5.
pointsTitlestring'What you get'Text, up to 60 characters.
turnaroundstring'Within 24 hours'Text, up to 60 characters.
turnaroundLabelstring'Turnaround'Text, up to 40 characters.
limitstring'Five reviews this week'Text, up to 60 characters.
limitLabelstring'This week'Text, up to 40 characters.
mode'link' | 'form''form'One of 'link', 'form'.
linkLink{…}See the type.
form{ fieldLabel, fieldType, fieldName, submit, note }{…}Fields: fieldLabel, fieldType ('domain' | 'url' | 'email' | 'text'), fieldName (optional), submit, note (optional).
actionstring-Text, up to 300 characters. Optional; empty is not rendered.
method'post' | 'get'-One of 'post', 'get'. Optional; empty is not rendered.
hidden{ }-Optional; empty is not rendered.
captchaboolean-Optional; empty is not rendered.
captchaSitekeystring-Text, up to 100 characters. Optional; empty is not rendered.
status'idle' | 'sent' | 'error'-One of 'idle', 'sent', 'error'. Optional; empty is not rendered.
messages{ sent, error }{…}Fields: sent, error. Optional; empty is not rendered.
errors{ required, email, url, domain }{…}Fields: required (optional), email (optional), url (optional), domain (optional). Optional; empty is not rendered.
headingLevel'1' | '2'-One of '1', '2'. Optional; empty is not rendered.