Princípios de design para engenheiros de software
Fundamentos de design para engenheiros de software: tipografia, cores, espaçamento, animação, padrões de interface com IA, design tokens e 48 estudos de caso de produtos atuais.
Atualizado em 18 de maio de 2026
Atualização de 18 de maio de 2026: Atualizou o índice de Estudos de Design para corresponder ao corpus atual de 48 estudos e ampliou os Padrões de Interface de IA com evidências de fluxos de trabalho com agentes: checkpoints, estados de aprovação, confiança nas fontes e verificação visível.
Atualização de maio de 2026: Adicionou uma observação sobre o rascunho de trabalho de março de 2026 do WCAG 3.0 e a posição do W3C de que o WCAG 2.2 e o 3.0 vão coexistir. O WCAG 2.2 continua sendo o padrão a seguir para trabalhos atuais de acessibilidade.
Atualização de fevereiro de 2026: Adicionou duas novas seções — Padrões de Interação (8 paradigmas a partir do estudo de Framer, Flighty, Halide, Warp, Bear, Craft e Superhuman) e Padrões de Interface de IA (design com citações em primeiro plano, fases de streaming, transparência de erros da Perplexity). Atualizou Padrões Web para 2026 com anchor positioning, animações orientadas por rolagem e @starting-style. Atualizou acessibilidade para refletir a padronização ISO do WCAG 2.2. Veja Estudos de Design para análises aprofundadas de 48 produtos excepcionais.
Passei anos estudando design enquanto criava software, absorvendo princípios de lendas como Dieter Rams e analisando a fundo interfaces de produtos como Linear, Stripe e Raycast. Este guia condensa esse entendimento na referência abrangente que eu gostaria que existisse quando comecei a me importar com a aparência do meu software e com a sensação de usá-lo.
Design não é decoração. É comunicação. Cada pixel comunica função, hierarquia e significado. A diferença entre um software que parece amador e um software que parece profissional está em entender esses princípios e aplicá-los com consistência.
Este guia parte do princípio de que você já sabe escrever código. Ele ensina você a enxergar: a entender por que algumas interfaces parecem naturais enquanto outras parecem caóticas e, mais importante, como criar as primeiras.
Sumário
Parte 1: Fundamentos
- Psicologia Gestalt
- Tipografia
- Teoria das cores
- Hierarquia visual
- Espaçamento e ritmo
- Princípios de animação
Parte 2: Interação e IA
Parte 3: Filosofia de design
Parte 4: Implementação
- Padrões web 2026
- Sistema de design tokens
- Dark mode feito do jeito certo
- Fluxos de extração do Figma
Parte 5: Referência
Psicologia Gestalt
“O todo é diferente da soma de suas partes.” — Kurt Koffka
A psicologia Gestalt, desenvolvida na Alemanha dos anos 1920, explica como os seres humanos percebem informação visual. O cérebro não enxerga pixels individuais — ele organiza elementos em padrões significativos. Domine esses princípios para controlar como os usuários percebem suas interfaces.
Proximidade
Elementos próximos entre si são percebidos como um grupo.
Este é o princípio Gestalt mais poderoso no design de UI. O espaço comunica relacionamento mais do que qualquer outra propriedade visual.
ERRADO (espaçamento igual = sem agrupamento):
┌─────────────────┐
│ Label │
│ │
│ Input Field │
│ │
│ Label │
│ │
│ Input Field │
└─────────────────┘
CORRETO (espaçamento desigual = grupos claros):
┌─────────────────┐
│ Label │
│ Input Field │ ← Apertado (4px) - relacionados
│ │
│ │ ← Amplo (24px) - separando grupos
│ Label │
│ Input Field │ ← Apertado (4px) - relacionados
└─────────────────┘
Implementação CSS:
.form-group {
margin-bottom: 24px; /* Between groups: wide */
}
.form-group label {
margin-bottom: 4px; /* Label to input: tight */
display: block;
}
Implementação SwiftUI:
VStack(alignment: .leading, spacing: 4) { // Tight within group
Text("Email")
.font(.caption)
.foregroundStyle(.secondary)
TextField("you@example.com", text: $email)
.textFieldStyle(.roundedBorder)
}
.padding(.bottom, 24) // Wide between groups
Similaridade
Elementos que compartilham características visuais parecem relacionados.
Quando elementos têm a mesma aparência, os usuários assumem que funcionam da mesma forma. É por isso que sistemas de design usam estilos de botão consistentes, tratamentos de cards e tipografia padronizada.
Exemplo de navegação:
┌───────────────────────────────────┐
│ [Dashboard] [Projects] [Settings] │ ← Mesmo estilo = mesma função
│ │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Card │ │Card │ │Card │ │ ← Mesmo estilo = mesmo tipo de conteúdo
│ └─────┘ └─────┘ └─────┘ │
│ │
│ [+ New Project] │ ← Estilo diferente = função diferente
└───────────────────────────────────┘
Figura-fundo
O conteúdo deve se separar claramente do plano de fundo.
O cérebro precisa distinguir a “figura” (no que focar) do “fundo” (o plano de fundo). Relações fracas entre figura e fundo criam confusão visual.
Técnicas: - Contraste (figura clara sobre fundo escuro, ou vice-versa) - Sombras (elevar a figura acima do fundo) - Bordas (delimitar as arestas da figura) - Desfoque (desfocar o fundo, manter a figura nítida)
/* Strong figure-ground relationship */
.card {
background: var(--color-surface); /* Figure */
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1); /* Elevation */
}
.modal-overlay {
background: rgba(0, 0, 0, 0.5); /* Dim ground */
backdrop-filter: blur(4px); /* Blur ground */
}
Região comum
Elementos dentro de um limite são percebidos como agrupados.
Envolver elementos em um contêiner visual (card, caixa, área com borda) sinaliza que eles pertencem ao mesmo grupo.
Continuidade
O olho segue caminhos, linhas e curvas.
Use alinhamento e fluxo visual para guiar a atenção ao longo da sua interface.
CONTINUIDADE NO ALINHAMENTO:
┌────────────────────────────────┐
│ Logo [Nav] [Nav] [Nav] │ ← Alinhados no eixo horizontal
├────────────────────────────────┤
│ │
│ Headline │
│ ───────────────────────────── │ ← O olho segue a margem esquerda
│ Paragraph text continues │
│ along the same left edge │
│ │
│ [Primary Action] │ ← Ainda na margem esquerda
└────────────────────────────────┘
Fechamento
O cérebro completa formas incompletas.
Os usuários não precisam que cada pixel seja desenhado — eles completam mentalmente formas familiares. Isso permite designs mais minimalistas e elegantes.
/* Horizontal scroll with partial card (closure) */
.card-carousel {
display: flex;
gap: 16px;
overflow-x: auto;
padding-right: 48px; /* Show partial card = scroll hint */
}
.card-carousel .card {
flex: 0 0 280px; /* Fixed width, partial visible */
}
Referência rápida de Gestalt
| Princípio | Regra | Uso principal |
|---|---|---|
| Proximidade | Relacionados = perto, não relacionados = longe | Campos de formulário, seções de conteúdo |
| Similaridade | Mesma aparência = mesma função | Botões, cards, navegação |
| Figura-fundo | Separação clara de camadas | Cards, modais, overlays |
| Região comum | Limites agrupam conteúdo | Seções de configurações, cards de usuário |
| Continuidade | Seguir linhas e alinhamento | Timelines, fluxo de leitura |
| Fechamento | O cérebro completa formas | Ícones, dicas de rolagem, skeletons |
Tipografia
“Tipografia é o ofício de dar à linguagem humana uma forma visual durável.” — Robert Bringhurst
A tipografia é a base do design de interfaces. O texto comunica funcionalidade, hierarquia e marca. Uma tipografia ruim torna as interfaces mais difíceis de usar; uma tipografia excelente é invisível — simplesmente funciona.
Escala tipográfica
Uma escala consistente cria harmonia visual. Use uma proporção matemática.
Escala 1.25 (recomendada para UI):
:root {
/* Base: 16px (1rem) */
--text-xs: 0.64rem; /* 10.24px - use sparingly */
--text-sm: 0.8rem; /* 12.8px - captions, labels */
--text-base: 1rem; /* 16px - body text */
--text-lg: 1.25rem; /* 20px - lead text */
--text-xl: 1.563rem; /* 25px - h4 */
--text-2xl: 1.953rem; /* 31.25px - h3 */
--text-3xl: 2.441rem; /* 39px - h2 */
--text-4xl: 3.052rem; /* 48.8px - h1 */
}
Altura de linha (leading)
A altura de linha afeta dramaticamente a legibilidade. Diferentes conteúdos precisam de diferentes espaçamentos entre linhas.
| Tipo de conteúdo | Altura de linha | Por quê |
|---|---|---|
| Títulos | 1.1 - 1.2 | Compactos, em negrito, curtos |
| Texto de UI | 1.3 - 1.4 | Labels, botões |
| Corpo de texto | 1.5 - 1.7 | Parágrafos legíveis |
| Textos longos | 1.7 - 2.0 | Artigos, documentação |
Comprimento de linha (medida)
O comprimento ideal de linha previne fadiga visual e melhora a compreensão na leitura.
- Ideal: 45-75 caracteres por linha
- Alvo: 50-65 caracteres
- Máximo absoluto: 85 caracteres
p {
max-width: 65ch; /* ch unit = width of '0' character */
}
.article-body {
max-width: 70ch;
margin: 0 auto;
}
Seleção de fontes
Fontes do sistema primeiro. Elas carregam instantaneamente, combinam com a plataforma e são otimizadas para telas.
:root {
--font-sans: system-ui, -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
--font-mono: ui-monospace, 'SF Mono', 'Cascadia Code',
'JetBrains Mono', Consolas, monospace;
}
Use fontes personalizadas para: - Diferenciação de marca (sites de marketing) - Sensação editorial/publicação - Intenção de design específica não alcançável com fontes do sistema
Peso da fonte para hierarquia
Use peso para estabelecer hierarquia, não apenas tamanho.
h1 { font-weight: 700; } /* Bold */
h2 { font-weight: 600; } /* Semibold */
h3 { font-weight: 600; } /* Semibold */
.lead { font-weight: 500; } /* Medium */
p { font-weight: 400; } /* Regular */
.meta { font-weight: 400; color: var(--text-muted); }
Referência rápida de tipografia
| Propriedade | Corpo de texto | Títulos | Labels de UI |
|---|---|---|---|
| Tamanho | 16-18px | 24-48px | 12-14px |
| Peso | 400 | 600-700 | 500 |
| Altura de linha | 1.5-1.7 | 1.1-1.2 | 1.3-1.4 |
| Comprimento de linha | 45-75ch | N/A | N/A |
| Alinhamento | Esquerda | Centro OK | Esquerda |
Teoria das cores
“A cor é uma força que influencia diretamente a alma.” — Wassily Kandinsky
A cor comunica mais rápido do que as palavras. Ela estabelece o clima, guia a atenção, sinaliza significado e constrói reconhecimento de marca.
A regra 60-30-10
A distribuição de cores mais confiável para interfaces equilibradas.
┌──────────────────────────────────────────┐
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ 60% - Dominant (Background)
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░│ 30% - Secondary (Cards, sections)
│░░░░░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░│
│░░░░░▓▓▓▓▓▓▓▓▓▓▓▓██████▓▓▓▓▓▓▓▓▓▓░░░░░░░░│ 10% - Accent (Buttons, links)
└──────────────────────────────────────────┘
Criando uma paleta de cores
Toda interface precisa destas cores semânticas:
:root {
/* Brand */
--color-primary: hsl(220, 80%, 50%);
--color-primary-hover: hsl(220, 80%, 45%);
/* Semantic */
--color-success: hsl(142, 76%, 36%); /* Green - positive */
--color-warning: hsl(38, 92%, 50%); /* Amber - caution */
--color-error: hsl(0, 84%, 60%); /* Red - danger */
/* Neutrals */
--color-background: hsl(0, 0%, 100%);
--color-surface: hsl(220, 14%, 96%);
--color-border: hsl(220, 13%, 91%);
/* Text */
--color-text: hsl(220, 13%, 13%);
--color-text-secondary: hsl(220, 9%, 46%);
--color-text-muted: hsl(220, 9%, 64%);
}
Psicologia das cores
| Cor | Psicologia | Uso em UI |
|---|---|---|
| Azul | Confiança, estabilidade, calma | Finanças, tecnologia, corporativo |
| Verde | Crescimento, natureza, sucesso | Saúde, eco, estados positivos |
| Vermelho | Energia, urgência, perigo | Alertas, vendas, erros |
| Laranja | Calor, entusiasmo | CTAs, marcas descontraídas |
| Amarelo | Otimismo, cautela | Avisos, destaques |
| Roxo | Luxo, criatividade | Produtos premium |
| ### Design com modo escuro em primeiro lugar (Vercel) | ||
| Vercel projeta primeiro para o modo escuro e depois deriva o modo claro. Isso produz interfaces escuras melhores porque o modo escuro se torna a consideração principal, em vez de uma reflexão tardia. |
/* Design dark first, derive light */
:root {
/* Dark mode defaults */
--color-background: hsl(0, 0%, 0%);
--color-surface: hsl(0, 0%, 7%);
--color-border: hsl(0, 0%, 15%);
--color-text: hsl(0, 0%, 93%);
--color-text-secondary: hsl(0, 0%, 63%);
}
@media (prefers-color-scheme: light) {
:root {
--color-background: hsl(0, 0%, 100%);
--color-surface: hsl(0, 0%, 97%);
--color-border: hsl(0, 0%, 89%);
--color-text: hsl(0, 0%, 9%);
--color-text-secondary: hsl(0, 0%, 40%);
}
}
Quando usar: Ferramentas para desenvolvedores, apps de mídia, dashboards — contextos em que os usuários passam longas sessões e o modo escuro reduz o cansaço visual.
Contraste de acessibilidade
| Nível | Texto normal | Texto grande | Componentes de UI |
|---|---|---|---|
| AA | 4,5:1 | 3:1 | 3:1 |
| AAA | 7:1 | 4,5:1 | N/A |
| WCAG 2.2 se tornou um padrão ISO (ISO/IEC 40500:2025) em outubro de 2025, adicionando critérios de visibilidade do foco, entrada redundante e autenticação acessível. Principais adições: os indicadores de foco não devem ficar totalmente ocultos por outro conteúdo (2.4.11), e a autenticação não deve depender apenas de testes de função cognitiva (3.3.8). O W3C publicou uma versão atualizada do WCAG 2.2 em dezembro de 2024, com previsão de lançamento como ISO/IEC 40500:2026 até o fim de 2026. |
WCAG 3.0 ainda é um working draft. A revisão mais recente foi publicada em março de 2026 e não substitui o WCAG 2.2; o W3C afirma que os dois padrões vão coexistir. O Accessibility Guidelines Working Group planeja publicar um cronograma projetado para o WCAG 3 em 2026, mas o WCAG 2.2 continua sendo o padrão a mirar no trabalho atual.
Ferramentas: WebAIM Contrast Checker, seletor de cores do Chrome DevTools
Hierarquia visual
“O design é o embaixador silencioso da sua marca.” — Paul Rand
A hierarquia visual controla o que os usuários veem primeiro, segundo e terceiro. Sem uma hierarquia clara, os usuários precisam se esforçar para encontrar informações. Com ela, as interfaces parecem simples de usar.
As seis ferramentas da hierarquia
1. Tamanho — Elementos maiores chamam atenção primeiro
.hero-title { font-size: 3rem; } /* Dominant */
.section-title { font-size: 1.5rem; } /* Secondary */
.body-text { font-size: 1rem; } /* Baseline */
2. Peso — O negrito se destaca, o leve recua
h1 { font-weight: 700; }
.lead { font-weight: 500; }
p { font-weight: 400; }
3. Cor e contraste — Alto contraste = atenção
.title { color: var(--color-text); } /* Near black */
.meta { color: var(--color-text-muted); } /* Gray */
4. Posição — Posições-chave importam
F-PATTERN (content pages): Z-PATTERN (landing pages):
████████████████████████ 1 ──────────────────► 2
████████ ↘
████ ↘
██ ↘
3 ──────────────────► 4
5. Espaço em branco — O isolamento cria importância
.hero { padding: 120px 48px; } /* Generous space */
.data-table { padding: 12px; } /* Dense content */
6. Profundidade e elevação — Elementos que parecem avançar exigem atenção
:root {
--shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
--shadow-md: 0 4px 6px rgba(0,0,0,0.1);
--shadow-lg: 0 10px 15px rgba(0,0,0,0.1);
}
.card { box-shadow: var(--shadow-sm); }
.card:hover { box-shadow: var(--shadow-md); }
.modal { box-shadow: var(--shadow-lg); }
Padrões aplicados
Presença colaborativa (Figma): Vários cursores de usuários com rótulos de nome, destaques de seleção e contornos de componentes criam um documento vivo. A cor de cada colaborador é distinta, mas tem o mesmo peso visual: nenhum cursor é “mais chamativo” que outro.
Indicadores sutis de status (Vercel): O status do deploy usa indicadores sutis e persistentes, em vez de alertas intrusivos. Uma barra fina de cor no topo comunica o estado (em build, publicado, com falha) sem interromper o fluxo de trabalho.
Analogias de design do mundo real (Flighty): As visualizações de progresso do voo espelham instrumentos reais da aviação: curvas de altitude, indicadores de velocidade e mapas de portão usam metáforas visuais familiares em vez de barras de progresso abstratas.
O teste de semicerrar os olhos
Semicerre os olhos ao olhar para o seu design. Você ainda consegue ver a hierarquia? Se sim, ela está forte.
Espaçamento e ritmo
“O espaço em branco é como o ar: é necessário para que o design respire.” — Wojciech Zieliński
O espaçamento é a estrutura invisível do design. Um espaçamento consistente cria ritmo visual — a sensação de que os elementos pertencem a um sistema coerente.
A grade de 8px
A grade de 8px é o padrão do setor porque: - Divide uniformemente (8, 16, 24, 32, 40, 48…) - Funciona com densidades de tela comuns (1x, 1.5x, 2x, 3x) - Cria um ritmo consistente sem matemática
:root {
--space-1: 4px; /* Tight: icon gaps */
--space-2: 8px; /* Compact: inline elements */
--space-3: 12px; /* Snug: form fields */
--space-4: 16px; /* Default: most gaps */
--space-6: 24px; /* Spacious: card padding */
--space-8: 32px; /* Section gaps */
--space-12: 48px; /* Major sections */
--space-16: 64px; /* Page sections */
--space-20: 80px; /* Hero spacing */
}
Espaçamento interno vs externo
Interno (padding): Espaço dentro de um elemento Externo (margin): Espaço entre elementos
Regra: O espaçamento interno normalmente deve ser maior que o espaçamento externo dentro de grupos relacionados.
.card {
padding: 24px; /* Internal: spacious */
margin-bottom: 16px; /* External: less than padding */
}
Padrões de espaçamento de componentes
Cards:
.card { padding: 24px; border-radius: 12px; }
.card-header { margin-bottom: 16px; }
.card-title { margin-bottom: 4px; } /* Tight to subtitle */
Botões:
.btn { padding: 12px 24px; border-radius: 8px; }
.btn--sm { padding: 8px 16px; }
.btn--lg { padding: 16px 32px; }
.btn-group { display: flex; gap: 12px; }
Formulários:
.form-row { margin-bottom: 24px; }
.form-label { margin-bottom: 4px; }
.form-help { margin-top: 4px; }
.form-actions { margin-top: 32px; display: flex; gap: 12px; }
Referência rápida de espaçamento
| Contexto | Espaçamento recomendado |
|---|---|
| Do ícone ao texto | 4-8px |
| Do rótulo ao campo | 4px |
| Entre grupos do formulário | 24px |
| Padding do card | 20-24px |
| Espaçamento entre cards | 16-24px |
| Padding da seção (mobile) | 48-64px |
| Padding da seção (desktop) | 80-96px |
| Padding do botão (h/v) | 24px / 12px |
| — |
Princípios de animação
“Animação não é a arte de desenhos que se movem, mas a arte de movimentos que são desenhados.” — Norman McLaren
Animação dá vida às interfaces. Bem feita, ela direciona a atenção, comunica estado e cria conexão emocional. Mal feita, frustra e distrai.
O princípio fundamental
Animação deve parecer inevitável, não decorativa.
Boa animação: 1. Comunica algo que o design estático não consegue 2. Reduz a carga cognitiva ao mostrar relações 3. Parece natural e esperada 4. Desaparece da percepção consciente
Má animação: 1. Existe apenas porque “fica legal” 2. Atrasa o usuário 3. Chama atenção para si mesma 4. Gera ansiedade ou impaciência
Princípios-chave para UI
1. Antecipação — Prepare os usuários para o que vem a seguir.
.button {
transition: transform 0.1s ease-out;
}
.button:active {
transform: scale(0.97); /* Slight press before action */
}
2. Continuidade — Deixe o movimento se completar naturalmente com uma acomodação tipo mola.
.panel {
transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
withAnimation(.spring(response: 0.4, dampingFraction: 0.7)) {
isOpen = true
}
3. Ease-In, Ease-Out — Nada na natureza se move em velocidade constante.
| Curva | Quando usar | Caráter |
|---|---|---|
ease-out |
Elementos entrando | Início rápido, parada suave |
ease-in |
Elementos saindo | Início suave, saída rápida |
ease-in-out |
Mudanças de estado | Suave do início ao fim |
linear |
Indicadores de carregamento | Contínuo, mecânico |
4. Encenação — Direcione a atenção para o que importa. Apenas um elemento deve se mover por vez, a menos que coreografado como grupo.
5. Escalonamento — Elementos devem chegar em sequência, não todos de uma vez.
.list-item {
animation: fadeSlideIn 0.3s ease-out both;
}
.list-item:nth-child(1) { animation-delay: 0ms; }
.list-item:nth-child(2) { animation-delay: 50ms; }
.list-item:nth-child(3) { animation-delay: 100ms; }
.list-item:nth-child(4) { animation-delay: 150ms; }
@keyframes fadeSlideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
Diretrizes de tempo
| Duração | Caso de uso | Sensação |
|---|---|---|
| 50-100ms | Micro-interações (hover, press) | Feedback instantâneo |
| 150-200ms | Mudanças de estado simples (toggle, seleção) | Ágil |
| 250-350ms | Transições médias (painel deslizante, virada de card) | Suave |
| 400-500ms | Movimentos amplos (transições de página, modais) | Deliberado |
Performance: a regra de ouro
Anime apenas transform e opacity — esses são acelerados por GPU e não disparam recálculo de layout.
/* BAD: Animating layout */
.panel { transition: left 0.3s, width 0.3s; }
/* GOOD: Using transform */
.panel { transition: transform 0.3s; }
Quando NÃO animar
-
O usuário tem
prefers-reduced-motionativadocss @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } -
A animação não acrescenta informação — spinners gratuitos, elementos saltitantes
- O usuário está com pressa — estados de erro, validação de formulário, resultados de busca
- A animação atrasaria ações repetidas — atalhos de teclado devem ignorar animações
- Os dados já estão carregados — Bear usa zero estados de carregamento ao pré-carregar o conteúdo, fazendo o app parecer instantâneo. Se você consegue pré-carregar, pule o skeleton/spinner completamente.
// Bear's approach: preload so no loading state is needed
struct NoteListView: View {
@Query var notes: [Note] // SwiftData loads from disk instantly
// No loading state, no skeleton, no spinner — data is always there
var body: some View {
List(notes) { note in
NoteRow(note: note)
}
}
}
Referência rápida de animação
:root {
/* Durations */
--duration-instant: 0.1s;
--duration-fast: 0.15s;
--duration-normal: 0.25s;
--duration-slow: 0.4s;
/* Easings */
--ease-out: cubic-bezier(0.0, 0.0, 0.58, 1.0);
--ease-in: cubic-bezier(0.42, 0.0, 1.0, 1.0);
--ease-in-out: cubic-bezier(0.42, 0.0, 0.58, 1.0);
--ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
}
Padrões de interação
“A melhor interface é nenhuma interface.” — Golden Krishna
Padrões de interação definem como os usuários manipulam, navegam e compreendem seu produto. Esses padrões foram extraídos do estudo de produtos que entregam interações excepcionais.
Manipulação direta (Framer)
Torne conceitos abstratos tangíveis. Framer transforma breakpoints de CSS — números abstratos — em alças arrastáveis. Os usuários veem os layouts se adaptarem em tempo real.
/* Breakpoint handle styling */
.breakpoint-handle {
position: absolute;
top: 0;
bottom: 0;
width: 4px;
background: var(--accent);
cursor: col-resize;
opacity: 0.6;
transition: opacity 0.15s ease;
}
.breakpoint-handle:hover,
.breakpoint-handle:active {
opacity: 1;
width: 6px;
}
Quando usar: Qualquer configuração em que o resultado é visual — arrastar para redimensionar, seletores de cor, scrubbing de timeline.
Interfaces sensíveis ao contexto (Flighty, Figma)
Mostre apenas o que é relevante para o momento atual. Flighty usa 15 estados distintos para rastreamento de voos. O painel de propriedades do Figma se transforma completamente com base no que você selecionou.
| Fase (Flighty) | O que o usuário vê |
|---|---|
| 24h antes | Código de confirmação, informações do terminal |
| No aeroporto | Número do portão, horário de embarque |
| Em voo | Tempo restante, progresso, horário estimado de chegada |
| Pouso | Portões de conexão, caminho a percorrer |
enum ContextState: CaseIterable {
case farOut, dayBefore, headToAirport, atAirport
case atGate, boarding, inFlight, landed, connection
static func current(for flight: Flight, context: UserContext) -> ContextState {
// Factor in: time, location, flight status
// Return the single most relevant state
}
}
Anti-padrão: Mostrar todos os controles e deixar os irrelevantes esmaecidos. Isso cria ruído visual.
Ativação inteligente (Halide)
Ferramentas devem perceber o contexto e se ativar automaticamente. A lupa de foco do Halide aparece ao arrastar o foco e desaparece ao soltar. Nenhum botão de alternância necessário.
struct IntelligentlyActivated<Content: View>: ViewModifier {
let isInteracting: Bool
@State private var isVisible = false
func body(content: Content) -> some View {
content
.opacity(isVisible ? 1 : 0)
.scaleEffect(isVisible ? 1 : 0.95)
.animation(.easeInOut(duration: 0.2), value: isVisible)
.onChange(of: isInteracting) { _, newValue in
if newValue {
withAnimation { isVisible = true }
} else {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
if !isInteracting { isVisible = false }
}
}
}
}
}
Design de modo duplo (Halide, Warp)
Mudanças de modo devem transformar a UI, não apenas alternar elementos. Os modos Auto e Manual do Halide são interfaces completamente diferentes. Warp conecta CLI e GUI por meio de quatro métodos de entrada (digitação, paleta, IA, mouse) sem forçar os usuários a adotar um único paradigma.
Conteúdo estruturado (Warp, Bear, Craft)
Adicione estrutura a conteúdo tradicionalmente não-estruturado. Warp transforma a saída do terminal em blocos discretos que podem ser copiados, compartilhados ou reexecutados. Bear permite organizar notas inline enquanto escreve (#tag/subtag). Craft permite que qualquer bloco se torne uma página — a estrutura emerge do uso, não de uma hierarquia predefinida.
Treinamento progressivo (Superhuman)
Ensine aos usuários o caminho rápido por meio de exposição repetida. A paleta Cmd+K do Superhuman sempre exibe atalhos de teclado junto aos resultados. Cada uso é uma micro-lição.
/* Always show shortcut alongside command name */
.command-result {
display: flex;
justify-content: space-between;
padding: 8px 12px;
}
.command-shortcut {
font-family: var(--font-mono);
font-size: 12px;
color: var(--text-muted);
background: var(--bg-subtle);
padding: 2px 6px;
border-radius: 4px;
}
Anti-padrão: Modais de tutorial que explicam funcionalidades. Explicação é esquecida; prática é lembrada.
Padrões de interface de AI
“As melhores interfaces de AI tornam o processo da máquina visível e o resultado da máquina verificável.”
As interfaces de AI enfrentam desafios únicos: os usuários não conseguem prever o resultado, verificar a precisão apenas pela inspeção e, muitas vezes, nem mesmo saber se o sistema está funcionando ou com problemas.
O problema central
| Software tradicional | Software de AI |
|---|---|
| O resultado é previsível | O resultado varia |
| Os erros são óbvios | Os erros parecem plausíveis |
| Os usuários verificam fazendo testes | Os usuários verificam consultando as fontes |
| Carregamento = espera | Carregamento = trabalho em andamento (mostre isso) |
| Confiança por padrão | A confiança precisa ser conquistada |
Design centrado em citações (Perplexity)
Toda afirmação factual deve conter um link para sua fonte. O Perplexity insere citações inline [1] em cada afirmação, com prévias ao passar o cursor e um painel de fontes persistente.
.citation-marker {
position: relative;
color: var(--accent);
cursor: pointer;
font-size: 0.8em;
vertical-align: super;
}
.citation-preview {
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
width: 280px;
padding: 12px;
background: var(--bg-elevated);
border: 1px solid var(--border);
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
Antipadrão: interfaces de AI que geram afirmações sem fontes rastreáveis. Se o modelo não conseguir citar uma fonte, a interface deve sinalizar isso.
Indicadores das etapas de streaming (Perplexity)
Mostre aos usuários o que a AI está fazendo, não apenas que ela está trabalhando. Substitua indicadores de carregamento genéricos por indicadores de etapa: “Pesquisando…” → “Lendo 4 fontes…” → “Escrevendo a resposta…”
.phase-indicator {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
background: color-mix(in srgb, var(--phase-color) 10%, transparent);
border-radius: 16px;
font-size: 13px;
color: var(--phase-color);
transition: all 0.3s ease;
}
.loading-dots span {
width: 4px;
height: 4px;
background: currentColor;
border-radius: 50%;
animation: pulse 1.4s ease-in-out infinite;
}
Transparência sobre erros
Quando a AI falhar ou estiver incerta, deixe isso claro — não esconda o problema atrás de um texto que pareça confiante.
| Situação | Padrão ruim | Padrão bom |
|---|---|---|
| Baixa confiança | Afirmar com confiança | “Não tenho certeza, mas…” com estilo menos destacado |
| Nenhuma fonte encontrada | Inventar um texto | “Não encontrei fontes para esta afirmação” |
| Fontes contraditórias | Escolher uma sem avisar | Mostrar ambas com o conflito destacado |
| Informações desatualizadas | Apresentar como atuais | “Em [data]…” com um indicador de atualidade |
Insight principal: os usuários perdoam uma AI que admite suas incertezas. Eles não perdoam uma AI que está errada e ainda assim demonstra confiança.
Evidências em fluxos de trabalho agênticos
Os agentes de AI precisam de estados de interface que comprovem o trabalho, não apenas descrevam o esforço. Um bom fluxo de trabalho agêntico torna o progresso compreensível por meio de checkpoints: plano aceito, fontes reunidas, alterações aplicadas, testes executados, revisão pendente e lançamento bloqueado ou pronto.
| Estado do agente | Padrão de interface | Por que isso é importante |
|---|---|---|
| Planejamento | Objetivo e critérios de aceitação explícitos | Impede que o agente otimize para gerar atividade em vez de alcançar o resultado |
| Exploração | Lista de fontes com nível de confiança e atualidade | Permite que os usuários diferenciem fatos verificados de hipóteses de trabalho |
| Execução | Resumo dos arquivos alterados vinculado aos checkpoints | Permite revisar as alterações sem ler toda a transcrição |
| Verificação | Evidência por meio de teste, rota, captura de tela ou execução | Separa as provas da confiança artificial |
| Lançamento | Estado de aprovação, deploy ou revisão nativa | Impede que a publicação esconda trabalho inacabado atrás de verificações locais bem-sucedidas |
Antipadrão: um único estado “Concluído” para um trabalho agêntico com várias etapas. Trabalhos complexos exigem uma cadeia de custódia visível: o que mudou, o que comprovou o resultado, o que foi recusado e o que ainda precisa do julgamento humano.
Dieter Rams: dez princípios
“Menos, porém melhor.” — Dieter Rams
Dieter Rams é o designer industrial mais influente do século 20. Como diretor de design da Braun de 1961 a 1995, ele criou produtos que continuam atemporais décadas depois. Seu trabalho inspirou diretamente a linguagem de design da Apple.
Os dez princípios do bom design
1. O bom design é inovador Não copie. Combine o avanço da tecnologia com um design inovador.
2. O bom design torna um produto útil Cada elemento deve cumprir uma finalidade. A forma segue a função.
3. O bom design é estético A beleza não é superficial — ela é essencial. Os produtos que usamos diariamente afetam nosso bem-estar.
4. O bom design torna um produto compreensível Os usuários não deveriam precisar de instruções. A própria interface ensina como usá-la.
5. O bom design é discreto O design deve dar suporte, não sobrecarregar. O conteúdo do usuário é o protagonista, não a sua UI.
/* Obtrusive: UI competes with content */
.editor {
background: linear-gradient(135deg, purple, blue);
border: 3px dashed gold;
}
/* Unobtrusive: UI recedes, content shines */
.editor {
background: var(--color-background);
border: 1px solid var(--color-border);
}
6. O bom design é honesto Não use padrões obscuros. Não prometa além do que pode cumprir. Seja transparente sobre as limitações.
7. O bom design é duradouro Evite tendências que ficarão ultrapassadas rapidamente. Prefira o clássico ao que está na moda.
TRENDY (will date): TIMELESS:
- Extreme glassmorphism - Clean typography
- Neon colors, glitch effects - Subtle elevation
- Aggressive gradients - Neutral palette with considered accent
8. O bom design é minucioso até o último detalhe Nada deve ser arbitrário. Estados de carregamento, estados vazios, estados de erro — tudo deve ser projetado.
9. O bom design é sustentável Performance também é uma questão ambiental. Respeite a atenção do usuário. Escreva código eficiente.
10. O bom design é o mínimo possível de design Remova tudo o que não for necessário. O melhor design é invisível.
Padrões web de 2026
O CSS nativo agora substitui o JavaScript em um conjunto cada vez maior de problemas de layout e interação. O período de 2025 a 2026 trouxe posicionamento por âncora, animações controladas por rolagem e @starting-style aos navegadores disponíveis em produção, enquanto meados de 2026 adicionaram dimensionamento automático de controles de formulário, decorações de espaçamento e ajuste automático de texto.
Aqui, o status de suporte importa mais do que a novidade. Um recurso disponível em um único mecanismo é um aprimoramento progressivo; um recurso classificado como Baseline Newly available pode ser usado com segurança. A tabela abaixo separa os dois casos em agosto de 2026.
| Recurso | Chrome | Firefox | Safari | Status |
|---|---|---|---|---|
field-sizing |
123 | 152 | 26.2 | Baseline Newly available |
shape-outside: rect() / xywh() |
149 | 149 | 17.2 | Baseline Newly available |
background-clip: border-area |
150 | — | 18.2 | Dois mecanismos |
Decorações de espaçamento (column-rule em grid/flex) |
149 | — | — | Somente Chrome |
text-fit |
150 | — | — | Somente Chrome |
focusgroup |
150 | — | — | Somente Chrome |
Fontes: Novidades da plataforma web em junho e julho, web.dev.
Consultas de contêiner
Dimensione os componentes com base no contêiner, não na viewport.
.card-grid {
container-type: inline-size;
container-name: card-grid;
}
.card {
display: grid;
gap: 16px;
padding: 20px;
}
@container card-grid (min-width: 400px) {
.card {
grid-template-columns: auto 1fr;
}
}
@container card-grid (min-width: 600px) {
.card {
padding: 32px;
gap: 24px;
}
}
O seletor :has()
Seleção do elemento pai com base nos filhos — algo que antes era impossível sem JavaScript.
/* Card with image gets different padding */
.card:has(img) {
padding: 0;
}
.card:has(img) .card-content {
padding: 20px;
}
/* Form group with error */
.form-group:has(.input:invalid) .form-label {
color: var(--color-error);
}
/* Highlight navigation when on that page */
.nav-item:has(a[aria-current="page"]) {
background: var(--color-surface);
}
Aninhamento de CSS
Aninhamento nativo sem pré-processadores.
.card {
background: var(--color-surface);
border-radius: 12px;
padding: 24px;
& .card-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 8px;
}
& .card-body {
color: var(--color-text-secondary);
line-height: 1.6;
}
&:hover {
box-shadow: var(--shadow-md);
}
@media (min-width: 768px) {
padding: 32px;
}
}
Decorações de espaçamento
Os espaçamentos de grid e flex podem ter suas próprias linhas, então os divisores não exigem mais pseudoelementos, bordas em cada elemento filho nem um wrapper por coluna. Disponível somente no Chrome 149 e versões posteriores, o que torna esse recurso um aprimoramento progressivo, não uma base.
.pricing-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 32px;
/* Vertical rules between columns, horizontal between rows */
column-rule: 1px solid var(--color-border);
row-rule: 1px solid var(--color-border);
}
A abordagem antiga aplicava um border-left a todos os itens, exceto ao primeiro, e deixava de funcionar assim que o grid passava para uma segunda linha. As decorações são desenhadas no próprio espaçamento, portanto continuam corretas quando os itens quebram de linha.
Como o suporte está limitado a um único mecanismo, trate essas linhas como decoração, nunca como o elemento que separa significados. Um layout que se torna ambíguo sem elas é um layout que falha no Firefox e no Safari.
Controles de formulário que se ajustam ao conteúdo
field-sizing: content permite que inputs, textareas e selects aumentem ou diminuam conforme o usuário digita, substituindo o JavaScript baseado na altura de rolagem que toda base de código acaba reimplementando.
.comment-box {
field-sizing: content;
min-height: 3lh; /* floor: three lines */
max-height: 12lh; /* ceiling: then scroll */
}
.tag-input {
field-sizing: content;
min-width: 8ch;
}
Sempre combine esse recurso com limites min-/max-. Sem um limite mínimo, um campo vazio encolhe até quase desaparecer; sem um limite máximo, um texto longo colado no campo empurra o botão de envio para fora da tela.
Esse recurso alcançou o status Baseline Newly available em junho de 2026, portanto pode ser usado com segurança como mecanismo principal, não apenas como aprimoramento.
Texto que se ajusta à caixa
text-fit dimensiona a fonte para preencher a largura do contêiner, atendendo aos casos de títulos de destaque e números grandes em dashboards que antes exigiam um script de medição.
.stat-value {
text-fit: consistent; /* one size for the whole box */
}
Disponível somente no Chrome 150. Defina primeiro um font-size normal para que outros mecanismos recebam um tamanho intencional, não um valor padrão:
.stat-value {
font-size: clamp(2rem, 8vw, 6rem); /* the real answer everywhere */
text-fit: consistent; /* refinement where supported */
}
clamp() já resolve a maior parte dos casos em que as pessoas recorrem a esse recurso e tem suporte universal. Use text-fit quando o comprimento do conteúdo variar tanto que nenhuma configuração única de clamp funcione.
Bordas em gradiente sem truques
background-clip: border-area pinta um fundo na caixa da borda, transformando as bordas em gradiente em uma regra de duas linhas, sem exigir elementos aninhados nem truques com mask-composite.
.featured-card {
border: 2px solid transparent;
border-radius: 12px;
background:
linear-gradient(var(--color-surface), var(--color-surface)) padding-box,
linear-gradient(135deg, #6366f1, #ec4899) border-area;
}
Disponível no Chrome 150 e no Safari 18.2; o Firefox ainda não implementou o recurso. Declare primeiro um border-color sólido para que o fallback seja uma borda real, não transparente.
Navegação com as setas sem um manipulador de keydown
O atributo focusgroup informa ao navegador que um conjunto de controles forma uma única unidade de teclado: Tab entra no grupo uma vez, as setas navegam dentro dele e Tab sai. Barras de ferramentas, listas de abas, controles segmentados e grupos de botões no estilo de opções de rádio precisam desse comportamento — e essa é a parte que componentes implementados manualmente erram com mais frequência.
<div role="toolbar" focusgroup="wrap">
<button>Bold</button>
<button>Italic</button>
<button>Underline</button>
</div>
wrap faz com que a seta no último item retorne ao primeiro. Por padrão, a navegação para nas extremidades.
Disponível somente no Chrome 150, portanto mantenha o manipulador de keydown existente até que o suporte aumente. Vale a pena conhecer o atributo desde já porque ele define com precisão o comportamento acessível: uma barra de ferramentas deve ocupar uma única parada de tabulação, não cinco, e essa expectativa antecede o atributo em décadas. As Práticas de criação da ARIA descrevem o padrão, independentemente de como ele é implementado.
Integração com HTMX
Interatividade controlada pelo servidor sem frameworks pesados de JavaScript.
<!-- Load content on click -->
<button hx-get="/api/more-items"
hx-target="#item-list"
hx-swap="beforeend"
hx-indicator="#loading">
Load More
</button>
<!-- Form with inline validation -->
<form hx-post="/api/contact"
hx-target="#form-response"
hx-swap="outerHTML">
<input type="email" name="email"
hx-post="/api/validate-email"
hx-trigger="blur"
hx-target="next .error" />
<span class="error"></span>
</form>
Posicionamento por âncora
Posicionamento nativo com CSS de um elemento em relação a outro — sem precisar de JavaScript. Tooltips, popovers e menus suspensos que acompanham seus elementos acionadores.
/* Anchor an element to another */
.trigger {
anchor-name: --my-trigger;
}
.tooltip {
position: fixed;
position-anchor: --my-trigger;
top: anchor(bottom);
left: anchor(center);
translate: -50% 8px;
}
Animações controladas por rolagem
Vincule o progresso da animação à posição de rolagem. Indicadores de progresso de leitura, efeitos de paralaxe e sequências de revelação sem JavaScript.
/* Reading progress bar */
.progress-bar {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 3px;
background: var(--color-primary);
transform-origin: left;
animation: progress linear;
animation-timeline: scroll();
}
@keyframes progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
@starting-style
Defina os estilos iniciais dos elementos que entram no DOM, permitindo animações de entrada feitas somente com CSS, sem JavaScript.
.card {
opacity: 1;
transform: translateY(0);
transition: opacity 0.3s ease, transform 0.3s ease;
@starting-style {
opacity: 0;
transform: translateY(10px);
}
}
Sistema de design tokens
Um sistema completo de tokens para manter a consistência em todo o aplicativo.
:root {
/* Colors */
--color-text: #1a1a1a;
--color-text-secondary: #666666;
--color-text-muted: #999999;
--color-background: #ffffff;
--color-surface: #f8f9fa;
--color-surface-elevated: #ffffff;
--color-border: #e5e7eb;
--color-primary: #3b82f6;
--color-primary-hover: #2563eb;
--color-success: #10b981;
--color-warning: #f59e0b;
--color-error: #ef4444;
/* Typography */
--font-sans: system-ui, -apple-system, sans-serif;
--font-mono: "SF Mono", Consolas, monospace;
--text-xs: 0.75rem;
--text-sm: 0.875rem;
--text-base: 1rem;
--text-lg: 1.125rem;
--text-xl: 1.25rem;
--text-2xl: 1.5rem;
--text-3xl: 2rem;
--leading-tight: 1.25;
--leading-normal: 1.5;
--leading-relaxed: 1.75;
/* Spacing (8px base) */
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
--space-12: 3rem; /* 48px */
--space-16: 4rem; /* 64px */
/* Borders */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-full: 9999px;
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
/* Transitions */
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--duration-fast: 100ms;
--duration-normal: 200ms;
}
Dark mode bem-feito
Não basta inverter as cores — redesenhe para contextos escuros.
@media (prefers-color-scheme: dark) {
:root {
/* Neutrals */
--color-background: hsl(220, 13%, 10%);
--color-surface: hsl(220, 13%, 15%);
--color-surface-elevated: hsl(220, 13%, 18%);
--color-border: hsl(220, 13%, 23%);
/* Text (inverted) */
--color-text: hsl(220, 9%, 93%);
--color-text-secondary: hsl(220, 9%, 70%);
--color-text-muted: hsl(220, 9%, 55%);
/* Adjust saturation for dark mode */
--color-primary: hsl(220, 80%, 60%);
--color-success: hsl(142, 70%, 45%);
--color-error: hsl(0, 80%, 65%);
/* Shadows in dark mode need adjustment */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
}
}
Princípios do dark mode: - Reduza a saturação em superfícies grandes - Aumente a luminosidade das cores de destaque - Reforce as sombras (elas precisam de mais contraste) - Projete o dark mode de forma intencional, não como algo acrescentado depois
Fluxos de extração do Figma
Transformar arquivos de design em código de produção exige a extração sistemática dos tokens de design — cores, tipografia, espaçamento e efeitos que definem sua linguagem visual.
Exportação de variáveis do Figma
O recurso nativo Variables do Figma oferece o caminho mais simples para a extração:
Etapas de exportação:
1. Abra o arquivo do Figma → painel Local Variables
2. Clique no menu da coleção → “Export to JSON”
3. Salve como figma-variables.json
Estrutura dos tokens JSON:
{
"colors": {
"primitive": {
"blue-500": { "value": "#3b82f6", "type": "color" },
"blue-600": { "value": "#2563eb", "type": "color" }
},
"semantic": {
"primary": { "value": "{colors.primitive.blue-500}", "type": "color" },
"primary-hover": { "value": "{colors.primitive.blue-600}", "type": "color" }
}
},
"spacing": {
"1": { "value": "4px", "type": "spacing" },
"2": { "value": "8px", "type": "spacing" },
"4": { "value": "16px", "type": "spacing" }
}
}
Transformação de tokens em CSS
Propriedades personalizadas de CSS:
:root {
/* Primitive colors (direct values) */
--color-blue-50: #eff6ff;
--color-blue-100: #dbeafe;
--color-blue-500: #3b82f6;
--color-blue-600: #2563eb;
--color-blue-900: #1e3a8a;
/* Semantic colors (reference primitives) */
--color-primary: var(--color-blue-500);
--color-primary-hover: var(--color-blue-600);
--color-background: var(--color-white);
--color-surface: var(--color-gray-50);
/* Spacing (8px grid) */
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-4: 1rem; /* 16px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
/* Typography */
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
/* Effects */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
}
Tokens de dark mode:
@media (prefers-color-scheme: dark) {
:root {
--color-background: var(--color-gray-900);
--color-surface: var(--color-gray-800);
--color-text: var(--color-gray-100);
--color-text-secondary: var(--color-gray-400);
/* Adjusted shadows for dark mode */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
}
}
Transformação de tokens em SwiftUI
Extensão de cores:
import SwiftUI
extension Color {
// MARK: - Primitive Colors
static let blue50 = Color(hex: "eff6ff")
static let blue500 = Color(hex: "3b82f6")
static let blue600 = Color(hex: "2563eb")
// MARK: - Semantic Colors
static let brandPrimary = Color.blue500
static let brandPrimaryHover = Color.blue600
// MARK: - Surface Colors
static let surfaceBackground = Color(light: .white, dark: Color(hex: "0f172a"))
static let surfaceElevated = Color(light: Color(hex: "f8fafc"), dark: Color(hex: "1e293b"))
}
extension Color {
init(hex: String) {
// Standard hex parsing implementation
}
init(light: Color, dark: Color) {
self.init(UIColor { traits in
traits.userInterfaceStyle == .dark ? UIColor(dark) : UIColor(light)
})
}
}
Constantes de espaçamento:
enum Spacing {
static let xs: CGFloat = 4 // --space-1
static let sm: CGFloat = 8 // --space-2
static let md: CGFloat = 16 // --space-4
static let lg: CGFloat = 24 // --space-6
static let xl: CGFloat = 32 // --space-8
}
// Usage
VStack(spacing: Spacing.md) {
// ...
}
.padding(Spacing.lg)
Checklist de entrega do designer
O que os designers devem exportar:
| Tipo de ativo | Formato | Observações |
|---|---|---|
| Cores | Variables JSON | Inclua os modos claro e escuro |
| Tipografia | Exportação de estilos | Fonte, tamanho, peso, altura da linha |
| Espaçamento | Variables JSON | Unidade-base documentada |
| Ícones | SVG | Contornados, em uma única cor |
| Imagens | PNG @2x/@3x ou WebP | Com compactação |
| Componentes | Links do Figma | Para consulta durante a implementação |
Critérios de controle de qualidade:
- [ ] Todas as cores estão definidas como variáveis (sem valores hexadecimais fixos)
- [ ] A tipografia usa estilos de texto definidos
- [ ] O espaçamento segue o sistema de grid (base de 8px)
- [ ] Há variantes para dark mode
- [ ] Os estados interativos estão documentados (hover, ativo, desabilitado)
- [ ] Os breakpoints responsivos estão indicados
- [ ] Os requisitos de acessibilidade estão registrados (taxas de contraste)
O desenvolvedor recebe:
- Arquivos de tokens (JSON/CSS/Swift, dependendo da plataforma)
- Especificações dos componentes com medidas
- Ativos exportados nos formatos exigidos
- Documentação das interações (estados, animações)
- Anotações de acessibilidade
Tabelas de referência rápida
Princípios da Gestalt
| Princípio | Regra | Uso |
|---|---|---|
| Proximidade | Relacionado = próximo | Formulários, seções |
| Semelhança | Mesma aparência = mesma função | Botões, cards |
| Figura-Fundo | Separação clara entre camadas | Modais, cards |
| Continuidade | Siga as linhas | Linhas do tempo, alinhamento |
| Fechamento | O cérebro completa as formas | Ícones, indicações de rolagem |
Tipografia
| Elemento | Tamanho | Peso | Altura da linha |
|---|---|---|---|
| Corpo do texto | 16px | 400 | 1,5-1,7 |
| Títulos | 24-48px | 600-700 | 1,1-1,2 |
| Rótulos da UI | 12-14px | 500 | 1,3-1,4 |
| Legendas | 12px | 400 | 1,4 |
Funções das cores
| Função | Modo claro | Dark mode |
|---|---|---|
| Fundo | #ffffff | #0f172a |
| Superfície | #f4f5f7 | #1e293b |
| Borda | #e4e6ea | #334155 |
| Texto | #1a1a2e | #f1f5f9 |
| Texto secundário | #6b7280 | #94a3b8 |
| Primária | #3b82f6 | #60a5fa |
| Sucesso | #22c55e | #4ade80 |
| Erro | #ef4444 | #f87171 |
Escala de espaçamento
| Token | Valor | Uso |
|---|---|---|
| –space-1 | 4px | Espaços entre ícones |
| –space-2 | 8px | Elementos inline |
| –space-4 | 16px | Espaços padrão |
| –space-6 | 24px | Padding de cards |
| –space-8 | 32px | Espaços entre seções |
| –space-16 | 64px | Seções da página |
Checklist de design
Antes de lançar qualquer interface, verifique:
Gestalt
- [ ] Os elementos relacionados estão mais próximos entre si do que os não relacionados (Proximidade)
- [ ] Funções semelhantes têm estilos semelhantes (Semelhança)
- [ ] Há uma separação clara entre o primeiro plano e o fundo (Figura-Fundo)
- [ ] O olhar percorre o layout naturalmente (Continuidade)
Tipografia
- [ ] O tamanho-base da fonte é de pelo menos 16px
- [ ] A altura da linha é de pelo menos 1,5 no corpo do texto
- [ ] As linhas têm menos de 75 caracteres
- [ ] A hierarquia é clara (3 níveis distinguíveis)
- [ ] Uma escala consistente é usada em toda a interface
Cor
- [ ] Todos os textos atendem ao contraste de 4,5:1 (WCAG AA)
- [ ] A cor não é o único indicador (também há ícones/rótulos)
- [ ] O dark mode foi projetado de forma intencional
- [ ] A distribuição 60-30-10 foi seguida
Hierarquia visual
- [ ] É possível identificar o elemento mais importante
- [ ] O olhar percorre os elementos na ordem pretendida
- [ ] Há um CTA claro por seção
- [ ] A escala tipográfica é consistente
Espaçamento
- [ ] Todo o espaçamento usa uma escala definida (sem números arbitrários)
- [ ] Cards/componentes têm padding consistente
- [ ] O espaçamento em dispositivos móveis é confortável
- [ ] O alinhamento do grid é consistente (base de 8px)
Interação
- [ ] Os usuários conseguem alcançar seus objetivos sem precisar pensar na ferramenta?
- [ ] A UI se adapta ao contexto atual?
- [ ] As ferramentas aparecem apenas quando são relevantes?
- [ ] O uso recorrente ensina métodos mais rápidos?
Interfaces de IA
- [ ] Toda afirmação factual tem uma fonte rastreável
- [ ] O streaming mostra as etapas do processo, não apenas um indicador de carregamento
- [ ] Os estados de erro são transparentes, não ocultos
- [ ] Resultados com baixa confiança têm uma diferenciação visual
Verificação de Dieter Rams
- [ ] É possível remover alguma coisa?
- [ ] Cada elemento cumpre uma função?
- [ ] Isso pareceria ultrapassado daqui a 5 anos?
- [ ] Projetei todos os estados?
Recursos
Livros: - As Little Design as Possible, de Sophie Lovell (Dieter Rams) - The Elements of Typographic Style, de Robert Bringhurst
Ferramentas: - Verificador de contraste do WebAIM - Gerador de escala tipográfica - Figma Tokens Studio — Gerenciamento de tokens de design
Sistemas de design: - Apple HIG - Material Design 3 - Radix UI - shadcn/ui
Estudos de design
Análises aprofundadas de 48 produtos excepcionais, documentando padrões e princípios que vale a pena aproveitar.
Ferramentas para desenvolvedores e AI
| Produto | Principal contribuição |
|---|---|
| Figma | Presença multiusuário, painéis sensíveis ao contexto |
| Warp | Terminal baseado em blocos, ponte entre CLI e GUI |
| Framer | Design responsivo visual, controles de propriedades |
| Vercel | Excelência no modo escuro, status ambiente |
| Linear | Optimistic UI, fluxo de trabalho centrado no teclado |
| Raycast | Sistema de extensões, ações rápidas |
| Stripe | Excelência na documentação, design de API |
| Perplexity | AI centrada em citações, fases de streaming |
| Obsidian | Composição local-first, interfaces de grafos de conhecimento |
Ferramentas nativas da Apple e de criação
| Produto | Principal contribuição |
|---|---|
| Flighty | 15 estados inteligentes, Live Activities, visualização de dados |
| Halide | Ativação inteligente, controles por gestos |
| Bear | Tipografia em primeiro lugar, tags integradas ao texto |
| Craft | Experiência nativa em várias plataformas, páginas aninhadas |
| Things | Datas adiadas, padrões de entrada rápida |
| Darkroom | UI escura e imersiva, edição centrada em fotos |
| Procreate | Ferramentas criativas centradas em gestos |
| Overcast | Engenharia de áudio invisível como design de interface |
| Camo | UI profissional para produção de vídeo |
| Ivory | Timeline bem elaborada, precisão divertida |
| Anybox | Transparência nativa da plataforma |
| Drafts | Clareza na captura centrada em texto |
| Notion Calendar | Precisão no calendário, integração com o workspace |
Produtividade, conhecimento e finanças
| Produto | Principal contribuição |
|---|---|
| Superhuman | Regra dos 100 ms, treinamento da paleta de comandos, onboarding com prática |
| Notion | Sistema de blocos, comandos com barra |
| Arc | Espaços, visualização dividida, barra de comandos |
| Todoist | Minimalismo acolhedor, máxima contenção |
| Amie | Produtividade prazerosa, minimalismo acolhedor |
| Loom | Profissionalismo amigável em vídeos assíncronos |
| Pitch | Linguagem visual marcante para apresentações |
| Readwise Reader | Ferramentas para leitura profunda, identidade visual cósmica |
| Copilot Money | Visualização cinematográfica de dados financeiros |
| 1Password | Segurança sem atritos |
| Mercury | Sofisticação cinematográfica para serviços bancários |
Consumo, interação social e confiança
| Produto | Principal contribuição |
|---|---|
| Spotify | Cor, emoção e escala |
| Duolingo | Gamificação como linguagem de design |
| Signal | Segurança por meio da simplicidade |
| Airbnb | Confiança na escala de um marketplace |
| Bluesky | Transparência algorítmica |
| Letterboxd | Cinema como objeto social |
| Strava | Dados de GPS como moeda social |
| Apple Music | Voz editorial, áudio espacial |
| Headspace | Calma como estratégia de interface |
| Zomato | UX gastronômica guiada pela personalidade |
Produtos físicos, jogos e acessibilidade
| Produto | Principal contribuição |
|---|---|
| Balatro | Ciclos de feedback, sistemas de sensação de jogo |
| Rivian | Fotografia de aventura e tipografia monumental |
| Teenage Engineering | Restrições como identidade estética |
| OKO | Acessibilidade por áudio e resposta tátil |
| CARROT Weather | Personalidade como diferencial em aplicativos utilitários |
Este guia evolui com a prática. Os princípios de design são atemporais, mas sua aplicação muda com a tecnologia e o conhecimento.