Paulo Antunes

// pantunes.dev · design system

Design System

Os tokens, a tipografia, os componentes e as decisões de acessibilidade deste site. Tudo aqui é renderizado com a mesma folha de estilo do site, e as cores e razões de contraste são lidas direto dos tokens do código na hora do build, então esta página não fica desatualizada.

Paleta: Monokai · Stack: SCSS + custom properties · Meta: WCAG 2.2 AA

Cores

Uma base Monokai escura: fundos quase pretos e quentes, texto quase branco com cinzas na mesma matiz, e quatro acentos saturados usados com moderação. Verde marca interação e foco, ciano é a ação principal, laranja é informação secundária.

Acentos

  • --accent #a6e22e text, cursor, selection
  • --accent-btn #66d9ef CTA button — Monokai cyan
  • --accent-ink #1a1a1a Backgrounds
  • --green #a6e22e
  • --cyan #66d9ef
  • --orange #fd971f
  • --pink #ff6b9d lightened from Monokai #f92672 to pass AA as text

Fundos

  • --bg-hero #272822
  • --bg-about #20211b
  • --bg-contact #20211b
  • --bg-card #31322b
  • --bg-terminal #1b1a17 Text

Texto

  • --white #fff
  • --ink #f8f8f2
  • --ink-2 #cfcec3
  • --ink-3 #c9c8bd
  • --ink-4 #a8a99c
  • --ink-muted #b1a993 passes AA (4.7:1+) even on the lightest card gradient

Bordas

  • --border #3a3b32
  • --border-2 #41423a
  • --border-hov #5a5b50 Typography

Efeitos

  • --red #f92672 original Monokai pink: error rings and borders only, never text
  • --black #000 shadows, overlays and masks, mixed with transparent
  • --bg-video #020205 behind the hero video while it loads

Janela do terminal

  • --chrome-top #3a3833
  • --chrome-bottom #322f2a
  • --chrome-title #b9b6a8
  • --chrome-ink #d7d6cb text inside terminal-style fields
  • --dot-close #ff5f57
  • --dot-close-ink #511a17
  • --dot-min #febc2e
  • --dot-max #28c840 Borders

Contraste

Cada token de texto contra cada token de fundo, calculado com a fórmula de luminância relativa da WCAG 2.x. AA exige 4,5:1 para texto comum e 3:1 para texto grande (24px, ou 18,7px em negrito). Pares marcados como AA Large só são usados em títulos ou acentos de interface, nunca em texto corrido.

Razão de contraste de cada token de texto (linhas) em cada token de fundo (colunas)
Texto \ Fundo --bg-hero--bg-about--bg-card--bg-terminal
--white Aa 14,86:1 AAA Aa 16,22:1 AAA Aa 12,95:1 AAA Aa 17,40:1 AAA
--ink Aa 13,94:1 AAA Aa 15,22:1 AAA Aa 12,15:1 AAA Aa 16,33:1 AAA
--ink-2 Aa 9,39:1 AAA Aa 10,25:1 AAA Aa 8,18:1 AAA Aa 11,00:1 AAA
--ink-3 Aa 8,83:1 AAA Aa 9,64:1 AAA Aa 7,70:1 AAA Aa 10,34:1 AAA
--ink-4 Aa 6,24:1 AA Aa 6,81:1 AA Aa 5,44:1 AA Aa 7,31:1 AAA
--ink-muted Aa 6,35:1 AA Aa 6,92:1 AA Aa 5,53:1 AA Aa 7,43:1 AAA
--green Aa 9,58:1 AAA Aa 10,46:1 AAA Aa 8,35:1 AAA Aa 11,22:1 AAA
--cyan Aa 9,01:1 AAA Aa 9,84:1 AAA Aa 7,85:1 AAA Aa 10,55:1 AAA
--orange Aa 6,81:1 AA Aa 7,43:1 AAA Aa 5,93:1 AA Aa 7,97:1 AAA
--pink Aa 5,55:1 AA Aa 6,06:1 AA Aa 4,84:1 AA Aa 6,50:1 AA

Pares de componentes

Onde Texto Fundo Razão
Botão principal (CTA) --accent-ink --accent-btn Aa 10,56:1 AAA
Botão de envio --bg-hero --accent Aa 9,58:1 AAA
Seleção de texto --bg-hero --pink Aa 5,55:1 AA
Placeholder de campo --ink-muted --bg-card Aa 5,53:1 AA
Link de pular conteúdo --bg-hero --accent Aa 9,58:1 AAA

Tipografia

Três famílias hospedadas no próprio site. Space Grotesk leva títulos e interface, Hanken Grotesk leva a leitura de textos longos, e Space Mono leva rótulos, código e a voz de terminal. Os tamanhos grandes escalam com clamp().

Display · .hero-headline
Space Grotesk 700 · clamp(2rem, 4.5vw, 3.75rem) · 1.05

20 anos construindo uma web que funciona para todos.

Heading 2 · .about-title
Space Grotesk 700 · clamp(2rem, 3.5vw, 2.5rem) · 1.08

Sobre mim

Heading 3 · .skills-title
Space Grotesk 700 · 22px

O que eu faço

Lead · .hero-sub
Hanken Grotesk 400 · clamp(16px, 1.8vw, 18px) · 1.55

Código, acessibilidade, prazo apertado, cliente exigente — partes diferentes do mesmo ofício.

Body · .about-text
Hanken Grotesk 400 · clamp(14px, 1.65vw, 16.5px) · 1.62

// Em 1999 a web virou meu playground; em 2006, minha profissão. O texto corrido fica perto de 65 caracteres por linha para uma leitura confortável.

Eyebrow · .hero-eyebrow
Space Mono 400 · 13px · 0.08em

// 20 years · web · html · css · js · a11y

Label · .field-label
Space Mono · uppercase

E-MAIL

Espaçamento e layout

O conteúdo fica numa coluna única de 1280px com margem lateral de 20px. Grupos de elementos usam flex ou grid com gap, nunca margens por elemento. O ritmo entre seções é fluido, e mídias largas (o vídeo do hero, a faixa de trabalhos) param em 1520px.

ValorUso
--max-w: 1280pxColuna de conteúdo
--px: 20pxMargem lateral em qualquer largura
1520pxLargura máxima de mídias de ponta a ponta
clamp(50px, 10vw, 100px)Espaçamento vertical das seções
gap: 16px · 24px · 80pxCards · pilhas · layouts em duas colunas
radius: 3px · 4px · 8px · 10pxCampos e etiquetas · cards e selos · CTA · janela do terminal
500 · 560 · 700 · 860pxBreakpoints: hero compacto · grid de skills recolhe · hero empilha e menu some · sobre empilha

Componentes

Componentes reais, com as classes do site. Passe o mouse ou use o Tab para ver os estados de foco.

Botões

.btn-cta · .btn-submit · .btn-submit:disabled — altura mínima de 44px

Selos, etiquetas e controles pequenos

Clientes próprios front-end EN

.agent-chip · .exp-tag · .client-role · .site-nav-lang · .clients-toggle

Campos de formulário

Informe um e-mail válido.

.form-group · .field-label · [aria-invalid="true"] + .field-hint — os erros são anunciados com role="alert" no envio

Cards

.skill-card · .client-card.is-own · .client-card.is-taoti — a origem aparece em texto, não só pela cor

Terminal

.modal-box · .sh-bar · .sh-line + .sh-g .sh-c .sh-o .sh-d .sh-w — role="dialog", aria-modal, Esc fecha e o foco volta ao botão que abriu

Movimento

O movimento é curto, com desaceleração, e ligado a um momento: o título se digita quando a seção chega, o conteúdo sobe para o lugar, e só duas coisas ficam em loop. Toda animação tem uma versão para movimento reduzido.

PadrãoTempoMovimento reduzido
Digitação de título30–50ms / char (hero) · 55–85ms (sections)Texto inteiro de uma vez
Revealopacity + translateY(8px) · .5s ease · 150–300ms staggerTudo visível ao carregar
Elevação no hovertranslateY(-5px) · .22sSem elevação
Cursor piscando1.1s step-end ∞—
Pulso do agent-ready2s ease-out ∞Anel parado
Faixa de trabalhos60s linear ∞Começa pausada; botão de pausa sempre presente
Easing--ease-out: cubic-bezier(0.25, 1, 0.5, 1)—

Acessibilidade

Acessibilidade faz parte do sistema, não é uma revisão no fim. Estas são as regras que todo componente segue.

  • 1.4.3Texto corrido atinge 4,5:1 sobre o fundo. A matriz de contraste acima é a referência.
  • 1.4.1A cor nunca carrega significado sozinha: origem dos cards, erros de formulário e campos obrigatórios também aparecem em texto.
  • 2.4.7Todo elemento interativo tem anel de foco visível, de 2px, na cor de destaque do contexto.
  • 2.4.11Elementos em foco nunca ficam escondidos: a faixa de trabalhos para e rola até mostrar o card focado.
  • 2.2.2Tudo que se move sozinho por mais de 5 segundos pode ser pausado, e a escolha fica salva.
  • 2.3.3prefers-reduced-motion é respeitado por toda animação.
  • 2.5.8Controles principais têm pelo menos 44px de altura; controles pequenos, pelo menos 32px.
  • 4.1.2Elementos nativos primeiro: botões, links, labels e listas de verdade; ARIA só onde o HTML não tem equivalente.

Como é feito

A stack por trás deste site, pequena de propósito.

Páginas
Templates PHP renderizados como HTML estático no build, em inglês e português.
Estilos
SCSS com CSS custom properties. Os mesmos tokens alimentam esta página.
JavaScript
JavaScript puro, empacotado com webpack. Sem framework.
Hospedagem
Vercel, com deploy a cada push no GitHub e um preview para cada branch.
Funções
O formulário de contato e o servidor MCP rodam como Vercel Functions.
Para agentes
llms.txt, resume.json, AGENTS.md e um servidor MCP em /api/mcp.
Segurança
Content Security Policy estrita, sem scripts inline, endpoints de formulário só para o próprio site e limites de envio.
Acessibilidade
Auditado com axe-core segundo a WCAG 2.2 AA, com o contraste sobre degradês verificado à mão.
Ferramentas
Construído com o Claude Code como par de programação.