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

## Colors

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

## Neutral palette

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

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

<Callout variant="tip">

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

</Callout>

[See how to use neutral colors](#colors-usage-guidelines)

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

---

## Accent palette

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

[See how to use accent colors](#colors-usage-guidelines)

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

---

## Notification palette

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

### Blue

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

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

### Green

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

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

### Orange

Orange indicates a warning or that progress is hindered. Use orange to indicate to indicate a user that an issue can be avoided or needs a corrective action.

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

### Red

Red indicates error states and messages. Red is an alarming color and should be used with care as it can convey a negative feeling.

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

---

## Functional tokens

Base color tokens listed above just represent a static color 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 color tokens to enable more predictable combination and application of colors.

Migration to functional tokens will allow easier implementation of new color-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 color 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 color and theme updates "for free", which is a win for maintainability going forward.

<Callout variant="tip">

Avoid referencing color 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.

</Callout>

<Callout variant="tip">

We use fairly generic names for the functional color 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.

</Callout>

Every functional color 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`.

This gives us final token names like:

Finally, the functional tokens are referenced throughout component styles:

```jsx
import { styled } from '@gemini-suite/vera-react';

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

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

<Callout variant="tip">

Functional tokens are available for use in [all styling APIs](/get-started/developing/developing#styling-apis) that `@gemini-suite/vera-react` offers.

</Callout>

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

### Pairing

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

However not all colors 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 color 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',
        border: '1px solid $borderAccentModerate',
        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: '$backgroundAccentSubtle',
        color: '$foregroundAccent',

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

        '&:hover': {
          backgroundColor: '$backgroundAccentStrongHover'
        }
      }}
    >
      {'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

Color 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.

<Callout variant="tip">

CSS variables come automatically bundled with `@gemini-suite/vera` core package.

</Callout>

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 `@gemini-suite/design-colors` package.

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

---

### Background tokens

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

<ColorTokensList list={colorTokens.background} />

---

### Foreground tokens

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

<Callout variant="tip">

Regular foreground colors tokens ensure enough contrast ratio when used on top of default, `minimal` and `subtle` background color tokens.

Note that icons have different contrast requirements than text. Since they are graphical objects, they only need to meet a 3:1 color 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)).

</Callout>

<ColorTokensList list={colorTokens.foreground} />

---

### Border tokens

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

<ColorTokensList list={colorTokens.border} />

---

### RGB channels

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

While sticking to solid colors is the default, recommended way, in some special cases there might be a need to reduce the opacity of a color. 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 color tokens, their RGB channel values are exposed as separate tokens to be combined with an alpha/opacity. You can use them with the [rgba color 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('data'))}
/>

---

## Data visualisation colors

The colors available in this category have a unique purpose and should be used only only for data visualisation and information highlighting.

<Callout variant="tip">

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

</Callout>

<Callout variant="tip">

Data visualisation colors are produced using [OKLCH color space](https://hybridheroes.de/blog/2023-04-27-rgb-hsl-oklch/#why-are-we-looking-forward-to-oklch) to ensure that the colors are perceptually similar in lightness and saturation across the palettes.

A perceptually uniform color space in data visualisation matters, because the perceived colors should not be different from the data points reflected in the color values.
For example, imagine a map that uses different colors for geographic areas to reflect the value of a data point, where it's crucial that the user can compare colors between regions to get a sense of the data.

</Callout>

### Teal

<Palette colors={colorTokens.data} colorKeys="dataTeal" />

### Purple

<Palette colors={colorTokens.data} colorKeys="dataPurple" />

### Pink

<Palette colors={colorTokens.data} colorKeys="dataPink" />

### Aqua

<Palette colors={colorTokens.data} colorKeys="dataAqua" />

### Blue

<Palette colors={colorTokens.data} colorKeys="dataBlue" />

### Lazuli

<Palette colors={colorTokens.data} colorKeys="dataLazuli" />

### Green

<Palette colors={colorTokens.data} colorKeys="dataGreen" />

### Lime

<Palette colors={colorTokens.data} colorKeys="dataLime" />

### Orange

<Palette colors={colorTokens.data} colorKeys="dataOrange" />

### Pear

<Palette colors={colorTokens.data} colorKeys="dataPear" />

### Brown

<Palette colors={colorTokens.data} colorKeys="dataBrown" />

### Red

<Palette colors={colorTokens.data} colorKeys="dataRed" />

---

### RGB channels

RGB channel values of data visualisation colors are exposed as separate tokens to be combined with an alpha/opacity.

<Callout variant="tip">

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

</Callout>

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

---

## Colors usage guidelines

Each color in Veras' color palette has its purpose.

The [neutral color palette](#neutral-palette) is used for most backgrounds including the backgrounds of main navigation elements, such as left panels and top headers.

The [accent color palette](#accent-palette) is used for all other interactive elements such as buttons and inputs, including highlights of labels and messages.
The accent color is differentiating the content from the main navigation elements.

---

Using [neutral color palette](#neutral-palette) for typography and alternative backgrounds than white, ensure that your content is contrasted correctly.

---

## Colors accessibility

Found colors in the Vera 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 colors you're planning on using to see if the pair meets the minimum color contrast requirements.

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