import { Canvas, Meta, Story, Source } from "@storybook/addon-docs";

<Meta title="Migrating/From v3 to v4" />

# Objective

The Cunningham color system has been revised with a methodical approach focused on modularity and accessibility. This revision enables the systematic generation of coherent themes, the automatic implementation of display modes (light/dark), the constant maintenance of contrast ratios independently of the selected theme, and the structured allocation of colors according to their role (background, content, border).

An algorithm (available soon) has been developed to facilitate the rapid generation and adaptation of color palettes, producing a JSON file compatible with the existing infrastructure and natively supporting both light and dark display modes. This algorithmic solution optimizes Cunningham's adaptability to a wide range of user environments.

# Structure

The color system is structured around two complementary, interdependent palettes:

1. The "Color Primitive" palette is the exhaustive repository of color values specific to a given theme, defining all available shades.
2. The "Color Contextual" palette establishes a functional interface between primitive values and user interface components via a semantic abstraction layer.

This two-tier architecture facilitates the systematic propagation of changes: any alteration to the primitive palette is automatically reflected in all interface elements without the need for additional adjustments (see Figure 1).

<figure>
  <img
    src="docs/migrating/ressources/v3_to_v4/Figure1.gif"
    alt="Changing the color primitive palette automatically updates the color contextual palette while maintaining contrast ratios inside components."
  />
  <figcaption style={{ textAlign: "center" }}>
    Figure 1. Changing the color primitive palette automatically updates the
    color contextual palette while maintaining contrast ratios inside
    components.
  </figcaption>
</figure>

A **theme** is a comprehensive color configuration derived from a brand's visual identity. It constitutes a specific implementation of the "Color Primitive" palette with predetermined color values. The Cunningham theme is provided as the default reference.

A **mode** represents a systematic modulation of luminance and contrast parameters from an established theme, executed through the "Color Contextual" palette. This parametric adjustment accommodates diverse usage contexts while preserving the fundamental chromatic identity. Standard implementations include light and dark modes. These could be supplemented with specialized modes (such as high contrast) to meet specific accessibility needs or style requirements.

# Palettes

## Color Primitive

The Color Primitive palette includes 16 colors. Each color is available in 19 distinct shades, except gray, which contains 22. Each shade is referenced by a number between 000 and 1000. A shade of 000 corresponds to pure white, while a shade of 1000 corresponds to pure black. Each intermediate shade value is then defined on the basis of the perceived luminance noted L* in the CIELAB color space ([more info on CIELAB](https://en.wikipedia.org/wiki/CIELAB_color_space)). Using L* as a reference ensures that each primitive color fits into a predictable tonal scale, regardless of hue or saturation. This ensures consistent contrast levels across all themes, promoting universal accessibility. The correspondence between shade (S) and perceived luminance (L*) is as follows: $S=1000 \times (1-L^*)$ with $L^* \in [0;1]$. See Figure 2 for an example.

<figure>
  <img
    src="docs/migrating/ressources/v3_to_v4/Figure2.png"
    alt="Breakdown of the first 6 colors of a Color Primitive theme. Gray includes 3 complementary shades."
  />
  <figcaption style={{ textAlign: "center" }}>
    Figure 2. Breakdown of the first 6 colors of a "Color Primitive" theme. Gray
    includes 3 complementary shades.
  </figcaption>
</figure>

To optimize visual ergonomics in dark mode, it is necessary to reduce color saturation in the darkest shades (S > 600). This gradual desaturation avoids perceptual glare in dark mode and improves legibility in low ambient light environments.

An algorithm will soon be available to automatically adjust the parameters of perceived luminance (L*) and saturation (C*) according to a decreasing function for dark shades, while preserving the integrity of the theme's visual identity.

## Color Contextual

<figure>
  <img
    src="docs/migrating/ressources/v3_to_v4/Figure3.png"
    alt="Excerpt from the Color Contextual palette for the background.semantic.brand role, with light and dark modes."
  />
  <figcaption style={{ textAlign: "center" }}>
    Figure 3. excerpt from the "Color Contextual" palette for the
    background.semantic.brand role, with light and dark modes.
  </figcaption>
</figure>

The "Color Contextual" palette allows you to classify the various colors of a theme according to their actual use, differentiating between each of the modes (light, dark, etc.). This makes it possible (1) to simplify and limit errors when assigning colors to different components, and (2) to manage multiple modes.

This palette introduces the notion of roles, whose format is as follows:

<Source
  dark={true}
  code={`
layer.scope.(intent).variant.(state)
`}
></Source>

### Layer

The layer designates the visual rendering level of an interface element, and is divided into three distinct categories:

- Background: Background layer serving as visual support for components (e.g., button background).
- Content: Informative elements conveying a message (e.g., text, iconography)
- Border : Peripheral delimitation of components

### Scope

The scope determines the functional area of application of a color according to the following hierarchy:

- Surface: Structural elements of the interface with different levels of elevation (e.g., backgrounds, modals, maps).
- Semantic: Interactive elements communicating a specific meaning to the user.
- Palette: set of colors for specific applications requiring customization (e.g., color selection for avatars)

### Intent (optional)

The intent specifies the communicative function associated with the scope. It provides an additional contextual specification of the element's purpose in the interface.

### Variant

The variant establishes a hierarchy of visual importance according to the following taxonomy:

- Primary: Overriding importance, attracts priority attention
- Secondary: Intermediate importance, supports primary elements
- Tertiary: Subordinate importance, provides additional information
- On [...]: Color inversion mechanism to ensure legibility of superimposed content (applicable to layer content only)

### State (optional)

The state characterizes the interactional state of an interface element (e.g., Hover, Active, Disabled), making it possible to visually communicate its reactivity to the user.

# **Accessibility**

Accessibility is a fundamental principle guiding the design of this color system. As demonstrated in the Color Primitive section, the methodical standardization of luminance values (L\*) ensures consistent contrast ratios, regardless of the theme or display mode selected. This systematic approach eliminates the need to re-evaluate accessibility parameters when implementing new themes, ensuring ongoing compliance with WCAG accessibility standards. The main objective is to establish an accessibility framework that is invariant and resilient in the face of multiple usage contexts.

# **Technical implementation**

Due to all the changes and the token architecture, all CSS variables have changed. You must therefore update your CSS variables. It is absolutely necessary to regenerate your tokens with the command `cunningham -g css,ts,js` to get the new CSS variables.

In the case of theme tokens, all primitive values are in `theme.globals`. This corresponds to primitive colors, transitions, fonts, spacings, breakpoints, font weights, font families, etc.
As a result, all contextual values are in `theme.contextuals`. This corresponds to background colors, content colors, border colors, palette colors, etc.

```json
// Old structure
{
  "themes": {
    "default": {
      "theme": {
        "colors": "...",
        "font": "...",
        "spacings": "...",
        "breakpoints": "...",
        ...
      },
      "components": {
        "button": {
          "...": "..."
        }
      }
    }
  }
}


// New structure
{
  "themes": {
    "default": {
      "globals": {
        "colors": "...",
        "font": "...",
        "spacings": "...",
        "breakpoints": "...",
        ...
      },
      "contextuals": {
        "background": {
          "...": "..."
        },
        "content": {
          "...": "..."
        },
        "border": {
          "...": "..."
        }
      },
      "components": {
        "button": {
          "...": "..."
        },
        ...
      }
    }
  }
}
```

## **Migration Steps**

### **1. Update Dependencies**

First, update your `package.json` to use version 4.0.0:

```json
{
  "dependencies": {
    "@gouvfr-lasuite/cunningham-react": "^4.0.0"
  }
}
```

### **2. Regenerate Tokens**

Run the token generation command to get the new CSS variables:

```bash
cunningham -g css,ts,js
```

This command will generate the new CSS variables compatible with the new structure.

### **3. Update CSS Variables in Your Code**

All your references to old CSS variables will need to be updated. The new variables follow this structure:

```css
/* Old structure (v3) */
.test {
  color: var(--c--theme--colors--primary-500);
}

/* New structure (v4) */
.test {
  color: var(--c--globals--colors--brand-500);
  color: var(--c--contextuals--background--semantic--brand--primary);
  color: var(--c--contextuals--content--semantic--brand--primary);
  color: var(--c--contextuals--border--semantic--brand--primary);
  color: var(--c--contextuals--palette--brand--primary);
}
```

### **3. Update Button Props**

For buttons, you need to update the `color` and `variant` props to use the new structure.
The color prop corresponds to the primitive color and the variant prop corresponds to the button type.

```tsx
/* Old structure (v3) */
<Button color="primary" />

/* New structure (v4) */
<Button color="brand" variant="primary" />
<Button color="neutral" variant="secondary" />
<Button color="error" variant="tertiary" />
<Button color="warning" variant="bordered" />
```

### **4. Verify Accessibility**

The new architecture automatically ensures WCAG accessibility standards compliance through methodical standardization of luminance values (L\*). Contrast ratios are now consistent regardless of the selected theme or display mode.

## **Migration Benefits**

1. **Enhanced Accessibility**: Automatic compliance with WCAG standards
2. **Mode Management**: Native support for light/dark modes
3. **Visual Consistency**: Automatic propagation of color changes
4. **Simplified Maintenance**: No need to re-evaluate accessibility parameters when adding new themes

## **Important Notes**

- **Mandatory Migration**: The update is not optional as all CSS variables have changed
- **Testing Required**: Verify that all your custom components using CSS variables work correctly after migration
- **Documentation**: Consult the official documentation for new color patterns and best practices

This migration represents a significant but necessary investment to benefit from a more robust, accessible, and maintainable design system.
