2026-08-24·2 min read

A third site, same grammar

field-notesside-projectsperpeturapantheon

Perpetūra and Pantheon each had a site already, on their own subdomains. Both worked fine on their own. What did not exist was the bare domain. Type lacunaedesigns.com and there was nothing there: no page introducing the studio, nowhere to send someone who has not read either book yet, nowhere to write about the making of them rather than the fiction itself.

So I built the front door. It names both works and links out to them, and it has a journal, a making-of page per book, an about page, and one mailing list instead of two. The pages were the easy part. The real question was where a third site sits next to two that already have a look.

One grammar, three accents

The two book sites read as siblings: dark grounds, warm metal accents, parchment-toned reading text, the same type logic. The hub had to join that family without outranking it, so I built it as a third sibling rather than a parent. All three share the grammar, and each keeps one accent that is only its own. Perpetūra is gold. Pantheon is oxidised brass. The hub takes crimson, on an oxblood-tinted near-black rather than either of the other two grounds.

The rule I would defend is narrower than the palette. Crimson never carries text on dark. It is a mark, a border, a wash, and never the colour a sentence is set in. Readable text on the hub runs in lighter rose steps instead. I did not take that on faith. Pantheon’s theme CSS had already measured the problem: its proof red came out at 2.7 to 1 on its carbon ground, well short of what body copy needs. So the rule is a number, and it holds on the hub even in places where crimson would look right at a glance. Any new pairing gets measured in the browser before it ships.

It also keeps the hub in its place. A loud accent that never speaks for the page cannot compete with the two books it is introducing.

No framework, because the siblings have none

The stack matches on purpose: plain HTML and CSS, no framework, no build step on the host. This site runs on Astro. That one does not, because its neighbours do not, and matching them mattered more than matching this one.

The only tooling is a small Node script with no dependencies. It reads markdown posts with a little frontmatter and turns them into the journal index, a page per post, the homepage’s latest-posts list, and an RSS feed. The generated pages are committed alongside the source, so the host has nothing left to build and serves the folder as it is. The cost is that a forgotten regeneration would ship stale pages, so the script has a --check mode that renders everything fresh, compares it against what is committed, and fails if they differ.