NULLPORT / FIELD NOTES / BUILD 06

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.

01 / concept

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.

02 / signature technique

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'));
}
03 / palette + type

A deliberately small system.

VOID#0A0F0A
PHOSPHOR#33FF66
WARNING#FFB000
READABLE INK#D7FFE0
IBM Plex Mono — 400 / 500 / 600 / 700Every character, label, command, and body paragraph uses IBM Plex Mono. Its shapes stay sober at small interface sizes but have enough personality to make the ASCII heading feel intentional rather than nostalgic shorthand.
04 / iteration record

What broke, what changed.

Pass 1 — establish the relay

01 / Voice

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.

02 / Instrument

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

01 / Rhythm

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.

02 / Type

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.

03 / CRT

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

01 / Signal

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.

02 / Arrival

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.

03 / Handoff

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.