Typeset
Prose typography for rendered markdown, MDX, and CMS content — a wrapper class that styles headings, lists, code, quotes, and tables from the design tokens, so long-form content inherits the house look without hand-classing every element.
Setup
Import the stylesheet once (after theme.css), then wrap rendered content in Prose.
import '@shuttering/tokens/typeset.css'
import { Prose } from '@shuttering/ui'
<Prose variant="docs">{renderedMarkdown}</Prose>Anatomy
Prose styles whatever HTML it wraps — here the elements a markdown renderer emits.
Section heading
Body copy reads in --font-sans at the token type scale, with strong and emphasis and an inline link in the palette color.
- A list item with
inline code - Another item
pnpm add @shuttering/uiA blockquote, bordered and muted.
| Token | Role |
|---|---|
| --primary | accent |
| --foreground | body text |
The three knobs
One class controls the whole rhythm. Override these on the wrapper (or a preset) to retune.
| --typeset-size | base text size | 1em |
| --typeset-leading | line height | 1.7 |
| --typeset-flow | space between blocks | 1.25em |
Fonts come from --typeset-font-body / --typeset-font-heading / --typeset-font-mono, defaulted to the shuttering type tokens.
Presets
Two rhythms out of the box: docs reads long-form, chat is tighter for messages.
docs
Comfortable line height and generous flow for reading.
chat
Tighter size and flow, tuned for message bubbles.
With markdown
@shuttering/ai's Markdown renders a markdown string into the chat preset — GitHub-flavored (tables, task lists), and streaming-safe.
Generation report
The grid ran 62% renewable in the last hour. Notable movers:
- Solar climbed to
34% - Wind held at
28% - Hydro steady near 18%
| Source | Share | Δ |
|---|---|---|
| Solar | 34% | +6% |
| Wind | 28% | −2% |
Prices held flat despite the ramp.
See the methodology for how shares are computed.
Streaming-safe by design: the vertical rhythm uses only backward-looking selectors (no :last-child or :has()), so appending tokens as a response streams never restyles content already on screen.
Editorial pieces
Typographic flourishes that pair with Typeset for long-form content — a drop cap to open, a pull quote to lift a line, and a key-point marker that reveals an aside on hover. All take children and read from the tokens.
Shuttering is the reusable formwork a structure is poured into — the frame that shapes it, then is struck once it sets. The same idea, for frontends: one house style every application is cast in.
The system ships the defaults; the app expresses taste.
Reduced motion and the palette flow through automatically. Every editorial piece reads its color from the --primary token, so it re-tints with the theme and each palette. Hover the marker to see its note.