How it was made · Generative Assets 207
Enigma — build notes
A working Enigma I in a single HTML file — no libraries, no build step. The cipher core runs the historically documented rotor tables; the body is CSS 3D and SVG. The page's one job: let you watch a letter's electrical path re-route through the machine on every keystroke, and understand why that both made the lock immense and gave Bletchley the crack.
Concept
A wartime bakelite artefact, close and tactile: three rotor drums above a lampboard and keyboard, an auto-operator already mid-message, and a live wiring diagram tracing every stroke from key through plugboard, three rotors and reflector back to a lamp. The audience is anyone who has heard "Enigma" and never seen the current move. Type, and the machine is yours.
Palette
Type
Barlow Semi Condensed carries the machine plate: a DIN-flavoured grotesque, condensed like stamped engineering lettering, set in uppercase with generous tracking for eyebrows and all-caps display for the headline. Special Elite is the typewritten layer — the message tape and the wiring tables — because every Enigma decrypt ended its life on a typewriter.
Techniques
Cipher core, honest. Rotors I, II, III (EKMFLGDQVZNTOWYHXUSPAIBRCJ,
AJDKSIRUXBLHWTMCQGZNPYFVOE, BDFHJLCPRTXVZNYEIWGAKMUSQO), reflector B
(YRUHQSLDPXNGOKMIEBFZCWVJAT), turnovers Q / E / V, ring settings A-A-A, six plug
pairs, ground setting ADS. Stepping is odometer-with-a-defect: right drum every stroke, middle
at the right's notch, middle and left when the middle sits on its own notch — the
double-step, which the machine plays out on screen in its first five strokes
(ADV → AEW → BFX) and which trims the stepping period from 17,576 to a
measured 16,900.
Signature — the live path trace. Each keystroke returns a full trace object (key, plugboard, three forward rotor exits, reflector pair, three inverse exits, lamp). An SVG with six contact columns × 26 rows plots it as two polylines — a 7-point amber forward run ending in the reflector's vertical jog, and a 6-point paper-toned return — animated by stroke-dashoffset so the current visibly flows. Because the rotors move before the circuit closes, pressing the same key twice draws two different roads; the diagram is computed from the same trace the lamps use, so it cannot lie.
CSS 3D drums. Each rotor is a true cylinder: 26 lettered faces, each rotated
360/26 ≈ 13.85° apart and pushed out translateZ(90px) (radius from face
height 22px: 11/tan(π/26) ≈ 90.3). The drum rotates by cumulative steps — ground + step count —
so carries roll continuously without unwinding, and the housing clips the cylinder to a window
with an amber bezel over the reading row. Turnover letters carry a machined notch-dot on their
face — a second-read detail for whoever watches a full revolution.
Auto-operator. A convoy sighting report types itself at a 700 ms cadence, so the
7-second thumbnail catches the machine mid-message with the double-step already played.
Your own keydown takes the keyboard over; the operator resumes after six idle seconds. A
window.__enigma probe exposes the machine, its class, and a driveable
press() so QA gates on state, not wall-clock.
Iteration log
Pass 1 — Craft
- Caught a stray corrupted attribute line in the SVG dot builder (a junk fill value written then overwritten) — removed before it could mask a real bug.
- The h1 read "26 lamps…" with no brand name — an SEO/outline gap; added a visually-hidden "Enigma —" prefix inside the single h1.
- The scaled machine kept its 540px layout box at 375px width, silently masked by
overflow-x:hidden— the exact W2 hazard from the playbook. Clipped the wrapper and centred the machine so the layout box can never leak. - Node-tested the shipped cipher against the standard vector: AAAAA at AAA with no plugs lights BDZGO. Ten core assertions, all passing, before any visual work continued.
Pass 2 — Depth
- Added the carry pulse: when the middle or left drum is dragged over, its window bezel flashes amber for 340 ms — the double-step anomaly becomes something you can see happen, not just read about.
- Strengthened the drum window bezel so the reading row is unambiguous against the brass.
- Cut a machined crease between lampboard and keyboard — the two grids read as one slab before; the real machine has a fold there too.
Pass 3 — Hardening
- Chanel rule: removed the tape's left-edge shading gradient — the paper reads cleaner without it.
- Reduced motion: the machine renders settled six strokes into the message with the path
drawn and no timers running — verified headlessly under emulated
prefers-reduced-motion. - 375px: scrollWidth clean, nav and wordmark inside the viewport box, machine and diagram both fit; keys stay clickable at the scaled size.
- Final driven sweep: same key pressed twice lights different lamps and draws different roads; 5,200 scripted strokes across four ground settings produced zero self-encodings; encrypt→decrypt round-trips the full convoy message at identical settings.
Honest numbers
- 158,962,555,217,826,360,000 — 60 rotor orders × 17,576 ground positions × 150,738,274,937,250 ten-pair plugboards; product recomputed in BigInt, digits match the commonly cited figure. Ring settings excluded, as in the usual quote — copy hedges accordingly.
- 16,900 — stepping period measured by driving the shipped stepper until the window state recurred (double-step trims 26³).
- BDZGO — output of AAAAA at rotors I-II-III / AAA / no plugs, asserted in Node against the shipped source.
- ADV → AEW → BFX and the documented KDO → KDP, KDQ, KER, LFS, LFT — both double-step sequences asserted against the shipped stepper.
- 0 self-encodings in 5,200 driven strokes — the reflector's flaw, held live on the page counter.