Atualização floresta

This commit is contained in:
Luiz Silva 2026-05-31 11:27:51 -03:00
parent 0886fd5c3e
commit 2d4d8f8929
103 changed files with 19266 additions and 14160 deletions

View file

@ -1,58 +0,0 @@
---
description: Workflow para criação e padronização de documentação em código (JSDoc, comentários e tipagem)
---
# Workflow: Documentar Código
## 🎯 Objetivo
Estabelecer um padrão global e unificado para a redação de documentação em código (comentários, `JSDoc` e explicações arquiteturais) em todas as aplicações, garantindo clareza sem prolixidade e respeitando a política de tipagem explícita.
---
## 1️⃣ Princípios Básicos de Documentação
- **Por que, não o Quê**: Documente o raciocínio por trás da decisão arquitetural ou a regra de negócio que forçou a estratégia, não o mecanismo óbvio que o TypeScript nativamente expressaria.
- **Nomenclatura Limpa**: Confie na auto-documentação de nomes de variáveis expressivos baseados no domínio antes de escrever um comentário de texto livre.
## 2️⃣ Funções Compartilhadas e JSDoc (Obrigatória)
Toda função central ou de uso compartilhado, independente da aplicação (frontend, backend, mobile ou bibliotecas comuns), deve portar cabeçalho em `JSDoc`.
### Padrão para JSDoc
```typescript
/**
* Busca os detalhes de uma entidade baseando-se no ID fornecido e calcula privilégios aplicáveis.
* Não utilizar em fluxos de processamento em lote para evitar sobrecarga de requisições ou banco.
*
* @param tenantId - Identificador único do cliente/tenant no sistema
* @param entityId - ID exclusivo identificando o registro na base de dados
* @returns Retorna o objeto consolidado com dados ou `null` caso não seja encontrado
*/
export const obterDetalhesEntidade = async (tenantId: string, entityId: string) => { ... }
```
## 3️⃣ Tratamento de Exceções e Casts Temporários
Devido à política `TypeScript sem any`, não utilizamos conversores obscuros imperativamente.
Porém, se uma coerção agressiva (`as unknown as X`) demonstrar-se temporariamente necessária por divergência ou limitação de SDK terceiro, **o comentário justificando a anomalia é obrigatório**.
```typescript
// Necessário cast duplo pois a biblioteca externa não provê tipagem genérica adequada na versão atual
const dados = payload.raw as unknown as RespostaFormatada
```
## 4️⃣ Atribuição de TODOs
Toda refatoração, debito técnico visualizado ou dúvida de negócio deixada aberta em código de longo prazo **não prescreve** e deve ser acompanhada do formato `// TODO`:
- **Tipagem**: `// TODO de tipagem: Criar interface estrita para o retorno da API de listagem (Removendo Partial)`
- **Negócio**: `// TODO de regra: Validar com a equipe de Produto se a nova taxa adicional será inserida para clientes antigos.`
## 5️⃣ Validação do Fluxo
Sempre ao propor documentação de um arquivo novo ou refatorado, valide via checklist:
* [ ] A documentação está aderente sem estar redundante à tipagem TS?
* [ ] A formatação de parágrafos/espaçamento quebra alguma regra no formatador?
* [ ] A sintaxe suporta autocompletion na sua camada dependente (`@params` estão exatos)?
---
## Referências
- Rules: `.agent/rules/typescript-sem-any.global.md` (política de tipagem que influencia a documentação)
- Skill: `.agent/skills/documentar-decisao-tecnica/SKILL.md` (para decisões arquiteturais que exigem ADR além de JSDoc)

View file

@ -0,0 +1,221 @@
---
description: Otimizar código e documentar padrões de qualidade (estrutura, limites, JSDoc e tipagem)
---
# Workflow: Qualidade e Documentação de Código
## 🎯 Objetivo
Unificar as regras de **estrutura de arquivos**, **otimização** e **documentação** em um único fluxo de referência para o projeto `eli-vue`.
---
## 1️⃣ Limite de Linhas por Arquivo
Nenhum arquivo `*.vue`, `*.ts` ou `*.tsx` pode ultrapassar **250 linhas**.
Essa regra existe para facilitar a leitura humana, a revisão de código e a manutenção a longo prazo.
> O script `scripts/check-vue-linhas.sh` valida automaticamente os arquivos `.vue` no `prebuild`.
**Estratégias quando o limite se aproxima:**
| Situação | Ação |
|---|---|
| Template longo | Extrair seções como subcomponentes |
| CSS extenso | Mover para `<nome>.css` co-localizado |
| `setup()` extenso | Extrair subcomponentes, CSS ou Dispatch Table |
| Modal/Dialog embutido | Sempre em componente separado (`*Modal.vue`) |
| Handlers e dispatch | Extrair para `handlers.ts` ou `dispatch.ts` |
---
## 2️⃣ Estrutura de Componentes Vue
### `defineComponent` obrigatório
Todo componente Vue deve usar `defineComponent` para garantir inferência de tipos correta e consistência.
```vue
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'MeuComponente',
setup() {
// lógica aqui
}
})
</script>
```
**Por que é importante:**
- Inferência de tipos TypeScript correta dentro do componente
- Reconhecimento por ferramentas de análise estática e IDEs
- Compatível com Options API e Composition API com `setup()`
- Padronização entre todos os componentes do projeto
---
### `setup()` não pode ser externo
O `setup()` deve estar sempre dentro do componente `.vue`. Não é permitido extrair ou delegar o `setup` para nenhum arquivo externo.
```ts
// ❌ Proibido — setup delegado inteiramente para arquivo externo
// useEliTabela.ts
export function useEliTabela(props, emit) { ... }
// EliTabela.vue
export default defineComponent({
setup(props, { emit }) {
return useEliTabela(props, emit) // setup é apenas um proxy vazio
}
})
```
```ts
// ✅ Correto — setup com lógica própria dentro do componente
// EliTabela.vue
export default defineComponent({
setup(props, { emit }) {
const estado = ref(null)
const carregar = async () => { ... }
return { estado, carregar }
}
})
```
> Composables `use*.ts` podem encapsular lógica reutilizável pontual (ex: `useFormatador`, `usePermissao`), mas nunca substituir ou esvaziar o `setup()` do componente. Se o componente ultrapassar 250 linhas, a solução é extrair subcomponentes, mover CSS ou usar Dispatch Table — não esvaziar o `setup`.
---
### Desassociação de CSS
A separação de estilos em arquivo externo é permitida e recomendada quando o CSS contribui significativamente para o total de linhas.
**Padrão de nomenclatura:**
```
MeuComponente.vue
MeuComponente.css
```
O `.vue` importa o arquivo CSS no script:
```ts
import './MeuComponente.css'
```
Ou via tag `<style>`:
```vue
<style src="./MeuComponente.css" />
```
---
### Dispatch Table em Arquivo Separado
O uso de Dispatch Table (mapa de funções) em arquivos separados é bem-vindo para eliminar blocos longos de `if/else` ou `switch`.
```ts
// handlers.ts
export const acaoHandlers: Record<string, () => void> = {
salvar: () => { ... },
cancelar: () => { ... },
excluir: () => { ... },
}
```
```ts
// MeuComponente.vue
import { acaoHandlers } from './handlers'
function executar(acao: string) {
acaoHandlers[acao]?.()
}
```
---
## 3️⃣ Documentação em Código (JSDoc)
### Princípios básicos
- **Por que, não o Quê**: Documente o raciocínio por trás da decisão arquitetural, não o mecanismo óbvio que o TypeScript já expressa.
- **Nomenclatura limpa**: Confie na auto-documentação de nomes expressivos antes de escrever comentários de texto livre.
### Funções compartilhadas — JSDoc obrigatório
Toda função central ou de uso compartilhado (frontend, backend, mobile ou bibliotecas comuns) deve ter cabeçalho em `JSDoc`.
```typescript
/**
* Busca os detalhes de uma entidade baseando-se no ID fornecido e calcula privilégios aplicáveis.
* Não utilizar em fluxos de processamento em lote para evitar sobrecarga de requisições.
*
* @param tenantId - Identificador único do cliente/tenant no sistema
* @param entityId - ID exclusivo identificando o registro na base de dados
* @returns Retorna o objeto consolidado com dados ou `null` caso não seja encontrado
*/
export const obterDetalhesEntidade = async (tenantId: string, entityId: string) => { ... }
```
---
## 4️⃣ Casts Temporários e Exceções de Tipagem
Devido à política **TypeScript sem any**, coerções agressivas requerem justificativa obrigatória em comentário.
```typescript
// Necessário cast duplo pois a biblioteca externa não provê tipagem genérica adequada na versão atual
const dados = payload.raw as unknown as RespostaFormatada
```
---
## 5️⃣ TODOs Estruturados
Toda dívida técnica ou dúvida de negócio deixada em código deve seguir o formato `// TODO`:
- **Tipagem**: `// TODO de tipagem: Criar interface estrita para o retorno da API de listagem`
- **Negócio**: `// TODO de regra: Validar com Produto se a taxa adicional se aplica a clientes antigos`
---
## 6️⃣ Resumo das Regras
| Regra | Permitido | Proibido |
|---|---|---|
| Tamanho de arquivo | Até 250 linhas | Acima de 250 linhas |
| `defineComponent` | Obrigatório em todo `.vue` | Componentes sem `defineComponent` |
| `setup()` externo | — | Proibido em qualquer forma |
| CSS externo | `<nome>.css` vinculado ao `.vue` | CSS inline quando ultrapassa o limite |
| Dispatch Table | Em arquivo separado | — |
| JSDoc | Obrigatório em funções compartilhadas | Omitir em funções de uso amplo |
| Casts `as any` | Com `biome-ignore` justificado | Sem comentário explicativo |
---
## 7️⃣ Checklist de Validação
Antes de concluir qualquer refatoração ou adição de código:
- [ ] O arquivo resultante tem menos de 250 linhas?
- [ ] Funções compartilhadas têm `JSDoc` com `@param` e `@returns`?
- [ ] Casts temporários têm comentário justificando?
- [ ] TODOs estão no formato padronizado?
- [ ] A documentação explica o **porquê**, não apenas o **o quê**?
- [ ] `defineComponent` está presente em todo componente `.vue`?
---
## Referências
- Script: `scripts/check-vue-linhas.sh` (validação automática de tamanho)
- Rule: `.agent/rules/vue-limite-linhas.global.md` (política de limite de linhas)
- Rule: `.agent/rules/typescript-sem-any.global.md` (política de tipagem)
- Skill: `.agent/skills/documentar-decisao-tecnica/SKILL.md` (ADRs para decisões arquiteturais)

View file

@ -0,0 +1,289 @@
---
description: Revisar e otimizar UX de componentes e telas Vue (Frontend)
---
# Workflow: Revisão de UX
Guia de revisão e otimização de interfaces Vue 3 + Vuetify 3 no ecossistema Azteca — para usuários corporativos com baixa familiaridade tecnológica.
---
## Perfil do Usuário
O público-alvo das interfaces é corporativo e diversificado em experiência técnica:
- Gestores públicos e ambientais
- Técnicos de campo
- Consultores ambientais
- Operadores administrativos
**Premissa central**: o usuário não tem familiaridade avançada com tecnologia. A interface precisa ser autoexplicativa, sem dependência de treinamento prévio.
---
## Paleta de Cores Institucional
Cor base: `#688C00` (verde floresta). Três escalas derivadas: **Verde floresta** (primária), **Âmbar terroso** (apoio/aviso), **Cinza musgo** (neutros). Semânticas independentes para garantir reconhecimento universal.
### Escala primária — Verde floresta
| Token | Hex | Stop | Uso |
|---|---|---|---|
| `--cor-eli-primaria-bg` | `#EEF3D0` | 50 | Fundo de cards destacados, linhas ativas, hover suave |
| `--cor-eli-primaria-zebra` | `#F6F9E8` | 30 | Linha zebrada de tabelas (quase branco esverdeado) |
| `--cor-eli-primaria-suave` | `#BFC99C` | — | **Cabeçalho de tabela** — sage/olive mudo, sem limão, texto escuro |
| `--cor-eli-primaria-clara` | `#D4E290` | 100 | Badges, chips, seleção, fundo de hover em listas |
| `--cor-eli-primaria-media` | `#ADCC44` | 200 | Tags, indicadores secundários |
| `--cor-eli-primaria-acao` | `#8AAF00` | 400 | Ação secundária, ícones ativos |
| `--cor-eli-primaria` | `#688C00` | 600 | **Botões principais, links ativos, destaques — CTA principal** |
| `--cor-eli-primaria-escura` | `#4A6500` | 800 | Hover em botões, bordas ativas, títulos com ênfase |
| `--cor-eli-primaria-texto` | `#2E3F00` | 900 | Texto escuro sobre fundos claros da paleta primária |
### Escala de apoio — Âmbar terroso
| Token | Hex | Stop | Uso |
|---|---|---|---|
| `--cor-eli-alerta-bg` | `#FAF3DF` | 50 | Fundo de banners de aviso |
| `--cor-eli-alerta-clara` | `#F5DC8A` | 100 | Badges de atenção, chips de alerta |
| `--cor-eli-alerta` | `#DDB847` | 200 | Ícones de aviso, bordas de alerta |
| `--cor-eli-alerta-forte` | `#8C6A00` | 600 | Texto sobre fundo de alerta, status pendente |
### Escala neutra — Cinza musgo
| Token | Hex | Stop | Uso |
|---|---|---|---|
| `--cor-eli-fundo` | `#F2F3EE` | 50 | Background geral de páginas |
| `--cor-eli-borda` | `#D5D8CC` | 100 | Bordas padrão de containers |
| `--cor-eli-borda-forte` | `#B5BAA8` | 200 | Bordas de foco, divisores |
| `--cor-eli-neutro` | `#5E6553` | 600 | Textos secundários, ícones inativos |
| `--cor-eli-neutro-escuro` | `#3E4436` | 800 | Texto de label, cabeçalhos de tabela |
| `--cor-eli-superficie` | `#FFFFFF` | — | Cards, modais, popovers |
### Cores semânticas
| Token | Hex | Uso |
|---|---|---|
| `--cor-eli-sucesso` | `#2e7d32` | Confirmações, status positivo |
| `--cor-eli-sucesso-bg` | `#E8F5E9` | Fundo de mensagens de sucesso |
| `--cor-eli-erro` | `#c62828` | Erros, ações destrutivas |
| `--cor-eli-erro-bg` | `#FFEBEE` | Fundo de mensagens de erro |
| `--cor-eli-info` | `#1565c0` | Informações auxiliares |
| `--cor-eli-info-bg` | `#E3F2FD` | Fundo de banners informativos |
### Regras de contraste
- Texto sobre `--cor-eli-primaria` (`#688C00`) deve ser **branco** (`#ffffff`) — contraste 4.6:1 ✓
- Texto sobre `--cor-eli-primaria-bg` (`#EEF3D0`) deve ser `--cor-eli-primaria-texto` (`#2E3F00`) — contraste 12:1 ✓
- Texto sobre `--cor-eli-primaria-escura` (`#4A6500`) deve ser **branco** (`#ffffff`) — contraste 7.1:1 ✓
- Texto sobre `--cor-eli-alerta-bg` (`#FAF3DF`) deve ser `--cor-eli-alerta-forte` (`#8C6A00`) — contraste 5.2:1 ✓
- Texto sobre `--cor-eli-primaria-suave` (`#BFC99C`) deve ser `--cor-eli-neutro-escuro` (`#3E4436`) — contraste ~12:1 ✓
- **⚠️ Efeito limão**: `--cor-eli-media` (`#ADCC44`) e `--cor-eli-acao` (`#8AAF00`) têm saturação 100% no hue amarelo-verde — **nunca usar como fundo de cabeçalho**. Para fundo verde mudo, usar `--cor-eli-primaria-suave`.
- Sempre validar contraste mínimo de **4.5:1** (WCAG AA) para texto normal e **3:1** para texto grande (18px+ ou 14px bold).
---
## Passos
### 1. Identificar o escopo da revisão
Determinar qual componente, tela ou modal será revisado. Pode ser:
- Um componente isolado (ex: `EliTabela`, `EliCartao`)
- Uma página completa (ex: `PaginaCadastro.vue`)
- Um modal ou drawer (ex: `EliTabelaModalFiltroAvancado.vue`)
- Uma interação específica (ex: fluxo de filtro, paginação, menu de ações)
### 2. Mapear o estado atual
Antes de alterar, entender o que já existe:
- Ler o template (`<template>`) para entender a estrutura visual
- Ler o CSS/SCSS associado para mapear os tokens de design em uso
- Identificar quais componentes Vuetify estão sendo utilizados (ex: `v-btn`, `v-dialog`, `v-select`)
- Verificar se existem estilos inline que deveriam migrar para classes CSS
### 3. Avaliar contra os critérios de UX
Para cada elemento da interface, avaliar:
#### Clareza
- [ ] O propósito de cada elemento é óbvio sem instrução?
- [ ] Labels e placeholders são descritivos? (ex: "Buscar por nome ou CPF" vs "Buscar")
- [ ] Ícones acompanham texto quando a ação não é universalmente reconhecível?
- [ ] O estado vazio (empty state) orienta o usuário sobre o próximo passo?
#### Hierarquia visual
- [ ] O olho do usuário é guiado para a ação principal primeiro?
- [ ] Ações primárias usam `--cor-eli-primaria` (`#688C00`) com destaque?
- [ ] Ações secundárias são visuais mas não competem com a primária?
- [ ] Ações destrutivas (Excluir, Limpar) usam `--cor-eli-erro` com variante `text` ou `outlined`?
#### Feedback e estados
- [ ] Botões têm estados claros de hover (`--cor-eli-primaria-escura`), focus e disabled (`--cor-eli-borda-forte`)?
- [ ] Carregamentos exibem indicador visual (spinner, skeleton, barra de progresso)?
- [ ] Erros de formulário aparecem próximos ao campo com mensagem descritiva, usando `--cor-eli-erro` + `--cor-eli-erro-bg`?
- [ ] Sucesso de operações tem confirmação visual (snackbar, toast, badge) com `--cor-eli-sucesso`?
#### Densidade e espaçamento
- [ ] O espaçamento segue múltiplos de 4px (4, 8, 12, 16, 24, 32)?
- [ ] Em desktop, o espaço horizontal é bem aproveitado? (ex: grids de 2+ colunas para formulários largos)
- [ ] Em mobile, os elementos empilham verticalmente sem quebra visual?
- [ ] Modais têm largura proporcional ao conteúdo?
#### Tipografia
- [ ] Tamanhos de fonte seguem a escala: 12px (caption), 14px (body), 16px (subtitle), 20px (title), 24px (heading)?
- [ ] Textos longos usam `line-height: 1.5` para legibilidade?
- [ ] Labels de formulário são visualmente distintos do conteúdo preenchido?
#### Acessibilidade básica
- [ ] Elementos interativos têm `aria-label` quando o texto visual não é suficiente?
- [ ] Foco via teclado (`Tab`) segue uma ordem lógica?
- [ ] Cores não são o único meio de comunicar estado (ex: ícone + cor para erro)?
- [ ] Todo texto sobre cor primária ou escura usa branco (`#FFFFFF`)?
- [ ] Todo texto sobre `--cor-eli-primaria-bg` usa `--cor-eli-primaria-texto` (`#2E3F00`)?
### 4. Aplicar padrões Vue/Vuetify do projeto
Ao implementar melhorias, seguir os padrões do ecossistema:
#### Componentes Vuetify
- Usar `v-btn` com variantes do tema (`color="primary"`) em vez de classes CSS manuais para botões
- Usar `v-dialog` para modais, `v-menu` para popovers contextuais
- Usar `v-text-field`, `v-select` etc. para inputs sempre que possível
- Aproveitar props de Vuetify: `density`, `variant`, `rounded`, `elevation`
#### Iconografia — Lucide (obrigatório)
Todos os ícones do projeto devem vir exclusivamente da biblioteca **`@lucide/vue`** (dependência já instalada no `package.json`).
**Proibido**:
- SVG inline manual (hardcoded no template)
- Ícones de `@mdi/font` ou Material Design Icons em componentes do projeto
- Bibliotecas alternativas (Font Awesome, Heroicons, etc.)
**Como usar**:
```vue
<script lang="ts">
import { Filter, Plus, X, Trash2, Eye } from "@lucide/vue"
</script>
<template>
<!-- Uso direto como componente -->
<Filter :size="18" :stroke-width="2" />
<!-- Dentro de botão -->
<button>
<Plus :size="15" :stroke-width="2.5" />
Adicionar
</button>
</template>
```
**Props úteis**: `:size` (número em px), `:stroke-width` (espessura do traço, padrão 2), `:color` (cor do ícone).
**Catálogo de referência**: https://lucide.dev/icons — buscar pelo nome do ícone em inglês.
#### CSS do projeto
```css
/* Escala primária — Verde floresta */
--cor-eli-primaria-bg: #EEF3D0;
--cor-eli-primaria-zebra: #F6F9E8;
--cor-eli-primaria-suave: #BFC99C;
--cor-eli-primaria-clara: #D4E290;
--cor-eli-primaria-media: #ADCC44;
--cor-eli-primaria-acao: #8AAF00;
--cor-eli-primaria: #688C00;
--cor-eli-primaria-escura: #4A6500;
--cor-eli-primaria-texto: #2E3F00;
/* Escala de apoio — Âmbar terroso */
--cor-eli-alerta-bg: #FAF3DF;
--cor-eli-alerta-clara: #F5DC8A;
--cor-eli-alerta: #DDB847;
--cor-eli-alerta-forte: #8C6A00;
/* Escala neutra — Cinza musgo */
--cor-eli-fundo: #F2F3EE;
--cor-eli-borda: #D5D8CC;
--cor-eli-borda-forte: #B5BAA8;
--cor-eli-neutro: #5E6553;
--cor-eli-neutro-escuro: #3E4436;
--cor-eli-superficie: #FFFFFF;
/* Semânticas */
--cor-eli-sucesso: #2E7D32;
--cor-eli-sucesso-bg: #E8F5E9;
--cor-eli-erro: #C62828;
--cor-eli-erro-bg: #FFEBEE;
--cor-eli-info: #1565C0;
--cor-eli-info-bg: #E3F2FD;
```
> **⚠️ Regra crítica para componentes distribuídos como biblioteca**: todo token CSS novo (`--cor-eli-primaria-zebra`, `--cor-eli-primaria-suave`, etc.) deve ter **fallback hardcoded** no CSS do componente: `var(--token, #valorhex)`. Projetos destino podem não ter a versão mais recente do `design-tokens.css` e a variável resolverá como `undefined`, tornando a propriedade invisível.
- Classes devem seguir BEM: `eli-componente__elemento--modificador`
- Evitar `!important` — resolver especificidade via seletor mais específico
- Usar `var(--cor-eli-primaria)` em vez de valores hex hardcoded no CSS dos componentes
- Transições padrão: `transition: all 0.2s ease` para hover/focus
#### Composição de componentes
- Componentes filhos devem receber dados via `props` e emitir eventos via `$emit`
- Evitar acessar o DOM diretamente; preferir `ref` do Vue
- Não duplicar CSS entre componentes — extrair para classe utilitária ou CSS do componente pai
### 5. Implementar melhorias prioritárias
Ordenar as melhorias por impacto no usuário:
1. **Crítico**: elementos que causam confusão ou impedem o uso (falta de feedback, botão invisível, estado vazio sem orientação)
2. **Alto**: melhorias que reduzem atrito (espaçamento, hierarquia de botões, responsividade)
3. **Médio**: refinamentos visuais (transições, micro-animações, consistência de cores)
4. **Baixo**: polish (sombras sutis, arredondamentos, tipografia refinada)
### 6. Validar resultado
Após implementar:
- [ ] A tela renderiza sem erros no console?
- [ ] Os estados (vazio, carregando, erro, com dados) estão todos cobertos?
- [ ] A paleta de cores está coerente com a base `#688C00`?
- [ ] Todos os tokens usados estão definidos na escala primária, de apoio ou neutra?
- [ ] Nenhuma cor está hardcoded no CSS do componente (usar `var(--token, #fallback)`)?
- [ ] Tokens novos têm fallback hardcoded? (ex: `var(--cor-eli-primaria-suave, #BFC99C)`)?
- [ ] Contraste de texto validado: branco sobre `--cor-eli-primaria` e `--cor-eli-primaria-escura`; `--cor-eli-neutro-escuro` sobre `--cor-eli-primaria-suave`?
- [ ] Nenhuma ação ficou sem feedback visual?
- [ ] O layout não quebra em larguras menores que 1024px?
- [ ] Componentes Vuetify recebem props de tema (`color`, `variant`) em vez de override CSS?
- [ ] Efeito zebra de tabelas tem fundo branco explícito nas linhas normais (para funcionar sobre qualquer fundo de página)?
---
## Anti-padrões a evitar
| ❌ Anti-padrão | ✅ Alternativa |
|---|---|
| Botão sem label de texto | Botão com ícone + texto, ou `aria-label` descritivo |
| Cor vermelha para ação primária | Vermelho apenas para destrutivas; primária usa `--cor-eli-primaria` |
| Modal com scroll interno extenso | Dividir em etapas ou usar drawer lateral |
| Tabela com 15+ colunas visíveis | Usar o modal de colunas para esconder as menos usadas |
| Placeholder como único label | Label fixo acima do campo + placeholder como exemplo |
| Ações alinhadas à esquerda em linha de tabela | Ações à direita, próximas ao fim da linha visual |
| Toast/snackbar sem ação de fechar | Sempre incluir botão de fechar ou auto-dismiss com tempo suficiente (5s+) |
| Estilos inline em `<template>` | Migrar para `<style scoped>` com classe BEM |
| Cor hex hardcoded no componente | Usar `var(--cor-eli-primaria)` e demais tokens com fallback |
| Texto escuro (`#333`) sobre `--cor-eli-primaria` | Usar branco (`#FFFFFF`) para garantir contraste WCAG AA |
| Amarelo/âmbar para sucesso | Âmbar é reservado para **aviso**; sucesso usa `--cor-eli-sucesso` (`#2E7D32`) |
| Misturar stops da paleta fora dos tokens | Usar apenas os tokens definidos; nunca interpolar valores avulsos |
| Usar `--cor-eli-media` ou `--cor-eli-acao` como fundo de cabeçalho | Usar `--cor-eli-primaria-suave` (`#BFC99C`) — verde mudo sem efeito limão |
| `var(--token)` sem fallback em componente de biblioteca | Sempre declarar `var(--token, #valor)` — o projeto destino pode não ter o token atualizado |
| Zebra de tabela sem fundo branco explícito nas linhas normais | Declarar `.eli-tabela__tr .eli-tabela__td { background: var(--cor-eli-superficie, #fff) }` antes da regra zebra |