# Colours
> By keeping the usage of colours systematic, we are distinguishing our brand and creating a consistent experience across products.

## Colours

For consistency and brand awareness, we use the below defined colour palettes throughout our interfaces.

## Neutral palette

The neutral colour palette is used for typography and most backgrounds.

Neutral colours help you structure your content. They set a calm and not distracting environment. They don’t typically have a meaning associated with them, though they can imply things like disabled states of elements.

> **Tip**
>
> Our neutral palette is slightly saturated with the hue close to our accent hue
> to create more harmonious vibe.

<Palette colors={colorTokens.core} colorKeys="colorWhite, colorGray" />

---

## Accent palette

The accent colour palette is used in logical ways throughout the product to guide the eye and highlight
the important, interactive UI bits.

<Palette colors={colorTokens.core} colorKeys="colorSolarMist" />

---

## Notification palette

Each colour in the notification colour palette is selected intentionally to provide meaningful feedback within our experiences.
Notification colours should be used purposefully to communicate and inform users.

### Info

Info palette is used to indicate informative notifications, progress, and labels in the system.

<Palette colors={colorTokens.core} colorKeys="colorAqua" />

### Success

Success palette is used to indicate success states. Green is a vibrant colour and should be used sparingly to convey a positive feeling.

<Palette colors={colorTokens.core} colorKeys="colorGreen" />

### Warning

Warning palette is used to indicate a warning or that progress is hindered. Use yellow to indicate to indicate a user that an issue can be avoided or needs a corrective action.

<Palette colors={colorTokens.core} colorKeys="colorYellow" />

### Danger

Danger palette is used to indicate error states and messages. Red is an alarming colour and should be used with care as it can convey a negative feeling.

<Palette colors={colorTokens.core} colorKeys="colorRed" />

---

## Functional tokens

Base colour tokens listed above just represent a static colour value and looking at them doesn't tell you much about possible applications.
Functional tokens allow us to abstract values to attach a meaning to their intended usage.
They allow us to layer references on top of base colour tokens to enable more predictable combination and application of colours.

![Tokens relationship](https://next.wave-design-system.pages.dev/_next/static/chunks/images/colors-tokens-relationship-31882cffee9ef50881b49618e2826b3c.png)

Migration to functional tokens will allow easier implementation of new colour-related features like dark mode, custom themes or even simplify future product rebranding.
Functional tokens act as an <abbr title="Application Programming Interface">API</abbr> on top of our colour palettes, in a sense that the tokens can be referenced without worrying about their underlying value.
Apps that stick to the tokens will get all future colour and theme updates "for free", which is a win for maintainability going forward.

> **Tip**
>
> Avoid referencing colour scales by their actual scale name like `colorGray100`. Instead, use the functional tokens whenever possible. In rare cases, you may need to use explicit scale tokens to define custom functional variables in your application.

> **Tip**
>
> We use fairly generic names for the functional colour tokens that work as a guide for the application but don't rely on our component inventory, thus can also be used to build your custom components.

Every functional colour token follows the same predictable naming convention that helps provide an understanding on how or when the token should be used.

The format of the name is: `[property][role][variant][state]`, where:

- `property` is a UI entity the token will be applied to, such as `background` or `border`.
- `role` describes the intention behind the token.
- `variant` refers to variations of the token, for example how prominent it appears. Prominence scale ranges from `minimal` to `contrast`.
- `state` is optional and can represent available interaction options such as `hover` or `active`.

![Functional tokens structure explanation](https://next.wave-design-system.pages.dev/_next/static/chunks/images/colors-functional-tokens-structure-4290d077f862a393e0d745f65300792f.png)

This gives us final token names like:

![Functional tokens names](https://next.wave-design-system.pages.dev/_next/static/chunks/images/colors-functional-token-names-793d99ab91931bb69adce0185ae31e54.png)

Finally, the functional tokens are referenced throughout component styles:

![Functional tokens usage example](https://next.wave-design-system.pages.dev/_next/static/chunks/images/colors-functional-tokens-example-5098ddced8eebc8c69de48d9cab1c3fb.png)

```jsx
import { styled } from '@volue/wave-react';

const Component = styled('div', {
  backgroundColor: '$backgroundSuccessStrong',
  color: '$foregroundSuccessInverse',

  '&:hover': {
    backgroundColor: '$backgroundSuccessStrongHover'
  }
});
```

> **Tip**
>
> Functional tokens are available for use in [all styling APIs](https://next.wave-design-system.pages.dev/get-started/developing.md#styling-apis) that `@volue/wave-react` offers.

Our functional colour tokens belong to one of three groups: [background](#background-tokens), [foreground](#foreground-tokens) and [border](#border-tokens).

### Pairing

It is recommended to pair default colour foregrounds with their default and subtle background counterparts.
These pairings are designed to be legible and meet [accessibility guidance](#colours-accessibility) (WCAG AA contrast requirements).

However not all colours pair well with each other. For example you shouldn't combine default foregrounds with strong backgrounds as that will result in inaccessible pairings. Instead, use inverse foreground tokens designed to show on strong backgrounds for optimal contrast.

Here are some general colour pairings that have been designed and tested for accessible contrast ratios:

```jsx
<Flex flow="column">
  <Flex>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundNeutral',
        border: '1px solid $borderNeutral',
        color: '$foregroundNeutral'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundNeutralModerate',
        border: '1px solid $borderNeutralModerate',
        color: '$foregroundNeutralModerate'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundNeutralSubtle',
        border: '1px solid $borderNeutralSubtle',
        color: '$foregroundNeutralSubtle'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundNeutralModerate',
        color: '$foregroundNeutral'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundNeutralBold',
        color: '$foregroundInverse'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundNeutralContrast',
        color: '$foregroundInverse'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
  </Flex>
  <Flex>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundAccent',
        border: '1px solid $borderAccent',
        color: '$foregroundAccent'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundAccentSubtle',
        color: '$foregroundAccentModerate'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundAccentStrong',
        color: '$foregroundInverse'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
  </Flex>
  <Flex>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundDanger',
        border: '1px solid $borderDanger',
        color: '$foregroundDanger'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundDangerStrong',
        color: '$foregroundInverse'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
  </Flex>
  <Flex>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundSuccess',
        border: '1px solid $borderSuccess',
        color: '$foregroundSuccess'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundSuccessStrong',
        color: '$foregroundInverse'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
  </Flex>
  <Flex>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundWarning',
        border: '1px solid $borderWarning',
        color: '$foregroundWarning'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundWarningStrong',
        color: '$foregroundWarningInverse'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
  </Flex>
  <Flex>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundInfo',
        border: '1px solid $borderInfo',
        color: '$foregroundInfo'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
    <TokensPreviewBox
      css={{
        backgroundColor: '$backgroundInfoStrong',
        color: '$foregroundInverse'
      }}
    >
      {'Aa'}
    </TokensPreviewBox>
  </Flex>
</Flex>
```

Use `hover`, `active` and `disabled` tokens to communicate visual changes related to interaction states:

```jsx
<Flex flow="column">
  <Flex as="ul" flow="column" gap="none" padding="none" margin="none">
    <Box
      as="li"
      css={{
        paddingY: '$spacingS',
        paddingX: '$spacingM',
        cursor: 'pointer',
        backgroundColor: '$backgroundAccent',
        color: '$foregroundAccent',

        '&:hover': {
          backgroundColor: '$backgroundAccentHover'
        },
        '&:active': {
          backgroundColor: '$backgroundAccentActive'
        }
      }}
    >
      {'Actionable item'}
    </Box>
    <Box
      as="li"
      css={{
        paddingY: '$spacingS',
        paddingX: '$spacingM',
        cursor: 'pointer',
        backgroundColor: '$backgroundAccentActive',
        color: '$foregroundAccent'
      }}
    >
      {'Selected item'}
    </Box>
  </Flex>
  <Flex>
    <Box
      as="button"
      css={{
        backgroundColor: '$backgroundNeutralStrong',
        color: '$foregroundInverse',
        borderRadius: '$s',
        paddingX: '$spacingM',
        paddingY: '$spacingS',

        '&:hover': {
          backgroundColor: '$backgroundNeutralStrongHover'
        }
      }}
    >
      {'Pseudo button'}
    </Box>
    <Box
      as="button"
      css={{
        backgroundColor: '$backgroundDisabled',
        cursor: 'not-allowed',
        color: '$foregroundDisabled',
        borderRadius: '$s',
        paddingX: '$spacingM',
        paddingY: '$spacingS'
      }}
    >
      {'Pseudo disabled button'}
    </Box>
  </Flex>
</Flex>
```

### CSS variables

Colour tokens exist in different formats and can be also consumed as [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) or variables.
You can use any styling solution to read those variables.

> **Tip**
>
> CSS variables come automatically bundled with `@volue/wave` core package.

CSS variable names are formatted in [kebab-case](https://en.wikipedia.org/wiki/Letter_case#Kebab_case):

```css
.element {
  background: var(--color-background-neutral-moderate);
  color: var(--color-foreground-neutral);
}
```

There are even more ways of integrating tokens into your product with help of `@volue/design-colors` package.

<Grid
  columns={{
    '@initial': '1',
    '@mqLargeAndUp': '2'
  }}
  columnGap="spacingL"
>
  <GridItem>
    <Card
      href="https://github.com/Volue/wave/tree/next/design-primitives/design-colors"
      title="See colour tokens repo"
      actionIcon="externalLink"
    />
  </GridItem>
</Grid>

---

### Background tokens

Background colour tokens define the background colours used in surfaces of components or UI elements. Do not use these for border colours or foreground colours.

<ColorTokensList list={colorTokens.background} />

---

### Foreground tokens

Foreground colour tokens are used for text content, icons, and other elements rendered on top of a background. Do not use these for border colours or background colours.

> **Tip**
>
> Regular foreground colours tokens ensure enough contrast ratio when used on top of default, `minimal` and `subtle` background colour tokens.
>
> Note that icons have different contrast requirements than text. Since they are graphical objects, they only need to meet a 3:1 colour contrast ratio ([WCAG 1.4.11](https://www.w3.org/TR/WCAG21/#non-text-contrast)), as opposed to text, which must meet 4.5:1 contrast ratio ([WCAG 1.4.3](https://www.w3.org/TR/WCAG21/#contrast-minimum)).

<ColorTokensList list={colorTokens.foreground} />

---

### Border tokens

Border colour tokens define the colour of borders, as seen in toasts, cards, form fields, and more. Do not use these for background colours or foreground colours.

<ColorTokensList list={colorTokens.border} />

---

### RGB channels

When a token translates to `#000000` (hex) or `rgb(0, 0, 0)` colour value in CSS, it becomes a challenge to apply opacity just to the colour value without making the whole component transparent.

While sticking to solid colours is the default, recommended way, in some special cases there might be a need to reduce the opacity of a colour. For example, transparent shades adapt easier to different backgrounds, since they keep the contrast between the element and its background more consistent.

That's why for a subset of background colour tokens, their RGB channel values are exposed as separate tokens to be combined with an alpha/opacity. You can use them with the [rgba colour function](https://www.w3.org/TR/css-color-4/#rgb-functions) like this:

```jsx
const Component = styled('div', {
  backgroundColor: 'rgba($rgbBackgroundNeutralBold, 0.15)'
});
```

```css
.element {
  background: rgba(var(--color-rgb-background-neutral-bold), 0.15);
}
```

The following rgb channel tokens are available:

<ColorTokensList
  list={colorTokens.rgb.filter(token => token.path.includes('background'))}
/>

---

## Secondary colours

Colours other than Aqua, Green, Yellow and Red have a unique purpose and should be used only only for data visualisation and information highlighting.

> **Tip**
>
> Data visualisation is the representation of information in pictorial or graphical format, such as charts, graphs, maps, and diagrams.

### Teal

<Palette colors={colorTokens.core} colorKeys="colorTeal" />

### Purple

<Palette colors={colorTokens.core} colorKeys="colorPurple" />

### Pink

<Palette colors={colorTokens.core} colorKeys="colorPink" />

### Blue

<Palette colors={colorTokens.core} colorKeys="colorBlue" />

### Lazuli

<Palette colors={colorTokens.core} colorKeys="colorLazuli" />

### Lime

<Palette colors={colorTokens.core} colorKeys="colorLime" />

### Orange

<Palette colors={colorTokens.core} colorKeys="colorOrange" />

### Pear

<Palette colors={colorTokens.core} colorKeys="colorPear" />

### Brown

<Palette colors={colorTokens.core} colorKeys="colorBrown" />

---

### RGB channels

RGB channel values of secondary colours are exposed as separate tokens to be combined with an alpha/opacity.

> **Tip**
>
> See [functional tokens RGB channels](#rgb-channels) for example usage.

<ColorTokensList
  list={colorTokens.rgb.filter(token => !token.path.includes('background'))}
/>

---

## Colours accessibility

Found colours in the Wave palette that you would like to use together, but not sure if they will pass WCAG AA contrast requirements?

Recommended tools below can find you to test the colours you're planning on using to see if the pair meets the minimum colour contrast requirements.

<Grid
  columns={{
    '@initial': '1',
    '@mqLargeAndUp': '2'
  }}
  columnGap="spacingL"
>
  <GridItem>
    <Card
      href="/colors-test"
      title="Colours test page"
      actionIcon="arrowRight"
    />
  </GridItem>
  <GridItem>
    <Card
      href="https://www.oddcontrast.com/#hex__*e6ebec__*082d35"
      title="Contrast checker tool"
      actionIcon="externalLink"
    />
  </GridItem>
</Grid>
