Dark mode (padrão) · Light mode disponível via toggle no header
Portfólio pessoal de Hayssa Gomes — Fullstack Developer.
Aplicações modernas, responsivas e bem arquitetadas, unindo tecnologia, design e experiência do usuário.
| Seção | Descrição |
|---|---|
| 📌 Sobre | Visão geral do projeto |
| 🗺️ Roadmap | O que já foi feito e próximos passos |
| 🛠️ Tecnologias | Stack utilizada |
| 🏗️ Arquitetura | Organização técnica do projeto |
| 📁 Estrutura | Estrutura de pastas |
| ✨ Funcionalidades | Principais recursos |
| 🎨 Design System | Tokens, cores e padrões visuais |
| 🚀 Getting Started | Como rodar o projeto |
| ⚙️ Variáveis de Ambiente | Configuração do .env |
| 🐳 Docker | Ambiente com containers |
| 📜 Scripts | Comandos disponíveis |
| 🚀 Deploy | Publicação em produção |
| 📄 Licença | Informações de uso |
O PortfolioV2 é um portfólio pessoal desenvolvido para apresentar identidade profissional, habilidades técnicas, projetos e experiência de forma clara, moderna e visualmente marcante.
A proposta do projeto é unir performance, responsividade e uma estética tech refinada, criando uma experiência fluida tanto para quem navega quanto para quem avalia o código por trás da interface.
O projeto foi pensado para:
- Apresentar uma identidade profissional com visual moderno e consistente
- Destacar projetos, habilidades e experiência de forma objetiva e envolvente
- Facilitar deploy em ambientes de produção com Docker e Nginx
- Preservar boas práticas de arquitetura, componentização e organização de código
O visual adota um design system próprio inspirado em terminais, interfaces de código e elementos glassmorphism, com tema dark como padrão, suporte a tema light, transições suaves e foco em uma experiência elegante e responsiva.
- Estrutura base com React 18 + TypeScript 5
- Build e desenvolvimento com Vite 5
- Estilização com Tailwind CSS 3 e design tokens via CSS variables
- Tema dark como padrão, com toggle para light mode
- Persistência do tema escolhido via
localStoragesem flash no reload - Hero Section com headline, badge de status e CTAs
- Console/code card animado com efeito typewriter (hook
useTypewriterCode) - Wordmark como componente React (
Wordmark.tsx) - Main Brand com tagline no footer (
MainBrand.tsx) - Header fixo com navegação suave e destaque de seção ativa (
IntersectionObserver) - Footer com ícones de redes sociais
- Seções: Hero, Sobre, Serviços, Projetos, Experiência, Contato
- Modal de projetos com case study detalhado
- Responsividade mobile-first
- Docker multi-stage: desenvolvimento com hot reload, produção com Nginx
- Variáveis de ambiente via
.env - Suporte a
prefers-reduced-motion - Acessibilidade básica (aria-labels, sr-only, roles semânticos)
- Modal de Download CV com listagem automática de PDFs via Google Drive + Apps Script
- Serviço de dados (
cvService) com cache de sessão e tratamento de erros - Utilitário
formatCvNamepara formatar nomes de arquivos
- Integração com API própria para gerenciamento de projetos
- CMS ou painel administrativo
- Animações avançadas com Framer Motion
- Testes automatizados (Vitest + Testing Library)
- CI/CD com GitHub Actions
- Melhorias de acessibilidade (WCAG AA)
- Internacionalização PT/EN
- Página individual por projeto com URL própria
- Blog com artigos técnicos
- PWA com suporte offline
| Tecnologia | Versão | Uso |
|---|---|---|
| React | 18.3 | Biblioteca principal de UI |
| TypeScript | 5.5 | Tipagem estática e segurança no desenvolvimento |
| Vite | 5.3 | Build tool, HMR e ambiente de desenvolvimento |
| Tailwind CSS | 3.4 | Estilização utilitária com tokens via CSS vars |
| PostCSS | 8.4 | Processamento de CSS |
| Autoprefixer | 10.4 | Compatibilidade cross-browser automatizada |
| Docker | 20+ | Padronização de ambiente dev e produção |
| Nginx (alpine) | latest | Servidor de arquivos estáticos em produção |
| Node.js | 20 LTS | Runtime para desenvolvimento e build |
Fontes utilizadas (via Google Fonts):
| Família | Uso |
|---|---|
| Space Grotesk | Títulos e headlines |
| Plus Jakarta Sans | Textos e parágrafos |
| Inter | Labels, badges e UI compacta |
| Sansation | Wordmark / identidade visual |
O projeto segue uma arquitetura modular e componentizada, organizada em camadas com responsabilidades bem definidas:
Pages / Sections
│
▼
Components (Layout, Brand, UI)
│
▼
Hooks (useTheme, useActiveSection, useTypewriterCode)
│
▼
Services (cvService — fetch + cache de sessão)
│
▼
Data (projetos, serviços, stack, navegação)
│
▼
Styles / Design System (theme.css + globals.css)
Princípios aplicados:
- Separação de responsabilidades — seções, componentes, hooks e dados em camadas independentes
- Componentização — cada elemento visual é um componente reutilizável e isolado
- Design Tokens — cores definidas como variáveis CSS no formato RGB (
rgb(var(--c-primary) / <alpha>)) para suporte completo aos modificadores de opacidade do Tailwind - Hook pattern — lógica de estado e efeitos encapsulada em hooks customizados
- Imutabilidade de dados — arrays e objetos de configuração definidos fora dos componentes
- Baixo acoplamento — componentes não dependem de estado global ou contexto externo
portfolioV2/
├── public/ # Arquivos públicos e estáticos servidos diretamente pelo navegador
│
├── src/
│ ├── app/ # Ponto de entrada da aplicação, providers e configuração global
│ │
│ ├── components/ # Componentes reutilizáveis da interface
│ │ ├── brand/ # Componentes de identidade visual, logo, wordmark e marca principal
│ │ ├── layout/ # Componentes estruturais como Header, Footer, Container e navegação
│ │ └── ui/ # Componentes base e reutilizáveis como botões, cards, badges e headings
│ │
│ ├── config/ # Configurações da aplicação, variáveis de ambiente e constantes globais
│ │
│ ├── data/ # Dados estáticos utilizados nas seções, como projetos, stacks e links
│ │
│ ├── hooks/ # Hooks customizados para lógica reutilizável e comportamentos da interface
│ │
│ ├── services/ # Serviços de dados externos (ex: cvService para buscar CVs no Drive)
│ │
│ ├── utils/ # Funções utilitárias puras (ex: formatCvName)
│ │
│ ├── sections/ # Seções principais da landing page, como Hero, About, Projects e Contact
│ │
│ ├── styles/ # Estilos globais e tokens visuais da aplicação
│ │ ├── theme.css # Tokens de cor para dark e light mode
│ │ └── globals.css # Estilos base, utilitários globais e animações
│ │
│ ├── types/ # Tipos TypeScript compartilhados entre componentes, dados e configurações
│ │
│ ├── main.tsx # Arquivo responsável por renderizar a aplicação no DOM
│ └── vite-env.d.ts # Tipagens globais do Vite
│
├── .env # Variáveis de ambiente utilizadas pela aplicação
├── .env.example # Exemplo de variáveis necessárias para configurar o projeto
├── Dockerfile # Build multi-stage para desenvolvimento, build e produção
├── docker-compose.yml # Orquestração dos containers em ambiente de desenvolvimento
├── nginx.conf # Configuração do Nginx para servir a aplicação em produção
├── tailwind.config.ts # Configuração do Tailwind CSS, tema, tokens e breakpoints
├── vite.config.ts # Configuração do Vite
├── tsconfig.json # Configuração principal do TypeScript
├── package.json # Dependências, scripts e metadados do projeto
└── README.md # Documentação principal do projeto- Headline principal com efeito glitch no hover
- Badge de status animado
SYSTEM.INITIALIZE(DEV_PORTFOLIO) - Parágrafo de apresentação
- Botões CTA para projetos e contato com animações de hover
- Console animado (
CodeConsole) com typewriter effect, syntax highlighting, pausas humanas e loop — inicia preenchido e redigita em ciclo - Barra de tecnologias com grayscale que colore no hover
- Efeito glassmorphism no card do console
Wordmark.tsx— logo compacto no headerMainBrand.tsx— logo completo com tagline no footer- Gradiente de marca em
brand-nameebrand-surnamevia CSS custom properties - Dark mode como padrão, light mode alternativo com transição suave
- Header fixo com
backdrop-blure fundo semi-transparente - Seção ativa destacada via
IntersectionObserver(useActiveSection) - Scroll suave para seções
- Menu mobile com hambúrguer
- Toggle de tema (ícone Material Symbols)
- Cards com thumbnail, stack de tecnologias e links
- Modal com case study completo (problema, solução, desafios, resultados)
- Layout responsivo em grid
- Foto de perfil com scanline overlay e efeito hover
- Stats (anos de exp., projetos, clientes)
- Bio completa com parágrafos descritivos
- Tags de especialização
- CTA para contato
- Botão Download CV — abre modal que lista automaticamente todos os PDFs de uma pasta do Google Drive, sem necessidade de alterar código ao adicionar ou remover arquivos
- Busca os arquivos via Google Apps Script (endpoint público, sem autenticação)
- Cache de sessão: a lista é buscada uma única vez por visita
- Estados: carregando, erro (com retry), vazio, lista de arquivos
- Cada item exibe nome formatado, data de atualização, e botões para visualizar e baixar
- Fecha com
Esc, clique no backdrop ou botão X
- Links para redes sociais (Instagram, LinkedIn, GitHub, X, YouTube, TikTok)
- Formulário de contato
- Footer com copyright e ícones SVG inline
- Dark como padrão
- Persiste em
localStorage - Inline script no
index.htmlprevine flash (FOUC) - Transição suave com classe
.theme-transitioning - Todos os tokens de cor respondem automaticamente
Todas as cores são definidas como variáveis CSS no formato RGB, compatíveis com os modificadores de opacidade do Tailwind (bg-primary/10, text-on-surface/60).
| Token | Dark Mode (RGB) | Light Mode (RGB) | Descrição |
|---|---|---|---|
primary |
199 0 56 |
199 0 56 |
Vermelho/crimson — cor principal |
primary-container |
255 81 103 |
255 81 103 |
Tom mais vibrante do primário |
secondary |
0 219 233 |
0 106 112 |
Ciano/teal — destaque técnico |
tertiary |
195 101 255 |
112 0 168 |
Roxo — detalhes e keywords |
surface |
19 19 19 |
250 247 247 |
Fundo principal |
surface-container |
28 28 28 |
237 230 230 |
Cards e superfícies elevadas |
on-surface |
236 224 224 |
26 21 22 |
Texto sobre fundo |
outline-variant |
80 56 56 |
212 192 192 |
Bordas sutis |
| Papel | Família | Uso |
|---|---|---|
headline |
Space Grotesk | Títulos, h1–h3, números de destaque |
body |
Plus Jakarta Sans | Parágrafos e textos corridos |
label |
Inter | Labels, badges, botões, navegação |
brand |
Sansation | Wordmark (HAYSSA / GOMES) |
mono |
Monospace sistema | Code console, snippets de código |
- Glassmorphism —
backdrop-blur+bg-white/35 dark:bg-black/35+ bordas sutis - Cyber grid — grade de fundo via
background-imagecom CSS vars - Glow effects —
text-shadowebox-shadowcom cor primária - Sombras soft —
shadow-2xl shadow-black/60 - Efeito glitch — duplicação de sombra de texto no hover
- Scanlines — overlay CRT na imagem de perfil
- Animações —
animate-pulse,animate-ping,cursor-blinkpersonalizado - Bordas — raio mínimo por padrão (0.125rem), crescendo até
xl(0.5rem)
- Node.js
>=20 - npm
>=10
# Clone o repositório
git clone https://github.com/issagomesdev/portfolioV2
cd portfolioV2
# Instale as dependências
npm install
# Copie o arquivo de variáveis de ambiente
cp .env.example .envnpm run devAcesse em: http://localhost:3000
A porta pode ser alterada via variável
PORTno.env.
Crie um arquivo .env na raiz do projeto:
# Porta do servidor de desenvolvimento
PORT=3000
# URL da API (para integrações futuras)
VITE_API_URL=http://localhost:3333
# Endpoint do Google Apps Script para listagem de CVs
VITE_CV_ENDPOINT=https://script.google.com/macros/s/SEU_ID_DO_DEPLOY/exec| Variável | Padrão | Descrição |
|---|---|---|
PORT |
3000 |
Porta do servidor Vite e Docker |
VITE_API_URL |
http://localhost:3333 |
URL base da API para requisições frontend |
VITE_CV_ENDPOINT |
— | Endpoint público do Google Apps Script responsável por listar os arquivos PDF da pasta de currículos no Google Drive |
Variáveis com prefixo
VITE_são expostas ao cliente viaimport.meta.env.
O botão Download CV utiliza um endpoint público do Google Apps Script para listar automaticamente os arquivos PDF disponíveis em uma pasta pública do Google Drive.
Essa abordagem evita deixar os links dos currículos fixos no front-end. Sempre que um novo PDF for adicionado, removido ou substituído na pasta do Drive, o modal de seleção de CV será atualizado automaticamente.
- Acesse script.google.com
- Clique em Novo projeto
- Apague o código inicial gerado automaticamente
- Copie o conteúdo do arquivo
script.gs, localizado na raiz deste projeto - Cole o código no editor do Google Apps Script
- Salve o projeto
- Clique em Deploy
- Selecione New deployment
- Em Select type, escolha Web app
- Configure:
- Execute as:
Me - Who has access:
Anyone
- Execute as:
- Clique em Deploy
- Autorize o acesso à sua conta Google
- Copie a URL gerada em Web app URL
A URL gerada será parecida com:
https://script.google.com/macros/s/AKfycbx.../execAdicione essa URL no arquivo .env:
VITE_CV_ENDPOINT=https://script.google.com/macros/s/AKfycbx.../execImportante: o valor de
VITE_CV_ENDPOINTdeve ser a URL do Google Apps Script Web App, não o link direto da pasta do Google Drive.
O arquivo script.gs usa o ID da pasta do Google Drive para listar apenas arquivos PDF e retornar os dados em formato JSON:
[
{
"id": "file-id",
"name": "curriculo_hayssa_fullstack.pdf",
"viewUrl": "https://drive.google.com/file/d/file-id/view",
"downloadUrl": "https://drive.google.com/uc?export=download&id=file-id",
"updatedAt": "2026-06-09T15:00:00.000Z"
}
]O front-end consome esse endpoint para montar o modal de seleção de currículo com opções como:
- Backend Node.js
- Frontend
- Fullstack
- PHP / Laravel
- A pasta do Google Drive precisa estar pública ou acessível pela conta usada no Apps Script.
- O Apps Script deve estar publicado como Web app.
- O endpoint deve permitir acesso para Anyone.
- Apenas arquivos PDF são listados.
- O navegador não deve fazer
fetchdireto para a pasta do Google Drive, pois o Drive bloqueia esse tipo de requisição por CORS.
O projeto possui um Dockerfile multi-stage com três targets: development, builder e production.
docker compose up --build- Usa
node:20-alpine - Monta o diretório local como volume para hot reload
- Hot reload com polling habilitado (
usePolling: true) para compatibilidade com Windows/macOS - Porta configurável via
PORTno.env(padrão:3000)
# Build e execução da imagem de produção
docker build --target production -t portfolioV2 .
docker run -p 80:80 portfolioV2- Stage
builder: compila o projeto comnpm ci && npm run build - Stage
production: copia o/distparanginx:alpine - Servido via Nginx na porta
80 - Configuração personalizada em
nginx.conf
development → node:20-alpine → npm run dev (hot reload)
builder → node:20-alpine → npm run build
production → nginx:alpine → serve /dist
| Script | Descrição |
|---|---|
npm run dev |
Inicia o servidor de desenvolvimento (Vite HMR) |
npm run build |
Type-check + build de produção em /dist |
npm run preview |
Pré-visualiza o build de produção localmente |
npm run type-check |
Valida tipagem TypeScript sem gerar arquivos |
- Acesse o servidor e clone o repositório:
git clone https://github.com/issagomesdev/portfolioV2
cd portfolioV2- Configure as variáveis de ambiente:
cp .env.example .env
nano .env- Gere e suba o container de produção:
docker build --target production -t portfolioV2 .
docker run -d --name portfolio -p 80:80 --restart unless-stopped portfolioV2- Configure o domínio e reverse proxy (Nginx externo ou Caddy):
server {
listen 80;
server_name url.exemple www.url.exemple;
location / {
proxy_pass http://localhost:80;
}
}- Configure SSL com Certbot:
certbot --nginx -d url.exemple -d www.url.exempleO projeto pode ser acessado em: https://url.exemple (substituir pelo domínio real)
- Mobile-first — estilos base para mobile, breakpoints para telas maiores
- Componentização — UI dividida em componentes reutilizáveis e isolados
- Tipagem estrita — TypeScript com
strict: trueenoEmitvalidado no build - Design Tokens — paleta centralizada em variáveis CSS, sem hardcode de cores
- Separação de responsabilidades — dados, lógica e apresentação em camadas distintas
- Hooks customizados — lógica de efeitos encapsulada e testável independentemente
- Ambiente padronizado — Docker garante paridade dev/prod em qualquer máquina
- Sem flash de tema — script inline no
<head>aplica o tema antes da renderização - Acessibilidade —
aria-label,sr-only,aria-hidden, roles semânticos,prefers-reduced-motion - Performance — imagens otimizadas, fontes carregadas via
<link preconnect>, lazy render - Semântica HTML —
<header>,<main>,<section>,<aside>,<footer>,<nav> - Código limpo — sem comentários desnecessários, nomes autodescritivos, sem lógica duplicada
| Projeto | Descrição | Repositório |
|---|---|---|
| Portfolio | Versão anterior do portfólio pessoal, desenvolvida como base inicial da identidade visual, apresentação profissional e estrutura de seções. | Acessar repositório |
| Portfolio API | API criada para servir dados do portfólio, como projetos, tecnologias, informações profissionais e conteúdos dinâmicos para futuras integrações. | Acessar repositório |
Projeto desenvolvido para fins de portfólio, demonstração técnica e evolução profissional.
Feito com foco em performance, usabilidade e código bem estruturado.
Hayssa Gomes · Fullstack Developer
Instagram •
LinkedIn •
GitHub



