Skip to content
Autumn 2026 Mesh Release and Design Tokens v2 now available! Read the announcement

Migrating to Design Tokens

A guide to help you migrate your project to Design Tokens v2 and the new modes system. Covers removed color selectors and how to pick suitable replacements for them.

This document covers in detail how to work with color in design-tokens v2, and how to migrate from the previous system. If you are looking for a more general overview of the changes in the Autumn 2026 release, see our release notes.

Approach to applying color

Many of the concepts behind applying color in design-tokens v2 already existed in v1, but v1 still supported legacy color patterns through:

  • theme-based selectors (imported from @nib-components/theme)
  • color props on components mapping to theme values (such as color="darkest" or background="brandBase")

Consumers were encouraged to apply color via modes, but the old approaches were still available and were not initially marked as deprecated. That made it hard for teams to know when they had fully moved to the new system, so many applications that adopted tokens still rely on legacy color usage somewhere.

In v2, these legacy approaches have been removed. Any existing usage needs to be refactored to use the new modes system and token values. This guide explains how.

There are two main ways to apply color:

  • applying color via props on Box (or other components that accept color props, such as Copy or Heading)
  • applying color via styled components, using either
    • the token function (named export from @nib-components/theme)
    • CSS custom properties directly

Props on Box

Using Box props has a few advantages:

  • quick to apply
  • makes the purpose of the color clear (background, foreground, or border)
  • gives you access to sentiment and prominence to further refine the color choice
jsx
<Box background="default" foreground="default" borderColor="default">
...
</Box>

Styled components/CSS

Via CSS, you only have access to the available token color options. You cannot set sentiment or prominence via CSS.

token function

jsx
const MyComponent = styled.div`
background: ${token('theme.color.bg')};
color: ${token('theme.color.fg')};
border-color: ${token('theme.color.border')};
`;

CSS custom properties

jsx
const MyComponent = styled.div`
background: var(--themeColorBg);
color: var(--themeColorFg);
border-color: var(--themeColorBorder);
`;

In both approaches, the token value is determined by the mode the component is rendered within.

jsx
<ModeProvider sentiment="sage" prominence="prominent">
<MyComponent />
<Box sentiment="hero" prominence="gentle">
<MyComponent />
</Box>
</ModeProvider>

The same MyComponent will render with different colors in each case, based on the surrounding mode. Box can also be used in place of ModeProvider.

Why has our approach changed?

When you choose a color token, you are not choosing a fixed color. You are choosing a color role, and each mode fills that role with the appropriate color. This makes the system more flexible and easier to scale.

Dark mode is a clear example of why this is important: you choose the same role, and the system automatically resolves it to the right dark-mode color. The same is true for sentiments and prominences: you choose the role, and the system automatically resolves it to the right color for that sentiment and prominence.

Because the token set is curated to work across modes, staying within the system helps maintain accessible color contrast. Choosing colors outside it increases the risk of accessibility issues.

Picking a suitable replacement for theme based selectors

Start by identifying how the color is being used: background, text, or border. Then choose from the corresponding token set.

Never use a color token for a purpose it was not designed for! The tokens have been carefully designed to maintain sufficient contrast between backgrounds and foregrounds across brands, sentiments, and prominences. Using a background token as a foreground color, or vice versa, is likely to create accessibility issues.

What if there is no direct replacement?

In the tables below, there are many cases where there is no direct replacement for the color you were using. When you encounter this, you will need to pick the closest available option and potentially adjust your design to accommodate the change in color.

Think semantically about the purpose of the color and choose a replacement that aligns with that purpose. If that is not clear, default is a safe starting point for background and foreground colors. Start there and adjust as needed.

If you find that there is a gap in the token set that makes it hard to find a suitable replacement, or you are unsure, please reach out to the mesh team to discuss potential solutions.

Background color

At a glance, the background token set looks limited, but it is designed to work with the modes system to produce a wide range of backgrounds. The available background tokens are:

  • default
  • hover (reserved for hover states of interactive elements, should not be used as a static background color)
  • transparent

Note: For each of these selectors, you might instead have been passing the color as a string prop to a component, such as background="brandBase". In that case, replace the value with default and ensure the component is wrapped in a mode that sets the background to the intended color, for example hero.

BeforeAfter
colorBrandBase<Box sentiment="hero" background="default" foreground="default">
colorBrandDark<Box sentiment="hero" prominence="gentle" background="default" foreground="default">
colorBrandLight<Box sentiment="hero" background="prominent" foreground="default">
colorAccentNo direct replacement available.
colorFocusNo direct replacement available. The focus color is reserved for focus states of interactive elements. Should not be used as a background color.
colorWhite<Box sentiment="default" background="default" foreground="default">
colorNearWhite<Box sentiment="default" prominence="gentle" background="default" foreground="default">
colorLightest<Box sentiment="default" prominence="gentle" background="default" foreground="default">
colorLighter<Box sentiment="default" prominence="muted" background="default" foreground="default">
colorLightNo direct replacement available.
colorDarkNo direct replacement available.
colorDarkerNo direct replacement available.
colorDarkestNo direct replacement available.
colorBlackNo direct replacement available.
colorHospitalNo direct replacement available.
colorExtrasNo direct replacement available.
colorCombinedNo direct replacement available.
colorHighlightBgNo direct replacement available.
colorHighlightTextNo direct replacement available.
colorSuccess<Box sentiment="positive" prominence="prominent" background="default" foreground="default"> Also other prominences available.
colorInfo<Box sentiment="informative" prominence="prominent" background="default" foreground="default"> Also other prominences available.
colorError<Box sentiment="negative" prominence="prominent" background="default" foreground="default"> Also other prominences available.
colorWarning<Box sentiment="cautionary" prominence="prominent" background="default" foreground="default"> Also other prominences available.
colorTrueGreen<Box sentiment="hero" prominence="default" background="default" foreground="default">
colorTrueGreen80No direct replacement available.
colorTrueGreen60No direct replacement available.
colorTrueGreen40No direct replacement available.
colorTrueGreen20No direct replacement available.
colorBrightGreen<Box sentiment="hero" prominence="prominent" background="default" foreground="default">
colorBrightGreen80No direct replacement available.
colorBrightGreen60No direct replacement available.
colorBrightGreen40No direct replacement available.
colorBrightGreen20No direct replacement available.
colorSageGreen<Box sentiment="sage" prominence="prominent" background="default" foreground="default">
colorSageGreen80<Box sentiment="sage" prominence="default" background="default" foreground="default">
colorSageGreen60<Box sentiment="sage" prominence="gentle" background="default" foreground="default">
colorSageGreen40<Box sentiment="sage" prominence="gentle" background="default" foreground="default">
colorSageGreen20<Box sentiment="sage" prominence="muted" background="default" foreground="default">
colorWarmWhite<Box sentiment="warm" prominence="default" background="default" foreground="default">
colorWarmWhite80<Box sentiment="warm" prominence="default" background="default" foreground="default">
colorWarmWhite60<Box sentiment="warm" prominence="gentle" background="default" foreground="default">
colorWarmWhite40<Box sentiment="warm" prominence="gentle" background="default" foreground="default">
colorWarmWhite20<Box sentiment="warm" prominence="muted" background="default" foreground="default">
colorSunsetPink<Box sentiment="sunset" prominence="default" background="default" foreground="default">
colorSunsetPink80<Box sentiment="sunset" prominence="default" background="default" foreground="default">
colorSunsetPink60<Box sentiment="sunset" prominence="gentle" background="default" foreground="default">
colorSunsetPink40<Box sentiment="sunset" prominence="gentle" background="default" foreground="default">
colorSunsetPink20<Box sentiment="sunset" prominence="muted" background="default" foreground="default">

Foreground color

Foreground colors have a substantially larger set of options to pick from:

  • default
  • prominent
  • gentle
  • muted
  • brand
  • sentiment
  • error
  • success
  • info
  • warning
  • selected

Even with the expanded set of options compared to background colors, each of these tokens can still vary across sentiments/prominences.

Note: For each of these selectors, you might instead have been passing the color as a string prop to a component, such as color="brandBase". In this case, you would replace the value with brand and ensure that the component is wrapped in a mode that sets the foreground to the appropriate color for that mode.

Whilst we are updating foreground colors, note that the color prop on Box has been renamed to foreground to better reflect the purpose of the prop.

BeforeAfter
colorBrandBase<Box foreground="brand">
colorBrandDark<Box foreground="brand">
colorBrandLight<Box foreground="brand">
colorAccentNo direct replacement available.
colorFocusNo direct replacement available. The focus color is reserved for focus states of interactive elements. Should not be used as a foreground color.
colorWhite<Box foreground="white">. This is one non-mode aware value. It is literally #ffffff. Very risky to use alongside a variable background.
colorNearWhiteNo direct replacement available.
colorLightestNo direct replacement available.
colorLighterNo direct replacement available.
colorLightNo direct replacement available.
colorDark<Box foreground="muted">
colorDarker<Box foreground="gentle">
colorDarkest<Box foreground="default">
colorBlack<Box foreground="black">. This is one non-mode aware value. It is literally #000000. Very risky to use alongside a variable background.
colorHospitalNo direct replacement available.
colorExtrasNo direct replacement available.
colorCombinedNo direct replacement available.
colorHighlightBgNo direct replacement available.
colorHighlightTextNo direct replacement available.
colorSuccess<Box foreground="success">
colorInfo<Box foreground="info">
colorError<Box foreground="error">
colorWarning<Box foreground="warning">
colorTrueGreen<Box foreground="brand">
colorTrueGreen80No direct replacement available.
colorTrueGreen60No direct replacement available.
colorTrueGreen40No direct replacement available.
colorTrueGreen20No direct replacement available.
colorBrightGreenNo direct replacement available.
colorBrightGreen80No direct replacement available.
colorBrightGreen60No direct replacement available.
colorBrightGreen40No direct replacement available.
colorBrightGreen20No direct replacement available.
colorSageGreenNo direct replacement available.
colorSageGreen80No direct replacement available.
colorSageGreen60No direct replacement available.
colorSageGreen40No direct replacement available.
colorSageGreen20No direct replacement available.
colorWarmWhiteNo direct replacement available.
colorWarmWhite80No direct replacement available.
colorWarmWhite60No direct replacement available.
colorWarmWhite40No direct replacement available.
colorWarmWhite20No direct replacement available.
colorSunsetPinkNo direct replacement available.
colorSunsetPink80No direct replacement available.
colorSunsetPink60No direct replacement available.
colorSunsetPink40No direct replacement available.
colorSunsetPink20No direct replacement available.

For each of the suggestions above being set on Box, you could also apply the same token values to any other component that accepts a color prop, such as Copy or Heading. You could also apply the same token values to a styled component:

jsx
const MyErrorComponent = styled.div`
color: ${token('theme.color.fg.error')};
`;

Border color

Border colors take a similar approach to foreground colors, with tokens for prominence within the neutral palette (default, prominent, gentle and muted), as well as tokens for more semantic purposes (brand, error, success, info, warning, selected and sentiment). In addition, we have a focus border color that is reserved for focus states of interactive elements, an input border color that is used for form controls and some product-specific border colors (productBasic, productBronze, productSilver, productGold, productHospital, productExtras and productCombined).

Note: For each of these selectors, you might instead have been passing the color as a string prop to a component, such as borderColor="brandBase". In this case, you would replace the value with brand and ensure that the component is wrapped in a mode that sets the border color to the appropriate color for that mode.

BeforeAfter
colorBrandBase<Box borderColor="brand" />
colorBrandDark<Box borderColor="brand" />
colorBrandLight<Box borderColor="brand" />
colorAccentNo direct replacement available.
colorFocus<Box borderColor="focus" />
colorWhite<Box borderColor="white" />
colorNearWhiteNo direct replacement available.
colorLightestNo direct replacement available.
colorLighterNo direct replacement available.
colorLightNo direct replacement available.
colorDark<Box borderColor="muted" />
colorDarker<Box borderColor="gentle" />
colorDarkest<Box borderColor="default" />
colorBlack<Box borderColor="prominent" />
colorHospital<Box borderColor="productHospital" />
colorExtras<Box borderColor="productExtras" />
colorCombined<Box borderColor="productCombined" />
colorBasic<Box borderColor="productBasic" />
colorBronze<Box borderColor="productBronze" />
colorSilver<Box borderColor="productSilver" />
colorGold<Box borderColor="productGold" />
colorHighlightBgNo direct replacement available.
colorHighlightTextNo direct replacement available.
colorSuccess<Box borderColor="success" />
colorInfo<Box borderColor="info" />
colorError<Box borderColor="error" />
colorWarning<Box borderColor="warning" />
colorTrueGreen<Box borderColor="brand" />
colorTrueGreen80No direct replacement available.
colorTrueGreen60No direct replacement available.
colorTrueGreen40No direct replacement available.
colorTrueGreen20No direct replacement available.
colorBrightGreenNo replacement available in light mode.
colorBrightGreen80No direct replacement available.
colorBrightGreen60No direct replacement available.
colorBrightGreen40No direct replacement available.
colorBrightGreen20No direct replacement available.
colorSageGreenNo direct replacement available.
colorSageGreen80No direct replacement available.
colorSageGreen60No direct replacement available.
colorSageGreen40No direct replacement available.
colorSageGreen20No direct replacement available.
colorWarmWhiteNo direct replacement available.
colorWarmWhite80No direct replacement available.
colorWarmWhite60No direct replacement available.
colorWarmWhite40No direct replacement available.
colorWarmWhite20No direct replacement available.
colorSunsetPinkNo direct replacement available.
colorSunsetPink80No direct replacement available.
colorSunsetPink60No direct replacement available.
colorSunsetPink40No direct replacement available.
colorSunsetPink20No direct replacement available.

Appendix

List of removed color selectors

A complete list of color selectors that are no longer available in v2 is as follows:

  • colorBrandBase
  • colorBrandDark
  • colorBrandLight
  • colorAccent
  • colorFocus
  • colorWhite
  • colorNearWhite
  • colorLightest
  • colorLighter
  • colorLight
  • colorDark
  • colorDarker
  • colorDarkest
  • colorBlack
  • colorHospital
  • colorExtras
  • colorCombined
  • colorHighlightBg
  • colorHighlightText
  • colorSuccess
  • colorInfo
  • colorError
  • colorWarning
  • colorTrueGreen
  • colorTrueGreen80
  • colorTrueGreen60
  • colorTrueGreen40
  • colorTrueGreen20
  • colorBrightGreen
  • colorBrightGreen80
  • colorBrightGreen60
  • colorBrightGreen40
  • colorBrightGreen20
  • colorSageGreen
  • colorSageGreen80
  • colorSageGreen60
  • colorSageGreen40
  • colorSageGreen20
  • colorWarmWhite
  • colorWarmWhite80
  • colorWarmWhite60
  • colorWarmWhite40
  • colorWarmWhite20
  • colorSunsetPink
  • colorSunsetPink80
  • colorSunsetPink60
  • colorSunsetPink40
  • colorSunsetPink20