A chronological photo & video timeline web application built with Astro, React, and TypeScript over a 6-day span using Claude (Anthropic) as an AI development partner across four iterative sessions. Tammell handled all architecture, design, and project management decisions while using Claude to accelerate component implementation, debug issues, and maintain a living handoff document that preserved context between sessions.
Features
Timeline Feed — Vertically scrolling, chronological feed of photos, videos, text blocks, and milestone cards
Interactive Map — Leaflet.js world map with heart markers, location clustering, and carousel popups
3D Photo Gallery — Three.js WebGL scene with photos arranged in a helical spiral, orbit controls, and lightbox integration
Music Player — Ambient audio with play/pause, skip, scrub bar, and auto-advance
Calendar Navigation — Month/year picker that scrolls the timeline to any date
Fullscreen Lightbox — Image overlay with keyboard navigation, triggered from any photo entry
Tech Stack
| Technology | Role |
|---|---|
| Astro 4.x | Static site generator — pages pre-rendered at build time |
| React 18 | Interactive island components (map, player, lightbox, gallery) |
| TypeScript | Strict mode, Zod schema validation |
| Tailwind CSS | Utility-first styling with custom colour tokens |
| Leaflet.js | Interactive map (CDN-loaded) |
| Three.js | WebGL 3D photo gallery (CDN-loaded) |
| Sharp | Build-time image optimisation (WebP, AVIF, responsive sizes) |
Architecture
Key design decisions:
Islands architecture — React only loads for interactive widgets. The timeline content is plain HTML.
Browser-native inter-component communication — Islands use CustomEvent on window rather than shared state (Redux/Zustand would require a single React tree, defeating the islands pattern).
CDN-loaded heavy libraries — Leaflet (~40KB) and Three.js (~150KB) load on-demand when the user opens the relevant modal, keeping initial page load fast.
JSON content collection — Each timeline entry is a standalone JSON file validated by a Zod schema at build time.
Getting Started
Prerequisites
Node.js 18+
npm
Install & Run
Build
Adding Content
Photos
Export from Photos.app as JPEG
Place in src/assets/images/YYYY/MM/
Create a JSON file in src/content/timeline/:
Videos
Convert to MP4: ffmpeg -i input.MOV -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4
Place in public/videos/YYYY/MM/
Create a JSON file with "type": "video"
Milestones
Any entry type can include a location object to appear on the map.
Deployment
Push to GitHub → connect to Cloudflare Pages → build command: npm run build → output directory: dist. No adapter needed.
Built With Claude
| Session | Focus | Team Role | Claude Role |
|---|---|---|---|
| 1 | Foundation | Defined the tech stack, design direction (valentine theme, gradient, clouds), and data architecture | Implemented the base Astro project, light theme, cloud CSS, floating photos component |
| 2 | Map & Video | Decided on Leaflet for mapping, designed the location schema, planned video support | Built MapViewer with clustering/carousel popups, added video rendering, updated Zod schema |
| 3 | Music | Specified player UX (skip logic, scrub, auto-advance) | Rewrote MusicPlayer with full transport controls |
| 4 | 3D Gallery & Polish | Chose helix layout for 3D gallery, identified and reported the skip-back SVG bug | Built PhotoViewer3D with Three.js, fixed the broken SVG, created handoff documentation |







