Making-of record · 27 Jul 2026
How to make a bureau terminal feel like a place, not a costume.
NULLPORT is a fictional Bergen data-recovery office that began in 1982 and never quite stopped operating. The site frames its visitor as a read-only guest on an old relay: the navigation is a terminal command, and the copy is written as actual bureau record rather than a tech-themed sales pitch.
An aging screen with a professional conscience.
The visual idea is deliberately restrained: one green-on-black phosphor display, an amber warning state, hard hairlines, and sparse data readouts. The “noir” comes from the sense that every recovered byte has a history, not from rain-soaked neon decoration.
The layout moves from the bureau’s origin, through cases and method, to a present-day intake warning. Each section has a different information shape—narrative, file index, procedure, and ledger—while still behaving like one terminal session.
The screen is an operating instrument.
The command line parses help, ls, open <section>, and whoami, then writes a response into the terminal and scrolls to the requested record. The page is also routed through an SVG feDisplacementMap. A tiny canvas creates a radial red/green displacement texture: at the edge, its channels push pixels outward, giving the full content plane a light barrel bend rather than merely rounding a frame. A separate Flux Reader lower on the page turns the same recovery idea into a real, keyboard-operable instrument: it only reveals the recovered record when its tuning head reaches the narrow carrier window.
function makeBarrelMap() {
const canvas = document.createElement('canvas');
const size = 160;
canvas.width = canvas.height = size;
const context = canvas.getContext('2d');
const pixels = context.createImageData(size, size);
for (let y = 0; y < size; y++) {
for (let x = 0; x < size; x++) {
const nx = (x / (size - 1)) * 2 - 1;
const ny = (y / (size - 1)) * 2 - 1;
const radial = Math.min(1, nx * nx + ny * ny);
const offsetX = nx * radial * 112;
const offsetY = ny * radial * 112;
const i = (y * size + x) * 4;
pixels.data[i] = 128 + offsetX;
pixels.data[i + 1] = 128 + offsetY;
pixels.data[i + 2] = 128;
pixels.data[i + 3] = 255;
}
}
context.putImageData(pixels, 0, 0);
barrelMap.setAttribute('href', canvas.toDataURL('image/png'));
}
A deliberately small system.
What broke, what changed.
Pass 1 — establish the relay
The first risk was pastiche. The bureau became a specific Bergen office with a flooded archive, a chain-of-custody ethic, and cases that have consequences. That gave the terminal a reason to exist beyond its green text.
The terminal had to navigate for real. The initial build established the parser, sector map, accessible text input, typed boot sequence, phosphor bloom, scanlines, and the radial displacement map that bends the page as one display.
Pass 2 — design depth
Repeated section rhythm. The records all arrived in the same safe centred column. The command dock now sits off-axis, the first casefile becomes a full-width evidence strip, the method becomes a deliberately scrollable four-stage signal trace, and the clearance advisory cuts into its own field.
Timid hierarchy. The original headings clustered around one polite scale. The bureau brief now takes display scale in a deliberate two-line construction; the lead, labels, and operational headings use clearer intervals, tighter display tracking, and balanced wraps.
Underused terminal behavior. Commands now cause a short phosphor pulse rather than merely adding a line of text. The custom, quartic terminal-navigation scroll gives typed navigation a deliberate motion curve; reduced-motion keeps both interactions immediate.
Pass 3 — complexify
A recovered record needed to feel earned. The new Flux Reader is a deterministic canvas trace driven by a real range control. Away from 064.0 kHz it honestly reports no carrier; near the target it tracks; inside ±0.5 kHz it resolves Sector 04 and unlocks the Fjord Ledger line. Resetting returns the instrument to its uncalibrated state.
The page was retyping visible copy after first paint. The permanent claim now remains in the document from the start; only the empty terminal status types in. The reader animates only while it is on screen and the tab is visible, while reduced-motion keeps a still, fully usable trace.
The finishing audit added the salvage sector to the command index, matching Open Graph records, explicit keyboard focus for every control, and narrow, medium, and wide layout guardrails. The end state is a bureau terminal that can be explored without sacrificing the paper trail.