Pular para o conteúdo

Duas camadas. Componente só enxerga a de cima.

Primitivos são a escala bruta de valores possíveis e não carregam significado de uso. Semânticos são apelidos nomeados pelo papel que cumprem na interface. Separar os dois é o que permite trocar a aparência inteira do produto sem reabrir um único componente.

Por que não bastam os primitivos

A marca tem oito cores fixas e nenhum modo escuro previsto. Ainda assim a camada semântica vale, por dois motivos concretos.

Primeiro: a regra "vermelho é só ação" só é executável se o componente escrever var(--asa-action). Escrevendo var(--asa-red), a regra continua sendo folclore que alguém precisa lembrar. Segundo: a v3.1 troca vermelho e amarelo de papel. Isso é literalmente um tema, e sem apelido seria reescrever todo componente para produzir a variante B2B.

Os quatro arquivos
asa-tokens.css@font-face + as duas camadas
asa-base.cssreset, elementos, layout, foco
asa-components.cssa biblioteca inteira
asa-utilities.csscorte 8°, hachura, auxiliares

Nesta ordem. Sem build, é a cascata por ordem de origem que dispensa !important: utilitário por último para poder vencer componente quando precisar.

Convenção
Bloco.asa-btn
Elemento.asa-card__price
Modificador.asa-btn--primary
Estadoatributo nativo

Estado de runtime nunca vira classe: :disabled, [aria-invalid], [data-state="loading"], [aria-current="step"]. É o que o framework já emite, e traz acessibilidade junto de graça.

Catorze primitivos, quinze apelidos.

Primitivos · nunca use em componente
--asa-yellow#FEC42B
--asa-black#141517
--asa-red#E80911
--asa-mist#F4F4F3 · fundo de composição e camada flutuante
--asa-red-dark#C4070E
--asa-green#065F46
--asa-black-deep#0D0D0E
--asa-white#FFFFFF
--asa-gray-body#4A4C50
--asa-gray-caption#5A5C60
--asa-gray-dark-1#8A8C90 · só sobre escuro
--asa-gray-dark-2#A8AAAE · só sobre escuro
--asa-disabled-bg#F2F2F0
--asa-placeholder#E4E0DA · hachura
Semânticos · o que o componente consome
ApelidoAponta paraPapel
--asa-surfaceyellowsuperfície principal da marca
--asa-bgmistfundo de composição; body é branco por padrão
--asa-bg-elevatedwhitecard, superfície elevada
--asa-bg-denseblackbloco de informação densa
--asa-bg-deepblack-deeppeça noturna, rodapé
--asa-surface-floatmistmodal, sheet, popover, menu
--asa-actionredsomente ação
--asa-action-hoverred-darkhover, foco, erro
--asa-on-actionwhitetexto sobre vermelho
--asa-inkblacktexto principal
--asa-ink-2gray-bodycorpo secundário
--asa-ink-3gray-captionlegenda
--asa-ink-inversewhitetexto sobre escuro
--asa-okgreenconfirmação
--asa-linergba(20,21,23,.14)borda sobre claro
A variante B2B em nove linhas
/* asa-tokens-v31.css: carregar DEPOIS de asa-tokens.css. Nenhum componente muda. Nenhuma classe muda. Só o papel das cores. */ :root { --asa-surface: var(--asa-red); /* vermelho vira ambiente */ --asa-bg: #FFF2F2; /* fundo claro da v3.1 */ --asa-action: var(--asa-yellow); /* amarelo vira ação */ --asa-on-action: var(--asa-black); /* sobre amarelo, só preto */ --asa-action-hover: #EAB227; }

Esta é a prova de que a camada semântica não é cerimônia. Com ela, a variante B2B é um arquivo de cinco declarações. Sem ela, seria uma caça manual a cada lugar do produto onde #E80911 foi escrito direto.

Tipografia, espaço, forma, ícone e movimento.

Tipografia
--asa-fontBR Omny + fallback
--asa-fs-display64px
--asa-fs-title32px
--asa-fs-highlight20px
--asa-fs-body16px
--asa-fs-label12px · só etiqueta (.asa-tag)
--asa-fs-mono11px · só metadado de produto
--asa-tracking-display-0.03em · H1, Registro 1
--asa-tracking-title-0.01em · H2, Registro 2
--asa-measure640px

Não existe token composto de tipografia. O atalho font não carrega letter-spacing nem text-transform, e três dos cinco degraus dependem de um ou de outro; um token composto reintroduziria a chance de erro exatamente onde o sistema é mais frágil.

Escala de UI
--asa-fs-subtitle17px · título de card
--asa-fs-body-dense14px · botão, rótulo, denso
--asa-fs-lead18px · lide sob o H2
--asa-fs-price-card24px · registro de numeral

Degrau paralelo à escala de conteúdo acima, com o mesmo piso de 12px. Componente não inventa tamanho fora dessas duas escalas: asa-tag e a categoria do card usam --asa-fs-label, nunca um valor solto. Ver 13 · Roadmap.

Espaço e grade
--asa-space-1…114 a 90px · o 90 é margem lateral
--asa-section-pad-yclamp(72px, 8vw, 120px) · entre faixas
--asa-section-pad-xclamp(20px, 6vw, 90px)
--asa-container-max1200px
--asa-gutter24px
--asa-columns12 / 8 / 4
--asa-safe-fold680px

O vão entre seções tem token próprio, --asa-section-pad-y: 120px no desktop e 72 no celular. Breakpoints existem como token para leitura e para JS, mas as media queries repetem o valor literal: custom property não funciona dentro de @media.

Forma e tamanho
--asa-radius8px
--asa-radius-full50% · só avatar
--asa-border-width1.5px
--asa-control-h48px
--asa-touch-min44px
--asa-icon-inline24px
--asa-icon-dense16px · card e chip
--asa-icon-stroke1.5

Só dois valores de raio, e é de propósito: uma escala sm/md/lg convidaria alguém a escolher entre eles. O sistema não oferece essa escolha.

Coleção que não existe Sombra

Não há --asa-shadow-*, por decisão.

A marca é chapada: elevação se resolve com borda de 1,5px e contraste de fundo, e foco se resolve com outline. Se um dia alguém precisar de box-shadow, o problema está no layout.

Geometria e movimento
--asa-angle8deg
--asa-rise14.05cqw
--asa-dur-fast200ms
--asa-dur-default240ms
--asa-dur-scene320ms
--asa-dur-max400ms
--asa-ease-insaída de overlay

Sob prefers-reduced-motion, as quatro durações caem para 1ms na própria camada de tokens; nenhum componente precisa lembrar disso. --asa-ease-in é só para saída de overlay, modal, sheet e popover. A entrada usa --asa-ease: sair mais rápido do que se entra é o que faz o overlay parecer deliberado.

Camada, atenção e superfície de interação.

Tokens da camada flutuante e da navegação de produto: canal de atenção, ordem de sobreposição, superfícies de interação e offset de header. Os componentes que os consomem estão em 06 · Componentes.

Canal de atenção
--asa-warn#A35200 · 5,58:1 sobre branco, 5,02:1 sobre --asa-warn-bg
--asa-warn-bg#FDF1E4

"Esgotado", "restam 2", "documento recusado" e "campo inválido" falam por este canal. O vermelho fica reservado ao CTA. --asa-warn nunca é ação: não leva onClick.

Camada e sobreposição
--asa-z-sticky1000
--asa-z-dropdown1010
--asa-z-overlay1200
--asa-z-modal1210
--asa-z-popover1220
--asa-z-toast1300
--asa-scrimrgba(13,13,14,.56)
--asa-surface-float= mist

Escala de 10 em 10, com vão para inserção sem renumerar tudo. --asa-z-dropdown vence --asa-z-sticky de propósito: um combobox aberto sob um header fixo precisa aparecer por cima dele.

Superfícies de interação
--asa-surface-hoverrgba(20,21,23,.04)
--asa-surface-selectedamarelo a 12%
--asa-line-strongrgba(20,21,23,.30)

Servem o .asa-input, o asa-menu, o asa-datepicker e a aresta de contato de qualquer superfície sticky.

Offset de header
--asa-header-h70px

Um único token faz dois trabalhos: é a altura real de asa-navbar (ver Navegação) e o scroll-margin-top de toda âncora do site. A utility bar não entra na conta: ela não é sticky e rola para fora antes do navbar grudar no topo.

Cole os quatro arquivos. Não há build, não há dependência.

HTML puro, WordPress, qualquer coisa
<link rel="stylesheet" href="css/asa-tokens.css"> <link rel="stylesheet" href="css/asa-base.css"> <link rel="stylesheet" href="css/asa-components.css"> <link rel="stylesheet" href="css/asa-utilities.css"> <!-- e o markup já nasce na marca --> <h1>Seu carro já tá te esperando</h1> <button class="asa-btn asa-btn--primary"> <span class="asa-btn__label">Ver carros</span> </button>
React, Vue, Svelte
// importe uma vez, na raiz import './css/asa-tokens.css' import './css/asa-base.css' import './css/asa-components.css' import './css/asa-utilities.css' // o estado é atributo, não classe: nada de // className={loading ? 'btn--loading' : ''} <button className="asa-btn asa-btn--primary" data-state={loading ? 'loading' : undefined} disabled={loading} >
Migrando para CSS Modules, Tailwind ou styled-components

A camada de tokens vai inteira, sem tradução: são custom properties, e todo sistema de estilo lê custom property. O que muda é só a camada de componente. Se o destino for Tailwind, mapeie os tokens no theme.extend apontando para as mesmas variáveis. Não copie os valores hexadecimais para lá, senão as duas fontes de verdade divergem na primeira mudança de marca.

Anterior← 09 · Segurança Próxima seção11 · Movimento →