Generative Assets · Guide 191

How Catenary was made

A chain hanging between two drifting anchors settles — every frame, by nothing but link constraints and gravity — into a·cosh(x/a). The page fits that equation to the live chain, overlays the parabola everyone assumes it is, shades the disagreement, and then flips the whole scene into Gaudí's standing arch. Visit the site.

Concept

Catenary is a single-screen study in the "Form" wave: the curve of a hanging chain, treated as a lecture a crypt could give. The audience is anyone who has ever assumed a slack rope is a parabola. The page has one job — to show, honestly and live, that the chain's own shape and the parabola through the same anchors are two different curves, and that inverting one gives you architecture.

Palette

#201C18 crypt-stonethe ground — a warm near-black, candle-lit masonry rather than screen-black
#D3A94C chain-goldlines & marks only — the chain, the fit, anchor pins. Never body copy
#6E86A8 parabola-ghostthe wrong guess gets a cold blue, dashed; its disagreement shades at 13–15% alpha
#EADFC8 candle-inkbody copy, ≈11.9:1 on stone; dimmed to #C0B398 (≈7.6:1) for secondary text

The spec's bright chain-gold is held strictly to a line/mark token; the body ink is derived from candle-ink with two darker steps (#C0B398, #877D69 — the last decorative only), so every piece of running text clears 4.5:1 comfortably on the stone.

Type

Gloock carries the display voice — a high-contrast modern serif whose heavy ball terminals read like wrought iron; it sets the wordmark, the readout numerals, and the giant TENSION / COMPRESSION word that swaps at each inversion. JetBrains Mono does everything measured: the promise line, readout labels, legend, and Hooke's anagram — the right register for a page whose centrepiece is a fitted equation.

Techniques

Verlet chains (canvas 2D). Each chain is 22–38 point masses under position-Verlet integration with fixed 1/60 s steps, 14–26 relaxation iterations per step over its distance constraints, endpoints pinned to anchors that drift on slow incommensurate sine paths. Nothing about the shape is scripted — the catenary emerges from the constraints.

The honest fit. Every frame the page measures the lead chain's true arc length, then solves 2a·sinh(h/2a) = √(L²−v²) for a with Newton's method (the transcendental equation for a catenary through two given anchors with a given length), placing x₀, y₀ from tanh((u₁+u₂)/2) = v/L. The thin gold line drawn over the chain is that analytic curve; the readout's rms residual (typically under 1 px once settled) is the proof the simulation found the equation. The parabola ghost is the quadratic through the same two anchors and the catenary's own lowest point — the fairest possible impostor — and the blue shade fills exactly the region where the two curves disagree, with Δmax read out.

The Gaudí inversion. On a 32-second cycle, gravity's sign eases through a cosine from +1 to −1: the chains swing up through their anchor rail and re-settle as standing arches — Hooke's 1675 anagram played live, tension becoming compression with no change of shape. The fit runs in mirrored coordinates during the arch phase, so the same cosh equation is verified in both worlds. Overlays gate on the fit residual and only fade in once a chain has genuinely settled.

Iteration log

Pass 1 — Craft

  • Driving the fit assert caught a real bug the eye missed: canvas y grows downward, so the solver was fitting the catenary opening the wrong way — residual 357 px, and the honesty gate had silently hidden every overlay. One sign flip later the chain matches its cosh fit at 0.20 px rms, verified again in the arch at 0.16 px.
  • Uppercase readout labels were mangling the mathematics — PARAMETER A, ΔMAX. The symbols now opt out of the transform and sit italic: Parameter a, Δmax.
  • The deep background chain (slack 1.62) bottomed out exactly where the lead chain's vertex sits, tangling the centre of the frame; re-hung it at slack 1.42 over a narrower bay so it nests inside the lead curve.
  • Gave the Hooke note a soft left-anchored scrim with a 2 px backdrop blur — the left chain drifts behind it and the small type stayed readable through every drift phase.

Pass 2 — Depth

  • Made the inversion the typographic event: the giant Gloock TENSION fades out mid-flip, flashes Hooke's own words — ut pendet · sic stabit — in tracked mono while gravity crosses zero, then resolves to COMPRESSION. Screenshot-verified at the cycle's midpoint.
  • Second-read details: the lead chain's links alternate hollow ring / solid stud like real chain; hovering (or focusing) the Hooke note unscrambles the 1675 anagram into its Latin solution; the Sag s readout quietly relabels itself Rise s while the arch stands.
  • Overlays gate on the live residual, easing in as it falls — after each flip the equation visibly "catches" the chain as it settles rather than popping on, and can never draw over an unsettled swing.
  • Deepened the disagreement shade to 18% alpha and pushed the lead parabola ghost to 0.8 alpha at 1.3 px — the near-miss now reads at a glance without shouting.

Pass 3 — Hardening

  • 375 px rebuilt, not squeezed: the readout leaves the top-right (it collided with the promise line) and becomes a three-stat row above the footer; the note and legend stand down; the lead chain re-hangs wider and deeper for the portrait frame. Probe confirms scrollWidth = 375 with nothing past the right edge.
  • Reduced motion honoured twice over — CSS media query kills transitions; a JS matchMedia gate skips the rAF loop and renders one 900-step pre-settled frame with overlays and readouts (verified: identical screenshots 1.3 s apart, rms 0.16 px, zero console errors).
  • DPR capped at 2, debounced resize re-lays and re-warms the chains, rAF stops on document.hidden, and the cycle clock advances on sim time so a background tab can't skip the flip.
  • Chanel rule: cut the vignette's second candle-glow gradient — the gold belongs to the chains alone. Final copy read tightened the promise line.

Verification

Headless Chrome, 7-second settles: zero console errors on both pages, one h1 each, hero visible, 375 px clean, two-frame liveness pass, anchor-drift assert, and the signature drive — force the inversion, assert the chain stands above the rail as an arch and still matches its cosh fit to sub-pixel rms, then revert and assert it hangs again.