Notas
20 de janeiro de 2026·3 min

Como construí este portfólio

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

  1. Menos é mais , cada elemento visual precisa justificar sua existência
  2. Saber desistir , tentei fazer SVG animado dos kanjis, falhei, voltei pro simples. E tá ótimo.
  3. Não over-engineer , Context API > biblioteca de i18n para 2 línguas