Colophon

The tech stack, design decisions, and integrations that make this site tick.

Framework & Hosting

Astro 5

Static-first framework with islands architecture. Astro components handle server-side rendering, React components hydrate client-side only where interactivity is needed.

React 19

Used for interactive islands — animated icons, GitHub calendar, social links — hydrated via client:idle and client:visible directives.

Netlify

Static output with serverless API routes for Spotify, Discogs, Hardcover, view counting, and password-protected posts.

TypeScript

End-to-end type safety across components, API routes, content schemas, and utility functions.

Content

Astro Content Collections

Four collections — Thoughts, TIL, Projects, Photography — with Zod schemas, Markdown/MDX support, and frontmatter validation.

Shiki

Syntax highlighting with dual themes (Catppuccin Latte for light, Tokyo Night for dark), plus transformers for filename labels, line highlighting, and diff notation.

Custom Rehype Plugins

Sidenotes rendered as margin notes on wide screens, external link indicators, and GFM support via remark-gfm.

Pages CMS

Git-based content management for data files like bookmarks, brain dumps, and networks.

Styling & Design

Tailwind CSS 3

Utility-first CSS with class-based dark mode. Extended via a custom design system token layer built on CSS custom properties.

Design Tokens

CSS variables for colours, shadows, radii, z-index scale, and transition speeds. Every component references tokens, never raw values.

Typography

Literata (serif) for body and headings, system sans-serif for UI elements. Font size accessibility controls for reader preference.

View Transitions

Astro's ClientRouter for smooth page transitions. Dark mode toggle uses a clip-path circle reveal animation from the click point.

Integrations

Spotify

Now-playing widget with marquee text, spinning vinyl disc animation, and idle state. OAuth token refresh handled server-side.

Hardcover

GraphQL-powered reading list with book spines, genres, ratings, and reading progress.

Discogs

Vinyl collection displayed in a scattered, draggable layout with cover art and metadata.

Upstash Redis

View counting for Thoughts and TIL posts with per-session deduplication, stale-while-revalidate caching, and graceful fallback.

GitHub

Contribution calendar on the projects page via react-github-calendar.

Microlink

Auto-generated bookmark preview thumbnails for the curated links collection.

Cloudflare Web Analytics

Privacy-friendly, cookie-free analytics with no pageview limits. No individual visitor tracking.

Interactions & Polish

30+ Animated Icons

SVG React components with hover animations, derived from itshover.com and wrapped in a shared animation controller.

Sound Effects

Web Audio API sounds on interactions — button taps, modal opens, navigation. Off by default with a mute toggle.

Haptic Feedback

Vibration API patterns on mobile for button presses, toggles, and form submissions.

Command Palette

Cmd+K interface for keyboard navigation across all pages and posts, plus g+key shortcuts.

PWA

Installable with offline support via service worker. Save individual posts for offline reading.

OG Images

Dynamic Open Graph image generation via Vercel OG for every blog post.

Performance

Static Output

Pre-rendered HTML with selective hydration. Only interactive islands ship JavaScript to the client.

Asset Compression

Images optimised to AVIF via Astro's image pipeline. CSS and JS compressed at build time.

Prefetching

All routes prefetched on page load for near-instant navigation.

Caching

Build-time API response caching with 5-minute TTL. Redis view counts use stale-while-revalidate headers.

LQIP Blur Placeholders

Photography gallery loads tiny 32px thumbnails with CSS blur as instant placeholders, fading out once the full image loads.