19 KiB
| type | name | description | scope | updatedAt |
|---|---|---|---|---|
| workflow | ux | Revisar e otimizar UX de componentes e telas Vue (Frontend) | global | 2026-06-01 |
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 (Resolução via memorias-ia/modulo.yml)
O público-alvo e o domínio de negócio do módulo devem ser obtidos obrigatoriamente em memorias-ia/modulo.yml (modulo-descricao e modulo-tipo), abrangendo perfis operacionais, administrativos, técnicos e de gestão (pública ou privada).
Premissa central: o usuário é especialista no seu domínio de negócio, mas não tem obrigação de ter familiaridade avançada com tecnologia. A interface precisa ser autoexplicativa, sem dependência de treinamento prévio.
Paleta de Cores Institucional (Conforme rules/estilos-design-system.md)
A seleção do Design System depende do módulo identificado em memorias-ia/modulo.yml (ver rules/estilos-design-system.md):
- Estilo Floreta (Iniciativa Privada / Verde Floresta
#688C00): tokens--cor-eli-*detalhados nas tabelas abaixo. - Estilo Betha (Governo / Setor Público
#007bffe Header#343a40): tokens governamentais documentados emrules/estilos-design-system.md.
Escala primária — Estilo Floreta (Verde floresta #688C00)
| 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 ✓ - ⚠️ Token
secondaryno Vuetify 3 (dark: false): NUNCA configurarsecondarynovuetify.tscom cor pastel clara (#EAF2D3,#EEF3D0), poisvariant="tonal"evariant="outlined"usam a própria cor como texto sobre fundo branco, tornando botões e chips invisíveis. Usar sempre--cor-eli-neutro-escuro(#3E4436) ou--cor-eli-primaria-escura(#4A6500). - Sempre validar contraste mínimo de 4.5:1 (WCAG AA) para texto normal e 3:1 para texto grande (18px+ ou 14px bold).
- Fluxo Funcional e Arquitetura de Informação: Para navegação visível ordenada pela tarefa, revelação progressiva (anti-split-screen
4+8espremido), eliminação de jargões técnicos e quadros Kanban horizontais, aplicar em conjunto a skillux-fluxo-funcional(skills/ux-fluxo-funcional/SKILL.md). - Despoluição Visual e Hierarquia (Refactoring UI): Aplicar obrigatoriamente a regra
refactoring-ui-hierarquia-despoluicao(rules/refactoring-ui-hierarquia-despoluicao.md) e consultar o livro de referência emhttps://adm.paiol.idz.one/estaticos/Refactoring-UI-Steve-Schoger-Adam-Wathan.pdf.
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 e UX Writing (Material Design 3)
- O propósito de cada elemento é óbvio sem instrução?
- Títulos, cabeçalhos, labels, abas, menus e botões usam Capitalização de frase (Sentence case) (apenas a 1ª letra da 1ª palavra e siglas em maiúscula, ex.:
"Nova solicitação","Salvar alterações", sem Title Case artificial)? - Textos orientativos começam pelo objetivo antes da ação (
"Para concluir a solicitação, anexe o comprovante")? - Rótulos (
label), botões, títulos, tooltips de 1 frase e toasts de 1 frase omitem ponto final (.) e nenhumlabelou título termina com dois-pontos (:)? - Modais de confirmação seguem a Anatomia M3: Título com pergunta direta (
"Excluir etapa?"), corpo com a consequência neutra sem repetir o título, e botões[Cancelar]+[Verbo + objeto](sem botões genéricos[Sim],[Não]ou[OK])? - Quantidades e limites usam algarismos (
"3 pendências","Até 10 MB") e a tela está livre de abreviações truncadas ("Qtd.","Obs.","Cad.","End.") e pontos de exclamação (!) em erros/alertas? - Labels e placeholders são descritivos (ex.:
"Buscar por razão social ou CNPJ"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 com botão de ação?
Hierarquia visual e Pirâmide de Ações (Refactoring UI)
- O olho do usuário é guiado para a ação principal primeiro (apenas 1 ação primária sólida
variant="flat"por vista/seção)? - Ações primárias usam o token
primarydo tema com destaque, secundárias usamoutlined/tonale terciárias usamtext? - Ações destrutivas (Excluir, Limpar, Remover) na tela principal são discretas (
variant="text"ou emv-menu), reservando o botão vermelho sólido exclusivamente para o modal de confirmação? - Rótulos óbvios foram omitidos ou combinados com o valor (
"12 etapas", CNPJ/e-mail pelo formato) em vez de pilhas repetitivas deRótulo: Valor? - Em cards de indicadores/KPIs, o valor numérico é o protagonista (
20px–24px, peso600/700) e o rótulo é secundário (12px, cor neutra)? - Títulos de seção (
h1–h3) têm tamanho contido (16px–20px, peso600) sem roubar espaço do conteúdo?
Despoluição de Containers e Tabelas (Use Fewer Borders)
- A tela está livre de Card-ception (zero
v-cardcom borda aninhado dentro de outrov-cardcom borda)? - A separação entre grupos prioriza contraste de superfície (
#FFFFFFsobre#F2F3EE), sombra sutil ou espaçamento extra (24px–32px) em vez de linhas<v-divider>em tudo? - Tabelas consolidam dados relacionados em uma mesma célula de 2 linhas (ex.: Razão Social em negrito + CNPJ • Cidade/UF abaixo em
12pxneutro), evitando 8+ colunas estreitas? - Colunas numéricas e monetárias estão alinhadas à direita com
tabular-nums? - Badges e chips usam contraste invertido (fundo pastel claro + texto escuro da mesma matiz) em vez de múltiplas pílulas saturadas escuras?
- Quando a listagem está inicialmente vazia (zero registros), barras de filtros secundárias e paginação inúteis são ocultadas?
- O cabeçalho operacional respeita o teto de 2 faixas horizontais (mantendo criadores rápidos
+ Nova Tarefarecolhidos sob demanda)? - Ao abrir uma gaveta inspetora de detalhes (
400px+), o menu lateral de navegação recolhe automaticamente (Sidebar Mutual Exclusion) para preservar >= 70% de largura útil? - Linhas de árvore/lista exibem no máximo 3 indicadores em repouso (sem "Natal de Badges"), revelando ações secundárias (
+ Sub,Editar) em:hover/:focus-within? - Painéis de detalhe usam seções colapsáveis (Acordeão) com resumo no título para itens secundários (Pré-requisitos, Recursos, Responsáveis), sem card de resumo duplicado no topo?
- A Matriz de Superfícies M3 é respeitada (Basic Dialog restrito a confirmações críticas ou 3–4 campos rápidos; Side Sheet para formulários de 5–8 campos ou inspeção;
v-snackbarpara avisos passivos; formulários longos agrupados em blocos de até 4–6 campos)? - Em modais (
v-dialog) e painéis laterais (Side Sheets), o Cabeçalho no topo (com botão fecharXnos painéis) e o Rodapé de ações permanecem fixos (pinned) caso o conteúdo central role?
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, espaçamento e Lei da Proximidade
- O espaçamento começa generoso (
pa-6,ga-6) e segue a escala do sistema (4, 8, 12, 16, 24, 32, 48)? - A Lei da Proximidade é respeitada (espaço entre campos
16px–20px> espaço entre label e input4px–6px; espaço entre seções32px+)? - Formulários simples e cards de leitura respeitam sua largura ideal (
max-width: 640px–800pxou layout4+8com título de seção à esquerda + inputs à direita) sem esticar inputs por1400px? - Em mobile, os elementos empilham verticalmente sem quebra visual?
- Modais têm largura proporcional ao conteúdo?
Tipografia — Google Sans (obrigatório)
- A fonte
Google Sans(Variable Font 100–900 via@font-facedehttps://paiol.idz.one/estaticos/GoogleSans/GoogleSans-VariableFont_GRAD,opsz,wght.ttf) está aplicada em todo o sistema (--font-sanse--eli-font-family)? - Proibido
font-monoem contadores, códigos e valores: usartabular-numscomGoogle Sans. - Apenas 2 faixas de peso (
400/500normal e600/700ênfase, nunca< 400) e 3 níveis de cor de texto (primário escuro, secundário médio, terciário suave)? - Escala: 12px (caption), 14px (body), 16px (subtitle), 20px (title), 24px (heading);
line-height: 1.5em textos longos (45ch–75ch),1.15–1.25em títulos/KPIs eletter-spacing: 0.05emem textosUPPERCASE? - Tamanhos de fonte diferentes na mesma linha estão alinhados pela linha de base (
align-baseline)? - Ícones de destaque em empty states ou cabeçalhos mantêm tamanho nativo (
20px–24px) dentro de container arredondado (40px–48px) com fundo pastel suave, nunca inflados a seco para48px+?
Acessibilidade básica
- Elementos interativos têm
aria-labelquando 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-bgusa--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-btncom variantes do tema (color="primary") em vez de classes CSS manuais para botões - Usar
v-dialogpara modais,v-menupara popovers contextuais - Usar
v-text-field,v-selectetc. 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:
lucide-vue-next,@mdi/font, Font Awesome, Heroicons, SVGs inline manuais ou caracteres ASCII/Unicode (└,➔) como ícones.
Como usar:
<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>
<script lang="ts">
import { Filter, Plus, X, Trash2, Eye } from "@lucide/vue"
</script>
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.
Os tokens CSS estão documentados nas tabelas da seção Paleta de Cores Institucional acima. No código, usar
var(--token, #fallback)— sempre com fallback hardcoded em componentes de biblioteca.
- 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 easepara hover/focus
Composição de componentes
- Componentes filhos devem receber dados via
propse emitir eventos via$emit - Evitar acessar o DOM diretamente; preferir
refdo 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:
- Crítico: elementos que causam confusão ou impedem o uso (falta de feedback, botão invisível, estado vazio sem orientação)
- Alto: melhorias que reduzem atrito (espaçamento, hierarquia de botões, responsividade)
- Médio: refinamentos visuais (transições, micro-animações, consistência de cores)
- 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 o Design System do módulo (
rules/estilos-design-system.md: Estilo Floreta#688C00ou Estilo Betha#007bff/#343a40conformememorias-ia/modulo.yml)? - 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-primariae--cor-eli-primaria-escura;--cor-eli-neutro-escurosobre--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ão | ✅ Alternativa |
|---|---|
| Botão sem label de texto | Botão com ícone + texto, ou aria-label descritivo |
| Cor vermelha sólida para botão Excluir na tabela | Usar variant="text" discreto na linha e vermelho sólido apenas no modal de confirmação |
Múltiplos botões sólidos (primary, success, warning) lado a lado |
Pirâmide de ações: 1 primário flat, secundários outlined/tonal e terciários text |
Card-ception (v-card com borda dentro de v-card + v-divider) |
Separar seções por contraste de superfície (#FFFFFF sobre #F2F3EE) ou espaçamento (24px–32px) |
Pilha de Rótulo: Valor com mesmo peso visual |
Omitir rótulos óbvios pelo formato ou combinar em frase; destacar o dado e suavizar o rótulo |
| Modal com scroll extenso ou 6+ campos espremidos | Converter em Side Sheet (5–8 campos), página dedicada ou Full-Screen Dialog, mantendo Cabeçalho e Rodapé fixos (pinned) |
Modal de confirmação com botões [Sim] / [Não] ou [OK] |
Título com pergunta ("Excluir etapa?"), consequência no corpo e botões [Cancelar] + [Excluir etapa] |
Title Case anglófono ("Nova Solicitação", "Salvar Alterações") ou labels com : |
Capitalização de frase (Sentence case: "Nova solicitação", "Salvar alterações") e zero dois-pontos (:) em labels/títulos |
Abreviações truncadas ("Qtd.", "Obs.", "Cad.", "Máx.") |
Escrever por extenso ("Quantidade", "Observações", "Cadastro", "Máximo") e usar algarismos (3, 10 MB) |
| Tabela com 10–15+ colunas estreitas | Consolidar colunas correlatas em célula de 2 linhas (Título + metadado secundário) |
Ícone inflado a seco (48px–64px) |
Ícone 20px–24px dentro de badge arredondado (40px–48px) com fundo pastel |
| Estilos inline em template | Usar <style scoped> com tokens CSS e fallback |
| Cor hex hardcoded | Usar var(--cor-eli-primaria, #688C00) com fallback |