lanecodes.devAvailablefor new projects
lanecodes-dev.tsx

// Development · Web system

lanecodes.dev — Portfolio 2.0

My full-stack portfolio: bilingual website, custom API and admin panel.

A personal portfolio I designed and built from scratch: a Next.js website full of interactive animations, a NestJS API with PostgreSQL and a Vue 3 admin panel to edit all content, in Portuguese and English, without touching code.

lanecodes.dev — Portfolio 2.0
client:
'Projeto pessoal',
category:
'Web system',
role:
'Design, full-stack development, animations, infrastructure and deploy.',
year:
'2026',
stack:
Vue.js 3QuasarReactNext.jsTypeScriptCSS3GSAPScrollTriggerNode.jsNestJSPostgreSQLPrismaFigmaViteGitDockerREST APIsJWT authenticationOpenAPI
mainTSXUTF-8lanecodes.dev
01

The challenge

Building a portfolio that is itself proof of what I can do. Listing projects was not enough: the site had to show original design, animations that tell a story and a real product architecture, with a back-end, a database and an admin panel.

At the same time, everything had to be fast, accessible, easy to maintain and readable for recruiters in Brazil and abroad.

02

The solution

  • Three separate applications: a public website in Next.js 15 + React 19, an API in NestJS 11 + Prisma + PostgreSQL and an admin panel in Vue 3 + Quasar.
  • Single contract: Zod schemas in the API generate the OpenAPI spec, and both front-ends generate their TypeScript types from it.
  • 100% editable content from the admin: profile, projects, services, process, stack, journey, talks, certificates and blog.
  • Static site with on-demand updates: pages generated at build time and regenerated through tag-based revalidation whenever something changes in the admin.
  • Bilingual (PT/EN) with /en routes, typed dictionaries and translated content from the API.
  • Original animations with GSAP, ScrollTrigger and Lenis, each with a reduced-motion version.
  • PDF résumé generated on the server in Portuguese and English, always with current data.
03

Results

A portfolio live at lanecodes.dev that works as a complete product: original design, purposeful animations, editable content in two languages, automatic deploys on every push and a technical foundation that shows, in practice, how I think about front-end, back-end and experience.

Architecture

The system is split into three repositories that talk through a documented REST API.

  • Website (Next.js 15, App Router, React 19): statically generated pages (SSG/ISR), a 1-hour cache and instant tag-based revalidation (home, projects, project:<slug>, posts) whenever the admin saves something.
  • API (NestJS 11): domain modules, Zod validation, JWT authentication (15-minute access token) with a rotating refresh token in an httpOnly cookie, Argon2 password hashing, rate limiting and Swagger docs.
  • Database (PostgreSQL + Prisma 6): 20 tables, versioned migrations and a JSON translations column for English content.
  • Admin (Vue 3 + Quasar + Pinia): sortable content forms, a Tiptap rich-text editor for the blog, image uploads and English fields side by side with Portuguese.
  • Images converted to WebP with Sharp and stored on Cloudflare R2.
  • Contact form with a styled email via Resend and an option to send straight to WhatsApp.

Animations and interactions

Every home section has an animation designed for the story it tells. Scroll-linked scenes use GSAP + ScrollTrigger, entrances and loops use CSS (@keyframes and animation-timeline: view()), and smooth scrolling is handled by Lenis.

  • Terminal preloader: types initializing lanecodes.dev, runs 5 steps with a spinner and ✓, a progress bar, build successful and welcome to my world_; a black and red curtain reveals the hero. It runs once per session and can be skipped with a click or any key.
  • Hero: title lines rise in sequence, a blinking cursor, a spinning globe and a scroll arrow; everything waits while the preloader runs.
  • About: an editorial magazine layout with a headline, drop cap, columns, a duotone portrait and a fan of certificates.
  • Manifesto: a pinned section where red lines rise and the text is "handwritten" with a mask and SVG stroke, synced to scroll (pin).
  • What I do: cards with corner marks that enter as they appear, CSS only (animation-timeline: view()).
  • Process: a serpentine flowchart; a red SVG connector is drawn by scrolling (scrub) and lights up each step, with the "Approved?" decision and animated dashed "adjustments" and "new cycle" loops.
  • 100% responsive: a pinned, scrubbed timeline zooms into the monitor, turns the desktop layout into a phone layout, pulls back to reveal the device and ends with the battery draining at 1% and the screen going dark.
  • Projects: on desktop, an IDE with a folder explorer, tabs and terminal; on mobile, a scroll-snap carousel of code-file style cards.
  • Stack: giant words drifting in the background, cards entering in sequence and an animated dashed rail linking patterns and integrations.
  • Journey: a pinned section where scrolling walks the timeline and fills the red bar. Next to it, a physics badge: an elastic lanyard simulated with XPBD on canvas, a gentle idle sway, and visitors can pull, release and flip it (front and back with a QR code).
  • Talks and blog: talks as tickets, "admission open" tapes running in the background and the latest post as a poster.
  • Fireframe: the Fire + Frame equation slides in from the sides, the flame flickers and the cards spread on hover.
  • Red bridges: every seam between dark sections has a gradient ellipse cut in half, one half in each section, forming a continuous glow down the page.
  • Turn off animations: a header button and a preloader option save the preference, and a <head> script applies html[data-motion='reduced'] before the first paint. The site also respects prefers-reduced-motion.

Performance and accessibility

  • Only `transform` and `opacity` in animations, so they run on the GPU without layout recalculation.
  • Centralized GSAP: ScrollTrigger.config({ ignoreMobileResize: true }) avoids recalculating when the mobile browser bar shows up, and pinned sections keep their progress on resize instead of jumping.
  • Every scene created in `gsap.context()` / `gsap.matchMedia()` and reverted when the component unmounts.
  • WebP and AVIF images with next/image and self-hosted fonts.
  • Optional motion across the site: every animation has a static version.
  • Bilingual SEO: canonical, hreflang (pt-BR, en, x-default), a sitemap with both versions and per-page Open Graph.
  • Tested at 390, 768 and 1440 px, with dedicated mobile layouts where the desktop experience would not make sense.

Infrastructure and deploy

  • Vercel: website and admin, with automatic deploys on every push to main.
  • Render: NestJS API with migrations applied before each deploy (prisma migrate deploy) and a health check.
  • Neon: managed PostgreSQL.
  • Cloudflare: the lanecodes.dev domain, DNS and images on R2, served from media.lanecodes.dev.
  • Resend: contact form emails.
  • GitHub Actions: formatting, type checking and build on every push.
  • PDF résumé generated on demand with @react-pdf/renderer, with fonts and photo embedded so it works in a serverless environment.

Desktop10 screens

Mobile04 screens

next filepaycom.tsx