How this site is built.

A colophon is the note at the back of a book listing the type, the paper, and the press. This is that note for a website. Every claim on this page is checkable in the source, which is the point: an SEO who says a site should be legible to machines should be willing to show his own.

The Stack.

No framework, no server-side build, no JavaScript required to read a word of it. Sass compiles on my machine, the compiled CSS is committed, and Netlify publishes /public exactly as it lands in the repo. Four pieces, and you can read all of them.

Hand-written HTML

Static pages under /public, one file per route. No templating layer, which means the markup you view-source is the markup I wrote — same way the other builds are put together. If you can read HTML, you can audit the whole site.

Sass

Twenty-one partials under /src/scss, compiled to one minified stylesheet: 38 KB on disk, 7.6 KB over the wire. Deliberately plain — no mixins, no functions, no loops. Theming is CSS custom properties, and the readable version is the Sass, in the repo.

Vanilla JavaScript

/js/main.js holds the theme toggle, the mobile nav, one batched scroll handler, and two IntersectionObservers. No framework, no analytics, no third-party JavaScript — and no content depends on any of it.

Hosting & Delivery

Deployed on Netlify from the public repo. A push publishes the /public directory as committed: there is no server-side build step, because Sass compiles locally and the compiled CSS ships in the commit. Redirects live in /public/_redirects and response headers in /public/_headers, both read straight from the published directory.

The domain is registered at Namecheap with DNS delegated to Netlify DNS, resolving on NS1 infrastructure, with www redirecting to the apex. TLS is a Let's Encrypt certificate covering the apex and wildcard, provisioned and auto-renewed by Netlify. The contact form posts to FormSubmit, which handles the honeypot field and its own CAPTCHA, and returns to a confirmation page at /thank-you.html.

Nothing above is a secret. The registrar, nameservers, and full certificate history are public in RDAP and Certificate Transparency logs. The only redacted fields are personal contact details, which is exactly how it should be.

The Design System.

Every color on this site is a token. Nothing is a loose hex value in a component, which is why a theme switch is a variable swap and not a rewrite. These swatches are painted with the live tokens, and the values beside them are read from the same declarations, so they follow the theme you are in right now.

--first-color Decorative accent. Offset borders, blocks, and rails.
--accent-text Accent for text only. Darker in light mode, lighter in dark, so accent copy clears AA contrast in both.
--title-color Headings and emphasized copy.
--text-color Body copy.
--body-color Page background.
--container-color Chips, section rules, and form fields.
--black-color Hard borders and the footer ground.

The Accent Split

One accent is not enough. A saturated orange that looks right as a four-pixel border fails contrast as body text, so the system carries two: --first-color for anything decorative and --accent-text for anything you read. The split is why accent text passes AA in both themes instead of only one.

Two Typefaces, Two Jobs

Bai Jamjuree carries everything a person reads. JetBrains Mono carries everything that exists in source: file paths, token names, schema keys, and the panels. If it is set in mono on this site, you can go find it.

Images

Cropped, resized, compressed, then converted — Image Resizer, Squoosh, and occasionally cwebp. Every content image ships as WebP, sized to the slot it renders in. The budget is 60 KB for a card and 250 KB for a full-bleed hero, and nothing on the site is over it.

Accessibility.

Tested by hand, not assumed. The automated pass is the floor, not the finish line.

Contrast at the token level

Contrast is handled where the colors are declared rather than patched per component. Both themes are checked separately, because a palette that passes in light can fail inverted.

Keyboard and screen reader

Semantic HTML first, ARIA only where markup runs out. Nav controls are real buttons with aria-expanded, Escape closes the menu and returns focus, and the scrollable schema panels are reachable by keyboard.

The Entity Graph.

Seven pages, one entity. The Person is declared once, on the homepage, with a stable @id. Every other page points at that identifier instead of redescribing me, so a crawler that reads any page resolves to the same node rather than to seven similar-looking strangers. This is the arrangement the schema panels show.

Canonical node, declared on / https://nickpoole.dev/#nick-poole "@type": "Person"
  • / Person · WebSite · WebPage declares the node · #website author → @id
  • /expertise/seo/ WebPage about → @id
  • /portfolio/ CollectionPage author, creator → @id
  • /credentials/ ProfilePage mainEntity → @id
  • /resume/ ProfilePage mainEntity → @id, worksFor
  • /colophon/ AboutPage about → #website
  • /accessibility/ WebPage isPartOf → #website

The second node is the site itself, https://nickpoole.dev/#website, whose author is the Person. Pages that are about the work point at the Person; pages that are about the site, this one included, point at the WebSite. Two identifiers, seven pages, no duplicates.

For Machines.

Three plain-text files at the root, each written for a different reader. All three are public. Go look.

/robots.txt

Crawler instructions

Open to everyone, with the sitemap declared. The confirmation page is kept out of the index with an on-page noindex rather than a Disallow a crawler could never read past.

Read robots.txt
/sitemap.xml

The map

Every indexable page, with a last-modified date that gets updated when the page actually changes. A sitemap whose dates are decorative teaches a crawler to stop trusting them.

Read sitemap.xml
/llms.txt

The one for language models

A short markdown brief for models reading this site: who I am, the key facts, and where each page lives. Written to be read, not crawled around.

Read llms.txt
The argument

The honest case for llms.txt

llms.txt is a September 2024 proposal by Jeremy Howard of Answer.AI: a Markdown file at the domain root pointing language models at your most important content. As of 2026 it has no standards-body backing and no confirmed consumer among the major AI providers. Google's documentation says it has no effect on Search or AI Overviews, and John Mueller has compared it to the keywords meta tag. The data agrees with him. SE Ranking's 300,000-domain study found no correlation between the file and AI citations, and Ahrefs' log analysis found 97 percent of deployed files were never requested by anyone at all.

And yet. The Chrome team shipped an experimental Lighthouse audit that checks for the file, on the theory that browsing agents may use it to navigate sites more cheaply. Even SE Ranking, whose own study found zero effect, concluded it is a low-effort way to prepare for whatever AI indexing becomes. Both positions are currently true, and nobody controls whether agents start reading the file, including the companies saying it doesn't matter.

Mine costs nothing to carry, took twenty minutes to write, and stays accurate because it describes a site I control. The real value was never the file. It is the conversation an organization has while deciding whether to ship one: what do we want machines to know about us, and who owns that answer? Have that conversation now, whatever you decide about the file.

Audit This Site.

Do not take any of this on faith. The tools are free and the site is public.

Structured data

Schema.org validator

Accessibility

WAVE

This Page Describes Itself.

application/ld+json · live in this page's source
{
  "@type": "AboutPage",
  "@id": "…/colophon/#webpage",
  "about": {
    "@id": "https://nickpoole.dev/#website" },
  "author": {
    "@id": "https://nickpoole.dev/#nick-poole" }
}
{
  "@type": "WebSite",
  "@id": "https://nickpoole.dev/#website",
  "author": {
    "@id": "https://nickpoole.dev/#nick-poole" }
}

The page about the site is the one page whose subject is the site. Both nodes above are the same two identifiers drawn in the diagram further up.

Now Go Read the Source.

View the Repo Accessibility Statement