Changelog
What has changed here, in the order it changed. Written mostly so that I remember, and partly because a project that shows its work is easier to trust than one that does not.
A feed, and a way around
There is an RSS feed now. Entries arrive in it whole rather than as a headline and a link, because a feed that makes you click through to read it is one you unsubscribe from.
Every page also links to the others at last. Those links went into the footer rather than the header, which was a decision rather than a default: the header is being kept for the tools, and there will be six of those. Nine pages about the site itself is a footer at any size. Better to make that split before anyone learns where things are than after.
The bug that had no symptoms
Feed entries link to their own heading in the changelog, so the link carries a fragment — the part after the
#. The library that builds the feed tidies up paths by making sure they end in a slash, which is right for a page and wrong for a fragment. It appended the slash to the end of the whole link, inside the fragment, so every entry pointed at a heading that did not exist and every subscriber would have landed at the top of this page instead.Nothing about it looked wrong. The feed was valid, the links were well-formed, and the page they pointed at loaded fine. It was caught by reading the library’s source before trusting it, and there is now a check on every release that fails if a fragment ever ends in a slash again.
That is the second time in two releases that something passed every test it had and was still broken. The first was a set of type definitions that only exist after a build step, so the checks ran against them locally and against nothing at all on a clean checkout — green on my machine, twenty-seven errors in the pipeline. Both were found by trying to prove the thing worked rather than waiting for it to fail.
If you want to follow along without checking back, the feed is here, and how the site is built is on the colophon.
A design system, and the first pages
The site has a look. Warm off-white ground, rust accent, serif headlines, hard rules instead of boxes — the reference is a field guide rather than a dashboard.
Everything visual is defined in one place, as CSS custom properties, so the maps and charts that arrive with the tools can read the same palette instead of keeping their own copy of it:
--color-ivory: oklch(97.8% 0.008 85); --color-ink: oklch(23.5% 0.014 60); --color-rust: oklch(52% 0.14 42);Every foreground and background pairing was computed against the accessibility contrast thresholds rather than judged by eye. Dividers that mean something — the edge of a form field, say — use a darker tone than dividers that are only decoration, because the threshold for the two is genuinely different.
One decision worth recording: the palette block deletes the framework’s default colours outright. Writing
bg-blue-500now produces no style at all rather than quietly working. It is easier to keep a design system coherent when stepping outside it is a visible mistake.What is on the site now
A landing page listing the five planned tools, marked honestly — one is being built and four are not started. A privacy page, which was short to write because nothing is collected. An about page. A colophon. And this.
What is next
The seasonality atlas. It is first because it is the simplest of the five, which means the time goes into the platform rather than into the tool.
The site is live
There is nothing on it yet worth reading, but the part underneath is finished. Infrastructure is defined as code, deployed by a pipeline that holds no long-lived credentials, and every release is checked against the live site before it counts as done.
That last part is the piece I care about. A deploy that reports success is not the same as a system that works, so each release now makes a set of assertions against the running site — that the page loads, that an unknown path serves the real error page rather than a generic one, that
wwwredirects to the apex, that the security headers survived, and that the stylesheet the page references is actually reachable.Every one of those checks was tested against a deliberately broken version first. A check that has never been seen to fail is not a check.