Lookbook

The season's design system — colour, type, space, motion. Every value on this page is read out of assets/css/hollow.css and site/assets/css/moral-gray.css at runtime, and every contrast figure is computed here rather than typed. If a token moves in those files, this page moves with it. It cannot go stale, and it cannot lie.

Colour

Two colourways. The season is a blown-out bone ground with a wine-black ink; the 2016 half of the Moral Gray page is its negative — a pale figure on midnight. Contrast is measured against each colourway's own ground. PASS is 4.5:1; roles marked large only are held to 3:1 because nothing wears them below about 24px.

The season — bone

2016 — midnight

Rhyme chains

Four slots, assigned in fixed order and never cycled. Highlight marks in running text are the all-pairs case — any two can end up side by side — and past four, no set clears the perceptual floors. Two are reserved globally (violet /aɪ/, orange /eɪ/); two are re-assigned per section. Both sets were validated against their own ground, and the midnight set is not the light set darkened: the reference dark violet collides with the dark blue at CVD ΔE 1.9 and had to be replaced.

GroundWorst all-pairs CVDWorst normal-visionVerdict
bone #f2f1efΔE 9.2 (deutan)ΔE 16.3all pass
midnight #131826ΔE 8.8 (deutan)ΔE 16.5all pass

Type

Two families and nothing else. Sizes below are the computed values at this viewport — every one is a clamp(), so resize the window and the numbers move. The specimens are real elements wearing the real classes, measured where they stand.

FamilyWeightsRoleStack

Tracking is the system's accent. Mono is always letter-spaced — 0.14em on chips, up to 0.52em on section labels — and always uppercase. Where tracking is heavy, an equal text-indent follows it: tracking adds a trailing space after the last letter, which throws a centred line off by half that amount. Serif is never tracked.

Space

Everything fluid, nothing stepped. The gutter and the measure are the only two spacing tokens; section rhythm is written as clamps at the point of use rather than a scale, because there are six sections in the whole site and a scale would be ceremony.

TokenDeclaredComputed hereWhat it does

Motion

One curve. Everything that eases uses --ease; anything that should feel mechanical uses steps(1) instead, which is how the tear and the grain read as faults rather than animations.

Durations cluster in three bands: 260–520ms for anything answering a pointer, 900–1200ms for content arriving, and 90s+ for the fog, which should never be caught moving. The split is the one exception at 1900ms, because it is the page's only narrative beat.

Edges & surfaces

The rule that holds the whole thing together: nothing has a hard edge. Rules are gradients that fade at both ends, sections bleed into one another, the figure dissolves into a bank of haze rather than being cropped. The two deliberate exceptions are the seam on the Moral Gray page — where the split is the content — and the focus ring, which has to be unambiguous.

Divergences

Tokens declared in both stylesheets with different values. The two sheets deploy separately and neither imports the other, so drift here is real and worth seeing rather than assuming away.

Tokenhollow.cssmoral-gray.css