Problem evidence
- The distinction between long-form editorial prose (an article body,
pullquote, lore, blockquote) and UI text (a card body, a nav, form help) is today implicit in [data-section="body"] line-height plus scattered per-rune CSS. There is no classification to drive measure, paragraph rhythm, drop-cap eligibility, or a styled first paragraph. - The one editorial feature that exists —
textblock's dropcap / columns — is locked to a single rune. Nothing else can be read as prose, and the article body (the top-level markdown of a content page) is not a rune at all, so it can't opt in. - The seam SPEC-094 §8 named: "which runes' bodies are long-form editorial prose versus UI text … may be better modeled as a refinement of
data-section (e.g. a prose body role) than a new top-level axis; the shape is deferred to whenever an editorial theme first needs it." This spec settles that shape.
Design
A reading role on body content, emitted as a refinement of data-section="body" — data-reading="<value>" — not a new top-level rune axis. It classifies a body's reading register; the register drives the editorial-text cluster. Like the SPEC-107 axes it is a small semantic vocabulary: the author (or layout, or rune default) picks the register; the theme owns the magnitude.
1. The register vocabulary
Ordered from tightest-UI to most-editorial:
| Value | Intent | Typical bodies |
|---|
fine | Fine print — captions, footnotes, asides | figure caption, sidenote, fine metadata |
ui (default) | Interface text — terse, container-width, no measure cap | card body, nav, form help, hint |
prose | Long-form reading — measure-capped, editorial rhythm, drop-cap / lede eligible | article body, pullquote, lore, blockquote, textblock |
ui is the current implicit default, so unmarked content is unchanged. fine earns a rung because captions/footnotes genuinely want a distinct smaller, tighter treatment they get today only through scattered per-rune CSS.
2. What the register enables — owned by the theme, not the author
The register is the author's single choice; everything below is the skin's interpretation of reading="prose" (a docs theme and a magazine theme paint it very differently — that is the point):
- measure — the line-length cap (
--rf-measure, ~60–72ch). Distinct from width: a prose block may be width: default (full content column) yet cap its text at 66ch and centre it. width is the block's footprint in the layout track; measure is the line-length inside it. Conflating them loses "full-bleed frame, contained text" (see §4). - paragraph style — spaced (web/docs) vs indented-first-line (book/magazine). A single choice that is one of the strongest tells between a docs theme and an editorial one.
- lede / standfirst — the opening paragraph rendered larger; the theme may auto-apply it to the first prose paragraph.
- running-text niceties — hanging punctuation, link underline style, widow/orphan control, hyphenation.
3. One author opt-in: dropcap
Drop-cap is eligible in prose but not automatic — you cap the opening of an article, not every prose block. So it stays an explicit per-instance boolean (generalising textblock's existing dropcap so any prose body can opt in). The theme owns the glyph treatment; the author owns where.
4. Assignment is layout-aware (like width)
Reading-role has the same two-source shape as width (SPEC-107 §2) — and the layout source is the dominant one, because the most important body text is not a rune:
- Layout / region default. The article body of a page is the top-level markdown of the content region. A
blog-article layout declares its content region reading: prose, so running paragraphs read as an article with zero author markup; a docs layout declares its content region ui (or a docs-tuned prose). This is the path that matters most. - Per-rune default.
pullquote / lore / blockquote / textblock default to prose; card / nav / form to ui; captions to fine. So a pullquote reads as prose in any context with no author action. - Author / region override for the exceptions.
Per-rune defaults live in the theme's RuneConfig (a defaultReading, mirroring defaultElevation / defaultWidth); the layout default lives in the layout config.
5. Composition with the SPEC-107 axes
Reading-role is the missing piece of the editorial-article header. The combination SPEC-107 was careful to keep reachable — a full-bleed frame with a contained, readable body — only actually reads as editorial once the body has a reading register:
{% recipe elevation="flush" width="full" prominence="display" reading="prose" %}