Skip to content
01 Cores

Tokens de Cor

Design System · Arrow DS · Dimensão 01 Cor

Versão: 1.0 · Status: Validado
Âncora base: #081128 (primitive.midnight.900)
Depende de:
Usado por: Dimensão 02 Tipografia, todos os componentes de UI

Princípios da Dimensão

Cor comunica intenção antes de comunicar estética.
Em um produto denso como a Effecti prazos, valores, status de processo a cor não decora. Ela informa: este campo tem erro, esta ação é destrutiva, este prazo está crítico. Antes de qualquer palavra, a cor já tomou uma decisão semântica.

Escalas LCH perceptual calibradas, não arbitrárias.
As 9 famílias de cor foram construídas com progressão uniforme em LCH (Lightness–Chroma–Hue), não em espaço sRGB. O resultado é uma escala onde cada stop parece visualmente equidistante sem os saltos bruscos ou aglomerações que surgem em escalas HSL. As âncoras vêm do BrandBook; os demais stops são derivados matematicamente.

Dois níveis obrigatórios primitivos para construir, semânticos para usar.
Nenhum valor hexadecimal ou primitivo entra diretamente no código de produto. Todo componente referencia um token semântico nomeado por intenção (color.action.primary, color.feedback.error). Primitivos existem para construir os semânticos e para nada mais.

Fundação Famílias Cromáticas

O sistema é composto por 9 famílias cromáticas, cada uma com 11 stops (0 a 900). As âncoras de cada família são os valores do BrandBook; os demais stops são escalas LCH derivadas.

FamíliaÂncoraStop âncoraPapel no sistema
Midnight Neutral#081128900Neutro base superfícies, conteúdo, bordas
Blizzard Blue#A7EAFB200CTA principal, ação, acento de marca
Gulf Blue#121D59800Institucional, informação, marca profunda
Merino Beige#F1EDE1100Superfície quente, fundo editorial
Bloom Red#D2082D500Erro, destruição, prazo crítico
Orange Sunset#E56307500Premium, destaque comercial
Mint Green#349E06500Sucesso, confirmação, habilitado
Petal Pink#C40795500Badge, notificação, elemento de destaque
Butter Yellow#ECCE24400 / 500Aviso, atenção, alerta não crítico

Regra

As famílias Gulf, Merino, Pink e Yellow têm uso restrito — Gulf e Merino são institucionais, Pink e Yellow são reservados para feedback específico. O Midnight e o Blizzard são as famílias de trabalho do sistema.

Primitivos

Primitivos são os valores brutos das escalas o vocabulário cromático do sistema. Eles existem para serem mapeados nos tokens semânticos, nunca para aparecer diretamente em componentes.

Midnight Neutral

TokenHexUso semântico
primitive.midnight.0Branco absoluto, superfície base light
primitive.midnight.50Superfície sutil, fundo de input
primitive.midnight.100Superfície elevada, hover neutro
primitive.midnight.200Borda padrão, overlay
primitive.midnight.300Borda forte, conteúdo desabilitado
primitive.midnight.400
primitive.midnight.500Conteúdo terciário
primitive.midnight.600Conteúdo secundário
primitive.midnight.700
primitive.midnight.800
primitive.midnight.900Conteúdo primário, superfície invertida

Blizzard Blue

TokenHexUso semântico
primitive.blizzard.50
primitive.blizzard.100Superfície de ação, hover de ação
primitive.blizzard.200Ação sutil, focus ring, brand
primitive.blizzard.300
primitive.blizzard.400CTA em dark mode
primitive.blizzard.500CTA light mode, borda de acento, conteúdo acento
primitive.blizzard.600Hover de ação
primitive.blizzard.700Pressed de ação
primitive.blizzard.800Ação sutil em dark
primitive.blizzard.900Superfície de ação em dark

Gulf Blue

TokenHexUso semântico
primitive.gulf.50
primitive.gulf.100
primitive.gulf.200
primitive.gulf.300
primitive.gulf.400
primitive.gulf.500
primitive.gulf.600
primitive.gulf.700
primitive.gulf.800Brand institucional
primitive.gulf.900

Merino Beige

TokenHexUso semântico
primitive.merino.50Superfície quente (surface.warm)
primitive.merino.100Brand editorial
primitive.merino.200
primitive.merino.300
primitive.merino.400
primitive.merino.500
primitive.merino.600
primitive.merino.700
primitive.merino.800
primitive.merino.900

Bloom Red

TokenHexUso semântico
primitive.red.50Hover de erro
primitive.red.100Superfície de erro
primitive.red.200
primitive.red.300
primitive.red.400Erro em dark mode
primitive.red.500Erro, borda de erro
primitive.red.600Hover de erro
primitive.red.700Conteúdo de erro, texto sobre superfície de erro
primitive.red.800
primitive.red.900Superfície de erro em dark

Orange Sunset

TokenHexUso semântico
primitive.orange.50
primitive.orange.100Superfície premium
primitive.orange.200
primitive.orange.300
primitive.orange.400Premium em dark
primitive.orange.500Premium
primitive.orange.600Hover premium
primitive.orange.700Conteúdo premium
primitive.orange.800
primitive.orange.900Superfície premium em dark

Mint Green

TokenHexUso semântico
primitive.green.50
primitive.green.100Superfície de sucesso
primitive.green.200
primitive.green.300
primitive.green.400Sucesso em dark
primitive.green.500Sucesso
primitive.green.600Hover sucesso
primitive.green.700Conteúdo sucesso
primitive.green.800
primitive.green.900Superfície sucesso em dark

Petal Pink

TokenHexUso semântico
primitive.pink.50
primitive.pink.100Superfície de badge
primitive.pink.200Focus ring de erro
primitive.pink.300
primitive.pink.400Badge em dark
primitive.pink.500Badge
primitive.pink.600Hover badge
primitive.pink.700Conteúdo badge
primitive.pink.800
primitive.pink.900Superfície badge em dark

Butter Yellow

TokenHexUso semântico
primitive.yellow.50
primitive.yellow.100Superfície de aviso
primitive.yellow.200
primitive.yellow.300
primitive.yellow.400Aviso em dark
primitive.yellow.500Aviso ⚠ não passa AA sozinho
primitive.yellow.600Hover aviso
primitive.yellow.700Conteúdo aviso
primitive.yellow.800
primitive.yellow.900Superfície aviso em dark
css
:root {
  /* Midnight Neutral */
  --primitive-midnight-0:   #FFFFFF;
  --primitive-midnight-50:  #F8F8F9;
  --primitive-midnight-100: #EDEEF0;
  --primitive-midnight-200: #DCDCE1;
  --primitive-midnight-300: #BFC0C8;
  --primitive-midnight-400: #9B9DA9;
  --primitive-midnight-500: #737686;
  --primitive-midnight-600: #505468;
  --primitive-midnight-700: #33384E;
  --primitive-midnight-800: #1B2339;
  --primitive-midnight-900: #081128;

  /* Blizzard Blue */
  --primitive-blizzard-50:  #EAF9FD;
  --primitive-blizzard-100: #D1F4FD;
  --primitive-blizzard-200: #A7EAFB;
  --primitive-blizzard-300: #4FD1EC;
  --primitive-blizzard-400: #00B2D7;
  --primitive-blizzard-500: #0092BE;
  --primitive-blizzard-600: #007198;
  --primitive-blizzard-700: #005677;
  --primitive-blizzard-800: #003C55;
  --primitive-blizzard-900: #002738;

  /* Gulf Blue */
  --primitive-gulf-50:  #F7F6FB;
  --primitive-gulf-100: #E9E7F2;
  --primitive-gulf-200: #D5D2E7;
  --primitive-gulf-300: #B7B2D4;
  --primitive-gulf-400: #918BB9;
  --primitive-gulf-500: #6B679E;
  --primitive-gulf-600: #494783;
  --primitive-gulf-700: #2B2E6B;
  --primitive-gulf-800: #121D59;
  --primitive-gulf-900: #051244;

  /* Merino Beige */
  --primitive-merino-50:  #FEFCF7;
  --primitive-merino-100: #F1EDE1;
  --primitive-merino-200: #DCD4BA;
  --primitive-merino-300: #C0B691;
  --primitive-merino-400: #A4996C;
  --primitive-merino-500: #877C4C;
  --primitive-merino-600: #6A6135;
  --primitive-merino-700: #4E4721;
  --primitive-merino-800: #363112;
  --primitive-merino-900: #242007;

  /* Bloom Red */
  --primitive-red-50:  #FFF3F1;
  --primitive-red-100: #FFE2DE;
  --primitive-red-200: #FFC6BF;
  --primitive-red-300: #FF9D94;
  --primitive-red-400: #FB6965;
  --primitive-red-500: #D2082D;
  --primitive-red-600: #AC001B;
  --primitive-red-700: #87000F;
  --primitive-red-800: #640003;
  --primitive-red-900: #430000;

  /* Orange Sunset */
  --primitive-orange-50:  #FFF4EC;
  --primitive-orange-100: #FFE5D5;
  --primitive-orange-200: #FFCBAE;
  --primitive-orange-300: #FCA779;
  --primitive-orange-400: #ED8143;
  --primitive-orange-500: #E56307;
  --primitive-orange-600: #BB4900;
  --primitive-orange-700: #923400;
  --primitive-orange-800: #692200;
  --primitive-orange-900: #441500;

  /* Mint Green */
  --primitive-green-50:  #F2F9ED;
  --primitive-green-100: #E0F0D7;
  --primitive-green-200: #C2E0B1;
  --primitive-green-300: #97C97E;
  --primitive-green-400: #66AF47;
  --primitive-green-500: #349E06;
  --primitive-green-600: #137C00;
  --primitive-green-700: #005E00;
  --primitive-green-800: #004200;
  --primitive-green-900: #092800;

  /* Petal Pink */
  --primitive-pink-50:  #FFF3FA;
  --primitive-pink-100: #FFE3F4;
  --primitive-pink-200: #FBC9E6;
  --primitive-pink-300: #F5A1D5;
  --primitive-pink-400: #EA6ABE;
  --primitive-pink-500: #C40795;
  --primitive-pink-600: #A10078;
  --primitive-pink-700: #7E005C;
  --primitive-pink-800: #5D0043;
  --primitive-pink-900: #3D002C;

  /* Butter Yellow */
  --primitive-yellow-50:  #FDF9EF;
  --primitive-yellow-100: #F9F0D8;
  --primitive-yellow-200: #F6E4AF;
  --primitive-yellow-300: #F2D97C;
  --primitive-yellow-400: #ECCE24;
  --primitive-yellow-500: #B09707;
  --primitive-yellow-600: #8C7900;
  --primitive-yellow-700: #6F6000;
  --primitive-yellow-800: #544800;
  --primitive-yellow-900: #3F3607;
}

Regra

Primitivos nunca entram no código de produto diretamente. Todo componente referencia apenas tokens semânticos. Usar #0092BE em vez de color.action.primary é proibido.

Tokens Semânticos

Estrutura de cada token

Tokens de cor seguem o padrão de intenção sobre valor:

color.{categoria}.{papel}
└── color (valor hexadecimal via alias do primitivo)

Exemplo:
color.action.primary      → var(--primitive-blizzard-500)
color.feedback.error      → var(--primitive-red-500)
color.surface.base        → var(--primitive-midnight-0)

Categoria: Surface

Papel: Camadas de fundo e estrutura visual. Define a hierarquia de profundidade da interface do mais claro (base) ao mais denso (overlay e inverted).

TokenLight ModeDark ModeUso
`color.surface.base``midnight.0` (#FFF)`midnight.900`Fundo de página, base de modal
`color.surface.subtle``midnight.50``midnight.800`Input, área de conteúdo secundário
`color.surface.raised``midnight.100``midnight.700`Card elevado, hover neutro
`color.surface.overlay``midnight.200``midnight.600`Overlay leve, divisor visual
`color.surface.inverted``midnight.900``midnight.0`Tooltip dark, banner invertido
`color.surface.warm``merino.50``midnight.800`Fundo editorial, seção institucional
css
--color-surface-base:     var(--primitive-midnight-0);
--color-surface-subtle:   var(--primitive-midnight-50);
--color-surface-raised:   var(--primitive-midnight-100);
--color-surface-overlay:  var(--primitive-midnight-200);
--color-surface-inverted: var(--primitive-midnight-900);
--color-surface-warm:     var(--primitive-merino-50);

Boas práticas Surface

  • surface.base é o padrão absoluto de fundo ponto de partida de qualquer tela
  • surface.subtle para inputs, áreas de preenchimento, fundos de seção secundária
  • surface.raised para cards, dropdowns, qualquer elemento que precise de elevação visual
  • surface.inverted é exclusivo para componentes que flutuam sobre o fundo claro (tooltip, snackbar dark)
  • surface.warm é reservado para páginas editoriais, onboarding, institucional nunca em UI operacional densa
  • Nunca empilhar mais de 3 níveis de surface em sequência direta a hierarquia perde contraste

Combinações recomendadas

color.surface.base     →  fundo de toda tela de produto
color.surface.subtle   →  fundo de input, área de tabela zerada
color.surface.raised   →  card de pregão, dropdown de filtro
color.surface.warm     →  página de onboarding, empty state editorial
color.surface.inverted →  tooltip, snackbar de confirmação

Categoria: Content

Papel: Cor de texto e ícones. Hierarquiza a informação do texto principal ao desabilitado sem depender de tamanho ou peso.

TokenLight ModeDark ModeUso
`color.content.primary``midnight.900``midnight.50`Títulos, dados em destaque, texto principal
`color.content.secondary``midnight.600``midnight.200`Texto corrido, descrições, parágrafos
`color.content.tertiary``midnight.500``midnight.300`Labels, metadados, texto de suporte
`color.content.disabled``midnight.300``midnight.600`Texto desabilitado (não passa AA intencional)
`color.content.inverted``midnight.0``midnight.900`Texto sobre superfície invertida
`color.content.accent``blizzard.500``blizzard.400`Link, ação textual, acento de destaque
css
--color-content-primary:   var(--primitive-midnight-900);
--color-content-secondary: var(--primitive-midnight-600);
--color-content-tertiary:  var(--primitive-midnight-500);
--color-content-disabled:  var(--primitive-midnight-300);
--color-content-inverted:  var(--primitive-midnight-0);
--color-content-accent:    var(--primitive-blizzard-500);

Boas práticas Content

  • content.primary para todo texto que carrega informação crítica números, títulos, dados de processo
  • content.secondary para texto corrido e descrições nunca usar primary em parágrafos longos
  • content.tertiary tem contraste de 4.1:1 em surface.base uso restrito a texto auxiliar e labels pequenos
  • content.disabled reprova intencionalmente no WCAG sinaliza que o elemento não está disponível
  • content.accent exclusivo para elementos clicáveis ou de ênfase editorial nunca usar em texto estático

Combinações recomendadas

content.primary   + type.heading.*  →  título de seção, número de pregão
content.secondary + type.body.*     →  descrição do objeto, texto de suporte
content.tertiary  + type.label.*    →  label de campo, metadado de card
content.accent    + type.body.md    →  link inline, ação textual
content.inverted  + surface.inverted →  texto em tooltip dark

Categoria: Border

Papel: Delimitação de elementos inputs, cards, divisores, highlight de seleção. Separa sem ocupar espaço visual excessivo.

TokenLight ModeDark ModeUso
`color.border.default``midnight.200``midnight.700`Input idle, card, divisor, tabela
`color.border.strong``midnight.300``midnight.600`Input hover, separador com mais peso
`color.border.accent``blizzard.500``blizzard.400`Input focus, elemento selecionado, destaque de ação
`color.border.error``red.500``red.400`Input com erro de validação
css
--color-border-default: var(--primitive-midnight-200);
--color-border-strong:  var(--primitive-midnight-300);
--color-border-accent:  var(--primitive-blizzard-500);
--color-border-error:   var(--primitive-red-500);

Boas práticas Border

  • border.default é o estado idle de todo input e card nunca usar valor bruto
  • border.accent exclusivo para estado de foco ou seleção nunca usar decorativamente
  • border.error sempre acompanha feedback.error e state.focus-ring-error no mesmo input
  • Nunca usar border.strong em estado de foco ele não tem contraste suficiente para sinalizar seleção

Combinações recomendadas

border.default + surface.base     →  input idle, card neutro
border.accent  + state.focus-ring →  input em foco
border.error   + feedback.error   →  campo de formulário com erro
border.strong  + content.tertiary →  divisor de seção com peso

Categoria: Action

Papel: CTA principal e seus estados interativos. O Blizzard Blue é a cor de ação do sistema botões primários, links de navegação, checkboxes ativos.

TokenLight ModeDark ModeUso
`color.action.primary``blizzard.500``blizzard.400`Botão primário (default), ícone ativo
`color.action.hover``blizzard.600``blizzard.300`Botão primário em hover
`color.action.pressed``blizzard.700``blizzard.500`Botão primário em pressed
`color.action.subtle``blizzard.200``blizzard.800`Ação secundária, chip de filtro ativo
`color.action.surface``blizzard.100``blizzard.900`Fundo de área de ação, banner CTA
`color.action.disabled``midnight.200``midnight.700`Botão desabilitado
css
--color-action-primary:  var(--primitive-blizzard-500);
--color-action-hover:    var(--primitive-blizzard-600);
--color-action-pressed:  var(--primitive-blizzard-700);
--color-action-subtle:   var(--primitive-blizzard-200);
--color-action-surface:  var(--primitive-blizzard-100);
--color-action-disabled: var(--primitive-midnight-200);

Boas práticas Action

  • A progressão primary → hover → pressed é obrigatória nunca criar estados intermediários fora da escala
  • action.subtle é para ações secundárias e filtros nunca para CTAs que precisam de destaque
  • action.disabled substitui action.primary em botões desabilitados junto com content.disabled no texto
  • Em dark mode, o CTA sobe um stop (blizzard.400) para manter o contraste WCAG de 4.5:1 sobre surface.base dark

Combinações recomendadas

action.primary   + content.inverted   →  botão primário (texto branco sobre azul)
action.hover     + content.inverted   →  botão primário em hover
action.subtle    + content.accent     →  botão ghost / outline com fill sutil
action.disabled  + content.disabled  →  botão desabilitado
action.surface   + border.accent     →  banner de chamada para ação

Categoria: Feedback Erro

Papel: Erros de validação, ações destrutivas, prazos críticos. A cor mais importante do sistema de feedback deve ser reservada estritamente para estados negativos.

TokenLight ModeDark ModeUso
`color.feedback.error``red.500``red.400`Ícone de erro, indicador de campo inválido
`color.feedback.error-hover``red.600`Estado hover em elemento destrutivo
`color.feedback.error-surface``red.100``red.900`Fundo de toast de erro, área de alerta
`color.feedback.error-border``red.500``red.400`Borda de input com erro
`color.feedback.error-content``red.700``red.200`Texto de mensagem de erro
css
--color-feedback-error:         var(--primitive-red-500);
--color-feedback-error-hover:   var(--primitive-red-600);
--color-feedback-error-surface: var(--primitive-red-100);
--color-feedback-error-border:  var(--primitive-red-500);
--color-feedback-error-content: var(--primitive-red-700);

Boas práticas Erro

  • feedback.error e feedback.error-border sempre aparecem juntos em inputs inválidos
  • feedback.error-content sobre feedback.error-surface garante contraste para a mensagem de erro abaixo do campo
  • Nunca usar vermelho para ênfase decorativa ou chamada de atenção não relacionada a erro isso deprecia o sinal
  • Em formulários, o trio border.error + feedback.error-surface + feedback.error-content é o padrão de validação

Categoria: Feedback Sucesso

Papel: Confirmação de ação, habilitação de fornecedor, processo concluído com sucesso.

TokenLight ModeDark ModeUso
`color.feedback.success``green.500``green.400`Ícone de sucesso, indicador de status positivo
`color.feedback.success-surface``green.100``green.900`Fundo de toast de sucesso
`color.feedback.success-border``green.500``green.400`Borda de elemento com status positivo
`color.feedback.success-content``green.700``green.200`Texto de mensagem de sucesso
css
--color-feedback-success:         var(--primitive-green-500);
--color-feedback-success-surface: var(--primitive-green-100);
--color-feedback-success-border:  var(--primitive-green-500);
--color-feedback-success-content: var(--primitive-green-700);

Boas práticas Sucesso

  • Reservado para confirmações reais proposta enviada, documento aprovado, fornecedor habilitado
  • Nunca usar verde para progresso parcial ou estados neutros isso confunde com confirmação total

Categoria: Feedback Aviso

Papel: Alertas de atenção, prazos próximos, informações que precisam de revisão. Diferente do erro a ação ainda é possível.

TokenLight ModeDark ModeUso
`color.feedback.warning``yellow.500``yellow.400`Ícone de aviso ⚠ sempre acompanhado de ícone
`color.feedback.warning-surface``yellow.100``yellow.900`Fundo de banner de aviso
`color.feedback.warning-border``yellow.500``yellow.400`Borda de elemento em atenção
`color.feedback.warning-content``yellow.700``yellow.200`Texto de mensagem de aviso
css
--color-feedback-warning:         var(--primitive-yellow-500);
--color-feedback-warning-surface: var(--primitive-yellow-100);
--color-feedback-warning-border:  var(--primitive-yellow-500);
--color-feedback-warning-content: var(--primitive-yellow-700);

Boas práticas Aviso

  • feedback.warning (yellow.500) tem ratio 3.8:1 sobre surface.base não passa AA em texto solo
  • Obrigatório sempre usar acompanhado de ícone de aviso para garantir acessibilidade
  • feedback.warning-content (yellow.700) passa AA e pode ser usado em texto sobre feedback.warning-surface
  • Nunca usar amarelo como cor de destaque positivo no contexto da Effecti, amarelo significa atenção

Categoria: Feedback Premium

Papel: Recursos, funcionalidades ou planos premium. Diferencia conteúdo exclusivo do fluxo padrão.

TokenLight ModeDark ModeUso
`color.feedback.premium``orange.500``orange.400`Ícone de premium, tag de recurso exclusivo
`color.feedback.premium-surface``orange.100``orange.900`Fundo de card premium, banner de upgrade
`color.feedback.premium-border``orange.500``orange.400`Borda de card premium
`color.feedback.premium-content``orange.700``orange.200`Texto de label premium
css
--color-feedback-premium:         var(--primitive-orange-500);
--color-feedback-premium-surface: var(--primitive-orange-100);
--color-feedback-premium-border:  var(--primitive-orange-500);
--color-feedback-premium-content: var(--primitive-orange-700);

Boas práticas Premium

  • feedback.premium (orange.500) tem ratio 3.2:1 não passa AA em texto solo, assim como warning
  • Usar sempre com ícone ou em contexto onde o rótulo "Premium" já está visível
  • Nunca usar laranja para alertas ou erros a família Orange Sunset é exclusiva do premium

Categoria: Feedback Badge

Papel: Notificações, contadores, badges de destaque. A cor mais vibrante do sistema uso muito restrito.

TokenLight ModeDark ModeUso
`color.feedback.badge``pink.500``pink.400`Ponto de notificação, contador de badge
`color.feedback.badge-surface``pink.100``pink.900`Fundo de badge de notificação
`color.feedback.badge-border``pink.500``pink.400`
`color.feedback.badge-content``pink.700``pink.200`Número dentro do badge
css
--color-feedback-badge:         var(--primitive-pink-500);
--color-feedback-badge-surface: var(--primitive-pink-100);
--color-feedback-badge-border:  var(--primitive-pink-500);
--color-feedback-badge-content: var(--primitive-pink-700);

Boas práticas Badge

  • Exclusivo para elementos de notificação contadores, pontos de alerta não lido
  • É a cor mais saturada do sistema usar com extrema parcimônia
  • Nunca substituir feedback.error por feedback.badge papéis distintos, não intercambiáveis

Categoria: States

Papel: Estados interativos transientes hover, pressed, focus, disabled. Não comunicam semântica de conteúdo, comunicam interatividade.

TokenLight ModeDark ModeUso
`color.state.hover-neutral``midnight.100``midnight.800`Hover em linha de tabela, item de menu, chip
`color.state.hover-accent``blizzard.100``blizzard.900`Hover em item de ação secundária
`color.state.hover-error``red.50`Hover em elemento com estado de erro
`color.state.pressed-accent``blizzard.700`Pressed em botão de ação
`color.state.focus-ring``blizzard.200``blizzard.400`Anel de foco padrão (todos os elementos interativos)
`color.state.focus-ring-error``pink.200`Anel de foco em campo com erro
`color.state.disabled-surface``midnight.50``midnight.800`Fundo de elemento desabilitado
`color.state.disabled-content``midnight.300``midnight.600`Texto/ícone de elemento desabilitado
css
--color-state-hover-neutral:    var(--primitive-midnight-100);
--color-state-hover-accent:     var(--primitive-blizzard-100);
--color-state-hover-error:      var(--primitive-red-50);
--color-state-pressed-accent:   var(--primitive-blizzard-700);
--color-state-focus-ring:       var(--primitive-blizzard-200);
--color-state-focus-ring-error: var(--primitive-pink-200);
--color-state-disabled-surface: var(--primitive-midnight-50);
--color-state-disabled-content: var(--primitive-midnight-300);

Boas práticas States

  • state.focus-ring é obrigatório em todos os elementos interativos nunca remover o outline de foco
  • state.focus-ring-error substitui o ring padrão quando o campo está em estado de erro
  • state.hover-neutral é o hover padrão para qualquer elemento de lista ou tabela não usar surface.raised para hover
  • O par disabled-surface + disabled-content é sempre usado junto nunca desabilitar apenas cor de texto

Categoria: Brand

Papel: Tokens institucionais de marca. Para uso em peças de comunicação, onboarding, páginas de marketing nunca em UI funcional operacional.

TokenValorUso
`color.brand.midnight``midnight.900`Cor primária de marca fundos, logotipo
`color.brand.blizzard``blizzard.200`Cor de acento de marca highlights, gradientes
`color.brand.gulf``gulf.800`Cor institucional secundária
`color.brand.merino``merino.100`Cor de fundo editorial da marca
css
--color-brand-midnight: var(--primitive-midnight-900);
--color-brand-blizzard: var(--primitive-blizzard-200);
--color-brand-gulf:     var(--primitive-gulf-800);
--color-brand-merino:   var(--primitive-merino-100);

Regras Globais do Sistema

Hierarquia de camadas

Primitivos   →  vocabulário bruto (nunca no produto)
Semânticos   →  intenção (único nível permitido em componentes)
Estados      →  interatividade transiente (hover, focus, disabled)
Dark Mode    →  inversão semântica (mesmos tokens, primitivos remapeados)

Acessibilidade pares WCAG validados

ParRatioNívelRestrição
`content.primary` / `surface.base`19.2:1AAA ✓
`content.secondary` / `surface.base`7.2:1AAA ✓
`content.tertiary` / `surface.base`4.1:1AA ✓Uso restrito a texto auxiliar
`content.disabled` / `surface.base`2.4:1reprovadoIntencional sinaliza indisponibilidade
`action.primary` / `surface.base`4.6:1AA ✓
`feedback.error` / `surface.base`5.9:1AA ✓
`feedback.success` / `surface.base`5.1:1AA ✓
`feedback.warning` / `surface.base`3.8:1AA***Sempre com ícone**
`feedback.badge` / `surface.base`5.4:1AA ✓
`feedback.premium` / `surface.base`3.2:1AA***Sempre com ícone**

Regra crítica

feedback.warning e feedback.premium não passam WCAG AA em texto solo. Qualquer uso desses tokens em conteúdo textual exige acompanhamento de ícone ou rótulo visível que identifique o estado independentemente da cor.

Dark Mode lógica de inversão

O dark mode não é uma inversão simples de cor. Cada token é remapeado individualmente para manter contraste e hierarquia:

  • Superfícies invertem a escala Midnight (0→900, 50→800, etc.)
  • Conteúdo inverte a hierarquia (900→50, 600→200, 500→300)
  • CTAs e feedback sobem um stop na escala para compensar o fundo escuro (blizzard.500blizzard.400)
  • Superfícies de feedback caem para os stops mais escuros (100→900) para não criar ruído luminoso
css
[data-theme="dark"],
@media (prefers-color-scheme: dark) {
  :root {
    --color-surface-base:     var(--primitive-midnight-900);
    --color-surface-subtle:   var(--primitive-midnight-800);
    --color-surface-raised:   var(--primitive-midnight-700);
    --color-surface-overlay:  var(--primitive-midnight-600);
    --color-surface-inverted: var(--primitive-midnight-0);
    --color-surface-warm:     var(--primitive-midnight-800);

    --color-content-primary:   var(--primitive-midnight-50);
    --color-content-secondary: var(--primitive-midnight-200);
    --color-content-tertiary:  var(--primitive-midnight-300);
    --color-content-disabled:  var(--primitive-midnight-600);
    --color-content-inverted:  var(--primitive-midnight-900);
    --color-content-accent:    var(--primitive-blizzard-400);

    --color-border-default: var(--primitive-midnight-700);
    --color-border-strong:  var(--primitive-midnight-600);
    --color-border-accent:  var(--primitive-blizzard-400);
    --color-border-error:   var(--primitive-red-400);

    --color-action-primary:  var(--primitive-blizzard-400);
    --color-action-hover:    var(--primitive-blizzard-300);
    --color-action-pressed:  var(--primitive-blizzard-500);
    --color-action-subtle:   var(--primitive-blizzard-800);
    --color-action-surface:  var(--primitive-blizzard-900);
    --color-action-disabled: var(--primitive-midnight-700);

    --color-feedback-error:         var(--primitive-red-400);
    --color-feedback-error-surface: var(--primitive-red-900);
    --color-feedback-error-content: var(--primitive-red-200);

    --color-feedback-success:         var(--primitive-green-400);
    --color-feedback-success-surface: var(--primitive-green-900);
    --color-feedback-success-content: var(--primitive-green-200);

    --color-feedback-warning:         var(--primitive-yellow-400);
    --color-feedback-warning-surface: var(--primitive-yellow-900);
    --color-feedback-warning-content: var(--primitive-yellow-200);

    --color-feedback-premium:         var(--primitive-orange-400);
    --color-feedback-premium-surface: var(--primitive-orange-900);
    --color-feedback-premium-content: var(--primitive-orange-200);

    --color-feedback-badge:         var(--primitive-pink-400);
    --color-feedback-badge-surface: var(--primitive-pink-900);
    --color-feedback-badge-content: var(--primitive-pink-200);

    --color-state-hover-neutral:    var(--primitive-midnight-800);
    --color-state-hover-accent:     var(--primitive-blizzard-900);
    --color-state-focus-ring:       var(--primitive-blizzard-400);
    --color-state-disabled-surface: var(--primitive-midnight-800);
    --color-state-disabled-content: var(--primitive-midnight-600);
  }
}

O que nunca fazer

ProibidoAlternativa correta
Usar hex direto no componente (`#0092BE`)Usar `color.action.primary`
Usar token primitivo no componente (`--primitive-blizzard-500`)Usar `color.action.primary`
Usar `feedback.warning` ou `feedback.premium` em texto sem íconeAdicionar ícone ou usar o token `-content` com `-surface`
Usar `content.disabled` intencionalmente para texto legível`content.tertiary` como mínimo para texto lido
Usar `brand.*` em UI operacionalUsar os tokens funcionais equivalentes
Criar estado de hover com valor arbitrárioUsar `state.hover-neutral` ou `state.hover-accent`
Usar `feedback.error` como cor de destaque decorativoReservado para estados negativos reais
Remover o `state.focus-ring` de elementos interativosObrigatório para acessibilidade de teclado

Integração com Dimensão 02 Tipografia

Token tipográficoToken de cor recomendadoContexto
`type.display.*``color.content.primary`Título de alto impacto
`type.heading.*``color.content.primary`Título de seção, modal, card
`type.body.md/lg``color.content.secondary`Texto corrido, descrições
`type.body.sm/xs``color.content.secondary`Texto de suporte, disclaimers
`type.label.*``color.content.tertiary`Labels, metadados, tags
`type.label.*``color.content.primary`Label ativo ou selecionado
`type.code.*``color.content.primary`Dado técnico em destaque
qualquer tipo`color.content.accent`Link, ação textual, chamada de atenção
qualquer tipo`color.feedback.error-content`Mensagem de validação de erro
qualquer tipo`color.feedback.warning-content`Mensagem de aviso (sobre surface de aviso)

Decisões Estratégicas Registradas

Estas decisões foram tomadas, discutidas e validadas. Nenhuma pode ser revertida sem discussão explícita.

Escalas LCH em vez de HSL
As 9 famílias foram construídas em espaço LCH (Lightness–Chroma–Hue), não HSL. O motivo é perceptual: escalas HSL têm brilho percebido inconsistente entre stops o que parece "meio claro" em azul parece "muito escuro" em amarelo. LCH garante que cada stop parece visualmente equidistante em qualquer família.

Dois amarelos âncora 400 e 500 hue fixo
O amarelo tem o problema mais crítico de contraste em WCAG: o stop de melhor saturação (400, #ECCE24) reprova como texto, e o stop que passa AA (500, #B09707) é mais escuro e menos vibrante. O sistema mantém os dois stops âncora com hue fixo em 93.6°, e documenta explicitamente que warning nunca aparece solo em texto.

Blizzard Blue como único CTA Gulf Blue apenas institucional
O BrandBook Effecti tem dois azuis: Blizzard (claro, vibrante) e Gulf (escuro, institucional). A decisão foi segmentar: Blizzard é o CTA e acento de UI, Gulf é restrito a brand e institucional. Misturar os dois azuis em UI cria ambiguidade semântica o usuário não sabe o que é clicável.

Dark Mode por data-attribute com fallback em prefers-color-scheme
O dark mode é ativado por [data-theme="dark"] com fallback automático em @media (prefers-color-scheme: dark). Esta arquitetura permite que o produto respeite a preferência do sistema mas ofereça override manual padrão esperado em produtos B2B.

content.disabled reprova WCAG intencionalmente
O token de conteúdo desabilitado (ratio 2.4:1) não passa AA. Essa falha é intencional: um elemento desabilitado deve ser visivelmente inacessível o baixo contraste comunica que ele não pode ser usado. A WCAG excepciona explicitamente componentes desabilitados do critério de contraste (1.4.3).

Merino Beige fora da paleta operacional
A família Merino é restrita a surface.warm, brand.merino e peças institucionais. Em UI operacional, o quente compete com os sinais de feedback (warning/premium) e dilui a hierarquia semântica.

Exemplos de Uso

Card de pregão — tokens em combinação

surface · content · border · action · feedback em conjunto

Pregão Eletrônico · 0045/2026Habilitado

Fornecimento de material de escritório para a administração pública federal

UASG 153042 · Ministério da Educação

Valor estimado

R$ 284.750,00

Estados de feedback — os 5 tipos

color.feedback.* — erro · sucesso · aviso · premium · badge

Prazo encerrado — documentação inválida
Fornecedor habilitado com sucesso
⚠ Prazo de habilitação encerra em 2 dias
Recurso disponível no plano Premium
3 novas notificações não lidas

Hierarquia de superfícies

color.surface.* — base → subtle → raised → inverted → warm

color.surface.base
color.surface.subtle
color.surface.raised
color.surface.inverted
color.surface.warm

Estados de input

border · feedback.error · state.focus-ring — aplicados em campos

00.000.000/0001-00
12.345.678/0001-90
12.345.678/000X-90

CNPJ inválido — verifique os dígitos

Arquivos de Output Dimensão 01

ArquivoFormatoConteúdo
`effecti_tokens_color.css`CSSCustom Properties primitivos + semânticos + dark mode
`effecti_tokens_color.dart`Dart`EffectiPrimitives`, `EffectiColors`, `EffectiColorsDark`
`effecti_color_palette_v1.svg`SVGVisualização das 9 famílias para validação no Figma

Effecti Programa de Governança de Design System · Dimensão 01 · v1.0