feat: comprehensive design system overhaul

Applied impeccable design critique, audit, harden, layout, distill, and polish across all pages.

DESIGN SYSTEM:
- Created PRODUCT.md (5 design principles, WCAG 2.1 AA target)
- Created DESIGN.md (34 color tokens, 6 radius scale, full component spec)
- Created .impeccable/design.json (sidecar with tonal ramps, shadows, motion)

ACCESSIBILITY:
- 33 aria-labels across 7 pages (was ~13)
- 63 <label> elements (was ~30)
- 6 <main> landmarks + role=navigation on all sidebars
- Esc to close modals on 4 pages
- Keyboard shortcuts (Ctrl+J/K, Ctrl+F) on chat

THEMING:
- 216 hardcoded colors replaced with var() references
- 449 !important removed from dark-mode.css
- Dark mode script unified (was duplicated 9x inline)
- All modals converted to .modal-overlay + .modal design system classes

CHAT:
- Error states for messages (.msg.erro, .msg.enviando)
- Connection status indicator
- Confirmation modal before finalizar
- Input bar reorganized (3 visible actions, + menu)
- Right panel accordions
- Send button disabled when empty
- Touch targets 44px on mobile

CLIENT DETAIL:
- Tabs/badges/sub-tabs use CSS classes instead of inline styles
- 'Iniciar Conversa' button now primary action
- alert() replaced with inline feedback
- Modal converted to design system classes

CLIENT LIST:
- Modal moved inside <body> (was HTML-invalid)
- alert() replaced with inline feedback
- Modal uses .show pattern

SETTINGS:
- 4 modals converted to design system classes
- 14 alert() calls replaced with inline feedback
- fecharModal() uses classList instead of style.display

ROUTES:
- border-radius normalized, hardcoded colors fixed

Score progression:
  Chat:        23 → 32/40
  Client List: 32 → 35/40
  Client Detail: 26 → 30/40
  Settings:     29 → 35/40
  Routes:       37 → 38/40
  Audit (project): 14/20 → 17/20
This commit is contained in:
2026-06-23 16:58:12 +00:00
parent cf720c37a1
commit 12d419de7c
113 changed files with 52423 additions and 951 deletions
@@ -0,0 +1,52 @@
---
target: src/public/chat.html
total_score: 23
p0_count: 0
p1_count: 3
timestamp: 2026-06-23T14-35-01Z
slug: src-public-chat-html
---
# Design Critique: Chat — Chatc2
**Target:** src/public/chat.html
**Score:** 23/40 (Acceptable)
## Design Health Score
| # | Heuristic | Score | Key Issue |
|---|-----------|-------|-----------|
| 1 | Visibility of System Status | 3 | Sem indicador de digitando, sem status de conexão, sem feedback de erro visível |
| 2 | Match System / Real World | 3 | Padrão WhatsApp familiar; termos como associar precisam de contexto |
| 3 | User Control and Freedom | 3 | Cancel em modais; sem undo em mensagens; sem reabertura direta |
| 4 | Consistency and Standards | 2 | 30+ violações de design system (cores/radii fora do DESIGN.md) |
| 5 | Error Prevention | 2 | Botão enviar ativo sem texto; sem confirmação ao finalizar |
| 6 | Recognition Rather Than Recall | 3 | Tabs com contagens; ícones ambíguos sem labels |
| 7 | Flexibility and Efficiency | 2 | Sem atalhos de teclado; zero ações em lote |
| 8 | Aesthetic and Minimalist Design | 3 | Visual limpo; painel direito pode sobrecarregar |
| 9 | Error Recovery | 1 | Zero indicadores visuais de erro em toda a interface |
| 10 | Help and Documentation | 1 | Sem tooltips, ajuda contextual ou onboarding |
| **Total** | | **23/40** | **Acceptable** |
## Anti-Patterns Verdict
NAO parece gerado por IA. Interface com identidade própria (padrão WhatsApp). Detector: 34 advisories de drift de design system, 2 warnings (single-font = falso positivo intencional, dark-glow merece atenção).
## Overall Impression
Tela de chat funcionalmente sólida, WhatsApp-style bem executado, dark mode completo, mobile responsivo. Problema crítico: resiliência — zero feedback de erro. Mais drift de design system e falta de atalhos para uso intensivo.
## Priority Issues
[P1] Design system drift — 30+ valores fora do DESIGN.md. Cores e raios do chat precisam ser incorporados ou consolidados.
[P1] Zero visibilidade de erro — mensagem falhou, upload quebrou, conexão caiu: atendente fica no escuro.
[P1] Chat input com 5 botões competindo — ícones ambíguos, sem labels, peso visual similar.
[P2] Painel direito sobrecarregado — todas as seções visíveis, scroll excessivo.
[P2] Zero atalhos de teclado — 8h+/dia sem atalhos gera fadiga.
## Persona Red Flags
Alex (Power User): Sem atalhos, sem notificação de novas conversas, 5 botões sempre visíveis.
Jordan (First-Timer): Ícones sem texto, toggle privada ambíguo, sem onboarding.
Sam (Accessibility): Botões emoji sem aria-label, enviar sem nome acessível, sem trap de foco em modais.
## Minor Observations
- Padrão SVG do fundo é toque WhatsApp autêntico
- Botão Finalizar sem confirmação
- Drag-overlay excelente affordance
- border-radius: 22px vs 50% inconsistente
- Empresa-tag com border-radius inline
+377
View File
@@ -0,0 +1,377 @@
{
"schemaVersion": 2,
"generatedAt": "2026-06-23T17:00:00.000Z",
"title": "Design System: Chatc2",
"extensions": {
"colorMeta": {
"indigo-funcional": {
"role": "primary",
"displayName": "Índigo Funcional",
"canonical": "#667eea",
"tonalRamp": [
"#1a1a5e", "#2a2a7e", "#3a3a9e", "#4a4abe",
"#667eea", "#8888f0", "#aaaaf6", "#ccccfa"
]
},
"indigo-profundo": {
"role": "primary",
"displayName": "Índigo Profundo",
"canonical": "#5a67d8",
"tonalRamp": [
"#151860", "#252878", "#353a90", "#454ca8",
"#5a67d8", "#7a84e6", "#9aa1f0", "#babff8"
]
},
"violeta-apoio": {
"role": "secondary",
"displayName": "Violeta de Apoio",
"canonical": "#764ba2",
"tonalRamp": [
"#1e0a3c", "#2e1658", "#3e226e", "#4e2e84",
"#764ba2", "#9678c0", "#b69ed8", "#d6c4ee"
]
},
"meia-noite-inicio": {
"role": "neutral",
"displayName": "Meia-Noite Início",
"canonical": "#1e1b4b",
"tonalRamp": [
"#0a0830", "#100e40", "#181450", "#1e1b4b",
"#2e2b68", "#3e3b82", "#4e4b9a", "#5e5bb0"
]
},
"meia-noite-fim": {
"role": "neutral",
"displayName": "Meia-Noite Fim",
"canonical": "#312e81",
"tonalRamp": [
"#101040", "#1a1858", "#242270", "#312e81",
"#4a4898", "#6462ae", "#7e7cc4", "#9896da"
]
},
"papel-limpo": {
"role": "neutral",
"displayName": "Papel Limpo",
"canonical": "#ffffff",
"tonalRamp": [
"#f0f0f0", "#f3f3f3", "#f6f6f6", "#f9f9f9",
"#ffffff", "#ffffff", "#ffffff", "#ffffff"
]
},
"papel-suave": {
"role": "neutral",
"displayName": "Papel Suave",
"canonical": "#f9fafb",
"tonalRamp": [
"#e8eaed", "#edeff2", "#f2f4f6", "#f6f7f9",
"#f9fafb", "#fbfcfc", "#fdfdfd", "#fefefe"
]
},
"papel-frio": {
"role": "neutral",
"displayName": "Papel Frio",
"canonical": "#f3f4f6",
"tonalRamp": [
"#e0e2e6", "#e5e7eb", "#eaecf0", "#eff0f3",
"#f3f4f6", "#f7f7f9", "#fafafb", "#fcfcfd"
]
},
"grafite": {
"role": "neutral",
"displayName": "Grafite",
"canonical": "#111827",
"tonalRamp": [
"#0a0e14", "#0d1118", "#0f141e", "#101724",
"#111827", "#1f2937", "#374151", "#4b5563"
]
},
"verde-confirma": {
"role": "semantic",
"displayName": "Verde Confirma",
"canonical": "#059669",
"tonalRamp": [
"#002a18", "#004228", "#005a34", "#007240",
"#059669", "#22b87a", "#40d492", "#60eaaa"
]
},
"vermelho-alerta": {
"role": "semantic",
"displayName": "Vermelho Alerta",
"canonical": "#ef4444",
"tonalRamp": [
"#3c0000", "#5c0000", "#7c0808", "#9c1414",
"#ef4444", "#f47070", "#f89898", "#fcc0c0"
]
},
"ambar-aviso": {
"role": "semantic",
"displayName": "Âmbar Aviso",
"canonical": "#f59e0b",
"tonalRamp": [
"#3c2400", "#5c3800", "#7c4c00", "#9c6000",
"#f59e0b", "#f7b840", "#f9ce70", "#fbe4a0"
]
},
"verde-whatsapp": {
"role": "semantic",
"displayName": "Verde WhatsApp",
"canonical": "#25d366",
"tonalRamp": [
"#003d10", "#005d1a", "#007d24", "#009d2e",
"#25d366", "#45e880", "#65f0a0", "#85f8c0"
]
},
"bolha-agente": {
"role": "semantic",
"displayName": "Bolha Agente",
"canonical": "#dcf8c6",
"tonalRamp": [
"#8cb870", "#a8d090", "#bce8a8", "#ccf0b6",
"#dcf8c6", "#e8fad6", "#f0fce6", "#f8fef0"
]
},
"bolha-privada-bg": {
"role": "semantic",
"displayName": "Bolha Privada Fundo",
"canonical": "#fef9c3",
"tonalRamp": [
"#b0a840", "#c8c060", "#d8d480", "#e8e8a0",
"#fef9c3", "#fefbd6", "#fefde8", "#fffef4"
]
},
"chat-wallpaper": {
"role": "neutral",
"displayName": "Chat Wallpaper",
"canonical": "#e5ddd5",
"tonalRamp": [
"#b0a898", "#c0b8a8", "#d0c8b8", "#d8d0c8",
"#e5ddd5", "#eae4de", "#f0ece8", "#f6f4f0"
]
},
"violeta-tab": {
"role": "primary",
"displayName": "Violeta Tab",
"canonical": "#a78bfa",
"tonalRamp": [
"#403060", "#604890", "#8060c0", "#9070e0",
"#a78bfa", "#b8a0fc", "#c8b8fe", "#d8d0ff"
]
},
"vermelho-hover": {
"role": "semantic",
"displayName": "Vermelho Hover",
"canonical": "#dc2626",
"tonalRamp": [
"#3c0000", "#5c0808", "#7c1010", "#9c1818",
"#dc2626", "#f05050", "#f88080", "#fcb0b0"
]
},
"cinza-borda-hover": {
"role": "neutral",
"displayName": "Cinza Borda Hover",
"canonical": "#d1d5db",
"tonalRamp": [
"#a0a4aa", "#b0b4ba", "#c0c4ca", "#c8ccd2",
"#d1d5db", "#dce0e6", "#e8ecf0", "#f4f6f8"
]
}
},
"typographyMeta": {
"display": {
"displayName": "Display",
"purpose": "Título da página de login. Uso exclusivo em momentos de entrada."
},
"title": {
"displayName": "Title",
"purpose": "Título da topbar e cabeçalhos de seção principal."
},
"body": {
"displayName": "Body",
"purpose": "Texto corrido, labels, conteúdo de mensagens, células de tabela."
},
"label": {
"displayName": "Label",
"purpose": "Rótulos de navegação, cabeçalhos de tabela, metadados. Sempre uppercase com tracking."
}
},
"shadows": [
{
"name": "ambient",
"value": "0 1px 3px rgba(0,0,0,0.08)",
"purpose": "Cards estáticos e topbar. Sombra padrão para separação sutil."
},
{
"name": "floating",
"value": "0 4px 16px rgba(0,0,0,0.10)",
"purpose": "Elementos com destaque moderado: dropdowns, previews."
},
{
"name": "modal",
"value": "0 20px 60px rgba(0,0,0,0.18)",
"purpose": "Exclusivo para overlays de modal, combinado com backdrop-filter blur."
}
],
"motion": [
{
"name": "ease-standard",
"value": "all 0.15s ease",
"purpose": "Transição padrão para todos os estados interativos: hover, focus, active."
},
{
"name": "modal-enter",
"value": "0.18s ease",
"purpose": "Animação de entrada de modais: fade + scale(0.96 → 1)."
}
],
"breakpoints": [
{ "name": "tablet", "value": "768px" },
{ "name": "desktop-sm", "value": "1024px" },
{ "name": "mobile-sm", "value": "480px" }
]
},
"components": [
{
"name": "Primary Button",
"kind": "button",
"refersTo": "button-primary",
"description": "Ação principal. Fundo índigo funcional, resposta imediata ao hover e active.",
"html": "<button class=\"ds-btn-primary\">ENVIAR</button>",
"css": ".ds-btn-primary { background: #667eea; color: #fff; border: 1px solid #667eea; padding: 9px 18px; border-radius: 10px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.15s ease; font-family: inherit; display: inline-flex; align-items: center; gap: 6px; } .ds-btn-primary:hover { background: #5a67d8; border-color: #5a67d8; } .ds-btn-primary:active { transform: scale(0.98); } .ds-btn-primary:focus-visible { outline: 2px solid #667eea; outline-offset: 2px; }"
},
{
"name": "Secondary Button",
"kind": "button",
"refersTo": "button-secondary",
"description": "Ação secundária. Fundo branco com borda cinza. Hover suave para papel-suave.",
"html": "<button class=\"ds-btn-secondary\">CANCELAR</button>",
"css": ".ds-btn-secondary { background: #ffffff; color: #374151; border: 1px solid #e5e7eb; padding: 9px 18px; border-radius: 10px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.15s ease; font-family: inherit; display: inline-flex; align-items: center; gap: 6px; } .ds-btn-secondary:hover { background: #f9fafb; } .ds-btn-secondary:active { transform: scale(0.98); } .ds-btn-secondary:focus-visible { outline: 2px solid #667eea; outline-offset: 2px; }"
},
{
"name": "Danger Button",
"kind": "button",
"refersTo": "button-danger",
"description": "Ação destrutiva. Exclusivo para excluir, finalizar, remover.",
"html": "<button class=\"ds-btn-danger\">EXCLUIR</button>",
"css": ".ds-btn-danger { background: #ef4444; color: #fff; border: 1px solid #ef4444; padding: 9px 18px; border-radius: 10px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.15s ease; font-family: inherit; display: inline-flex; align-items: center; gap: 6px; } .ds-btn-danger:hover { background: #dc2626; border-color: #dc2626; } .ds-btn-danger:active { transform: scale(0.98); } .ds-btn-danger:focus-visible { outline: 2px solid #ef4444; outline-offset: 2px; }"
},
{
"name": "Text Input",
"kind": "input",
"refersTo": "input-text",
"description": "Campo de texto padrão com ring de foco de 3px como assinatura de acessibilidade.",
"html": "<input class=\"ds-input-text\" type=\"text\" placeholder=\"Buscar...\" />",
"css": ".ds-input-text { width: 100%; padding: 10px 14px; border: 2px solid #e5e7eb; border-radius: 10px; font-size: 14px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; color: #111827; background: #f9fafb; outline: none; transition: all 0.15s ease; } .ds-input-text:focus { border-color: #667eea; background: #ffffff; box-shadow: 0 0 0 3px rgba(102,126,234,0.12); } .ds-input-text::placeholder { color: #6b7280; } .ds-input-text.error { border-color: #ef4444; background: #fef2f2; }"
},
{
"name": "Card",
"kind": "card",
"refersTo": "card",
"description": "Container padrão para conteúdo. Fundo branco, borda sutil, sombra ambient.",
"html": "<div class=\"ds-card\"><h3>Título do Card</h3><p>Conteúdo do card com informações relevantes para o atendente.</p></div>",
"css": ".ds-card { background: #ffffff; border-radius: 16px; padding: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); border: 1px solid #f3f4f6; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } .ds-card h3 { font-size: 15px; font-weight: 600; color: #374151; margin: 0 0 16px 0; } .ds-card p { font-size: 14px; color: #374151; margin: 0; line-height: 1.5; }"
},
{
"name": "Stat Card",
"kind": "card",
"refersTo": "stat-card",
"description": "Card de métrica do dashboard com faixa lateral colorida como identificador semântico.",
"html": "<div class=\"ds-stat-card ds-stat-abertas\"><div class=\"ds-stat-num\">42</div><div class=\"ds-stat-lbl\">Conversas Abertas</div></div>",
"css": ".ds-stat-card { background: #ffffff; border-radius: 12px; padding: 18px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); border-left: 4px solid #9ca3af; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } .ds-stat-abertas { border-left-color: #059669; } .ds-stat-num { font-size: 32px; font-weight: 800; color: #111827; line-height: 1; } .ds-stat-lbl { font-size: 13px; color: #6b7280; margin-top: 6px; font-weight: 600; }"
},
{
"name": "Badge / Chip",
"kind": "chip",
"refersTo": "badge",
"description": "Indicador de status. Totalmente arredondado, trio semântico completo.",
"html": "<span class=\"ds-badge ds-badge-success\">ATIVO</span>",
"css": ".ds-badge { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 20px; font-size: 12px; font-weight: 600; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } .ds-badge-success { background: #d1fae5; color: #065f46; } .ds-badge-danger { background: #fef2f2; color: #991b1b; } .ds-badge-warning { background: #fef3c7; color: #92400e; }"
},
{
"name": "Navigation Sidebar",
"kind": "nav",
"refersTo": "sidebar",
"description": "Barra lateral noturna fixa. Âncora de navegação em todas as páginas.",
"html": "<nav class=\"ds-sidebar\"><div class=\"ds-sidebar-brand\">Chatc2</div><a href=\"#\" class=\"ds-sidebar-link active\">📊 Dashboard</a><a href=\"#\" class=\"ds-sidebar-link\">👥 Clientes</a></nav>",
"css": ".ds-sidebar { width: 240px; background: linear-gradient(180deg, #1e1b4b 0%, #312e81 100%); display: flex; flex-direction: column; flex-shrink: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } .ds-sidebar-brand { padding: 20px 18px; border-bottom: 1px solid rgba(255,255,255,0.08); color: #fff; font-size: 16px; font-weight: 700; letter-spacing: -0.2px; } .ds-sidebar-link { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 8px; color: rgba(255,255,255,0.72); text-decoration: none; font-size: 14px; margin: 1px 10px; transition: all 0.15s ease; } .ds-sidebar-link:hover { background: rgba(255,255,255,0.10); color: #fff; } .ds-sidebar-link.active { background: rgba(255,255,255,0.16); color: #fff; font-weight: 600; }"
},
{
"name": "Modal",
"kind": "custom",
"refersTo": "modal",
"description": "Overlay com blur. A caixa de diálogo definitiva do Chatc2.",
"html": "<div class=\"ds-modal-overlay show\"><div class=\"ds-modal-box\"><h3>Confirmação</h3><p>Tem certeza que deseja prosseguir?</p><div class=\"ds-modal-footer\"><button class=\"ds-btn-secondary\">Cancelar</button><button class=\"ds-btn-primary\">Confirmar</button></div></div></div>",
"css": ".ds-modal-overlay { background: rgba(0,0,0,0.48); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } .ds-modal-box { background: #ffffff; border-radius: 16px; padding: 28px; width: 90%; max-width: 440px; box-shadow: 0 20px 60px rgba(0,0,0,0.18); animation: ds-modalIn 0.18s ease; } @keyframes ds-modalIn { from { opacity: 0; transform: scale(0.96) translateY(-10px); } to { opacity: 1; transform: scale(1) translateY(0); } } .ds-modal-box h3 { margin: 0 0 18px 0; font-size: 17px; font-weight: 700; color: #111827; } .ds-modal-box p { margin: 0 0 20px 0; font-size: 14px; color: #374151; } .ds-modal-footer { display: flex; gap: 8px; justify-content: flex-end; }"
},
{
"name": "Chat Bubble - Cliente",
"kind": "custom",
"refersTo": "msg-cliente",
"description": "Bolha de mensagem do cliente. Alinhada à esquerda, fundo branco com borda sutil.",
"html": "<div class=\"ds-msg-cliente\">Olá, preciso de ajuda com meu boleto.</div>",
"css": ".ds-msg-cliente { align-self: flex-start; background: #ffffff; border: 1px solid #f3f4f6; padding: 10px 14px; border-radius: 16px; border-top-left-radius: 4px; max-width: 70%; font-size: 14px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; color: #111827; word-wrap: break-word; }"
}
],
"narrative": {
"northStar": "O Terminal Humanizado",
"overview": "O Chatc2 é um terminal funcional — preciso, confiável, sem firulas — mas que não esquece que do outro lado da tela há uma pessoa. A interface respira. Curvas suaves (6px16px) substituem cantos duros de terminal. O espaço entre elementos é generoso o suficiente para não cansar, mas econômico o bastante para manter densidade de informação. Toques de índigo funcional guiam o olhar sem gritar. O sidebar noturno ancora a experiência com profundidade, como um painel de comando que nunca apaga. O sistema rejeita explicitamente a poluição visual e a ambiguidade. Cada estado tem feedback imediato. Cada cor tem um porquê. Cada pixel de sombra existe para hierarquia, não por decoração.",
"keyCharacteristics": [
"Paleta enxuta: um acento índigo + violeta de apoio + neutros limpos",
"Dark mode como cidadão de primeira classe",
"Sombras leves — destaque sem peso",
"Tipografia de sistema: nativa, zero latência",
"Componentes táteis que respondem ao toque com confiança"
],
"rules": [
{
"name": "The One Voice Rule",
"body": "O índigo funcional ocupa ≤10% de qualquer tela. Sua raridade é o ponto. Se tudo é índigo, nada é importante.",
"section": "colors"
},
{
"name": "The Semantic Triplet Rule",
"body": "Estados (sucesso, erro, aviso) sempre usam o trio completo: cor de destaque + fundo claro + texto escuro. Nunca usar a cor de destaque como fundo de texto corrido.",
"section": "colors"
},
{
"name": "The Native-First Rule",
"body": "Nunca importar webfonts. O sistema operacional já tem tipografia excelente.",
"section": "typography"
},
{
"name": "The Weight Discipline Rule",
"body": "Apenas três pesos convivem: 400 (corpo), 600 (labels), 700800 (títulos). Nunca usar 300, 500 ou 900.",
"section": "typography"
},
{
"name": "The Flat-by-Default Rule",
"body": "A superfície base é plana. Sombras aparecem apenas quando um elemento precisa de separação hierárquica — nunca por decoração.",
"section": "elevation"
},
{
"name": "The Dark Mode Elevation Rule",
"body": "No dark mode, sombras são abolidas. A diferenciação entre superfícies é 100% tonal.",
"section": "elevation"
}
],
"dos": [
"Usar o índigo funcional (#667eea) em ≤10% da superfície visível. Ele é um acento, não uma cor de fundo.",
"Garantir que todo estado interativo tenha feedback em ≤150ms.",
"Comunicar estado com ícone + cor. Nunca apenas cor.",
"Usar o trio semântico completo para qualquer indicador de estado.",
"Manter o dark mode com diferenciação tonal, nunca com sombras.",
"Usar border-left: 4px solid com cor semântica para stat cards no dashboard.",
"Usar padding mínimo de 24px em cards, 14px 24px na topbar.",
"Preservar a barra lateral noturna em todas as páginas."
],
"donts": [
"Criar interfaces abarrotadas onde o atendente precise adivinhar onde as coisas estão.",
"Usar mais de 3 pesos tipográficos na mesma tela.",
"Importar webfonts externas.",
"Usar sombras em dark mode.",
"Usar cores semânticas como cor de fundo para texto corrido.",
"Criar modais sem overlay escuro + blur.",
"Usar cantos vivos (border-radius: 0) em componentes interativos.",
"Omitir o ring de foco de 3px em inputs."
]
}
}
+6
View File
@@ -0,0 +1,6 @@
{
"files": ["src/public/**/*.html"],
"insertBefore": "</body>",
"commentSyntax": "html",
"cspChecked": true
}