The Concept
The Codex Aurea pretends to be a thirteenth-century bestiary, digitized: four creatures that were reported but never captured, sworn to by witnesses, moralized in the proper bestiary manner, and annotated by generations of disagreeing marginal hands. The fiction is total — Thornmere Abbey, Brother Anselm, the warm folio — and it is carried by craft rather than by claim.
The aesthetic school is medieval manuscript illumination — think the Aberdeen Bestiary or the Luttrell Psalter — translated to the browser with discipline: an aged vellum ground, aged-ink text (#3a3026, never pure black), oxblood rubrics, lapis panels, and gold leaf used the way illuminators actually used it: on initials, halos, and borders, where the light should catch. Blackletter is confined to display sizes; the body is EB Garamond with old-style figures, because a manuscript should be beautiful and readable, in that order of difficulty.
The Techniques
I · The parchment recipe
The vellum is two layers of SVG feTurbulence noise in a fixed, full-viewport overlay, blended with mix-blend-mode: multiply so the fibres darken everything beneath them — text included, which is what makes the ink feel in the page rather than on it. A high-frequency layer (baseFrequency 0.9) makes the fibre; a low-frequency layer (0.004) run through a gamma curve makes the blotchy stains. A CSS radial gradient vignettes the edges, as parchment darkens where hands held it.
<filter id="stains">
<feTurbulence type="fractalNoise"
baseFrequency="0.004 0.007" numOctaves="4" seed="4"/>
<feColorMatrix type="matrix" values="
0 0 0 0 0.38 0 0 0 0 0.27
0 0 0 0 0.12 0 0 0 0.42 0"/>
<feComponentTransfer>
<feFuncA type="gamma" exponent="2.4"/> <!-- blotch, not fog -->
</feComponentTransfer>
</filter>
II · The gilding
Real gilding is laid over gesso — a pale ground — then burnished until it flashes. The initials do the same. Each letter is gradient-clipped text whose gradient begins in gesso-pale and ends in layered golds, with one bright band for the burnish. Scrolling the initial into view adds one class; a single keyframe sweeps background-position from the gesso end to the gold end, so the shine passes across the letter exactly once and stays gold. The vine border draws itself alongside via pathLength="1" and a dash-offset transition. Hover a gilded initial and a screen-blended sheen crosses the whole panel, like tilting gold leaf at a candle.
.initial-letter {
background-image: linear-gradient(105deg,
var(--gesso) 0% 17%, /* underdrawing */
#a8811c 32%, var(--gold) 41%,
#fdf3c0 50%, /* the burnish */
var(--gold) 59%, var(--gold-deep) 71%,
var(--gold) 84%, #e5c95c 100%);
background-size: 340% 100%;
background-clip: text; color: transparent;
}
.gilded .initial-letter { animation: gild 1.8s forwards; }
@keyframes gild { to { background-position: 100% 0; } }
.vine { stroke-dasharray: 1; stroke-dashoffset: 1; } /* pathLength="1" */
.gilded .vine { stroke-dashoffset: 0; transition: 1.7s var(--d); }
Here is one, live — scroll did this; hover it for the sheen:
The S stands for steal this, which is the fourth part of this commentary.
III · The living marginalia
Every gloss in the codex is an <aside> keyed to a phrase by a shared token: the phrase carries data-gloss="vh-1", the note carries data-gloss-for="vh-1". One loop wires hover and keyboard focus in both directions — touch a phrase and its note flushes oxblood; touch a note and the phrase is washed in gold. The notes also ink themselves in when first scrolled into view: opacity plus a clip-path: inset() wipe from the left, so the writing appears in the order a quill would have made it. The doodles (the fox, the manicule, the paw prints) draw in with the same dash-offset trick as the vines.
<span data-gloss="vh-1" tabindex="0"
aria-describedby="gloss-vh-1">…</span>
<aside data-gloss-for="vh-1" id="gloss-vh-1">…</aside>
.gloss { opacity: 0; clip-path: inset(-4% 103% -4% -3%); }
.gloss.inked { opacity: 1; clip-path: inset(-4% -3% -4% -3%); }
Try it here: this very phrase is annotated, and the annotation, in the manner of annotations, disagrees.
IV · The beasts
All four plates are hand-written SVG paths — no image files, no tracing. They are deliberately a little naive, because that is period-accurate: the monk who drew the Aberdeen whale had never seen a whale either. Each plate keeps to the codex palette (ink strokes, one lapis accent, gold only where the story says light), uses short parallel strokes for woodcut hatching, and hides one joke for the patient — the bat in the choir's nets, the ship that sails ahead of the whale, the bitten Q.
V · The discipline
Two typefaces, pushed hard: UnifrakturMaguntia for display only, EB Garamond everywhere else with font-feature-settings: "onum" so the figures sit low and old. Six colors total. Rubrics are red because rubric means red. Paragraphs inside an account run together with oxblood pilcrows, as a scribe saving vellum would have run them. And if the reader prefers reduced motion, the codex simply arrives pre-gilded — finished, as a manuscript is when you open it — rather than stripped of its gold.
How It Was Made
This site was built by Claude (Fable 5) writing vanilla HTML, CSS, and JavaScript by hand — no frameworks, no build step, no image assets; every beast, vine, stain, and thread is markup in the two files you are reading. It is one of twenty-five sites in the Fable Showcase, each in a wildly different visual language; the whole cabinet is at fable-25-dhb.pages.dev.
Steal This
- Texture through multiply, not opacity. A fixed feTurbulence overlay with mix-blend-mode: multiply ages the text along with the background. Texture that sits under the type always reads as wallpaper.
- Animate one property for “material” effects. The entire gilding is a background-position sweep on gradient-clipped text. One property, one keyframe, GPU-cheap, and it ends in its resting state — no cleanup JavaScript.
- pathLength="1" is the drawing cheat code. Set it on any path and dasharray/dashoffset become 0-to-1 fractions — you can choreograph a dozen hand-drawn strokes with one CSS rule and a per-path delay variable.
- Link annotations with data-attributes, both directions. A shared token between phrase and note costs ten lines of JS and makes a page feel inhabited. Add tabindex and aria-describedby and keyboards get it free.
- Treat reduced motion as a different finished state, not an absence. Here it means “the manuscript is already gilded.” Decide what your page has always looked like for that reader, and ship that.