Skip to main content

Project Overview

danhenderson.dev is a client-side React + TypeScript portfolio site. It is a single-page application built for static hosting, with route-level pages for a CV, climbing log, photography galleries, and a public blog.

The site is not a template or a starter kit. It is a purpose-built frontend application with deliberate choices around motion choreography, theme-driven visual consistency, and compositional UI architecture.

What the site does

RouteExperience
/Home page with a faux-VS Code IDE hero — draggable, resizable, expandable — featuring terminal typewriter animation and optional welcome audio
/cvInteractive CV with responsive desktop/mobile layout, GitHub-backed highlights with fallback data, tab/accordion detail panels, and an immersive story mode (?mode=story)
/climbingSearchable climbing log with MUI X DataGrid, fuzzy filtering, and analytics dashboard
/photographyGallery grid with tilt-effect album cards, quilted image layouts, and an immersive full-screen lightbox
/blogEditorial blog with hero cards, tag filtering, code blocks, callouts, and post navigation

What makes the implementation notable

Motion as architecture

The site treats animation as a first-class architectural concern, not a decorative afterthought. A unified motion system provides:

  • Duration, easing, and stagger tokens shared across all animated surfaces
  • Framer Motion variant definitions for consistent entrance, hover, and transition behavior
  • A four-level motion intensity dial (off → subtle → default → expressive) that globally scales all animation timing, tilt effects, and CSS animations — with automatic prefers-reduced-motion override
  • Scroll-triggered viewport reveals using IntersectionObserver, with per-component motion scaling
  • Page-level entrance choreography including a parametric spiral motion path on the home hero

See Motion architecture for full detail.

Theme-driven appearance system

Six named appearance presets (atlas, evergreen, ember, solstice, drift, graphite) each provide complete dichromatic palettes, font stacks, surface treatments, and motion rules. The theme system resolves a preset + palette mode + motion intensity into a single AppResolvedTreatment that every style builder and component reads from theme.appearanceTreatment.

See Theme and styling for the full pipeline.

Compositional UI

Pages compose from a layered set of shared primitives:

PageFrame / BackgroundPaper        ← route scaffold
SectionCard / CVSectionCard ← section surface
SectionHeading ← section intro
AnimatedContentList ← viewport card lists
AnimatedContentCard ← individual reveal with optional tilt
Text ← semantic text
AnimatedSlideList ← controlled repeated-item reveals

Each layer has a defined role and clear ownership. Two intentional subsystems — the Home IDE hero and CV story mode — bypass the default shared design system by design. Blog and photography stay inside the shared text system through prose and overlay contexts.

See Component architecture and the Design system reference.

Repository organization

Key directories

DirectoryResponsibility
src/pages/Route-level page composition — one file per route, declarative assembly of components and hooks
src/components/Shared UI primitives (cards, lists, text, layout) and feature-specific components (cv/, blog/, photography/, ide/, header/)
src/hooks/Data adapters and route helpers — each hook wraps a data module and provides a stable API to pages
src/data/Source-of-truth content modules — CV entries, blog posts, climbing logs, photography metadata
src/motion/Unified animation foundation — tokens, easing, variants, and animated React primitives
src/theme/MUI theme assembly, appearance presets, and TypeScript augmentation
src/styles/Theme-conditioned style maps, Emotion keyframes, and spring easing
src/constants/Build-time stable config — route definitions, command palette actions, feature flags, recovery context
src/types/Centralized data model types shared across data, hooks, components, and pages
src/utils/Pure, framework-agnostic helper functions
test/unit/Jest + React Testing Library — ~125 test files covering providers, hooks, components, pages, and utilities
test/e2e/Playwright — route-level browser specs with mocked GitHub API and route readiness helpers

Stack

ConcernTechnology
FrameworkReact 18
LanguageTypeScript 5.6
RoutingReact Router v6
Component libraryMUI (Material UI) + Emotion
Data tablesMUI X DataGrid
AnimationFramer Motion (via motion/react)
Build toolingVite for dev/build; standalone Jest/ESLint/typecheck tooling
Unit testingJest + React Testing Library
E2E testingPlaywright
CI runtimeNode 20

Further reading