276 lines
No EOL
19 KiB
Markdown
276 lines
No EOL
19 KiB
Markdown
---
|
||
type: workflow
|
||
name: ux
|
||
description: Revisar e otimizar UX de componentes e telas Vue (Frontend)
|
||
scope: global
|
||
updatedAt: "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 `#007bff` e Header `#343a40`):** tokens governamentais documentados em `rules/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 `secondary` no Vuetify 3 (`dark: false`)**: NUNCA configurar `secondary` no `vuetify.ts` com cor pastel clara (`#EAF2D3`, `#EEF3D0`), pois `variant="tonal"` e `variant="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+8` espremido), eliminação de jargões técnicos e quadros Kanban horizontais, aplicar em conjunto a skill **`ux-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 em `https://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 nenhum `label` ou 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 `primary` do tema com destaque, secundárias usam `outlined`/`tonal` e terciárias usam `text`?
|
||
- [ ] Ações destrutivas (Excluir, Limpar, Remover) na tela principal são discretas (`variant="text"` ou em `v-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 de `Rótulo: Valor`?
|
||
- [ ] Em cards de indicadores/KPIs, o valor numérico é o protagonista (`20px–24px`, peso `600/700`) e o rótulo é secundário (`12px`, cor neutra)?
|
||
- [ ] Títulos de seção (`h1`–`h3`) têm tamanho contido (`16px–20px`, peso `600`) 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-card` com borda aninhado dentro de outro `v-card` com borda)?
|
||
- [ ] A separação entre grupos prioriza contraste de superfície (`#FFFFFF` sobre `#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 `12px` neutro), 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 Tarefa` recolhidos 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-snackbar` para 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 fechar `X` nos 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 input `4px–6px`; espaço entre seções `32px+`)?
|
||
- [ ] Formulários simples e cards de leitura respeitam sua largura ideal (`max-width: 640px–800px` ou layout `4+8` com título de seção à esquerda + inputs à direita) sem esticar inputs por `1400px`?
|
||
- [ ] 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-face` de `https://paiol.idz.one/estaticos/GoogleSans/GoogleSans-VariableFont_GRAD,opsz,wght.ttf`) está aplicada em todo o sistema (`--font-sans` e `--eli-font-family`)?
|
||
- [ ] Proibido `font-mono` em contadores, códigos e valores: usar `tabular-nums` com `Google Sans`.
|
||
- [ ] Apenas 2 faixas de peso (`400/500` normal e `600/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.5` em textos longos (`45ch–75ch`), `1.15–1.25` em títulos/KPIs e `letter-spacing: 0.05em` em textos `UPPERCASE`?
|
||
- [ ] 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 para `48px+`?
|
||
|
||
#### 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**:
|
||
- `lucide-vue-next`, `@mdi/font`, Font Awesome, Heroicons, SVGs inline manuais ou caracteres ASCII/Unicode (`└`, `➔`) como ícones.
|
||
|
||
**Como usar**:
|
||
|
||
```vue
|
||
<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 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 o Design System do módulo (`rules/estilos-design-system.md`: Estilo Floreta `#688C00` ou Estilo Betha `#007bff` / `#343a40` conforme `memorias-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-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ã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 | |