Skip to content
My Website

My Website

The site you're on - built research-first, fully static, and mine end to end.

2026Live

I wanted a place to put everything - the photographs, the projects, the random stuff I've built or at least tried to. Less portfolio, more library. This is the site you're reading it on.

It was the complete opposite of how I built Stride. That one grew on vibes; this one I planned. I had a clear vision of how things should look and was already hosting an earlier version on 22slides.com - so the job was to rebuild it properly and own every part of it.

The first thing committed wasn't code - it was deep research: what stack made sense in 2026, what a photography-plus-project portfolio actually needs, and what it deliberately shouldn't have. Out of that came a roadmap of five phases, ordered by hard dependencies, with the landing page nearly last because it's a composition of everything else.

deveshksd.com
207commits
5planned phases
3fonts
8fix batches
1unplanned museum
01

Built around the photographs

Every layout decision deferred to the images. Full-bleed heroes, a nav left floating and transparent over them, and one warm paper background on every page so a photograph never has to fight the interface for attention. No dark mode, by design - a photo deserves to sit on the same surface every time you look at it.

Snowdonia, Wales - the kind of frame the whole site is built to get out of the way of.

Beer, on the Jurassic Coast - from the Uncharted Canvas collection.

02

Room for the unplanned

The Museum of Curiosities was never on the roadmap. It appeared one exhibit at a time - the home for everything that didn't fit a collection or a case study. The site is a bit all over the place on purpose, and this is where that shows.

03

Built by an engineer who makes pictures

By day the work is aerospace systems; the photographs are the other half. This is the first place both live together - the systems thinking shows up in the static architecture and the typed content model, the pictures in nearly every full-bleed frame. A personal home more than a portfolio.

Bristol harbourside - from the Bristol collection.

Process

Five phases, ordered by dependency

01
FoundationDesign tokens, Spectral + Jost, the site shell, shared primitives.
April
02
Photography pipelineCollections, masonry galleries, the lightbox, blur-up placeholders.
April
03
Projects pipelineCustom components and the Stride write-up.
April
04
Landing + AboutThe assembly phase - hero slideshow, scroll reveals, portrait, bio.
April
05
Polish + launchSEO, OG images, sitemap, CLI content tooling, deployment.
April
Museum of CuriositiesNever on the roadmap. Appeared anyway, one exhibit at a time.
Unplanned
Detours

The font saga and other fights

The plan said Cormorant Garamond. The site shipped briefly with Playfair Display and Raleway (classic AI bias). It runs today on Spectral and Jost. Each swap happened because the type looked right in a spec and wrong on a full-bleed photograph - editorial serifs are moody like that. There's even a commit titled "correct stale font comments" because the CSS couldn't keep up.

Cormorant GaramondThe plan. Elegant in the spec, too delicate once it sat over a full-bleed photograph.
the plan
Playfair Display + RalewayShipped, briefly. The classic AI-default pairing - it had to go.
shipped, briefly
Spectral + JostThe keepers. A moody editorial serif for display, a clean grotesque for body.
kept ✓

The nav was the longest-running fight: a transparent bar floating over photography looks great over a dark hero and vanishes over a white page. It took five attempts - backdrop blur, a CSS filter hack, mix-blend-mode, currentColor SVG, and finally a gradient vignette with route-aware dark mode. "Floating transparent nav" is a one-line design decision.

The landing hero went through its own evolution - static image, then scroll animation, then a slow random slideshow with a blur crossfade. The randomness introduced the site's best bug: shuffling with Math.random() during render meant the server and the browser disagreed about which photo came first - a hydration error, a visible swap on the most important page, and massive flickering. React doesn't care that your randomness was artistic.

Reckoning

The audit

Two months in, with the site live, I ran a full Fable 5.0 review across four tracks - design, performance, security, and code quality. It produced a score and, more usefully, a ranked list of every sharp edge.

8.5
Design & app code
Design system, polish, and application code all scored highest.
8.0
Perf & security
Fast static delivery; a few headers and edges left to tighten.
7.5
Privacy & SEO
Solid, with metadata and consent decisions worth revisiting.
8
fix batches
Bugs, a11y, script hardening, a dependency purge, then SEO - over two days.

The fixes went out as eight focused batches over two days: visible bugs first, then accessibility, then script hardening, then a dependency purge that removed an entire animation library (GSAP came along for one experiment and never left), and finally SEO and cleanup. The very last commit of the build deleted the privacy policy page - I'd built the full consent machinery for analytics, then accepted that a personal photo site doesn't need to act as a SaaS product.

Behind the Build

Key Technical Decisions

  • Next.js 16, fully static: App Router, React 19, strict TypeScript. Every route is pre-rendered; unknown paths 404 at the edge.
  • Typed files as the CMS: collections are TypeScript arrays, case studies are MDX. The whole "backend" is basically a folder of content files.
  • ImageKit + a 30-line custom loader: one master upload, with thumbnails, heroes, and OG images as URL parameters and blur-ups server-rendered.
  • Motion in thin client wrappers so pages stay server components - the site animates everywhere but ships very little JS.
  • Anti-features, decided in writing: no dark mode, no contact form (it's a mailto: link), no loading spinners, no carousels. A photograph deserves to sit still while you look at it.
For the road

What I'd tell you if you're building one

  1. 01
    Weighted decisions before building anything.

    You won't build a skyscraper on unstable ground.

  2. 02
    Static is a superpower for content sites.

    No servers, no cold starts, nothing to patch at 2am.

  3. 03
    Your content model is your CMS.

    Typed files plus small scripts go a very long way for a single author.

  4. 04
    Decide what you won't build, in writing.

    The anti-feature list killed more scope creep than any amount of what to add.

  5. 05
    Always audit your own site.

    The scored review found real bugs that went under the radar.

  6. 06
    Leave room for the Museum.

    The unplanned section turned out to be the most personal part of the site.

The site is a bit all over the place, which is fine for me. And honestly, so was the process.

deveshksd.com · built April – June 2026 · Next.js · MDX · ImageKit · Motion