1.1 Color system
Meridian's palette is warm-neutral, high-contrast, and minimal-accent. The palette asks one question of every color decision: does this support reading, or does it compete with it?
Pure white (#FFF) and pure black (#000) are banned on surfaces and body text respectively. Warm off-white (#FAFAF8) and warm off-black (#1A1A1A) replace them. This reduces eye strain during extended reading sessions. The three themes — light, sepia, and dark — are all required; sepia is not a "v2 feature."
Accent is link-only
The only color in Meridian body content is the link color. Color elsewhere — colored headings, colored callout titles, colored body emphasis — draws the eye away from reading. Resist it.
Light mode (default)
| Token | Value | Swatch | Use |
|---|---|---|---|
| --surface-page | #FAFAF8 | Page background | |
| --surface-card | #FFFFFF | Slightly raised surface (rare) | |
| --surface-sunken | #F5F5F0 | Code blocks, sidebar bg | |
| --text-body | #1A1A1A | Body text (warm off-black) | |
| --text-muted | #6B6B6B | Metadata, captions | |
| --text-faint | #9B9B9B | Timestamps, breadcrumb seps | |
| --accent-link | #0066CC | Body links — the only color | |
| --accent-link-visited | #663399 | Visited links (academic purple) | |
| --accent-highlight | rgba(255,235,153,0.5) | Search match, mark highlight |
Sepia mode (extended reading)
Sepia is Meridian's Kindle-style variant. Warm cream surfaces (#F5EFE0) and a shifted purple-blue link color (#6B5B95) reduce eye fatigue during marathon reading sessions.
| Token | Value | Swatch | Use |
|---|---|---|---|
| --surface-page | #F5EFE0 | Warm cream page bg | |
| --surface-sunken | #EDE5D0 | Code blocks on cream | |
| --text-body | #2B2B2B | Slightly softer than light | |
| --accent-link | #6B5B95 | Purple-blue (better on cream) | |
| --accent-link-visited | #7B4F7B | Visited (warm purple) |
Dark mode (night reading)
| Token | Value | Swatch | Use |
|---|---|---|---|
| --surface-page | #1A1A1A | Dark page bg | |
| --surface-sunken | #2E2E2E | Code blocks dark | |
| --text-body | #E8E8E8 | Warm off-white body text | |
| --accent-link | #66B3FF | Light blue link on dark | |
| --accent-link-visited | #CC99FF | Lavender visited | |
| --accent-highlight | rgba(255,235,153,0.18) | Dimmer highlight on dark |
Callout semantic colors (all themes)
These tokens use the same hue across all three themes. The -bg tokens use low-opacity tints; the -rule tokens set the left border.
| Callout | Rule color | Swatch | Meaning |
|---|---|---|---|
| Note | #0066CC | Informational aside | |
| Tip | #00A878 | Best-practice guidance | |
| Warning | #D97706 | Caution required | |
| Danger | #DC3545 | Breaking change / destructive |
Accessibility contrast verification (WCAG 2.1)
| Pair | Foreground | Background | Ratio | Status |
|---|---|---|---|---|
| Body text — light | #1A1A1A | #FAFAF8 | 17.8:1 | AAA |
| Link — light | #0066CC | #FAFAF8 | 5.7:1 | AA |
| Muted text — light | #6B6B6B | #FAFAF8 | 5.1:1 | AA |
| Body text — sepia | #2B2B2B | #F5EFE0 | 12.4:1 | AAA |
| Link — sepia | #6B5B95 | #F5EFE0 | 5.2:1 | AA |
| Body text — dark | #E8E8E8 | #1A1A1A | 14.3:1 | AAA |
| Link — dark | #66B3FF | #1A1A1A | 7.9:1 | AAA |
| Muted text — dark | #999999 | #1A1A1A | 4.8:1 | AA |
| Faint text — light | #9B9B9B | #FAFAF8 | 2.9:1 | FAIL — captions only, non-essential |
Faint text (--text-faint) falls below 3:1 in light mode. Use it only for purely decorative separators and timestamps — never for essential information. For captions, use --text-muted (5.1:1 AA).
1.2 Typography
Typography is the most consequential section in Meridian. Every other system archetype defaults to sans-serif body; Meridian defaults to serif. The font choice signals "long reading" the same way a book cover signals genre before a page is opened.
Body size is 17–19px — larger than the web default of 14–16px. Web defaults were tuned for product UI scanning, not reading. Meridian inverts this deliberately. Line height is 1.75 — the academic typography sweet spot for sustained reading.
Body font choice is a commitment
Serif signals editorial and academic. Sans signals technical and docs. Stripe Docs uses sans; Substack uses serif. Choose per product brand and stick with it — mixing sans headings with serif body or vice versa is the only sanctioned exception.
Serif default vs. sans alternative
Design tokens are the single source of truth for every visual decision in your product. You define a token once — the link color, the body size, the reading width — and every component inherits it automatically.
Tokens stay in sync because they reference one source. Change the token; every component updates. This is the core promise of the token layer.
Design tokens are the single source of truth for every visual decision in your product. You define a token once — the link color, the body size, the reading width — and every component inherits it automatically.
Tokens stay in sync because they reference one source. Change the token; every component updates. This is the core promise of the token layer.
Type scale
Design tokens: a primer
Get started with the token system
Semantic token naming conventions
The Meridian archetype is built for documents people read, not pages people scan. Every constraint in the system — the 68ch reading width, the 17px minimum, the 1.75 line height — exists to serve the reader, not the designer.
You set the token to var(--text-body) on the root element. Every paragraph, list item, and body-level element inherits it automatically. You override it only when the semantic context demands it — captions, footnotes, code blocks.
Figure 3: The reading-width token hard-caps prose at 68ch. Tables and code blocks extend to 80ch — they're scanned, not read line-by-line.
Updated April 2026 · 8 min read · Design Systems v1.0
| Token | Value | Leading | Weight | Use |
|---|---|---|---|---|
| --font-serif | Source Serif 4, Charter, Georgia, serif | Body default | ||
| --font-sans | Inter, system-ui, sans-serif | UI, captions, code filenames | ||
| --font-mono | JetBrains Mono, SF Mono, Menlo | Code inline + block | ||
| --leading-body | 1.75 | — | — | Body paragraphs — generous |
| --leading-lede | 1.6 | — | — | Lede / intro paragraph |
| --leading-heading | 1.25 | — | — | Headings — tight |
| --leading-code | 1.6 | — | — | Code blocks — vertical breathing |
| --tracking-heading | -0.01em | — | — | Headings (tighter for serif) |
| --tracking-overline | 0.08em | — | — | Uppercase eyebrow labels |
1.3 Spacing and reading widths
Meridian's spacing is generous but purposeful. Each decision asks: does this support reading rhythm? Paragraph spacing is --space-4 (16px) between consecutive paragraphs — not first-line indent, which is a print convention that reads poorly on screen.
Reading width hard caps
The reading-width tokens are hard limits, not suggestions. Eye fatigue collapses past 80ch on prose. Tables and code blocks are allowed wider because they're scanned, not read line-by-line.
Relative widths (approximation — actual ch varies by font):
1.4 Elevation
Meridian is flat. Shadows interrupt reading flow by adding visual weight that competes with text. The rule: use shadows only on floating overlays — the search modal, copy-link toasts — never on surface cards in body content.
Warm oklch shadows banned
Warm oklch shadows are the Harbor archetype's signature. They carry atmospheric connotations that conflict with Meridian's editorial restraint. Use cold rgba shadows on the rare surfaces that need them.
| Token | Value | Allowed on |
|---|---|---|
| --shadow-sm | 0 1px 2px rgba(0,0,0,0.04) | Rare — floating chip, minimal lift |
| --shadow-md | 0 4px 12px rgba(0,0,0,0.08) | Search modal, glossary tooltip |
| --shadow-lg | 0 8px 24px rgba(0,0,0,0.12) | Command palette, diagram full-screen |
Banned: shadows on cards in body content (visual weight steals attention from text). Shadows on default page surfaces. Warm oklch shadows.
FLAT — correct in body
A callout or code block with no box-shadow. The border alone provides affordance without visual weight.
SHADOW IN BODY — banned
Shadow here (--shadow-lg) creates a card that floats off the page surface — pulling the eye from reading. This pattern belongs in product UI, not documentation.
1.5 Shape
Meridian uses sharp corners by editorial convention. Books, magazines, and academic journals use sharp corners. Rounded corners feel product-like; reading systems lean editorial. The maximum radius in body content is 8px, reserved for dialogs and search popovers.
| Token | Value | Use |
|---|---|---|
| --radius-none | 0 | Text, code blocks, callouts — sharp = editorial |
| --radius-xs | 2px | Inline code background, badges, contrast badges |
| --radius-sm | 4px | Buttons (rare in body), copy button, search modal |
| --radius-md | 8px | Dialogs, search popovers — maximum allowed |
| --radius-pill | 9999px | Filter chips in docs nav only; theme toggle pill |
Banned: radius > 8px on any element in body content. Rounded code blocks (looks like a sticker, not an editor).
1.6 Motion
Motion in body content interrupts reading. The eye follows motion involuntarily. A reading system that animates loses readers. Meridian bans all animation on body content by rule — this is not a recommendation, it is a governance gate.
Animation on body content is banned
No fade-in paragraphs. No scroll-triggered reveals. No parallax. No rotating headlines. No skeleton shimmer. If a CSS lint rule finds transition or animation on .article-body or its descendants, the build fails.
| Token | Value | Use |
|---|---|---|
| --duration-fast | 150ms | Hover state, link color transition |
| --duration-base | 200ms | Search modal open/close |
| --duration-slow | 300ms | Page theme transition, anchor scroll |
| --easing-standard | cubic-bezier(0.4, 0, 0.2, 1) | All transitions |
Motion is allowed only on: search modal open/close · reading progress bar (continuous) · theme toggle (color transition) · anchor link smooth-scroll (with prefers-reduced-motion instant-jump fallback).
prefers-reduced-motion: Meridian's defaults are already minimal. With prefers-reduced-motion: reduce, all transition and animation durations collapse to 0.01ms — effectively instant. The progress bar jumps in 10% increments instead of continuous fill.
1.7 Iconography — Heroicons outline
Meridian uses Heroicons (outline). This is the family Stripe Docs, Vercel Docs, Tailwind Docs, and most modern documentation sites converge on. The 1.5px stroke weight has a refined editorial feel. Outline variants pair quietly with serif body text without competing for visual weight.
Lucide is explicitly banned. Lucide's stroke is heavier — it competes with reading flow. The solid Heroicons variant is allowed sparingly where filled aids recognition: warning callout icons, code-file indicators. Never in general body content.
Iconoir as substitute
If Heroicons is unavailable, substitute Iconoir — similar editorial restraint and stroke weight. Never substitute Lucide, Material Icons, or Phosphor (all heavier stroke families).
Grid: 20px standard for chrome (slightly smaller than Sentinel's 24px); 16px inline (external-link indicator). Stroke: 1.5px. Color: currentColor — inherits from parent.
Inline usage: external links show the arrow-up-right icon (16px) inline after link text. Code-block filenames show the document-text icon before the filename. All icons use aria-hidden="true" since adjacent text provides the label.
Example inline indicator: Browse the full Heroicons set
2 Voice
Meridian's voice is second person, present tense, and instructional. Documentation is a contract between the writer and a reader who already has a problem. The reader didn't come to be sold to. Every hype word — "powerful," "seamless," "revolutionary" — is a broken promise. State what the thing actually does.
Meridian adds five rules on top of governance voice requirements: define terms on first use; one idea per sentence; code before prose; active over passive; sentence case headings.
Do / don't pairs
"You set the token to var(--color-primary)"
Second-person + active voice. Concrete example with actual code.
"The token can be set by the user to a CSS variable"
Passive voice, third person, no example. The reader has to decode the indirection before they can act.
"See the governance section for the full token naming rules"
Link text describes the destination. Cross-reference is navigable.
"Click here for more information"
Meaningless out of context. Screen-reader users hear "click here, click here, click here" in the links list.
"Tokens stay in sync because they reference one source — the design system."
States the mechanism. Readers understand why it works.
"Tokens are powerful, seamless, and revolutionary — they unlock effortless consistency!"
Hype replaces specifics. Every word here is meaningless without the mechanism. Build fails copy lint.
"8 min read · Updated April 2026"
Facts the reader needs before committing. Respects their time.
"A comprehensive deep-dive guide for the modern design engineer"
Aspirational framing that tells the reader nothing. "Comprehensive" and "modern" are the reader's evaluation to make, not the writer's to claim.
"REST (Representational State Transfer) is a set of architectural constraints…"
Define on first use. Respects the reader's first-time-here state.
"The REST API accepts the following parameters…" (REST defined nowhere)
Forces the reader to leave the page to look up an acronym. Lost reading momentum, lost trust.
"Get started with tokens" (sentence case heading)
Utility heading. Reads as a directive. Governance mandates sentence case.
"Unlock the Power of Design Tokens" (title case marketing headline)
Title case and hype framing signal marketing, not documentation. Reader trust drops immediately.
3 Foundation components — Layer 1
Foundation components are the atoms of Meridian. Each is constrained to --reading-width (68ch) unless the spec grants a wider allowance. All headings receive auto-generated IDs and hover-reveal anchor links.
1. Article structural primitive
The Article component is the structural primitive. It wraps the reading column and enforces all reading-width constraints. It carries structured-data markup (schema.org/Article) and OG meta tags for shareable documentation links.
Article structure
eyebrow (category, --tracking-overline) → h1 → lede paragraph (--reading-width-narrow) → metadata row (author · date · read time) → body paragraphs (--reading-width)
2. Heading with anchor (h2–h4)
Every heading at h2 and deeper receives an auto-generated id. On hover, a hashtag icon appears at the inline-start. Clicking copies the fragment URL and shows the "Link copied" toast. This page demonstrates the pattern throughout.
Hover any heading on this page
The hashtag icon appears at inline-start of the heading. Click to copy the anchor link. Screen readers hear "Permalink to: {heading text}" from the aria-label.
4. Inline elements
The inline element palette is deliberately minimal. In long-form reading, every inline style competes for attention. Use the minimum needed to communicate semantic meaning, not visual interest.
Internal link (default state) ·
External link with icon ·
code-inline ·
strong emphasis (term-of-art) ·
italic (term introduction, first use) ·
highlighted text (search match) ·
Footnote reference1
6. Search input → modal
The search input in the nav bar opens the full search modal on focus. The modal provides fuzzy matching, grouped results, match highlighting, and keyboard navigation. Press ⌘K anywhere to open it; press Esc to close.
5. Button (rare in Meridian)
Buttons are rare in Meridian body content. Most CTAs are inline links. Buttons are reserved for end-of-article actions: subscribe, next article, download spec.
3.C Composite components — Layer 2
Composite components combine Foundation primitives with Meridian-specific reading conventions. Each enforces reading-width hard caps, respects the motion ban, and degrades gracefully across themes.
9. Callout box (note / tip / warning / danger)
Callouts are inline, never floating. The 4px left rule and tinted background communicate semantic meaning without color-only encoding (icons provide redundancy). Titles are mandatory.
Note — informational
Use for context the reader benefits from but can skip without losing understanding. Blue left-rule: --callout-note-rule (#0066CC).
Tip — best practice
Use for best-practice guidance and shortcuts the reader can act on immediately. Green left-rule: --callout-tip-rule (#00A878).
Warning — caution required
Use when a reader action could cause harm if done incorrectly. Orange left-rule: --callout-warning-rule (#D97706).
Danger — breaking change / destructive action
Use for breaking changes in changelogs, irreversible destructive operations, or security-critical warnings. Red left-rule: --callout-danger-rule (#DC3545). Limit use — if everything is danger, nothing is.
10. Code block (filename header + copy button + syntax highlighting)
/* Meridian token layer — reading system */
:root {
/* Body — NEVER below 17px */
--text-body: clamp(1.0625rem, 0.95rem + 0.4vw, 1.1875rem);
/* Reading width — HARD CAP */
--reading-width: 68ch;
/* Leading — 1.75 for sustained reading */
--leading-body: 1.75;
/* Accent — link-only */
--accent-link: #0066CC;
}
11. Inline tabs — language switcher
const response = await fetch('/api/tokens', {
method: 'GET',
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const tokens = await response.json();
import requests
response = requests.get(
'/api/tokens',
headers={'Authorization': f'Bearer {api_key}'}
)
tokens = response.json()
curl -X GET https://api.example.com/tokens \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json"
12. Pull quote
Documentation is a contract between the writer and a reader who already has a problem. Everything else is friction.
Meridian archetype philosophy — v1.0 spec
Pull quotes use --reading-width-quote (52ch), serif italic, and a left border. No quotation marks — the visual style does the work. Only quote text that appears in the body.
13. Footnote
Footnotes appear as superscript numbers in body text2, linking to a numbered list at the article end. Back-links return focus to the inline reference position. Screen readers announce "Footnote 2" and "Return to text" for the back-link.
14. Sidenote (Tufte-style — optional)
Sidenotes appear in the right margin at viewports wider than 1400px. They show parenthetical context — source citations, related asides — without interrupting the main reading column. On narrower viewports they collapse to a footnote equivalent. This pattern is optional: not every Meridian product uses sidenotes. Enable per product. (Sidenote inline fallback for narrow viewports)
--text-body-sm and --text-muted. Enable per product — requires wider viewport than 1400px to render correctly.15. Reading progress bar
The 2px bar at the top of the viewport fills from 0% to 100% as you scroll this page. It uses --accent-link color and position: fixed at top: 0. With prefers-reduced-motion: reduce, it jumps in 10% increments instead of continuous fill. See it in action as you read this page.
17. Search modal (⌘K / Ctrl+K)
The search modal opens on ⌘K (or Ctrl+K on Windows/Linux). It is display: none until the .open class is added by JavaScript. The modal is centered, uses --shadow-lg, and traps focus until Esc closes it. Results are grouped by section and type, with snippet previews and match highlighting.
18. Theme toggle (light / sepia / dark)
The theme toggle in the top-right nav switches between light, sepia, and dark modes. It persists the user's choice in localStorage. All three themes are defined and functional — use the toggle to see this page in each mode now. The transitions use --duration-slow (300ms) on background and color only — no transform or layout changes.
19. Font controls (Reader Mode)
20. Loading states
Most Meridian pages render statically — loading states are rare. When needed: a 24px circle spinner with --accent-link stroke. Skeletons are banned (motion ban) — use opacity-static placeholder blocks or no loader at all.
20a. Figure container — diagrams, charts, screenshots, equations
The figure container is a new Layer 2 composite for any visual asset that appears mid-body. It uses --reading-width-wide (80ch) — wider than body prose since visual assets are scanned, not read line-by-line. The <figcaption> is mandatory and must describe what the reader should see — not just label the figure.
No decorative figures
Every figure must teach. If removing the figure loses no meaning from the surrounding prose, remove the figure. Decorative figures interrupt reading flow and signal "promotional" to the reader.
Variant A — Diagram (architecture / decision tree / flow)
Variant B — Inline chart (line / bar)
Variant C — Screenshot with numbered callouts
3.D Domain layer — Layer 4
Domain components compose Foundation and Composite layers with Meridian's reading rules. All five named examples below are rendered live. Each respects --reading-width-wide (80ch), enforces the motion ban, uses semantic accent only, and ships full accessibility support.
28. API method block (REST / GraphQL docs)
/v1/tokens/{id}/sync
| Parameter | Type | Description |
|---|---|---|
idrequired |
string | Token set identifier. Format: ts_[a-z0-9]{16} |
theme |
string | One of light · sepia · dark. Omit to sync all three. |
force |
boolean | Set true to bypass cache and force a full re-render. Default: false. |
curl -X POST https://api.example.com/v1/tokens/ts_abc123/sync \
-H "Authorization: Bearer $TOKEN" \
-d '{"theme":"light","force":false}'
const res = await fetch(`/v1/tokens/${id}/sync`, {
method: 'POST',
body: JSON.stringify({ theme: 'light', force: false })
});
29. Versioned changelog entry
- Figure container (20a) — new Layer 2 composite for diagrams, charts, screenshots, and math equations with mandatory figcaption
- Sepia theme variant now ships by default for all Meridian products
- Domain Layer expanded to 5 named components (API method block, Changelog, Glossary tooltip, Citation block, Mermaid embed)
- Iconography family changed from Lucide to Heroicons outline — 1.5px stroke, editorial restraint
- BYOC section updated to document ~50 required color roles across all three theme variants
Breaking — icon family change
Any product that imported Lucide icons via the meridian-icons package must migrate to Heroicons outline. Run npx meridian-migrate-icons to automate the replacement.
30. Glossary term tooltip
A design tokenA design token is a named value that stores a single visual decision — a color, a size, a shadow. Tokens replace raw hex and pixel values in component CSS, creating a single source of truth.Read the full token spec is the most commonly confused term in design systems. Hover or focus the underlined term to see the tooltip definition. Tooltip uses --shadow-md; no animation beyond CSS display toggle.
Critical terms get full inline first-use definitions. Tooltips are recall aids for terms already defined earlier in the document — not substitutes for a clear first-use definition.
31. Citation block (academic / technical writing)
The optimal line length for body text is between 55 and 75 characters including spaces. Lines that are too short create a zig-zag reading pattern; lines that are too long tire the eye and make it difficult to return to the start of the next line.
Bringhurst, R. (2004). The Elements of Typographic Style (3rd ed.). Hartley & Marks. p. 26.3
32. Mermaid / diagram embed
aria-label. ↑4 Patterns
Document layouts D1–D6
Every Meridian page is one of six document layouts. The shapes are conventional — readers should not have to re-learn navigation.
21. Article header pattern
The article header is the first impression. It orients the reader quickly — breadcrumb, title, lede, metadata — and gets out of the way. No hero image taller than 200px (delays first paragraph). No social share buttons above the fold (the reader hasn't read the article yet).
Documentation · Token System
Design tokens: a primer
Tokens are the single source of truth for every visual decision. You define them once; every component inherits them automatically.
23. End-of-article block
Get the design systems newsletter
New articles on tokens, reading systems, and component design — delivered monthly. No hype, no product pitches.
27. Empty state
No results for "meridian byoc"
Try fewer keywords, or see all BYOC documentation.
26. Print stylesheet rules
Every Meridian product ships a print stylesheet by default. This is a governance gate — any product without @media print rules fails build. The print rules on this page: nav/sidebar/TOC/search hidden, full URLs expanded after links, footnotes visible, page-break-before on h1, callouts preserved with simplified borders.
Try printing this page
Use your browser's print preview to see the print stylesheet active. Nav, sidebar TOC, and all interactive chrome hide. Full URLs appear after each link. Body text dominates the printed page.
5 Accessibility
Meridian targets WCAG 2.1 AA minimum with AAA on primary body text. Reading-specific criteria add to the universal baseline: minimum body font size 17px (larger than WCAG's 18pt/14pt bold threshold); line height 1.75 (exceeds WCAG SC 1.4.12 text spacing minimums); logical CSS properties for RTL reading direction support.
Keyboard navigation map
| Key | Context | Action |
|---|---|---|
| Tab | Global | Move focus forward through all interactive elements in DOM order |
| Shift+Tab | Global | Move focus backward |
| ⌘K / Ctrl+K | Global | Open search modal from anywhere on the page |
| Esc | Search modal | Close modal and return focus to the triggering element |
| ↑↓ | Search results | Navigate between result items |
| ↵ Enter | Search result, heading anchor, button | Activate / follow the focused element |
| ← → | Inline tab strip | Switch between language tabs (Left/Right arrow) |
| Home / End | TOC list | Jump to first / last item in sidebar TOC |
Screen reader notes
- All icon-only buttons use
aria-label(copy button, expand button, theme toggle buttons, font controls) - Heading anchor links use
aria-label="Permalink to: {heading}"— screen readers hear the destination, not "#" - Footnote back-links use
aria-label="Return to text for footnote N" - The reading progress bar uses
role="progressbar"witharia-valuenowupdated by JS - Search modal uses
role="dialog"+aria-modal="true"; focus traps inside until Esc - Copy toast uses
aria-live="polite"+aria-atomic="true"so screen readers announce the confirmation - All decorative SVGs use
aria-hidden="true"; meaningful figure SVGs userole="img"/tabindex="0"+aria-label - The search modal input has explicit
aria-label="Search documentation"(never placeholder-as-label) - Glossary tooltips are accessible on focus as well as hover —
tabindex="0"on the term
prefers-reduced-motion
When prefers-reduced-motion: reduce is set: all CSS transitions and animations collapse to 0.01ms. The reading progress bar jumps in 10% increments. Theme transitions are instant. Anchor scroll is instant. The spinner stops animating. Meridian's defaults are already minimal, so the reduced-motion fallback is nearly imperceptible in practice.
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
Reading-specific WCAG criteria
| Criterion | Requirement | Meridian value | Status |
|---|---|---|---|
| SC 1.4.3 Contrast (minimum) | 4.5:1 body text | 17.8:1 (light), 12.4:1 (sepia), 14.3:1 (dark) | AAA |
| SC 1.4.4 Resize text | 200% zoom without loss | clamp() scales; reading-width in ch units | AAA |
| SC 1.4.8 Visual presentation | No justified text; line height ≥ 1.5 | text-align: left; leading 1.75 | AAA |
| SC 1.4.10 Reflow | No horizontal scroll at 320px | Single column; code wraps or scrolls inline | AA |
| SC 1.4.12 Text spacing | 1.5× line height; 0.12em letter spacing | 1.75 leading; letter spacing 0 (uses optical tracking) | AAA |
| SC 2.4.3 Focus order | Logical DOM order | Nav → skip-link → main → sidebar | AAA |
| SC 2.4.6 Headings and labels | Descriptive headings | All h2–h4 have auto-id + anchor; sentence case | AAA |
6 Governance
Meridian inherits universal governance gates from governance.spec.md and adds 11 Meridian-specific overrides. All gates are build-blocking — a PR that violates any gate is rejected.
| Gate | Check | Severity |
|---|---|---|
| Reading-width ≤ 72ch on body | Lint flags prose container max-width > 72ch | blocking |
| Body type ≥ 17px | Lint flags --text-body declared smaller | blocking |
| Line-height ≥ 1.7 on body | Lint flags tighter --leading-body | blocking |
| Animation on body content banned | Lint flags transition/animation on .article-body descendants | blocking |
| Sepia + dark mode tokens defined | Token validation script checks all 3 theme blocks | blocking |
| Print stylesheet required | Build fails if no @media print block found | blocking |
| All h2+ auto-id'd with anchor | Lint flags heading without id attribute | blocking |
| External links flagged with icon | Lint warns on a[href^=http] without .external-link-icon | warning |
| Code blocks have copy button | Lint flags pre>code without adjacent copy affordance | blocking |
| ⌘/Ctrl+K search wired | Review gate — docs products without search fail review | blocking |
| Hype words blocked in body | Copy lint rejects "powerful", "seamless", "revolutionary" etc. | blocking |
Versioning (SemVer)
MAJOR — breaking token rename, removed component, breaking API change. MINOR — new component, new variant, new token, deprecation notice. PATCH — bug fix, doc update, non-visual refactor. Deprecated tokens/components ship for 2 MINOR versions before removal. Deprecation warnings log at build time.
BYOC — required color roles
When you use a custom palette instead of Meridian's canonical warm-neutral defaults (Bring Your Own Colors), your palette must cover all three themes (light, sepia, dark) for every text and surface token. Meridian is the most palette-extensive archetype because it ships three reading-comfort variants. Approximately 50 color roles minimum across all three themes.
BYOC validation rules (all must pass)
All three themes defined (light/sepia/dark) — no "sepia is a v2 feature." Reading width ≤ 72ch enforced. Body type ≥ 17px on all themes. Body line-height ≥ 1.7. Link colors meet 4.5:1 against their respective surface-page on each theme. Pure #FFF surfaces banned (warm off-white minimum). Pure #000 body text banned (warm off-black minimum). Multi-accent palettes rejected.
Light theme — required roles
Sepia theme — required roles
Dark theme — required roles
When to pick Meridian
Pick Meridian when the primary user activity is reading — not navigating, not acting, not scanning. Articles should be 3–15 minutes of focused reading. Content is educational, technical, or editorial, not promotional. Users return to re-read and reference the same content.
Domains: documentation sites · technical blogs · academic publications · knowledge bases · wikis · long-form journalism · newsletters · ebooks · study guides · API references.
Sample adjectives that route to Meridian
These adjectives are archetype-selection aids (Finding 5 demoted-adjective routing), not generation inputs. If three or more of your brand adjectives appear in this list, Meridian is likely your archetype.
Real-world examples
Calibrate against these public sites. Each exemplifies different facets of Meridian's principles.
| Site | Meridian facet | Note |
|---|---|---|
| Stripe Docs | Canonical modern docs reference | Sans body variant; generous reading column; sidebar TOC + scroll-spy; code blocks with copy |
| MDN Web Docs | Academic, precise, footnoted | High-density reference; 3-column layout; excellent print styles |
| Tailwind CSS / React / Vue docs | Sans body variant | Technical docs feel; Heroicons throughout; code-first structure |
| Substack publications | Serif body variant | Editorial feel; focused reading column; no sidebar chrome |
| Notion (as KB / wiki) | Reading mode with right-rail TOC | Clean reading mode; block editor aligns with Meridian prose patterns |
| Smashing Magazine | Editorial-academic hybrid | Generous body size; rich callouts; serif-adjacent feel |
| Apple Developer docs | Formal, dense reference | Authoritative voice; systematic structure; print-ready |
| Read the Docs (Sphinx) | Academic baseline | No-frills reading system; body-as-hero; full RTL support |
Do not pick Meridian if…
| Use case | Why Meridian fails | Correct archetype |
|---|---|---|
| Marketing site / brand portfolio | Utilitarian headings, no atmospheric hero, no CTAs above the fold — conversion drops | Harbor |
| Internal tool / dashboard | Reading-width caps body to 68ch on a 1920px monitor; sidebar TOC is wasted real estate | Sentinel |
| Mobile-first consumer app | Pattern is desktop-optimized; no font controls without explicit Reader Mode | Current |
| Data-dense terminal / analytics | Generous spacing leaves 30 rows where 5 fit; body-as-hero is wrong metaphor | Lattice |
| User spends < 1 min per visit | Meridian's reading optimizations waste on scan-and-leave behavior | Harbor or Current |
Failure modes
When teams force Meridian onto the wrong use case, predictable failures appear in this order. Recognizing the symptom early saves a rebuild.
Marketing pretension
Symptom: A marketing page reads as a docs page — utilitarian headings, no atmospheric hero, no CTAs above the fold. Conversion drops. The site looks "academic" when it should look "exciting."
Root cause: Meridian's body-as-hero principle and "no marketing hype" voice rules are deliberately the opposite of what marketing surfaces need.
Switch to Harbor for marketing and conversion-focused surfaces.
Density famine
Symptom: A dashboard built in Meridian shows 5 rows where 30 fit. Reading-width caps body to 68ch on a 1920px monitor. Sidebar TOC is wasted real estate. Users complain the product "feels slow" because each interaction takes more scroll.
Root cause: Meridian optimizes for sustained reading; product UI optimizes for scan-and-act. These are opposite objectives.
Switch to Sentinel — compact density, scan-optimized.
Mobile reading awkwardness
Symptom: 17px body at 1.75 leading inside a 390px viewport equals roughly 30 lines before scroll. Sidebar TOC hidden. No font controls without explicit Reader Mode toggle. Generally acceptable, but feels stripped on small screens compared to desktop.
Root cause: Meridian's pattern is desktop-optimized. Mobile is acceptable but less rich. Scroll depth on mobile is high; discovery is harder without sidebar TOC.
Stay with Meridian — accept the mobile experience is different. OR add a Current-styled mobile companion if reading on mobile is primary (rare for docs).
Marketing-fluff drift
Symptom: Docs slowly fill with hype words: "powerful," "seamless," "robust," "blazing fast." Reader trust declines as the docs feel less authoritative. The information is still correct, but the tone undercuts credibility.
Root cause: Meridian's voice rules ban hype words but without enforcement, copywriters drift back to marketing patterns, especially when docs are maintained by a product marketing team.
Tighten governance: enable the hype-word copy lint at CI time. Block PRs that introduce banned words in body content.
The "no one finds anything" failure (Meridian without ⌘K)
Symptom: Docs site has 200 pages. Readers can't find what they need. Bounce rate from search-engine landing pages spikes. Sidebar TOC is fine for browsing within a page, but useless for discovery across 200 pages.
Root cause: Meridian requires ⌘/Ctrl+K search wired. Teams sometimes ship the reading system without connecting it to search. Discoverability collapses — readers abandon the docs and open Stack Overflow instead.
Tighten governance: enforce ⌘K search at review time (Meridian governance override, gate 10 of 11). This gate is build-blocking for docs products.