186 lines
14 KiB
Markdown
186 lines
14 KiB
Markdown
---
|
||
type: rule
|
||
name: refactoring-ui-hierarquia-despoluicao
|
||
description: Diretrizes obrigatórias do livro Refactoring UI (Steve Schoger & Adam Wathan) para eliminar poluição visual, excesso de bordas, botões concorrentes e falta de hierarquia nos frontends.
|
||
scope: global
|
||
trigger: always_on
|
||
priority: alta
|
||
updatedAt: "2026-10-26"
|
||
---
|
||
|
||
# Regra: Despoluição Visual e Hierarquia de UI (*Refactoring UI*)
|
||
|
||
## Contexto
|
||
|
||
Interfaces geradas sem disciplina de hierarquia visual tendem a sair **carregadas, barulhentas e confusas**: cartões dentro de cartões com bordas e divisores em excesso (*Card-ception*), múltiplos botões coloridos sólidos competindo por atenção, dezenas de pares `Rótulo: Valor` com mesmo peso visual, tabelas espremidas com 10+ colunas e formulários esticados por toda a tela.
|
||
|
||
Toda construção ou refatoração em pacotes `*-front` (`@front`, `@ux`, `@land`) **DEVE** obedecer aos 6 pilares práticos de **Steve Schoger & Adam Wathan (*Refactoring UI*)**.
|
||
|
||
- **Obra de referência completa (consulta online no Paiol):** `https://adm.paiol.idz.one/estaticos/Refactoring-UI-Steve-Schoger-Adam-Wathan.pdf`
|
||
|
||
---
|
||
|
||
## Regra
|
||
|
||
### 1. Hierarquia Visual por Peso e Contraste (Cap. 2 — *Hierarquia é Tudo*)
|
||
|
||
1. **3 Níveis de Cor de Texto e 2 Pesos de Fonte:**
|
||
- **Pesos permitidos:** `400`/`500` para texto normal e `600`/`700` para ênfase (títulos, valores principais, células-chave). **Proibido** usar peso `< 400` ou fonte `< 12px` para des-enfatizar texto (reduz legibilidade).
|
||
- **Cores de texto:** Primário escuro (`--cor-eli-primaria-texto` `#2E3F00` ou `#212529`), Secundário médio (`--cor-eli-neutro` `#5E6553` ou `#495057`) e Terciário discreto para metadados auxiliares.
|
||
2. **Enfatizar Des-enfatizando (*Emphasize by de-emphasizing*):**
|
||
- Quando um elemento principal não se destaca, **não** aumente sua fonte ou saturação indefinidamente: reduza o contraste dos elementos que competem com ele (itens inativos, textos de apoio, barras laterais sem caixas pesadas).
|
||
3. **Rótulos são o Último Recurso (*Labels are a last resort*):**
|
||
- **Proibido** empilhar listas ingênuas de `Rótulo: Valor` vindas do banco de dados com igual peso visual.
|
||
- Omitir o rótulo quando o formato ou contexto já identifica o dado (CNPJ, e-mail, telefone, status, moeda, data) ou combinar rótulo + valor em frase natural (`"12 condicionantes pendentes"`, `"150,5 ha de área total"`).
|
||
- Quando o rótulo for necessário (ex.: cards de indicadores/KPIs), o **valor é o protagonista** (`20px–24px`, peso `600/700`, cor escura) e o rótulo é secundário (`12px`, cor neutra suave).
|
||
4. **Separar Hierarquia Visual da Semântica HTML:**
|
||
- Tags `<h1>`, `<h2>`, `<h3>` em telas de aplicação funcionam como rótulos de seção: devem ser contidas (`16px–20px`, peso `600`), nunca títulos gigantes que roubam espaço da área de trabalho.
|
||
5. **Equilibrar Peso e Contraste em Ícones (`@lucide/vue`):**
|
||
- Ícones têm maior densidade superficial que texto. Ao acompanhar um rótulo, o ícone deve ter contraste suavizado (`color` neutra/secundária, `:size="16"` a `"18"`, `:stroke-width="1.75"` ou `"2"`) para não pesar mais que o texto.
|
||
6. **Proibido Texto Cinza ou Branco Translúcido em Fundos Coloridos:**
|
||
- Sobre fundos coloridos, texto secundário nunca deve ser cinza puro nem branco com `opacity` reduzida: escolher tom da mesma matiz com luminosidade ajustada (ex.: `#2E3F00` sobre `#EEF3D0`).
|
||
|
||
### 2. Pirâmide de Ações: A Semântica é Secundária (Cap. 2, p. 60)
|
||
|
||
1. **Apenas 1 Ação Primária Verdadeira por Vista/Seção:**
|
||
- Somente a ação principal da tela recebe botão sólido de alto contraste (`color="primary" variant="flat"`).
|
||
2. **Ações Secundárias e Terciárias:**
|
||
- **Secundárias** (ex.: *Filtrar, Exportar, Voltar*): usar `variant="outlined"` ou `variant="tonal"` com cor neutra/secundária escura (`#3E4436` / `#495057`).
|
||
- **Terciárias** (ex.: *Cancelar, Limpar, Ver mais*): usar estilo discreto (`variant="text"`).
|
||
3. **Ações Destrutivas Discretas Fora do Modal:**
|
||
- Ser uma ação destrutiva (*Excluir, Remover, Arquivar*) **NÃO** significa que o botão deva ser vermelho sólido e chamativo na página principal ou em cada linha da tabela.
|
||
- Na tela principal/listagem, ações destrutivas devem usar tratamento secundário/terciário discreto (`variant="text"` neutro com hover em `--cor-eli-erro`, ou agrupadas em `v-menu`). O botão vermelho sólido (`color="error" variant="flat"`) deve existir **exclusivamente dentro do modal de confirmação**.
|
||
|
||
### 3. Anti-Ruído: Use Menos Bordas e Zero *Card-ception* (Cap. 7, p. 238)
|
||
|
||
1. **Proibido Aninhar Cartões com Borda (*Card-ception*):**
|
||
- **NUNCA** colocar `v-card` com borda (`variant="outlined"` ou `border`) dentro de outro `v-card` com borda, nem inserir `<v-divider>` a cada par de linhas.
|
||
2. **3 Alternativas Obrigatórias ao Excesso de Bordas:**
|
||
- **Contraste de superfície:** posicionar o card branco (`--cor-eli-superficie` `#FFFFFF`) diretamente sobre o fundo neutro da página (`--cor-eli-fundo` `#F2F3EE` ou `#EBEDF0`), dispensando bordas pesadas.
|
||
- **Sombra sutil de elevação:** usar `box-shadow` leve para delinear o container sem linha dura.
|
||
- **Espaçamento extra:** aumentar a distância entre grupos (`24px–32px`) em vez de desenhar linhas divisórias (`<v-divider>`).
|
||
|
||
### 4. Espaço em Branco, Proximidade e Largura Ideal (Cap. 3, p. 66–99)
|
||
|
||
1. **Começar com Espaço em Branco Generoso:**
|
||
- O respiro visual (`pa-6`, `ga-6`) é o padrão; compactar apenas deliberadamente em tabelas operacionais densas.
|
||
2. **Evitar Espaçamento Ambíguo (Lei da Proximidade):**
|
||
- Deve haver **sempre mais espaço ao redor de um grupo do que dentro dele**:
|
||
- Entre label e input: `4px–6px`
|
||
- Entre um campo e o próximo campo: `16px–20px`
|
||
- Entre seções distintas de um formulário/tela: `32px–40px`
|
||
3. **Não Preencher a Tela Inteira sem Necessidade:**
|
||
- Formulários simples, cartões de leitura ou configurações não devem ser esticados em `100%` da largura (`1360px+`). Limitar à largura ideal (`max-width: 640px–800px`) ou usar layout em 2 colunas assimétricas (título e texto explicativo da seção à esquerda em `4 cols` + card de campos à direita em `8 cols`).
|
||
4. **Larguras Fixas Onde Necessário:**
|
||
- Não usar colunas fluidas percentuais para elementos que exigem largura fixa otimizada (menus laterais, colunas de ações, avatares, badges de status).
|
||
|
||
### 5. Tabelas Escaneáveis e Tipografia Refinada (Caps. 4 e 7, p. 102–135, 242)
|
||
|
||
1. **Combinar Colunas Relacionadas em Tabelas:**
|
||
- **Proibido** criar tabelas espremidas com 8–15 colunas onde cada campo vira uma coluna isolada.
|
||
- Combinar dados correlatos em uma única célula com hierarquia de 2 linhas (ex.: Linha 1 em `14px` peso `600` escuro com *Razão Social*; Linha 2 em `12px` peso `400` neutro com *CNPJ • Município/UF*).
|
||
2. **Alinhamento e Ritmo Tipográfico:**
|
||
- Textos alinhados à esquerda; números, quantidades e valores monetários alinhados à **direita** com `font-variant-numeric: tabular-nums`.
|
||
- Comprimento de linha de parágrafos e textos de ajuda limitado a `45ch–75ch`.
|
||
- `line-height` inversamente proporcional ao tamanho da fonte: `1.15–1.25` para títulos grandes/números de KPI e `1.5` para corpo de texto.
|
||
- Alinhar pela linha de base (`align-baseline`) ao misturar tamanhos de fonte na mesma linha (ex.: título + subtítulo/contador).
|
||
- Textos em `UPPERCASE` (cabeçalhos de tabela, siglas, badges) devem ter tamanho reduzido (`11px–12px`), peso `600` e `letter-spacing: 0.05em`.
|
||
|
||
### 6. Contraste Invertido, Ícones e Estados Vazios (Caps. 5, 6 e 7)
|
||
|
||
1. **Contraste Invertido em Badges e Alertas (p. 162):**
|
||
- Evitar múltiplos chips/badges com fundo escuro saturado que competem com o botão primário. Usar **fundo claro suave (`stop 50/100`) + texto escuro da mesma matiz (`stop 800/900`)**. Nunca confiar apenas na cor (combinar com ícone ou rótulo explícito).
|
||
2. **Tamanho Pretendido de Ícones e Bordas de Acento (p. 208, 224):**
|
||
- **Proibido** ampliar ícones de `16–24px` para `48px–64px` a seco (ficam grosseiros). Para destaque em *empty states* ou cabeçalhos de cards, manter o ícone em `20px–24px` dentro de um container arredondado (`40px–48px`) com fundo suave (`--cor-eli-primaria-bg`).
|
||
- Usar bordas de acento (`border-top` ou `border-left: 3px solid var(--cor-eli-primaria)`) em cards de resumo ou alertas para dar acabamento sem ruído.
|
||
3. **Estados Vazios Despoluídos (p. 234):**
|
||
- Quando uma coleção estiver inicialmente vazia (zero registros criados), **ocultar barras de filtros secundárias, abas vazias e paginação**, exibindo somente o *Empty State* orientador com o botão de ação primária (CTA).
|
||
|
||
### 7. Ergonomia Cognitiva, Orçamento de Viewport e Densidade Visual (Leis de Sweller, Hick e Miller)
|
||
|
||
Mesmo respeitando pesos tipográficos e ausência de bordas, uma tela continuará **carregada e cansativa** se desperdiçar espaço de tela com múltiplas barras fixas, colidir painéis laterais ou pendurar dezenas de pílulas coloridas em cada linha. Todo frontend deve obedecer a 4 limites quantitativos de ergonomia espacial:
|
||
|
||
1. **Orçamento de Viewport (Regra 75/25) e Teto de 2 Faixas no Topo:**
|
||
- Em uma tela desktop padrão (`1366x768` ou `1440x900`), no mínimo **70%–75% da área da janela** deve pertencer ao **canvas principal de trabalho** (lista, árvore, tabela, Gantt, Kanban).
|
||
- **Proibido empilhar 3 a 6 barras horizontais de cabeçalho/filtros/formulários inline acima do conteúdo.** O cabeçalho operacional de uma visão deve consolidar-se em no máximo **2 faixas horizontais enxutas**:
|
||
- *Faixa 1 (Contexto):* Título do contexto ativo + KPIs resumidos inline + ações secundárias discretas/compactas.
|
||
- *Faixa 2 (Operação):* Seletor de visão/abas + busca/filtros integrados + botão `+ Novo` (revelando campos de criação inline ou modal **sob demanda**, sem manter formulários multi-campo abertos permanentemente roubando altura).
|
||
2. **Prevenção de Colisão de Painéis Laterais (*Sidebar Mutual Exclusion*):**
|
||
- **Proibido** manter abertos simultaneamente um Menu Lateral de Navegação (`240px–280px`) e um Painel Inspetor de Detalhes (`400px–440px`) quando a soma dos painéis laterais consumir mais de **30%–35% da largura da tela**, espremendo o conteúdo central.
|
||
- Ao abrir um Painel Inspetor (`Master-Detail`) ou alternar para visões de alta densidade horizontal (`Cronograma Gantt` / `Quadro Kanban`), o menu lateral secundário deve **recolher automaticamente** (`auto-collapse`), liberando largura para a área de trabalho.
|
||
3. **Orçamento de Densidade por Linha/Card (*Teto de 3 Indicadores em Repouso*):**
|
||
- Cada linha de árvore/lista ou card Kanban em estado de repouso deve exibir no máximo **3 sinais visuais** além do título (ex.: `1. Checkbox/Ícone de modalidade`, `2. Prazo ou Progresso X/Y`, `3. Indicador de bloqueio ou status crítico`).
|
||
- **Proibido o "Natal de Badges"** (empilhar 5 a 7 pílulas coloridas de modalidade, dependência, barra de progresso, moeda, data, responsável e status em cada linha, nem pintar todas as linhas concluídas com fundos e bordas saturadas).
|
||
- Ações secundárias de linha (ex.: `+ Sub`, `Editar`, `Excluir`) devem ficar ocultas ou discretas em repouso, revelando-se em `:hover` ou `:focus-within` (`opacity-0 group-hover:opacity-100`).
|
||
4. **Revelação Progressiva Intra-Painel (*Inspetor em Acordeão & Zero Card de Resumo Redundante*):**
|
||
- Painéis inspetores (`Drawer` / `Aside`) **nunca** devem iniciar com um "Card de Resumo" que duplica os mesmos dados já visíveis na linha selecionada e nos blocos editáveis imediatamente abaixo.
|
||
- No máximo **2 seções primárias** (*Identificação/Prazo* e *Entrega*) devem iniciar abertas. Seções relacionais secundárias (*Pré-requisitos/Dependências*, *Recursos e Custos*, *Responsáveis*) devem utilizar **seções colapsáveis (Acordeão)** exibindo o resumo no próprio cabeçalho (ex.: `Recursos e Custos (2 • R$ 2.424,00)`) e abrindo a lista/formulário apenas quando expandidas pelo usuário.
|
||
|
||
---
|
||
|
||
## Exemplos
|
||
|
||
### ❌ Incorreto — Tela carregada (*Card-ception*, botões brigando e rótulos redundantes)
|
||
|
||
```vue
|
||
<v-card variant="outlined" class="pa-2">
|
||
<h1 class="text-h3">Listagem de Licenças</h1>
|
||
<v-divider class="my-2" />
|
||
<v-card variant="outlined" class="pa-2 mb-2">
|
||
<div><strong>Razão Social:</strong> Mineração Vale Verde</div>
|
||
<v-divider class="my-1" />
|
||
<div><strong>CNPJ:</strong> 12.345.678/0001-90</div>
|
||
<v-divider class="my-1" />
|
||
<div><strong>Status:</strong> Vigente</div>
|
||
<div class="d-flex ga-2 mt-2">
|
||
<v-btn color="primary" variant="flat">Editar</v-btn>
|
||
<v-btn color="success" variant="flat">Renovar</v-btn>
|
||
<v-btn color="warning" variant="flat">Exportar</v-btn>
|
||
<v-btn color="error" variant="flat">Excluir</v-btn>
|
||
</div>
|
||
</v-card>
|
||
</v-card>
|
||
```
|
||
|
||
### ✅ Correto — Hierarquia clara, menos bordas e pirâmide de ações (*Refactoring UI*)
|
||
|
||
```vue
|
||
<section class="pa-6">
|
||
<header class="d-flex align-baseline justify-space-between mb-6">
|
||
<div>
|
||
<h1 class="text-h6 font-weight-semibold">Licenças Ambientais</h1>
|
||
<p class="text-body-2 text-medium-emphasis">12 licenças vigentes no período</p>
|
||
</div>
|
||
<div class="d-flex align-center ga-3">
|
||
<v-btn color="secondary" variant="outlined">Exportar</v-btn>
|
||
<v-btn color="primary" variant="flat">Nova Licença</v-btn>
|
||
</div>
|
||
</header>
|
||
|
||
<v-card flat class="pa-5 bg-surface rounded-lg">
|
||
<div class="d-flex align-center justify-space-between">
|
||
<div>
|
||
<div class="text-subtitle-1 font-weight-semibold">Mineração Vale Verde Ltda.</div>
|
||
<div class="text-caption text-medium-emphasis">12.345.678/0001-90 • Criciúma/SC</div>
|
||
</div>
|
||
<div class="d-flex align-center ga-2">
|
||
<v-btn color="secondary" variant="tonal" size="small">Renovar</v-btn>
|
||
<v-btn variant="text" size="small">Editar</v-btn>
|
||
<v-btn variant="text" color="error" size="small">Excluir</v-btn>
|
||
</div>
|
||
</div>
|
||
</v-card>
|
||
</section>
|
||
```
|
||
|
||
## Impacto
|
||
|
||
Elimina o aspecto amador, sobrecarregado e confuso das interfaces geradas pela IA, garantindo telas limpas, escaneáveis e com hierarquia visual profissional em todo o ecossistema.
|
||
|
||
## Referências
|
||
|
||
- Livro completo no Paiol: `https://adm.paiol.idz.one/estaticos/Refactoring-UI-Steve-Schoger-Adam-Wathan.pdf`
|
||
- Rule: `global/rules/estilos-design-system`
|
||
- Skill: `skills/ux/SKILL.md`
|
||
- Skill: `skills/ux-fluxo-funcional/SKILL.md`
|
||
- Skill: `skills/auditar-ux-heuristicas/SKILL.md`
|