Work Case study

This Portfolio

A static site written by hand, with no framework and no build step to speak of.

Live
  • HTML
  • CSS
  • JavaScript (ES modules)
  • Node.js
  • Netlify
Role
Solo, design and build
When
Aug 2026 to Present
Status
huntermshaps.com · revised continuously

01

The Idea

A portfolio is a product with exactly one user story, so it seemed worth building it the way I would build anything else: a design system rather than a stylesheet, content as data rather than as markup, and no dependency I could not justify.

There is no framework here. The pages are generated from the content files by a small Node script that also serves them in development, so the markup a browser receives is the markup in the repository.

02

Design Evolution

Three published versions, all still in the git history.

The current version of the portfolio: the wordmark on the left, an at-a-glance panel on the right listing the current role and degrees, and a line of links to what is currently being built

V3 · 18 August 2026 The rebuild. Content moved into data files, every project got a case-study page, and the hero gained the two facts a recruiter looks for first. The small letter-spaced labels above headings came out.

03

Technical Decisions

The deploy is an allowlist

The build copies a named list of files into dist/ rather than ignoring a list of secrets. Publishing the repository root would put .env and .git on a public CDN; with an allowlist a new asset directory has to be added deliberately.

Why it matters: The failure mode of the safer-looking option is a leaked SMTP credential at /.env.

Content is data, markup is generated

Projects, skills and dates live in content/*.js. The homepage, every case-study page, the timeline and the command palette all read from those files, so a date exists in exactly one place.

Videos are loaded only if you reach them

Each preview is preload="none" and starts on its first intersection, then pauses when it leaves. A visitor who never scrolls to a case study never downloads its video.

The previews were re-encoded, not just compressed

The two demo videos were 42 MB and 52 MB and tracked in Git LFS, which meant a plain clone produced 133-byte pointer files and both previews failed silently. Re-encoded to 1.1 MB and 2.6 MB, audio dropped, and committed directly.