Working Note: 004N. Indoriya
Series: nikunjindoriya.comAI Engineer · iGPT Agency
Category: Engineering NoteAugust 2026
Status: Living DocumentRev. 2
reader's choice

A Website With Rules

The constraints behind this site, and the mistakes they caught

Nikunj Indoriya  ·  nikunjindoriya@gmail.com

Abstract

This note is about the system you are currently reading. It is a static site with no framework on the client, no tracker, and about 1.3 kilobytes of JavaScript, which switches the theme. That is not the interesting part. The interesting part is that it was built under a handful of hard rules, and the rules turned out to be load-bearing: they forced design decisions I would not have reached by taste, they made one genuine misrepresentation impossible to ship, and in the one place a rule had to bend, bending it in public cost less than quietly abandoning it. Written as an engineering note rather than a tour, because a tour of one's own website is not worth anyone's time.

Status of This Document

A living document, revised as the site changes. Everything described here is running in production at the address in the footer; nothing is aspirational. The decision records this note summarises live in the site's own repository, which is private, so the summaries here are the public version.

1. Why this is worth writing down

A personal website is the most-built and least-documented category of software there is. Everyone makes one; almost nobody writes down why theirs is shaped the way it is, because the honest answer is usually that a template decided.

I had a specific reason to decide deliberately. The rest of this series argues that I work to a set of standards, and standards asserted on a page are worth very little. This site is the one system I have shipped end to end where every decision was mine, which makes it the cheapest available test of whether those standards survive contact with a real build. If they do not hold here, on a project with no deadline, no client and no legacy code, the claim that they hold elsewhere is not worth much.

The site is not evidence because it looks a certain way. It is evidence because it was built under rules that could have been broken quietly, and were not.

2. The shape, and what it rejected

The first decision was the genre. I mocked up five directions with real content in each, because arguing about typography in the abstract is a waste of an afternoon: a literal arXiv preprint, a journal spread, a Tufte-style page with margin notes, an RFC-style plain technical report, and a modern research-article layout.

What shipped is a fusion of two of them. The document furniture is from IETF RFCs: the header block of labelled fields, the numbered sections, the status-of-this-document box, the RFC 2119 keywords in the method section. The typographic register is from arXiv: serif prose, centred title block, an abstract, a real reference list. Prose speaks serif; apparatus speaks monospace. That single split is the whole design system, and once it was stated, most subsequent questions answered themselves.

A photograph was among the last things added, and the interesting part was where it could not go. A portrait above the title converts a technical document into a personal homepage in a single move: nothing about that layout is badly made, and the genre changes anyway. Technical publishing settled this long ago, so the site borrows the settlement. Journals close an article with an author biography, a small photograph beside a short third-person note, after the references; this site does the same at the foot of its first note, which means a reader meets the work before the person. The same photograph is deliberately absent from the CV PDF, because that file travels into hiring processes where photographs are discouraged.

Three of the five were rejected for reasons worth recording. The literal preprint was the most memorable and the most costume: justified serif at length is punishing to read on a phone, and a website pretending to be a PDF is a joke that stops being funny on the second visit. The Tufte layout is beautiful and its margin collapses on mobile, which is where most readers are. The modern research-article layout was the safest and the least distinguishable from every other technical personal site, which is a real cost when the point is to be remembered.

3. One record, two genres

The hardest engineering problem on this site is not the design system. It is that a curriculum vitae has to exist twice, in two genres, and must never disagree with itself.

On the site, the CV is a document in this series: the same header, the same section numbering, the same typography. But a recruiter or an admissions committee does not want a web page. They want a one-page PDF in the format their whole field uses, which they can download, forward and skim in twenty seconds. Those are genuinely different artifacts with different conventions, and the obvious approach, maintaining both, guarantees that one drifts. The drifted one is always the copy someone forwards.

So the content lives once, in a plain data module, and is rendered twice. The site page is generated from it by the same layout as every other note. The PDF is generated by filling a LaTeX template with it and compiling with pdflatex, so the resume is a genuine LaTeX document with real paragraph breaking rather than a web page printed to paper.

src/data/cv.js the record, once Astro layout same as every note LaTeX template pdflatex /cv a note in the series /cv.pdf one page, its own genre hash of the sources: if the committed PDF falls behind, the build fails
Fig. 1 The two renderings cannot disagree about content, because there is only one copy of the content. What differs between them is genre, not record: the resume is one page and drops the site's navigation furniture; the page keeps the series' apparatus.

4. Rules that can fail the build

A rule nobody enforces is a preference. Two of the rules here are enforced by the build refusing to run.

The PDF is a committed binary, which means it can silently fall behind the data it was generated from. So a check hashes the data module and the template and compares that against what was recorded when the PDF was last built. If they differ, the build stops with a message naming the command that fixes it. This blocks deployment, including deployment of unrelated changes, which is an annoyance I accepted deliberately: a wrong CV in someone's inbox is worse than a five-minute delay, and the delay has a one-line fix.

The second is an audit that runs over the built output rather than the source, since the built output is what a reader receives. It resolves every internal link and every same-page anchor, checks that each page has exactly one top-level heading and no skipped heading levels, verifies that every image and inline diagram carries a text alternative, computes the contrast ratio of every colour pair in both themes against the WCAG threshold, and counts the JavaScript. It has caught dead links and a heading-level skip that reading the source would not have revealed.

pages
10 routes, all static, counted at build time
type
198 KB of self-hosted woff2, the largest thing shipped
stylesheet
one file, no preprocessor
javascript
1,318 bytes inline, 0 external, 0 third-party
trackers
none, which is why the number above is exact

5. Where a rule bent

The rule was no client-side JavaScript. It lasted until the first genuinely reasonable request: readers wanted to choose a theme rather than inherit whatever their operating system decided.

There is no honest way to do that without JavaScript. A theme that respects an explicit choice needs to store the choice and apply it before the first paint, and CSS cannot store anything. The options were to refuse the feature, to fake it with a CSS-only trick that loses the setting on the next page, or to bend the rule.

I bent it, and then made the bend visible. The site now carries about 1.3 kilobytes of inline JavaScript, and the colophon at the foot of every page says so in as many words: the only JavaScript on this site switches the theme. That sentence is worth more than the rule was. It converts an unverifiable claim of minimalism into a specific factual one that any reader can check with view-source, and it makes the next feature request expensive in a useful way, since adding a second script would require editing a sentence on every page.

A constraint you have to publicly amend is a constraint you will think carefully before amending again.

This is also why there is no analytics on the site, and why a piece of structured metadata that would have helped search engines was left out: it ships as a second script tag, and the credibility of the sentence in the footer was worth more than the indexing.

6. What the rules caught

Four errors, none of which I would have found by looking harder.

An author list that misrepresented my position

The resume abbreviated long author lists to save space, in the ordinary academic style of naming a few authors and adding et al. The abbreviation kept the first two names and mine. On a paper where I am the eighth author, that reads as third. Nobody would have called it a lie, and it was one: author position is a claim about contribution, and dropping the people between the front of the list and my name inflates it. The rule that the PDF and the page must state the same record made the discrepancy visible the moment they were compared. The abbreviation is gone; both now carry the full list.

119 kilobytes of nothing

The site shipped two font files whose names implied different weights. A checksum showed they were byte-identical: the same variable font, duplicated. Deleting one cut the total payload by nearly a third. Investigating that also settled a question I had been guessing at, by reading the font's internal table directory to confirm it really was a variable font, which means the bold text is drawn from a weight axis rather than synthesised by the browser. On a site whose entire argument is typographic, faux-bold would have been quietly embarrassing.

Ninety-nine em dashes

A reader told me the prose read as machine-written, and pointed at the punctuation. Dense em dash usage is a recognisable tell. There were ninety-nine of them across the source. What made this a rule rather than a one-time edit is that a blind find-and-replace would have flattened the writing: an em dash sometimes introduces a list, sometimes wraps an aside, sometimes joins two sentences that should simply be two sentences. Each one was replaced by hand with the punctuation the sentence actually wanted. The prohibition is now written into the house style, alongside the note that en dashes in numeric ranges stay, because those are correct typography and a different character entirely.

A silent deployment failure that had not happened yet

An early deployment route would have served the site through a system that ignores directories beginning with an underscore, which is exactly where the compiled stylesheet lives. The failure mode is a site that loads with every word intact and no styling at all, which is easy to misdiagnose as a CSS bug. It was caught by reasoning about the platform before trusting it, and fixed with a one-byte marker file. That route was later abandoned for unrelated reasons, but the habit is the point.

7. What it costs

An honest accounting, since a note that only lists wins is an advertisement.

None of these has cost more than the alternative would have. The alternative, for most of them, was finding out later and in public.

stack
Astro, static output, no client framework
type
Source Serif 4 and IBM Plex Mono, self-hosted
resume
LaTeX, compiled locally, committed
hosting
built from a private repository, no public mirror of the source
history
one logical change per commit, no squashing
decisions
recorded before implementation, then summarised here

One thing this note deliberately does not do is quote its own statistics. Counts of commits, notes and decisions are true on the day they are typed and quietly false afterwards, and a document that reports stale numbers about itself has no standing to argue for measurement. What survives above is either a historical fact that cannot change, a property the design enforces, or a figure counted at build time.

Revision History

r22026-08-08the photograph decision recorded in section 2
r12026-08-08first published

Typeset in Source Serif 4 and IBM Plex Mono, self-hosted. Built without a framework. The only JavaScript on this site switches the theme. No tracker, no analytics. Just documents. WN-004 · rev. 2 · 2026-08-08 · nikunjindoriya.com/projects/building-this-site/