Every page on this site grows its own landscape: link previews drawn from the page's own words
A generative system that turns each page's text and edit date into a unique topographic map for its social preview. Deterministic, built at no cost per visit, and split so anyone can write their own drawing style. How we designed it, how we proved each step, and all the code.
Three pages of text, side by side, pass through one generator labelled text, numbers, terrain, image, and come out as three different dark brown topographic maps with orange halftone ribbons and no text. Then one line on the middle page is rewritten in orange and marked edited; only the middle map is redrawn as a new landscape and outlined, while the other two are marked unchanged.
Contents
Share any page from this site and the preview shows a map of a landscape that exists nowhere else: hills raised by the page's own most distinctive words, terrain shaped by the rhythm of its sentences, weathering laid down on the day it was last edited. Edit the page, and its landscape changes.
Every preview from one build of this site, 21 pages, 21 landscapes.
Most sites solve link previews with one card for every page, or a template with the title pasted on. We wanted each page to have its own face, made from what the page actually says. Three problems had to be solved: what a preview picture is for, how to turn prose into terrain, and how to make the system something other people can build on. We solved all three in one working session.
What a preview picture is for
We started from what platforms actually show. On Discord and X, the title, description and domain already sit beside the image, and X stamps its own label in the corner. Text baked into the picture repeats the first and collides with the second. So the picture carries no text at all. Its job is to say "this page is its own place" at a glance.
A link preview as a chat or feed shows it: the domain mackenziebowes.com, the post title and two grey description bars sit above a dark brown topographic card. The card arrives with a drafted domain mark on a dark band in its bottom-left corner. The domain text above and the baked-in mark light up orange together as duplicates. An X Article badge drops onto the same corner and covers part of the mark. The band and mark then lift off and fade, leaving only the map with the badge on clean terrain.
The real preview for one research page.
Colour came from the same kind of looking. Nearly every app people scroll through is slightly blue, so a warm brown and orange picture reads as distinct from the interface around it.
Turning prose into terrain
The pipeline has four stages, and only the first and last touch files: acquire the text and edit date, analyze the text into numbers, draw an SVG from the numbers, and rasterize it.
Four boxed stations, left to right: Acquire, Analyze, Synthesize and Rasterize. A page travels through them and each keeps a faded copy of what it made. Acquire holds a page sheet and is cabled to a box labelled files + git. Analyze holds six bars of different heights, and Synthesize a contour map; both sit inside one rounded case labelled plain code: nothing plugged in, with no cables to it. Rasterize holds the finished PNG card, outlined in orange, and is cabled to a box labelled Next.js.
The text becomes six measurements, each from 0 to 1 on a fixed scale, so a page's picture never depends on the rest of the site: how long it is, how varied its vocabulary is, how long its sentences run, how much punctuation it uses, how many long words it has, and how numeric it is. Variety sets how many layers of noise build the land, sentence length sets how broad the landforms are, and punctuation sets how much the terrain twists. The nine most distinctive words each raise a hill, placed by a hash of the word. The edit date adds a finer layer of weathering.
The detail that makes it look printed is the halftone. A dot screen covers the image, and every dot is sized by its distance in pixels to the nearest contour line. The dots trace the paths the terrain takes, so the brightest contours read as ribbons of ink.
A crop of a topographic map with thin contour lines crowded on the steep left side of a hill and spread out on the gentle right. Two brighter index contours are each traced by a band of orange dots on a 45-degree, 11 px screen: dots are largest on the line and shrink with distance, so each band is about the same width in pixels on both sides of the hill. One dot is ringed, with a dashed line to the nearest index contour giving its distance and radius. Below, a strip shows dot radius falling from 5 px at the line to nothing at about 17 px, with the ribbon ending at 22 px.
One page in three styles: lines, halftone, and the mix the site uses.
It's fully deterministic: the same page always gives the same bytes, so platform caches behave. Every image is drawn once at build time, so visitors never wait for one and it costs nothing per visit.
Making it something others can build on
The first version worked and was fitted to one picture. To publish it, we split what describes a page from what draws it. The result is a small plain-JSON description of a page, the seed, which says nothing about how to draw. It holds three independent sources of randomness (one stable across edits, one that changes with any edit, one that changes with the edit day), the facts, the six measurements, the salient words and two profiles along the page.
We proved each step. Before the split, we recorded the exact output of 24 renders. After it, none matched, and a numeric diff traced every difference to one constant: 1/4.4 written as 0.2273. With the exact value, all 24 came back byte-identical.
To prove the seed isn't secretly shaped like terrain, we wrote a second drawing style, stacked ridgelines driven by the sentence-length profile, with no change to the seed at all.
A page goes into an analyzer, which fills one tray called ArtSeed with five compartments: Entropy, Facts, Features, Marks and Series. Below are two machines. The terrain synth is cabled to Entropy, Features and Marks, with its Series socket empty and labelled unused, and prints a topographic map card. The ridgeline synth is cabled to Entropy, Features, Marks and Series, and prints a rough card of stacked orange ridgelines with a tall central spike running off the top and a few bright dots. Facts is wired to neither and marked as only feeding alt text. The words seed unchanged appear at the end.
One seed, two drawing styles. And because one randomness source is stable across edits, an edited page can keep its landscape. The terrain before and after adding a sentence correlates at 1.00, and at 0.91 after adding a paragraph.
Top: a page re-rolled by an edit. Bottom: the same edit with the stable layout. The hills stay, and only the detail is re-surveyed.
How the design moved
| In the first plan | What we decided |
|---|---|
| Tree rings for page age | Cut: the only geometric shape in an organic picture, and nobody could read it |
| A domain mark on the image | Removed after testing real Discord and X previews |
| Teal on near-black | Warm brown and orange |
| Plain contour lines | Halftone ribbons on the main contours, chosen side by side |
Research ran as five parallel passes: generative examples, editorial design, trends, rendering technique and platform behaviour. One lesson from it is worth taking. Ask what's out there, and leave your own choice out of the prompt, or the research will confirm what you already picked.
Two panels, each with five stick-figure researchers holding lamps below a dark field of five spots: a plant, a disc, an empty dashed outline where contour art would be, a wordmark and a bar chart. On the left, titled prompt names our choice, the brief reads about contour art with a circled contour icon, and all five orange beams swing to the empty dashed outline, which holds nothing, while the other four stay dark. On the right, titled the rule we kept: ask what is out there, the brief reads what is out there? and the beams fan out one onto each spot, lighting the plant, disc, wordmark and chart; the beam on the dashed outline is labelled contour: none found.
What this says about how we work
A link preview is the smallest surface a site has, and most people never think about it. We treated it as a design problem worth solving from first principles: we looked at how platforms really show it, built a system instead of a template, proved every step with measurements, and gave the whole method away. That's how we approach every problem a template doesn't fit, whether it's a preview picture or a client's business.
Two panels with the same three pages of text, each page with a few words marked in orange. On the left, titled a template, a rubber stamp presses the same picture, two bars and a dot, onto each page's card: 3 pages, 1 face. On the right, titled a system, each page's orange words fall onto its card and each raises a hill of contour rings where it lands, so the three cards get hills in different places: 3 pages, 3 landscapes.
Take it
All of it is free to copy: the seed format, both drawing styles, the shared tests every style must pass (deterministic output, a response to content and date changes, no crash on an empty seed), and the rules for writing your own style. It's all below.
A seed tray on the left is cabled to three drawing machines: terrain, ridgelines, and a dashed empty one labelled your style. One at a time, each machine prints a card, a contour map, stacked ridgelines and then a grid of dots once the third machine fills in, and slides it through a window in one shared gauge labelled the same tests. As each card clears the gauge, three lamps light above it. All three styles pass the same three tests.
The code (lib/og-art/, 2 October 2026): seed.ts, text.ts, terrain.ts, ridgeline.ts, canvas.ts, source.ts, render.tsx. Between source.ts and render.tsx it is plain TypeScript with no framework.
If you're solving a design problem that the usual template doesn't fit, I'd like to hear about it: mackenzie@mackenziebowes.com or @_mackenziebowes.