Under the hood

The portfolio is part of the portfolio.

The decisions behind this site, and the engineering principles it is meant to demonstrate.

01

Content

Typed modules and Markdown in content/

T

Tokens

Colour, spacing, type and motion as CSS variables

02

Routes

App Router pages, prerendered

03

Components

Server by default, client where needed

04

Interactions

SVG, GSAP, CSS motion, palette

  • Testing
  • Accessibility
  • Performance
Testing, accessibility and performance run underneath every layer

Decisions

01 Why SVG for the hero?

The topology is a structured 2D system: seven nodes, their connections and a path out. SVG gives exact geometry, text that scales and stays selectable, and a graphic that works without a rendering stack. GSAP animates the same elements: the intro timeline, a scroll-scrubbed line toward Selected Work and a quiet pointer parallax.

02 Why not Three.js?

Visual complexity alone would not improve the story enough to justify the runtime and maintenance cost. A 3D scene would add a dependency chain, a fallback problem and a mobile cost, for an idea that reads clearly in two dimensions.

03 Why abstract project visuals?

Authentic screenshots were not available, and fabricated interface screenshots would misrepresent the projects. Each graphic is a deliberately abstract diagram drawn from the project's documented subject, generated as SVG on the server.

04 Why file-based content?

The portfolio does not need a CMS. Profile, projects, skills, journey and résumé data are typed TypeScript modules in content/, and Lab notes are Markdown files with frontmatter. Components never contain biography, so a fact is edited in one place.

05 Why is the command palette lazy-loaded?

It is a secondary way to navigate. A tiny loader listens for Ctrl/Cmd+K and imports cmdk only on first use, so no page pays for it up front. Opening it does not shift the layout, and focus returns to the element that opened it.

06 Why reduced motion?

Motion is part of the visual language, but never more important than usability. With prefers-reduced-motion the intro, parallax, magnetic buttons, travelling signal and reveal offsets are removed, and the page keeps its full final composition.

07 Why server components?

Almost every page is static content. Server components are the default, and client components are limited to what needs the browser: the hero, navigation, palette, project index, security pipeline, contact form, filters and scroll helpers. Pages are prerendered at build time.

What it is built with

Framework
Next.js App Router, React, TypeScript (strict)
Styling
CSS design tokens, Tailwind CSS base
Motion
GSAP + ScrollTrigger (hero only), CSS elsewhere
Content
Typed modules, Markdown with frontmatter for Lab
Testing
Vitest, Playwright smoke tests in system Chrome
Hosting
Node, Docker standalone build, health endpoint

Practices

Accessibility

  • Skip link, landmarks and ordered headings
  • Visible focus on every control
  • Menu and palette manage and return focus
  • Roving-tabindex tablist for the security pipeline

Performance

  • Static prerendering
  • No raster images, only SVG
  • GSAP confined to the hero
  • Palette code loaded on first use

Testing

  • Unit tests for content integrity and validation
  • Playwright smoke tests across key flows
  • Lab frontmatter and reading-time logic covered by unit tests

SEO

  • Per-page metadata and canonical URLs
  • Sitemap and robots generated from content
  • JSON-LD for the person, projects and Lab notes