WallpaperGuide

Build notes · Site 190 · Generative Assets

Stamping one glyph through all seventeen plane groups

Wallpaper is a working printing plate for the classification theorem every repeating pattern obeys: any two-directional repeat belongs to one of exactly seventeen symmetry groups. The page's single job is to make that census physical — one Fraunces ampersand, its weight slowly breathing, is stamped live through each group in turn while the mirrors, glide axes and rotation centres that define it are drawn as construction marks over the ink.

Palette — plate, ink, and two kinds of mark

The scheme is argued from letterpress furniture: a dark steel plate, one pale ink, and the two colours a plate-maker would scribe in. Teal is reserved for lines — mirrors solid, glides dashed — and brass for point marks, the rotation centres. Body text never borrows the accent colours; it has its own ink so small labels stay above 4.5:1 on the plate.

#191D1B
Printing plate
The ground. Green-black steel, dark enough that flooded ink reads as relief, not decoration.
#E4DED0
Motif ink
The ampersand itself. A warm stone white — full white would strobe against 200 stamps a screen.
#5FA895
Symmetry teal
Lines and marks only: mirror lines solid, glide axes dashed, the unit-cell outline. Never body copy.
#C99A3F
Rotation brass
Point marks: lozenge, triangle, square, hexagon for 2-, 3-, 4- and 6-fold centres, as crystallographers draw them.
#BEC7C0
Body ink
Derived reading tone for running text — the ink/line split the collection settled on in Wave 2.
#8FA097
Muted label
Census metadata, eyebrows, this caption tier. Checked at 375px against both plate tones.

Type — the specimen is the subject

Fraunces &

Fraunces variable

The motif is not set in Fraunces; the motif is Fraunces. Its weight axis breathes between 180 and 640 on a 4.2-second cycle, so the whole plane pulses as one organism. Display sizes ride the optical-size axis to 144; the hexagonal family's group names (p3, p3m1, p31m, p6, p6m) are set italic as a quiet taxonomy marker.

p4g · 04/17

Azeret Mono

The surveyor's voice: crystallographic names, cell metadata, generator readouts, and every caption on this page. Its squarish counters sit naturally beside construction marks, and tabular figures keep the 17-group census aligned.

Technique — symmetry as arithmetic, marks as theorems

Everything is canvas 2D — no libraries. Each of the seventeen groups is stored as its textbook operation set: integer 2×3 matrices in lattice coordinates, exactly as the International Tables list them (p4g, for instance, is the four rotations of p4 plus the same four reflections shifted by ½,½). A basis matrix B per lattice class — oblique, rectangular, rhombic, square, hexagonal — maps cell coordinates to pixels, and each operation's screen transform is the conjugation L = B·M·B⁻¹, handed straight to ctx.setTransform. The ampersand lives on one offscreen 320px canvas, re-rasterised every frame at the breathing weight, then stamped hundreds of times per group; where an operation's determinant is negative the stamp prints left-handed — a chiral ampersand no font menu contains, and the site's second read.

The construction marks are the part I refused to hand-draw. For every operation the code solves for its fixed locus: rotations solve (I−L)c = τ for the centre point and take the trace for its order; reflections split their translation into components along and normal to the axis direction φ = ½·atan2 of the linear part, and the smallest parallel component over all lattice copies decides solid mirror or dashed glide. So the marks are not an illustration of the group — they are computed from it, and a wrong matrix would draw its own accusation. A test hook asserts the derived mirror/glide/rotation census for all seventeen groups against the crystallographic table on every build.

Choreography: each group floods outward from the centre — stamps pop in distance-ordered with a cubic ease — then cell outline, axes and centres fade up over the ink. The cycle rests 5.4 seconds per group (9.5 on the opening p6m, so the first frame a visitor or a thumbnail sees is the full kaleidoscope, flooded, marks up). Labels swap through a 180ms opacity dip; the census cards and the 17-stop rail jump the plate to any group directly.

Iteration log

Pass 1Craft

  • Unified the mark language across every surface: census-card chips repeat the plate's exact grammar — solid teal outline for mirror, dashed for glide, brass for rotation — so the legend teaches itself.
  • Kept teal and brass off running text entirely; body copy got its own two-ink scale (#BEC7C0 / #8FA097), both checked above 4.5:1 on the plate tones.
  • The giant group-name readout was hidden from assistive tech with aria-hidden — removed it; the name is the page's principal live datum.
  • Rewrote generator captions to read as spoken geometry ("mirror one way · glide the other · half-turns") rather than Hermann–Mauguin shorthand.

Pass 2Depth

  • Replaced hand-placed decorations with derived marks: centres and axes are solved from the operation matrices at runtime, which is what makes seventeen genuinely different plates rather than seventeen backdrops.
  • Added the chirality second read — reflected stamps print left-handed ampersands, and the rotation-only family (p1, p2, p3, p4, p6) provably never flips one; the legend note points it out only after the census.
  • Gave the boot cycle an overture: the page wakes on p6m, the order-12 maximum, and holds it 9.5 seconds before starting the tour from p1.
  • Exposed a features() self-test that recomputes each group's mirror/glide/max-rotation census; all seventeen match the textbook table.

Pass 3Hardening

  • 375px verified by element boxes (wordmark, nav, readout, rail), not just scrollWidth; the readout column stacks and the rail keeps 17 stops tappable — hit areas widened past the 3px tick marks.
  • Reduced motion renders a settled mid-cycle plate — flooded stamps, marks up, no loop — via the CSS query plus a matchMedia switch with a live change listener.
  • Canvas discipline: DPR capped at 2, debounced resize rebuild, rAF paused when the tab hides, painting skipped while the hero is scrolled out of view, fonts gated on document.fonts.ready with a 3-second fallback.
  • Headless checks: zero console errors, exactly one h1 per page, two-frame screenshot-hash liveness, and per-group screenshots pairwise distinct across the glide and hexagonal families.