XRAPH/Design

Instrument

The system this site is built in. It is named for what it tries to look like: a measuring instrument, where every rule is a rule for a reason and the page shows its own construction. Six themes, four faces, one variable axis doing most of the work.

01

The frame

rails, gutters, hatch

The page is drawn inside a frame rather than on an open canvas. Two vertical rails sit at the outer gutters, fixed to the viewport and capped at 1680px, and horizontal hatch bands separate the sections. Both are filled with the same 45° hatch at background-attachment: fixed, so the stripes are anchored to the viewport rather than to each element. The rails and the bands are windows onto one continuous field, which is why their diagonals meet exactly at every corner.

--gut · clamp(12px, 3vw, 52px)

The rails and a hatch band, drawn at page scale

Where a band crosses a rail the system draws a crosshair rather than letting one line pass behind the other, which is the technical-drawing tick for two members meeting. Below 700px the rails are removed entirely, so there is nothing left to intersect and the crosshairs go with them.

02

Colour

six grounds, one token set

Nothing in the system names a colour. Every rule reads a token, and a theme is a redefinition of those tokens on [data-dir]. Four grounds are general and two belong to a single page each. Because the tokens are the only interface, a page written for one ground works on all six without knowing which it is on.

data-dir="a"InkThe default. Every page that does not ask for another.
data-dir="b"PaperWarm. Reference pages: work, identity, this one.
data-dir="c"BlackPure black and acid. Reachable from the visitor switcher.
data-dir="e"DocsNeutral rather than warm, so code and screenshots sit without a cast.
data-dir="d"Dawn/cross only. A --dawn variable ramps the whole page as it plays.
data-dir="p"Reading room/x-files only. Adds a serif reading face and a reader-set --scale.

Ink, dim, faint, signal, cool — the five that carry meaning

TokenCarriesRule
--bg / --bg-2The ground, and the raised panel above it.Never text.
--inkHeadlines, marks, anything that must be read first.Full contrast.
--ink-dimBody copy and prose.Clears 4.5:1 on every ground.
--ink-faintLabels, readouts, the trademark.Labels only, never prose.
--signalOne accent. Section indices, links on hover, live state.Sparingly, or it stops meaning anything.
--coolThe second accent, for the rare case needing two.Never decorative.
--rule / --rule-softHairlines. The soft one for bands inside a section.Alpha on ink, not a grey.
--panelThe barely-raised surface under specimens and code.2.5–3.5% ink.
--grainFilm grain opacity, per ground..02 on white, .09 on black.
03

Type

four faces, one axis
AaArchivowdth 62 – 125 · wght 100 – 900Every headline, section head, numeral and mark. The width axis is the signature of the system.
AaJetBrains Monowght 200 – 500Every label, readout, chip, crumb and code sample. Also the body face of this site’s chrome, at 300.
AaInstrument Serif400 · italicEmphasis words and pull quotes only. It is a display italic and is never asked to carry a paragraph.
AaSource Serif 4400 / 600 / 700 · optical sizeLoaded for one page. X-Files is a document reader, and a reviewer thirty pages into a paper needs a face drawn for its own size.

Archivo is variable on width, not just weight, and that is the part of the system worth understanding. Sixty-three rules, counted in August 2026, across the four stylesheets pin font-variation-settings: 'wdth' to a specific value, and they fall into two populations that behave differently.

64XRAPH INSTRUMENT.act--weight h2
74XRAPH INSTRUMENT.outro h2
82XRAPH INSTRUMENT.paper-h1
88XRAPH INSTRUMENT.shead h2
92XRAPH INSTRUMENT.anat h4
96XRAPH INSTRUMENT.hero h1
120XRAPH INSTRUMENT.chapter .cnum
125XRAPH INSTRUMENT.mark

The same string at each width the system actually uses

Where every width-axis rule sits

Font size against width-axis setting for 63 rules in the design systemText and headings occupy a band from width 64 to 96, and the setting narrows as size grows. Numerals set as data and the wordmark sit separately, from width 100 to 125, regardless of size.608010012012px25px50px100px200pxFont size, log scalewdth axisNumerals and the wordmarkText and headings.outro h2 — 240px at wdth 74.pl-count — 220px at wdth 84.hero h1 — 208px at wdth 96.act--weight h2 — 168px at wdth 64.dhero h1 — 150px at wdth 88.phero h1 — 140px at wdth 88.cortex h2.big — 132px at wdth 86.act h2 — 124px at wdth 86.spot h3 — 96px at wdth 88.paper-h1 — 84px at wdth 82.mtext — 66px at wdth 84.chapter h3 — 64px at wdth 92.dfeat-title — 58px at wdth 86.dart h1 — 46px at wdth 86.mailto span — 44px at wdth 90.sheet h1 — 42px at wdth 96.lf-done h2 — 42px at wdth 88.pitem h3 — 40px at wdth 84.doc h1 — 38px at wdth 94.pillar h3 — 36px at wdth 84.signals .v — 34px at wdth 90.dcard h3 — 34px at wdth 86.ticker-track span — 34px at wdth 74.ocd-name — 32px at wdth 90.spot .metrics .v — 32px at wdth 88.ritem h3 — 32px at wdth 86.tl-item h4 — 30px at wdth 90.pcard h3 — 30px at wdth 90.prose h2 — 30px at wdth 88.sfield input — 28px at wdth 92.bhead h2 — 27px at wdth 86.phero .facts .v — 26px at wdth 92.post h4 — 26px at wdth 88.row .n — 25px at wdth 94.cmd-field input — 25px at wdth 92.adopt h3 — 25px at wdth 88.telemetry .v — 22px at wdth 90.x-refs h2 — 21px at wdth 88.nf-route-label — 21px at wdth 88.dindex-row .nm — 20px at wdth 90.steps .sk — 19px at wdth 92.orrery-readout .t — 19px at wdth 92.plate .v — 19px at wdth 90.related .rr .n — 18px at wdth 92.anat h4 — 18px at wdth 92.xv-name — 15px at wdth 92.cortex .pillars2 h4 — 15px at wdth 92.shead h2 — 15px at wdth 88.dart .prose h2 — 15px at wdth 88.cmd-row-title — 13.5px at wdth 88.lf-kind b — 13px at wdth 92.prod .nm — 12px at wdth 96.dart .prose h3 — 12px at wdth 92.orrery-legend .ol-n — 11px at wdth 92.chapter .cnum — 112px at wdth 120.post .bignum — 104px at wdth 118.nf-code — 58px at wdth 120.outro-foot .now .t — 46px at wdth 110.oc-forge — 21px at wdth 100.mark — 15px at wdth 125.brand .wordmark — 15px at wdth 125.xnav .mark — 14px at wdth 125.pl-mark — 13px at wdth 125
Text and headings (54)Numerals and the wordmark (9)
Show the 63 rules as a table
SelectorSizewdthBand
.outro h2240px74Text
.pl-count220px84Text
.hero h1208px96Text
.act--weight h2168px64Text
.dhero h1150px88Text
.phero h1140px88Text
.cortex h2.big132px86Text
.act h2124px86Text
.chapter .cnum112px120Wide
.post .bignum104px118Wide
.spot h396px88Text
.paper-h184px82Text
.mtext66px84Text
.chapter h364px92Text
.nf-code58px120Wide
.dfeat-title58px86Text
.outro-foot .now .t46px110Wide
.dart h146px86Text
.mailto span44px90Text
.sheet h142px96Text
.lf-done h242px88Text
.pitem h340px84Text
.doc h138px94Text
.pillar h336px84Text
.signals .v34px90Text
.dcard h334px86Text
.ticker-track span34px74Text
.ocd-name32px90Text
.spot .metrics .v32px88Text
.ritem h332px86Text
.tl-item h430px90Text
.pcard h330px90Text
.prose h230px88Text
.sfield input28px92Text
.bhead h227px86Text
.phero .facts .v26px92Text
.post h426px88Text
.row .n25px94Text
.cmd-field input25px92Text
.adopt h325px88Text
.telemetry .v22px90Text
.oc-forge21px100Wide
.x-refs h221px88Text
.nf-route-label21px88Text
.dindex-row .nm20px90Text
.steps .sk19px92Text
.orrery-readout .t19px92Text
.plate .v19px90Text
.related .rr .n18px92Text
.anat h418px92Text
.mark15px125Wide
.brand .wordmark15px125Wide
.xv-name15px92Text
.cortex .pillars2 h415px92Text
.shead h215px88Text
.dart .prose h215px88Text
.xnav .mark14px125Wide
.cmd-row-title13.5px88Text
.pl-mark13px125Wide
.lf-kind b13px92Text
.prod .nm12px96Text
.dart .prose h312px92Text
.orrery-legend .ol-n11px92Text

Text narrows as it grows. Across the 54 text rules the correlation between size and width is r = -0.46: a 240px outro headline is set at 64 to 74, a 30px sub-head at 88 to 92. Large type has enough room to be read condensed, and condensing it is what stops a headline turning into a wall.

Numerals and the mark do not. The other 9 rules sit at 100 to 125 whatever their size, because they are read as data rather than as language. A chapter number at 112px and the 15px wordmark are both near the ceiling. The one apparent exception, .pl-count at 220px and width 84, is a display numeral set like a headline, and it behaves like one.

04

Space

four numbers

The system has very few spacing tokens. Almost everything else is a clamp() tied to the viewport, so the page rescales continuously rather than snapping at breakpoints.

TokenValueWhat it positions
--gutclamp(12px, 3vw, 52px)The rail width, and so the page frame.
--padclamp(14px, 2vw, 34px)Clearance between the rail and the text.
--nav62pxHeader height; section heads stick beneath it.
max-width1680pxThe rails, the bands and .wrap all share it.

A content column is --gut + --pad in from the page edge, which is what keeps text off the rails at every width. Measure is capped by content rather than by the grid: the lede runs to 56 characters, prose to 70.

05

Motion

two curves

Two easings, and a rule about when each applies. Anything that enters or settles uses the decelerating curve; anything that swaps one state for another uses the symmetric one. Nothing in the system uses a linear or a default ease.

--ease

cubic-bezier(.16, 1, .3, 1) Reveals, hovers, theme changes. Fast out of the gate and a long settle.

--ease-io

cubic-bezier(.76, 0, .24, 1) State swaps and transforms. Symmetric, so it reads as one movement rather than an arrival.

Sections arrive on a stagger rather than together: .rv starts 26px low and transparent, and data-d="1" through "8" add 70ms each. Eight steps is the whole ladder, which caps the longest entrance at just over half a second.

06

Parts

the shared components

A handful of components appear on nearly every page, and they carry the system more than any single rule does.

07

Section head

index, title, readout
XRAPH/Design

Label · mono 10px · tracked .22em

A lede. Sized between 14 and 17px against the viewport, capped at 56 characters, and set in --ink-dim so it reads as introduction rather than as body.

Live components, rendered from the system’s own classes

ComponentBehaviour worth knowing
.navFixed and frosted in every theme, at 62% of the ground with a 16px blur.
.markThe wordmark lockup at wdth 125 with a cap-flush trademark. Specified in full at /identity.
.sheadSticks to the bottom of the nav while its section is in view, so you always know which one you are in.
.hatchA separator band. Takes .soft for a lighter field and .tall for 1.6× the gutter.
.grain / .vigFilm grain over the whole viewport, and a vignette. Both are per-theme, and the docs ground drops the vignette entirely.
.rvScroll reveal, with an eight-step delay ladder.
07

How it is layered

one system, five surfaces
The systemTokens, the frame, the type roles and every shared component. Everything else layers on top of it.
DocumentationThe reader, on the white ground, tuned for twenty minutes rather than twenty seconds.
The crossOne page, with its own palette and the dawn ramp that drives it.
The reading roomThe reviewer paper, its serif reading face and a reader-set scale.
IdentityThe wordmark specification at /identity.
This pageWritten in the system it documents.

All of it is hand-written CSS, imported as one stylesheet. There is no utility framework and no component library underneath, and the classes on this page are the same classes every other page uses, which is the only reason a documentation page can be trusted to still be true.