Pular para o conteúdo

DESIGN.md

O DESIGN.md reúne, em um único arquivo de texto, as decisões visuais e de interface do MDS: cores, tipografia, espaçamento, elevação, formas, componentes-chave, estilo de escrita e as diretrizes de comportamento (estados, feedback, ações destrutivas, formulários e navegação). É o contexto que uma IA precisa para gerar telas que parecem e se comportam como o produto.

  • Em ferramentas de código (Claude Code, Cursor e similares): baixe o arquivo e salve como DESIGN.md na raiz do projeto, para o agente ler antes de gerar ou alterar interface.
  • Em geradores de interface (Google AI Studio, Lovable, v0 e similares): cole o conteúdo nas instruções do projeto ou anexe o arquivo como conhecimento.
  • Para classes CSS exatas, combine com o pacote @mobiis/mds-style (o DESIGN.md descreve as decisões; as classes mds-* vêm do CSS).

O arquivo é gerado do CSS real e das diretrizes do MDS. Quando o sistema mudar, baixe de novo.

1. Overview

O Mobiis Design System (MDS) é a linguagem visual do ecossistema de logística integrada da Mobiis (TMS, YMS, WMS, roteirização, rastreamento de frota e a assistente MIA). O público é operacional e técnico — operadores logísticos, motoristas, gerentes de pátio, diretores de supply chain — e a interface precisa sustentar alta densidade de dados em tempo real sem parecer poluída.

Diretriz central: simplificar e revelar informação progressivamente. Mostre apenas o que é pertinente para a ação do momento; deixe o sistema fazer o trabalho pesado e o usuário no controle. Cada tela tem um objetivo principal (Lei de Hick: mais opções visíveis = mais tempo de decisão).

Princípios formais do MDS (fonte: docs/principios-de-design.md):

  • Questionamos — O trabalho deve ter um propósito - procuramos abordar problemas reais e urgentes que as pessoas estão enfrentando. Questionamos até entender claramente o núcleo do problema antes de gastar um pouco de tempo no desenvolvimento de soluções. Questionamos afim de não perder tempo resolvendo os problemas errados.
  • Clareza — Para uma interface ser eficaz e eficiente, o usuário deve ser capaz de reconhecer a sua utilidade e entender como ela pode ajudá-lo, prever o que vai acontecer durante o uso, e conseguir interagir com sucesso. Não há motivos para mistérios nas interfaces. Clareza inspira confiança e cativa o uso.
  • Objetividade — O tempo que leva para fazer uma decisão aumenta com o número de opções apresentadas. (Lei de Hick)
  • Consistência — Padronização de componentes, comportamentos e funcionalidades. Comportamento igual para itens semelhantes. “Se parece um botão, deve se comportar como um botão”.

Identidade técnica: BEM estrito com prefixo mds- em todo componente (.mds-btn, .mds-card__header, .mds-btn--primary), enquanto fundações e utilitários (grid, spacing, texto) usam nomes “limpos” no padrão Bootstrap/Tailwind (.container, .gap--md, .text-muted) para reduzir a curva de aprendizado. Tudo — com ou sem prefixo — resolve para os mesmos design tokens (CSS Custom Properties --mds-*), então a consistência visual é garantida mesmo nas classes sem prefixo.

Multi-marca: O sistema suporta múltiplos tenants/produtos trocando só a cor primária via [data-primary="..."] no elemento raiz. O padrão (sem atributo) é brand-mobiis. Um agente que gerar UI para um cliente específico deve preservar essa variável, nunca fixar a cor em hexadecimal.


2. Colors

Todas as cores são CSS Custom Properties (--mds-colors-*), nunca hex fixo no HTML/CSS de consumo. Cada papel semântico tem 5 tons (lighter, light, main, dark, darker) + seu par de contraste — nomenclatura alinhada ao Figma (--mds-colors-<papel>-<tom> para o fundo, --mds-colors-<papel>-on-<tom> para o texto/ícone legível sobre ele, ex.: --mds-colors-primary-main + --mds-colors-primary-on-main).

Papéis semânticos (tema claro)

Papel Token base lighter light main dark darker Quando usar
Primary --mds-colors-primary-* #ecf3ff #a0c4fd #408afa #3068bb #20457d Ação principal, marca, item ativo/selecionado, foco de interação
Secondary --mds-colors-secondary-* #e9ebf3 #939ac5 #27348b #1d2768 #141a46 Marca institucional, badges/destaques secundários, campo válido (borda)
Danger --mds-colors-danger-* #fcebe6 #f29980 #e53200 #ac2600 #731900 Erro, exclusão, bloqueio, ação irreversível
Warning --mds-colors-warning-* #fef9e6 #f8e280 #f0c400 #b49300 #786200 Atenção, campo obrigatório, dado pendente de revisão
Info --mds-colors-info-* #e6f3fb #80c3ed #0087db #0065a4 #00446e Mensagem neutra, dica, estado informativo sem urgência
Success --mds-colors-success-* #e6f9e6 #80e381 #00c703 #009502 #006402 Confirmação, conclusão, dado validado

on-<tom> é a cor de texto/ícone garantida legível sobre aquele fundo — sempre use o par (--mds-colors-<papel>-main + --mds-colors-<papel>-on-main), nunca aplique texto escuro fixo sobre um fundo de token.

✅ Checagem cruzada com o Figma (2026-09-22, Design System 2.0): Os fundos (lighter/main/dark/darker) batem exatamente com o Figma em todas as 12 famílias (primary, secondary, danger, warning, success, info, aqua, blue, green, orange, pink, red, teal, yellow) e na escala de cinza inteira.

Corrigido em src/scss/themes/_light.scss em 2026-09-22 (reproduzindo a fórmula de src/stories/foundations/TokenManager.stories.ts, generateScale: tom light = passo 200 = 50% de mistura da cor-base com branco): o tom light de Primary/Secondary estava desatualizado.

  • --mds-colors-primary-light: era #70a7fb, agora #a0c4fd.
  • --mds-colors-primary-on-light: era #020408, agora #060e19 (par de contraste do tom acima, ajustado junto para continuar legível).
  • --mds-colors-secondary-light: era #5d67a8, agora #939ac5.
  • --mds-colors-secondary-on-light: era #f9f9fc, agora #010204 (par de contraste do tom acima, ajustado junto para continuar legível).

Achado à parte, ainda em aberto (não corrigido): Figma: on-main/on-dark/on-darker = o próprio tom lighter do papel. CSS: um quase-branco específico do papel, próximo mas não idêntico ao lighter.

  • primary: CSS #f9fbff, Figma reaproveita o lighter (#ecf3ff).
  • secondary: CSS #f9f9fc, Figma reaproveita o lighter (#e9ebf3). Confiança: alta para primary/secondary (zoom dedicado); padrão, não confirmado byte a byte, nos demais papéis.

Background / Surface / Text (neutros)

Escala base: --mds-colors-gray-0 #fefefe … --mds-colors-gray-50 #fafbfc … --mds-colors-gray-100 #f3f4f6 … --mds-colors-gray-200 #e8eaee … --mds-colors-gray-300 #dcdfe5 … --mds-colors-gray-400 #d0d4dc … --mds-colors-gray-500 #9c9fa5 … --mds-colors-gray-600 #686a6e … --mds-colors-gray-700 #343537 … --mds-colors-gray-800 #151516 … --mds-colors-gray-900 #060607.

Uso Token Valor Regra
Surface / Card --mds-dimmed-default #fefefe Fundo padrão de card, modal, painel — “branco” do sistema
Background (página) --mds-colors-background-light #fafbfc Fundo da aplicação por trás dos cards
Background (elemento) --mds-colors-background-main #f3f4f6 Fundo de blocos secundários (ex.: .mds-box)
Background (rebaixado) --mds-colors-background-dark #e8eaee Hover neutro, divisores de área, estado “dimmed”
Border --mds-colors-ui-border #e8eaee Toda borda 1px de card, input, tabela
Text — corpo (padrão) --mds-colors-foreground-main #686a6e Texto de parágrafo, valor de dado, corpo em geral
Text — ênfase/secundário --mds-colors-foreground-dark #343537 Título, rótulo em destaque, texto que precisa de mais peso que o corpo
Text — muted/apoio --mds-colors-foreground-light #9c9fa5 Placeholder, texto de ajuda, timestamp, metadado de baixa prioridade

Note a inversão de intuição: foreground-dark é o texto de MAIOR ênfase (mais escuro = mais peso), e foreground-light é o texto de MENOR ênfase (mais claro = apoio). Siga essa semântica, não o nome literal.

Destructive

Não existe token destructive isolado — Danger cobre esse papel (botão de exclusão = variant="danger" / .mds-btn--danger, --mds-colors-ui-danger = #e53200).

Overlay / Shadow

  • --mds-colors-ui-shadow: rgba(22, 22, 23, 0.15) — base de toda sombra do sistema.
  • --mds-colors-background-transparency: rgba(52, 53, 55, 0.6) — backdrop de modal/drawer.

Multi-marca ([data-primary="..."])

Tenant Cor main
brand-mobiis #408afa
brand-log #64be50
blue #0087db
teal #00dbdb
aqua #00f0b8
green #00c703
yellow #f0c400
orange #f07800
red #e53200
pink #ff0073

Tema escuro

[data-theme="dark"] e :root aplicam-se ao mesmo elemento — uma prop não redeclarada em [data-theme="dark"] cai para o valor de :root (cascata normal do CSS); a maioria dos papéis redeclara os 5 tons com valores próprios para dark. Ex.: primary-main é #408afa no claro e #3068bb no escuro. Neutros do tema escuro: fundo #001027, texto de corpo #8090a7. Um agente de IA nunca deve ler valor de cor fixo: sempre referenciar o token, para funcionar nos dois temas automaticamente.

🧮 Primary/Secondary do tema escuro: calculados, não conferidos ao vivo no Figma (2026-09-22). Não existe página de dark mode no arquivo Figma. Fórmula + mapeamento de src/stories/foundations/TokenManager.stories.ts (generateScale, selectOnColor/APCA, semanticMappingsDark), rodados com Node (apca-w3/culori, as mesmas libs da story) — não lidos de um Figma consultado ao vivo.

Mapeamento aplicado (semanticMappingsDark): lighter=passo 700, light=passo 600, main=passo 500, dark=passo 300, darker=passo 200.

Primary (src/scss/themes/_dark.scss):

  • lighter: #20457d → #10223f; on-lighter: #f9fbff → #ecf3ff
  • light: #3068bc → #20457d; on-light: #f9fbff → #ecf3ff
  • main: #408afa → #3068bb; on-main: #f9fbff → #ecf3ff
  • dark: #a0c5fd → #70a7fb; on-dark: #020408 → #020408
  • darker: #cfe2fe → #a0c4fd; on-darker: #020408 → #060e19 Secondary (src/scss/themes/_dark.scss):
  • lighter: #141a46 → #0a0d23; on-lighter: #f9f9fc → #e9ebf3
  • light: #1d2768 → #141a46; on-light: #f9f9fc → #e9ebf3
  • main: #27348b → #1d2768; on-main: #f9f9fc → #e9ebf3
  • dark: #939ac5 → #5d67a8; on-dark: #f9f9fc → #e9ebf3
  • darker: #c9cce2 → #939ac5; on-darker: #010204 → #010204

⚠️ O CSS anterior de dark já usava outro mapeamento de passo (lighter=600, light=500, main=400, dark=200, darker=100) — diferente do declarado no Token Manager. main muda de valor visível de forma perceptível (não só um ajuste de contraste): de #408afa (idêntico ao main do tema claro) para #3068bb, mais escuro. ⚠️ Sem página de dark no Figma, não há como confirmar visualmente — só a fórmula do gerador garante a consistência.


3. Typography

Fonte: "Manrope", system-ui, -apple-system, "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji". Token: --mds-font-family.

Pesos: --mds-font-weight-light 300 · --mds-font-weight-normal 400 · --mds-font-weight-semibold 600 · --mds-font-weight-bold 700 (peso padrão de botões: semibold).

Escala de tamanho (--mds-font-size-*)

Token px
xs 12
sm 14
md 16
lg 20
xl 24
xxl 32
xxxl 40
hg 48
xhg 56
xxhg 64

Hierarquia semântica (classes atuais, prefixo mds-)

Classe Tamanho Peso Line-height
.mds-headline--h1 64px 700 125%
.mds-headline--h2 48px 700 125%
.mds-headline--h3 32px 700 125%
.mds-headline 24px 700 125%
.mds-headline--h4 24px 700 125%
.mds-title--lg 20px 700 125%
.mds-title 16px 700 125%
.mds-title--md 16px 700 125%
.mds-title--sm 14px 700 125%
.mds-body--lg 20px 400 150%
.mds-body 16px 400 150%
.mds-body--md 16px 400 150%
.mds-body--sm 14px 400 150%
.mds-body--xs 12px 400 150%

Classes legadas (sem prefixo, @deprecated no SCSS — não usar em código novo)

Classe Tamanho Peso Line-height
.display2 40px 300 125%
.display 32px 700 125%
.title 24px 400 125%
.subtitle 20px 700 125%
.body 16px 400 150%
.small 14px 400 150%
.caption 14px 700 125%
.helper-text 12px 400 150%

Também existem diretivas Angular equivalentes às classes atuais: mdsHeadline="h1|h2|h3|h4", mdsTitle="lg|md|sm", mdsParagraph="lg|md|sm|xs".

Classes utilitárias de alinhamento/transformação de texto (.text-left, .text-uppercase…) não são conceito de tipografia — são utilitário de fundação. Lista exata na skill mds-style (agent-skills/SKILL.md), seção “Utility Classes Cheat Sheet”.


4. Layout & Spacing

Base: grid inspirado em Bootstrap (.container, .container-fluid, .row, .col-[n], breakpoints xs/sm/md/lg/xl/xxl), sem prefixo mds- (é fundação, não componente).

Densidade: média-alta — o produto prioriza mostrar mais dado por tela (tabelas, kanbans, cards compactos) mantendo respiro suficiente para uso prolongado.

Escala de espaçamento (--mds-spacing-*)

Token px
xs 4
sm 8
md 16
lg 24
xl 32
xxl 40
xxxl 48

md (16px) é o padrão quando nenhum tamanho é especificado.

As classes utilitárias que aplicam esta escala (.padding-{pos}--{tam}, .margin-{pos}--{tam}, .gap--{tam}, .d-flex e o resto do grid/flexbox) são utilitário de fundação, não conceito de spacing — catálogo exato na skill mds-style (agent-skills/SKILL.md), seção “Utility Classes Cheat Sheet”.


5. Elevation & Depth

Sombra em 5 níveis, todas usando a mesma cor-base, variando só o espalhamento — cresce junto com a escala de espaçamento:

Nível Classe box-shadow
1 .mds-elevation--1 (ou .elevation--1) 0 1px 1px rgba(22, 22, 23, 0.15)
2 .mds-elevation--2 (ou .elevation--2) 0 2px 4px rgba(22, 22, 23, 0.15)
3 .mds-elevation--3 (ou .elevation--3) 0 4px 8px rgba(22, 22, 23, 0.15)
4 .mds-elevation--4 (ou .elevation--4) 0 8px 16px rgba(22, 22, 23, 0.15)
5 .mds-elevation--5 (ou .elevation--5) 0 16px 24px rgba(22, 22, 23, 0.15)

Blur (glassmorphism pontual — não é padrão de fundo): --mds-blur-xs 8px · --mds-blur-sm 16px · --mds-blur-md 32px · --mds-blur-lg 48px · --mds-blur-xl 64px, via .blur--{tam} (backdrop-filter).

Divisores: linha 1px sólida na cor de borda (não sombra) — usada em vez de elevação para separar seções de mesma superfície.

Motion: transições de estado (hover/active/expand) usam 0.2s com easing cubic-bezier(0.645, 0.045, 0.355, 1) — perceptível mas rápido, sem “bounce”.


6. Shapes & Borders

Cantos padronizados em escala própria (não ligada à escala de spacing, apesar de nomes iguais):

Token px
xxs 4
xs 6
sm 8
md 16
lg 24
xl 32
xxl 40
xxxl 48

Raio por família de componente (extraído do SCSS de cada um — não presuma)

Elemento Raio Fonte
Botão (md, padrão) 8px (--mds-radius-sm) tokens/_components.scss
Input / Select (padrão) 8px (--mds-radius-sm) mixins/_fields.scss:33 (parâmetro padrão do mixin)
Card 8px (--mds-radius-sm) components/_card.scss:12
Modal (mds-float-panel--modal) 8px (--mds-radius-sm) components/_float-panel.scss:189
Drawer / tela cheia (--fullscreen) 0px (sem raio — encosta na borda da viewport) components/_float-panel.scss:226
Avatar (padrão) 8px, quadrado arredondado (não é círculo por padrão) components/_avatar.scss:23
Avatar .mds-avatar--rounded 100% (círculo completo) components/_avatar.scss:30
Checkbox 6px (--mds-radius-xs) components/_checkbox.scss:4 (parâmetro padrão do mixin)
Switch/Toggle 40px (--mds-radius-xxl, pill) components/_checkbox.scss:42 (parâmetro padrão do mixin)

A maioria dos componentes de formulário/superfície (botão, input, select, card, modal, checkbox) usa o mesmo raio pequeno (--mds-radius-sm, 8px, ou --mds-radius-xs, 6px, no checkbox) — não há um raio “de input” desproporcionalmente maior; só avatar --rounded e switch/toggle chegam a formas totalmente arredondadas.

Borda: 1px sólida como padrão (--mds-colors-ui-border ou --mds-control-default-border); campo em foco/erro sobe para 2–3px com a cor semântica. Nunca use outline do navegador puro — o MDS estiliza o próprio anel de foco.


7. Key Components

Botões (.mds-btn)

Tamanho Altura Raio Fonte do botão
xxs 12px --mds-radius-xxs — (sem botão nesse tamanho)
xs 24px --mds-radius-xs 12px
sm 32px --mds-radius-sm 12px
md 48px --mds-radius-sm 14px
lg 56px --mds-radius-sm 16px
  • Peso de texto sempre semibold (600), independente do tamanho (fonte: components/_button.scss:18).
  • Variantes de cor: control/default (neutro, cinza), primary, secondary, danger, warning, success, info, transparent/link (sem fundo, ação de baixa prioridade). Regra de produto: no máximo 1 botão primary por tela/formulário/diálogo.
  • Modificadores: outline (contorno, sem fundo sólido), rounded (pill), loading (loader substitui o conteúdo, botão inerte), disabled.
  • Botão só-ícone precisa de aria-label/tooltip — nunca um botão mudo visualmente.

Inputs / Campos de formulário

  • Raio padrão igual ao de botões e cards (8px) — não é mais arredondado que o resto do sistema.
  • Estado padrão: fundo branco (surface), borda 1px na cor de borda padrão.
  • Foco/ativo: borda sobe para a cor primary; erro: borda + sombra em danger; obrigatório pendente: destaque em warning; válido: borda secondary-dark.
  • Rótulo acima do campo (não usa placeholder como rótulo); texto de ajuda abaixo, cor muted.

Cards

  • Fundo surface, raio 8px, elevação 1 em repouso, sobe ao hover/seleção.
  • Cabeçalho (mdsCardHeader) arredonda só o topo; corpo e rodapé (mdsCardFooter) seguem o mesmo raio do card.
  • Notificação/atualização: badge sólido no canto; seleção em lote: checkbox + anel de destaque (box-shadow: 0 0 0 2px na cor do estado).

Modais e Drawers (mds-float-panel)

  • Modal (--modal): raio 8px, elevação alta, backdrop escuro translúcido. Diálogo central, para interrupção/confirmação/detalhe que exige foco total.
  • Drawer (--drawer): painel lateral sem raio (encosta na borda), para fluxos de formulário que devem manter contexto da tela por trás.
  • Tela cheia (--fullscreen): raio zerado explicitamente.
  • Ações sempre no rodapé, fixas; título curto; fechamento por “×” ou clique no backdrop.
  • Topbar: altura fixa 64px. Menu lateral: 256px expandido, 64px compacto (só ícones), altura de item 64px.
  • Item ativo com fundo item-active-background (tom claro de primary) e borda/texto primary-dark.
  • Abas (nav-tabs): item ativo com peso bold e indicador em primary; nunca mais de 2 níveis de profundidade em menus/dropdowns.

Ícones

  • Sistema Lucide (SVG), consumido por alias semântico em português no Angular (ex.: icon="excluir") — nunca pelo nome literal do ícone Lucide.
  • Tamanhos alinhados à escala de fonte (sm/md/lg/xl), herdam a cor do texto/ícone do contexto (currentColor).

8. Voice & Writing

O texto da interface é lido em movimento (pátio, doca, celular do motorista), por quem quer saber o que aconteceu com a carga e o que fazer agora. Todo texto gerado para o MDS segue as regras abaixo — inclusive rótulos, placeholders, mensagens e dados de exemplo em protótipos.

Princípios

Princípio Regra
Direto A informação mais importante vem primeiro.
Preciso Diga qual carga, placa ou documento e quanto; nada de “ocorreu um erro”.
Neutro Voz do sistema: sem “você”, “eu” ou “nós”; sem “Ops”; sem exclamação.
Familiar Vocabulário do operador (Carga, Viagem, Manifesto, Pátio, Doca), não o do banco de dados.
Consistente Um conceito, um nome, em todas as telas.

Estrutura da mensagem

Mensagem de feedback = o que aconteceu (com o objeto específico) + o que fazer (se houver). Ex.: “CPF inválido. Insira apenas números.” — nunca “Você digitou o CPF errado.” nem “Ocorreu um erro.”

Capitalização

Elemento Estilo Exemplo
Botão Título Confirmar Entrega
Título de página/modal/drawer/EmptyState Título Excluir Rota?
Item de menu e aba, cabeçalho de coluna de tabela Título Agendamento de Docas · Data de Entrega
Rótulo de campo, placeholder Sentença Nome do motorista
Toast, Alert, erro, Tooltip, texto de carregamento Sentença Falha na conexão.
Descrição e texto de ajuda, status/badge Sentença Em trânsito

Caixa de título: cada palavra significativa em maiúscula; artigos, preposições e conjunções (a, o, de, da, em, para, por, com, e, ou…) em minúscula (Ir para o Dashboard). Caixa de sentença: só a primeira palavra e nomes próprios; siglas mantêm a grafia (NF-e, CPF). Nunca digite texto em CAIXA ALTA — se o design pedir maiúsculas, é estilo (CSS). (a validar: A regra por classe gramatical adapta ao português a regra “AP” (palavras com mais de 3 letras) hoje descrita nas Diretrizes.)

Regras de rótulo, pontuação e vocabulário

  • Botão: verbo no infinitivo + objeto, 1–2 palavras (Salvar, Emitir Nota, Despachar Carga); sem repetir o contexto da seção (seção “Motoristas” → Adicionar). Em confirmação, o botão repete a ação (Excluir Rota), nunca “Sim”/“OK”; a saída é Cancelar.
  • Reticências (…) no botão/item que abre outra janela ou pede mais dados antes de concluir (Configurar Filtros…); nunca em placeholder, tooltip ou item de submenu. Use o caractere único …, não três pontos.
  • Ponto final em mensagens e descrições (Toast, Alert, erro, EmptyState); sem ponto em rótulo, botão, título, placeholder, status e tooltip de uma frase. Pergunta sempre termina com “?”.
  • Status descreve onde a coisa está (particípio/expressão curta: Despachada, Em trânsito, Aguardando doca); ação descreve o que vai acontecer (infinitivo); processo em andamento é gerúndio + reticências (Gerando relatório…).
  • Verbo padrão por ação: Salvar, Excluir (definitivo), Cancelar (interrompe e mantém histórico), Pesquisar, Confirmar/Registrar/Concluir, Despachar, Emitir (documento fiscal). Não alterne com sinônimos (Deletar, Apagar, Buscar, Submeter).
  • Siglas: as de todo operador (NF-e, CT-e, MDF-e, CPF, CNPJ, CEP, ETA) valem sem explicação; as demais vêm por extenso ou em Tooltip (ICMS → “Imposto sobre circulação de mercadorias”). Termo em inglês só se for nome de produto ou uso corrente do setor.
  • Link descreve o destino (“Ver detalhes da carga”), nunca “Clique aqui”. Botão só-ícone sempre com aria-label e Tooltip.
  • Plural e gênero corretos, sem “(s)”: “1 carga”, “12 cargas”, “Nenhuma carga”. Cada frase é uma string inteira — nunca montada por concatenação.

Formatos (pt-BR)

Tipo Formato Exemplo
Data dd/mm/aaaa 25/09/2026
Hora 24 h 14:30
Moeda R$, ponto no milhar, vírgula nos centavos R$ 1.250,90
Peso, volume, distância Número, espaço, unidade 1.250 kg · 32,5 m³ · 142 km
Duração Unidade abreviada, sem ponto 45 min · 2 h 10 min
Placa Com hífen (antiga); sem hífen (Mercosul) ABC-1234 · ABC1D23
CEP / CPF Com máscara 00.000-000 · 000.000.000-00

Evite → Prefira

Evite Prefira
Sua carga foi despachada com sucesso agora. Carga despachada.
Tem certeza que quer apagar? Título “Excluir Rota?” + botões Cancelar · Excluir Rota
Ops, nada por aqui! Nenhuma Viagem Encontrada. Não há viagens para o filtro selecionado.
Por favor, aguarde enquanto carregamos… Carregando viagens…
Não foi possível agendar. Doca 3 indisponível às 14h. Escolha outro horário.
Digite aqui o nome do motorista… Nome do motorista

Ainda em aberto (a validar com Produto)

  • Termos oficiais do domínio (Carga, Viagem, Doca, Check-in/Check-out…) e o verbo Remover (tirar um item de uma lista ou vínculo sem apagá-lo) ainda precisam ser fechados com Produto e Operações.
  • Mostrar o fuso horário explicitamente em telas que operem em mais de um fuso.

9. Interface Guidelines

Estas diretrizes são direcionamento, não livro de regras: desviar é permitido, desviar sem saber por quê não. Quando duas regras conflitarem, desempate nesta ordem — Clareza › Consistência › Objetividade (e antes de tudo, confirme que o problema é o certo). Se nenhum padrão serve, procure um componente existente no MDS antes de inventar; nunca crie estilo local “quase igual” ao do sistema.

Regras de comportamento e composição de tela (o “como a interface deve se comportar”), complementares às seções visuais 2–7 e ao estilo de escrita da seção 8. Fonte: seção Guidelines do docs-site. Itens marcados (proposta) ainda não foram validados com Produto — aplique, mas não trate como regra fechada.

9.1 Princípios aplicados a uma tela

Princípio Como aplicar Teste
Questionamos Parta do problema da pessoa (“quem quer fazer o quê e o que impede”), não da tela pedida. Consigo dizer qual problema isto resolve sem citar tela ou componente?
Clareza Toda tela responde: onde estou (título, breadcrumb, item ativo), o que posso fazer (uma ação principal em destaque), o que vai acontecer (rótulo que diz o resultado, estado sempre visível). Hierarquia por tamanho, contraste e espaço — “se tudo grita, nada é ouvido”. Em 5 segundos a pessoa diz para que serve a tela e qual é o próximo passo?
Objetividade Uma tela, um objetivo, um CTA primary. Mostre só o que serve à ação do momento; o resto fica atrás de um clique (Collapse, Drawer, Modal). Preencha o que o sistema já sabe. A ação principal cabe em uma frase sem “e”?
Consistência Mesma coisa, mesma aparência (tokens, nunca valor avulso); mesmo gesto, mesmo resultado (se Excluir confirma numa tela, confirma em todas); um conceito, um nome. Antes de criar, procure no MDS. Quem domina uma tela adivinha como funciona outra?

9.2 Filosofia — quando as regras acabam

  • O sistema carrega a complexidade, não a pessoa (Lei de Tesler): calcule, valide, preencha, sugira. Não peça digitação do que o sistema já sabe (usuário logado, carga selecionada, data de hoje).
  • Projete para o “usuário bêbado” — distraído, com pressa, de luva, no celular no pátio sob o sol, interrompido: alvos de toque generosos, contexto sempre visível, caminho de volta, dados preservados se a pessoa for interrompida, prevenção de erro em vez de só mensagem de erro. (proposta como checklist de revisão)
  • A pessoa no controle: preencha automaticamente mas deixe editar; toda ação que altera dado pode ser desfeita ou avisa claramente que não pode; nunca tome decisão irreversível pela pessoa.
  • Design não é decoração: sem enfeite que não ajude a tarefa (ilustração no lugar de dado, animação sem função, gradiente que compete com a informação). Cor, espaço e tipografia servem à hierarquia. Beleza é consequência de clareza.

9.3 Estados da interface

Nenhuma tela está pronta enquanto os cinco estados não estiverem desenhados e implementados — o estado “com dados” é só um deles.

Estado Pergunta que responde Componente
Carregando O sistema está trabalhando? .mds-loader, .mds-loader-box, .mds-progress--bar/--circle
Vazio Por que não há nada aqui e o que faço? .mds-empty-state
Erro O que falhou e como resolvo? .mds-alert--danger ou EmptyState com ação “Tentar novamente”
Sucesso Deu certo? Toast (ver lacuna abaixo), .mds-btn--success, tela de conclusão
Com dados Estado principal O componente da tela

Carregando

  • Nunca deixe o usuário olhando tela parada sem saber se travou. Escopo: global (página inteira → loader centralizado), da área (.mds-loader-box sobre o painel/tabela; o resto segue utilizável), inline (botão .mds-btn--loading).
  • Diga o que carrega, em caixa de sentença e sem pronome: “Gerando relatório…”, “Carregando viagens…” — nunca “Por favor, aguarde enquanto carregamos…”.
  • Desabilite a ação em andamento (evita despacho duplo). Prefira barra de progresso a spinner quando o sistema sabe quanto falta.
  • Skeleton não existe (nem em CSS nem no Angular): use .mds-loader-box sobre a área. Não invente .mds-skeleton.

Vazio

  • Estrutura fixa de cima para baixo: ícone/ilustração ligado ao contexto → título (caixa de título) → descrição (por quê/como resolver, caixa de sentença) → ação. Título e descrição são obrigatórios; ilustração sozinha não explica nada; nunca “Ops, nada por aqui”.
  • Três vazios diferentes: primeiro uso (ação = criar: “Subir Arquivo”), sem resultado do filtro (ação = Limpar Filtros, não criar), tudo em ordem (“Nenhum Alerta Pendente” + “Ir para o Dashboard”).

Erro

  • Três escalas: campo (no campo, abaixo dele), ação (Alert no contexto, ou Toast se não exigir correção), tela (estado de erro ocupando a área, com “Tentar novamente” — proposta).
  • Fórmula: o que aconteceu + como resolver, sem culpa — “CPF inválido. Insira apenas números.”, nunca “Você digitou o CPF errado.” / “Ocorreu um erro.”
  • Preserve tudo que o usuário digitou. Mantenha o erro visível até ser resolvido. Erro de campo aparece ao sair do campo, não a cada tecla.

Sucesso

  • Proporcional ao impacto: ação pequena → Toast “Alterações salvas.”; conclusão de fluxo (despachar, registrar entrega) → botão Success + estado de conclusão; ação em massa → resumo completo “12 cargas despachadas. 2 com falha.”

9.4 Feedback ao usuário

Regra de ouro: o peso do feedback é proporcional ao impacto — quanto mais a pessoa precisa agir, mais ele interrompe e permanece visível. Um erro que some sozinho em 4 s pode ser uma carga não despachada que ninguém viu.

Escolha o componente respondendo na ordem e parando no primeiro “sim”:

  1. Mensagem sobre um campo de formulário? → mensagem no próprio campo (.mds-input--danger + .mds-input__helper).
  2. Precisa de decisão antes de continuar (confirmar exclusão, escolher)? → Modal (.mds-float-panel--modal).
  3. O problema precisa continuar visível até ser resolvido (falha na emissão, manutenção atrasada)? → Alert (.mds-alert--{neutral|info|warning|danger|success}).
  4. Só confirma o resultado de uma ação, sem nada a fazer? → Toast.
  5. Explicação curta de ícone/sigla/dado? → Tooltip (.mds-tooltip).
  6. Não há dados? → EmptyState.
Tipo (Alert) Cor Quando usar
Erro Danger (vermelho) Bloqueia a operação — falha na emissão de nota
Aviso Warning (amarelo) Requer cautela, não bloqueia — veículo com manutenção atrasada
Sucesso Success (verde) Confirma conclusão — rota otimizada
Informação Info (azul) Contexto útil, sem urgência — nova versão do manifesto disponível
Neutro sem cor semântica Aviso genérico, sem peso semântico
  • A cor nunca é o único sinal: acompanhe sempre com texto e, quando couber, ícone (parte dos operadores não distingue vermelho de verde; o sol no pátio apaga contraste sutil). Vermelho é reservado para erro — para destacar “importante”, use aviso.
  • Alert: fica no contexto do problema (topo da área afetada, não num canto distante); dispensável só quando ignorar não tem consequência; um por área (vários problemas → uma lista dentro de um Alert). Botão de ação que leva a tela de resolução usa reticências (“Configurar impressora…”).
  • Toast: no máximo uma frase curta, sem ação crítica, sem tirar o foco; nunca o único registro de erro que exige correção. (proposta) sucesso/info somem sozinhos, erro permanece até ser dispensado; um por vez, o resto em fila.
  • Modal: só para interromper (confirmação crítica, decisão, detalhe que pede foco total); sempre com saída clara (Cancelar e ×); nunca abra modal sobre modal — fluxo longo usa Drawer. (proposta) foco preso dentro, Esc fecha, foco volta ao elemento de origem.
  • Tooltip: descreve ícone sem texto visível; nunca repete o rótulo visível; nunca carrega informação essencial ou ação (não aparece em toque); sem ponto final.
  • Lacuna conhecida — Toast: existe só no Figma; não há .mds-toast nem <mds-toast>. A aproximação prevista é <mds-alert [fixed]="true" [dismissible]="true"> (.mds-alert fixo e dispensável). Não invente a classe; sinalize no ticket que a tela usa a aproximação.

9.5 Ações destrutivas e confirmação

Regra de ouro: o atrito da confirmação é proporcional ao custo de desfazer. Reversível → sem confirmar. Irreversível → confirmação explícita dizendo o que será perdido. Confirmar tudo faz o operador clicar “OK” sem ler.

Nível de atrito Quando O que fazer
1. Reversível, baixo impacto Recuperável fácil, afeta só o próprio usuário Executa direto + Toast. (proposta) oferecer “Desfazer” por alguns segundos
2. Destrutivo e limitado Apaga/cancela um item; perda grande mas isolada (excluir rota, cancelar agendamento) Modal de confirmação
3. Irreversível, em massa ou com impacto em outros Não recupera, ou afeta muitos itens/pessoas Modal com a consequência explícita; (proposta) nos casos graves, exigir digitar o nome/número do item

Anatomia da modal de confirmação (sempre estas partes):

  1. Título: a pergunta com ação + objeto, caixa de título, termina em “?” → Excluir Rota?
  2. Corpo: o que será perdido, com números e nomes, e se dá para desfazer; cite impacto em outras pessoas quando houver → “A rota RT-2041 e seus 12 pontos de parada serão removidos. Essa ação não pode ser desfeita.”
  3. Saída: Cancelar, estilo secundário. Confirmação: repete a ação, .mds-btn--danger → Excluir Rota. Nunca “Sim”/“Não”/“OK”; sem reticências no botão de confirmação.
  • Fechar (×, Esc, clique no backdrop) equivale a Cancelar — nunca confirma. Uma decisão por modal. Sem tom de ameaça, caixa alta ou exclamação: a seriedade vem do conteúdo. (proposta) foco inicial em Cancelar, para Enter sem pensar não destruir nada.
  • Vocabulário: Excluir = apaga de forma definitiva; Cancelar = interrompe algo em andamento/criado e mantém histórico; Remover = tira da lista/vínculo sem apagar o item (verbo ainda a validar com Produto). Não misture os três.
  • Prefira alternativas a excluir quando há histórico/auditoria/obrigação fiscal: motorista com viagens → Inativar Motorista (proposta); carga que já andou → Cancelar Carga; documento fiscal emitido → não oferecer exclusão, emitir o cancelamento/correção previsto em lei.
  • Posição na tela: a ação destrutiva nunca é o primary da tela; usa Danger e peso visual menor que a principal. Em menu de ações: no fim, separada por divisor, em cor de perigo; frequentes (Editar, Duplicar) no topo. Em linha de tabela: uma ação → botão de ícone com Tooltip; duas ou mais → menu Mais opções com a destrutiva no fim. Afaste de ações de uso constante (toque/luva). O item de menu que abre a confirmação leva reticências (“Excluir Registro…”).
  • Em massa: selecionar não executa (ação em botão separado); a confirmação diz a quantidade (“Excluir 12 cargas?”); diga antes quais itens não podem ser afetados e por quê; depois mostre o resultado completo (“10 cargas excluídas. 2 mantidas.”) — nunca só “Concluído”.
  • Prevenir em vez de confirmar: ação inválida fica desabilitada com Tooltip explicando o motivo (“Carga em trânsito. Cancele a viagem para excluir.”); bloqueie por dependência e explique; respeite permissões (sem permissão, não aparece ou desabilita com motivo); mostre o impacto antes do clique.
  • Depois: sucesso → Toast “Rota excluída.” e o item some da lista imediatamente, usuário continua onde estava (volta à lista, não a uma tela vazia); falha → Alert no contexto, item continua na lista; parcial → resumo do que foi e do que falhou, com motivo.

9.6 Formulários e validação

Regra de ouro: só peça o que é necessário para concluir a tarefa agora; o resto pode ser preenchido depois. Antes de desenhar cada campo: o sistema já sabe? precisa agora? dá para escolher em vez de digitar?

  • Uma coluna por padrão; duas só para campos curtos e relacionados (CEP + número; data + hora). Rótulo sempre acima e visível — placeholder nunca substitui rótulo. Texto de apoio abaixo, curto, esmaecido; explica formato ou consequência, não repete o rótulo.
  • Ordem da tarefa, não do banco de dados. Agrupe campos relacionados sob cabeçalho de seção (SectionHeader: “Dados do motorista”, “Veículo”). Revelação progressiva: campos dependentes só aparecem depois da escolha (ConfigToggle, opção “Outro”). (proposta) acima de ~10 campos, use seções/etapas com indicação do que falta.
  • Obrigatório: realce amarelo (warning) + asterisco no rótulo + aria-required="true" (.mds-input--required); vermelho é só erro. Explique o asterisco no topo se houver mais de um. (proposta) se quase tudo é obrigatório, marque os opcionais com “(opcional)” e retire o amarelo.

Qual controle usar

Necessidade Controle Regra
Texto, número, dado com máscara (CPF, CNPJ, CEP, placa, moeda) Input Use a máscara pronta do tipo, nunca máscara customizada
Uma opção entre 2 a 5 Radio Sempre com uma opção pré-selecionada e título de grupo
Uma ou mais entre muitas Select com busca Múltipla mostra tags dentro do campo (só via Angular)
Marcar itens de uma lista Checkbox Cada caixa independente; só vale após confirmar
Ligar/desligar com efeito imediato Switch Sem botão de confirmar. Se só vale após “Salvar” → Checkbox
Ligar/desligar um bloco de campos ConfigToggle Campos dependentes aparecem logo abaixo
Data ou período DatePicker dd/mm/aaaa, com atalhos (Hoje, Últimos 7 dias)
Arquivo Uploader Mostre formatos e tamanho aceitos antes do envio (só via Angular)
Cadastrar item que falta num Select MicroForm (.mds-microform) Máx. 5 campos; o que foi digitado na busca entra no campo principal; ao confirmar, o item já fica selecionado
  • Input/Select/DatePicker: substantivo curto, caixa de sentença. Checkbox: positivo e diz o que acontece ao marcar (“Incluir seguro de carga”, não “Não deixar sem seguro”). Switch: rótulo estático, nunca alterna entre “Ativado/Desativado”, sem pergunta (“Rastreador GPS”). ConfigToggle: título em caixa de título + descrição em sentença. Placeholder de Select convida sem reticências (“Selecione o estado”).

Prevenção

  • Prefira prevenir: máscaras para dados formatados; restrinja o que não faz sentido (datas retroativas em agendamento futuro; campo dependente desabilitado até a origem ser preenchida); valores padrão inteligentes; placeholder com formato quando a máscara não deixa claro (ABC-1234, 00.000-000); busca no Select em listas longas. Nunca bloqueie a digitação por regra de validação — o campo não “engole” o que a pessoa digita.

Quando validar

Momento Regra
Enquanto digita Não mostra erro (exceção: requisito que se cumpre em tempo real, como força de senha)
Ao sair do campo Valida e mostra o erro daquele campo
Ao enviar Valida tudo; (proposta) foco no primeiro campo com erro e resumo se houver mais de um
Depois de corrigir O erro some assim que o valor fica válido
  • Mensagem = o que está errado + como corrigir, no próprio campo, abaixo dele, em vermelho, sem culpa. Nunca “inválido” sozinho: “Informe a placa do veículo.”, “CPF inválido. Insira apenas números.”, “Mínimo de 8 caracteres.”, “Já existe um motorista com este CPF.”, “O peso máximo por carga é 32.000 kg.”.
  • Erro do servidor: de um campo → no campo, com foco nele; do envio como um todo (falha de conexão) → Alert no topo do formulário (“Falha ao salvar a carga CG-1042. Verifique a conexão e tente novamente.”). Nos dois casos mantenha os dados e devolva o botão ao estado normal para nova tentativa.

Ações do formulário

  • Um único botão primary com o verbo da tarefa (Salvar, Emitir Nota, Agendar Doca); Cancelar ao lado em estilo secundário, nunca mais chamativo que o de salvar. Botões fixos no rodapé do Drawer/Modal. Enquanto envia: botão em carregamento (“Salvando…”) e inerte (sem envio duplo).
  • Não desabilite o enviar só porque o formulário está inválido sem explicar (proposta: deixe clicar e mostre os erros). (proposta) Com alterações não salvas, confirme antes de sair: Descartar alterações? → Continuar Editando · Descartar.
Situação Onde colocar Por quê
Cadastro/edição completa Drawer (.mds-float-panel--drawer) Mantém tabela/mapa visível ao fundo, preservando o contexto
Poucos campos e uma decisão Modal (.mds-float-panel--modal) Foco total; a pessoa volta logo
Item que falta em um Select MicroForm Cadastra sem sair do fluxo
Configuração de recurso ConfigToggle na própria tela Campos só aparecem quando o recurso é ligado

Estados de campo

Estado Como se apresenta
Padrão Borda neutra, fundo surface; placeholder só exemplifica formato, sem reticências
Foco Borda realçada em primary; rótulo ganha destaque
Obrigatório Realce amarelo + asterisco + aria-required (.mds-input--required)
Preenchido Borda de maior peso visual (.mds-input--active) — confirma que o dado foi assimilado
Desabilitado Opacidade reduzida, cursor de bloqueio; rótulo legível; (proposta) explique o motivo em tooltip/apoio
Somente leitura Fundo e texto esmaecidos, valor visível
Erro Borda e mensagem em vermelho (.mds-input--danger), mensagem específica

Acessibilidade

  • Rótulo associado ao campo (clicar no texto foca; em Radio/Checkbox, marca). Erro nunca só por cor (texto + ícone/borda). Ordem de tabulação = ordem visual. Alvo de toque confortável para luva/tablet. (proposta) mensagem de erro ligada ao campo com aria-describedby.

9.7 Navegação e hierarquia

Regra de ouro: cada tipo de navegação tem um lugar e um componente; não misture (páginas de módulos diferentes no mesmo submenu, ação no lugar de destino, produto dentro do menu do módulo). A pessoa sempre sabe onde está, o que pode fazer e como chegar a outro lugar.

Hierarquia, do mais amplo ao detalhe: Produto (AppLauncher) → Contexto/unidade (.mds-menu-business) → Módulo (menu nível 1) → Página (menu nível 2) → Aba → Seção (SectionHeader).

Preciso… Use
Trocar de produto (TMS, Roteirizador, Torre de Controle) AppLauncher na topbar (produtos não licenciados separados)
Trocar de unidade/empresa Alternador de contexto .mds-menu-business (muda dados, permissões, módulos)
Outro módulo Menu lateral, nível 1 (.mds-menu + .mds-menu-item)
Outra página do módulo Menu lateral, nível 2 (.mds-menu__group, item --sm)
Outro conteúdo da mesma página Tabs (.mds-nav-tabs); subpágina tem rota própria
2–3 visões exclusivas simples, sem rota .mds-control-group
Subir um nível Breadcrumb (.mds-breadcrumbs)
Executar algo Botão ou Dropdown — ação não é destino
Dividir a página em blocos SectionHeader (só Angular, header[mdsSectionHeader])
Escolher período DateNavigator (disponibilidade) ou DatePicker (dado)
  • Máximo de dois níveis no menu (módulo › página) e no Dropdown (menu › submenu). Se sente falta de um terceiro, o problema é a estrutura da informação: reagrupe, use Tabs ou outro módulo. Nunca aninhe mais.
  • Menu lateral: nível 1 = módulo, com ícone e maior peso; nível 2 = só páginas daquele módulo, menores e recuados. Rótulos em caixa de título, curtos (“Dashboard”, não “Ver o Dashboard de indicadores”). Item ativo sempre destacado (fundo claro de primary, .mds-menu-item--active); módulo com página ativa abre sozinho. Navegação utilitária (Automação, Preferências, Integrações, Cadastros gerais) ancorada na base, separada dos módulos operacionais.
  • Três modos do menu: expandido (256 px, ícone + rótulo), compacto (64 px, só ícones com Tooltip em cada um), flutuante (mobile/telas reduzidas, sobrepõe o conteúdo, .mds-menu--floating).
  • Topbar (.mds-top-bar, 64 px, fixa e visível em todas as telas): marca + nome do produto ativo à esquerda; pesquisa global (cargas, veículos, motoristas); utilitários (notificações, ajuda, seletor de produtos, perfil) — (proposta) em ordem fixa, do mais ao menos frequente. Botão só-ícone sempre com Tooltip. Um único lugar para trocar a unidade (o perfil pode mostrá-la, não trocá-la).
  • Breadcrumb só em páginas com 3+ níveis (em estrutura plana, não use). Último item = página atual, sem link; anteriores são links; nomes curtos; a partir de 4 itens colapsa o meio em “…” (caractere único).
  • PageHeader (.mds-page-title + .mds-page-options): um título por página, caixa de título, igual ao item de menu; ação principal (primary, verbo) junto ao título — um único destaque por tela; utilitários à direita (atualizar ↻, filtros/configurações, Mais opções ⋮) só ícone com Tooltip; busca rápida com placeholder “Pesquisar por código” (Pesquisar, nunca “Buscar”).
  • Tabs: só conteúdos do mesmo nível (nunca trocar módulo/produto); rótulos substantivos em caixa de título, sem ponto; a mais importante à esquerda; exatamente uma ativa; ícone em todas ou em nenhuma; modo compacto só-ícone exige Tooltip (aba sem ícone precisa manter o rótulo).
  • SectionHeader: título em caixa de título, descrição opcional em sentença; tamanho reflete a profundidade (seção mestra > subseção); se uma seção tem descrição, todas têm. Dropdown: item pai curto e categórico, seta para submenu sem reticências; frequentes no topo, destrutivas no fim separadas por divisor em danger; item que abre confirmação/janela leva reticências.
  • Localização e estado: item de menu ativo, aba ativa e último item do breadcrumb dizem a mesma coisa. (proposta) URL é o estado (módulo/página/aba na URL; link compartilhável; voltar do navegador funciona). Item sem permissão não aparece (ou aparece desabilitado com o motivo). Ao carregar a próxima página, menu e cabeçalho ficam no lugar; só a área de conteúdo carrega.
  • Nome de destino é substantivo, nome de ação é verbo (“Agendamentos” leva a uma lista; “Novo Agendamento” faz algo) — não misture no mesmo menu. Título da página = item de menu = (versão curta no) breadcrumb.

Hierarquia visual na página

  • Uma ação principal por tela, junto ao título; as demais secundárias ou em Mais opções. Ordem de leitura = importância (mais crítico primeiro, à esquerda e no topo). Um título, muitos subtítulos — não pule níveis. Peso visual proporcional à importância (módulo > página; seção mestra > subseção).
  • Ícones ajudam, não substituem texto na navegação principal; ícone sozinho só em modo compacto, sempre com Tooltip.

9.8 Checklist de revisão (auto-verificação antes de entregar)

  • Sei dizer o problema real que a tela resolve, sua ação principal em uma frase e há no máximo um botão primary?
  • Os cinco estados (carregando, vazio, erro, sucesso, com dados) estão contemplados? O carregamento diz o quê; o vazio tem título + descrição + ação?
  • Escolhi o componente de feedback pela árvore de decisão (campo → Modal → Alert → Toast → Tooltip → EmptyState)? Erro que exige ação não depende só de Toast? Nada depende só de cor?
  • Ação destrutiva: atrito proporcional, confirmação com título-pergunta + botão que repete a ação (Danger) + Cancelar, nunca “Sim/OK”?
  • Formulário: uma coluna, rótulo visível acima, máscara/tipo certo, validação ao sair do campo, mensagem “o que + como corrigir”, dados preservados em erro, envio com botão inerte em carregamento?
  • Navegação: no máximo dois níveis, título = item de menu, item ativo/aba/breadcrumb concordam, botão só-ícone com Tooltip, substantivo para destino e verbo para ação?
  • Usei só componentes, tokens e classes existentes (nada de .mds-toast/.mds-skeleton/estilo local “quase igual”)? Se abri exceção, sei justificar?

Este arquivo é regenerado por npm run design:build (ver package.json). O gerador falha (em vez de gerar algo errado) se um valor que ele espera encontrar no SCSS mudou de lugar — rode npm run design:build de novo para ver a mensagem de erro com o arquivo/linha exatos.