← typeset SPEC.md Download

SPEC.md

The same content as prose, generated from spec.json by tools/build-spec.mjs. This is the one to paste into a model's context when you want the whole specification at once.

1812 lines · 52.3 KB

1# typeset — typographic specification
2
3Version 2.2.1 · updated 2026-10-09 · Adilson Carvalho
4Canonical: https://typeset.adilsoncarvalho.com
5
6A normative typographic specification for printed documents — essays, letters, reports. This file is the source of truth. CSS, Typst, LaTeX or any other implementation conforms to it; where an implementation and this file disagree, this file is right.
7
8**Target.** Paper and PDF at 100% scale. Not screens, not reflowing layouts.
9
10## Conformance
11
12- Every length is absolute. Points (pt) and millimetres (mm) mean the same thing in every engine; 1pt = 1/72in.
13- A length given in em is relative to the font size of the element it is declared on, not to the document base.
14- line_height is a multiple of the element's own font size, and defines the baseline-to-baseline advance. An engine whose leading is measured between line boxes rather than between baselines must derive its value from the resulting advance, stated per element in baseline_advance.
15- An implementation MUST reproduce every value under `properties`. It MAY add anything the target engine needs to achieve them.
16- Where an engine cannot express a property, it must fail visibly or degrade as named in `fallback` — never silently.
17- Colour is sRGB. Ink is never pure black: #000 blooms on laser output and glares in a backlit PDF.
18- Deriving leading: where the engine measures the gap between line boxes rather than between baselines, pin the line box to the band from the baseline up to 1em (in Typst: top-edge: 1em, bottom-edge: 0pt). The advance is then 1em + leading, so leading = (line_height - 1) em, independent of the font's own metrics.
19
20## Foundation
21
22### page
23
24| Property | Value |
25| --- | --- |
26| size | `A4` |
27| sizes note | Every paper this spec is set for, width before height. `size` names the one a document gets by default; the others are chosen per document. A paper is added here and nowhere else — every page box, text width and column width in this spec is derived from this table and from `margins`. |
28| text width | Not a stated constant: the paper width minus the left and right margins — twice the symmetric value, or inner plus outer for a duplex pair. The two are equal for any one size, by the rule above. |
29
30#### sizes mm
31
32| Property | Value |
33| --- | --- |
34| A4 | `210`, `297` |
35| A5 | `148`, `210` |
36| Letter | `215.9`, `279.4` |
37
38#### margins
39
40| Property | Value |
41| --- | --- |
42| default | `standard` |
43| symmetric mm | narrow: `10`; standard: `20`; wide: `30` |
44| duplex inner mm | narrow: `13`; standard: `23`; wide: `33` |
45| duplex outer mm | narrow: `7`; standard: `17`; wide: `27` |
46| note | Symmetric is what a document gets unless it asks otherwise: the named size applies to all four sides. Duplex is the explicit opt-in, for a sheet that will be bound — top and bottom stay at the symmetric value, and left and right split into an inner (binding) edge and an outer edge. A duplex pair preserves its symmetric pair's total, inner plus outer equal to twice the symmetric value, and shifts the gutter by 3mm: 20+20=40 becomes 23+17. A document keeps the same text width whichever it chooses, so switching between symmetric and duplex never reflows it. |
47
48#### running head
49
50| Property | Value |
51| --- | --- |
52| position | `top centre` |
53| content | the current level-2 heading, uppercased |
54| font | `sans` |
55| size | `8pt` |
56| tracking | `0.08em` |
57| color | `ink_faint` |
58| suppressed on | `first page` |
59
60#### folio
61
62| Property | Value |
63| --- | --- |
64| position | `bottom centre` |
65| content | `page number` |
66| font | `serif` |
67| size | `9pt` |
68| numerals | `oldstyle` |
69| color | `ink_muted` |
70| suppressed on | `first page` |
71
72### fonts
73
74| Property | Value |
75| --- | --- |
76| embedding | Font files MUST be embedded in the output. A document that resolves its fonts at print time is not reproducible. |
77
78#### serif
79
80| Property | Value |
81| --- | --- |
82| role | body text — the reading face |
83| family | `EB Garamond` |
84| license | `OFL` |
85| fallbacks | `Iowan Old Style`, `Palatino`, `Georgia`, `serif` |
86| weights | `400`, `600` |
87| styles | `normal`, `italic` |
88| features | `oldstyle figures`, `small caps`, `standard ligatures`, `kerning` |
89| note | Set no smaller than 11pt. Below that the strokes thin out on office laser output. |
90
91#### sans
92
93| Property | Value |
94| --- | --- |
95| role | headings, tables, captions, labels |
96| family | `Source Sans 3` |
97| license | `OFL` |
98| fallbacks | `Helvetica Neue`, `Helvetica`, `Arial`, `sans-serif` |
99| weights | `300`, `600`, `700` |
100| styles | `normal`, `italic` |
101| note | Humanist, so it sits with an old-style serif instead of fighting it. |
102
103#### mono
104
105| Property | Value |
106| --- | --- |
107| role | code, listings, technical identifiers |
108| family | `IBM Plex Mono` |
109| license | `OFL` |
110| fallbacks | `SF Mono`, `Menlo`, `Consolas`, `monospace` |
111| weights | `400`, `600` |
112| styles | `normal`, `italic` |
113| features | `ligatures disabled` |
114| note | Monospaced faces run optically large beside a serif; every size below is already corrected for it. |
115
116### scale
117
118| Property | Value |
119| --- | --- |
120| ratio | `1.2` |
121| base | `11pt` |
122
123#### steps
124
125| Property | Value |
126| --- | --- |
127| xs | `8pt` |
128| sm | `9.5pt` |
129| base | `11pt` |
130| h4 | `12pt` |
131| h3 | `14pt` |
132| h2 | `18pt` |
133| h1 | `24pt` |
134
135### rhythm
136
137| Property | Value |
138| --- | --- |
139| line height | `1.45` |
140| line height tight | `1.2` |
141| baseline advance | `15.95pt` |
142| space | `11pt` |
143| space note | One unit of vertical space is 11pt — one line of base leading, near enough. Every gap below is a multiple of it. |
144| measure | `33em` |
145| measure mm | `128` |
146| measure chars | `66` |
147| measure note | The single largest legibility lever. Past about 75 characters the return sweep fails and readers re-read lines without noticing; below 45 the eye fixates too often. `measure` is canonical — an em measure follows a type-scale change, where a millimetre one does not. `measure_mm` is derived from it, 33 × the 11pt base, and is kept only as a millimetre convenience for readers who think in paper dimensions; tools/check.mjs asserts the two agree. |
148| measure position | Centred, not flush to one edge. The measure is a maximum column width; where foundation.page's text_width (the paper less its margins) is wider than it, the surplus splits evenly between the two sides of the column, so the column sits in the middle of the text area. A template whose measure IS the column, with no surplus to split, is exempt — templates.two-column names its own exemption. |
149
150#### measure variants
151
152| Property | Value |
153| --- | --- |
154| narrow | `27em` |
155| wide | `40em` |
156
157### color
158
159#### ink
160
161| Property | Value |
162| --- | --- |
163| hex | `#1a1a1a` |
164| role | `body text` |
165
166#### ink muted
167
168| Property | Value |
169| --- | --- |
170| hex | `#5a5a5a` |
171| role | captions, attributions, secondary text |
172
173#### ink faint
174
175| Property | Value |
176| --- | --- |
177| hex | `#8a8a8a` |
178| role | labels, list markers, running heads |
179
180#### rule
181
182| Property | Value |
183| --- | --- |
184| hex | `#c9c4bd` |
185| role | hairlines, table body rules |
186
187#### rule strong
188
189| Property | Value |
190| --- | --- |
191| hex | `#6f6a64` |
192| role | table header and footer rules, block accents |
193
194#### wash
195
196| Property | Value |
197| --- | --- |
198| hex | `#f4f1ec` |
199| role | code and callout backgrounds |
200
201#### accent
202
203| Property | Value |
204| --- | --- |
205| hex | `#7a1f1f` |
206| role | drop caps, note markers, fleurons |
207| note | Oxblood. Chosen to read as a dark grey when printed in greyscale. |
208
209## Page templates
210
211A template sets the page and the scale. Everything under `foundation` and `sections` still applies; a template states only what it overrides, and what it forbids.
212
213Default: `single-column`
214
215### Single column
216
217`single-column`
218
219**Use for.** Essays, letters, reports, memoranda — anything read continuously from start to finish.
220
221**page.** as foundation.page
222
223**scale.** as foundation.scale
224
225**rhythm.** as foundation.rhythm
226
227**justification.** optional
228
229#### notes
230
231- The default. Nothing to opt into.
232
233### Two column, equal
234
235`two-column` · opt-in: `typeset--two-column`
236
237**Use for.** Papers, journal articles, newsletters, technical notes — documents that are scanned and referenced as much as read, and where a figure is worth more than an uninterrupted argument.
238
239#### derivation
240
241| Property | Value |
242| --- | --- |
243| derived for | The paper named in foundation.page.size, at the margin named in foundation.page.margins.default. No copy of either is kept here: every number below is a function of those two and of the gutter. |
244| column gap mm | `6` |
245| column width mm | `82` |
246| floor | `45` |
247| margins supported | `narrow`, `standard` |
248| conclusion | An 82mm column carries 42 characters at the 11pt base — below the 45-character floor this spec sets for a line of prose. 10.5pt still falls short, at 44. The base therefore DROPS to 10pt, the first step that clears the floor — but only just, at 47, two characters of headroom. The template drops one step further anyway, to 9.5pt and 49: a floor is not a target, and a bare pass is not the same as room to breathe. This is arithmetic, not preference: an implementation that keeps 11pt or 10.5pt in two columns violates the measure rule, which is the rule everything else in this spec is downstream of. |
249| refusal | Two columns are refused, not set badly, on any paper and margin whose column falls below the floor. That is a computed rule rather than a list of papers: margins_supported names the margins that reach the floor on the paper in foundation.page.size, and tools/check.mjs recomputes it. The checker fails when this declaration disagrees with the arithmetic, when the default margin cannot reach the floor, or when no named margin on the paper can. |
250| recompute when | The paper in foundation.page.size, the default margin, or the gutter. Characters per line = (foundation.rhythm.measure_chars / measure_mm) x column_mm x (11 / base_pt), rounded; column_mm = (paper width - twice the margin - the gutter) / 2. tools/check.mjs recomputes every number here from foundation.page, so a margin cannot move without these following it or the checker going red. |
251
252**characters per line**
253
254| Property | Value |
255| --- | --- |
256| 11pt | `42` |
257| 10.5pt | `44` |
258| 10pt | `47` |
259| 9.5pt | `49` |
260| 9pt | `52` |
261
262#### page
263
264| Property | Value |
265| --- | --- |
266| size | `as foundation.page.size` |
267| margins | as foundation.page.margins, at the default size — symmetric unless the sheet is bound, duplex if it is. A duplex pair leaves the text width unchanged, so a two-column document does not reflow between them. |
268| columns | `2` |
269| column widths | equal — the two columns are the same width, always |
270| column gap mm | `6` |
271| column width mm | `82` |
272| column rule | none by default; an optional 0.5pt hairline in `rule` where the columns need separating |
273| column balance | the final page balances its columns to equal height |
274| lines per column | `54` |
275| running head | as foundation.page — spans the full text width, not a column |
276| folio | `as foundation.page` |
277
278#### scale
279
280| Property | Value |
281| --- | --- |
282| ratio | `1.2` |
283| base | `9.5pt` |
284| note | Every step comes down. A 24pt heading inside an 82mm column takes three lines to say two words; 18pt takes two. The h1 keeps display size because it spans both columns. |
285
286**steps**
287
288| Property | Value |
289| --- | --- |
290| xs | `7pt` |
291| sm | `8.5pt` |
292| base | `9.5pt` |
293| h4 | `9.5pt` |
294| h3 | `11pt` |
295| h2 | `13pt` |
296| h1 | `20pt` |
297
298#### rhythm
299
300| Property | Value |
301| --- | --- |
302| line height | `1.4` |
303| baseline advance | `13.3pt` |
304| space | `9.5pt` |
305| measure | the column — 82mm, not a character count |
306| measure chars | `49` |
307| measure position | exempt from foundation.rhythm.measure_position — the column has no surplus to split, because the column IS the measure. Centring would have nothing to act on. |
308| note | Leading tightens with the measure: a shorter line needs less vertical separation to keep the return sweep unambiguous. |
309
310#### requirements
311
312- Justification with hyphenation is MANDATORY, not optional. At 49 characters a ragged right edge produces a visibly serrated column and word gaps wide enough to read as rivers. This is the one place the spec removes a choice it otherwise offers.
313- The last line of a paragraph is still flush left. Two columns make a stretched last line more visible, not less.
314- Balance the columns on the final page. A last page with one full column and one empty third reads as a printing error.
315- A spanning element must span BOTH columns fully or neither. An element that spans one and a half columns has no correct reading order.
316- Keep a spanning element at the top or the bottom of the page, never mid-column. Interrupting both columns in the middle forces the reader to find their place twice.
317
318#### spanning
319
320| Property | Value |
321| --- | --- |
322| always | `frontmatter-title-block`, `frontmatter-subtitle`, `frontmatter-byline`, `frontmatter-dateline`, `frontmatter-abstract`, `heading-h1`, `bibliography-heading`, `frontmatter-colophon` |
323| optional | `a figure`, `a table`, `a code block`, `a pull quote` |
324| never | `a paragraph`, `a list`, `a block quote`, `a callout`, `heading 2 and below`, `a block of endnotes` |
325| note | A wide figure or table opts in per instance. The default is column-width, because a spanning element costs a break in both columns. `always` is element ids, so tools/check.mjs can hold both implementations to it; `optional` and `never` are prose, because they describe author choice and default flow rather than a property either implementation can be held to. Each of those entries is written so that it cannot be read as an id — tools/check.mjs fails if one ever matches an element or section id, which is what keeps the two arms distinguishable by shape now that `figure`, `table`, `list` and `callout` are ids in their own right. `bibliography-heading` is on `always` as its own element, distinct from `heading-h2`: `never`'s "heading 2 and below" names the generic heading levels heading-h2 through heading-h6, not a differently-identified element that happens to share their scale — so a bibliography heading may span both columns while an ordinary section heading may not. |
326
327#### forbidden
328
329| Property | Value |
330| --- | --- |
331| sidenote | There is no margin to put it in. Use a footnote or an endnote. |
332| dropcap | A three-line cap at 3.05em is 29pt in an 82mm column — 10mm of the column given to one letter. Open with small caps instead. |
333| measure variants | narrow and wide are meaningless: the column is the measure. |
334
335#### element overrides
336
337**h1**
338
339| Property | Value |
340| --- | --- |
341| size | `20pt` |
342| spans | `both columns` |
343| space after | `9.5pt` |
344
345**h2**
346
347| Property | Value |
348| --- | --- |
349| size | `13pt` |
350| space before | `19pt` |
351| space after | `4.75pt` |
352
353**h3**
354
355| Property | Value |
356| --- | --- |
357| size | `11pt` |
358| space before | `19pt` |
359| space after | `4.75pt` |
360
361**h4**
362
363| Property | Value |
364| --- | --- |
365| size | `9.5pt` |
366| space before | `19pt` |
367| space after | `4.75pt` |
368
369**paragraph**
370
371| Property | Value |
372| --- | --- |
373| size | `9.5pt` |
374| line height | `1.4` |
375| space after | `0` |
376| first line indent | `1.25em` |
377| note | Indented paragraphs are the default here, not an option: a blank line costs 3% of a column. |
378
379**blockquote**
380
381| Property | Value |
382| --- | --- |
383| size | `9pt` |
384| indent left | `9.5pt` |
385
386**table**
387
388| Property | Value |
389| --- | --- |
390| size | `8pt` |
391| line height | `1.3` |
392
393**codeblock**
394
395| Property | Value |
396| --- | --- |
397| size | `7.5pt` |
398| line height | `1.4` |
399
400**figure caption**
401
402| Property | Value |
403| --- | --- |
404| size | `8pt` |
405
406**footnote**
407
408| Property | Value |
409| --- | --- |
410| size | `8pt` |
411| note | Scoped to the page, not the column: one notes area spanning both columns at the page foot. |
412
413**endnotes**
414
415| Property | Value |
416| --- | --- |
417| size | `8.5pt` |
418
419**pullquote**
420
421| Property | Value |
422| --- | --- |
423| size | `12pt` |
424| note | Column width by default. Spanning both columns turns it into a divider, which is a different and heavier thing. |
425
426**abstract**
427
428| Property | Value |
429| --- | --- |
430| size | `9pt` |
431| max width | the full text width, set apart above the columns |
432
433## Elements
434
435### Structure
436
437#### Headings
438
439`heading`
440
441- Sans against the serif body, so hierarchy reads by contrast rather than by size alone.
442- Below level 4 the size stops changing and the register shifts instead — small caps, then italic. Six distinct levels inside a 24pt–11pt range.
443- Space above is four times the space below: a heading belongs to what follows it.
444- A heading MUST NOT be the last thing on a page. This is the most common defect in printed documents.
445
446##### Heading 1 — document title
447
448| Property | Value |
449| --- | --- |
450| font | `sans` |
451| weight | `300` |
452| size | `24pt` |
453| line height | `1.2` |
454| baseline advance | `28.8pt` |
455| tracking | `-0.015em` |
456| color | `ink` |
457| align | `left` |
458| space before | `0` |
459| space after | `5.5pt` |
460| break after | `avoid` |
461| break inside | `avoid` |
462| wrap | `balanced` |
463
464##### Heading 2 — section
465
466| Property | Value |
467| --- | --- |
468| font | `sans` |
469| weight | `600` |
470| size | `18pt` |
471| line height | `1.2` |
472| baseline advance | `21.6pt` |
473| tracking | `-0.01em` |
474| color | `ink` |
475| align | `left` |
476| space before | `22pt` |
477| space after | `5.5pt` |
478| break after | `avoid` |
479| break inside | `avoid` |
480| wrap | `balanced` |
481| sets running head | yes |
482
483##### Heading 3 — subsection
484
485| Property | Value |
486| --- | --- |
487| font | `sans` |
488| weight | `600` |
489| size | `14pt` |
490| line height | `1.2` |
491| baseline advance | `16.8pt` |
492| color | `ink` |
493| align | `left` |
494| space before | `22pt` |
495| space after | `5.5pt` |
496| break after | `avoid` |
497
498##### Heading 4
499
500| Property | Value |
501| --- | --- |
502| font | `sans` |
503| weight | `600` |
504| size | `12pt` |
505| line height | `1.2` |
506| baseline advance | `14.4pt` |
507| color | `ink` |
508| align | `left` |
509| space before | `22pt` |
510| space after | `5.5pt` |
511| break after | `avoid` |
512
513##### Heading 5
514
515| Property | Value |
516| --- | --- |
517| font | `serif` |
518| weight | `600` |
519| size | `11pt` |
520| variant | `all small caps` |
521| tracking | `0.06em` |
522| color | `ink` |
523| space before | `22pt` |
524| space after | `5.5pt` |
525| break after | `avoid` |
526
527> No size change from body — the register carries the level.
528
529##### Heading 6
530
531| Property | Value |
532| --- | --- |
533| font | `serif` |
534| weight | `400` |
535| style | `italic` |
536| size | `11pt` |
537| color | `ink` |
538| space before | `22pt` |
539| space after | `5.5pt` |
540| break after | `avoid` |
541
542##### Run-in heading
543
544| Property | Value |
545| --- | --- |
546| display | inline with the first line of its paragraph |
547| separator | ` · ` |
548| separator color | `ink_faint` |
549| space before | `0` |
550| space after | `0` |
551
552> For dense reports where a full heading line is too much vertical cost.
553
554#### Section numbering
555
556`numbering` · opt-in: `typeset--numbered`
557
558- Numbers are generated by a counter, never typed. A typed number drifts the moment a section moves.
559- Reports are numbered; essays and letters are not. It must be one switch.
560
561##### Level-2 number
562
563| Property | Value |
564| --- | --- |
565| format | `1` |
566| separator | `two spaces` |
567| color | `ink_faint` |
568| numerals | `lining tabular` |
569| resets | `the level-3 counter` |
570
571##### Level-3 number
572
573| Property | Value |
574| --- | --- |
575| format | `1.1` |
576| separator | `two spaces` |
577| color | `ink_faint` |
578| numerals | `lining tabular` |
579
580### Prose
581
582#### Paragraphs
583
584`paragraph`
585
586- Two conventions, one switch. Spaced paragraphs suit documents that get skimmed. Indented paragraphs with no gap suit continuous prose and are the convention of nearly every printed book.
587- The first paragraph after any heading, block or break is flush left: the thing above it has already marked the start.
588
589##### Paragraph — spaced (default)
590
591| Property | Value |
592| --- | --- |
593| font | `serif` |
594| weight | `400` |
595| size | `11pt` |
596| line height | `1.45` |
597| baseline advance | `15.95pt` |
598| numerals | `oldstyle proportional` |
599| color | `ink` |
600| space after | `11pt` |
601| first line indent | `0` |
602| orphans | `2` |
603| widows | `2` |
604| max width | `33em` |
605
606##### Paragraph — indented (opt-in: `typeset--indented`)
607
608| Property | Value |
609| --- | --- |
610| space after | `0` |
611| first line indent | `1.5em` |
612| first line indent after block | `0` |
613
614> Applies after a heading, blockquote, figure or section break, and to the first paragraph of the document.
615
616#### Alignment: ragged or justified
617
618`justification` · opt-in: `typeset--justified`
619
620- Ragged right is the DEFAULT, and it is a choice rather than an absence — a document states it. Justification buys a clean right edge at the cost of uneven word spacing; a ragged setting keeps the spacing even and gives up the edge. Neither is more correct, but the cost lands differently by document.
621- Choose ragged right for a letter, a memorandum, a short note — anything addressed to a person rather than to a readership. Justification reads as institutional, and its even edge is the visual signature of print that was set for strangers.
622- Choose justification for continuous prose at a full measure: an essay, a report, a paper. It is mandatory in two columns, where a ragged edge at 49 characters serrates the column.
623- These are a single decision. Justification without hyphenation opens rivers of white space; hyphenation without justification breaks words for no gain. Take both or neither.
624- Hyphenation is per-language and requires the document language to be declared. An English dictionary applied to Portuguese produces confident nonsense.
625- The last line of a paragraph is NEVER stretched. State this explicitly — a paginating engine fragments the text, so the visual last line stops looking like the end of a paragraph and gets justified. It does not reproduce in an unpaginated preview.
626- Justification applies to prose only. It MUST NOT reach a subtitle, byline, caption, address block, table cell, heading or listing. In an engine where alignment inherits, every such block declares its own alignment rather than relying on an exception list.
627- Alignment inherits, and so does last-line alignment. A block that sets its own alignment — a centred pull quote, a centred section break — must also set its own last-line alignment, or the document's justification flushes its last line (its only line, for a one-liner) to the left.
628
629##### Ragged right (default) (opt-in: `typeset--ragged — names the default; no class needed to get it`)
630
631| Property | Value |
632| --- | --- |
633| align | `left` |
634| align last line | `left` |
635| hyphenation | `manual — never automatic` |
636| line breaking | high effort: avoid a very short last line, and even out the right edge |
637| applies to | `paragraph`, `list item`, `blockquote`, `definition description`, `callout` |
638
639> Hyphenation exists to serve justification. Without justification a hyphen breaks a word for no gain, so it stays off.
640
641> The rag itself is the thing to judge: an even rag reads as deliberate, a rag with one very short line and one very long one reads as an accident.
642
643##### Justified
644
645| Property | Value |
646| --- | --- |
647| align | `justify` |
648| align last line | `left` |
649| justify method | `inter-word` |
650| hyphenation | `automatic` |
651| hyphenation min word chars | `6` |
652| hyphenation min chars before break | `3` |
653| hyphenation min chars after break | `3` |
654| max consecutive hyphens | `2` |
655| applies to | `paragraph`, `list item`, `blockquote`, `definition description`, `callout` |
656
657Where unsupported: automatic hyphenation, but at the engine's own built-in limits — the four tuning values above are not configurable
658
659##### Never justified
660
661| Property | Value |
662| --- | --- |
663| align | `left` |
664| hyphenation | `manual` |
665| applies to | `all headings`, `subtitle`, `byline`, `dateline`, `abstract`, `attribution`, `epigraph`, `verse`, `caption`, `figure caption`, `address block`, `table cell`, `table header`, `code block`, `table of contents`, `bibliography`, `endnotes`, `sidenote`, `letterhead`, `salutation`, `closing`, `signature`, `enclosures`, `postscript`, `definition term` |
666
667#### Drop cap
668
669`dropcap`
670
671- For the opening of an essay or a chapter, and nowhere else.
672- The size and line height are tuned together to cover exactly three lines. Change the leading and the cap must be retuned.
673- The opening words go in small caps. Without them the jump from 33pt to 11pt is too abrupt and the eye skips the first line.
674
675##### Drop cap
676
677| Property | Value |
678| --- | --- |
679| font | `serif` |
680| weight | `400` |
681| size | `3.05em` |
682| size pt | `33.55pt` |
683| line height | `0.86` |
684| color | `accent` |
685| float | `left` |
686| lines covered | `3` |
687| padding right | `0.06em` |
688| padding top | `0.02em` |
689| first line indent | `0` |
690
691##### Opening words
692
693| Property | Value |
694| --- | --- |
695| variant | `all small caps` |
696| tracking | `0.04em` |
697| extent | the first two to four words |
698
699#### Inline emphasis
700
701`inline`
702
703- Nested emphasis FLIPS to roman rather than compounding. This is correct typographic behaviour and most engines get it wrong by default.
704- Superscripts and subscripts must not disturb the line's leading.
705- Underline is reserved for insertions. On paper it is a typewriter's substitute for italic, and there is no reason to imitate a typewriter.
706
707##### Bold
708
709| Property | Value |
710| --- | --- |
711| weight | `600` |
712
713> For the load-bearing clause.
714
715##### Italic
716
717| Property | Value |
718| --- | --- |
719| style | `italic` |
720
721> For a title or a term of art.
722
723##### Nested italic
724
725| Property | Value |
726| --- | --- |
727| style | `normal` |
728
729##### Small caps
730
731| Property | Value |
732| --- | --- |
733| variant | `all small caps` |
734| tracking | `0.05em` |
735| numerals | `oldstyle` |
736
737> Named entities, acronyms, stage directions.
738
739##### Abbreviation
740
741| Property | Value |
742| --- | --- |
743| variant | `all small caps` |
744| tracking | `0.05em` |
745| underline | `0.5pt dotted` |
746| underline color | `ink_faint` |
747
748##### Superscript
749
750| Property | Value |
751| --- | --- |
752| size | `0.72em` |
753| baseline shift | `+0.45em` |
754| line height | `0` |
755| affects leading | no |
756
757##### Subscript
758
759| Property | Value |
760| --- | --- |
761| size | `0.72em` |
762| baseline shift | `-0.22em` |
763| line height | `0` |
764| affects leading | no |
765
766##### Deletion
767
768| Property | Value |
769| --- | --- |
770| decoration | `line-through` |
771| color | `ink_muted` |
772
773##### Insertion
774
775| Property | Value |
776| --- | --- |
777| decoration | `underline` |
778| underline offset | `0.15em` |
779
780##### Highlight
781
782| Property | Value |
783| --- | --- |
784| background | `wash` |
785| bleed | `2pt beyond the glyphs` |
786
787##### Key
788
789| Property | Value |
790| --- | --- |
791| font | `sans` |
792| size | `0.85em` |
793| padding | `0.15em 0.35em` |
794| border | `0.5pt rule` |
795| border bottom | `1.5pt rule` |
796| radius | `2pt` |
797
798#### Inline code
799
800`code-inline`
801
802##### Inline code
803
804| Property | Value |
805| --- | --- |
806| font | `mono` |
807| size | `0.86em` |
808| ligatures | `disabled` |
809| background | `wash` |
810| padding | `0.1em 0.28em` |
811| radius | `2pt` |
812| wrap | `may break within a word` |
813
814> The 0.86em corrects for the monospace face running optically large beside the serif.
815
816> Ligatures off: an arrow rendered as one glyph is charming in an editor and wrong in a document that quotes source.
817
818#### Links in print
819
820`link`
821
822- Paper has no hover and no click. A URL that carries information must be printed.
823
824##### Link
825
826| Property | Value |
827| --- | --- |
828| color | `inherit` |
829| decoration | `underline` |
830| underline thickness | `0.5pt` |
831| underline offset | `0.14em` |
832| skip descenders | yes |
833
834##### Printed URL
835
836| Property | Value |
837| --- | --- |
838| content | the href in parentheses, after the link text |
839| font | `mono` |
840| size | `0.82em` |
841| color | `ink_muted` |
842| wrap | `may break anywhere` |
843| applies to | external (http/https) links only |
844| excluded | `internal anchors`, `mailto:`, `links marked bare` |
845
846##### Link — URL suppressed
847
848| Property | Value |
849| --- | --- |
850| print url | no |
851
852> Opt-out for a link whose URL would be noise in print: a shortened URL, a tracking URL, or one the surrounding sentence already gives.
853
854#### Numerals
855
856`numeral`
857
858- Three kinds, three jobs. Getting this wrong is the most visible amateur tell in a set document, and it is one setting.
859- Old-style figures have ascenders and descenders and sit inside the x-height. Lining figures are uniform cap height. Tabular figures share one advance width, which is the only reason a column of numbers can align.
860
861##### In running prose
862
863| Property | Value |
864| --- | --- |
865| numerals | `oldstyle proportional` |
866
867##### In headings and display
868
869| Property | Value |
870| --- | --- |
871| numerals | `lining proportional` |
872
873##### In tables and columns
874
875| Property | Value |
876| --- | --- |
877| numerals | `lining tabular` |
878
879##### Fractions
880
881| Property | Value |
882| --- | --- |
883| form | `diagonal` |
884
885### Blocks
886
887#### Quotations
888
889`quote`
890
891- Four jobs, four treatments. A block quote is evidence. An epigraph opens a chapter. A pull quote is display type lifted from the body. Verse preserves the poet's line breaks.
892- A pull quote repeats text that already appears in the body, so it MUST NOT be the only place a claim appears — a skimming reader would get the claim without its qualification.
893- Attribution always sits outside the quotation. Inside, it becomes part of what was said.
894
895##### Block quote
896
897| Property | Value |
898| --- | --- |
899| font | `serif` |
900| size | `10.5pt` |
901| line height | `1.45` |
902| color | `ink` |
903| space before | `13.75pt` |
904| space after | `13.75pt` |
905| indent left | `16.5pt` |
906| border left | `1pt rule` |
907| break inside | `avoid` |
908| last child space after | `0` |
909
910##### Attribution
911
912| Property | Value |
913| --- | --- |
914| display | `block` |
915| align | `left` |
916| space before | `5.5pt` |
917| size | `9.5pt` |
918| style | `normal` |
919| color | `ink_muted` |
920| prefix | `em dash and a space` |
921
922##### Epigraph
923
924| Property | Value |
925| --- | --- |
926| font | `serif` |
927| style | `italic` |
928| size | `10pt` |
929| color | `ink_muted` |
930| align | `left` |
931| block alignment | `flush right` |
932| max width | `24em` |
933| border | `none` |
934| space after | `22pt` |
935
936> Cite inside an epigraph is roman, not italic — the surrounding block is already italic.
937
938##### Pull quote
939
940| Property | Value |
941| --- | --- |
942| font | `sans` |
943| weight | `300` |
944| size | `15pt` |
945| line height | `1.3` |
946| align | `centre` |
947| wrap | `balanced` |
948| border top | `1.5pt rule_strong` |
949| border bottom | `0.5pt rule` |
950| padding top | `11pt` |
951| padding bottom | `11pt` |
952| space before | `16.5pt` |
953| space after | `16.5pt` |
954
955##### Verse
956
957| Property | Value |
958| --- | --- |
959| font | `serif` |
960| size | `11pt` |
961| align | `left` |
962| line breaks | `preserved as authored` |
963| indent left | `22pt` |
964| runover indent | `1.5em` |
965| border | `none` |
966
967Where unsupported: in Typst: the left indent and the authored line breaks, but no runover indent — a wrapped line reads the same as one the poet wrote
968
969> Runover lines indent further than the verse line they continue, so a wrapped line cannot be mistaken for a new one.
970
971#### Lists
972
973`list`
974
975- The marker's colour, weight and width must be under control. A grey marker with black text reads as one thing; a black marker competes with the first word.
976- Runover lines align to the text, never to the marker.
977- Two levels of nesting is the limit worth designing for.
978- Definition lists are underused: they are the right shape for a glossary, a set of terms, or the field-and-value blocks of a letter.
979
980##### Unordered list
981
982| Property | Value |
983| --- | --- |
984| marker | `·` |
985| marker color | `ink_muted` |
986| marker weight | `700` |
987| marker column width | `1.4em` |
988| indent | `1.4em` |
989| item space after | `2.75pt` |
990| space after | `11pt` |
991
992##### Unordered list, nested
993
994| Property | Value |
995| --- | --- |
996| marker | `–` |
997| marker weight | `400` |
998| space before | `2.75pt` |
999
1000##### Ordered list
1001
1002| Property | Value |
1003| --- | --- |
1004| marker | `1.` |
1005| marker color | `ink_muted` |
1006| numerals | `lining tabular` |
1007| marker column width | `1.4em` |
1008| indent | `1.4em` |
1009| item space after | `2.75pt` |
1010
1011> Tabular numerals so 9 and 10 align.
1012
1013##### Ordered list, nested
1014
1015| Property | Value |
1016| --- | --- |
1017| marker | `a.` |
1018
1019##### Tight list (opt-in: `ts-list-tight`)
1020
1021| Property | Value |
1022| --- | --- |
1023| item space after | `0` |
1024
1025> For enumerations that are not prose.
1026
1027##### Definition term
1028
1029| Property | Value |
1030| --- | --- |
1031| font | `sans` |
1032| weight | `600` |
1033| size | `9.5pt` |
1034| align | `left` |
1035| space before | `6.6pt` |
1036| space before first | `0` |
1037| break after | `avoid` |
1038
1039##### Definition description
1040
1041| Property | Value |
1042| --- | --- |
1043| font | `serif` |
1044| size | `11pt` |
1045| indent left | `16.5pt` |
1046| space after | `0` |
1047
1048#### Tables
1049
1050`table`
1051
1052- Rules, not grids. Vertical rules are almost never needed — the columns already read as columns, and every added line is ink competing with data.
1053- Three horizontal rules only: above the header, below the header, below the body.
1054- A table is scanned, not read. Sans at 9.5pt; the serif's job is reading.
1055- Numbers align on their right edge, on tabular figures. Units go in the header, not in every cell.
1056- A table that spans pages MUST repeat its header on each. Without it, page two of a table is unreadable.
1057
1058##### Table
1059
1060| Property | Value |
1061| --- | --- |
1062| font | `sans` |
1063| size | `9.5pt` |
1064| line height | `1.35` |
1065| numerals | `lining tabular` |
1066| width | `full measure` |
1067| space before | `13.75pt` |
1068| space after | `13.75pt` |
1069| border collapse | yes |
1070
1071##### Header cell
1072
1073| Property | Value |
1074| --- | --- |
1075| font | `sans` |
1076| weight | `600` |
1077| size | `8pt` |
1078| case | `uppercase` |
1079| tracking | `0.07em` |
1080| color | `ink_muted` |
1081| align | `left` |
1082| border top | `1pt rule_strong` |
1083| border bottom | `1pt rule_strong` |
1084| padding | `0.45em 0.7em 0.45em 0` |
1085| repeats across pages | yes |
1086
1087##### Body cell
1088
1089| Property | Value |
1090| --- | --- |
1091| align | `left` |
1092| vertical align | `baseline` |
1093| border bottom | `0.5pt rule` |
1094| padding | `0.45em 0.7em 0.45em 0` |
1095| last row border bottom | `1pt rule_strong` |
1096
1097##### Numeric cell
1098
1099| Property | Value |
1100| --- | --- |
1101| align | `right` |
1102| numerals | `lining tabular` |
1103
1104##### Footer cell
1105
1106| Property | Value |
1107| --- | --- |
1108| weight | `600` |
1109| border bottom | `none` |
1110
1111##### Caption
1112
1113| Property | Value |
1114| --- | --- |
1115| position | `above the table` |
1116| align | `left` |
1117| font | `sans` |
1118| size | `9.5pt` |
1119| color | `ink` |
1120| space after | `0.5em` |
1121| max width | `none` |
1122
1123##### Row
1124
1125| Property | Value |
1126| --- | --- |
1127| break inside | `avoid` |
1128
1129##### Zebra striping (opt-in: `ts-table-zebra`)
1130
1131| Property | Value |
1132| --- | --- |
1133| background | `wash on even body rows` |
1134
1135> For wide, dense tables only. Not a default.
1136
1137##### Caption label
1138
1139| Property | Value |
1140| --- | --- |
1141| weight | `600` |
1142| caps | `all small caps` |
1143| tracking | `0.06em` |
1144
1145#### Code blocks
1146
1147`codeblock`
1148
1149- Paper cannot scroll. Lines wrap; they are never clipped.
1150- A long listing MUST be allowed to split across pages. Forbidding the break pushes a blank page ahead of it.
1151
1152##### Code block
1153
1154| Property | Value |
1155| --- | --- |
1156| font | `mono` |
1157| size | `8.5pt` |
1158| line height | `1.45` |
1159| background | `wash` |
1160| border left | `2pt rule_strong` |
1161| padding | `0.8em 1em` |
1162| space before | `13.75pt` |
1163| space after | `13.75pt` |
1164| wrap | `soft-wrap long lines` |
1165| tab size | `2` |
1166| break inside | avoid on screen, allowed in print |
1167
1168#### Figures & captions
1169
1170`figure`
1171
1172- A caption is not a title: it goes below the figure.
1173- A figure and its caption stay on one page. This is the one place a no-break rule is unambiguously right.
1174- The caption carries a small-caps label so a cross-reference in the text has something to point at.
1175
1176##### Figure
1177
1178| Property | Value |
1179| --- | --- |
1180| space before | `16.5pt` |
1181| space after | `16.5pt` |
1182| break inside | `avoid` |
1183| image max width | `full measure` |
1184
1185##### Figure caption
1186
1187| Property | Value |
1188| --- | --- |
1189| position | `below the figure` |
1190| font | `sans` |
1191| size | `9.5pt` |
1192| line height | `1.4` |
1193| color | `ink_muted` |
1194| align | `left` |
1195| space before | `0.5em` |
1196| border top | `0.5pt rule` |
1197| padding top | `0.4em` |
1198
1199##### Figure caption label
1200
1201| Property | Value |
1202| --- | --- |
1203| weight | `600` |
1204| color | `ink` |
1205| caps | `all small caps` |
1206| tracking | `0.06em` |
1207
1208#### Callouts
1209
1210`callout`
1211
1212- A callout is an aside the reader may skip without losing the argument. If skipping it would lose the argument, it is a paragraph.
1213- Two variants only. A document with five callout colours has none.
1214
1215##### Callout
1216
1217| Property | Value |
1218| --- | --- |
1219| font | `serif` |
1220| size | `10pt` |
1221| background | `wash` |
1222| border | `0.5pt rule` |
1223| border left | `2.5pt rule_strong` |
1224| padding | `0.75em 1em` |
1225| space before | `13.75pt` |
1226| space after | `13.75pt` |
1227| break inside | `avoid` |
1228
1229##### Callout title
1230
1231| Property | Value |
1232| --- | --- |
1233| font | `sans` |
1234| weight | `700` |
1235| size | `8pt` |
1236| case | `uppercase` |
1237| tracking | `0.09em` |
1238| color | `ink_muted` |
1239| space after | `0.35em` |
1240
1241##### Callout — warning
1242
1243| Property | Value |
1244| --- | --- |
1245| border left | `2.5pt accent` |
1246| title color | `accent` |
1247
1248#### Section breaks
1249
1250`break`
1251
1252- A blank line cannot survive a page break: if the break falls on the gap, the reader never learns the scene changed. Over a long document this is a certainty, not an accident. The mark MUST be visible.
1253- Four registers, one per kind of division.
1254
1255##### Break — three asterisks
1256
1257| Property | Value |
1258| --- | --- |
1259| content | `* * *` |
1260| size | `10pt` |
1261| tracking | `0.6em` |
1262| color | `ink_faint` |
1263| align | `centre` |
1264| space before | `16.5pt` |
1265| space after | `16.5pt` |
1266| break after | `avoid` |
1267
1268> The default, for a change of scene in prose.
1269
1270##### Break — asterism
1271
1272| Property | Value |
1273| --- | --- |
1274| content | `⁂` |
1275| size | `14pt` |
1276| color | `ink_faint` |
1277| align | `centre` |
1278
1279> A heavier division: a change of part.
1280
1281##### Break — fleuron
1282
1283| Property | Value |
1284| --- | --- |
1285| content | `❦` |
1286| size | `12pt` |
1287| color | `accent` |
1288| align | `centre` |
1289
1290> Where the document can afford ornament.
1291
1292##### Break — rule
1293
1294| Property | Value |
1295| --- | --- |
1296| border top | `0.5pt rule` |
1297| content | `none` |
1298
1299> Where it cannot. Reports.
1300
1301### Apparatus
1302
1303#### Footnotes, endnotes & sidenotes
1304
1305`note`
1306
1307- Bottom-of-page footnotes require an engine that can measure the page while laying it out. Typst and LaTeX do this natively. WeasyPrint 53+ and Prince implement the CSS footnote model. No browser does.
1308- Where footnotes are unavailable the note text MUST still live in the document, degrading to a numbered endnotes block — never to a lost note.
1309- Sidenotes are the better default where the page can afford the margin: no page-break arithmetic, and the reader never leaves the sentence they are in.
1310- The reference mark must not disturb the leading of the line it sits on.
1311
1312##### Reference mark
1313
1314| Property | Value |
1315| --- | --- |
1316| content | `the note number` |
1317| size | `0.7em` |
1318| baseline shift | `+0.45em` |
1319| line height | `0` |
1320| color | `accent` |
1321| numerals | `lining` |
1322| decoration | `none` |
1323| brackets | `none` |
1324| affects leading | no |
1325
1326##### Footnote
1327
1328| Property | Value |
1329| --- | --- |
1330| position | foot of the page carrying the mark |
1331| font | `serif` |
1332| size | `9.5pt` |
1333| line height | `1.35` |
1334| separator | a rule above the notes area |
1335
1336Where unsupported: an endnotes block at the end of the document
1337
1338##### Endnotes block
1339
1340| Property | Value |
1341| --- | --- |
1342| font | `serif` |
1343| size | `9.5pt` |
1344| line height | `1.4` |
1345| align | `left` |
1346| space before | `22pt` |
1347| border top | `0.5pt rule` |
1348| padding top | `11pt` |
1349| list indent | `1.8em` |
1350| item space after | `0.4em` |
1351| heading | none — the rule above the block is the only mark it needs |
1352
1353> No 'NOTES' label. In a one-page document the rule plus the numbered list already reads as a notes area, and a heading over two lines of small print is heavier than the thing it labels.
1354
1355##### Sidenote (opt-in: `typeset--sidenotes`)
1356
1357| Property | Value |
1358| --- | --- |
1359| font | `sans` |
1360| size | `8pt` |
1361| line height | `1.4` |
1362| color | `ink_muted` |
1363| align | `left` |
1364| width | `11em` |
1365| position | the right margin, 2em past the text column's own right edge |
1366| vertical offset | -0.3em from the marker's line |
1367| marker prefix | the note number in accent, weight 600 |
1368| measure when active | `27em` |
1369| reserved margin | 14em — the gap plus the note, with an em to spare |
1370
1371> Anchor the note to the text column's right edge, not to the measure. The measure is a maximum: where the reserved margin is the binding constraint the column is narrower than it, and a note offset from the measure lands on top of the text.
1372
1373> Sidenotes are positioned, not flowed: a long note followed closely by another will overlap it. Keep each note short and consecutive notes apart — one per paragraph, and not in every paragraph. An implementation cannot fix this, and should not pretend to; it is a constraint on the writing.
1374
1375#### Table of contents
1376
1377`toc`
1378
1379- Page numbers require the engine to resolve a cross-reference after pagination. Where it cannot, the entry MUST omit the number rather than print a wrong one — a TOC with wrong numbers is worse than one with none.
1380
1381##### Table of contents
1382
1383| Property | Value |
1384| --- | --- |
1385| font | `sans` |
1386| size | `9.5pt` |
1387| align | `left` |
1388
1389##### Entry
1390
1391| Property | Value |
1392| --- | --- |
1393| space after | `0.35em` |
1394| decoration | `none` |
1395| page number | `resolved after pagination` |
1396| page number numerals | `lining tabular` |
1397| page number color | `ink_muted` |
1398
1399Where unsupported: leaders render, page numbers are omitted
1400
1401##### Entry — level 2
1402
1403| Property | Value |
1404| --- | --- |
1405| indent left | `1.5em` |
1406
1407##### Dot leader
1408
1409| Property | Value |
1410| --- | --- |
1411| leader | dotted 0.5pt rule, colour rule, filling the space between title and number |
1412| baseline offset | `-0.15em` |
1413
1414#### Bibliography
1415
1416`bibliography`
1417
1418- Hanging indent, always. The surname is what is being scanned, so it must be the leftmost thing on the entry.
1419- The heading is its own element, not an instance of heading-h2, even though it shares h2's scale and weight: the distinct id is what lets it span both columns in the two-column template while an ordinary section heading — heading-h2 through heading-h6 — cannot.
1420
1421##### Heading
1422
1423| Property | Value |
1424| --- | --- |
1425| font | `sans` |
1426| weight | `600` |
1427| size | `18pt` |
1428| line height | `1.2` |
1429| baseline advance | `21.6pt` |
1430| tracking | `-0.01em` |
1431| color | `ink` |
1432| align | `left` |
1433| space before | `22pt` |
1434| space after | `5.5pt` |
1435| break after | `avoid` |
1436| break inside | `avoid` |
1437| wrap | `balanced` |
1438| sets running head | yes |
1439
1440##### Entry
1441
1442| Property | Value |
1443| --- | --- |
1444| font | `serif` |
1445| size | `9.5pt` |
1446| line height | `1.4` |
1447| align | `left` |
1448| hanging indent | `1.8em` |
1449| space after | `0.55em` |
1450| marker | `none` |
1451| break inside | `avoid` |
1452| title style | `italic` |
1453
1454Where unsupported: in Typst: every property here except the hanging indent — a wrapped line sits flush with the surname instead of indented past it
1455
1456### Documents
1457
1458#### Front matter
1459
1460`frontmatter`
1461
1462- A colophon closes the document, recording how it was made and in what type. It is the one piece of matter that is purely for pleasure, and the cheapest thing here to include.
1463
1464##### Title block
1465
1466| Property | Value |
1467| --- | --- |
1468| space after | `33pt` |
1469| padding bottom | `11pt` |
1470| border bottom | `0.5pt rule` |
1471
1472##### Subtitle
1473
1474| Property | Value |
1475| --- | --- |
1476| font | `sans` |
1477| weight | `300` |
1478| size | `14pt` |
1479| line height | `1.25` |
1480| color | `ink_muted` |
1481| align | `left` |
1482| wrap | `balanced` |
1483| space after | `11pt` |
1484
1485##### Byline
1486
1487| Property | Value |
1488| --- | --- |
1489| font | `serif` |
1490| size | `11pt` |
1491| variant | `all small caps` |
1492| tracking | `0.08em` |
1493| align | `left` |
1494| space after | `0` |
1495
1496##### Dateline
1497
1498| Property | Value |
1499| --- | --- |
1500| font | `sans` |
1501| size | `9.5pt` |
1502| color | `ink_muted` |
1503| align | `left` |
1504| space before | `0.2em` |
1505
1506##### Abstract
1507
1508| Property | Value |
1509| --- | --- |
1510| font | `serif` |
1511| size | `10pt` |
1512| line height | `1.45` |
1513| color | `ink_muted` |
1514| align | `left` |
1515| max width | `30em` |
1516| space after | `22pt` |
1517
1518##### Colophon
1519
1520| Property | Value |
1521| --- | --- |
1522| font | `serif` |
1523| style | `italic` |
1524| size | `9.5pt` |
1525| color | `ink_muted` |
1526| align | `left` |
1527| max width | `26em` |
1528| space before | `33pt` |
1529| padding top | `11pt` |
1530| border top | `0.5pt rule` |
1531| break before | `avoid` |
1532
1533##### Abstract label
1534
1535| Property | Value |
1536| --- | --- |
1537| display | `block` |
1538| font | `sans` |
1539| size | `xs` |
1540| weight | `700` |
1541| tracking | `0.1em` |
1542| caps | `uppercase` |
1543| color | `ink_faint` |
1544
1545#### Letter
1546
1547`letter`
1548
1549- A letter is set justified, at 12pt, across the full width its margins leave. It is read once, closely, by one person, and an even page with a quiet edge serves that reading.
1550- Sender and address blocks are address data, not a masthead. The name line is set in small caps at body size, and the lines below it a step smaller, so the eye finds who before where. Nothing bold, nothing in the sans, nothing larger than the text: a personal letter does not announce itself.
1551- Address blocks are line-broken data, not prose: tighter leading, never justified, line breaks as authored.
1552- The letterhead — the addresses and any crest — sits the standard margin from the paper's edge, or at the text's own edge where that is nearer the paper. Where the text sits further in, under a wider margin or a centred measure, the letterhead stays out at the standard margin rather than moving in with it.
1553- The signature is the typed name with room above it to sign. No ruled line — a rule is a form to be filled in.
1554- A letter carries no running head and no folio.
1555- Footnotes belong in a letter as much as in an essay. Where the engine cannot set them at the page foot, the rule plus the numbered note at the end of a one-page letter reads as a footnote area regardless.
1556
1557##### Letter page
1558
1559| Property | Value |
1560| --- | --- |
1561| margin top mm | `35` |
1562| margin bottom mm | `35` |
1563| margin sides mm | `35` |
1564| base size | `12pt` |
1565| measure | full — the width the margins leave, about 66 characters on A4 |
1566| justification | `justified` |
1567| running head | `none` |
1568| folio | `none` |
1569| block quote | `letter-quote` |
1570
1571> The text sits letter_inset_mm inside the standard margin on every edge. The letterhead — letter-addresses and letter-crest — reaches back out by the same amount, so the addresses and the crest stand at the standard margin and the text is framed inside them.
1572
1573> At 12pt, the full width inside 35mm margins on A4 carries about 66 characters: the standard measure, reached by the margin rather than by a cap.
1574
1575##### Sender block
1576
1577| Property | Value |
1578| --- | --- |
1579| font | `serif` |
1580| weight | `400` |
1581| size | `12pt` |
1582| line height | `1.35` |
1583| color | `ink` |
1584| align | `left` |
1585| line breaks | as authored — name, street, suburb and postcode, country |
1586| space after | `30pt` |
1587| name line | small caps (smcp and c2sc), at body size |
1588| detail size | `10.2pt — 0.85 of body` |
1589
1590> The name is the one line in small caps, at body size; street, suburb and country sit a step smaller beneath it. Never larger and never bold — that turns a letter into stationery.
1591
1592> Omit what you do not use. A personal letter needs no email address and no telephone number.
1593
1594##### Address block
1595
1596| Property | Value |
1597| --- | --- |
1598| font | `serif` |
1599| size | `12pt` |
1600| line height | `1.35` |
1601| style | `normal` |
1602| align | `left` |
1603| line breaks | `as authored` |
1604| space after | `16.5pt` |
1605| name line | small caps (smcp and c2sc), at body size |
1606| detail size | `10.2pt — 0.85 of body` |
1607
1608##### Address column
1609
1610| Property | Value |
1611| --- | --- |
1612| left edge | foundation.page.margins.symmetric_mm.standard from the paper's left edge, or the text's own left edge where that is nearer the paper |
1613| reach | how far the text's left edge sits beyond symmetric_mm.standard — from a wider margin, a centred measure or both — or none |
1614
1615> Holds the sender and address blocks. The reach is measured from where the text actually starts, so it follows the page margin and the measure together.
1616
1617##### Crest
1618
1619| Property | Value |
1620| --- | --- |
1621| position | top right of the first page, its top on the top margin |
1622| right edge | symmetric_mm.standard from the paper's right edge, or the text's own right edge where that is nearer the paper |
1623| width | `20mm` |
1624| color | accent, where the mark is drawn in a single ink |
1625
1626> Optional. A letter with no crest leaves the corner empty; nothing moves into it.
1627
1628##### Date line
1629
1630| Property | Value |
1631| --- | --- |
1632| numerals | `oldstyle` |
1633| align | `left` |
1634| space before | `36pt` |
1635| space after | `24pt` |
1636
1637> The date and the line under it are one block. The space after belongs to the pair, not to the date alone.
1638
1639> Only the date is required. The line under it, where there is one, is the saint of the day, closed with “ora pro nobis”; with no saint the date stands alone.
1640
1641##### Line under the date
1642
1643| Property | Value |
1644| --- | --- |
1645| font | `serif` |
1646| style | `italic` |
1647| size | `10.8pt — 0.9 of body` |
1648| color | `ink_muted` |
1649| align | `left` |
1650| space before | none — the date's own next line, at body leading |
1651| space after | `24pt, the date's` |
1652
1653> A dedication, a feast, a devotion — whatever the writer puts under the date. Italic, at body size, immediately beneath.
1654
1655##### Salutation
1656
1657| Property | Value |
1658| --- | --- |
1659| align | `left` |
1660| space before | `24pt` |
1661| space after | `24pt` |
1662| form | greeting, name, comma — “Dear” unless the writer gives another greeting |
1663
1664##### Quotation — in a letter
1665
1666| Property | Value |
1667| --- | --- |
1668| font | `serif` |
1669| style | `italic` |
1670| weight | `400` |
1671| size | `12.6pt — 1.05 of body` |
1672| color | `ink_muted` |
1673| indent left | `24pt` |
1674| indent right | `24pt` |
1675| rule | `none` |
1676| space before | `18pt` |
1677| space after | `18pt` |
1678
1679> A letter quotes a prayer, a line, a remembered phrase. It is set apart by indent and colour, not by a rule: a rule is the essay's quotation, and a letter is not an essay.
1680
1681##### Closing
1682
1683| Property | Value |
1684| --- | --- |
1685| align | `left` |
1686| space before | `36pt` |
1687| space after | `24pt` |
1688| form | closing words and a comma — “Yours sincerely” unless the writer gives others |
1689
1690##### Signature block
1691
1692| Property | Value |
1693| --- | --- |
1694| font | `serif` |
1695| size | `12pt` |
1696| align | `left` |
1697| space before | `36pt — the room to sign` |
1698| rule | `none` |
1699| break inside | `avoid` |
1700| signature image max height | `16mm` |
1701
1702> The typed name only. A ruled line above a name is a form; a letter is not a form.
1703
1704##### Enclosures
1705
1706| Property | Value |
1707| --- | --- |
1708| font | `serif` |
1709| size | `12pt` |
1710| align | `left` |
1711| space before | `24pt` |
1712| label | same style as the text it introduces — no small caps, no weight change |
1713
1714> Same reasoning as the postscript: "Enc." introduces a sentence, it does not head a section.
1715
1716##### Postscript
1717
1718| Property | Value |
1719| --- | --- |
1720| font | `serif` |
1721| size | `12pt` |
1722| align | `left` |
1723| space before | 36pt — the signature's own distance from the closing |
1724| label | same style as the text it introduces — no small caps, no weight change |
1725
1726> A postscript is a sentence that happens to begin with "P.S.". The label is not a heading.
1727
1728##### Footnote — in a letter
1729
1730| Property | Value |
1731| --- | --- |
1732| marker | as the note marker in Apparatus — superscript, accent, no brackets |
1733| position | foot of the page where the engine can; otherwise after the signature block |
1734| font | `serif` |
1735| size | `9.5pt` |
1736| separator | 0.5pt rule above the notes area |
1737| heading | `none` |
1738
1739Where unsupported: a numbered note after the signature, under a rule — which on a one-page letter is the page foot anyway
1740
1741##### Address label
1742
1743| Property | Value |
1744| --- | --- |
1745| display | `block` |
1746| font | `sans` |
1747| size | `xs` |
1748| tracking | `0.1em` |
1749| caps | `uppercase` |
1750| color | `ink_faint` |
1751
1752#### Pagination utilities
1753
1754`utility`
1755
1756- The small set of overrides reached for while proofing a real document. Every one of them is a manual decision about a specific page, not a style.
1757
1758##### Break before
1759
1760| Property | Value |
1761| --- | --- |
1762| effect | start this element on a new page |
1763
1764> Chapter openings.
1765
1766##### Break after
1767
1768| Property | Value |
1769| --- | --- |
1770| effect | start the next element on a new page |
1771
1772##### Keep together
1773
1774| Property | Value |
1775| --- | --- |
1776| effect | never split this element across pages |
1777
1778> A short table, a signature block, a callout.
1779
1780##### No hyphenation
1781
1782| Property | Value |
1783| --- | --- |
1784| hyphenation | `manual` |
1785
1786##### Tie
1787
1788| Property | Value |
1789| --- | --- |
1790| effect | `no line break inside` |
1791
1792> A figure with its unit, an initial with a surname, a section mark with its number.
1793
1794##### Print only / screen only
1795
1796| Property | Value |
1797| --- | --- |
1798| effect | present in one medium, absent in the other |
1799
1800> The URL list a page needs and a screen does not; the navigation a screen needs and a page does not.
1801
1802##### Exact colour
1803
1804| Property | Value |
1805| --- | --- |
1806| effect | backgrounds and rules survive the output device's ink-saving |
1807
1808> Without it a print dialog can strip every rule in a table.
1809
1810---
1811
1812Generated from spec.json by tools/build-spec.mjs. Do not edit this file — edit spec.json and regenerate.