The design system, demonstrated on itself. Every swatch, rule and specimen on this page is rendered from the site's live design tokens and data — the guide cannot drift from the implementation, because it is the implementation. Daylight and midnight are both first-class: toggle the theme to read this page as a microfilm negative.
§ 1

Colour — two inks on two grounds, one accent

Grounds and ink stay warm in both themes; pine is the one cooler note and marks the current thing. Applied by weight: ground ≫ ink ≫ accent. The value printed under each swatch is read from the page's computed styles.

Grounds & surfaces

  • --color-background
  • --color-surface
  • --color-background-muted
  • --color-surface-elevated

Inks

  • --color-primary
  • --color-text-soft
  • --color-text-light

Accent — pine

  • --color-accent
  • --color-accent-dark

Borders & hairlines

  • --color-border
  • --color-hairline
  • --color-border-dark

Functional

  • --color-danger
  • --color-success

Visualisation palette (OKLCH, derived from ink + pine)

  • --sys-viz-1
  • --sys-viz-2
  • --sys-viz-3
  • --sys-viz-4
  • --sys-viz-5
  • --sys-viz-6
  • --sys-viz-7
§ 2

Typography — two voices, strictly cast

The document voice is what the scholar writes; the data voice is what the machine indexes. Every string on the site belongs to exactly one. Blurring them is the system's only unforgivable error: no mono headlines, no serif metadata.

Archivo — display

Ink + Signal

Nameplate, h1–h3, section heads, big data numbers. Wide, heavy cuts via the wdth axis — a compressed-broadsheet feel.

Newsreader — prose

All prose, h4–h6, subtitles, captions and quotes are set in a news serif with optical sizing and full Latin Extended — the reading default for a working archive.

And the standfirst beneath a title is its italic register.

Spline Sans Mono — data

Dossiers · 5 projects · 2013—2027

Metadata only, never body copy: eyebrows, datelines, counts, nav, filters, chips, DOIs, pagination — anything that could be a database column.

Type scale — forked ratios

--font-size-2xs The archive, read closely — minor third (1.2)
--font-size-xs The archive, read closely — minor third (1.2)
--font-size-sm The archive, read closely — minor third (1.2)
--font-size-base The archive, read closely — minor third (1.2)
--font-size-lg The archive, read closely — minor third (1.2)
--font-size-xl Signal — major third (1.25)
--font-size-2xl Signal — major third (1.25)
--font-size-3xl Signal — major third (1.25)
--font-size-4xl Signal — major third (1.25)
--font-size-5xl Signal — major third (1.25)

Reading measure — counted, not assumed

A ch is the advance width of the digit zero, not the width of one character. Newsreader's average character measures about 0.7ch, so a cap written as 65ch sets nearer ninety characters a line — past the forty-five to seventy-five that keeps a line scannable. Reason in characters and let the token carry the arithmetic. The counts below are measured in your browser, in the live font, at each role's own size.

Prose --measure-prose body copy, ledger descriptions, abstracts, CV entries — · — chars
Standfirst --measure-standfirst the italic deck under a page title — · — chars
Note --measure-note captions, review sources, the footer — · — chars
§ 3

Rules — hierarchy is drawn, not floated

Reach for the rule system before size or colour: the page should be navigable if all type were one size. Rules are ink-coloured, never gray. Corners are square; shadows and glass do not exist — depth comes from ink density and rule weight.

--rule-nameplate · 5px — the nameplate
--rule-masthead · 4px — mastheads, the footer
--rule-section · 3px — section openings
--rule-hairline · 1px — ledger rows, entry separators

The rule → content interval

Every ruled module — masthead, section, hairline — puts the same --rule-gap between the rule and what it opens, so only the rule's weight carries hierarchy. Vary the weight, never the gap.

A rule is not a border

The two share a 1px width and nothing else. A rule separates and is the lightest mark on the page; a box edge encloses an object and sits one step darker. Crossing the pair fails silently — a separator drawn in the edge colour just looks like a plate — so the tokens are named to be paired, and the three heavy weights above take --color-primary instead.

A rule — separates var(--rule-hairline) solid var(--color-hairline) ledger rows, entry separators, facet labels · —
A box edge — encloses var(--border-width-thin) solid var(--color-border) cards, image plates, inputs, chips · —
§ 4

The ledger — the universal record

Any dated or keyed record renders as a hanging-column ledger row, not a card: mono key left, serif content right, a hairline above each row.

2026 Specimen A two-column ledger row The key column carries the machine voice — a year, a term, an identifier — while the content column carries the document voice: a serif title and, beneath it, a description at reading measure.
2013—2026 Idiom A three-column row adds a meta column Publications, CV entries, activities and facets all render this way — the same idiom, tuned per instance with --ledger-key-w. Meta →

The meta-ledger — a catalogue entry

A distinct idiom, not a variant. The ledger above sets a record: mono key against serif content, because the content is something the scholar wrote. The meta-ledger sets a record’s catalogue entry — journal, DOI, place, date — where both columns are strings a database could hold, so both are the data voice, over a key column narrowed to 5.5rem for the 380px metadata rail. It is what the “Record” block prints on a publication or a talk, above the rail’s label and action stack.

Record

Type
Journal Article
Journal
Islamic Africa
Date
2026
DOI
10.1163/21540993-01201007 ↗
Access Publication ↗ Export BibTeX

Pine marks only the row that leaves the record — a DOI, a live project page — and only one control in the stack carries the accent fill.

§ 5

Chips, pagination & buttons

Flat, square, mono caps, count appended; selected means a solid ink fill. The counts below are real — the three most frequent tags in the publications corpus.

Chips

Islam 35West Africa 31Burkina Faso 15 All 117 tags ↓

Facet combobox

A chip row prints a closed list; an open one is reached by typing. The field is machine-facing, so it takes the data voice and the square edge of the search field, and the listbox is a plate rather than a floating card — paper ground, 1px border, ledger rows with the serif value left and the mono count right. It overlays what follows on purpose: laying all 117 publication tags out grew the index by a screen and a half. Matching ignores case and diacritics, so cote reaches Côte d’Ivoire.

Counts are real. Picks here narrow nothing — they only show the selected state.

Pagination

1 2 3 Next →

Buttons

The accent never fills large areas except the single primary button per screen.

§ 6

Data as ornament

The only decoration permitted is real data made visible. These bars are the actual publications-per-year distribution, 2013–2026; the newest year carries the accent. If a flourish doesn't encode something true, it goes.

2013 2026
Publications 44
Communications 79
Activities 33
Tags in the corpus 117
Colour tokens on this page 21
§ 7

Plates

Photographs, covers and scans are plates: square corners, a one-pixel border, and a serif-italic caption below.

Portrait of Frédérick Madore, set as a plate
Fig. 1 — Every image is a plate; the caption is set in the serif italic.
§ 8

Spacing & motion

An 8-point rhythm carries the density scholars expect — structured information over whitespace. Motion is near-zero by design: instant state changes, at most a short fade on page enter. The register is print, not app.

Semantic spacing

--space-xs
--space-sm
--space-md
--space-lg
--space-xl
--space-2xl
--space-3xl

Durations

--duration-instant
--duration-fast
--duration-normal
--duration-moderate
--duration-slow