Logo do Evandro.dev.br # Evandro.dev.br — portfólio **Portfólio profissional de Evandro Fonseca Junior: projetos, cases, serviços, currículo e contato por WhatsApp — com hero e notebook 3D progressivos que caem para HTML puro quando o dispositivo não comporta.** ![Next.js](https://img.shields.io/badge/Next.js-16.3.0-informational) ![React](https://img.shields.io/badge/React-19.1.0-informational) ![Node](https://img.shields.io/badge/Node-22.x-informational) [Rotas](#o-que-o-site-entrega) · [Como funciona](#como-funciona) · [Execução local](#execu%C3%A7%C3%A3o-local) · [CI/CD](#cicd)
> [!NOTE] > **Estado do projeto:** em desenvolvimento ativo (último commit: "refine portfolio > showcase, services and quality lab"); o site de produção é `https://evandro.dev.br`, > que é o host declarado em `app/sitemap.ts` e `app/robots.ts`. As ações externas > de SEO/GEO (Search Console, Bing, Cloudflare, CrUX) estão descritas como runbook e > **não executadas** em [`docs/seo-geo-operations.md`](docs/seo-geo-operations.md). > [!IMPORTANT] > **Next.js `16.3.0` é intencional.** A `16.2.11` ainda mantinha três advisories > transitivos de severidade alta; a `16.3.0` foi a menor versão estável da mesma > major que deixou as auditorias atuais sem vulnerabilidades high. Não faça > downgrade sem repetir `pnpm audit`. ## O que o site entrega | Rota | Conteúdo | | --- | --- | | `/` | Homepage com hero, notebook de projetos, perfil, competências, experiência, projetos, modalidades de trabalho e contato | | `/cases` | Índice dos seis cases | | `/cases/nutriscan` | Case NutriScan | | `/cases/twins-lab` | Case Twins Lab | | `/cases/reddit-explorer` | Case Reddit Posts Explorer | | `/cases/sc-plus` | Case SC Plus Aquicultura | | `/cases/gcc-installer` | Case MinGW GCC Installer | | `/cases/as-servicos` | Case AS Serviços | | `/servicos` | Índice dos seis serviços, com explicações de uso e acesso ao detalhamento técnico | | `/servicos/criacao-de-sites` | Criação de sites | | `/servicos/engenharia-de-software` | Sistemas web e aplicativos mobile sob medida | | `/servicos/consultoria-nextjs` | Consultoria Next.js | | `/servicos/tauri-rust` | Aplicativos desktop para Windows e Linux, com compatibilidade definida por projeto | | `/servicos/integracao-hardware-software-iot` | Integração de hardware, software e IoT | | `/servicos/arquitetura-de-software` | Arquitetura de software | | `/curriculo` | Currículo em HTML, com download de `/Profile.pdf` | | `/privacidade` | Página de privacidade e consentimento de analytics | O App Router também gera `/manifest.webmanifest`, `/robots.txt`, `/sitemap.xml`, `/opengraph-image`, `/icon.svg` e `/favicon.ico`. Caminhos desconhecidos usam a página 404 do projeto. Não há API route ativa. As páginas de serviços mantêm escopo, exemplos ilustrativos e etapas visíveis; tecnologias e decisões de implementação ficam em um `
` nativo. Sobre e Contato apontam para `/#about` e `/#contact`, com ajuste de chegada após a definição do layout do notebook. ## Como funciona ```mermaid flowchart LR A["public/portfolio-data.json
+ lib/site-content.ts"] --> B["lib/portfolio-data.ts
loadFeaturedProjects()"] C["data/project-health.json
snapshot versionado"] --> B D["scripts/check-projects.mjs
pnpm check:projects"] -->|rename atômico| C B --> E["app/ — App Router
homepage, cases, serviços"] E --> F["Next.js 16.3.0
build e start (Turbopack)"] ```
Conteúdo e project health O conteúdo principal vem de `public/portfolio-data.json` e `lib/site-content.ts`. A seleção da homepage usa o campo `featured`; o snapshot de disponibilidade não remove cards. Ele apenas controla o estado do CTA de cada demo: disponível, indisponível, desconhecido ou sem demo. Em produção, a renderização só lê o snapshot versionado e não consulta demos externas. Em desenvolvimento, um snapshot ausente ou com mais de 15 minutos é atualizado em memória. A atualização manual opcional é `pnpm check:projects` e grava o arquivo por rename atômico. O contrato completo está em [`docs/project-health.md`](docs/project-health.md).
3D progressivo e movimento reduzido O fundo 3D do hero (Three.js, sem React Three Fiber) só é montado a partir de `1024px`, com ponteiro fino, sem `prefers-reduced-motion: reduce`, sem economia de dados e com placa de vídeo real (WebGL por software mostra o hero estático). A cena monta depois da primeira interação ou com o navegador ocioso, desenha no máximo ~30 quadros por segundo e para quando nada se move. No celular e nos demais casos, o hero é estático e ocupa uma tela. As passagens entre seções e a barra de progresso são CSS (`animation-timeline`); a rolagem suave (Lenis) só existe com ponteiro fino.
Contato e consentimento de analytics O formulário da homepage valida os campos nativos de nome, e-mail, tipo e contexto. Ao enviar, ele abre `wa.me` em uma nova aba com o briefing preenchido; não existe backend de formulário. O rodapé mantém contato direto por e-mail. Google Analytics só é carregado depois de aceite explícito. A decisão fica em `evandro.analytics-consent.v1`; recusar não monta o loader. As preferências permanecem acessíveis e a revogação envia consentimento negado, ativa a flag de desabilitação, remove o loader e expira apenas cookies `_ga`/`_ga_*` acessíveis.
Stack e estrutura | Área | Pacotes usados | | --- | --- | | Aplicação | Next.js 16.3.8, React 19.1.0, React DOM 19.1.0 e TypeScript 5.9.2 | | Estilos | Tailwind CSS 4 | | Movimento | CSS (`animation-timeline`) e Lenis | | 3D | Three.js | | Interface | Lucide React | | Qualidade | Biome, Jest, Testing Library (JSDOM), Playwright e axe-core | Todas as dependências diretas estão fixadas em versões exatas no manifesto; o lockfile é instalado sem atualização implícita. ```text app/ App Router, rotas e componentes da interface lib/ Dados derivados, navegação, JSON-LD e project health public/ Conteúdo JSON, PDF, fontes, imagens e capturas scripts/check-projects.mjs Atualização manual do snapshot de demos data/project-health.json Última observação versionada das demos docs/project-health.md Contrato operacional do snapshot .github/workflows/ci.yml Gate único de integração contínua nixpacks.toml Build e start para Nixpacks ```
## Limitações conhecidas - **Sem backend.** O formulário de contato não grava nada: abre `wa.me` com o briefing preenchido. - **Demos externas podem aparecer como indisponíveis.** O CTA de cada case reflete o último snapshot versionado em `data/project-health.json`, não uma consulta em tempo real (em produção o render não faz fetch externo). - **Sem WebGL em telas pequenas, com ponteiro coarse ou movimento reduzido.** Nesses casos o hero e o notebook entregam a versão HTML. ## Execução local > [!WARNING] > Use **Node.js `22.x`** e **pnpm `9.15.9`** (fixado em `package.json#packageManager`). > A instalação é sempre com `--frozen-lockfile`; o CI e o Nixpacks fazem o mesmo. ```bash corepack pnpm@9.15.9 install --frozen-lockfile corepack pnpm@9.15.9 dev # Next.js com Turbopack corepack pnpm@9.15.9 build # build de produção com Turbopack corepack pnpm@9.15.9 start # serve um build já gerado ``` | Script | Comportamento | | --- | --- | | `pnpm dev` | Inicia o Next.js em desenvolvimento com Turbopack | | `pnpm build` | Gera o build de produção com Turbopack | | `pnpm start` | Serve um build já gerado | | `pnpm lint` | Executa `biome check` | | `pnpm typecheck` | Executa TypeScript sem emitir arquivos | | `pnpm format` | Formata o repositório com Biome | | `pnpm test` | Executa a suíte Jest | | `pnpm test:watch` | Executa Jest em modo watch | | `pnpm check:projects` | Verifica URLs de demonstração e substitui atomicamente `data/project-health.json` | Validação completa, na mesma ordem do CI: ```bash corepack pnpm@9.15.9 install --frozen-lockfile corepack pnpm@9.15.9 lint corepack pnpm@9.15.9 typecheck corepack pnpm@9.15.9 test -- --runInBand corepack pnpm@9.15.9 build corepack pnpm@9.15.9 audit --prod --audit-level=high corepack pnpm@9.15.9 audit --dev --audit-level=high ``` ## CI/CD O workflow único [`.github/workflows/ci.yml`](.github/workflows/ci.yml) roda em cada `push` e `pull_request`, com permissão `contents: read`. No job `verify` (`ubuntu-latest`) ele instala Node 22 e pnpm conforme `packageManager`, restaura o cache do pnpm e executa, nesta ordem: frozen install, lint, typecheck, Jest serial, build e auditorias de produção e desenvolvimento com limite high. O Nixpacks ([`nixpacks.toml`](nixpacks.toml)) usa `nodejs_22`, `pnpm-9_x`, `pnpm install --frozen-lockfile`, `pnpm run build` e `pnpm run start`. Não há etapa de deploy nem secret de CI neste repositório. ## Avisos - As capturas em `public/assets/prints/*.png` foram feitas com Chrome headless a partir de deploys de produção do próprio autor (evandro.dev.br) e aparecem como conteúdo da tela do notebook. Detalhes em [`CREDITS.md`](CREDITS.md).