Five candidates, each tried against the figure identity. Scroll through — the first spin drives fig 1.1.2 by scroll.
scrollama 3.2.0 · ~2 kB · IntersectionObserver steps sail the voyage via the new VoyageHandle
Ten years of war are over. Twelve ships, fifty men to a ship — six hundred set sail for home.
The wind carries the fleet to the Cicones. They sack the city; the counter-attack costs six men from every ship.
Rounding Malea for the last easy leg home, a nine-day storm drives them south past Cythera — off the chart of the known world.
Landfall among the lotus-eaters. Three scouts taste the fruit and forget home; Odysseus drags them back to the benches and ties them under the thwarts.
They beach below Etna. Six men are eaten in the cave before the stake goes into the eye — and the boast on the way out earns Poseidon’s grudge for the rest of the voyage.
Aeolus, keeper of the winds, ties every contrary wind into a bag and hands it over. Nine days of fair sailing east.
Close enough to see men tending fires on the home shore. Odysseus, nine days at the steering oar without rest, finally sleeps.
The crew open the bag looking for silver. The storm throws them the whole way back to Aeolia — and this time Aeolus refuses to help a man the gods clearly hate.
Six days of rowing north. In the closed harbour the giants spear eleven ships like fish. Only the flagship, moored outside, escapes: 484 men gone in an afternoon.
On Aeaea Circe turns the scouts to swine, then keeps the crew a year at her table. One man lost — Elpenor, off the roof. From her island they sail to the land of the dead and back, to ask a ghost the way home.
Past the Sirens with wax in every ear and Odysseus lashed to the mast — the only man to hear the song and live to report it.
In the strait at Messina, Scylla takes six men off the deck — the price, Circe said, of not losing the whole ship to Charybdis.
Weather-bound a month on the island of the Sun, the starving crew slaughter the cattle of Helios. The storm that follows splinters the ship; one man rides the keel.
Seven years on Ogygia — most of the voyage is this wait. Then Hermes brings the order Calypso cannot refuse: let him go.
A raft, a last storm from Poseidon, two days swimming. Nausicaa finds him on the Phaeacian beach — and the Phaeacians owe every guest a passage home.
A Phaeacian ship lands one sleeping man on his own beach. 600 left; one returns.
rough-notation 0.5.1 · 3.8 kB · circle / underline / strike / bracket, drawn once on first view
The Catalogue of Ships gives Odysseus twelve ships, and at fifty oars each that is 600 men — a number the poem then spends ten years spending. What the figure makes visible is that the losses are not gradual: almost everyone dies in one afternoon, in the Laestrygonian harbour, where ten eleven ships are trapped against the cliffs and only the flagship, moored warily outside, gets away.
gsap 3.15.0 (all plugins now free) · the fig's compiled coastline drawing itself, mainland first
canvas-sketch 0.7.8 + util · authoring-only: 18×12 cm generative ridgelines, exportable as a plot-ready SVG
katex 0.18.1 · display-mode typesetting of the band-width scale and chart transform
maplibre-gl 5.24 + deck.gl 9.3.7 (lazy-loaded) · self-contained basemap from world-atlas 110m, no tile server · TripsLayer pulses on great circles · pan/zoom live
zero dependencies · new house primitive: (i, t) → point over a 520×520 sheet, ~12k ink dots per frame, source printed as the caption
(a,b)=>{if(a>=12e3){let c=(a-12e3)/500;return[260+4*f(.8*b+1.6*c)*(1-c),292+200*c,1]}let c=h(a/100),d=a%100/100,e=205*(.55+.45*f(12.9898*c)),i=1.15*(1-d)**1.1-.32+.12*f(.7*b+.9*c)*(.3+.7*d),j=2.39996*c+.25*d*f(3*d+.5*b+c),k=e*d*g(i),l=e*d*f(i)+6*d*f(6*d+1.2*b+1.7*c);return[260+k*g(j),262+.5*k*f(j)-.62*l,.66*d]}(a,b)=>{let c=a%144/143,d=h(a/144)/79,e=f(.9*b+9*c+2*f(.5*b+5*d))*f(.6*b+7*d+3*c),g=.25+.75*d;return[260+(c-.5)*470*g,150+300*d-34*e*g,.5+.5*Math.tanh(1.4*e)]}zero dependencies · implicit surfaces F(x,y,z)=0 as tumbling ink point clouds — Newton-projected seeds, depth as color, equation typeset above, field printed below
(a,b,c)=>a**4-5*a*a+b**4-5*b*b+c**4-5*c*c+11.8
(a,b,c)=>{let d=i*i;return(d*a*a-b*b)*(d*b*b-c*c)*(d*c*c-a*a)-(2*i+1)/4*(a*a+b*b+c*c-1)**2}three 0.185 (lazy-loaded) · the same Tanglecube field extracted as a real mesh at 72³ and lit as a museum cast — white room, matte plaster, drag to orbit
d3 7 (force, hierarchy, drag) charting the lab itself · gsap pens the links, rough-notation circles the verdict · sizes measured on disk 2026-07-28
Dev weight, not shipped bytes — every heavy library is lazy-loaded by exactly one page. Still, the treemap keeps the score honest: the two primitives this lab actually produced, PointLaw and SurfaceLaw, weigh 0 MB — they are not in the treemap because there is nothing to measure.
zero dependencies · the sea's governing constants are live in the printed source — drag the blue numbers and the law re-renders the same frame
(i, t) => {
const x0 = (i % 144) / 143, y0 = floor(i / 144) / 79;
const h = sin(t * 0.9 + x0 * 9.0 + 2 * sin(t * 0.5 + y0 * 5)) * sin(t * 0.6 + y0 * 7 + x0 * 3);
const persp = 0.25 + 0.75 * y0;
return [260 + (x0 - 0.5) * 470 * persp, 150 + y0 * 300 - h * 34 * persp, 0.5 + 0.5 * tanh(1.4 * h)];
}zero dependencies · hover the dotted terms and fig 1.1.2 emphasizes what the sentence names — a module-global highlight channel, no context provider
Of the twelve ships that left Troy, only the flagship survives the Laestrygonian ambush — moored warily outside the closed harbour while eleven crews are speared like fish. And of the flagship’s own crew, one man outlasts the seven years on Ogygia that swallow most of the voyage’s decade.
zero dependencies · NYT's You-Draw-It on the house sheet: sketch the crew's decline, the truth draws over your line, the annotation layer marks the two decisive moments
600 men leave Troy with Odysseus; one arrives home ten years later. Draw how you think the crew declined — then see what Homer actually did.
source: Odyssey body counts · fig 1.1.2 data
zero dependencies · one dot per man in the voyage's leg colors; regroup BY SHIP ⇄ BY FATE with object constancy — the dots walk, the chart is never swapped
source: Odyssey body counts · fig 1.1.2 ship accounting
maplibre pitched over OpenFreeMap extrusions (keyless, live now) · Google photoreal Tile3DLayer wired behind an env key · synthetic localization frustums after Sidhu — drag to orbit downtown Austin
KEYLESS RUNG: OPENFREEMAP OSM EXTRUSIONS · the photoreal Tile3DLayer is wired and lights up when NEXT_PUBLIC_GOOGLE_3DTILES_KEY exists · FRUSTUM POSES ARE SYNTHETIC — THE GENRE, NOT THE PIPELINE (AFTER B. SIDHU'S AUSTIN GEOLOCATION TEST)
zero dependencies · the Fuhrer discipline in house ink: six PointLaw treatments of the same tumbling cube — wireframe, lattice, scanlines, dissolve, beads, and the cube dreaming of the sphere
(a,b)=>{let c=n[a%12],d=h(a/12)/120,e=m[c[0]],f=m[c[1]];return k(j(e[0]+(f[0]-e[0])*d,e[1]+(f[1]-e[1])*d,e[2]+(f[2]-e[2])*d,b))}(a,b)=>{let c=h(a/13)%13/12*2-1,d=h(a/169)/12*2-1;return k(j(a%13/12*2-1,c,d,b))}(a,b)=>{let c=h(a/48)/160*4,d=h(c),e=c-d,[f,g]=[[-1+2*e,-1],[1,-1+2*e],[1-2*e,1],[-1,1-2*e]][d%4];return k(j(f,a%48/47*2-1,g,b))}(a,b)=>{let c=a%6,d=2*l(2.1*a)-1,e=2*l(3.7*a)-1,g=c>>1,h=[0,0,0];h[g]=(1&c)*2-1,h[(g+1)%3]=d,h[(g+2)%3]=e;let i=Math.max(0,f(.6*b+6.28*l(a)))*l(5.3*a)*.4;return k(j(h[0]*(1+i),h[1]*(1+i),h[2]*(1+i),b))}(a,b)=>{let c=a%27,d=h(c/3)%3-1,e=h(c/9)-1,i=h(a/27),m=.11*Math.sqrt(l(1.3*i)),n=6.283*l(2.9*i),o=6.283*l(4.7*i);return k(j(c%3-1+m*g(n)*g(o),d+m*f(n)*g(o),e+m*f(o),b))}(a,b)=>{let c=a%6,d=2*l(1.7*a)-1,e=2*l(2.3*a)-1,g=c>>1,h=[0,0,0];h[g]=(1&c)*2-1,h[(g+1)%3]=d,h[(g+2)%3]=e;let i=Math.hypot(h[0],h[1],h[2]),m=.5+.5*f(.5*b),n=1-m+1.2/i*m;return k(j(h[0]*n,h[1]*n,h[2]*n,b))}the timeline primitive on trial: rAF playback, step and scrub, reduced-motion safe — and the cursor mirrors into the query string, so a moment is a link
line 0 / 12,107 · book 1 · 0 dawns · 0 dead
the cursor lives in the url — copy the address bar to share this exact moment
source: homerStats.data.ts (trial data) · useTimeline + useFigUrlState
small multiples with a shared y-domain: both poems' books on one honest scale — the iliad's are longer, and no number needs reading
the odyssey · 12,107 lines
the iliad · 15,687 lines
source: homerStats.data.ts (trial data) · SheetMultiples
all 173 notebooks from @d3/gallery, catalogued locally and runnable in place via @observablehq/runtime
Browse the gallery →boundary basis for anywhere at any level: world + US states/counties installed, German Kreise + Chinese counties compiled, and a geoBoundaries pipeline for every other country (ADM0–ADM5) · plus the source registry
Open the atlas →the instrument that watched this lab being made: every touch, check, and prompt of the session, timestamped — after the Poet Engineer's TD Field Observer
See the weave →