refactor(ux): garantir agnosticismo polimorfico e exemplos neutros nos artefatos de UX
This commit is contained in:
parent
b540fd97c0
commit
790b56e614
21 changed files with 259 additions and 254 deletions
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
type: rule
|
||||
name: mensagens-usuario
|
||||
description: Toda mensagem visível ao usuário final deve ser escrita em linguagem do domínio, sem termos técnicos de TI, seguindo as boas práticas de UX Writing do Material Design 3
|
||||
description: Toda mensagem visível ao usuário final deve ser escrita em linguagem do domínio do módulo (definido em memorias-ia/modulo.yml), sem termos técnicos de TI, seguindo as boas práticas de UX Writing do Material Design 3
|
||||
scope: global
|
||||
trigger: glob
|
||||
globs: "**/*.vue, **/*.ts, **/*.tsx"
|
||||
|
|
@ -12,9 +12,9 @@ updatedAt: "2026-10-26"
|
|||
|
||||
## Contexto
|
||||
|
||||
O usuário final dos módulos SaaS é profissional de **engenharia, ciência, administração pública ou gestão ambiental**. Ele entende de legislação, processos técnicos e operação — mas **não tem obrigação de entender tecnologia**.
|
||||
O usuário final dos módulos do ecossistema é especialista no **domínio de negócio do módulo** (cujo escopo, propósito e público-alvo devem ser consultados obrigatoriamente em `memorias-ia/modulo.yml` nos campos `modulo-descricao` e `modulo-tipo`) — mas **não tem obrigação de entender engenharia de software ou banco de dados**.
|
||||
|
||||
Toda mensagem e microcopy visível na interface — títulos de telas, cabeçalhos de seções, modais, painéis laterais, erros, validações, confirmações, tooltips, estados vazios e botões — deve unir a **linguagem do domínio do módulo** às **boas práticas de UX Writing do Material Design 3** (`https://m3.material.io/foundations/writing/best-practices`).
|
||||
Toda mensagem e microcopy visível na interface — títulos de telas, cabeçalhos de seções, modais, painéis laterais, erros, validações, confirmações, tooltips, estados vazios e botões — deve unir a **linguagem do domínio do módulo ativo** às **boas práticas de UX Writing do Material Design 3** (`https://m3.material.io/foundations/writing/best-practices`).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -30,12 +30,12 @@ Usar voz ativa, tom neutro (sem culpar o usuário e sem pontos de exclamação `
|
|||
"Erro de validação"
|
||||
"Formato inválido"
|
||||
"Payload inválido"
|
||||
"Informe a Área do Empreendimento"
|
||||
"Informe a Razão Social da Organização"
|
||||
|
||||
// ✅ CORRETO — linguagem do domínio + Sentence case (M3)
|
||||
"Informe a área do empreendimento (em hectares)"
|
||||
"Selecione o tipo de licença: LP, LI ou LO"
|
||||
"A data da vistoria deve ser anterior à data de hoje"
|
||||
"Informe a razão social da organização"
|
||||
"Selecione a categoria da solicitação"
|
||||
"A data de conclusão deve ser posterior à data de início"
|
||||
"Informe o CNPJ no formato 00.000.000/0000-00"
|
||||
```
|
||||
|
||||
|
|
@ -57,17 +57,17 @@ Explicar o que ocorreu de forma direta e como o usuário pode prosseguir, sem ex
|
|||
|
||||
### 3. Estados vazios (*empty states*) devem explicar o contexto e orientar a ação
|
||||
|
||||
Quando uma lista, tabela ou painel está vazio, o texto principal não usa ponto final e o texto de apoio orienta o próximo passo:
|
||||
Quando uma lista, tabela ou painel está vazio, o título não usa ponto final e o texto de apoio orienta o próximo passo:
|
||||
|
||||
```typescript
|
||||
// ❌ ERRADO — genérico e sem saída
|
||||
"Nenhum registro encontrado."
|
||||
"Lista vazia"
|
||||
|
||||
// ✅ CORRETO — explica o domínio e orienta
|
||||
// Título (sem ponto final): "Nenhuma condicionante cadastrada"
|
||||
// Apoio: "Para iniciar o controle de prazos, adicione a primeira condicionante desta licença."
|
||||
// Botão CTA: "Adicionar condicionante"
|
||||
// ✅ CORRETO — explica o contexto do domínio e orienta
|
||||
// Título (sem ponto final): "Nenhuma etapa cadastrada neste cronograma"
|
||||
// Apoio: "Para iniciar o acompanhamento de prazos, adicione a primeira etapa."
|
||||
// Botão CTA: "Adicionar etapa"
|
||||
```
|
||||
|
||||
### 4. Diálogos de confirmação devem explicar a consequência e usar botões específicos (M3)
|
||||
|
|
@ -88,15 +88,15 @@ Todo modal de confirmação/decisão crítica (`v-dialog`) deve obedecer à **An
|
|||
|
||||
// ✅ CORRETO — Anatomia M3 (Pergunta específica + Consequência + Verbo no botão)
|
||||
{
|
||||
titulo: "Excluir condicionante?",
|
||||
corpo: "O prazo de cumprimento e os documentos vinculados serão removidos permanentemente.",
|
||||
botoes: ["Cancelar", "Excluir condicionante"]
|
||||
titulo: "Excluir etapa do cronograma?",
|
||||
corpo: "Os prazos e os documentos vinculados a esta etapa serão removidos permanentemente.",
|
||||
botoes: ["Cancelar", "Excluir etapa"]
|
||||
}
|
||||
|
||||
{
|
||||
titulo: "Arquivar licença?",
|
||||
corpo: "Esta licença sairá das listagens ativas, mas poderá ser consultada no histórico.",
|
||||
botoes: ["Cancelar", "Arquivar licença"]
|
||||
titulo: "Arquivar solicitação?",
|
||||
corpo: "Esta solicitação sairá das listagens ativas, mas poderá ser consultada no histórico.",
|
||||
botoes: ["Cancelar", "Arquivar solicitação"]
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -108,30 +108,30 @@ Nunca finalizar `label` com dois-pontos (`:`) nem usar ponto final (`.`) em `lab
|
|||
// ❌ ERRADO — genérico, com dois-pontos ou Title Case em todas as palavras
|
||||
label: "Nome:"
|
||||
placeholder: "Digite aqui."
|
||||
label: "Razão Social Do Empreendedor:"
|
||||
label: "Razão Social Do Solicitante:"
|
||||
|
||||
// ✅ CORRETO — específico do domínio, Sentence case e sem pontuação final
|
||||
label: "Razão social do empreendedor"
|
||||
placeholder: "Ex.: Mineração Vale Verde Ltda."
|
||||
label: "Razão social do solicitante"
|
||||
placeholder: "Ex.: Organização Vale Verde Ltda."
|
||||
|
||||
label: "Área total do empreendimento (ha)"
|
||||
placeholder: "Ex.: 150,5"
|
||||
label: "Valor estimado do contrato (R$)"
|
||||
placeholder: "Ex.: 15.000,00"
|
||||
```
|
||||
|
||||
### 6. Schemas Zod devem ter mensagens de domínio em *Sentence case*
|
||||
|
||||
```typescript
|
||||
// ❌ ERRADO — mensagens padrão do Zod em inglês ou técnicas
|
||||
const zEmpreendimento = z.object({
|
||||
const zCadastro = z.object({
|
||||
nome: z.string().min(1),
|
||||
area: z.number().positive(),
|
||||
valor: z.number().positive(),
|
||||
})
|
||||
|
||||
// ✅ CORRETO — mensagens customizadas em linguagem do domínio
|
||||
const zEmpreendimento = z.object({
|
||||
nome: z.string().min(1, "Informe a razão social do empreendimento"),
|
||||
area: z.number({ invalid_type_error: "Informe um valor numérico para a área" })
|
||||
.positive("A área deve ser maior que zero"),
|
||||
const zCadastro = z.object({
|
||||
nome: z.string().min(1, "Informe a razão social da organização"),
|
||||
valor: z.number({ invalid_type_error: "Informe um valor numérico válido" })
|
||||
.positive("O valor deve ser maior que zero"),
|
||||
cnpj: z.string().regex(/^\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}$/,
|
||||
"CNPJ inválido. Use o formato 00.000.000/0000-00"),
|
||||
})
|
||||
|
|
@ -144,13 +144,13 @@ const zEmpreendimento = z.object({
|
|||
Toda escrita em componentes Vue (`*-front`) deve aplicar os 7 princípios do guia `m3.material.io/foundations/writing/best-practices`:
|
||||
|
||||
1. **Capitalização estilo de frase (*Sentence case*):**
|
||||
- Usar maiúscula **apenas na primeira letra da primeira palavra** e em **nomes próprios ou siglas oficiais** (`CNPJ`, `CPF`, `IBAMA`, `LP`, `LI`, `LO`, `ART`, `MTR`, `UF`).
|
||||
- Aplica-se a: títulos de páginas, cabeçalhos de cards/seções, títulos de modais e painéis laterais, labels de inputs, abas (`v-tab`), itens de menu e botões (`"Nova licença"`, `"Salvar alterações"`, `"Dados do empreendimento"`).
|
||||
- **Proibido** usar *Title Case* anglófono (`"Salvar Alterações"`, `"Dados Do Empreendimento"`) ou `ALL CAPS` em botões e títulos.
|
||||
- Usar maiúscula **apenas na primeira letra da primeira palavra** e em **nomes próprios ou siglas oficiais** (`CNPJ`, `CPF`, `CEP`, `UF`, `PDF`, `API`).
|
||||
- Aplica-se a: títulos de páginas, cabeçalhos de cards/seções, títulos de modais e painéis laterais, labels de inputs, abas (`v-tab`), itens de menu e botões (`"Nova solicitação"`, `"Salvar alterações"`, `"Dados do responsável"`).
|
||||
- **Proibido** usar *Title Case* anglófono (`"Salvar Alterações"`, `"Dados Do Responsável"`) ou `ALL CAPS` em botões e títulos.
|
||||
2. **Começar pelo objetivo (*Begin with the objective*):**
|
||||
- Quando uma frase orientativa descreve uma meta e a ação necessária para atingi-la, **iniciar a frase pelo objetivo** para facilitar o escaneamento rápido:
|
||||
- ✅ `"Para emitir a licença, anexe o parecer técnico conclusivo"`
|
||||
- ❌ `"Anexe o parecer técnico conclusivo para emitir a licença"`
|
||||
- ✅ `"Para concluir a solicitação, anexe o documento comprobatório"`
|
||||
- ❌ `"Anexe o documento comprobatório para concluir a solicitação"`
|
||||
3. **Pontuação enxuta para escaneabilidade (*Skip unnecessary punctuation*):**
|
||||
- **Omitir ponto final (`.`)** em: rótulos (`label`), botões, títulos e subtítulos, cabeçalhos de seção, tooltips curtos de 1 frase, toasts/snackbars de 1 frase e itens de lista (*bullet points*) de frase única.
|
||||
- **Proibir dois-pontos (`:`)** ao final de títulos, cabeçalhos de seção/lista e labels de campos (`<h3>Documentos exigidos</h3>` e nunca `<h3>Documentos exigidos:</h3>`).
|
||||
|
|
@ -160,9 +160,9 @@ Toda escrita em componentes Vue (`*-front`) deve aplicar os 7 princípios do gui
|
|||
- **Proibido** usar pontos de exclamação (`!`) ou palavras alarmistas (`"Atenção!"`, `"Erro fatal!"`, `"Cuidado!"`) em mensagens de erro ou aviso.
|
||||
5. **Consistência de pessoa verbal (2ª pessoa):**
|
||||
- Dirigir-se diretamente ao usuário em 2ª pessoa (`"você"`, `"seu/sua"`).
|
||||
- **Nunca misturar** 1ª pessoa (`"Meus processos"`) e 2ª pessoa (`"Gerencie seus processos"`) na mesma tela ou fluxo.
|
||||
- **Nunca misturar** 1ª pessoa (`"Minhas solicitações"`) e 2ª pessoa (`"Gerencie suas solicitações"`) na mesma tela ou fluxo.
|
||||
6. **Algarismos para números e zero abreviações truncadas (*Use numerals & Avoid abbreviations*):**
|
||||
- Escrever números, limites e contadores **sempre como algarismos** (`"3 condicionantes pendentes"`, `"Até 10 MB"`, `"Há 2 dias"`), nunca por extenso (`"três condicionantes"`).
|
||||
- Escrever números, limites e contadores **sempre como algarismos** (`"3 pendências encontradas"`, `"Até 10 MB"`, `"Há 2 dias"`), nunca por extenso (`"três pendências"`).
|
||||
- **Proibido** usar abreviações truncadas na interface (`"Qtd."`, `"Obs."`, `"Cad."`, `"End."`, `"Dt."`, `"Máx."`, `"Mín."`, `"Tel."`). Escrever a palavra por extenso (`"Quantidade"`, `"Observações"`, `"Cadastro"`, `"Endereço"`, `"Data"`, `"Máximo"`).
|
||||
7. **Acessibilidade textual (*Alt text & Anti-truncamento cego*):**
|
||||
- Textos alternativos (`alt`) devem ser concisos (até **125 caracteres**) e descrever a função/conteúdo sem iniciar por `"Imagem de..."` ou `"Ícone de..."`. Imagens decorativas devem usar `alt=""`.
|
||||
|
|
@ -172,11 +172,12 @@ Toda escrita em componentes Vue (`*-front`) deve aplicar os 7 princípios do gui
|
|||
|
||||
## Impacto
|
||||
|
||||
Sem esta regra, o agente gera interfaces com textos prolixos, capitalização inconsistente (*Title Case* misturado com *Sentence case*), botões de confirmação ambíguos (`Sim/OK`), abreviações amadoras (`Qtd.`, `Obs.`) e mensagens técnicas que confundem o usuário final.
|
||||
Sem esta regra, o agente gera interfaces com textos prolixos, capitalização inconsistente (*Title Case* misturado com *Sentence case*), botões de confirmação ambíguos (`Sim/OK`), abreviações amadoras (`Qtd.`, `Obs.`) e mensagens técnicas ou de outro domínio que confundem o usuário final.
|
||||
|
||||
## Referências
|
||||
|
||||
- Material Design 3 — Writing Best Practices: `https://m3.material.io/foundations/writing/best-practices`
|
||||
- Rule: `global/rules/identidade-modulo` (`memorias-ia/modulo.yml`)
|
||||
- Rule: `global/rules/zod-validacao-padrao` (schemas com mensagens customizadas)
|
||||
- Rule: `global/rules/refactoring-ui-hierarquia-despoluicao` (hierarquia visual e despoluição)
|
||||
- Skill: `skills/ux-fluxo-funcional/SKILL.md` (jornada e organização de telas, modais e painéis)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ Toda construção ou refatoração em pacotes `*-front` (`@front`, `@ux`, `@land
|
|||
- 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"`).
|
||||
- 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 etapas pendentes"`, `"R$ 15.000,00 de valor 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.
|
||||
|
|
@ -128,17 +128,17 @@ Mesmo respeitando pesos tipográficos e ausência de bordas, uma tela continuar
|
|||
|
||||
```vue
|
||||
<v-card variant="outlined" class="pa-2">
|
||||
<h1 class="text-h3">Listagem de Licenças</h1>
|
||||
<h1 class="text-h3">Listagem de Solicitações</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>
|
||||
<div><strong>Razão Social:</strong> Organizaçã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><strong>Status:</strong> Em andamento</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="success" variant="flat">Concluir</v-btn>
|
||||
<v-btn color="warning" variant="flat">Exportar</v-btn>
|
||||
<v-btn color="error" variant="flat">Excluir</v-btn>
|
||||
</div>
|
||||
|
|
@ -152,23 +152,23 @@ Mesmo respeitando pesos tipográficos e ausência de bordas, uma tela continuar
|
|||
<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>
|
||||
<h1 class="text-h6 font-weight-semibold">Solicitações ativas</h1>
|
||||
<p class="text-body-2 text-medium-emphasis">12 solicitações registradas 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>
|
||||
<v-btn color="primary" variant="flat">Nova solicitação</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-subtitle-1 font-weight-semibold">Organizaçã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 color="secondary" variant="tonal" size="small">Concluir</v-btn>
|
||||
<v-btn variant="text" size="small">Editar</v-btn>
|
||||
<v-btn variant="text" color="error" size="small">Excluir</v-btn>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue