The site itself

Colophon

Every other page here asks you to take a technical claim on trust. This one you can open in a browser and check.


This site is a small, inspectable example of how I specify and verify a product surface. Its implementation is deliberately simple: eighteen hand-authored HTML files, one 51 KB stylesheet, one 19 KB script with nothing imported into it, and four self-hosted font files. That is the whole supply chain, and every word of it is in view source.

This is not nostalgia, and it is not a position on frameworks. It is that a document whose job is to hold still and be read is the wrong place to spend a build pipeline, a lockfile and a supply chain — and knowing where complexity is worth paying for is most of what I am claiming elsewhere on this site.

IThe constraints it holds itself to

These are written at the top of codex.js as rules rather than as intentions, which is the only reason they survived contact with the rest of the work:

Nothing above the fold waits on an animation

The hero has one signature moment — the sentence arrives in monospace and settles into the display face, which is the footer line made literal. It lasts under a second, and the page is readable throughout it and identical to the no-JS render the moment it ends.

The number in the markup is the true number

Every figure that counts up on scroll reads its target from the markup and animates toward it. There is no separate data value that could drift from the one that ships. Turn JavaScript off and the real numbers are simply there.

Transform and opacity only — never layout, never backdrop-filter

Motion is confined to the two properties the compositor can handle without touching layout or paint. There is a documented budget of three simultaneous glass surfaces, because backdrop-filter is the most expensive thing on the page and the easiest to add a fourth of by accident.

Reduced motion is enforced twice, in CSS and in JS, independently

Not because one of them is unreliable, but because they fail differently. The comment in the stylesheet reads "both truths stated in CSS as well as in JS: if the script ever runs where motion is unwelcome, neither part appears."

Reveals fire once and are never re-triggered

An element that has appeared stays appeared. Scrolling back up a long case study does not replay anything, because the second viewing is navigation, not arrival.

IIWhat that buys, measured

Measured in headless Chromium against the built site
PropertyResultHow
First contentful paint100 msPaint Timing API, median of twenty-one loads, local server
Own payload237 KBHome page: HTML, CSS, JS and the four faces it loads
Third-party payload0 KBNo script, font, style or beacon from any other origin
Runtime dependencies0Nothing imported into codex.js
Horizontal overflow0Ten viewports, 320–2560 px, across all eighteen pages
Broken internal links0 / 417Every internal href and anchor resolved against the filesystem
Accessibility violations0axe-core, all eighteen pages, at 375 px and 1440 px
Renders without JavaScriptFullyAll content, all real figures, settled headline

IIIHow this page was actually made

This is the only page that makes a claim about method, because it is the only place a reader can inspect it directly. The production code this approach also informs belongs to a company and a private repository. So the claim is bounded on purpose: this is how I work with coding agents on this artefact, and nothing larger is being argued from it.

The shape is specification → generation → verification → correction → acceptance, and the reason it is written down is that the shorter version — prompt, output, ship — produces exactly the defects listed in the next section.

What I specify

The rules in section I, plus the ones that govern content: preserve the editorial voice and the visual system; no framework, no build step, no dependency; no fabricated metric and no career claim the record does not carry; audit read-only before modifying anything. The commit history is the evidence that this ordering is real rather than described — archive gate — commit the spec precedes build three concepts, ship none, and text and number gates + before snapshot precedes the work it gates.

What the agent generates

On the most recent pass: a homepage rebuilt around what is being built rather than around an argument about software; two sections renamed and their routes redirected; a new page for the four conversations worth having; a native <details> fold that lets four case studies stay complete without charging every reader six thousand words; attribution lines stating what I owned and what I did not on each project; and one contact address replacing five identities. I did not type most of that. I specified it, and I decided which of it survived.

What the system verifies — not me reading it

axe-core across all eighteen pages at 375 px and 1440 px; a hundred and eighty page-and-viewport combinations checked for horizontal overflow; all 417 internal links and anchors resolved against the filesystem; the no-JS render compared against the scripted one; reduced motion checked in the stylesheet and in the script independently. Those checks return zero every time, and they are the reason I am willing to publish the numbers in section II at all.

They do not always return zero first. On this pass axe found a serious contrast failure on twelve surfaces — a summary label I had dimmed a further 30% with opacity after choosing a colour that passed on its own — and a definition list I had written with the wrong container element. Both are fixed above. Neither would have survived a careful reading; neither was caught by one.

What the loop caught, and who caught it

The distinction matters more than the list. The audit found a homepage sentence claiming this site's essay contained a controlled trial that argued against it when the essay did not; a colophon that counted its own pages as sixteen when there were seventeen; a career sentence contradicted by the record two clicks away; scroll containers no keyboard could reach on a phone; and two font files that had been shipping to nobody for months. What the audit does not establish is who introduced any of them — I have not reconstructed that, and I am not going to guess in my own favour. I corrected the ones that were decisions rather than defects: dropping the analytics rather than gating it, leaving GitHub off because the repositories that matter are private and an empty list is not evidence, refusing to reconstruct a citation I have lost, and refusing to publish a measurement method that was never mine.

What this is not

One static document, eighteen pages, no users and no uptime. It is evidence of a working method on an artefact of that size, and it is not evidence that a production system can be built this way without engineers. The platform in the Vaulth case study needed an engineering constitution, seven blocking CI gates and two audit cycles precisely because the loop described here does not scale on its own.

IVWhere it falls short

A colophon that only lists what went right is marketing. These are open, and they are the same class of thing I would expect to find in anyone else's work:

I now have no idea who reads this. Google Analytics used to load on every page — 165 KB, larger than the HTML, CSS and JavaScript I wrote here put together, and set without asking anyone. That was hard to defend on a site whose flagship case study argues for consent over convenience and whose second product transmits nothing at all. So it is gone, and the content policy now permits no third-party origin at all. The cost is real and I am paying it knowingly: I have no traffic data, no referrer data, and no way to tell whether anyone reaches the end of a case study. If I want that back, it will be something cookieless that I can explain in one sentence — and until then the honest position is that I am flying blind on purpose.

There is no templating, so the head of every page is duplicated eighteen times. That is the honest reason this site shipped for months with no canonical tags and no social preview metadata: the change was mechanical and touched every file, so it kept losing to work that touched one. Renaming two sections on this pass meant rewriting the navigation in eighteen places. A generator would have prevented all of it. The trade is real and I have not settled it.

The oldest case studies still carry all the photographs. Three student projects from 2020–22 hold every screenshot on the site; the four products I would actually want judged are drawn as figures or described in prose. The student galleries are now folded and filed under earlier work, which changes the emphasis without fixing the underlying gap: there are no product screenshots yet, and this page will say so until there are.

VSet in three faces

Cinzel for display, EB Garamond for reading, JetBrains Mono for anything that labels rather than speaks. All three self-hosted, subset to Latin, preloaded, and cached immutably — four files, because EB Garamond ships a roman and an italic.

EB Garamond is served with a size-adjust: 124%, which is a fossil worth admitting to. This design started as two variants, and the other one set Newsreader; EB Garamond's x-height measures 0.804 of Newsreader's at the same size, so the adjustment kept one shared type scale instead of forking every token. Dusk then shipped everywhere, nothing ever set the other variant again, and its two font files sat in the repository being downloaded by nobody until an audit of this page found them. They are gone. The 124% stays, because the scale is now built around the adjusted size rather than the raw one — the correction outlived its reason and became load-bearing, which is the usual way that happens.

The habit comes from somewhere specific: I typeset fiction with the same two faces, and the About page explains why that is either satisfying or a warning sign.

The stack here is a footnote too. What I would want read is which things were made rules, and which were left as intentions.

Home · Work · About

Talk

Building something that should exist? Or want to argue with something here? Open to conversations.

pkrishna@vaulthai.health

Book twenty minutes · Working with me