Field note / 13
THE WET
NEON
PROBLEM.
Alley 9 had to feel discovered rather than advertised: a late-night noodle counter with a record wall, seen through rain from the mouth of a side street.
The concept
A sign you can almost hear.
The page starts in the rain because the business does. Alley 9 is imagined for the half-hour after a station closes: a place that makes a quiet decision to stay bright while the rest of the street goes dark. The layout is deliberately alley-like: a narrow approach, a blinding vertical sign, then a counter menu, crates, and the evening’s sequence.
Pink marks the address, cyan calls out the noodle-and-records promise, and sodium amber is the human light in the room. The large “9” carries the sign; everything else is sized to feel like it is pasted around it.
Signature technique
Live rain, live light, a wet floor.
The rainfall is not a background video or an image. A canvas makes individual diagonal streaks with their own length, speed, opacity, and occasional cyan/pink catch-light. It only animates while the hero is in view and the tab is visible; a static painted frame remains when movement is reduced.
function tick(now) {
if (!active) return;
const elapsed = now - last;
const dt = Math.min(40, elapsed) / 16.67;
last = now;
ctx.clearRect(0, 0, width, height);
drops.forEach(drop => {
drop.y += drop.speed * dt;
drop.x -= drop.speed * .19 * dt;
if (drop.y - drop.length > height || drop.x < -50) Object.assign(drop, makeDrop(false));
draw(drop, 1);
});
raf = requestAnimationFrame(tick);
}The sign itself is text layered with tight white cores and progressively wider coloured shadows. JavaScript chooses a fresh duration, negative delay, and timing curve on every load so the flicker avoids a clockwork loop. Its reflection is a second text sign, flipped vertically, blurred, and clipped by a gradient mask—the important part is that the reflected colour remains real type rather than a painted approximation.
.reflection-well {
overflow: hidden;
opacity: .48;
-webkit-mask-image: linear-gradient(to bottom,
rgba(0,0,0,.74), rgba(0,0,0,.26) 49%, transparent 94%);
}
.reflection {
transform: translateX(-50%) scaleY(-1) skewY(-3deg);
filter: blur(4px) saturate(1.15);
animation: reflection-waver var(--reflection-duration)
cubic-bezier(.23,.78,.35,1) var(--reflection-delay) infinite;
}Palette + type
Colour from the street.
Iteration log
Three passes, held.
Pass 1 — correctness
- Guarded the rain setup against missing DOM/canvas support, added an IntersectionObserver fallback, and synchronised the canvas and CSS neon loops with page visibility, reduced-motion preference, and hero visibility.
- Kept canvas density bounded (60–130 streaks), capped device pixel ratio at 2, batched resize work to an animation frame, and bounded frame deltas so the rain stays smooth without large catch-up jumps.
- Moved the mid-width layout switch to 920px and removed rigid content-column minimums that could overflow just above the former 820px breakpoint.
- Added the index page’s accessible H1, 44px minimum targets for interactive controls, and an ink focus ring for the email link over the amber panel. Both required gallery and guide links remain visible in each footer.
- Known limitation: the in-app browser was unavailable during this pass, so final viewport rendering could only be checked through the page’s responsive constraints and local static validation rather than live screenshots.
Pass 2 — design depth
- Weak moment: repeated centre-section rhythm. The menu, records, and schedule all read as orderly information blocks. The menu is now a tilted, cyan-tabbed night-service ticket set against a bleeding katakana field; the record wall is an uneven crate arrangement; and the programme has become a full-width typographic poster with its timetable pushed into a lit side panel.
- Weak moment: the type softened after the hero. A shared spacing scale now controls the page cadence, display faces use tighter, more deliberate proportions, and “Steam / in the / speakers.” plus “Needle / drops.” are purposefully composed into unbroken lines with a much larger scale contrast.
- Weak moment: the wet-ground signature froze too early. The reflection now shivers on independently randomised, irregular timing and a brief ripple layer cuts through it like rain disturbing pooled light. The endless marquee motion was removed so the remaining movement describes weather, light, or sound rather than decoration.
Pass 3 — complexify
- New lower-page moment: the counter deck. The four record sleeves became actual buttons instead of decorative tiles. Choosing one lights the turntable with that sleeve’s colour, drops the stylus, spins the platter, and changes the counter monitor to its catalogue side and staff note. “Lift the needle” returns it to an intentional blank state; the deck never pretends music is playing before a visitor makes a choice.
- New page state: outside becomes inside. Once the hero has passed, the main navigation docks as a dark, rain-glass strip. It turns the long scroll into a small journey from alley mouth to counter without duplicating navigation or adding a generic progress bar.
- Finish work. Motion begins only after the first painted frame and font-loading gets an optional, non-swapping path, so the page opens as composed type and rain rather than a sequence of pops. The deck, docked navigation, rain, and reflections all respect reduced motion; metadata, focus states, mobile code-block containment, and the final copy were reread together.