Todo portfólio de dev parece o mesmo: nome centralizado, lista de projetos, um "vamos trabalhar juntos" no fim. Eu queria contar uma história , então fiz meu portfólio viajar no tempo.
A ideia
O site abre como um portal japonês de 2010: denso, colorido, tabelas pra tudo. Aí um botão TIME SKIP faz os anos voarem de 2010 até hoje e te joga num design moderno.
Por quê? Porque conta minha trajetória (comecei a codar lá atrás) e é muito mais memorável do que mais um template minimalista.
2010: o portal
Recriei a estética dos portais da época: layout em <table> de três colunas, nav com gradiente, badges NEW! piscando, marquee, um contador de visitas LCD (recasteado como "commits desde os 13"), banners 88×31 e uns kaomoji (´▽\)`. Tudo em JetBrains Mono, fundo creme com grão diagonal.
Era pra ser não-responsivo (autêntico de 2010), mas no fim cedi: no mobile as três colunas empilham.
A transição
Ao clicar no TIME SKIP, os anos contam 2010 → 2026 sobre "warp lines", e meu rosto (avatar do Notion) entra com scale + rotação e some. Aí um flash branco revela o moderno. Funciona nos dois sentidos , o rewind conta pra trás.
const iv = setInterval(() => { y += forward ? 1 : -1 setYear(y) if (forward ? y >= 2026 : y <= 2010) clearInterval(iv) }, 65)
2026: "o site é um sistema rodando"
O moderno não é "nome + lista". É encenado como um sistema em produção desde 2010:
- bio = histórico de commits (
2013 · git init,2016 · checkout -b cybersecurity,2019 · merge backend → main) - trabalhos = deploys
- skills =
ps -aux(uma árvore alinhada em mono) - contato = "abra um pull request" , a única cena vermelha full-bleed
A tese tipográfica é o contraste: serif (o humano) vs. mono (a máquina). Um backend dev é a ponte entre os dois. Instrument Serif + JetBrains Mono + Inter.
A era persiste
Tem um estado de "era" guardado no localStorage. Default é 2010; se você dá time-skip, fica moderno , e continua moderno ao recarregar. Rewind volta pra 2010. Até as páginas de nota seguem a era: esta nota que você está lendo abre com a moldura da época em que você está.
export function getEra(): Era { if (typeof window === 'undefined') return '2010' return localStorage.getItem('era') === 'modern' ? 'modern' : '2010' }
Detalhes que dão alma
Os stickers (café, PC retrô) ganham uma borda branca "die-cut" empilhando vários drop-shadow em volta da silhueta , vira adesivo de verdade, sem editar o PNG:
filter: drop-shadow(0 -3px 0 #fffdf8) drop-shadow(0 3px 0 #fffdf8) drop-shadow(-3px 0 0 #fffdf8) drop-shadow(3px 0 0 #fffdf8) drop-shadow(0 11px 15px rgba(0,0,0,0.24));
E o DNA compartilhado entre as eras amarra tudo: o mesmo vermelho da marca, o mesmo grão de fundo, os mesmos números 2010→2026.
Stack
Next.js (App Router) · Tailwind CSS · Framer Motion
JetBrains Mono · Instrument Serif · Inter
O que aprendi
- Conceito > template , uma ideia boba ("viajar no tempo") deu mais identidade que qualquer grid minimalista.
- Reusar com intenção , o mesmo rosto é hero, ator da transição e marcador; o mesmo vermelho é o "sinal vivo".
- Hidratação é traiçoeira , ler
localStorageno initializer douseStatenão pega no client; precisei deuseEffect.