Skip to content
Dara Afraz

dara.pm

This site · Technical spec

Implementation details

Built for readability in code and on screen. The kitchen sink is the sibling playground; this page is the boring-but-useful changelog dressed as prose.

Core stack

  • Next.js 16 (App Router, React Server Components, route handlers, metadata API).
  • React 19 + TypeScript 5.
  • Tailwind CSS v4 with @tailwindcss/typography, @tailwindcss/postcss, and repo-root @import 'tailwindcss' source('..') so utilities resolve when the dev server runs from odd working directories.
  • MDX (@next/mdx, @mdx-js/react) for long-form pages alongside TSX.
  • Dev server pinned to webpack (next dev --webpack / next build --webpack) for predictable MDX + tooling behavior.

Design system & theming

  • Geist and Geist Mono via next/font/google—tight tracking, monospace for meta and code.
  • Layered CSS: design-tokens.css, theme-presets.css, semantic-utilities.css, wired into Tailwind’s @theme bridge.
  • PaletteProvider: multiple curated palettes, separate picks for light and dark, persisted in localStorage, with a tiny inline boot script before paint to reduce theme flash.
  • Header color mode + palette switchers; sticky header with backdrop blur; skip link and focus-visible rings throughout.
  • ThemedPortrait swaps art by color mode—small delight, zero wizardry.

Content, APIs & caching

  • Writing: Substack syndication via RSS (rss-parser), decoded entities, ISR revalidate = 300 so the archive stays fresh without hammering the feed.
  • GitHub page: public repos from the GitHub REST API, filtered and enriched client-side metadata, hourly-style cache via fetch next: { revalidate: 3600 }.
  • Footer widgets: route handlers for Strava (latest activity) and Oura (sleep summary)—live-ish “API as personality” without blocking the main layout.
  • Structured data: JSON-LD for Person + WebSite in the root layout; Open Graph + Twitter cards; per-route metadata and relative alternates.canonical.

Case study UX

  • PageLayout with left sidebar nav and optional right “On this page” rail; mobile TOC patterns on long case studies.
  • CaseStudyExpandableImage: click-to-fullscreen figures, viewport-width lightbox with vertical scroll for tall screenshots, Next/Image with unoptimized where re-encoding would soften crisp exports.
  • Full-screen magnifier (desktop): circular lens, 2×–16× zoom in whole-number steps, scroll-to-zoom over the image, click to toggle magnifier on/off, Escape exits the overlay. (The kind of feature you build when a single PRD screenshot deserves forensic attention.)

Interactive & motion

  • Perpetual Beta: client-side force-directed graph (canvas), concept taxonomy, fullscreen and layout modes—heavy on interaction state, light on dependencies.
  • Kitchen sink: Motion, carousels, comboboxes, layout experiments—living at /this-site/kitchen-sink.
  • Lucide icons, clsx + tailwind-merge for class composition.

Perf, SEO & ops

  • Vercel Analytics + Speed Insights in the root layout.
  • Sitemap (app/sitemap.ts) and robots metadata; middleware 301 from legacy /case-studies paths; /about/experience redirect in next.config.
  • next/image remote patterns for Substack, GitHub Open Graph, avatars; SVG allowed with CSP sandbox where needed.
  • Lighthouse npm scripts (lh:mobile / lh:desktop) for regression checks when pages move.

Local tooling

  • ESLint 9 + eslint-config-next, Prettier + Tailwind class sorting plugin.
  • outputFileTracingRoot pinned so monorepo-ish parent folders don’t confuse serverless traces.
  • App and content live in one repo; environment secrets stay in Vercel (or local .env) for Strava, Oura, and any server-only keys—nothing fancy, just boring hygiene.