Just a Markdown Viewer

Design system of the view-only macOS / iOS markdown app — where the system is the restraint: system colors only, no accent, one reading column.

Philosophy

The app is view-only and monochrome by constraint, not by phase. There is no accent color — deliberately. Even the toolbar toggles tint .primary: the off state is a plain glyph, the on state a solid circle in the label color, inverted in dark mode. There is no theme system either: every color in the app is an Apple system semantic color, so light/dark mode is free and always correct, and the document's text renders exactly the way the OS renders its own.

What remains — a type scale, two code-background alphas, a column width — is the whole design system. Everything on this page is extracted from the renderer source, not a style guide the app follows; the code is the spec.

Color

Six roles, all deferring to the platform. System semantic colors resolve differently in light and dark mode by design — the table lists the role, not a hex.

ColorUsed for
labelColorBody text, headings, code text
secondaryLabelColorBlockquotes, list markers, image placeholders, raw HTML blocks
tertiaryLabelColorThematic breaks (horizontal rules)
quaternaryLabelColorBlockquote left bar (macOS)
separatorColorTable cell borders (macOS)
label @ 4.5%Code block background; table header background (macOS)
label @ 7%Inline code background

Typography

System sans for prose, monospace where the text is literal. Bold is .semibold throughout — full bold reads too heavy at 15 pt.

h1 · 28pt / semibold
before 20 / after 8
Heading One
h2 · 22pt / semibold
before 20 / after 8
Heading Two
h3 · 18pt / semibold
before 14 / after 8
Heading Three
h4 · 16pt / semibold
Heading Four
h5–h6 · 15pt / semibold
Heading Five & Six
body · 15pt
line spacing 3.5
para spacing 12
Body text — the system font at 15 points, with generous line spacing for long reads.
inline code
0.88 × body / mono
let spec = code
code block · 13pt
mono / line spacing 2
func render(_ document: Document)
raw view · 13pt
mono / line spacing 3.5
# The unrendered source, one keystroke away

Layout & Spacing

TokenValue
Reading columnmax 680 pt, centered — side insets grow with the window so the column never exceeds it
Inset floor28 pt sides / 44 pt vertical (macOS) · 20 pt sides / 32 pt vertical (iOS)
List indent28 pt — marker sits in the gutter in monospaced digits, secondary color; task lists render ☑ / ☐
Code block12 pt padding; 1 px separator border on macOS
Blockquote+14 pt indent (iOS) · 3 pt quaternary left bar + 14 pt padding (macOS)
ImagesScale to line width, max height 480 pt, never upscaled
The reading column

Everything the app renders lands in this shape: one centered column, system label colors, quiet code backgrounds derived from the text color itself.

Blockquotes step aside in the secondary label color.
let column = min(bounds.width - insets, 680)

Inline code like maxColumnWidth gets the 7% wash; blocks get 4.5%.

Tables: Two Engines

The most platform-divergent part of the system. macOS renders real tables with NSTextTable; UIKit has no equivalent, so iOS draws a monospaced character grid instead — a deliberate, visible design decision rather than a workaround hidden behind a webview.

AspectmacOS — NSTextTableiOS — character grid
Borders0.5 pt separatorColor hairlinesBox-drawing characters in the mono font
Cell padding6 ptColumn gutters in the grid
Headerlabel @ 4.5% backgroundBold row
WidthNatural, within the column44-character budget — fits every phone from 6.1″ up; columns get a fair share, long cells word-wrap greedily inside
Rich text in cellsFullBold / italic / strikethrough / links preserved
AlignmentReal column alignmentHonored per column

Product Constraints as Design Tokens

ConstraintDesign consequence
View-onlyNo edit chrome anywhere; feature requests that add editing are rejected by default
No networkRemote images become linked placeholders — [alt] in the secondary color
Formatted ⇄ raw⇧⌘R flips the whole document to 13 pt monospaced source
Light / dark⇧⌘D — free and always correct, because every color is a system semantic
HTMLComments dropped from the formatted view; <br> becomes a line separator; other blocks shown as source in the secondary color

Footnote: the marketing pages for this app (here and in the app repo) use grey-scale palettes of their own. The app is canonical — its design system is the one documented above.

See It Live