alanlong.design/system

This page is the live system behind this site. The typography, colour, layout, and components here are the same ones that build every page. This isn’t documentation about the system. It is the system.

Two ideas drive it. Something made well isn’t afraid to show how it’s built. The grid, the layout, the tokens are all discoverable: that’s visible construction. And a portfolio is a conversation between two people. The colour follows your time of day because we’re sharing the same clock: the site responds to who’s viewing it.


Typography

Two typefaces. GT Sectra is a broad-nib serif where the pen origin is visible in the letterforms. It represents the complexity of humans. Pentameter is a monospace with calligraphic movement: fixed widths, lively forms. The built × natural tension lives inside this one typeface. Sectra speaks for people, Pentameter speaks for the system.

The rule is simple. If you’re reading sentences, it’s Sectra. If you’re scanning the interface, it’s Pentameter.

Each role is rendered here in its actual specs — the same CSS classes that build the site.

Body is 16px at 1.5 line-height. That gives 24px, which becomes the grid cell. The entire layout system grows from this single typographic decision.

Type does not respond to context. Colour shifts with time of day. Typography stays fixed. It’s the anchor.

Pentameter is a variable font (weight axis 100–900, 300–600 used). Sectra is static weights: Book (400) and Medium (500). Bold (700) is reserved for case study content only.

DISPLAY See the system.
HEADING-LG I was making this case in 2023.
HEADING-MD Roles that fit.
HEADING-SM What I built
BODY-LG A portfolio is a conversation between two people.
BODY-MD A portfolio is a conversation between two people.
BODY-SM Secondary descriptions, overlay text, supporting paragraphs.
UI COMPONENTS
DATA 16:42
META CEO, Interbrand · LinkedIn · 2023

Layout

The cell is 24px, derived from body line-height. The grid is 40 columns of square cells at 960px. Every spacing token is a multiple or fraction of the cell: space-025 (6px) through space-400 (96px).

The grid is not hidden infrastructure. It’s discoverable. This is visible construction in practice. In deliberate moments, the system shows its own working: column widths, type measures, spatial values surfaced on screen.

Spacing is measured, not generous. Proportions work because they were calculated, not because there’s a lot of empty space.

The cell is a CSS custom property. Every spacing token is a calc() expression derived from it.

×
SPACE-025 ¼ cell ·
SPACE-050 ½ cell ·
SPACE-100 1 cell ·
SPACE-200 2 cells ·
SPACE-300 3 cells ·
SPACE-400 4 cells ·

Colour

The colour creates a connection between Alan and the viewer. Both share the same sky.

The palette is modelled on natural light to make that connection real. One input (time, 0–24) generates every colour. Lightness dwells at day and night, transitions quickly at dawn and dusk, the way the sky does. Colour drains out during transition, the way it does at twilight. Two hue families (warm and cool) switch invisibly through this achromatic zone. Accent peaks at golden hour. Glint sweeps across borders at low sun.

Three roles: ground, ink, accent. Ground holds everything. Ink is its complement. Accent steers the eye.

The colour clock is the control. YOUR TIME shows the viewer’s sky. ALAN’S TIME shows Alan’s. Drag it to any point in the day.

On /system, the clock overrides the page palette. Drag it to golden hour and the entire page shifts — every ground, ink, and accent value updates live. Scroll past the colour section and the page reverts to your real time. This lets you verify the system works at every point in the day without leaving the page.

OKLCH colour space. CSS custom properties. All derived from time, nothing hardcoded. WCAG contrast maintained at every point on the spectrum.

The token architecture has two layers, not three. Most design systems have primitive tokens (static swatches), then semantic tokens mapped from them. Here, there are no static swatches. A generation function takes time as input and produces every colour through OKLCH derivation. The math is the primitive — it lives in code, not in tokens. The semantic tokens (ground, surface, ink, ink-secondary, accent, border) are the first tokenised expression of colour. They describe roles, not values. The palette moves, but the roles are stable. Component tokens reference the semantic layer: a nav label uses ink-secondary, a section heading uses ink. Two layers of tokens. The generation function replaces the third.

Colour clock — drag to scrub the time of day
GROUND
SURFACE
INK
INK-SECONDARY
ACCENT
BORDER

Motion

Motion creates the sense that content belongs where it lands. That’s why it’s here.

Composition, not animation. Content finds its place on the grid as the viewer scrolls. The grid is already there; the content arrives and settles. Long deceleration: fast at the start because it knows where it’s going, slow at the end because it’s precise about where it lands. Not bouncing, not snapping, not springing. Settling, because it belongs there.

Pace is slow. Content is being told to you, not thrown at you.

One easing curve: cubic-bezier(0.05, 0.7, 0.1, 1.0). Applied to everything. prefers-reduced-motion removes scroll-driven composition. Everything is simply present. The page works perfectly static because the structure holds without motion.

This section demonstrates itself. Trigger the animation and watch the easing in action.

0 time → 1

Iconography

Icons match optical weight with Pentameter at the size they sit beside. The system uses a small set of functional icons — arrows, external links, UI affordances — not a decorative library.

Each icon is an inline SVG, sized to the type role it accompanies. Stroke weight adjusts so the icon and the text feel equally heavy at a glance.

Arrow Left Phosphor Light · 14×14 Nav back links
Bicycle Phosphor Light · 16×16 Cycling map key
Shield Check Phosphor Light · 16×16 Cycling map key
Train Phosphor Light · 16×16 Cycling map key

Components

Button

The primary interactive affordance. Drives navigation and actions across the site.

Live component render — not yet built

Foundations

Typography ui
Colour ink, ground, accent
Spacing space-025, space-050

Used in: Hero, Spotlight

Accent colour adapts to company brand on /for/ routes.

Colour Clock

The connection between viewer and maker. Time of day generates every colour on the page.

Live component render — not yet built

Foundations

Typography data, meta
Colour ground, ink, accent, ink-secondary
Motion --ease

Used in: Hero, /system Colour section

Person

Gives a face and name to someone mentioned on the page, linking out to their online presence. Turns a quote or credit from abstract text into a real human.

Foundations

Typography ui, meta
Colour accent, ink-secondary
Spacing space-050, space-025

Used in: Hero, Tenon (LinkedIn embed), About

Quote Card

Third-party endorsement with a face attached. Person component for attribution, quote below. Links to the source.

Foundations

Typography body-md
Colour ink, ink-secondary, surface, border
Spacing space-100
Card .card base

Used in: Tenon section

Spotlight Card

The featured case study. Two-column layout with content and media, hairline borders on all sides. The card you want someone to click.

Foundations

Typography display, body-md, ui, meta
Colour ink, ink-secondary, border, surface
Spacing space-100
Card .card base

Used in: Tenon section

Work Card

A prior engagement distilled to one metric. Logo, number, label — enough to earn a click into the case study.

Foundations

Typography data, ui, meta
Colour ink, ink-secondary, border, surface
Spacing space-100, space-025
Card .card base

Used in: Prior Work section


Patterns


Views