Skip to main content
Gremorie

Colors

The intent-to-value mapping for the six Gremorie themes, in light and dark mode.

Semantic tokens are intents: primary, foreground, border. Each theme fills those intents with different values, and each mode (light / dark) brings its own mapping. This page is the truth table for the six bundled themes: Default, Claude, ChatGPT, Gemini, Perplexity and Mistral.

How to read the tables

  • The Light and Dark columns render the exact declared value as a chip over that theme's own light or dark background, so both are faithful no matter which mode you are reading in.
  • The Value columns show what the theme declares: a primitive name (consumed via var(--color-<token>)) or, where the theme matches a product surface that has no primitive equivalent, a literal OKLCH value.
  • A base badge means the theme does not override that token; it inherits the value from the base layer in theme.css. That inheritance is the shipped behavior, not an omission.

If you are auditing a component that looks "wrong" in some theme, start here. Comparing the intent (e.g. --primary) with the value it resolves to in each theme tells you whether the inconsistency comes from the component chrome or from the theme mapping.

Default

The base semantic layer itself, on the neutralized gray ramp. Conservative and brand-free; every other theme is an override layer on top of it.

--radius-base: 0.625rem · selector :root

LightDarkTokenValue (light)Value (dark)
--backgroundgray-50basegray-950base
--foregroundgray-950basegray-50base
--cardgray-0basegray-900base
--card-foregroundgray-950basegray-50base
--popovergray-0basegray-900base
--popover-foregroundgray-950basegray-50base
--primarygray-900basegray-100base
--primary-foregroundgray-50basegray-900base
--secondarygray-100basegray-800base
--secondary-foregroundgray-900basegray-50base
--mutedgray-100basegray-800base
--muted-foregroundgray-500basegray-400base
--accentgray-100basegray-800base
--accent-foregroundgray-900basegray-50base
--destructivered-600basered-400base
--destructive-foregroundgray-50basegray-50base
--bordergray-200baseoklch(1 0 0 / 10%)base
--inputgray-200baseoklch(1 0 0 / 15%)base
--ringgray-400basegray-500base
--chart-1oklch(0.646 0.222 41.116)baseoklch(0.488 0.243 264.376)base
--chart-2oklch(0.6 0.118 184.704)baseoklch(0.696 0.17 162.48)base
--chart-3oklch(0.398 0.07 227.392)baseoklch(0.769 0.188 70.08)base
--chart-4oklch(0.828 0.189 84.429)baseoklch(0.627 0.265 303.9)base
--chart-5oklch(0.769 0.188 70.08)baseoklch(0.645 0.246 16.439)base
--sidebargray-50basegray-900base
--sidebar-foregroundgray-950basegray-50base
--sidebar-primarygray-900basegray-100base
--sidebar-primary-foregroundgray-50basegray-900base
--sidebar-accentgray-100basegray-800base
--sidebar-accent-foregroundgray-900basegray-50base
--sidebar-bordergray-200baseoklch(1 0 0 / 10%)base
--sidebar-ringgray-400basegray-500base

Claude

Warm clay (coral terracotta) on cream surfaces, taupe support, serif display. Dark mode sits on the warm charcoal of the real product.

--radius-base: 0.5rem · selector [data-theme='claude']

LightDarkTokenValue (light)Value (dark)
--backgroundoklch(0.965 0.011 92)oklch(0.235 0.006 100)
--foregroundgray-950gray-50
--cardoklch(0.985 0.008 92)oklch(0.268 0.005 100)
--card-foregroundgray-950gray-50
--popoveroklch(0.985 0.008 92)oklch(0.268 0.005 100)
--popover-foregroundgray-950gray-50
--primaryclay-500clay-400
--primary-foregroundgray-50gray-950
--secondaryoklch(0.95 0.012 80)oklch(0.28 0.012 58)
--secondary-foregroundclay-900gray-50
--mutedoklch(0.95 0.012 80)oklch(0.28 0.012 58)
--muted-foregroundtaupe-600taupe-300
--accentclay-100clay-900
--accent-foregroundclay-900clay-50
--destructivered-600basered-400base
--destructive-foregroundgray-50basegray-50base
--borderoklch(0.9 0.014 78)oklch(1 0 0 / 10%)
--inputoklch(0.9 0.014 78)oklch(1 0 0 / 15%)
--ringclay-500clay-400
--chart-1clay-500clay-400
--chart-2clay-300clay-200
--chart-3clay-700clay-600
--chart-4taupe-400taupe-400
--chart-5amber-400amber-400
--sidebaroklch(0.97 0.01 84)oklch(0.24 0.012 60)
--sidebar-foregroundgray-950gray-50
--sidebar-primaryclay-600clay-400
--sidebar-primary-foregroundgray-50gray-950
--sidebar-accentclay-100oklch(0.28 0.012 58)
--sidebar-accent-foregroundclay-900gray-50
--sidebar-borderoklch(0.9 0.014 78)oklch(1 0 0 / 10%)
--sidebar-ringclay-500clay-400

ChatGPT

Emerald accent on a flat, low-shadow surface. Dark mode uses the flat graphite of the real product; surfaces otherwise inherit the neutral base.

--radius-base: 0.75rem · selector [data-theme='chatgpt']

LightDarkTokenValue (light)Value (dark)
--backgroundgray-50baseoklch(0.248 0 0)
--foregroundgray-950basegray-50base
--cardgray-0baseoklch(0.278 0 0)
--card-foregroundgray-950basegray-50base
--popovergray-0baseoklch(0.278 0 0)
--popover-foregroundgray-950basegray-50base
--primaryemerald-700emerald-400
--primary-foregroundgray-50gray-950
--secondarygray-100basegray-800base
--secondary-foregroundgray-900basegray-50base
--mutedgray-100basegray-800base
--muted-foregroundgray-500basegray-400base
--accentemerald-100emerald-900
--accent-foregroundemerald-900emerald-50
--destructivered-600basered-400base
--destructive-foregroundgray-50basegray-50base
--bordergray-200baseoklch(1 0 0 / 10%)base
--inputgray-200baseoklch(1 0 0 / 15%)base
--ringemerald-500emerald-400
--chart-1emerald-500emerald-400
--chart-2emerald-300emerald-200
--chart-3teal-600teal-400
--chart-4green-400green-400
--chart-5cyan-400cyan-400
--sidebargray-50basegray-900base
--sidebar-foregroundgray-950basegray-50base
--sidebar-primaryemerald-700emerald-400
--sidebar-primary-foregroundgray-50gray-950
--sidebar-accentgray-100basegray-800base
--sidebar-accent-foregroundgray-900basegray-50base
--sidebar-bordergray-200baseoklch(1 0 0 / 10%)base
--sidebar-ringemerald-500emerald-400

Gemini

Google blue with a blue-to-purple chart ramp and the roundest radius of the set. Dark mode sits on the cool graphite of the real product.

--radius-base: 1rem · selector [data-theme='gemini']

LightDarkTokenValue (light)Value (dark)
--backgroundgray-50baseoklch(0.239 0.002 248)
--foregroundgray-950basegray-50base
--cardgray-0baseoklch(0.274 0.002 248)
--card-foregroundgray-950basegray-50base
--popovergray-0baseoklch(0.274 0.002 248)
--popover-foregroundgray-950basegray-50base
--primaryoklch(0.55 0.19 258)oklch(0.75 0.11 258)
--primary-foregroundgray-50gray-950
--secondarygray-100basegray-800base
--secondary-foregroundgray-900basegray-50base
--mutedgray-100basegray-800base
--muted-foregroundgray-500basegray-400base
--accentindigo-100indigo-900
--accent-foregroundindigo-900indigo-50
--destructivered-600basered-400base
--destructive-foregroundgray-50basegray-50base
--bordergray-200baseoklch(1 0 0 / 10%)base
--inputgray-200baseoklch(1 0 0 / 15%)base
--ringoklch(0.63 0.18 260)oklch(0.75 0.11 258)
--chart-1oklch(0.63 0.18 260)oklch(0.75 0.11 258)
--chart-2oklch(0.78 0.11 258)oklch(0.85 0.07 255)
--chart-3oklch(0.629 0.136 304)oklch(0.72 0.12 304)
--chart-4oklch(0.78 0.09 304)oklch(0.84 0.06 300)
--chart-5oklch(0.53 0.2 276)oklch(0.68 0.14 276)
--sidebargray-50basegray-900base
--sidebar-foregroundgray-950basegray-50base
--sidebar-primaryoklch(0.55 0.19 258)oklch(0.75 0.11 258)
--sidebar-primary-foregroundgray-50gray-950
--sidebar-accentgray-100basegray-800base
--sidebar-accent-foregroundgray-900basegray-50base
--sidebar-bordergray-200baseoklch(1 0 0 / 10%)base
--sidebar-ringoklch(0.63 0.18 260)oklch(0.75 0.11 258)

Perplexity

True turquoise on offblack, sober and tight, with the smallest radius of the set. The light primary is the brand turquoise #20808D.

--radius-base: 0.375rem · selector [data-theme='perplexity']

LightDarkTokenValue (light)Value (dark)
--backgroundgray-50baseoklch(0.192 0.02 195.6)
--foregroundgray-950basegray-50base
--cardgray-0baseoklch(0.225 0.018 196)
--card-foregroundgray-950basegray-50base
--popovergray-0baseoklch(0.225 0.018 196)
--popover-foregroundgray-950basegray-50base
--primaryoklch(0.553 0.086 208.5)oklch(0.72 0.11 205)
--primary-foregroundgray-0gray-950
--secondarygray-100basegray-800base
--secondary-foregroundgray-900basegray-50base
--mutedgray-100basegray-800base
--muted-foregroundgray-500basegray-400base
--accentteal-100teal-900
--accent-foregroundteal-900teal-50
--destructivered-600basered-400base
--destructive-foregroundgray-50basegray-50base
--bordergray-200baseoklch(1 0 0 / 10%)base
--inputgray-200baseoklch(1 0 0 / 15%)base
--ringoklch(0.553 0.086 208.5)oklch(0.72 0.11 205)
--chart-1teal-600teal-400
--chart-2teal-300teal-200
--chart-3cyan-600cyan-400
--chart-4sky-400sky-400
--chart-5emerald-400emerald-400
--sidebargray-50basegray-900base
--sidebar-foregroundgray-950basegray-50base
--sidebar-primaryoklch(0.553 0.086 208.5)oklch(0.72 0.11 205)
--sidebar-primary-foregroundgray-0gray-950
--sidebar-accentgray-100basegray-800base
--sidebar-accent-foregroundgray-900basegray-50base
--sidebar-bordergray-200baseoklch(1 0 0 / 10%)base
--sidebar-ringoklch(0.553 0.086 208.5)oklch(0.72 0.11 205)

Mistral

Flame orange with a black-on-orange primary, matching Mistral brand usage. Surfaces inherit the neutral base in both modes.

--radius-base: 0.5rem · selector [data-theme='mistral']

LightDarkTokenValue (light)Value (dark)
--backgroundgray-50basegray-950base
--foregroundgray-950basegray-50base
--cardgray-0basegray-900base
--card-foregroundgray-950basegray-50base
--popovergray-0basegray-900base
--popover-foregroundgray-950basegray-50base
--primaryorange-600orange-400
--primary-foregroundgray-950gray-950
--secondarygray-100basegray-800base
--secondary-foregroundgray-900basegray-50base
--mutedgray-100basegray-800base
--muted-foregroundgray-500basegray-400base
--accentorange-100orange-900
--accent-foregroundorange-900orange-50
--destructivered-600basered-400base
--destructive-foregroundgray-50basegray-50base
--bordergray-200baseoklch(1 0 0 / 10%)base
--inputgray-200baseoklch(1 0 0 / 15%)base
--ringorange-500orange-400
--chart-1orange-500orange-400
--chart-2orange-300orange-200
--chart-3orange-700orange-600
--chart-4amber-400amber-400
--chart-5red-400red-400
--sidebargray-50basegray-900base
--sidebar-foregroundgray-950basegray-50base
--sidebar-primaryorange-600orange-400
--sidebar-primary-foregroundgray-950gray-950
--sidebar-accentgray-100basegray-800base
--sidebar-accent-foregroundgray-900basegray-50base
--sidebar-bordergray-200baseoklch(1 0 0 / 10%)base
--sidebar-ringorange-500orange-400

About the sidebar tokens

The --sidebar-* tokens are a parallel family covering the side navigation chrome. They exist because sidebars are surfaces often painted differently from background (darker, lighter, contrasting). Keeping dedicated intents avoids the "tinted background" trick that breaks when the theme changes.

About the chart tokens

--chart-1 through --chart-5 are the categorical series colors consumed by the chart components. Every theme redefines the full set in both modes: the dark block must re-declare every series because the themed light block outranks the base .dark selector, so a missing dark override would leak the light value into dark mode.

Editing or adding themes

Themes are override layers on top of the base semantic layer in packages/tokens/styles/theme.css. The short recipe:

  1. Create a new file at packages/tokens/styles/themes/<id>.css.

  2. Define the two selectors:

    :root[data-theme='<id>'] {
      /* light overrides */
    }
    :root[data-theme='<id>'].dark {
      /* dark overrides */
    }
  3. Override only what differs from the base. An accent theme like Mistral touches a dozen tokens; a full-surface theme like Claude remaps almost everything. Whatever the light block declares, the dark block must re-declare (see the chart note above), because :root[data-theme] outranks .dark.

  4. Import the file at the top of packages/tokens/styles/theme.css.

  5. Audit by running the theme in the workbench and checking contrast: primary/primary-foreground pairs must clear WCAG AA for text (4.5:1) and chart series must clear 3:1 on the theme background.

Reach for primitives first. Reference the ramps via var(--color-<token>) so a primitive edit cascades into every theme. The shipped themes hardcode OKLCH only where they match a product surface that has no primitive equivalent (e.g. the Claude cream background or the Gemini graphite). If your value is reusable, add it as a primitive instead.

On this page