Case Study
Personal Portfolio
This site itself: a personal portfolio built with React, TypeScript, and Tailwind CSS that presents each project as a full case study.
- Year
- 2026
- Role
- Designer & Developer
- React
- TypeScript
- Tailwind
- Vite
- React Router
A static portfolio site that puts the work first. Each project has its own case study page with consistent typography, a predictable structure, and nothing flashy getting in the way of the writing. It's a single-page React app written in TypeScript, styled with Tailwind CSS, routed with React Router, and deployed on Cloudflare Pages.
01 · Problem
Most junior developer portfolios lean on heavy animation, generic templates, or one-paragraph blurbs that don't explain the work. I wanted a site that reads more like a case study deck: each project should answer what the problem was, what I built, and what I took away from it.
02 · Features
- Reusable ProjectCard with hover and focus-visible states and a full-card click target
- Dynamic /projects/:slug routes via React Router, with a fallback page for unknown slugs
- Structured case study layout: Overview, Problem, Features, Challenges, What I Learned, Links
- Project content kept in one typed data file, separate from the UI components
- Screenshot galleries with lazy-loaded images and a keyboard-accessible lightbox
- Responsive project grid with one column on narrow screens, up to two on wider screens, and a trailing odd card spanning the full width
- Dark, accessible color palette tuned for long-form reading
03 · Challenges
The trickiest part was making the whole project card clickable while keeping the inline Repo and Live links independently actionable, since nesting <a> tags inside a <Link> isn't valid HTML. I solved it with an absolutely positioned overlay link and lifted the action links above it with z-index, so both targets work without breaking semantics.
04 · What I Learned
- Designing a small system of reusable components before writing any pages kept every later change small and predictable.
- Keeping text width to roughly 65 characters did more for readability than any other typography decision.
- Tailwind v4's marker: variant lets you style list bullets without giving up native <ul> semantics.
- Optional data fields make a content-driven site easier to fill out over time: a case study with missing sections still renders as an intentional page.