11 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
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-errocom variantetextououtlined?
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.5para legibilidade? - Labels de formulário são visualmente distintos do conteúdo preenchido?
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:
- SVG inline manual (hardcoded no template)
- Ícones de
@mdi/fontou Material Design Icons em componentes do projeto - Bibliotecas alternativas (Font Awesome, Heroicons, etc.)
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 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-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 para ação primária | Vermelho apenas para destrutivas; primária usa --cor-eli-primaria |
| Modal com scroll extenso | Dividir em etapas ou usar drawer lateral |
| Tabela com 15+ colunas visíveis | Usar modal de colunas para ocultar secundárias |
| Estilos inline em template | Usar <style scoped> com tokens CSS e fallback |
| Cor hex hardcoded | Usar var(--cor-eli-primaria, #688C00) com fallback |