Mark DordelGet in touch

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.

  1. RequirementsThe CouncilAgree the quest before anyone sets out
  2. Plan and designRivendellChoose the road and the company
  3. BuildThe Mines of MoriaDo the deep work
  4. TestThe BridgeNothing defective crosses
  5. ReleaseThe Great RiverThe company sets out
  6. 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