Colophon
How this site was built
This site is a static build with content and layout kept apart, every change checked in CI before it ships, secrets kept out of the repository, and the whole thing reproducible from a git clone. I built it the way I'd want a small production service built.
The whole lifecycle in six waypoints, from one git clone.
- 6
- automated checks on every pull request
- 0
- secrets in the repository, enforced by a scan
- 0
- client-side frameworks
- 2
- fonts, self-hosted under an open license
The kit
- Generator
- Astro 7. Static output with no client framework. Content collections validate every YAML file at build time, so a missing field fails the build instead of shipping.
- Content
- YAML. Roles, stages, skills and copy live in src/content. Updating a role or a number is a one-file commit, and the schema catches mistakes before they ship.
- Layout
- Astro components. Components and pages in src/components and src/pages hold the markup. They read content and never contain copy.
- Styling
- Plain CSS. The design is about seventeen custom properties: colors, fonts and two themes, light and dark. No framework.
- Illustrations
- Inline SVG. The road map and the compass rose are drawn in code, so they scale to any screen and take their colors from the theme.
- Fonts
- Fontsource. Cinzel and EB Garamond are installed from npm and served from the same origin. No third-party font requests.
- Scripts
- TypeScript. Four small modules, bundled by Astro: the road animation, the scrolling trail, the contact form and the print button.
- Contact form
- mailto. The form opens the visitor's email app with the message filled in. There is no server, nothing is stored, and there is no secret to protect.
- Hosting
- Cloudflare Workers. Static assets served from the edge with a 404 page, deployed from CI when a change merges to main.
- CI/CD
- GitHub Actions. Type and content-schema checks, HTML validation, a link check, Playwright with axe accessibility tests, Lighthouse CI and a secret scan. Deploy runs only when all of them pass on main.
- Testing
- Playwright and axe. A series of browser tests runs against the built site on a desktop and a phone profile. They cover accessibility in light and dark mode, navigation, page structure, the contact form, privacy (no third-party requests, cookies or storage) and layout at common screen widths.
- Git hooks
- simple-git-hooks. Before each commit the checks run locally (types, schemas, build, HTML and links). Before each push the full browser suite runs, so most problems are caught before CI sees them.
- Secrets
- GitHub Actions secrets. The Cloudflare token and account ID live only in GitHub's encrypted secrets. The repository holds .env.example with names and no values, and .gitignore blocks env files.
- Tooling
- Node and npm. Node is pinned in .nvmrc and dependencies in package-lock.json. One command sets up a clone: npm ci.
- Upkeep
- Dependabot. Dependencies and GitHub Actions update through pull requests, and CI is the gate.
- Analytics
- None. No cookies, no browser storage, no consent banner.
Decisions
Why Astro and not React
The site has a scroll trail, a form, a print button and one animation. A client framework would be the largest asset on the page and would buy nothing. Astro ships plain HTML and CSS, and it leaves room for an interactive island if that ever changes.
Why content is separate from layout
Copy sits in YAML and structure sits in components. A change to wording never touches markup, a change to layout never touches copy, and a schema stands between the two so a typo can't reach production.
Why the illustrations are code
The road map is SVG, so it stays sharp at any size and picks up its colors from the theme. On a phone it scrolls sideways instead of shrinking into a strip too small to read.
How a change reaches production
Edit a file and commit: the local hook validates it. Push, and the browser tests run before the push leaves the machine. Open a pull request and CI runs the schema check, build, HTML validation, link check, browser and accessibility tests, Lighthouse and the secret scan. Merge to main and the same build deploys.
How secrets stay out of the repository
Nothing the site needs to build or run is secret. The only secrets are the two deploy credentials, and they exist only in GitHub's encrypted store. A scan runs on every pull request to catch anything that slips into a commit.
What I would change at scale
For a multi-author site I would add a CMS on top of the same schemas. For a product I would add an image pipeline and a real design system, and a form service so messages deliver without the visitor's email app.
The road, stage by stage
Why a fantasy journey on a QA site? A release is a quest: many people, one road, and trouble can find it at any stage. QA is the companion who walks the whole way. The map at the top of the home page follows the software development lifecycle from requirements to maintenance, and the "Stage by stage" section gives each waypoint its own scene of work.
- RequirementsThe CouncilAgree the quest before anyone sets out
- Plan and designRivendellChoose the road and the company
- BuildThe Mines of MoriaDo the deep work
- TestThe BridgeNothing defective crosses
- ReleaseThe Great RiverThe company sets out
- MaintainThe WatchKeep the road open
The theme is inspired by a famous fantasy journey. Place names appear as map lettering only. No text, characters or artwork come from the books or films.
Credits
Designed and built with Claude in a chat, over several rounds of direction and revision, then turned into this repository. All content comes from my résumé. The structure is inspired by keithhuster.com. Fonts are by their foundries under the SIL Open Font License.
Updated September 21, 2026
Want to talk about your SDLC?
Get in touch