Internal · Testbed
evergreen
Kitchen Sink
A typography testbed that deliberately exercises every supported article element, so regressions in the design system show up before they ship.
For a successful technology, reality must take precedence over public relations, for Nature cannot be fooled.
— Richard Feynman, Rogers Commission Report (1986)
This page exists to drive the article-page typography through its paces. It is not intended to be read for content; it is a fixture11 The first sidenote in the document. Sidenotes are numbered consecutively in source order; the number you see in the gutter is assigned by the filter, not by the fn:label.. If something on this page looks wrong, the design system is wrong, and the article pages that haven't been written yet would inherit the defect. Edit this file whenever a new article element is introduced so the testbed stays exhaustive.
Margin notes are unnumbered asides set in the right gutter, part of the typeset page. When the window is too narrow for the gutter to sit on the sheet, they collapse to a clean indented block under the paragraph — they never bleed off the page.
This sentence carries an ◆arrow note, whose leader line points back from the gutter toward the word it annotates.
Arrow notes hang in the gutter and draw a thin leader back to their anchor — the convention from the sidenote-anatomy sketch, made live. The leader is suppressed when the note collapses inline.
A sticky note is a different thing entirely: not typeset marginalia but a foreign object, as if a reader peeled one off a pad and pressed it onto the page. It hangs off the sheet's right edge onto the board, sits at a real angle, and casts a lifted shadow. Authored with #+BEGIN_sticky.
Stuck on, not set in. Authored with #+BEGIN_sticky, used sparingly for an aside that should read as annotation-on-top.
A third leans back the other way — the tilt alternates per note so a run of them looks hand-placed rather than stamped.
The page as a sheet
Every page is set as a single sheet of warm ivory paper floating on a darker parchment board — the look of a printed page open in a document viewer. The sheet carries a soft drop shadow, a sliver of the next page peeks below its bottom edge, and the board is a deeper tone of the paper rather than neutral viewer-gray, so the surround reads as part of the book and not as foreign chrome. On phones the metaphor relaxes: the sheet fills the screen and the board, shadow, and page-sliver drop away.
Article-header chrome
Above the prose, the article header should present (in order) a kicker, a status pill, the H1 title in the title face and accent color, a subtitle in the display face at a lighter weight, a meta line carrying the planted and last-tended dates (with absolute ISO dates in the underlying <time> elements), and a comma-separated tag line in the link color. The block ends with generous space before the table of contents.
Body prose
The opening paragraph
The lede — the first <p> that's a direct child of <article> — receives a drop cap on its first letter and small caps on its first line. The drop cap is set in --font-dropcap (Goudy Initialen if vendored, Cormorant Upright otherwise) and tinted with --accent. The small-cap treatment eases the visual jump from the cap into the body register. Subsequent paragraphs do not get the treatment.
Subsequent paragraphs
Consecutive paragraphs receive a first-line indent of magnitude --first-indent (1.2em in the versal profile). The indent is suppressed when a paragraph follows a heading, list, blockquote, preformatted block, or figure — the visual break already establishes a new beginning, and an indent on top of that would look like a typesetting accident.
This is a second paragraph in the same subsection so the indent rule above has something to act on. The body face is Linux Libertine at --type-base, leading is --leading-body, the measure is --measure, and hyphenation is on.
A third paragraph, to make sure the rule applies more than once and not just to the immediate successor of a heading.
Inline marks
A run of prose containing italic emphasis, bold emphasis, both together, inline code, verbatim, strikethrough, and underline. Numbers like 1234567890 should render with lining figures; a small-caps run like "html and css" should pick up real small-cap glyphs from Libertine. Quotation marks "should curl" and apostrophes shouldn't look like primes. An em-dash — like this — should sit at x-height, and an en-dash (2014–2026) should be narrower. Ligatures: office, efficient, flowing.
A sidenote anchor should sit unobtrusively in the run of text22 Sidenotes are set in --font-sans at --type-sm and muted to --ink-muted so they read as a quieter register than the body prose. and a second one should follow without crowding33 Two sidenotes in the same paragraph should sit cleanly one above the other, both anchored near the lines that introduced them..
Links
An internal link to another page on this site, an external link to the canonical home, and a bare URL that Org should auto-link: https://example.org.
Headings at every level
The header above is an H2. What follows is an H3, then an H4, then a nominal H5 and H6 — the latter two should still be styled distinctly from body prose even if they are rarely used.
Third-level heading
Body to follow the H3, so we can see the margin treatment between heading and prose, and so the table of contents has a third-level item to render.
Fourth-level heading
Body to follow the H4.
Fifth-level heading
Body to follow the H5. Pandoc emits this as
<h5>; the SCSS today defines explicit rules only for h1–h4, with h5 and h6 falling back to the sharedh1, h2, h3, h4, h5, h6block. Worth checking that fallback looks intentional rather than accidental.Sixth-level heading
Body to follow the H6.
Lists
Unordered
- A first item at the top level.
- A second item, with a nested list under it:
- A first nested item.
- A second nested item, with a third level under it:
- A leaf.
- Another leaf.
- A third item back at the top level.
Ordered
- First.
- Second, with a nested ordered list:
- Two-point-one.
- Two-point-two.
- Third.
Definition list
- Saṃhitā
- A collection; in this site's case, a collection of long-form articles and notes.
- Versal
- The currently-defined design profile. Linux Libertine body, Linux Biolinum chrome, Cormorant Upright titles, Fira Code for monospace.
- Dinkus
- The three-character ornament rendered in place of a plain horizontal rule between sections.
A list that contains a paragraph
An item whose body wraps across multiple lines and includes a second paragraph after a blank line.
A second paragraph inside the list item. It should not receive a first-line indent — the
li > p { text-indent: 0 }rule should win.A shorter follow-up item.
Quotation
The site distinguishes two registers of quotation. The note register flows with body prose; the pullquote register stops the page to feature a single line.
Note quote
Used for incidental quoted material — a passage cited in passing, a definition, a remark that supports the surrounding argument but isn't the argument itself. Set in the body face at body weight, indented from the prose so the shift reads as quotation, no italic and no left rule.
A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.
— Antoine de Saint-Exupéry, Terre des Hommes (1939)
A short paragraph after the note quote so the spacing between the two is visible.
Pull quote
Used sparingly — for the kind of quotation that you'd want on a poster, not in a paragraph. Set in Ballet (an upright connecting script designed for display sizes), centered, with generous opening and closing quote marks in the accent color.
Typography exists to honor content.
— Robert Bringhurst, The Elements of Typographic Style
Below the pull quote, body prose resumes its normal register. The two paragraphs framing the pullquote should feel like a continuous thought; the quote is the moment of pause, not a section break.
Admonitions
Three callout variants — note, warning, important — authored as Org Special Blocks. The label is added by CSS, so the source stays clean.
Note
A note is the quiet admonition: aside information, a hint, a cross-reference. Reach for it when the reader can keep going without acting on what's inside.
Warning
A warning is for footguns: this works, but there's a way to get hurt that isn't obvious from the surrounding prose. Reach for it when the cost of missing the note is real.
Important
Important is for the load-bearing fact — the thing the reader absolutely must internalise before continuing, because the rest of the section assumes it. Use sparingly; if half the page is important, none of it is.
A short paragraph after the three admonitions so the spacing between the last box and the following prose is visible.
Article scaffolding
The long-form articles open with an objectives TL;DR, lift the key insight into a keystone, and explain aha-moments with an eli5 aside.
The objectives box is the "what you'll learn" lead, set just after the epigraph. It states, in a few lines, what the reader walks away with — so they can decide in five seconds whether to read on.
The keystone lifts a single load-bearing sentence out of the prose:
The restriction is the design.
And the eli5 makes a hard idea click with a plain-language analogy:
Think of a hash like a fingerprint: two files with the same contents have the same fingerprint, always, on any machine — so once you've seen a fingerprint you never need to look at the whole file again to know what it is.
A two-column section sets two things side by side — a before and an after, two definitions, a comparison. It stacks to one column on narrow screens.
Before. One utils module mixing datetime math, string parsing, and number formatting — three unrelated reasons to change, fused into one node of the build graph.
After. Three modules — datetime, parse, format — each with a single reason to change, so editing one rebuilds only its dependents.
Code (syntax highlighting)
Pandoc tags tokens in each fenced block with classes (kw, dt, dv, st, co, …) which the SCSS paints against --accent / --ink-muted / --ink so highlighting themes with the page rather than fighting it. Inline mention of the --measure custom property, and longer fenced blocks below in a range of languages so every token class has a chance to render.
The block below is not typed into this file: it is extracted at build time from a marked region of a real, Bazel-tested source in the workspace (filters/snippet.lua; a broken reference fails the build).
// Greeting returns the smoke-test greeting.
func Greeting(name string) string {
return fmt.Sprintf("hello, %s — from a Bazel-built Go example", name)
}Extracted from code/hello/hello.go — the caption line renders too.
def humanise(diff_days: int) -> str:
"""Render a day-difference as an English phrase."""
if diff_days == 0:
return "today"
if diff_days == 1:
return "yesterday"
if diff_days < 14:
return f"{diff_days} days ago"
return f"{diff_days // 7} weeks ago"A second block in a different language, so syntax-highlighting (if ever wired up) has something to differentiate against.
:root {
--measure: 38rem;
--rhythm: 1.4rem;
--type-base: 19px;
}
article > p:first-of-type::first-letter {
font-family: var(--font-dropcap);
float: left;
}A Lua snippet to exercise different token shapes — keywords, strings, numeric literals, line comments, function definitions:
-- Resolve a build/<src> path or fall through.
local function resolve(src)
if not src or not src:match('%.svg$') then
return nil
end
for _, candidate in ipairs({'build/' .. src, src}) do
local f = io.open(candidate, 'r')
if f then f:close(); return candidate end
end
return nil
endA shell block, for variety:
# Build the testbed and serve locally.
make clean
make build
python3 -m http.server -d build 8080Tables
A small table to exercise <thead>, <tbody>, alignment, and the bottom-border rule. A #+CAPTION: turns it into a numbered float — #+NAME: makes it referenceable, so Table links here:
| Profile | Body face | Title face | Mono |
|---|---|---|---|
| versal | Linux Libertine | Cormorant Upright | Fira Code |
| vāṭikā | (tbd) | (tbd) | (tbd) |
| margaśrī | (tbd) | (tbd) | (tbd) |
A wider table to check that overflow is handled gracefully on narrow viewports (the article column is fixed at --measure, so a wide table should either fit, scroll, or wrap — whichever the CSS prescribes). This one is Table:
| Key | Type | Default | Notes |
|---|---|---|---|
| –measure | <length> | 38rem | The text column width. |
| –rhythm | <length> | 1.4rem | The vertical paragraph rhythm. |
| –first-indent | <length> | 1.2em | First-line indent on consecutive paragraphs. |
| –dropcap-size | <length> | 3.6em | The drop-cap height in body-em units. |
An uncaptioned table stays unnumbered — only #+CAPTION: opts a table into the "Table N" sequence:
| a | b |
|---|---|
| 1 | 2 |
Algorithms
An #+BEGIN_algorithm block is a numbered, captioned float for pseudocode — the same "Algorithm N" treatment a paper gives, now available in every article, not just research-paper mode. The first line is the title; a code block carries the steps. As Algorithm shows, the label and number come from a CSS counter. (A #+BEGIN_ block can't take #+NAME: for its id — Pandoc drops it — so an algorithm is made referenceable with #+ATTR_HTML: :id algo:trim.)
Trim ASCII whitespace from both ends.
input: string s
output: s without leading/trailing spaces, tabs, newlines
1. i ← 0
2. while i < len(s) and s[i] is space: i ← i + 1
3. j ← len(s)
4. while j > i and s[j-1] is space: j ← j - 1
5. return s[i:j]
A second algorithm to confirm the counter advances — this is Algorithm:
Binary search over a sorted array.
input: sorted array a, target x
output: an index i with a[i] = x, or -1
1. lo ← 0; hi ← len(a) - 1
2. while lo ≤ hi:
3. mid ← (lo + hi) // 2
4. if a[mid] = x: return mid
5. if a[mid] < x: lo ← mid + 1 else: hi ← mid - 1
6. return -1
Horizontal rule (dinkus)
Below this paragraph is an <hr>, which the SCSS renders as the --dinkus ornament (three centered glyphs) rather than a literal line.
And a paragraph after the dinkus to verify the spacing on both sides is symmetric and that the following paragraph does not get a first-line indent (the hr + p rule should apply once Pandoc emits the dinkus as a sibling — if it doesn't, that's a bug to file against the SCSS or the filter).
Figures (Typst diagrams)
The site renders Typst diagrams under content/diagrams/ to SVG at build time, and the filters/typst-diagram.lua filter inlines the SVG into the page so it can inherit our CSS variables. Literal black strokes and fills in the source are rewritten to currentColor at inline time, so the diagram themes with light and dark mode automatically44 The color-rewriting trick: any literal #000 / #000000 / black in stroke or fill is replaced with currentColor at inline time, and the figure.diagram element sets color: var(--ink). One source SVG, two themes for free..
A paragraph after the figure to verify that vertical rhythm between the figure and the following prose is correct, and that the next paragraph does not pick up a first-line indent. The margin figure to the right is a small Typst diagram pulled into the gutter via #+BEGIN_marginfigure.
Full-width
For diagrams that need to escape the body measure, wrap the link in #+BEGIN_fullwidth ... #+END_fullwidth. The figure then spans the body column and the right gutter together:
Railroad diagrams (kgt)
Grammar railroad diagrams come from kgt, which reads an EBNF grammar and emits SVG. They run through the same inlining filter as the Typst figures: make diagrams generates and sanitises them for the strict CSP (the generator's inline <style> is stripped), and the committed SVG themes through currentColor.
Automata (libfsm)
Finite automata are written as .fsm sources and rendered by libfsm (which emits Graphviz DOT, laid out to SVG by dot). Graphviz's black strokes are recoloured to currentColor by the same sanitiser, so the automaton themes too.
Interactive automata
The same automaton, made interactive — type an input and step it through. The transition is a Mealy machine on a state-machine core; the SVG is its view; the spec is validated by decoders at the boundary. With JavaScript off, the committed static SVG above is what shows.
Graphs (FixedPoint spring layout)
A graph laid out by iterating a spring model to a fixed point — the layout is a fixpoint machine doing real work (repulsion + edge attraction, run to convergence). Press Re-layout to settle it again from a fresh start.
Linear maps (2×2 matrix)
The columns of a 2×2 matrix are where the basis vectors î (accent) and ĵ (link) land; the shaded cell is the transformed unit square and its area is the determinant. Drag the sliders — it's a machine: the matrix is the state, each slider an update, the SVG the view.
Mathematics
Pandoc emits MathML when given --mathml, so math reaches the browser with no JavaScript and no external CSS — it ages as well as the rest of the page.
Inline math sits in a run of prose, like the Euler identity or the quadratic formula .
Display math gets its own block:
A second display equation with a summation, to verify spacing:
And one with a matrix:
Accented symbol (pedagogical)
Math notation already uses italic-vs-upright to distinguish tokens — variables vs. operators vs. functions — so color is usually redundant noise. The exception is pedagogy: when one symbol recurs across an expression and the lesson hinges on tracking it, a single accent color earns its place. Below, Bayes' theorem with the hypothesis variable threaded in the accent so the reader can see "this is the same H three times":
Authoring this requires raw MathML (#+BEGIN_EXPORT html) and a class="accent" on each <mi> to thread. Pandoc's TeX-to-MathML path doesn't preserve color macros, so for this narrow case the raw markup is the price of admission. Two rules for that markup: wrap the whole expression in a single <mrow> (Pandoc's output is shaped that way; hand-written math with several top-level tokens is where layout bugs breed), and the accent class may sit on any descendant of <math>, so the same treatment works for fractions, subscripts, and operator runs.
Tufte marginalia
The site adopts Tufte's marginalia convention. Footnotes are transformed into sidenotes by filters/tufte.lua: each [fn:label] reference becomes a small superscript in the body and a numbered entry in the right gutter, aligned with the line that introduced it55 Sidenotes are like footnotes, except they don't force the reader to jump their eye to the bottom of the page. — Edward Tufte, paraphrased.. There is no footer footnotes section — the sidenote is the footnote.
This is a second margin note, deeper in the document, to verify that multiple unnumbered asides in the same article don't collide with each other or with neighboring sidenotes.
Margin notes (the gray block at the right) are authored with #+BEGIN_marginnote. They carry no number; use them for asides that don't need to be referenced back from the body. Multiple marginal elements in the same paragraph stack vertically in gutter order.
A second paragraph in this section — with its own sidenote66 A final sidenote, late in the document, to verify that numbering survives across many sections and that no early marker collides with a later one. — so we can see two sidenotes from adjacent paragraphs and verify they don't overlap. On narrow viewports (below ~1100px), all marginalia collapse to indented blocks under their reference, with a thin rule on the left as their visual cue.
Inline figures (text wrap)
Some figures want to live inside the body column rather than in the gutter, with prose flowing around them — Ilene Strizver's Type Rules! shows this with calligraphic plates that sit mid-paragraph while the discussion continues around them.
Authoring is a special block: #+BEGIN_inlinefigure-right (or -left) wrapping a Typst image link and an optional caption. The figure floats inside the body column at ~40% of the measure, leaving room for four or five lines of prose to wrap alongside. This paragraph keeps running so we can see the wrap behavior across several lines, and verify that the next paragraph picks back up at full width once the float clears. The caption sits underneath the figure in --font-display italic, --type-sm, muted to --ink-muted — quiet enough to read as a label rather than as competing prose. On narrow viewports the float drops and the figure becomes a centered block in the flow.
A second paragraph with a left-floated inline figure, so we can see both sides of the wrap convention working. The prose continues to the right of the plate, indents on its first line like every other consecutive paragraph, and clears the figure cleanly underneath. Where left-floated inline figures meet right-floated ones in nearby paragraphs, the clear rules keep them from stacking diagonally or overlapping each other.
Multilingual prose
Browsers fall back to OS-installed fonts for scripts outside our vendored Latin / Greek / Cyrillic families. This section exercises Devanagari, Tamil, Arabic, and Han so we can see how the page handles each — and where curated fallback stacks are needed.
Authoring uses a #+BEGIN_lang-<code> Special Block wrapping a #+BEGIN_verse for line-broken verses. filters/lang.lua promotes the lang-<code> class on the outer Div to a real lang attribute, which is what browsers and screen readers look for.
Sanskrit (Devanagari)
Āryabhata's approximation of π, from the Gaṇitapāda of the Āryabhaṭīya (499 CE) — one of the earliest known statements of π to four-decimal precision:
अयुतद्वयविष्कम्भस्यासन्नो वृत्तपरिणाहः ॥
caturadhikaṃ śatamaṣṭaguṇaṃ dvāṣaṣṭistathā sahasrāṇām ; ayuta- dvayaviṣkambhasyāsanno vṛttapariṇāhaḥ.
"Add four to one hundred, multiply by eight, and add sixty-two thousand. This is the approximate circumference of a circle whose diameter is twenty thousand." That yields π ≈ , accurate to four decimal places — and the verse calls out, with the word āsanna ("approximate"), that the number is not exact.
Greek (Heraclitus)
Linux Libertine carries a complete Greek subset, so this should render in the body face without falling back:
ἕτερα καὶ ἕτερα ὕδατα ἐπιρρεῖ.
potamoîsi toîsin autoîsin embaínousin / hétera kaì hétera húdata epirreî.
"On those stepping into the same rivers, other and yet other waters flow." (Diels–Kranz 22 B12.)
Tamil (Tirukkural)
The opening kuṟaḷ of Tiruvaḷḷuvar's Tirukkuṟaḷ — the verse from which every Tamil literary edition begins:
பகவன் முதற்றே உலகு.
akara mudala eḻuttellām ādi / pakavan mutaṟṟē ulaku.
"As all letters have a as their first, so the universe has the eternal divine as its first."
Arabic (al-Mutanabbī)
Right-to-left script; wrap the verse in both lang-ar and dir-rtl so the browser flips line direction:
وتأتي على قدرِ الكرامِ المكارمُ
ʿalā qadri ahli l-ʿazmi taʾtī l-ʿazāʾimu / wa-taʾtī ʿalā qadri l-kirāmi l-makārimu.
"To the measure of resolute men come resolves; to the measure of generous men come acts of generosity." (al-Mutanabbī, 10th c.)
Chinese (Confucius)
The opening of the Analects, in traditional characters:
xué ér shí xí zhī, bù yì yuè hū?
"Is it not a pleasure to learn, and to practice from time to time what one has learned?" (Lúnyǔ 1.1.)
Iconography
Small UI icons come from the self-hosted regular Phosphor webfont. They should sit beside labels rather than replace them, except for compact controls that carry an accessible name.
Repository · Download CV · RSS
- link
- external
- code
- copy
Timeline markers can opt into icons by placing a Phosphor glyph with class"tl-icon ph ph-…"= inside the list item. Items without a tl-icon keep the plain dot.
- Published — an item with a document icon in the marker circle.
- Merged — a source-control event with a different glyph.
- Plain dot — an unadorned item, to verify the old timeline style still works.
Coda
If this page renders cleanly — every heading level distinct, the drop cap and small caps where expected, lists indented correctly, tables ruled, the dinkus centered, footnotes legible, and the backlinks footer (if any) below it all — the article template is in good shape for real content.