Queria um portfólio que refletisse minha abordagem como desenvolvedor: simples, eficiente e com atenção aos detalhes.
A inspiração
Comecei buscando referências de portfólios minimalistas. Queria algo que fugisse do padrão "template de dev" , nada de gradientes neon ou animações exageradas.
A estética japonesa feudal surgiu naturalmente. Elementos como o Ensō (círculo zen), torii gates e padrões de ondas (seigaiha) trazem essa sensação de precisão e intenção que combina com backend development.
Stack técnica
Next.js 14 (App Router)
Tailwind CSS
Framer Motion
JetBrains Mono
Por que Next.js? SSG para performance, App Router para organização, e é o que uso no dia a dia , portfólio também é demonstração de stack.
Por que Tailwind? Produtividade. Escrever CSS utilitário direto no JSX acelera muito o desenvolvimento de interfaces únicas.
Por que Framer Motion? API declarativa que funciona bem com React. Animações como whileInView e AnimatePresence são triviais de implementar.
O título animado (ou a tentativa)
A ideia original era fazer os kanjis 原田 (Harada) com efeito de "escrita à mão" usando SVG:
<motion.path d={strokePath} initial={{ pathLength: 0 }} animate={{ pathLength: 1 }} transition={{ duration: 0.4, delay: i * 0.15 }} />
Cada traço seria um path animado seguindo a ordem real da caligrafia japonesa. O problema? Desenhar kanji com paths SVG é bem mais difícil do que parece. O resultado ficou... questionável.
No final, voltei pro básico: caracteres de texto com um fade simples. Às vezes a solução mais simples é a certa.
i18n sem biblioteca
Poderia ter usado next-intl ou react-i18next, mas para um site estático com duas línguas, um Context simples resolve:
const LanguageContext = createContext<{ locale: 'pt' | 'en' t: Translations setLocale: (locale: Locale) => void }>()
As traduções ficam em um objeto tipado. TypeScript garante que não esqueço nenhuma string.
Dark/Light mode
Implementado com classe CSS no <html> e variáveis CSS:
:root { --background: #fafafa; --foreground: #0a0a0a; } .dark { --background: #0a0a0a; --foreground: #fafafa; }
Simples, sem flash de conteúdo, persiste no localStorage.
A seção de Notas
Em vez de um blog formal que exige compromisso de publicação regular, optei por "Notas" , posts curtos, sem pressão.
Markdown puro com gray-matter para frontmatter e react-markdown para renderização. Sem CMS, sem banco de dados, só arquivos .md versionados no Git.
O que aprendi
- Menos é mais , cada elemento visual precisa justificar sua existência
- Saber desistir , tentei fazer SVG animado dos kanjis, falhei, voltei pro simples. E tá ótimo.
- Não over-engineer , Context API > biblioteca de i18n para 2 línguas