FoundationsColor

Color

GDS organizes color so products stay consistent in light and dark mode without hard-coded hex values.

Three layers

You'll almost always work with MUI palette slots for components and semantic tokens for custom surfaces. Primitives stay behind the scenes.

01

Primitives

Raw hex values like gray700 and blue500. Reserved for building tokens — almost never used in product UI.

Token authors only
02

Semantic tokens

Meaningful names such as surface.default and elements.default that point at primitives and flip with theme mode.

Custom surfaces & text
03

MUI palette slots

Standard slots (primary, success, error, …) wired to GDS. Use these in sx and component color props.

Day-to-day usage

Semantic palette

The six MUI palette slots. Each provides main, dark (hover/active), and light (backgrounds and softer states). Values follow the current theme mode.

primary

palette.primary.main

Light#2196F3
Main#1976D2
Dark#1565C0

secondary

palette.secondary.main

Light#BDBDBD
Main#757575
Dark#2F2F2F

success

palette.success.main

Light#81C784
Main#4CAF50
Dark#388E3C

warning

palette.warning.main

Light#FFB74D
Main#FF9800
Dark#F57C00

error

palette.error.main

Light#F44336
Main#D32F2F
Dark#C62828

info

palette.info.main

Light#64B5F6
Main#2196F3
Dark#1976D2
SlotUse it forLight mainDark main
primaryDominant action colorblue700 · #1976D2blue200 · #90CAF9
secondarySupporting / contrast actionsgray600 · #757575gray600 · #757575
successConfirmations, saved statesgreen500 · #4CAF50green300 · #81C784
warningRisky-but-recoverable statesorange500 · #FF9800orange100 · #FFE0B2
errorDestructive actions, validationred700 · #D32F2Fred500 · #F44336
infoNeutral informational messagingblue500 · #2196F3blue200 · #90CAF9

Surfaces & elements

Default, secondary, and low-contrast tokens flip with theme mode. Use low-contrast for subtle chrome — not for critical text.

Default

Default surface

Base page background. Wired to both background.default and background.paper.

#FFFFFF

semantic.surface.default
Secondary

Secondary surface

Supporting surface for custom layouts. Read from theme.gds — not an MUI palette slot.

#9E9E9E

semantic.surface.secondary
Low contrast

Low contrast surface

Subtle fills, dividers, and quiet chrome that should stay behind primary content.

#E0E0E0

semantic.surface.lowcontrast

Default

Aa

semantic.elements.default

#000000

Primary text and icons. Maps to text.primary.

Secondary

Aa

semantic.elements.secondary

#757575

Supporting copy and quieter UI. Maps to text.secondary.

Low contrast

Aa

semantic.elements.lowcontrast

#EEEEEE

Decorative lines, placeholders, and low-emphasis marks.

TokenMUI slotLightDark
semantic.surface.defaultbackground.default / paperwhite · #FFFFFFgray900 · #121212
semantic.surface.secondarytheme.gds onlygray500 · #9E9E9Egray300 · #E0E0E0
semantic.surface.lowcontrasttheme.gds onlygray300 · #E0E0E0gray700 · #616161
semantic.elements.defaulttext.primaryblack · #000000white · #FFFFFF
semantic.elements.secondarytext.secondarygray600 · #757575gray600 · #757575
semantic.elements.lowcontrasttheme.gds onlygray200 · #EEEEEEgray700 @ 30%

Using colors in code

In sx props (most common)

Use MUI palette slot names. They resolve to GDS values automatically.

import { GdsBox } from "@granicus/gds-core/GdsBox";
 
<GdsBox sx={{ bgcolor: "primary.main", color: "primary.contrastText", p: 2 }}>
  Primary surface
</GdsBox>

In component color props

Most GDS components accept color="primary" (or any palette slot) directly:

<GdsButton color="error" variant="contained">Delete</GdsButton>
<GdsCheckbox color="success" defaultChecked />

From the theme (when sx isn’t enough)

Reach into theme.gds only when you need a semantic value that isn’t covered by the MUI palette:

import { useTheme } from "@mui/material/styles";
 
function FeedbackBanner() {
  const theme = useTheme();
  return (
    <div
      style={{
        backgroundColor: theme.gds.semantic.feedbackBackground.info,
        color: theme.gds.semantic.feedbackElement.info,
      }}
    >
      Heads up!
    </div>
  );
}

Dark mode

GDS dark mode is fully wired through GDSThemeProvider. Wrap your app with <GDSThemeProvider mode="dark"> and every semantic token, MUI palette slot, and component picks up the dark values shown above.

import { GDSThemeProvider } from "@granicus/gds-core/GDSThemeProvider";
 
<GDSThemeProvider mode="dark">
  <App />
</GDSThemeProvider>