foundations Color Color in Momentum is delivered as tokens, not raw values. A component never references a hex code or a primitive swatch directly β€” it references a semantic theme token whose value is resolved per theme. This is what lets a single build render correctly in light, dark, and high-contrast modes and stay accessible. This topic explains how the color system is organized so you can find the right token by its name. For how those tokens change between modes, see Theming. For the glass aesthetic and its material/blur/overlay tokens, see Glass. Principles
  • Vibrant β€” color expresses energy and synergy through uplifting shades and dynamic gradients.
  • Consistent β€” the system produces a uniform visual appearance across diverse products and platforms.
  • Accessible β€” pairings target an adequate contrast ratio and adhere to WCAG wherever feasible. Any custom foreground/background pairing must be verified.
The token tiers Color tokens exist at two source levels. Consume the theme tier; never reach past it to a primitive.
TierNamespaceExampleConsume directly?
Primitivecolor.core.*, color.decorative.*color.core.blue.70No β€” internal palette
Semantic (theme)color.theme.*color.theme.text.primary.normalYes
Primitives are the raw palette. Semantic theme tokens map intent onto those primitives and are the only tier that flips between themes. If you hardcode a primitive (or a hex value) in a component, theming and contrast break. At build time each semantic token is compiled to a CSS custom property that components consume β€” color.theme.text.primary.normal becomes var(--mds-color-theme-text-primary-normal). Those custom properties are what a theme swaps at runtime (see Theming). How a theme token is named
color.theme.<usage>.<variant>.<state>
  • usage β€” where the color is applied (text, background, button, outline…).
  • variant β€” which treatment: prominence (primary/secondary/ tertiary), sentiment (error/success/warning/accent), an action (join/cancel), or a named accent (cobalt, purple…).
  • state β€” the interaction state: normal (rest), hover, pressed, active (selected/on), disabled. Focus rings are their own usage group.
Example: color.theme.button.primary.hover. Some tokens nest a variant deeper (button.secondary.active.hover) or omit the state when a color is stateless (text.highlight). Primitives (reference, don’t consume) The palette theme tokens draw from:
  • color.core β€” the base UI palette: white-alpha, black-alpha, gray, blue, green, red, yellow, orange. Alpha families are transparent (they let background tone through); solid families are opaque. Each family runs a numeric ramp (e.g. blue.10 … blue.100); higher numbers are more saturated/darker.
  • color.decorative β€” expressive accents used for people, labels, and avatars: gold, olive, lime, mint, cyan, cobalt, slate, violet, purple, pink.
  • color.partner β€” brand colors for third-party file types (pdf, word, powerpoint, excel, keynote…). Theme-invariant.
  • color.highcontrast, color.gradient, color.mobile, color.ai β€” specialized palettes for high-contrast modes, gradients, native mobile, and AI surfaces.
Authoritative source: packages/assets/tokens/src/core/value.json. Usage groups There are 16 theme usage groups. Each entry below gives the group’s intent, its main variants, and representative light/dark values (shown as the primitive they reference). The complete, authoritative token set per mode lives in packages/assets/tokens/src/theme/stable/ (light.json, dark.json, highcontrast/hc_light.json, highcontrast/hc_dark.json). text β€” color.theme.text.* Foreground color for type and inline icons.
TokenLightDark
text.primary.normalcore.black-alpha.95core.white-alpha.95
text.secondary.normalcore.black-alpha.70core.white-alpha.70
text.primary.disabledcore.black-alpha.40core.white-alpha.40
text.error.{normal,hover,active}core.red.{70,90,90}core.red.{40,20,20}
text.success / text.warning / text.accentgreen / yellow / blue .70β†’.90.40β†’.20
text.highlightcore.blue.20core.blue.80
text.team.<accent>.*decorative.<accent>.70β†’90.40β†’.20
Prominence: primary for high-emphasis body/headings, secondary for supporting text. Use sentiment variants (error, success, warning) only for matching status messaging, never for generic emphasis. Used by: text, button, input, listitem, dialog, toast, tooltip, and more β€” the most broadly consumed group (45 components). background β€” color.theme.background.* Surface fills, from transparent interaction layers to opaque canvases.
VariantIntentExample (light β†’ dark)
primary.{ghost,hover,active,disabled}Transparent hit-state layer over any surfaceblack-alpha.0/7/11 β†’ white-alpha.0/7/11
solid.{primary,secondary,tertiary,quaternary}Opaque page/card surfaceswhite-alpha.100 / gray.5/10 β†’ black-alpha.100 / gray.95/90
secondary.{normal,hover,active,subtle}Translucent filled surfacesblack-alpha.11/20/30/7 β†’ white-alpha.*
alert.{default,success,warning,error,theme,purple,orange}Banner/notification backgrounds*.10 β†’ *.90
accentBrand-tinted surfaceblue.60
solid.* are your opaque canvases; primary.* are the transparent layers you stack for hover/press feedback. glass.* lives in Glass. Used by: dialog, popover, banner, toast, listitem, input, chip, and more (31 components). groupedbackground β€” color.theme.groupedbackground.* Layered β€œgrouped” surfaces (primary β†’ quaternary) for nested containers, Γ  la inset/grouped lists. Light uses gray.5/white; dark steps through black-alpha.100 β†’ gray.80. Used by: no component currently consumes this group; it backs grouped/inset container surfaces. button β€” color.theme.button.* Fills for actionable controls, by prominence and by action.
VariantStatesExample (light)
primarynormal/hover/pressed/disabledblack-alpha.95/80/70/20 (dark: white-alpha.*)
secondary + secondary.activenormal/hover/pressed/disabledblack-alpha.0/7/20/0
joinnormal/hover/pressedgreen.60/70/80
cancelnormal/hover/pressedred.60/70/80
accentnormal/hover/pressedblue.60/70/80
glass.primarynormal/hover/pressedsee Glass
join/cancel are semantic actions (accept/decline a call), not generic success/error β€” use them only for those flows. Used by: button, tab, menupopover, navmenuitem. outline β€” color.theme.outline.* Borders, dividers, and separators. 16 variants including primary, secondary, theme (brand-tinted), input, button, join, cancel, promotion, warning, high-contrast, gradient, glass, and ai. Choose the variant that matches the bordered element (e.g. outline.input.* for fields, outline.button.* for button borders). Used by: input, button, card, dialog, checkbox, tab, divider, and more (36 components). control β€” color.theme.control.* Interactive control fills (checkboxes, radios, toggles, sliders).
  • control.active.* β€” the β€œon”/selected state, brand blue (blue.40β†’60 through hover/pressed).
  • control.inactive.* β€” the neutral β€œoff” track.
  • control.indicator.inactive.normal β€” gray.50 (theme-invariant).
Used by: checkbox, radio, toggle, slider, statictoggle, stepperitem, progressbar, progressspinner, spinner, staticcheckbox, staticradio (11 components). overlay β€” color.theme.overlay.* Scrims that dim content behind modals and menus (overlay.meetings, overlay.button). Used by: divider, slider. indicator β€” color.theme.indicator.* Status/presence dots. Each maps to a sentiment: stable (green), attention (red), caution (yellow/orange), secure (blue), plus locked and unstable. Use the indicator that matches the state being communicated. Used by: presence, progressbar. inverted β€” color.theme.inverted.* The mirror of the active theme β€” light colors in light mode, dark colors in dark mode β€” for surfaces that must contrast against the current theme (tooltips, coachmarks). Provides its own text, background, button, outline, and control sub-sets. See Theming for the concept. Used by: tooltip, coachmark, toggletip, popover, button, badge, input, link, and more (17 components). common β€” color.theme.common.* Colors that stay the same across all themes (e.g. media touchbar, partner file colors, fixed overlays). Only a few components use common colors; reach for them only when a color must not flip with the theme. See Theming. Used by: avatar, avatarbutton, badge, button, dialog, datepicker, popover, inputchip, statictoggle, timepicker (10 components). avatar β€” color.theme.avatar.* Avatar backgrounds: default, ghost, interaction states (hover, pressed), a glass variant, and the named-accent set (cobalt, cyan, gold, lime, mint, orange, pink, purple, slate, violet, yellow) used to color people consistently. Named accents are theme-invariant (decorative.<name>.70). Used by: avatar, avatarbutton. illustrations β€” color.theme.illustrations.* Multi-stop palettes for spot illustrations and empty/onboarding/success/error states. Mostly theme-invariant decorative pairs. Used by: no component currently consumes this group; illustration colors are applied in product-level artwork. gradientdivider β€” color.theme.gradientdivider.* Gradient separators that fade at both ends. Variants: default, success, warning, error, announce, orange, purple, and vertical. Light uses black-alpha; dark uses white-alpha. Used by: divider. globaltint β€” color.theme.globaltint.* App-wide tint (normal, selected) β€” brand blue. Used by: no component currently consumes this group. scrollbar β€” color.theme.scrollbar.* Scrollbar button (thumb), arrow, and background. Light black-alpha, dark white-alpha. Used by: themeprovider (global scrollbar styling). focus β€” color.theme.focus.* The focus ring (focus.default.0/1/2 β€” the layered ring stops). Never restyle focus with another token; use this group so keyboard focus stays consistent and visible. Used by: calendar, radio directly; most components inherit the focus ring from shared styling (utils/styles). Prominence and sentiment Two cross-cutting descriptors appear as variants across groups:
  • Prominence (visual hierarchy): primary (most prominent β€” high-emphasis fills, text, icons), secondary (supporting), tertiary (least prominent, mostly backgrounds).
  • Sentiment (situation/context): error, success, warning, accent, promotion. Use these only to convey their meaning, never for decoration.
Named accents (cobalt, cyan, gold, lime, mint…) are the expressive set used to distinguish people, labels, and avatars. Interaction states Most interactive tokens expose the same state ramp:
  • normal β€” resting state.
  • hover β€” pointer over the target.
  • pressed β€” active press.
  • active β€” selected / β€œon”.
  • disabled β€” non-interactive.
Do not simulate a state by swapping to a different variant’s normal; use the matching state token so behavior stays consistent across components and themes. Misuse β€” do not
  • Don’t hardcode hex values or reference color.core.* / color.decorative.* directly in a component. Always go through color.theme.*.
  • Don’t use a sentiment token (error, success, warning) for emphasis that isn’t that sentiment.
  • Don’t repurpose button.join/button.cancel outside accept/decline flows.
  • Don’t restyle focus with anything other than color.theme.focus.*.
  • Don’t pick a color by its resolved light-mode value β€” pick it by intent, so it resolves correctly in dark and high-contrast modes.
Quick lookup β€” β€œI need a color for…”
I need…Reach for
Body / heading texttext.primary.normal, text.secondary.normal
An error / success messagetext.error.*, background.alert.error.*
A primary button fillbutton.primary.*
A field borderoutline.input.*
A checkbox/toggle β€œon” statecontrol.active.*
A page / card surfacebackground.solid.primary.normal
A hover layer over a surfacebackground.primary.hover
A presence/status dotindicator.*
An avatar backgroundavatar.<accent>
A modal scrimoverlay.*
A keyboard focus ringfocus.default.*
A glass/translucent panelsee Glass
Related
  • Theming β€” how these tokens resolve across light, dark, and high-contrast modes; inverted vs. common.
  • Glass β€” the glass aesthetic: material, blur, and overlay tokens.
  • themeprovider component (Tier 3) β€” how a theme is applied at runtime.
Edit this page on GitHub