I The Concept
CARTOGRAPH is a fictional survey atelier that publishes charts of territories which do not exist. The whole site is one pannable, zoomable survey map, generated from a seed at load — six named territories are found inside the generated terrain and indexed in a chart-paper panel. The page has a single job: make you pan. Every visit reseeds the world, so the coastlines you wander tonight are gone by morning.
II Palette
- Slate field
#2E3A48- the survey plate itself; recedes so the linework can speak
- Contour ink
#8FA3B8- every line on the map — contours, hatching, graticule, names
- Chart paper
#E9E4D8- used sparingly: the index panel and the title plate only
- Survey red
#C4452B- the surveyor's pen — markers, active states, nothing else
- Deep water
#1F2833- the bottom of the hypsometric ramp; where the lead comes up warm
One field colour, one ink, one paper, one accent. Land lightens with elevation and the sea darkens with depth, so the terrain itself is the only gradient on the page.
III Type
Spectral SC — Place Names
Spectral, italic — for water names, soundings, and asides
Spectral SC sets every label on the map in engraved small caps, letter-spaced like a 19th-century plate. Spectral carries body copy; its italic is reserved for things the surveyor was less sure of — water names, depth soundings, coordinates. The bravery moment is the title plate: a three-line stack where "An atlas of" whispers in italic before PLACES THAT NEVER WERE lands in 62px small caps.
IV Techniques
- Seeded terrain — value noise, fBm, domain warp
A 32-bit seed (kept in the URL hash, so a chart can be shared) drives hash-based value noise. Seven octaves of fBm are sampled through a two-channel domain warp, which is what bends the coastlines out of blobbiness into fjords and reaches.
- Marching squares — the contour engine
Each tile samples a 65×65 elevation grid and runs the full 16-case marching-squares table (saddles disambiguated by cell-centre average) once per contour level: dashed bathymetric lines below sea level, fine lines above, a heavier index contour every fifth, and a bright coastline at the datum. When you descend past 2×, tiles re-render at half the contour interval — the survey redraws itself in a finer series.
- The fill — hypsometric tint, hillshade, hatching
Under the linework, a per-pixel pass bilinearly interpolates the grid: land lightens with elevation and takes a Lambert-ish hillshade lit from the north-west; sea darkens with depth. A dither of ±1.5 levels kills gradient banding. The engraved sea hatching is a field of 45° lines masked by a soft alpha ramp of the sea region (canvas destination-in), so hatch strokes fade exactly at the shore.
- Tile pyramid — how it stays at 60fps
The map renders like a slippy map: 256px tiles keyed by zoom level, drawn once into offscreen canvases and cached in an LRU (120 tiles). Panning just blits. Missing tiles are queued centre-out and rendered inside a 7ms-per-frame budget; until they arrive, the renderer substitutes scaled crops of cached ancestors or children, so the map never flashes blank. The rAF loop stops entirely when the camera, compass, and queue are all idle.
- Camera flights
Territory clicks fly the camera with zoom interpolated in log space, dipping by a distance-dependent term (a sine bump subtracted from the zoom curve) so long journeys rise, cruise, and descend like a map app. Duration scales with distance; reduced-motion users jump instantly.
- Found, not placed
The six territories are discovered in the terrain at load: candidate points are scored per kind (ring sampling for land fraction and coast transitions), then peaks and abysses hill-climb to their true local extremum so "The Candle" always sits inside closed summit rings. Minor names — fells, meres, deeps, soundings — are generated per 400-unit chunk from syllable tables, so the nomenclature is as infinite as the map.
V Iteration Log
Pass 1 — Craft
- Re-anchored the fictional graticule to 48°N · 13°W so coordinates read like a plausible North Atlantic survey instead of 0°-something readings.
- Fixed the index panel collision between long territory names and their kind tags (column gap + baseline alignment).
- Moved graticule edge labels off the panel and compass; thinned them to every second line.
- Extended the contour ladder — summits above the sixteenth line were rendering as blank plateaus — and stretched the hypsometric ramp to match.
Pass 2 — Depth
- Added the hillshade term to the fill pass; relief now reads even between contour lines.
- Added the fine survey series: below ~2× the interval is 0.022, past it tiles re-render at 0.011 with index lines every tenth.
- Peaks and abysses now hill-climb to their local extremum, so markers sit on true summits with closed rings.
- Second-read detail: depth soundings are printed in italics — and Territory VI's copy explains why ("cartographer for 'we believe'").
- Micro-interactions: inertia panning with a spring-damped compass needle that tracks travel bearing; arrival pulse rings; hovering an index entry rings its marker on the map.
Pass 3 — Hardening
- Rebuilt the 375px layout: index panel becomes a bottom sheet of swipeable chips; the status row was colliding with the panel head; chip scrollbar hidden.
- devicePixelRatio changes (browser zoom) now flush the tile cache; the chunk-label cache is capped; fixed a 60′ rounding bug in the degree-minute formatter.
- Resurvey now cancels any in-flight camera and recentres on the new world's overview.
- Reduced motion: flights become jumps, inertia and pulses are off, the intro settles without animation, and the render loop pauses when the tab hides.
- Chanel rule: removed the double-tick ornament from the panel rule — the hairline alone was enough.