Production note · 690 words
A room built backwards
The Composing Room imagines an uninterrupted letterpress shop founded in 1893: not a nostalgic museum, but a warm, slightly oily workplace with jobs still due. The central idea is the compositor’s transformation. Metal type must be selected from a carefully ordered case, assembled mirror-reversed, and only becomes ordinary language when pressure transfers ink to paper. The page makes that hidden mental act visible and playable.
The interface follows the shop’s physical sequence. The visitor enters past a monumental type case, works at the composing bench, learns the p-and-q trap, measures type, then crosses a ticket wall and reads the foreman’s rules. That long-form rhythm replaces a conventional marketing grid with a spatial journey from cabinet to press to stone.
Type, sorted & set
The California job case
In main.js, the upperOrder and lowerOrder arrays generate every compartment through makeSort(). Frequency classes such as xwide give common lowercase letters larger bins. Clicking a compartment calls addChar(); physical keyboard input uses the same path, so the displayed case and typed line never diverge.
renderLine() reverses the array before drawing the metal sorts. Each glyph is also horizontally flipped with scaleX(-1). This creates the compositor’s view: reversed character shapes in reverse reading order. Spaces become low, non-printing metal rather than blank characters. The twenty-four-em limit gives the stick a believable constraint.
The platen and proof
proofButton rebuilds the phrase in logical order on the proof sheet, applies deterministic width variation, and marks every seventh character as worn. CSS animates pullLever and closePlaten together, then slides the paper out. The ink uses opposing light and dark text shadows to suggest a debossed bite; small horizontal squash differences keep the line from looking digitally perfect. The separate p/q sort uses pqState to flip both the held type and its paper result.
The final shop ritual is interactive rather than decorative. Once the sheet clears the platen, approveProof() unlocks a wooden foreman’s stamp. Its strike leaves a slightly rotated union-red impression whose angle derives from the line length, so every approval feels related to the job without introducing unstable randomness.
A compact URL state accepts ?line=, &proof=1, and &approved=1, making a signed proof linkable without maintaining a second interaction model.
The point specimen is a real range control. setPointSize() writes its value into the --specimen-size custom property, allowing the heading to expand from 12 to 72 pixels without layout scripting. Intersection Observer adds a single staggered arrival moment; reduced-motion users receive the complete composition immediately.
proof-revealed gives the paper the room; approved signs it off.Oak, lead, ink, paper
#4a3826Lead grey
#7d8087Ink black
#191714Kraft
#c9aa78Union red
#a62d24
Oak is the architectural field; kraft and paper carry reading surfaces; grey belongs to machines and sorts. Union red is rationed to proof actions, shop stamps, and editorial emphasis. Brass appears as hairlines and hardware, lending warmth without turning the palette decorative.
Young Serif provides broad, ink-holding display shapes. Zilla Slab keeps long text sturdy and period-aware without becoming costume typography. Space Mono labels every compartment and measure like stamped shop furniture. All three are self-hosted.
Reproduce this
Prompt an AI agent to build a responsive, code-only site around one physical transformation rather than a theme alone. Specify a historically grounded workshop, a dominant dark material field, one restrained labor-color accent, and self-hosted display, slab, and mono faces. Require an interactive case whose data model controls both an intentionally unreadable work state and a legible output state. Ask for CSS-built machinery, imperfect print texture, a real measurement control, narrative shop records, keyboard access, reduced-motion behavior, and screenshot verification at phone, tablet, and desktop widths.