How I Built My Portfolio
I rebuilt my portfolio from scratch. It went through about fifteen iterations before landing on something I'm happy with. Here's what I learned.
The Stack
- Next.js 16 with App Router and React 19
- Tailwind CSS 4 with oklch colors
- Motion (Framer Motion) for animations
- Space Grotesk + Inter for typography
- Deployed on Vercel with ISR for GitHub data
The site is a single page with sections that scroll vertically — hero, about, experience, skills, projects, education, and contact. No SPA routing complexity, no page transitions. Just a well-organized scroll.
The Design Problem
The first version was a two-column sidebar layout with shadcn/ui cards. Functional, but it looked like every other developer portfolio built with AI in 2025 — dark background, cyan accent, card-based layout, Inter font. It was a digital resume, not a portfolio.
The goal was to make something that a recruiter would look at and think "this person has taste" rather than "nice template."
What Actually Worked
Two-Color System
Instead of one accent color everywhere, I split into two: cyan for information (section labels, nav dots, skill badges) and warm amber for actions (resume button, email CTA, availability indicator). This creates visual hierarchy — your eye goes to the warm elements because they're different.
Interactive Typography
The name in the hero uses spring-physics character scatter — hover over it and individual letters lift from the cursor position. It's built with Motion's useSpring and a per-character displacement calculation. Small touch, but it immediately communicates "this person builds interactive things."
GitHub Contribution Grid
The hero background has my actual GitHub contribution data rendered as squares with a quadratic vignette fade. Fetched at build time via GitHub's GraphQL API, revalidated daily. The squares align with the background dot grid and fade to transparent near the center so they don't compete with the text.
Magnetic Icons
Social icons and the resume button pull toward the cursor with spring physics — stiffness 200, damping 20. Subtle enough that you might not notice consciously, but the UI feels alive.
The Critique Loop
The most valuable part of the process was running iterative design critiques against UI/UX guidelines. Each round identified specific issues:
- Round 1: "This looks AI-generated" — gradient text, uppercase tracking, generic layout
- Round 2: Removed gradient text, added warm accent color
- Round 3: Removed numbered section labels, removed decorative elements
- Round 4: Added spring physics, magnetic icons, character scatter
- Round 5: Fine-tuned content, verified mobile and light mode
Each critique was honest about what was still template-looking, and each fix was concrete. The key insight: removing AI tells is more impactful than adding features. Deleting the gradient line under my name did more for the design than any animation.
Lessons Learned
The best code is no code at all — this is my bio and it turned out to be true for the portfolio too. Every time I removed a decorative element, the design got better. Section numbers? Removed. Uppercase subtitle? Removed. Gradient line? Removed. Scroll indicator text? Removed.
Spring physics > CSS transitions — the difference between transition-all duration-200 and a spring with stiffness and damping is the difference between a dead interface and a living one. Everything feels physical.
Content matters more than design — I spent hours on animations and hover effects. A recruiter will spend 10 seconds reading the bio and scanning the experience timeline. The interactions create a first impression, but the content is what actually matters.
Ship it — at some point, another round of polish has negative ROI. The portfolio is a tool for getting hired, not a lifelong art project. Ship it, build projects, and let the work speak for itself.