Pular para o conteúdo

mds-style

Os temas do MDS fazem parte do pacote @mobiis/mds-style, o CSS do Mobiis Design System. Um único arquivo traz os três temas (claro, escuro e escuro navy) e as variações de cor primária. Todos usam os mesmos tokens (--mds-colors-*, --mds-dimmed-*, --mds-buttons-*…) e só trocam os valores. Uma interface que referencia os tokens funciona nos três temas sem nenhuma mudança.

Janela do terminal
npm i @mobiis/mds-style

Importe o CSS uma vez, no estilo global da aplicação:

@import "@mobiis/mds-style/css/mds-styles.css";

Não há outro arquivo para importar por tema.

Tema Como ativar Arquivo-fonte
Claro (padrão) sem atributo src/scss/themes/_light.scss
Escuro <html data-theme="dark"> src/scss/themes/_dark.scss
Escuro navy <html data-theme="dark-blue"> src/scss/themes/_dark-blue.scss

O tema é definido no elemento raiz (<html>). Os três aceitam as variações de cor primária pelo atributo data-primary no mesmo elemento:

<html data-primary="blue"> <!-- claro com primary azul -->
<html data-theme="dark" data-primary="blue"> <!-- escuro com primary azul -->
<html data-theme="dark-blue" data-primary="red"> <!-- escuro navy com primary vermelho -->

Os tokens semânticos de cor seguem os três grupos da coleção “1. Colors” do Figma. O nome no CSS é o do Figma, sem o prefixo bg- (Background/bg-main vira --mds-colors-background-main).

Grupo Tokens Para quê
Background --mds-colors-background-{light, main, dark}
-{primary, secondary, error, warning, info, success}
-{aqua, blue, green, orange, pink, red, teal, yellow}
-transparency, -shadow
Fundos: página, blocos, fundo suave de cada cor, overlay e base das sombras
Foreground --mds-colors-foreground-{light, main, dark}
-{primary, secondary, error, warning, info, success}
-{aqua, blue, green, orange, pink, red, teal, yellow}
Texto e ícone: de apoio, de corpo, de ênfase e texto na cor do papel
Border --mds-colors-border-{light, main, dark}
-{primary, secondary, error, warning, info, success}
-{aqua, blue, green, orange, pink, red, teal, yellow}
Bordas e divisórias: main é a borda padrão de card, tabela e divisor

Os tons vêm das paletas, como no Figma:

Grupo Claro Escuro
Background de cor lighter lighter
Foreground de cor dark (darker em info, aqua e teal) darker
Border de cor main dark
Neutros light · main · dark Background 50 · 100 · 200, Foreground 500 · 600 · 700, Border 100 · 200 · 500 iguais, menos border-dark = 400

As cores de link (--mds-colors-ui-interactive-*) não têm equivalente no Figma e continuam no grupo ui.

O tema padrão: vale sempre que o <html> não tem data-theme.

Fundos, bordas e textos. No tema claro, --mds-dimmed-N é a escala de cinza (--mds-colors-gray-*), e o card é o quase-branco gray-0.

PapelTokenCor
Página (background-light)--mds-dimmed-0#fafbfc
Bloco rebaixado, menu (background-main)--mds-dimmed-1#f3f4f6
Card / superfície--mds-dimmed-default#fefefe
Hover, borda (background-dark, border-main)--mds-dimmed-2#e8eaee
Cabeçalho de tabela, fundo desabilitado--mds-dimmed-3#dcdfe5
Borda de campo--mds-dimmed-4#d0d4dc
Texto de apoio (foreground-light)--mds-dimmed-5#9c9fa5
Texto de corpo (foreground-main)--mds-dimmed-6#686a6e
Texto de ênfase (foreground-dark)--mds-dimmed-7#343537

A página (background-light) e o card são quase brancos. Blocos internos e menu (background-main) ficam um pouco mais escuros, rebaixados. Hover e bordas usam o background-dark.

Cada paleta nasce de uma semente (o passo 400) e expõe cinco tons, lighter, light, main, dark e darker, vindos dos passos 50, 200, 400, 500 e 600. Cada tom tem o seu par de texto on-*, escolhido pelo contraste APCA.

brand (Secondary)lighter#e9ebf3light#939ac5main#27348bdark#1d2768darker#141a46
brand-mobiis (Primary)lighter#ecf3fflight#a0c4fdmain#408afadark#3068bbdarker#20457d
blue (Info)lighter#e6f3fblight#80c3edmain#0087dbdark#0065a4darker#00446e
teallighter#e6fbfblight#80ededmain#00dbdbdark#00a4a4darker#006e6e
aqualighter#e6fef8light#80f8dcmain#00f0b8dark#00b48adarker#00785c
green (Success)lighter#e6f9e6light#80e381main#00c703dark#009502darker#006402
yellow (Warning)lighter#fef9e6light#f8e280main#f0c400dark#b49300darker#786200
orangelighter#fef2e6light#f8bc80main#f07800dark#b45a00darker#783c00
red (Danger)lighter#fcebe6light#f29980main#e53200dark#ac2600darker#731900
pinklighter#ffe6f1light#ff80b9main#ff0073dark#bf0056darker#80003a
gray (Neutral)lighter#fafbfclight#e8eaeemain#d0d4dcdark#9c9fa5darker#686a6e

Os papéis semânticos apontam para essas paletas: primary = brand-mobiis, secondary = brand, info = blue, success = green, warning = yellow, danger = red e neutral = gray. A fórmula e o pipeline estão em Geração de Cores.

O MDS tem duas variações escuras. As duas seguem as mesmas regras de contraste e de comportamento dos componentes. A diferença está só nos neutros (fundo, borda e texto).

dark dark-blue
Visual azul dessaturado, discreto navy saturado
Origem dos neutros calculados a partir da matiz da cor primária (OKLCH) cores do tema Mobiis Dark Blue do VS Code
Quando usar padrão para os produtos quando o produto quer a identidade navy da Mobiis
PapelTokenCor
Página (background-light)--mds-dimmed-0#08101c
Bloco rebaixado, menu (background-main)--mds-dimmed-1#0b1421
Card / superfície--mds-dimmed-default#121c2b
Hover, borda (background-dark, border-main)--mds-dimmed-2#222d3e
Cabeçalho de tabela, fundo desabilitado--mds-dimmed-3#2c3749
Borda de campo--mds-dimmed-4#606d80
Texto de apoio (foreground-light)--mds-dimmed-5#a2adbf
Texto de corpo (foreground-main)--mds-dimmed-6#d1d8e2
Texto de ênfase (foreground-dark)--mds-dimmed-7#eff2f7
PapelTokenCor
Página (background-light)--mds-dimmed-0#000814
Bloco rebaixado, menu (background-main)--mds-dimmed-1#000c1d
Card / superfície--mds-dimmed-default#001027
Hover, borda (background-dark, border-main)--mds-dimmed-2#0b2245
Cabeçalho de tabela, fundo desabilitado--mds-dimmed-3#0e2a54
Borda de campo--mds-dimmed-4#5a6f90
Texto de apoio (foreground-light)--mds-dimmed-5#8aa0bd
Texto de corpo (foreground-main)--mds-dimmed-6#c3ccd9
Texto de ênfase (foreground-dark)--mds-dimmed-7#e4eaf3

Elevação pela luminosidade. No escuro, a sombra quase não aparece, então o que está acima é mais claro: página < bloco rebaixado (menu, áreas internas) < card < hover e borda. Não coloque um card mais escuro que o fundo da página.

Superfícies dessaturadas. Cores muito saturadas em áreas grandes cansam e fazem o texto “vibrar”. O dark usa um azul de croma baixa; o dark-blue mantém o navy do VS Code, que é a identidade dele.

Sem branco puro. O texto de ênfase é --mds-colors-foreground-dark (quase branco, levemente azulado), não #fff.

Mesmo peso de leitura do tema claro. Os pares principais têm o mesmo contraste (APCA) nos três temas. O piso de conforto do MDS é Lc 45 para texto de 16 px.

Par Claro dark dark-blue
Texto de corpo sobre o card Lc 76 Lc 81 Lc 75
Texto de ênfase sobre o card Lc 97 Lc 97 Lc 93
Texto de apoio sobre o card Lc 51 Lc 56 Lc 49
Borda de campo sobre o card Lc 22 Lc 24 Lc 26

As paletas usam os passos do modo Mobiis-dark do Figma: lighter = 700, light = 600, main = 500, dark = 300, darker = 200. No escuro a escala se inverte: lighter é o tom mais profundo e darker o mais claro.

Paletas escuras (como vermelho, rosa e azul) não teriam contraste suficiente com esses passos. Por isso o build ajusta cada paleta contra o card da variação:

  • main clareia até o botão se destacar do card (WCAG ≥ 3) e o texto do botão ter Lc ≥ 60.
  • dark clareia até ter Lc ≥ 50 sobre o card. É o tom de link, de texto de item ativo e do anel de foco.
  • darker fica sempre um passo mais claro que o dark.

A regra fica em DARK_CONTRAST (scripts/tokens/palettes.config.js) e vale para os papéis semânticos (danger, info, warning…) e para as variações de primary. A Secondary (navy institucional) é exceção e mantém os passos de marca do Figma.

brand (Secondary)lighter#0a0d23light#141a46main#27348bdark#939ac5darker#c9cce2
brand-mobiis (Primary)lighter#10223flight#20457dmain#3068bbdark#70a7fbdarker#a0c4fd
blue (Info)lighter#002237light#00446emain#0087dbdark#80c3eddarker#bfe1f6
teallighter#003737light#006e6emain#00a4a4dark#40e4e4darker#80eded
aqualighter#003c2elight#00785cmain#00f0b8dark#40f4cadarker#80f8dc
green (Success)lighter#003201light#006402main#009502dark#40d542darker#80e381
yellow (Warning)lighter#3c3100light#786200main#f0c400dark#f4d340darker#f8e280
orangelighter#3c1e00light#783c00main#b45a00dark#f49a40darker#f8bc80
red (Danger)lighter#390c00light#731900main#e53200dark#f29980darker#f9ccbf
pinklighter#40001dlight#80003amain#ff0073dark#ff80b9darker#ffbfdc
gray (Neutral)lighter#08101clight#222d3emain#606d80dark#a2adbfdarker#d1d8e2
brand (Secondary)lighter#0a0d23light#141a46main#27348bdark#939ac5darker#c9cce2
brand-mobiis (Primary)lighter#10223flight#20457dmain#3068bbdark#70a7fbdarker#a0c4fd
blue (Info)lighter#002237light#00446emain#0065a4dark#80c3eddarker#bfe1f6
teallighter#003737light#006e6emain#00a4a4dark#40e4e4darker#80eded
aqualighter#003c2elight#00785cmain#00f0b8dark#40f4cadarker#80f8dc
green (Success)lighter#003201light#006402main#009502dark#40d542darker#80e381
yellow (Warning)lighter#3c3100light#786200main#f0c400dark#f4d340darker#f8e280
orangelighter#3c1e00light#783c00main#b45a00dark#f49a40darker#f8bc80
red (Danger)lighter#390c00light#731900main#e53200dark#f29980darker#f9ccbf
pinklighter#40001dlight#80003amain#bf0056dark#ff80b9darker#ffbfdc
gray (Neutral)lighter#000814light#0b2245main#5a6f90dark#8aa0bddarker#c3ccd9

Algumas regras mudam de sentido no escuro porque dark/darker passam a ser os tons mais claros. Elas ficam num bloco compartilhado pelas duas variações, em _dark.scss:

Elemento Claro Escuro
Texto em cor de papel (foreground-primary, -error…) tom dark tom darker
Borda e ícone de papel (border-error, border-info…) tom main tom dark
Hover e pressionado de botão escurecem (dark → darker) escurecem (light → lighter)
Degrau inferior do botão e sombra do selecionado tom mais escuro que o botão neutro mais profundo (dimmed-0)
Outline: texto e borda main dark
Outline: fundo background-light transparente
Anel de foco tom light tom dark
Borda de campo em hover/foco primary-main primary-dark
Sombra e overlay cinza translúcido preto translúcido

O modo Mobiis-dark do Figma tem as paletas coerentes, mas a camada semântica está incompleta: o texto (Foreground/*) ficou escuro sobre fundo escuro, as bordas ficaram quase pretas e a superfície ficou mais escura que a página. Onde o Figma não serve, o MDS decide por legibilidade. A lista completa e atualizada fica na seção “Tema escuro” do DESIGN.md.

data-primary troca a paleta do papel primary (--mds-colors-primary-*) e as cores de link (--mds-colors-ui-interactive-*). Valores: brand-mobiis (padrão), blue, teal, aqua, green, yellow, orange, red e pink.

Cada variação tem um bloco no tema claro e outro em cada tema escuro, no mesmo modelo, gerados por npm run tokens a partir de scripts/tokens/palettes.config.js. No escuro, todas as variações garantem:

  • o botão primary se destaca do card (WCAG ≥ 3);
  • o texto do botão tem Lc ≥ 60;
  • o link tem Lc ≥ 50.

A única diferença entre os modelos é o link desabilitado (--mds-colors-ui-interactive-disabled-text). No claro ele usa o tom light da paleta. No escuro esse tom é profundo e some, então ele passa a ser o tom do link misturado a 50% com o card.

As cores são geradas. Não edite à mão as regiões marcadas com @mds-tokens:generated nos arquivos de tema.

  1. Sementes das paletas: tokens/seeds/color.seeds.tokens.json.
  2. Passos, papéis e escuro: scripts/tokens/palettes.config.js (STEP_MAP, PALETTES, DARK_STEP_MAPS, DARK_CONTRAST, DARK_DIMMED, DARK_BLUE_DIMMED, DARK_VARIANTS).
  3. Tokens de componente e regras do escuro: escritos à mão. Os do claro (botões, controles, itens de menu) ficam em _light.scss, fora das regiões geradas. As regras do escuro (texto de papel, botões, foco…) ficam no bloco compartilhado no fim de _dark.scss.
  4. Rode npm run tokens. Ele atualiza os arquivos de tema e os JSON em tokens/generated/ (color.tokens.json, color.dark.tokens.json e color.dark-blue.tokens.json). O npm run tokens:verify falha se algo ficou desatualizado.