Case study
This Portfolio
This very site: a personal portfolio designed and built end-to-end with Claude Code assisting, one real feature at a time.

At a glance
- Role
- Sole designer and developer, built end-to-end with Claude Code assisting
- Status
- Live and actively maintained
- Platform
- Web (responsive, desktop and mobile)
- Tools
- Claude Code · VS Code · Git · GitHub · Vercel
- Tech stack
- Next.js 16 · React 19 · TypeScript · Tailwind CSS v4 · EmailJS · Vercel
Sections
Section 1
The Problem
A portfolio needed to exist: one place showing who Tharindu is, the real projects he's shipped, and a working way for people to actually reach him, built on a real design system instead of a generic template.
Section 2
Approach
Built up in layers, starting with tokens and primitives before any page content existed:
- Turned a supplied color palette and type scale (the Forest and Mint palette, an Inter type ramp) into actual CSS custom properties and Tailwind utilities, not just a reference document.
- Built a small component library first, a Button, NavLink, Navbar, and ThemeToggle, before writing any page content, so every later page reused the same primitives instead of one-off styles.
- Added a manual light/dark toggle on top of the system preference, using a data-theme override and an inline script so the stored theme applies before first paint instead of flashing the default.
- Wired the contact form straight to EmailJS with no backend, since a static portfolio has nowhere to run server code, then confirmed the same setup actually worked once deployed to Vercel, not just in local dev.
Section 3
Real Decisions & Fixes
Part of using an AI coding agent well is checking its claims instead of accepting them. A few examples from this build:
- React's ViewTransition component, documented for this Next.js version, turned out not to exist in the installed stable React build. That got checked with a one-line Node script before any code was written around it, rather than shipping something that would silently do nothing.
- The theme toggle's icon briefly mismatched between server and client, because its initial state read localStorage during render. Fixed by always rendering the same default on both sides and correcting it in a layout effect just before paint.
- Tapping a card or button on a phone left it visually stuck in its hover state until tapping elsewhere. Fixed once, site-wide, by redefining Tailwind's hover variant to require an actual hover-capable pointer.
- EmailJS's service ID, template ID, and public key are safe to keep in the client code itself. The whole integration runs in the browser, so an environment variable would not have hidden them any better; the real safeguard is the allowed-domains list in the EmailJS dashboard.
Section 4
Outcome
A live, responsive portfolio with a real design system, working project case studies with an image carousel, and a working contact form, built with iterative assistance from Claude Code, with the developer checking claims and fixing what it got wrong along the way, rather than accepting output at face value.
Links
More projects

Sri Charge
A design-led EV charging & booking platform for Sri Lanka, built to end the queue.

Kandy 1st Court
A full-stack booking platform for Sri Lanka's first dedicated pickleball court, built end-to-end by directing Claude Code, not by hand-coding or blind-accepting it.

MUNE TASKS
A local-first AI project planner that turns a description into a phased, trackable to-do list in about 20 seconds.

MUNE Splits
A local-first expense splitter that works out who owes whom in the fewest possible payments.