TENSEGRITY is a one-page study of floating compression: a six-strut tensegrity icosahedron — Kenneth Snelson's 1948 trick, Buckminster Fuller's name — hanging in a bright studio. Its single job is to make you circle a structure whose rigid parts never touch, and watch the tension that holds them apart re-balance in real time.
The subject is the expanded octahedron: three orthogonal pairs of rigid struts, no two of them meeting, laced together by twenty-four cables. Compression lives in islands; tension is continuous. The page stages exactly one object, lets a live physics relaxation find its equilibrium in front of you, and keeps it breathing so the structure reads as held, not modelled.
The audience is anyone who has seen Snelson's Needle Tower and wondered why it doesn't fall over. The single job: make the invisible half of the structure — the tension — visible, by tinting every cable with the load it carries.
Body copy sets in strut ink and a slate secondary (#49525A) on studio fog — comfortably past 4.5:1. Crimson and amber are reserved for lines, marks and the cables themselves; the amber never carries small text on the light ground.
A grotesque with engineering posture. Set tight (−.02em) at display size for the headline; tracked wide (+.22em) for the wordmark, where TEN- picks up the crimson — tension literally carried in the name.
Everything that measures: the readout, cable names, captions, this guide's body. Tabular numerals keep the live strain figures from jittering as they update.
The topology. Twelve nodes seeded at icosahedron vertices (strut half-length / half-separation = φ). Six struts are the long diagonals; the twenty-four icosahedron edges that don't join a parallel strut pair become cables. Relaxation then pulls the shape off the icosahedron to the true tensegrity equilibrium.
React Three Fiber, no build step. The scene is real R3F 8.17 + drei 9.114 loaded through a pinned ES-module importmap (react 18.3.1 with both jsx-runtime subpaths mapped, ?external= singletons so fiber and drei share the one three.js). Markup is written as htm tagged templates — no JSX transform anywhere. drei supplies OrbitControls (damped, slow auto-rotate), a procedural Environment built from three Lightformer panels (no external HDR — the CDN allowlist stays intact), and ContactShadows for the studio floor.
The verlet net. Physics is thirty lines of position-based dynamics: each node stores position and previous position; struts are hard equality constraints (corrected to exact length every iteration), cables are one-sided — they correct only when stretched past rest, because a cable cannot push. Seven constraint iterations per 60 Hz substep, 1.8% damping, centroid re-centred each step. Cables are pre-tensioned to 94% of their seed length, so at equilibrium every one of the twenty-four carries measurable strain — that strain drives both the crimson→amber tint and the live strip chart in the readout.
Breathing. Each cable family (x–y, x–z, y–z) modulates its rest length ±3% on a slow sine, phase-shifted 120° per family with a small per-cable offset. The net visibly re-balances — tension flows around the structure in waves — while the struts drift and never meet. A pluck (click the structure, or the keyboard-reachable button in the panel) kicks every node's velocity outward from the hit point and lets the cables argue it back to stillness.
Never touching, provably. Every physics step computes the minimum segment-to-segment distance across all fifteen strut pairs (minus two strut radii) and tracks the all-time minimum. The readout shows clearance as a percentage of strut length; the page exposes it to the QA harness, which asserts it stays positive through settling, breathing and plucks.
Hardening. DPR capped at 2, physics skipped while document.hidden, WebGL feature-detect plus a webglcontextlost handler that swaps in an inline-SVG rendition of the structure, and prefers-reduced-motion runs the relaxation to convergence synchronously and renders one settled frame on a demand-mode frameloop — settled and taut, not blank.
#6E7880 to #5C656D and moved all amber-coloured text to the derived #8A6115 amber-ink.toneMapped:false basic material — at 375px the crimson wires were vanishing into the fog under ACES tone mapping.c14 · x—z) carrying the most load.