An animated banner, generated.
scripts/make_banner.py renders the hero banner as WebP and GIF, plus a static PNG that reduced-motion visitors get instead. Edit the script to change the scene.
A minimal, fast, accessible, SEO-first developer portfolio — projects, case studies, a blog and a résumé, from one data file and two JSON files.
Built with Next.js App Router, Tailwind CSS v4 and Framer Motion. Fully static, no backend. The home page holds about, filterable projects, experience, tech stack and your GitHub activity. Around it: /work/[slug] case studies, a /blog and a printable /resume.
All / Web / Mobile / Desktop / Tooling filters, featured flags, LIVE / WIP / PRIVATE status, tags, live and repo links, and an optional case-study link. Try the live port below.
lib/data.ts → homeLong-form write-ups in content/work.json, rendered with the same block system as the blog. Three samples ship: Northwind Dashboard, Pocket Budget and Plainfile CLI.
/work/[slug]Posts with per-post Open Graph images and an RSS feed. npm run validate catches broken internal links, missing images and duplicate slugs before you deploy.
content/blog.jsonSearches sections, case studies, posts and your links. Keyboard-operable and escapable, and it returns focus where it was. Press ⌘K / Ctrl+K on this page.
keyboard-firstDark and light themes. The choice is saved, and a tiny inline script applies it before first paint, so a light theme never flashes dark.
pre-paint scriptA /resume page generated from the same data as the home page. Print it from the browser, or run npm run resume to regenerate public/resume.pdf.
/resumeThe template's signature details, sketched live in your browser. Drag or scroll sideways to travel through them.
scripts/make_banner.py renders the hero banner as WebP and GIF, plus a static PNG that reduced-motion visitors get instead. Edit the script to change the scene.
One canvas draws a pixel trail, click sparks and camera-style brackets that lerp to the cursor and snap to links and buttons. Fine pointers only.
Set profile.githubUser and the home page shows your last year of contributions. It's the only outside origin the CSP allows.
With prefers-reduced-motion set, the banner turns static and the cursor effects never start. Nothing important depends on animation.
make_brand_assets.py "Name" "Role" "domain" rebuilds them from your avatar, so shared links look like you, not like the template.

app/icon.png · app/apple-icon.png · app/opengraph-image.pngBlocks are h2 h3 p ul ol quote code img table. Inline: **bold** *italic* `code` [links]. One validator, one checklist, and a static export or a Node build.
lib/data.ts — name, role, bio, links, projects, experience, stack/resumecontent/work.json — case studies with slug, title, date, cover, blocks/work/[slug] pages with BreadcrumbList and TechArticle JSON-LDcontent/blog.json — posts in the same block format/blog, per-post Open Graph images and RSS at /feed.xmlpublic/img/ — avatar, banner and project coversmake_sample_assets.py · make_banner.py · optimize_images.pyEvery page gets metadata, a canonical URL and structured data. Crawlers, feed readers and LLMs all get a file made for them. And it works with a keyboard alone.
Person · WebSite · ProfilePage TechArticle · BlogPosting · Blog BreadcrumbList — escaped, per route. Open Graph + Twitter cards, generated per post, canonical URLs, sitemap.xml, robots.txt, RSS, llms.txt + llms-full.txt.
Security headers + strict CSP on Node hosts, no third-party scripts, X-Powered-By removed. a11y: skip link, landmarks, AA contrast, visible focus, keyboard palette and filters. CI: lint → typecheck → validate → build → audit.
The template's palette lists sections, links, the résumé, every case study and every post. This page has a working miniature with the sample content — open it with the button or ⌘K / Ctrl+K, type to filter, ↵ to jump.
indexes: sections · links · /resume · /work/* · /blog/*
Saved to localStorage, applied before first paint.
A launch film of the sample site: the live build, the theme toggle, the ⌘K palette and the mobile layout. Pick a chapter to jump to it.
The title lands while the focus reticle from the template locks on.
The three-word thesis, over the same pixel cursor trail the template ships.
Footage of the sample site: projects, a case study and the blog.
A real click on the theme toggle.
A live ⌘K search across sections, case studies and posts.
The responsive layout, captured on mobile.
Where to get it.
The template ships with neutral sample content — Alex Morgan, a fictional full-stack developer — so your copy starts clean. Click Use this template, work through the checklist, deploy.
lib/data.tscontent/work.json · content/blog.jsonpublic/img/make_brand_assets.py "Name" "Role" "domain"NEXT_PUBLIC_SITE_URL · lib/site.tsnpm run resumemake_banner.pyLead a small team building customer-facing web products, from architecture and APIs to CI/CD and performance budgets.
Built and shipped internal tools and a public dashboard used by thousands of people every week.
TypeScript · JavaScript · Python · SQL
React · Next.js · Tailwind CSS · Framer Motion
Node.js · PostgreSQL · Redis · GraphQL · REST
Docker · GitHub Actions · Vercel · Netlify
Git · Figma · Playwright · Vitest