Skip to main content

Design

An ode to design.

Nothing here was made for this site. The typefaces were drawn by other people, for their own reasons, years ago; the colours are computed in a space someone published as research; the moving field is an old printing trick; the coat of arms carries a name older than any of it. This page is where each of those came from.

Typography

Four typefaces, and the hands that drew them.

None of these were commissioned for this site. Each was drawn by someone else, for their own reasons, and released under a licence open enough to use freely. What follows is where each one came from and what older form it descends from. Every specimen is set in the face it describes.

Geist Vercel · 2023 · SIL Open Font License

Vercel drew its own typeface in 2023 and gave it away under an open licence. A neo-grotesque in the Swiss line that runs from Univers and Helvetica down to the interface sans-serifs of the last decade, made for developer tooling and documentation. Its clearest inheritance is in the figures: evenly weighted, wide apertures, no character that can be mistaken for another at a glance.

4625 · 03:41:07Z · DC01

Space Grotesk Florian Karsten · 2018 · SIL Open Font License

Florian Karsten drew Space Grotesk in 2018 as a proportional reworking of Space Mono, the fixed-width face Colophon Foundry had cut for Google two years earlier. It keeps the mechanical joints and flattened curves of that monospace but lets the widths breathe, so its lineage reads as engineered rather than styled. It carries its parent's slightly severe geometry into text that is no longer forced onto a grid.

Understand the system.

Cormorant Garamond Christian Thalmann · 2015 · SIL Open Font License

Christian Thalmann drew the Cormorant family in 2015 through his Catharsis foundry. It stands in the tradition of Claude Garamont's sixteenth-century romans, the model most later Garamonds revive, but it is an original drawing rather than a revival, and it is cut finer than a text Garamond would dare: high stroke contrast built for display sizes and engraving.

Observer

The system monospace stack No download · whatever the platform already ships

The one face with no single author, because it is not one face. The stack asks the operating system for whatever monospace it already has: SF Mono from Apple, Cascadia from Microsoft, and a fallback ladder behind them. Its origin is the machine you are reading on, which is the whole reason it always looks native and never has to be downloaded.

SigninLogs | where ResultType != 0

The scale, measured live

Every step is a clamp(), so a fixed number would be a fiction. These are the real computed values for this page at your current viewport. Resize and they move.

Hero
Once per page, in the display face
Section heading
Opens every section, paired with an eyebrow
Card heading
Cards, list rows and specimen labels
Body
Prose, capped at 65 ch for line length
Eyebrow
Uppercase, tracked, muted. The section's label
Mono
Code, queries and evidence fields

Colour

Colours computed, not sampled.

None of these were picked from a swatch book or pulled off a moodboard. They are computed in OKLCH, the perceptual colour space Björn Ottosson published in 2020, in which a single lightness and chroma read as roughly the same strength no matter the hue, so no one colour glows while another sinks. One choice is deliberately not fixed: the accent changes with the theme, a cobalt blue in the dark and a red in the light. The hero's dithered field carries that same warm-and-cool split, blue on the dark theme and orange on paper, so the two modes feel like different rooms rather than one inverted. The readouts below are live, printing each swatch's resolved value and measured contrast in the theme you are reading. AA is 4.5:1 for body text; AAA is 7:1.

Ink and paper

The two ends the whole system is built between: a near-black and an off-white, not pure #000 and #fff, because a small amount of warmth in each takes the glare off the contrast. One theme is the other inverted, so there is a single relationship to keep honest rather than two palettes to maintain. The same pair does the interface's heaviest lifting: every primary button is monochrome, ink on paper (--accent on --accent-ink), so colour is left free to mean something.

The ring, hue by hue

Eight positions spaced around the wheel. The names are the reference points they were tuned toward, and the lightness of each is set so no one hue shouts louder than the rest. All eight rotate through the Scenario Lab's packet palette, where adjacent flows must never share a colour.

--accent-blue Accent ยท blue / red

The accent, carrying the links and the interactive marks, and in the dark the dither field too. In the dark it is a cobalt blue that glows off the near-black; in the light it becomes a warm red, while the field warms separately to its own orange, since that same blue has nothing to glow against on paper. The swatch and its value follow whichever theme you are in.

--ok Lime

A yellow-green, the brightest position on the ring by nature, so it is given the least chroma on the ring and still holds its own against the page.

--warn Amethyst

A cool violet, sitting opposite the warm feature colour. It marks the in-progress and the worth-a-look without borrowing red, which now belongs to the light theme, or the muddy amber a darkened yellow always collapses into.

--signal / --danger Coral

A red pulled slightly toward orange. A pure spectral red vibrates against dark and tires the eye; this one stays a red while sitting a touch calmer.

--series-1 Cyan

The cold end of the ring, kept for data series now that the interface accent has moved to cobalt. It reads as instrumentation rather than identity, which is exactly its job.

--series-3 Brass

A restrained yellow held short of gold. Yellows blow out faster than any other hue in the dark, so this one trades chroma for legibility and sits closer to an instrument dial than a highlighter.

--series-5 Azure

A mid-blue sitting between the cyan and the magenta, the ring's bridge across the cool side of the wheel.

--series-6 Magenta

A pink-red that closes the ring between the amethyst warn and the coral danger, far enough from both to stay its own colour, and the one with no status attached.

And the hairlines

Not colours so much as the near-absence of one: the ink at a low alpha, so a division shows as a drawn line rather than a shadow or a filled panel.

--line

The lighter of the two, a hair over the background.

--line-strong

The heavier weight, for a division that has to hold next to a busy surface.

Space

One container, one column model, three rhythms.

Twelve columns on desktop, six below 1080px, one below 620px, from a single --grid-cols token that every layout inherits. The diagram below is drawing the model your viewport is actually in.

Columns at this viewport: 12

--section-pad-top
--section-pad-bottom
--section-intro-gap

Structure and motion

Hairlines, square corners, and motion that knows when to stop.

Hairlines over shadows

Cards are defined by a 1px border and nothing else. --shadow is set to none in both themes. Depth is implied by alignment, not by lifting things off the page.

Square corners, throughout

Corners are square throughout, with one narrow concession: a 2px easing on the smallest chips, inline code and logo tiles, where a hard corner reads as a rendering artefact rather than a decision. The dithering hero was ported from a component with 48px rounded corners and re-cut to hard edges to match, rather than the site bending to the component.

The dither field

The moving hero is an old idea. Ordered dithering, the trick that fakes shades from a fixed set of dots, goes back to the threshold matrix Bryce Bayer described in 1973 for early printing and displays. The field quantises domain-warped noise through that same 4×4 Bayer matrix, rewritten from a React shader component into dependency-free WebGL so it can run under a strict script-src 'self'.

Cheap by construction

The dither canvas renders one cell per fragment at roughly a third of its CSS size, then upscales with image-rendering: pixelated. The pixelation is the aesthetic and the optimisation at the same time.

Reveals that fail open

Sections fade in on scroll via IntersectionObserver, but anything already near the viewport is shown immediately and a 1.5 second timer reveals everything regardless. A missed observer can never leave content invisible.

Reduced motion is honoured

prefers-reduced-motion is checked in CSS and in the hero and gateway scripts. The animation stops; the composition does not change.

No build step

Hand-written HTML, one stylesheet and ES modules served as-is. Fonts, images and the social card are produced by one-off Python scripts, and cache-busting is a query string rewritten across the repo.

Heraldry and the marks

Why a security portfolio carries a coat of arms

Two marks do two different jobs. The radar is operational. It sits in the header on every page, sweeps when you rest on it, and stands for the work: watching, detecting, resolving. The coat of arms is ceremonial. It appears once, at the gateway, and then steps aside.

The name is a place before it is a family. It comes from the Old English welle and the Old Norse brunnr, a well by a stream, and it is already written down in the Domesday Book of 1086 as Wellebrune in Lincolnshire and Walebruna in Norfolk. The Lincolnshire line held the manor of Welbourn. Hugh de Welleburn turns up in the Hundred Rolls of 1273, Robert Walebrun in the Sussex subsidy rolls of 1296, and the spelling keeps moving for another three hundred years before it settles.

What survives after that is a scatter of people rather than a tidy line. Thomas Welbourne, a schoolmaster, was executed at York in 1605 for his faith and beatified in 1929. Another Thomas sat in the Virginia House of Burgesses from 1699 until his death in 1702, three generations after the first Welbournes crossed in the 1650s. Elijah Welbourne landed in South Australia in 1851, aged twenty five. I make no claim to descend from any of them in particular. That is the honest position with a name this old, and it is the more interesting one.

So the arms are here for what they represent rather than as a pedigree. An armorial achievement is an identity that is inherited and defended rather than bought, which is a fair thing to open a defensive security portfolio with and an easy thing to over-use. The gateway is the only place it renders at full size. Past it, you get the plain operational system that runs the rest of this site.

The arms are drawn twice, in colour and as an engraving, and the theme decides which one you get. Both are pre-rendered to WebP at three widths, because a ceremonial entrance that costs a second of loading is not ceremonial, it is slow.

View the ceremonial entrance