Brik Design System
Components

Content block

Fixed-slot Block-layer unit — title, subtitle, description, and actions, each independently omittable.

ContentBlock is a fixed-slot Block-layer unit for named content with a known shape: title / subtitle / description / actions, each independently omittable. It owns the vertical rhythm BETWEEN its own slots — a tight gap ties title to subtitle, a medium gap separates the last text slot from description, and the same medium gap leads into actions. See ADR-023.

ContentBlock never owns layout. Column count and orientation come from a Layout primitive (Stack, Grid) or a Container (Card) wrapped around it.

Use it for

  • A card's text content — feature copy, testimonial framing, pricing tile copy
  • A CTA's heading, supporting line, and button
  • Any named content unit with a known title/subtitle/description/actions shape

For open-ended, already-sanitized rich text with no fixed slot shape, use Prose instead.

Import

import { ContentBlock } from '@brikdesigns/bds';

Variants

All slots

<ContentBlock
  title="Membership Plans"
  subtitle="Choose the plan that fits your practice"
  description="Every plan includes unlimited support and quarterly reviews."
  actions={<Button variant="primary">View Plans</Button>}
/>

Omitted slots

Any slot can be dropped independently — the rhythm collapses to whatever slots remain, with no leftover spacing from an omitted one.

<ContentBlock
  title="First Impressions"
  description="75% of website credibility comes from design."
/>

Title element level

title renders as titleAs (default h3 — the common case nests inside a Card). Pick the element by outline position, not by convenience.

// Direct outline sibling of the page's <h1>
<ContentBlock titleAs="h2" title="Membership Plans" />

// Decorative unit repeated in a grid — not an outline node
<ContentBlock titleAs="div" title="Feature name" />

On a filled brand band

onColor swaps title / subtitle / description to --text-on-color-dark for a block on a filled brand or dark surface. The block owns its own inverse story (ADR-023 amendment 2026-08-16) — never push a color override from the consumer into a slot the block renders. --text-on-color-dark is mode-invariant white, so one prop covers light and dark with no theme branch.

<ContentBlock
  onColor
  title="Get in touch"
  description="Starting a new project or want to collaborate with us?"
  actions={<Button variant="on-color">Let&apos;s Talk</Button>}
/>

White on --surface-brand-primary is 3.78:1 — AA-large (3:1), not AA (4.5:1). Brand-primary fills are gated AA-large by policy (see Color Pairings, BDS-22 / ADR-015). The title is large text and unaffected; keep a band description short rather than running body copy long on the fill. Long-form copy belongs on a neutral surface.

For a centered, measure-capped section intro on a band, use SectionHeader — it forwards onColor.

Props

PropTypeDefault
titleReactNode
subtitleReactNode
descriptionReactNode
actionsReactNode
titleAs'h1' | 'h2' | 'h3' | 'h4' | 'div' | 'p''h3'
size'sm' | 'md' | 'lg''sm'
onColorbooleanfalse

On this page

💬