Pular para o conteúdo principal

Design Tokens

Este documento é a fonte única de verdade para todos os valores de design do projeto. Qualquer cor, espaçamento, animação ou constante de negócio utilizada no código deve estar referenciada aqui.


1. O que são Design Tokens?

Design tokens são os átomos do sistema de design — pares nome/valor que representam decisões visuais e de produto de forma agnóstica à plataforma. Em vez de espalhar o valor #F4C430 por centenas de arquivos, você usa o token gold-400 em todos os lugares.

Fonte única de verdade

No projeto existem dois arquivos que devem estar sempre sincronizados:

ArquivoPapel
tailwind.config.tsDefine os tokens como classes utilitárias Tailwind (text-gold-400, bg-primary-500, shadow-warm)
lib/design-tokens.tsExporta os mesmos valores como constantes TypeScript para uso em estilos inline, lógica condicional e testes

Regra: ao adicionar ou alterar qualquer token, ambos os arquivos devem ser atualizados na mesma PR. Ver seção Adicionando novos tokens.

Fluxo de uso

Decisão de design

tailwind.config.ts ←→ lib/design-tokens.ts
↓ ↓
Classes Tailwind TypeScript / inline styles
(className="text-gold-400") (style={{ color: BRAND_COLORS.goldRadiant }})

2. Cores — Paleta Completa

Primary — Marrom Âmbar

NívelHexUso semântico
50#fdf8f4Background de seção levíssimo, hover de linha em tabelas
100#f7e9d8Background de cartão sutil, chip inativo
200#eecfafBordas sutis, skeleton loading, divisores
300#e0ad7dHover de bordas, ícones decorativos secundários
400#ce8849Hover de elementos interativos, ícones de destaque
500#b96828Cor primária — botão secundário, link ativo, anel de foco
600#964e1aHover/active do botão primário âmbar
700#773b13Texto âmbar de alto contraste sobre fundo claro
800#5c2c0dTexto de máximo contraste, cabeçalhos escuros
900#3D2817Texto ultra escuro — quase equivale ao deep
950#1A1410Texto ultra escuro — idêntico ao token deep

Gold — Dourado Radiante

NívelHexUso semântico
50#fffef0Background de alerta/notificação dourado suavíssimo
100#fefce0Background de badge dourado
200#fdf5b0Highlight de texto, marcação de busca
300#fce870Borda de alerta positivo, ícone de estrela de avaliação
400#F4C430CTA principalbtn-gold, estrelas ativas, hover dourado
500#d4a020Botão gold pressionado (active state), texto dourado sobre claro
600#aa7e15Texto dourado de alto contraste
700#7e5d0fTexto dourado — máxima legibilidade
800#5c430bBordas douradas escuras
900#3f2f08Texto dourado de máximo contraste

Sage — Verde Sálvia

NívelHexUso semântico
50#eef9f4Background de mensagem de sucesso
100#d5f0e4Background de badge verde claro
200#a5ddc8Borda de campo válido (formulário)
300#6cc4a8Ícones de confirmação secundários
400#3da887Ícone de sucesso, hover de elemento sage
500#2D7A5FCor sage primária — badge "Em estoque", status DELIVERED/PAID
600#226350Hover/active de elementos sage
700#1a4d3eTexto sage de alto contraste
800#123c30Texto sage — máxima legibilidade
900#0d2e25Texto sage de máximo contraste

Cores funcionais da loja

Token TailwindValor hexUso
cream#FFF8E7Fundo principal da loja (body, hero)
cream-dark#F5E6C8Seções alternadas, fundo do footer
cream-warm#FDF0D5Hover de cards, fundo de banners de destaque
deep#1A1410Texto principal de máximo contraste

3. Constantes de Negócio

Definidas em lib/constants.ts. Estas constantes governam regras de negócio da loja e devem ser atualizadas exclusivamente neste arquivo — nunca hardcoded em componentes.

Frete e compras

ConstanteValorTipoOnde é usado
FREE_SHIPPING_THRESHOLD200number (BRL)Cálculo do carrinho, banner de frete grátis, progresso no mini-cart
SHIPPING_COST_DEFAULT19.90number (BRL)Simulação de frete antes do CEP, resumo do pedido
ConstanteValorTipoOnde é usado
LOW_STOCK_THRESHOLD5numberBadge "Restam X unidades", alerta de estoque baixo no admin
NEW_PRODUCT_DAYS30number (dias)Badge "Novo" em produtos criados nos últimos N dias

Paginação

ConstanteValorTipoOnde é usado
DEFAULT_PAGE_SIZE20numberListagem de produtos, histórico de pedidos, tabelas do admin
MAX_PAGE_SIZE100numberLimite máximo aceito pela API em queries paginadas

Identidade da loja

ConstanteValorTipoOnde é usado
STORE_NAME"LJ Velas & Aromas"string<title>, OG tags, e-mails transacionais, rodapé
STORE_DOMAIN"ljvelasearomas.com.br"stringURLs canônicas, links em e-mails, sitemap
STORE_WHATSAPP"5513981629679"stringLink direto wa.me/5513981629679, botão de suporte

4. Status Maps

Definidos em lib/design-tokens.ts. Mapeiam cada valor de enum de status para um conjunto de tokens visuais (label, cor de fundo, cor de texto, cor de borda).

ORDER_STATUS_MAP — Status de Pedido

StatusLabel PT-BRPaletaClasse badge (exemplo)
PENDINGAguardandoÂmbarbg-yellow-100 text-yellow-800 border-yellow-300
CONFIRMEDConfirmadoAzulbg-blue-100 text-blue-800 border-blue-300
PROCESSINGEm preparoRoxobg-purple-100 text-purple-800 border-purple-300
SHIPPEDEnviadoÍndigobg-indigo-100 text-indigo-800 border-indigo-300
DELIVEREDEntregueSagebg-sage-100 text-sage-700 border-sage-300
CANCELLEDCanceladoVermelhobg-red-100 text-red-800 border-red-300
REFUNDEDReembolsadoCinzabg-gray-100 text-gray-700 border-gray-300

PAYMENT_STATUS_MAP — Status de Pagamento

StatusLabel PT-BRPaletaClasse badge (exemplo)
PENDINGAguardando pagamentoÂmbarbg-yellow-100 text-yellow-800 border-yellow-300
PROCESSINGProcessandoAzulbg-blue-100 text-blue-800 border-blue-300
PAIDPagoSagebg-sage-100 text-sage-700 border-sage-300
FAILEDFalhouVermelhobg-red-100 text-red-800 border-red-300
REFUNDEDReembolsadoCinzabg-gray-100 text-gray-700 border-gray-300
CANCELLEDCanceladoVermelhobg-red-100 text-red-800 border-red-300

Os status maps são consumidos pelos componentes <OrderStatusBadge> e <PaymentStatusBadge>, que aceitam o enum e automaticamente aplicam o estilo correto. Não replique essa lógica em componentes individuais.


5. Animações

Definidas em tailwind.config.ts sob a chave theme.extend.animation e theme.extend.keyframes. A maioria usa tailwindcss-animate como base para as animações de acordeão.

Tabela de animações

NomeClasse TailwindDuraçãoEasingUse case
fade-inanimate-fade-in500msease-in-outEntrada de página, modais, skeleton → conteúdo
slide-upanimate-slide-up400msease-outCards entrando na viewport, toasts
slide-in-ranimate-slide-in-r350msease-outDrawer lateral, sidebar mobile, painel de filtros
pulse-softanimate-pulse-soft2s— (infinite)Skeleton loading, indicadores de "ao vivo"
shimmeranimate-shimmer1.5s— (infinite)Skeleton com gradiente deslizante — loading de cards
floatanimate-float3s— (infinite)Elemento decorativo flutuante no hero
marqueeanimate-marquee25slinear (infinite)Faixa de logos/benefícios em loop horizontal
accordion-downanimate-accordion-downExpansão de accordions (via tailwindcss-animate)
accordion-upanimate-accordion-upColapso de accordions (via tailwindcss-animate)

Notas de uso

  • shimmer: requer um gradiente definido no keyframe — background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.4) 50%, transparent 100%). Combinar com bg-primary-100 ou bg-gray-100 como base.
  • marquee: o container pai precisa de overflow-hidden. O conteúdo interno deve ser duplicado para criar o loop contínuo sem saltos.
  • Preferência por movimento reduzido: envolva animações decorativas em @media (prefers-reduced-motion: no-preference) ou use a variant motion-safe:animate-* do Tailwind.

6. Como Usar Tokens em Código

6.1 Em classes Tailwind (JSX)

A forma mais comum — use diretamente nos atributos className:

// Cor de texto primária
<p className="text-primary-700">Descrição do produto</p>

// Background dourado com texto escuro
<button className="bg-gold-400 text-deep rounded-btn px-8 py-4 font-montserrat font-semibold shadow-gold">
Adicionar ao Carrinho
</button>

// Badge de status com paleta sage
<span className="bg-sage-100 text-sage-700 border border-sage-300 rounded-pill px-3 py-1 text-sm">
Em estoque
</span>

// Card de produto
<div className="bg-white rounded-card shadow-warm hover:shadow-warm-lg transition-shadow">
{/* conteúdo do card */}
</div>

// Animação de entrada
<section className="animate-fade-in">
{/* conteúdo */}
</section>

6.2 Em TypeScript — importando design-tokens.ts

Use quando precisar dos valores em lógica de negócio, testes ou configurações de bibliotecas externas (ex: Chart.js, React Native, e-mail HTML):

import { colors, BRAND_COLORS, ORDER_STATUS_MAP, PAYMENT_STATUS_MAP } from '@/lib/design-tokens'

// Acessando uma cor da paleta
const primaryColor = colors.primary[500] // "#b96828"
const goldCTA = colors.gold[400] // "#F4C430"
const sageSuccess = colors.sage[500] // "#2D7A5F"

// Usando BRAND_COLORS para valores semânticos nomeados
const brandGold = BRAND_COLORS.goldRadiant // "#F4C430"
const brandDeep = BRAND_COLORS.deep // "#1A1410"
const brandCream = BRAND_COLORS.cream // "#FFF8E7"

// Resolvendo status de pedido dinamicamente
const statusConfig = ORDER_STATUS_MAP['DELIVERED']
// → { label: 'Entregue', bgClass: 'bg-sage-100', textClass: 'text-sage-700', ... }

6.3 Em estilos inline

Necessário quando uma biblioteca de terceiros não aceita classes Tailwind (ex: componentes de gráfico, mapas, editores rich-text):

import { BRAND_COLORS } from '@/lib/design-tokens'

// Em um componente com estilo inline
<div style={{ backgroundColor: BRAND_COLORS.cream, color: BRAND_COLORS.deep }}>
Conteúdo
</div>

// Em configuração de biblioteca (ex: Chart.js)
const chartOptions = {
plugins: {
legend: {
labels: {
color: BRAND_COLORS.deep,
font: { family: 'Montserrat' }
}
}
},
scales: {
x: { grid: { color: colors.primary[100] } },
y: { grid: { color: colors.primary[100] } }
}
}

6.4 Em CSS/SCSS (admin)

As variáveis do admin são usadas diretamente em CSS:

.admin-card {
background-color: var(--admin-surface);
border: 1px solid var(--admin-border);
color: var(--admin-text);
}

.admin-sidebar-item:hover {
background-color: var(--admin-accent-subtle);
color: var(--admin-sidebar-active-text);
}

7. Adicionando Novos Tokens

Ao adicionar qualquer novo token de design, siga obrigatoriamente os passos abaixo:

Passo 1 — tailwind.config.ts

Adicione o novo token na seção theme.extend correspondente:

// tailwind.config.ts
theme: {
extend: {
colors: {
// nova paleta ou nível
primary: { 975: '#0F0C0A' }
},
boxShadow: {
'nova-sombra': '0 8px 32px -4px rgba(61,40,23,0.16)'
},
borderRadius: {
'novo-radius': '2rem'
}
}
}

Passo 2 — lib/design-tokens.ts

Adicione o mesmo valor como constante TypeScript, espelhando o que foi definido no Tailwind:

// lib/design-tokens.ts
export const colors = {
primary: {
// ...valores existentes...
975: '#0F0C0A', // ← novo nível
}
}

export const shadows = {
// ...sombras existentes...
novaSombra: '0 8px 32px -4px rgba(61,40,23,0.16)', // ← nova sombra
}

Passo 3 — Documentar aqui

Adicione o novo token na tabela correspondente deste documento (docs/design/tokens.md), incluindo:

  • Nome do token (classe Tailwind e/ou constante TypeScript)
  • Valor (hex, px, string CSS)
  • Uso semântico — onde e quando deve ser usado

Regras de nomeação

  • Nomes de token devem ser descritivos do uso, não do valor. ✅ shadow-warm — não ❌ shadow-brown-12.
  • Novas paletas de cor devem seguir o padrão de escala 50–950.
  • Constantes de negócio devem estar em SCREAMING_SNAKE_CASE.
  • Tokens TypeScript de cor devem estar em camelCase.

8. Tokens do Admin

O admin usa CSS custom properties em vez de classes Tailwind de cor, permitindo troca de tema via JavaScript ou CSS sem recompilar.

Variáveis CSS — valores padrão (tema claro)

Variável CSSValor padrãoPropósito
--admin-bg#f9fafb (gray-50)Fundo geral da página do admin
--admin-surface#ffffffSuperfície de cards, formulários, tabelas
--admin-surface-raised#ffffff com sombraModais, popovers — elevação visual via sombra
--admin-border#e5e7eb (gray-200)Bordas padrão — inputs, separadores, linhas de tabela
--admin-border-strong#d1d5db (gray-300)Bordas de ênfase — foco de input, alertas
--admin-text#111827 (gray-900)Texto primário — labels, valores de célula
--admin-text-secondary#6b7280 (gray-500)Texto secundário — descrições, metadados, placeholders
--admin-text-disabled#9ca3af (gray-400)Texto desabilitado — campos readonly, botões inativos
--admin-accent#2563eb (blue-600)Acento principal — botões primários, links ativos
--admin-accent-hover#1d4ed8 (blue-700)Hover do botão primário do admin
--admin-accent-subtle#eff6ff (blue-50)Background de item selecionado, highlight de linha
--admin-sidebar-bg#1e293b (slate-800)Fundo da barra lateral
--admin-sidebar-text#cbd5e1 (slate-300)Texto de item de menu inativo
--admin-sidebar-muted#64748b (slate-500)Ícones e texto secundário da sidebar
--admin-sidebar-active-bg#2563eb (blue-600)Background do item de menu ativo
--admin-sidebar-active-text#ffffffTexto do item de menu ativo
--admin-sidebar-border#334155 (slate-700)Linha divisória interna da sidebar

Sombras do admin

Variável / TokenValor CSSPropósito
shadow-admin0 1px 3px 0 rgba(0,0,0,0.10), 0 1px 2px -1px rgba(0,0,0,0.10)Containers, cards base do admin
shadow-admin-md0 4px 6px -1px rgba(0,0,0,0.10), 0 2px 4px -2px rgba(0,0,0,0.10)Cards com maior elevação, sidepanels
shadow-admin-lg0 10px 15px -3px rgba(0,0,0,0.10), 0 4px 6px -4px rgba(0,0,0,0.10)Modais, drawers, overlays do admin

Preparação para dark mode

Para ativar um tema escuro no admin, basta sobrescrever as variáveis CSS em um seletor de tema:

/* globals.css ou admin-theme.css */
[data-theme="dark"] .admin-layout,
.admin-layout.dark {
--admin-bg: #0f172a; /* slate-900 */
--admin-surface: #1e293b; /* slate-800 */
--admin-surface-raised: #334155; /* slate-700 */
--admin-border: #334155;
--admin-border-strong: #475569;
--admin-text: #f1f5f9;
--admin-text-secondary: #94a3b8;
--admin-text-disabled: #475569;
/* demais variáveis... */
}

Nenhum componente React precisa ser alterado — eles já usam as variáveis CSS e herdarão os novos valores automaticamente.