Skip to content
The Membrane Palette
Layoutstable

Prose

One class that styles long-form HTML — articles, Markdown output, CMS content — with the full typographic system.

Examples

Article body

Translation, not decoration

Every element should answer one question: what does this translate? If it cannot, it does not belong. Read the notes for the full argument.

  • Warm surfaces for human moments
  • Cool precision for systems and code
Learning happens best when people build things that matter to them.

Inline code keeps the code register visible without taking over the paragraph.

HTML for “Article body”
<article class="mp-prose">
  <h2>Translation, not decoration</h2>
  <p>Every element should answer one question: <strong>what does this translate?</strong> If it cannot, it does not belong. Read the <a href="#prose-notes">notes</a> for the full argument.</p>
  <ul>
    <li>Warm surfaces for human moments</li>
    <li>Cool precision for systems and code</li>
  </ul>
  <blockquote>Learning happens best when people build things that matter to them.</blockquote>
  <p id="prose-notes">Inline <code>code</code> keeps the code register visible without taking over the paragraph.</p>
</article>

Guidance

Add .mp-prose to the element that wraps rendered Markdown or CMS HTML. Headings get Fraunces, body gets Instrument Sans, code gets the always-dark block treatment, and the line length is capped at --measure (65ch).

Every inner selector is wrapped in :where(), so the whole component has the specificity of one class — any rule you write wins.

When to use

  • Blog posts, documentation pages, case studies: anything authored as Markdown or rich text where you don't control the markup.

When not to use

  • Application UI. Use the specific components (.mp-card, .mp-alert, …) instead — prose styles bare elements and would fight them.

Accessibility

  • Keeps a 65-character measure and 1.6 line height for sustained reading (WCAG 1.4.8 guidance).
  • Links stay underlined inside prose — color alone never marks a link.
  • Code blocks that can scroll sideways need tabindex="0" on the <pre> so keyboard users can scroll them (most Markdown renderers let you add it in a post-process step).

API

Prose classes
ClassKind
.mp-proseroot

States styled: :focus-visible :hover. Set the native attribute or ARIA state; there are no state classes.

No component tokens: Prose reads the semantic tokens directly.

Design tokens consumed: --border-default --border-width-thick --border-width-thin --code-bg --code-border --code-text --color-action-primary --color-bg-tertiary --color-text-accent --color-text-primary --color-text-secondary --color-text-tertiary --focus-ring --focus-ring-offset --font-mono --font-sans --font-serif --gradient-divider --leading-body --leading-body-lg --leading-code --leading-heading --leading-small --leading-subheading --measure --radius-lg --radius-md --radius-sm --space-12 --space-2 --space-3 --space-5 --space-6 --text-body --text-body-lg --text-code --text-h1 --text-h2 --text-h3 --text-h4 --text-small --tracking-heading --tracking-subheading --weight-bold --weight-semibold

Verified contrast

The build measures each pair for the defaults and for every tone, variant and state that reassigns a token, over page and card surfaces. The ratios below are the worst case in each mode; a pair below its minimum stops the build.

Prose contrast pairs
UsePairLightDarkMinimum
inline code--color-text-primary on --color-bg-tertiary11.0111.364.5
link, including linked code--color-text-accent on --color-bg-primary5.116.454.5
link on a card--color-text-accent on --color-bg-secondary4.645.794.5

Source