Under the hood
This site is part of my portfolio, so here is how it works: the architecture, the trade-offs, the numbers for this very page load, and an open API.
Browser
Next.js 16
Data
Static pages for visitors, server actions for the owner, one repository underneath. Select a component to trace its connections.
Decisions
The choices that shape how the site feels and performs.
Static by default
Every public page is prerendered on the server and revalidated when I publish. Visitors get HTML, not a loading spinner.
One schema per content type
A Zod schema validates admin input, types the site and is exported as JSON Schema to generate the admin forms. Add a field once; it appears everywhere.
No animation library
Motion is CSS, the View Transitions API and one shared IntersectionObserver. Everything respects reduced-motion and pauses off-screen.
JavaScript on a budget
Brand icons render as inline SVG on the server. The palette, terminal and every tool in the toolkit load only when used.
Secure by construction
Admin credentials live only in environment variables as a scrypt hash. Sessions are signed, every server action re-checks them, and login is rate-limited behind strict security headers.
Charts without a chart library
The career timeline, evidence matrix and work overview are server-rendered HTML and CSS computed from the content — no client JavaScript, real tables for screen readers, and they redraw themselves when I publish.
Private by default
No third-party scripts, no cookies for visitors. Page views, tool uses and a few interest signals — a CV download, a saved contact card — are counted as totals server-side, never per person. Global Privacy Control and Do Not Track switch counting off.
This page, measured
Core Web Vitals and transfer sizes from your own browser, right now.
- Time to first byte
- —
- First contentful paint
- —
- Largest contentful paint
- —
- Cumulative layout shift
- —
- Interaction to next paint
- Interact to measure
- JavaScript transferred
- —
- Total transferred
- —
Measured live in your browser for this page load. Development builds are slower than production; numbers are not sent anywhere.
Public API
Everything published here is available as JSON — handy for integrations, or for an LLM that wants to read my portfolio.
GET /api/v1Index of available resources
GET /api/v1/profilePublic profile
GET /api/v1/hireRoles, reasons to hire, FAQ and bios
GET /resume.jsonThe résumé as JSON Resume
GET /api/v1/projectsPublished projects
GET /api/v1/projects?slug=bookodi-desktopOne project by slug
GET /api/v1/technologiesThe stack
GET /api/v1/toolsToolkit metadata
Pick an endpoint to see its response.
Keyboard shortcuts
- Command palette (Ctrl K on Windows/Linux)
- ⌘K
- Search everything
- /
- Open the terminal
- `
- Toggle light / dark theme
- T
- Go home
- GH
- Go to Work
- GW
- Go to the Lab
- GL
- Go to Stack
- GS
- Go to the Toolkit
- GT
- Go to About
- GA
- Go to Contact
- GC
- Hire me — roles, proof and the recruiter kit
- GJ
- Show these shortcuts
- ?
- Close any overlay
- Esc
Colophon
Built with Next.js 16 and React 19 Server Components, TypeScript, Tailwind CSS 4 and Zod, with the React Compiler handling memoisation. Engineered with an AI pair-programmer in the loop; architecture, content and every decision are mine.
Type is set in Hubot Sans and Mona Sans by GitHub, with Martian Mono by Evil Martians for code and Anek Bangla for Bengali. Icons come from Lucide and Simple Icons.
The mark is the hero’s exploded stack in miniature — interface, services and edge. The faint lattice behind the hero is a plain weave, a nod to my research on predicting fabric weight in knitwear.
The dark theme is “night shift” — sodium-amber for anything live, phosphor cyan for anything you can touch, violet for AI. The light theme is a drafting table, not an inverted dark mode. There’s also a toolkit, a command palette, a terminal and at least one secret.