Color — Primitives

primitives/color.json

Raw color values. Never use these directly in components — always reference semantic color tokens instead.

Neutral
0
#ffffff
50
#f9fafb
100
#f3f4f6
200
#e5e7eb
300
#d1d5db
400
#9ca3af
500
#6b7280
600
#4b5563
700
#374151
800
#1f2937
900
#111827
950
#030712
1000
#000000
Gray
50
#efefef
100
#e6e6e6
200
#cccccc
300
#b3b3b3
400
#999999
500
#808080
600
#666666
700
#4d4d4d
800
#333333
900
#1a1a1a
Blue
50
#eff6ff
100
#dbeafe
200
#bfdbfe
300
#93c5fd
400
#60a5fa
500
#3b82f6
600
#2563eb
700
#1d4ed8
800
#1e40af
900
#063270
Green
50
#f0fdf4
100
#dcfce7
200
#C1EFD1
300
#8DE0A9
400
#4ade80
500
#22c55e
600
#16a34a
700
#148448
800
#086B39
900
#14532d
Yellow
50
#fffbeb
100
#fff8d6
200
#ffed99
300
#ffd94d
400
#ffd233
500
#ffc107
600
#F09C14
700
#DC800F
800
#B16400
900
#743E00
Orange
50
#fff7ed
100
#FBEBD8
200
#FFDABD
300
#FFBC85
400
#fb923c
500
#f97316
600
#ea580c
700
#C94500
800
#A72E05
900
#6F1E03
Red
50
#fef2f2
100
#fee2e2
200
#FFCACF
300
#F5A5B0
400
#f87171
500
#ef4444
600
#D9233B
700
#BB1637
800
#95020E
900
#6E0B13
Pink
50
#fdf2f8
100
#fce7f3
200
#fccfe8
300
#faa6c1
400
#f472b6
500
#ec4899
600
#db2777
700
#be185d
800
#9d174d
900
#831843
Magenta
50
#FFF3FB
100
#fce7f6
200
#f9c2ec
300
#f490d9
400
#ee5ec4
500
#e029a8
600
#c01a8c
700
#9a1270
800
#730d54
900
#4d0838
Purple
50
#faf5ff
100
#f3e8ff
200
#e9d5ff
300
#d8b4fe
400
#c084fc
500
#a855f7
600
#9333ea
700
#7e22ce
800
#541886
900
#3d115e
Mauve
50
#f6f3f5
100
#ece5ea
200
#ddd0d7
300
#c9b5bf
400
#a6808c
500
#8d6876
600
#6F5A7E
700
#5a5160
800
#433c4a
900
#2d2833
Sand
50
#faf7f5
100
#f5ede8
200
#ede0d8
300
#deccc3
400
#ccb7ae
500
#b89d92
600
#9e7f72
700
#7d6356
800
#5e4a40
900
#3d2f28
Slate
50
#f8fafc
100
#f1f5f9
200
#e2e8f0
300
#cbd5e1
400
#94a3b8
500
#64748b
600
#475569
700
#334155
800
#1e293b
900
#0f172a
Olive
50
#f6f7ee
100
#eef0dc
200
#e8ead8
300
#d0d4ae
400
#a8ad7e
500
#8a9057
600
#6e7344
700
#575c2e
800
#3f4220
900
#2a2d12
Teal
50
#f0fdfa
100
#ccfbf1
200
#99f6e4
300
#5eead4
400
#2dd4bf
500
#14b8a6
600
#0d9488
700
#0f766e
800
#115e59
900
#134e4a
Cyan
50
#ecfeff
100
#cffafe
200
#a5f3fc
300
#67e8f9
400
#22d3ee
500
#06b6d4
600
#0891b2
700
#0e7490
800
#155e75
900
#164e63

Color — Semantic

semantic/base.json

These are the tokens components consume. Override these in themes — never the primitives.

Surface
TokenRoleValue (light)Swatch
semantic.color.surface.defaultPage / app background#ffffff {color.neutral.0}
semantic.color.surface.subtleSidebar, secondary areas#faf7f5 {color.sand.50}
semantic.color.surface.raisedCards, panels#ffffff {color.neutral.0}
semantic.color.surface.overlayModals, drawers#ffffff {color.neutral.0}
semantic.color.surface.sunkenInset areas, code blocks#f5ede8 {color.sand.100}
semantic.color.surface.skeletonSkeleton elements#d1d5db {color.neutral.300}
Text
TokenRoleValue (light)Swatch
semantic.color.text.defaultBody text#1f2937 {color.neutral.800}
semantic.color.text.subtleCaptions, metadata#4b5563 {color.neutral.600}
semantic.color.text.disabledDisabled state#9ca3af {color.neutral.400}
semantic.color.text.inverseOn dark backgrounds#ffffff {color.neutral.0}
Aa
semantic.color.text.linkLink default#6F5A7E {color.mauve.600}
semantic.color.text.linkHoverLink hover#5a5160 {color.mauve.700}
Border
TokenRoleValue (light)Swatch
semantic.color.border.defaultStandard borders#ede0d8 {color.sand.200}
semantic.color.border.subtleHairline, dividers#f5ede8 {color.sand.100}
semantic.color.border.strongEmphasized borders#d1d5db {color.neutral.300}
semantic.color.border.focusFocus ring#9333ea {color.purple.600}
Interactive
TokenRoleValue (light)Swatch
semantic.color.interactive.primaryPrimary action#6F5A7E {color.mauve.600}
semantic.color.interactive.primaryHoverPrimary hover#5a5160 {color.mauve.700}
semantic.color.interactive.primaryActivePrimary pressed#433c4a {color.mauve.800}
semantic.color.interactive.primarySubtlePrimary tint bg#f6f3f5 {color.mauve.50}
semantic.color.interactive.actionTextText on primary button — white#ffffff {color.neutral.0}
Aa
semantic.color.interactive.secondaryFilled secondary button color#1f2937 {color.neutral.800}
semantic.color.interactive.secondaryHoverSecondary button hover — darkens#111827 {color.neutral.900}
semantic.color.interactive.secondaryActiveSecondary button press — darkest#030712 {color.neutral.950}
semantic.color.interactive.ghostHoverGhost / list item hover bg — transient#f5ede8 {color.sand.100}
semantic.color.interactive.ghostActiveGhost / list item pressed bg — transient#ede0d8 {color.sand.200}
semantic.color.interactive.navSelectedSelected nav/list item bg — dark, persistent#6F5A7E {color.mauve.600}
semantic.color.interactive.navSelectedTextText on selected item — white on dark bg#ffffff {color.neutral.0}
Aa
semantic.color.interactive.navSelectedHoverHover on already-selected item#5a5160 {color.mauve.700}
semantic.color.interactive.navUnselectedPersistent unselected bg — subtle warm tint#f5ede8 {color.sand.100}
semantic.color.interactive.dangerDanger button background#BB1637 {color.red.700}
semantic.color.interactive.dangerHoverDanger button background hover#95020E {color.red.800}
semantic.color.interactive.dangerActiveDanger button background active#6E0B13 {color.red.900}
Status
TokenRoleValue (light)Swatch
semantic.color.status.successPositive / confirmed#148448 {color.green.700}
semantic.color.status.successSubtleSuccess background tint#dcfce7 {color.green.100}
semantic.color.status.warningCaution#C94500 {color.orange.700}
semantic.color.status.warningSubtleWarning background tint#FBEBD8 {color.orange.100}
semantic.color.status.errorError / destructive#D9233B {color.red.600}
semantic.color.status.errorSubtleError background tint#fee2e2 {color.red.100}
semantic.color.status.infoInformational#9333ea {color.purple.600}
semantic.color.status.infoSubtleInfo background tint#f3e8ff {color.purple.100}

Shape Personality

semantic + themes

These 4 semantic tokens control the entire visual character of a theme. Override only these to switch between sharp, friendly, and elevated personalities.

Radius — Semantic
TokenRoleBase valueSharpElevatedVisual
⭐ semantic.radius.component Buttons, inputs, chips 8px (lg)0px (none)12px (xl)
⭐ semantic.radius.container Cards, panels, modals 12px (xl)0px (none)16px (2xl)
semantic.radius.interactive Interactive elements 8px (lg)0px (none)12px (xl)
semantic.radius.badge Tags, badges, chips 9999px2px9999px
⭐ semantic.radius.control Checkbox visual box 2px (xs) 0px (none) 2px (xs)
Shadow — Semantic
TokenRoleBaseSharpElevatedVisual
⭐ semantic.shadow.component Input / chip elevation xsnonesm
⭐ semantic.shadow.container Card / panel elevation smnonelg
semantic.shadow.floating Dropdowns, popovers mdnonexl
semantic.shadow.overlay Modals, dialogs xlnone2xl
⭐ semantic.shadow.focus Focus ring 0 0 0 3px rgba(147,51,234,1) 0 0 0 2px rgba(147,51,234,1) 0 0 0 4px rgba(147,51,234,0.35)

Typography

primitives/typography.json
Type Scale
TokenValueSample
font.size.2xs10pxThe quick brown fox
font.size.xs12pxThe quick brown fox
font.size.sm14pxThe quick brown fox
font.size.md ★ body16pxThe quick brown fox
font.size.lg18pxThe quick brown fox
font.size.xl20pxThe quick brown fox
font.size.2xl24pxThe quick brown fox
font.size.3xl30pxThe quick brown fox
font.size.4xl36pxHeading
font.size.5xl48pxDisplay
font.size.6xl60pxHero
Font Weights
TokenValueSample
font.weight.thin100The quick brown fox
font.weight.extraLight200The quick brown fox
font.weight.light300The quick brown fox
font.weight.regular400The quick brown fox
font.weight.medium500The quick brown fox
font.weight.semibold600The quick brown fox
font.weight.bold700The quick brown fox
⭐ Semantic Typography — Theme override points
TokenRoleBase value
⭐ semantic.typography.family-bodyBody / UI font — swap for personalityGeologica
⭐ semantic.typography.family-headingHeading font — swap for personalityGeologica
semantic.typography.family-codeCode blocksJetBrains Mono

Text Styles — Composite

semantic/base.json → textStyle

Composite styles combining family, size, weight, line-height and letter-spacing. Components consume these directly. Each maps to a Figma Text Style.

Display & Headings
TokenSizeWeightSample
textStyle.display-2xl72pxboldDisplay 2XL
textStyle.display-xl60pxboldDisplay XL
textStyle.heading-xl36pxboldHeading XL
textStyle.heading-lg30pxboldHeading LG
textStyle.heading-md24pxsemiboldHeading MD
textStyle.heading-sm20pxsemiboldHeading SM
textStyle.heading-xs18pxsemiboldHeading XS
Body
TokenSizeWeightSample
textStyle.body-lg18pxlightThe quick brown fox jumps over the lazy dog
textStyle.body-md16pxlightThe quick brown fox jumps over the lazy dog
textStyle.body-sm14pxregularThe quick brown fox jumps over the lazy dog
Labels, Captions & Utility
TokenSizeWeightSample
textStyle.label-lg16pxmediumButton Label
textStyle.label-md14pxmediumInput Label
textStyle.label-sm12pxmediumBadge Tag Chip
textStyle.caption12pxlightImage caption or helper text
textStyle.footnote10pxlightLegal text, footnotes, fine print
textStyle.overline12pxsemiboldSECTION LABEL
textStyle.code14pxregularconst token = "value"

Spacing

primitives/spacing.json

4px base unit. All values are multiples of 4.

TokenValueVisual
space.0.52px
space.14px
space.28px
space.312px
space.416px
space.520px
space.624px
space.832px
space.1040px
space.1248px
space.1664px
space.2080px
space.2496px
space.32128px

Radius & Shadow — Primitives

primitives/shape.json

Raw scale values. Components consume these via semantic tokens, not directly.

Border Radius Scale
TokenValueVisual
radius.none0px
radius.xs2px
radius.sm4px
radius.md6px
radius.lg8px
radius.xl12px
radius.2xl16px
radius.3xl24px
radius.full9999px
Shadow Scale
TokenCSS ValueRoleVisual
shadow.nonenoneNo elevation
shadow.xs0 1px 2px 0 rgba(0,0,0,0.05)Inputs, chips
shadow.sm0 1px 3px 0 rgba(0,0,0,0.08),
0 1px 2px -1px rgba(0,0,0,0.05)
Default component elevation
shadow.md0 4px 6px -1px rgba(0,0,0,0.08),
0 2px 4px -2px rgba(0,0,0,0.05)
Cards, dropdowns
shadow.lg0 10px 15px -3px rgba(0,0,0,0.08),
0 4px 6px -4px rgba(0,0,0,0.05)
Floating panels, popovers
shadow.xl0 20px 25px -5px rgba(0,0,0,0.1),
0 8px 10px -6px rgba(0,0,0,0.05)
Modals, dialogs
shadow.2xl0 25px 50px -12px rgba(0,0,0,0.18)Drawers, full-screen overlays
shadow.innerinset 0 2px 4px 0 rgba(0,0,0,0.05)Inset fields, pressed states
Border Width
TokenValueVisual
border.width.none0px
border.width.thin1px
border.width.medium2px
border.width.thick4px

Motion

primitives/shape.json → duration + easing
Duration
TokenValueRole
duration.fast100msMicro-interactions, tooltips
duration.normal200msStandard transitions
duration.slow300msPanels, modals entering
duration.slower500msLarger layout shifts
duration.lazy700msPage-level animations
Easing — hover any track to preview
TokenValueRolePreview
easing.default cubic-bezier(0.4,0,0.2,1) General purpose
easing.in cubic-bezier(0.4,0,1,1) Exits
easing.out cubic-bezier(0,0,0.2,1) Entrances
easing.spring cubic-bezier(0.34,1.56,0.64,1) Springy, playful

Grid & Layout

primitives/grid.json
Column min-widths (CSS Grid minmax)
TokenValueRole
grid.column.min-xs120pxDense grids, icon lists
grid.column.min-sm160pxCompact cards, small tiles
grid.column.min-md240pxStandard cards, form fields
grid.column.min-lg320pxWide cards, content columns
grid.column.min-xl400pxLarge content blocks
grid.column.sidebar260pxSidebar in named-area layouts
grid.column.panel360pxDetail panel, drawer
Breakpoints — min-width (mobile-first)
TokenValueRole
breakpoint.xs0pxMobile — default, no media query needed
breakpoint.sm480pxLarge mobile / small tablet
breakpoint.md768pxTablet
breakpoint.lg1024pxSmall desktop / landscape tablet
breakpoint.xl1280pxDesktop
breakpoint.2xl1536pxWide desktop
Gutters & Margins per breakpoint
BreakpointMin widthGutterOuter margin
xs0px16px16px
sm480px16px24px
md768px24px32px
lg1024px32px48px
xl1280px32px64px
2xl1536px40px80px
Max widths
TokenValueRole
grid.maxWidth.content720pxProse / article body
grid.maxWidth.layout1280pxStandard page layout
grid.maxWidth.wide1536pxWide / dashboard layouts

Theme Overview

6 built-in combinations

Each theme is a combination of a color mode and a style personality. Community themes override only the semantic tokens.

Theme Color mode Shape personality Radius component Shadow component Surface / Interactive
light LightBase (friendly) 8pxxs
dark DarkBase (friendly) 8pxxs (dark)
light-sharp LightSharp / flat 0pxnone
dark-sharp DarkSharp / flat 0pxnone
light-elevated LightElevated / soft 12pxsm
dark-elevated DarkElevated / soft 12pxsm (dark)

Light Theme

semantic/base.json

All semantic color tokens resolved for the light theme. Components consume these values via CSS custom properties.

Surface
TokenRoleValueSwatch
semantic.color.surface.defaultPage background#ffffff {color.neutral.0}
semantic.color.surface.subtleDashboard canvas, sidebar#faf7f5 {color.sand.50}
semantic.color.surface.raisedCards, panels#ffffff {color.neutral.0}
semantic.color.surface.overlayModals, drawers#ffffff {color.neutral.0}
semantic.color.surface.sunkenInset areas, code blocks#f5ede8 {color.sand.100}
semantic.color.surface.skeletonSkeleton elements#d1d5db {color.neutral.300}
Text
TokenRoleValueSwatch
semantic.color.text.defaultBody text#1f2937 {color.neutral.800}
semantic.color.text.subtleCaptions, metadata#4b5563 {color.neutral.600}
semantic.color.text.disabledDisabled — WCAG exempt#9ca3af {color.neutral.400}
semantic.color.text.inverseOn dark backgrounds#ffffff {color.neutral.0}
Aa
semantic.color.text.linkLink#6F5A7E {color.mauve.600}
semantic.color.text.linkHoverLink hover#5a5160 {color.mauve.700}
Border
TokenRoleValueSwatch
semantic.color.border.defaultStandard borders#ede0d8 {color.sand.200}
semantic.color.border.subtleHairline, dividers#f5ede8 {color.sand.100}
semantic.color.border.strongEmphasized borders#d1d5db {color.neutral.300}
semantic.color.border.focusFocus ring#9333ea {color.purple.600}
Interactive
TokenRoleValueSwatch
semantic.color.interactive.primaryPrimary button fill#6F5A7E {color.mauve.600}
semantic.color.interactive.primaryHoverDarkens on hover#5a5160 {color.mauve.700}
semantic.color.interactive.primaryActiveDarkens on press#433c4a {color.mauve.800}
semantic.color.interactive.primarySubtleSelected/active bg#f6f3f5 {color.mauve.50}
semantic.color.interactive.actionTextText on primary button — white#ffffff {color.neutral.0}
Aa
semantic.color.interactive.secondaryFilled secondary button#1f2937 {color.neutral.800}
semantic.color.interactive.secondaryHoverDarkens on hover#111827 {color.neutral.900}
semantic.color.interactive.secondaryActiveDarkens on press#030712 {color.neutral.950}
semantic.color.interactive.ghostHoverGhost / list item hover bg — transient#f5ede8 {color.sand.100}
semantic.color.interactive.ghostActiveGhost / list item pressed bg — transient#ede0d8 {color.sand.200}
semantic.color.interactive.navSelectedSelected nav/list item bg — dark, persistent#6F5A7E {color.mauve.600}
semantic.color.interactive.navSelectedTextText on selected item — white on dark bg#ffffff {color.neutral.0}
Aa
semantic.color.interactive.navSelectedHoverHover on already-selected item#5a5160 {color.mauve.700}
semantic.color.interactive.navUnselectedPersistent unselected bg — subtle warm tint#f5ede8 {color.sand.100}
semantic.color.interactive.dangerDanger button background#BB1637 {color.red.700}
semantic.color.interactive.dangerHoverDanger button background hover#95020E {color.red.800}
semantic.color.interactive.dangerActiveDanger button background active#6E0B13 {color.red.900}
Status
TokenRoleValueSwatch
semantic.color.status.successPositive#148448 {color.green.700}
semantic.color.status.successSubtleSuccess background tint#dcfce7 {color.green.100}
semantic.color.status.warningCaution#c94500 {color.orange.700}
semantic.color.status.warningSubtleWarning background tint#fbebd8 {color.orange.100}
semantic.color.status.errorError#d9233b {color.red.600}
semantic.color.status.errorSubtleError background tint#fee2e2 {color.red.100}
semantic.color.status.infoInformational#9333ea {color.purple.600}
semantic.color.status.infoSubtleInfo background tint#f3e8ff {color.purple.100}

Dark Theme

themes/dark.json

Semantic overrides for dark mode. Interactive primary uses mauve.400 with dark text (8.43 AAA). Status colors shifted to 400-step for AAA on dark surfaces. Status subtle backgrounds are 15% tinted hex values.

Surface
TokenRoleValueSwatch
semantic.color.surface.defaultPage background#030712 {color.neutral.950}
semantic.color.surface.subtleSidebar, secondary areas#111827 {color.neutral.900}
semantic.color.surface.raisedCards, panels#1f2937 {color.neutral.800}
semantic.color.surface.overlayModals, drawers#1f2937 {color.neutral.800}
semantic.color.surface.sunkenInset areas, code blocks#000000 {color.neutral.1000}
semantic.color.surface.skeletonSkeleton elements#4b5563 {color.neutral.600}
Text
TokenRoleValueSwatch
semantic.color.text.defaultBody text#f9fafb {color.neutral.50}
semantic.color.text.subtleCaptions, metadata#9ca3af {color.neutral.400}
semantic.color.text.disabledDisabled — WCAG exempt#4b5563 {color.neutral.600}
semantic.color.text.inverseOn light surfaces in dark theme#111827 {color.neutral.900}
Aa
semantic.color.text.linkLink#a6808c {color.mauve.400}
semantic.color.text.linkHoverLink hover#c9b5bf {color.mauve.300}
Border
TokenRoleValueSwatch
semantic.color.border.defaultStandard — 3:1+ on dark#4b5563 {color.neutral.600}
semantic.color.border.subtleHairline, dividers#374151 {color.neutral.700}
semantic.color.border.strongEmphasized borders#6b7280 {color.neutral.500}
semantic.color.border.focusFocus ring#a855f7 {color.purple.500}
Interactive
TokenRoleValueSwatch
semantic.color.interactive.primaryPrimary button fill#a6808c {color.mauve.400}
semantic.color.interactive.primaryHoverLightens on hover#c9b5bf {color.mauve.300}
semantic.color.interactive.primaryActiveDarkens on press#8d6876 {color.mauve.500}
semantic.color.interactive.primarySubtleSelected/active bg#1f2937 {color.neutral.800}
semantic.color.interactive.actionTextDark text on light mauve#030712 {color.neutral.950}
Aa
semantic.color.interactive.secondaryFilled secondary button (light fill)#e5e7eb {color.neutral.200}
semantic.color.interactive.secondaryHoverLightens on hover#f3f4f6 {color.neutral.100}
semantic.color.interactive.secondaryActiveSlightly darker on press#d1d5db {color.neutral.300}
semantic.color.interactive.ghostHoverGhost / list item hover bg — transient#1f2937 {color.neutral.800}
semantic.color.interactive.ghostActiveGhost / list item pressed bg — transient#374151 {color.neutral.700}
semantic.color.interactive.navSelectedSelected nav/list item — brand mauve, persistent#a6808c {color.mauve.400}
semantic.color.interactive.navSelectedTextText on selected item — white on mauve, 5.43 AA#ffffff {color.neutral.0}
Aa
semantic.color.interactive.navSelectedHoverHover on already-selected item#c9b5bf {color.mauve.300}
semantic.color.interactive.navUnselectedPersistent unselected bg — subtle dark tint#1f2937 {color.neutral.800}
semantic.color.interactive.dangerDanger button background#f87171 {color.red.400}
semantic.color.interactive.dangerHoverDanger button background hover#F5A5B0 {color.red.300}
semantic.color.interactive.dangerActiveDanger button background active#ef4444 {color.red.500}
Status — 400-step colors, 15%-tinted subtle backgrounds
TokenRoleValueSwatch
semantic.color.status.successPositive#4ade80 {color.green.400}
semantic.color.status.successSubtleSuccess bg — green.400 @ 15% opacityrgba(74,222,128,0.15)
semantic.color.status.warningCaution#fb923c {color.orange.400}
semantic.color.status.warningSubtleWarning bg — orange.400 @ 15% opacityrgba(251,146,60,0.15)
semantic.color.status.errorError#f87171 {color.red.400}
semantic.color.status.errorSubtleError bg — red.400 @ 15% opacityrgba(248,113,113,0.15)
semantic.color.status.infoInfo#c084fc {color.purple.400}
semantic.color.status.infoSubtleInfo bg — purple.400 @ 15% opacityrgba(192,132,252,0.15)

Dataviz Colors

primitives/color.json → dataviz

Categorical series colors and semantic chart indicators. Series colors are pulled from existing palette ramps at their most perceptually distinct steps. Never use series colors to convey positive/negative meaning — use the indicator tokens for that.

Categorical Series — 10 colors
TokenValueRoleSwatch
dataviz.blue#3b82f6Series 1
dataviz.teal#14b8a6Series 2
dataviz.purple#a855f7Series 3
dataviz.orange#f97316Series 4
dataviz.pink#ec4899Series 5
dataviz.yellow#f5b000Series 6
dataviz.cyan#06b6d4Series 7
dataviz.green#22c55eSeries 8
dataviz.magenta#e029a8Series 9
dataviz.sand#b89d92Series 10
Series — visual strip
1
2
3
4
5
6
7
8
9
10

Tip: run through a CVD simulator before finalizing chart components for accessibility.

Semantic Indicators
TokenValueRoleSwatch
dataviz.positive#16a34aPositive trend, growth, success
dataviz.negative#dc2626Negative trend, decline, loss
dataviz.neutral#6b7280Flat / no change
dataviz.highlight#a855f7Selected or hovered series