Personal ProjectIn Progress

This Portfolio

Project scope: a bilingual engineering portfolio built to grow into a technical blog and personal brand. Context: most portfolios are templates. This one is a product. Status: in active development.

Next.js 15TypeScriptDockerDigitalOcean
View on GitHub
01

The Challenge

Most developer portfolios are either generic templates or visual experiments that sacrifice readability. I wanted something that felt genuinely mine: technically rigorous, bilingual from the start, and with a design language that communicated the way I think. Structured but not sterile. The constraint was also practical: it needed to run on a DigitalOcean droplet with 512MB RAM, meaning no heavy runtime overhead.

02

The Approach

Next.js 15 App Router with full static generation was the foundation. Every page is pre-rendered at build time, so the server only serves static assets at runtime. Tailwind CSS v4 with CSS custom properties gives the design system enough flexibility for the blueprint aesthetic without runtime CSS-in-JS cost. next-intl handles EN/ES routing with server-side translation loading. Docker + Nginx sit in front of everything, and GitHub Actions handles build, test, and deploy on every push to main.

03

What Was Built

The design system is built on a set of CSS custom property tokens, never raw hex values in components. The 'Blueprints Coming to Life' metaphor manifests as a blueprint grid background, technical annotation overlays, gradient text transitions from cyan to coral, and ghost monogram watermarks on section backgrounds. Each page is a thin orchestrator that composes server and client components. Server components handle static markup and translation loading, client components handle animation and interaction. Framer Motion drives scroll reveals with a custom useInView hook tuned to handle scroll-up and reload-at-bottom edge cases.

04

The Outcome

The site is live at bccloudsolutions.dev. Build times are under 30 seconds. The Docker image is lean enough for the 512MB droplet with swap headroom. The EN/ES toggle works correctly across all static paths. The design holds up in both light and dark mode. Each page sprint has followed a spec-driven process. Decisions locked before implementation, no scope creep mid-sprint.

05

What I'd Do Differently

I'd define the full CSS token system before writing any component. I had to retroactively normalize some color usages in early components when the token naming convention solidified mid-sprint. I'd also set up the i18n namespace structure on day one; adding namespaces late meant re-touching components to update import paths. The deployment pipeline is solid, but I'd add a staging environment earlier in the next project to catch build-time errors before they hit production.