Build guide · Experiment 04 / 25

A website you interrogate.

A practical breakdown of the CRT rendering stack, the canvas rain, the redacted case files, and the in-character terminal behind NEON DUSK, a fictional cyber-noir detective agency in 2087.

FormatSingle-page noir experience
Core stackHTML · CSS · Canvas 2D
Release10 July 2026

01 · Creative premise

Noir is a reading posture.

Detective fiction works because the reader is made complicit: you lean in, you squint, you want the sealed file. NEON DUSK is built around that posture. Case files arrive partially redacted and only unredact under your cursor. The agency's AI partner answers questions in a real terminal, in character, and admits that some commands are not listed. The site does not present the agency. It lets you investigate it.

The governing rule

Every interaction should feel like getting information out of someone who charges by the hour.

The world is fictional 2087: a two-desk agency above a noodle bar, one human ex-detective, one camera-reading intelligence named MARLOWE. All copy stays in that voice, including the invoice line.

02 · The CRT stack

Atmosphere is a stack of cheap layers.

The tube-monitor look is five inexpensive layers, each doing one job, all pure CSS on top of the page:

Scanlines

Repeating gradient

A 4 pixel repeating linear gradient at low opacity. The single biggest contributor to the look, and it costs nothing.

Vignette

Radial darkening

A fixed radial gradient pulls the corners down like tube falloff, which keeps eyes centered on content.

Fringe

Chromatic text-shadow

Headings carry a one pixel magenta shadow left and cyan right, a two-color aberration that reads as glass refraction.

Neon

Layered glow shadows

The sign in the hero is text with stacked text-shadows at increasing blur radii, plus a slow flicker keyframe on a random-feeling schedule.

Glitch

Scramble on approach

Section headings decode from random glyphs to their label when they enter the viewport, one IntersectionObserver and one interval per heading.

03 · Rain and redaction

Weather you can feel and change.

The rain is one fixed canvas behind everything: a few hundred streaks with three parallax depth bands, faster and brighter up close, slower and dimmer behind. Each drop is two lines (a cyan-tinted core and a fainter tail), and the whole layer pauses when the tab is hidden. Typing rain in the terminal toggles a downpour, because a noir site should let you make it rain harder.

drop.y += drop.speed * band.rate
if (drop.y > h) respawn(drop)   // three bands: 0.5x, 1x, 1.7x

The case files use a redaction interaction: sensitive phrases are wrapped in a span whose background matches the text until hover, when a clip-path wipe reveals the words beneath. On touch devices the redactions reveal on tap. What stays sealed is a copy decision, not a technical one: some cards never unredact, which is better noir.

redacted := hover ? reveal-wipe 350ms : solid slab · sealed := never

04 · The terminal

The mascot is a shell prompt.

The centerpiece is MARLOWE, a working terminal. It boots when scrolled into view, types a greeting, and answers a command set (help, about, cases, hire, rates, rain, clear, plus unlisted responses for the curious, including sudo). Responses type out character by character with an amber highlight token system, command history works with the arrow keys, and hint buttons under the window run commands for visitors who do not want to type.

Two engineering details carried it:

Markup

Segment-aware typing

Highlighted phrases are written as [[hi]] tokens, parsed into segments before animation. A naive character slice flashed raw brackets mid-animation; rendering from parsed segments means every intermediate frame is valid.

Locking

One writer at a time

The boot sequence, command echo, and responses all append lines asynchronously. A single busy flag makes them take turns, so fast typists cannot interleave the boot text with a command response.

05 · Stability lessons

Test the conversation, not the render.

Static screenshots said the terminal looked right. Only driving it like a user, headless keyboard input against the real page, proved it behaved right, and that is what caught both terminal bugs. The screenshot harness for this series gained a typing flag specifically for this site, and the lesson generalizes: interactive set pieces need interaction tests, in this case verifying the line count grows and the response text renders after a submitted command.

node scripts/shot.mjs <url> out.png --type "#term-in::help"
# clicks, types, presses Enter, waits, screenshots, fails on console errors

06 · Production process

Three passes before release.

01

Typewriter correctness

  • Replaced the naive character-slice typewriter with a segment parser so highlight tokens never flash as raw text.
  • Verified the fix across boot, help, and error responses.
02

Interaction integrity

  • Added a boot lock so the intro sequence and user commands cannot interleave.
  • Extended the screenshot harness with keyboard input and drove help and rain end to end.
  • Confirmed command history, hint buttons, and the unlisted responses.
03

Full-page QA and release

  • Swept desktop at five scroll depths and mobile at four; zero console errors throughout.
  • Checked redaction hover states, stat counters, neon flicker, and the closing CTA.
  • Verified reduced motion: static rain, instant text, no flicker.
  • Shipped through the production build and portfolio index.

07 · Authorship

Built by models. Directed by a person.

This series is a transparent record of AI orchestration. Credit is split by the work actually performed.

Concept and implementation

Claude Fable 5 invented the agency, wrote the in-character copy and terminal script, built the CRT stack, rain system, redactions, and completed the three polish passes.

Platform architecture

Codex established the portfolio index at /x, the per-experiment guide pattern, and the release pipeline this site ships through.

Creative direction

Viron Gil Estrada commissioned the 25-site experiment, set the quality bar, owns the platform, and defined the one-site-at-a-time release strategy.

Constraint

No images and no video. The city is a canvas of rain, the sign is glowing text, and the mascot is a conversation.

The file is open.
Go ask Marlowe something.

Enter Neon Dusk