Colors
Mapeamento intenção → valor para os seis temas Gremorie, em light e dark mode.
Tokens semânticos são intenções: primary, foreground,
border. Cada tema preenche essas intenções com valores
diferentes, e cada modo (light / dark) traz seu próprio
mapeamento. Esta página é a tabela de verdade para os seis
temas embarcados: Default, Claude, ChatGPT, Gemini, Perplexity e
Mistral.
Como ler as tabelas
- As colunas Light e Dark renderizam o valor exato declarado como um chip sobre o próprio background light ou dark do tema, então as duas são fiéis independente do modo em que você está lendo.
- As colunas Valor mostram o que o tema declara: um nome de
primitivo (consumido via
var(--color-<token>)) ou, onde o tema espelha uma superfície de produto sem primitivo equivalente, um valor OKLCH literal. - O badge
baseindica que o tema não sobrescreve aquele token; ele herda o valor da camada base emtheme.css. Essa herança é o comportamento que embarca, não uma omissão.
Se você está auditando um componente que parece "errado" em algum
tema, comece por aqui. Comparar a intenção (e.g. --primary) com
o valor resolvido em cada tema diz se a inconsistência é da chrome
do componente ou do mapeamento do tema.
Default
A propria camada semantica base, sobre a rampa gray neutralizada. Conservador e sem marca; todos os outros temas sao camadas de override por cima dele.
--radius-base: 0.625rem · selector :root
| Light | Dark | Token | Valor (light) | Valor (dark) |
|---|---|---|---|---|
| --background | gray-50base | gray-950base | ||
| --foreground | gray-950base | gray-50base | ||
| --card | gray-0base | gray-900base | ||
| --card-foreground | gray-950base | gray-50base | ||
| --popover | gray-0base | gray-900base | ||
| --popover-foreground | gray-950base | gray-50base | ||
| --primary | gray-900base | gray-100base | ||
| --primary-foreground | gray-50base | gray-900base | ||
| --secondary | gray-100base | gray-800base | ||
| --secondary-foreground | gray-900base | gray-50base | ||
| --muted | gray-100base | gray-800base | ||
| --muted-foreground | gray-500base | gray-400base | ||
| --accent | gray-100base | gray-800base | ||
| --accent-foreground | gray-900base | gray-50base | ||
| --destructive | red-600base | red-400base | ||
| --destructive-foreground | gray-50base | gray-50base | ||
| --border | gray-200base | oklch(1 0 0 / 10%)base | ||
| --input | gray-200base | oklch(1 0 0 / 15%)base | ||
| --ring | gray-400base | gray-500base | ||
| --chart-1 | oklch(0.646 0.222 41.116)base | oklch(0.488 0.243 264.376)base | ||
| --chart-2 | oklch(0.6 0.118 184.704)base | oklch(0.696 0.17 162.48)base | ||
| --chart-3 | oklch(0.398 0.07 227.392)base | oklch(0.769 0.188 70.08)base | ||
| --chart-4 | oklch(0.828 0.189 84.429)base | oklch(0.627 0.265 303.9)base | ||
| --chart-5 | oklch(0.769 0.188 70.08)base | oklch(0.645 0.246 16.439)base | ||
| --sidebar | gray-50base | gray-900base | ||
| --sidebar-foreground | gray-950base | gray-50base | ||
| --sidebar-primary | gray-900base | gray-100base | ||
| --sidebar-primary-foreground | gray-50base | gray-900base | ||
| --sidebar-accent | gray-100base | gray-800base | ||
| --sidebar-accent-foreground | gray-900base | gray-50base | ||
| --sidebar-border | gray-200base | oklch(1 0 0 / 10%)base | ||
| --sidebar-ring | gray-400base | gray-500base |
Claude
Clay quente (terracota coral) sobre superficies creme, apoio em taupe, display serifado. O dark mode usa o carvao quente do produto real.
--radius-base: 0.5rem · selector [data-theme='claude']
| Light | Dark | Token | Valor (light) | Valor (dark) |
|---|---|---|---|---|
| --background | oklch(0.965 0.011 92) | oklch(0.235 0.006 100) | ||
| --foreground | gray-950 | gray-50 | ||
| --card | oklch(0.985 0.008 92) | oklch(0.268 0.005 100) | ||
| --card-foreground | gray-950 | gray-50 | ||
| --popover | oklch(0.985 0.008 92) | oklch(0.268 0.005 100) | ||
| --popover-foreground | gray-950 | gray-50 | ||
| --primary | clay-500 | clay-400 | ||
| --primary-foreground | gray-50 | gray-950 | ||
| --secondary | oklch(0.95 0.012 80) | oklch(0.28 0.012 58) | ||
| --secondary-foreground | clay-900 | gray-50 | ||
| --muted | oklch(0.95 0.012 80) | oklch(0.28 0.012 58) | ||
| --muted-foreground | taupe-600 | taupe-300 | ||
| --accent | clay-100 | clay-900 | ||
| --accent-foreground | clay-900 | clay-50 | ||
| --destructive | red-600base | red-400base | ||
| --destructive-foreground | gray-50base | gray-50base | ||
| --border | oklch(0.9 0.014 78) | oklch(1 0 0 / 10%) | ||
| --input | oklch(0.9 0.014 78) | oklch(1 0 0 / 15%) | ||
| --ring | clay-500 | clay-400 | ||
| --chart-1 | clay-500 | clay-400 | ||
| --chart-2 | clay-300 | clay-200 | ||
| --chart-3 | clay-700 | clay-600 | ||
| --chart-4 | taupe-400 | taupe-400 | ||
| --chart-5 | amber-400 | amber-400 | ||
| --sidebar | oklch(0.97 0.01 84) | oklch(0.24 0.012 60) | ||
| --sidebar-foreground | gray-950 | gray-50 | ||
| --sidebar-primary | clay-600 | clay-400 | ||
| --sidebar-primary-foreground | gray-50 | gray-950 | ||
| --sidebar-accent | clay-100 | oklch(0.28 0.012 58) | ||
| --sidebar-accent-foreground | clay-900 | gray-50 | ||
| --sidebar-border | oklch(0.9 0.014 78) | oklch(1 0 0 / 10%) | ||
| --sidebar-ring | clay-500 | clay-400 |
ChatGPT
Acento emerald sobre superficie flat de sombras suaves. O dark mode usa o grafite flat do produto real; as demais superficies herdam a base neutra.
--radius-base: 0.75rem · selector [data-theme='chatgpt']
| Light | Dark | Token | Valor (light) | Valor (dark) |
|---|---|---|---|---|
| --background | gray-50base | oklch(0.248 0 0) | ||
| --foreground | gray-950base | gray-50base | ||
| --card | gray-0base | oklch(0.278 0 0) | ||
| --card-foreground | gray-950base | gray-50base | ||
| --popover | gray-0base | oklch(0.278 0 0) | ||
| --popover-foreground | gray-950base | gray-50base | ||
| --primary | emerald-700 | emerald-400 | ||
| --primary-foreground | gray-50 | gray-950 | ||
| --secondary | gray-100base | gray-800base | ||
| --secondary-foreground | gray-900base | gray-50base | ||
| --muted | gray-100base | gray-800base | ||
| --muted-foreground | gray-500base | gray-400base | ||
| --accent | emerald-100 | emerald-900 | ||
| --accent-foreground | emerald-900 | emerald-50 | ||
| --destructive | red-600base | red-400base | ||
| --destructive-foreground | gray-50base | gray-50base | ||
| --border | gray-200base | oklch(1 0 0 / 10%)base | ||
| --input | gray-200base | oklch(1 0 0 / 15%)base | ||
| --ring | emerald-500 | emerald-400 | ||
| --chart-1 | emerald-500 | emerald-400 | ||
| --chart-2 | emerald-300 | emerald-200 | ||
| --chart-3 | teal-600 | teal-400 | ||
| --chart-4 | green-400 | green-400 | ||
| --chart-5 | cyan-400 | cyan-400 | ||
| --sidebar | gray-50base | gray-900base | ||
| --sidebar-foreground | gray-950base | gray-50base | ||
| --sidebar-primary | emerald-700 | emerald-400 | ||
| --sidebar-primary-foreground | gray-50 | gray-950 | ||
| --sidebar-accent | gray-100base | gray-800base | ||
| --sidebar-accent-foreground | gray-900base | gray-50base | ||
| --sidebar-border | gray-200base | oklch(1 0 0 / 10%)base | ||
| --sidebar-ring | emerald-500 | emerald-400 |
Gemini
Azul Google com rampa de chart azul-para-roxo e o radius mais arredondado do conjunto. O dark mode usa o grafite frio do produto real.
--radius-base: 1rem · selector [data-theme='gemini']
| Light | Dark | Token | Valor (light) | Valor (dark) |
|---|---|---|---|---|
| --background | gray-50base | oklch(0.239 0.002 248) | ||
| --foreground | gray-950base | gray-50base | ||
| --card | gray-0base | oklch(0.274 0.002 248) | ||
| --card-foreground | gray-950base | gray-50base | ||
| --popover | gray-0base | oklch(0.274 0.002 248) | ||
| --popover-foreground | gray-950base | gray-50base | ||
| --primary | oklch(0.55 0.19 258) | oklch(0.75 0.11 258) | ||
| --primary-foreground | gray-50 | gray-950 | ||
| --secondary | gray-100base | gray-800base | ||
| --secondary-foreground | gray-900base | gray-50base | ||
| --muted | gray-100base | gray-800base | ||
| --muted-foreground | gray-500base | gray-400base | ||
| --accent | indigo-100 | indigo-900 | ||
| --accent-foreground | indigo-900 | indigo-50 | ||
| --destructive | red-600base | red-400base | ||
| --destructive-foreground | gray-50base | gray-50base | ||
| --border | gray-200base | oklch(1 0 0 / 10%)base | ||
| --input | gray-200base | oklch(1 0 0 / 15%)base | ||
| --ring | oklch(0.63 0.18 260) | oklch(0.75 0.11 258) | ||
| --chart-1 | oklch(0.63 0.18 260) | oklch(0.75 0.11 258) | ||
| --chart-2 | oklch(0.78 0.11 258) | oklch(0.85 0.07 255) | ||
| --chart-3 | oklch(0.629 0.136 304) | oklch(0.72 0.12 304) | ||
| --chart-4 | oklch(0.78 0.09 304) | oklch(0.84 0.06 300) | ||
| --chart-5 | oklch(0.53 0.2 276) | oklch(0.68 0.14 276) | ||
| --sidebar | gray-50base | gray-900base | ||
| --sidebar-foreground | gray-950base | gray-50base | ||
| --sidebar-primary | oklch(0.55 0.19 258) | oklch(0.75 0.11 258) | ||
| --sidebar-primary-foreground | gray-50 | gray-950 | ||
| --sidebar-accent | gray-100base | gray-800base | ||
| --sidebar-accent-foreground | gray-900base | gray-50base | ||
| --sidebar-border | gray-200base | oklch(1 0 0 / 10%)base | ||
| --sidebar-ring | oklch(0.63 0.18 260) | oklch(0.75 0.11 258) |
Perplexity
Turquesa verdadeiro sobre offblack, sobrio e compacto, com o menor radius do conjunto. O primary claro e o turquesa de marca #20808D.
--radius-base: 0.375rem · selector [data-theme='perplexity']
| Light | Dark | Token | Valor (light) | Valor (dark) |
|---|---|---|---|---|
| --background | gray-50base | oklch(0.192 0.02 195.6) | ||
| --foreground | gray-950base | gray-50base | ||
| --card | gray-0base | oklch(0.225 0.018 196) | ||
| --card-foreground | gray-950base | gray-50base | ||
| --popover | gray-0base | oklch(0.225 0.018 196) | ||
| --popover-foreground | gray-950base | gray-50base | ||
| --primary | oklch(0.553 0.086 208.5) | oklch(0.72 0.11 205) | ||
| --primary-foreground | gray-0 | gray-950 | ||
| --secondary | gray-100base | gray-800base | ||
| --secondary-foreground | gray-900base | gray-50base | ||
| --muted | gray-100base | gray-800base | ||
| --muted-foreground | gray-500base | gray-400base | ||
| --accent | teal-100 | teal-900 | ||
| --accent-foreground | teal-900 | teal-50 | ||
| --destructive | red-600base | red-400base | ||
| --destructive-foreground | gray-50base | gray-50base | ||
| --border | gray-200base | oklch(1 0 0 / 10%)base | ||
| --input | gray-200base | oklch(1 0 0 / 15%)base | ||
| --ring | oklch(0.553 0.086 208.5) | oklch(0.72 0.11 205) | ||
| --chart-1 | teal-600 | teal-400 | ||
| --chart-2 | teal-300 | teal-200 | ||
| --chart-3 | cyan-600 | cyan-400 | ||
| --chart-4 | sky-400 | sky-400 | ||
| --chart-5 | emerald-400 | emerald-400 | ||
| --sidebar | gray-50base | gray-900base | ||
| --sidebar-foreground | gray-950base | gray-50base | ||
| --sidebar-primary | oklch(0.553 0.086 208.5) | oklch(0.72 0.11 205) | ||
| --sidebar-primary-foreground | gray-0 | gray-950 | ||
| --sidebar-accent | gray-100base | gray-800base | ||
| --sidebar-accent-foreground | gray-900base | gray-50base | ||
| --sidebar-border | gray-200base | oklch(1 0 0 / 10%)base | ||
| --sidebar-ring | oklch(0.553 0.086 208.5) | oklch(0.72 0.11 205) |
Mistral
Laranja flame com primary preto-sobre-laranja, espelhando o uso de marca da Mistral. As superficies herdam a base neutra nos dois modos.
--radius-base: 0.5rem · selector [data-theme='mistral']
| Light | Dark | Token | Valor (light) | Valor (dark) |
|---|---|---|---|---|
| --background | gray-50base | gray-950base | ||
| --foreground | gray-950base | gray-50base | ||
| --card | gray-0base | gray-900base | ||
| --card-foreground | gray-950base | gray-50base | ||
| --popover | gray-0base | gray-900base | ||
| --popover-foreground | gray-950base | gray-50base | ||
| --primary | orange-600 | orange-400 | ||
| --primary-foreground | gray-950 | gray-950 | ||
| --secondary | gray-100base | gray-800base | ||
| --secondary-foreground | gray-900base | gray-50base | ||
| --muted | gray-100base | gray-800base | ||
| --muted-foreground | gray-500base | gray-400base | ||
| --accent | orange-100 | orange-900 | ||
| --accent-foreground | orange-900 | orange-50 | ||
| --destructive | red-600base | red-400base | ||
| --destructive-foreground | gray-50base | gray-50base | ||
| --border | gray-200base | oklch(1 0 0 / 10%)base | ||
| --input | gray-200base | oklch(1 0 0 / 15%)base | ||
| --ring | orange-500 | orange-400 | ||
| --chart-1 | orange-500 | orange-400 | ||
| --chart-2 | orange-300 | orange-200 | ||
| --chart-3 | orange-700 | orange-600 | ||
| --chart-4 | amber-400 | amber-400 | ||
| --chart-5 | red-400 | red-400 | ||
| --sidebar | gray-50base | gray-900base | ||
| --sidebar-foreground | gray-950base | gray-50base | ||
| --sidebar-primary | orange-600 | orange-400 | ||
| --sidebar-primary-foreground | gray-950 | gray-950 | ||
| --sidebar-accent | gray-100base | gray-800base | ||
| --sidebar-accent-foreground | gray-900base | gray-50base | ||
| --sidebar-border | gray-200base | oklch(1 0 0 / 10%)base | ||
| --sidebar-ring | orange-500 | orange-400 |
Sobre os tokens de sidebar
Os --sidebar-* são uma família paralela que cobre a chrome
de navegação lateral. Eles existem porque sidebars são surfaces
muitas vezes pintadas distintas do background (mais escuras,
mais claras, contrastantes). Manter intenções dedicadas evita o
truque de "background com tint" que se quebra ao mudar de tema.
Sobre os tokens de chart
--chart-1 a --chart-5 são as cores de série categóricas
consumidas pelos componentes de chart. Todo tema redefine o
conjunto completo nos dois modos: o bloco dark precisa
re-declarar cada série porque o bloco light do tema vence o
seletor .dark da base em especificidade, então um override dark
faltante vazaria o valor light para o dark mode.
Editando ou adicionando temas
Temas são camadas de override sobre a camada semântica base em
packages/tokens/styles/theme.css. A receita curta:
-
Crie um novo arquivo em
packages/tokens/styles/themes/<id>.css. -
Defina os dois selectors:
:root[data-theme='<id>'] { /* overrides do light */ } :root[data-theme='<id>'].dark { /* overrides do dark */ } -
Sobrescreva apenas o que difere da base. Um tema de acento como o Mistral toca uma dúzia de tokens; um tema de superfície completa como o Claude remapeia quase tudo. O que o bloco light declarar, o bloco dark precisa re-declarar (veja a nota de chart acima), porque
:root[data-theme]vence.dark. -
Importe o arquivo no topo de
packages/tokens/styles/theme.css. -
Audite rodando o tema no workbench e checando contraste: pares primary/primary-foreground precisam passar WCAG AA para texto (4.5:1) e as séries de chart precisam de 3:1 sobre o background do tema.
Prefira primitivos. Referencie as rampas via var(--color-<token>) para
que um ajuste de primitivo cascateie em todos os temas. Os temas embarcados
só hardcodam OKLCH onde espelham uma superfície de produto sem primitivo
equivalente (e.g. o creme do Claude ou o grafite do Gemini). Se o seu valor
é reutilizável, adicione-o como primitivo.
Visão geral
Tokens semânticos traduzem primitivos em intenção. É aqui que o Gremorie suporta múltiplos temas e modo escuro sem que componentes saibam disso.
Visão geral
Cinco esquemas canônicos para visualização de dados — cada um para uma forma específica de dado, validados em fundamentação acadêmica e prática de DS de produto.