> ## Oymyakon DS index
> Fetch the full index at: https://super-dollop-pzmo65r.pages.github.io/llms.txt
> HTML preview: https://super-dollop-pzmo65r.pages.github.io/colors.html
> Source: tokens/rules/color-rules.md, tokens/generated/primitives.css, tokens/generated/semantic.css

---

# Color Rules (Oymyakon DS · Colors 3.13.0)

Source: Figma — `🌈 Colors 3.13.0`, file `p8LXCOPy2B7bU3sX8N5E4G`.
All colors live in the **Variables panel** (not on the board). The file contains two color collections:

| Collection | Purpose |
|---|---|
| `Primitives` | Primitives — technical base (alpha layers, grey steps) |
| `Oymyakon` | Semantic tokens (Text&Icons, Background, Surface, Skeleton, Border, DoubleColor, Pastel, Accent, Constant, Safety, Shadow) |

The cards on the board (`Text&Icons`, `Background`, `Surface`, etc.) are a **visualization** of the `Oymyakon` collection: each table shows the name, color, opacity, and usage of a variable from the panel. The board does not store color — it displays it.

Read these rules **before every task** that involves color: when building a component, when describing state/style in a specification, when reviewing layouts.

---

## 0. General Principles

### 0.1 What "color" means in Oymyakon
In the DS, color is described by two layers of variables:

1. **Primitives** — the `Primitives` collection in the Variables panel. Contains technical base variables: alpha series (`Transparent/Graphite N`, `Transparent/White N`). Primitives are **not applied directly** in layouts and components — only as a foundation for semantic tokens or through semantic tokens.
2. **Semantic tokens** — the `Oymyakon` collection in the Variables panel. Each token is a name with a role that describes **where and why** to apply a color. Under the hood, a token contains either a direct HEX value or an alias to a primitive from the `Primitives` collection (for alpha variants). Semantic tokens are what is used in layouts and in code.

One-directional rule: **Components and layouts → Semantic tokens (`Oymyakon`) → Primitives (`Primitives`)**. The reverse is not allowed. Direct use of primitives in a layout is prohibited.

### 0.2 Where to find in Figma
- `Variables panel` → `🌈 Colors 3.13.0` → `Oymyakon` — select the semantic token for fill / stroke / text.
- `Variables panel` → `🌈 Colors 3.13.0` → `Primitives` — only for extending the semantics with new alpha tokens. Never bind directly to a layer.
- Board cards on the `Colors` page — a reference: name, visual, opacity, usage. Copy the token name, apply it through Variables.

### 0.3 Themes (Light / Dark)
All semantic tokens are bound to two themes:

- `[Light]` — light theme.
- `[Dark]` — dark theme.

At the layout/component level, the **same token name** is used — the value is substituted automatically depending on the active theme. You cannot hardcode HEX and you cannot substitute a token of one theme with a token of another.

All token groups are described for both themes: Light and Dark. Values are set through aliases to primitives from the `Primitives` collection (see section 11).

### 0.4 Description tone of voice
- Token purpose descriptions are neutral, without `must` / `never` / `always`.
- Each line provides one rule or one value.
- Inside specifications — English. Chat communication — Russian.

---

## 1. Structure of the `Colors 3.13.0` file

On the `Colors` page there are cards (frames), each representing one group of semantic tokens:

| Group | Purpose | Number of tokens |
|---|---|---|
| `TextAndIcon` | Text and icon color | 14 × (Light + Dark) |
| `Background` | Color of the background layer of a screen/surface | 10 × (Light + Dark) |
| `Surface` | Color of the second layer on top of Background (cards, sheet, overlay) | 9 × (Light + Dark) |
| `Skeleton` | Loading state / placeholder | 3 × (Light + Dark) |
| `Border` | Element strokes | 7 × (Light + Dark) |
| `DoubleColor` | Paired colors for two-color components (outline + bg) | 4 × (Light + Dark) |
| `Pastel` | Pastel backgrounds for informational and promo blocks | 12 × (Light + Dark) |
| `Accent` | Bright accent colors (Blue / Orange / Red / Green / Drive Green / Yellow) | 12 × (Light + Dark) |
| `Constant` | Theme-fixed family steps — one value in both themes | 18 × (Light = Dark) |
| `Safety` | Safety-team tokens (pastel base + fixed blue accent) | 2 × (Light + Dark) |
| `Shadow` | Elevation shadow colour — dissolves in Dark | 1 × (Light + Dark) |

Each card is a table with columns: **Name · Color · Opacity · Usage**.

---

## 2. Token naming

### 2.1 Format
A semantic token in Figma is a variable of the form `Group/Name` or `Group/SubGroup/Name`:

```
TextAndIcon/Primary
Background/BaseGrey
Surface/Overlay
Skeleton/Wave
Border/Inform
DoubleColor/Bg
Pastel/Blue 1
Accent/Drive Green 2
```

The separator is `/`. A space is allowed only within a name (`Drive Green 1`), **not** around `/`.

### 2.2 How the name is used
- In Figma the token name is the **source of truth**. When adding a new token, align the name with the existing style and record it in this table.
- In code (iOS / Android / Flutter) the name maps 1-to-1: `TextAndIcon/Primary` → `textAndIcon.primary`.
- In the specification (Figma `Specification`) the token name is specified in the **States and styles** and **Layout** blocks (see `spec-rules.md`, sections 5.3, 5.4).

### 2.3 Prohibited names
- `Default` for the first state — in Oymyakon this is `Standard` (see `spec-rules.md`, section 5.3). For color it is the same: there is no `*/Default` token in the sense of "initial state."
- Numbered steps without a group: `gray-900`, `blue-500` — **primitives only**, not semantic.
- HEX in the name: `colorFFFFFF`, `color191817` — prohibited.

---

## 3. Group `TextAndIcon`

14 text and icon tokens. The only group with a full Night theme. Values are specified through references to primitives.

| Token | Light | Dark | Usage |
|---|---|---|---|
| `TextAndIcon/Primary` | `Grey/900` | `White/White` | Primary text and icons (headings, body, Icon/primary) |
| `TextAndIcon/Secondary` | `Grey/700` | `Grey/400` | Secondary text, labels, subtitles, hints |
| `TextAndIcon/Disabled` | `Grey/400` | `Grey/300` | Text and icons in disabled elements |
| `TextAndIcon/Graphite` | `Graphite/850` | `Grey/600` | Text on graphite surfaces (`Background/AlwaysGraphite`) |
| `TextAndIcon/Brand` | `Drive Green/250` | `Drive Green/250` | Brand (lime) — only on dark contrasting backgrounds |
| `TextAndIcon/Accent` | `Blue/700` | `Blue/600` | Links, activity highlighting, value emphasis |
| `TextAndIcon/Success` | `Green/700` | `Green/500` | Positive statuses, confirmations |
| `TextAndIcon/Warning` | `Orange/700` | `Orange/600` | Warnings, attention |
| `TextAndIcon/Error` | `Red/700` | `Red/600` | Errors, destructive actions |
| `TextAndIcon/InversePrimary` | `White/White` | `Grey/900` | Text/icon on top of `Background/InversePrimary` |
| `TextAndIcon/AlwaysDark` | `Grey/900` | `Grey/900` | Fixed dark (does not change between themes) |
| `TextAndIcon/AlwaysLight` | `White/White` | `White/White` | Fixed light (does not change between themes) |
| `TextAndIcon/Yellow` | `Yellow/250` | `Yellow/250` | Fixed yellow glyph accent (rating-style highlights); does not change between themes |
| `TextAndIcon/Transparent` | `Transparent/Black 75%` | `Transparent/White 68%` | Semi-transparent text/icon over media and coloured surfaces |

**TextAndIcon selection rules:**
1. Default text is `Primary`. Secondary text (labels, metadata) is `Secondary`.
2. `Brand` is prohibited on light backgrounds and on `Background/BaseWhite` — only on dark surfaces (`InversePrimary`, `AlwaysGraphite`).
3. `AlwaysDark` / `AlwaysLight` — only in components with a **fixed** background (banners, promo, embedded in an image). Everything else uses the paired `Primary`/`InversePrimary`.
4. Status tokens `Success/Warning/Error` are used **only for semantic elements** (validation, badges, alerts). They are not used for regular text.

---

## 4. Group `Background`

The background layer of a screen. 10 tokens. Applied as `fill` on the root frame of a screen or large sections.

| Token | Light | Dark | Usage |
|---|---|---|---|
| `Background/BaseWhite` | `White/White` | `Black/Black` | Fixed base white/black background |
| `Background/BaseGrey` | `Grey/100` | `Black/Black` | Fixed warm light-grey background |
| `Background/Primary` | `White/White` | `Grey/875` | Base background for screens (inverts between themes) |
| `Background/Secondary` | `Grey/200` | `Transparent/Grey 3` | Secondary background, grouping zones |
| `Background/Brand` | `Drive Green/250` | `Drive Green/250` | Brand lime background — promo, CTA sections, splash |
| `Background/InversePrimary` | `Grey/875` | `White/White` | Inverse background — banners, footer, dark modals |
| `Background/AlwaysLight` | `White/White` | `White/White` | Always white regardless of theme |
| `Background/AlwaysGraphite` | `Graphite/850` | `Graphite/850` | Always graphite regardless of theme — bottom-sheet, dark-cards |
| `Background/AlwaysDark` | `Grey/875` | `Grey/875` | Fixed dark background (does not change between themes) |
| `Background/PopUp` | `Transparent/Graphite 4` | `Transparent/Graphite 5` | Popup overlay background / modal backdrop |

**Background selection rules:**
1. Default screen background is `Primary`. In Dark this is dark (`Grey/875`), in Light — white.
2. Use `Base*` and `Always*` when the visual **should not** invert when the theme changes (e.g., a branded label, a map).
3. On `InversePrimary` and `AlwaysGraphite`, text/icons use `TextAndIcon/InversePrimary` (or `AlwaysLight`).
4. `PopUp` — only for the backdrop. The modal surface above it starts with a `Background` base — `BaseGrey` when it has islands, `Primary` when it does not — and `Surface/OnWhite` / `Surface/OnGrey` go on top of that base. Do not skip the Background level by placing `Surface` directly on the backdrop.

---

## 5. Group `Surface`

The second layer on top of Background (cards, sheet, overlay). 8 tokens, including those with alpha.

| Token | Light | Dark | Usage |
|---|---|---|---|
| `Surface/OnWhite` | `Grey/100` | `Grey/850` | Card/container surface on top of `Background/Primary` and `Background/BaseWhite` |
| `Surface/OnGrey` | `White/White` | `Grey/800` | Surface on top of `Background/BaseGrey` and `Background/Secondary` — reversed contrast |
| `Surface/Overlay` | `Transparent/Grey 1` | `Transparent/White 1` | Dimming for semi-transparent overlays, bottom-sheet backdrop |
| `Surface/WhiteOverlay` | `Transparent/White 1` | `Transparent/White 1` | Lightening overlay on dark backgrounds |
| `Surface/PressedOverlay` | `Black/Black` | `Black/Black` | Pressed state for any surface |
| `Surface/ContrastOverlay` | `Transparent/Black 20%` | `Transparent/White 24%` | Contrast-raising overlay that flips with the theme |
| `Surface/DarkOverlay` | `Transparent/Black 20%` | `Transparent/Black 20%` | Darkening overlay, the same in both themes *(new in 3.10.0)* |
| `Surface/Floating` | `White/White` | `Grey/870` | The surface of a floating element (FAB, floating chrome). In Dark it is a step **lighter** than `Background/Primary` (`Grey/870` vs `Grey/875`) — elevation through lightness where a shadow cannot separate *(new in 3.10.0)* |
| `Surface/InverseOverlay` | `Transparent/White 8%` | `Transparent/Black 5%` | Overlay for elements sitting on **inverse** surfaces (`Background/InversePrimary`, `AlwaysGraphite`): lightens the dark inverse surface in Light, darkens the light one in Dark *(new in 3.13.0)* |

**Surface selection rules:**
1. `Surface` is the **second layer**. On a clean screen with no Background, Surface is not needed.
2. Choose Surface based on the parent: on `Primary`/`BaseWhite` → `OnWhite`, on `BaseGrey`/`Secondary` → `OnGrey`. Never use `OnWhite` on top of `BaseGrey` — contrast will disappear.
3. `*Overlay` are **alpha tokens**. They cannot be used as a solid background.
4. `PressedOverlay` is added **on top of** the main surface, not in place of it.

---

## 6. Group `Skeleton`

3 tokens for loading states.

| Token | Light | Dark | Usage |
|---|---|---|---|
| `Skeleton/OnWhite` | `Grey/100` | `Grey/850` | Skeleton placeholder on top of a white surface |
| `Skeleton/WhiteOverlay` | `Transparent/White 2` | `Transparent/White 2` | Skeleton placeholder on top of a colored/dark surface |
| `Skeleton/Wave` | `Transparent/White 4` | `Transparent/White 1` | The moving "wave" of the shimmer animation |

**Rules:**
1. Skeleton always has `accessibilityLiveRegion = Loading` at the component level (see `spec-rules.md`, section 5.14).
2. `Wave` is applied on top of `Skeleton/OnWhite` or `Skeleton/WhiteOverlay` with the motion token `shimmer`.
3. Skeleton is the same for all component presets — do not describe it separately for each.

---

## 7. Group `Border`

7 stroke tokens. Applied as `stroke` (inner or outer).

| Token | Light | Dark | Usage |
|---|---|---|---|
| `Border/Default` | `Grey/150` | `Grey/800` | Base stroke for cards and inputs in a neutral state |
| `Border/Active` | `Grey/900` | `White/White` | Stroke for a selected / focused element |
| `Border/Inform` | `Blue/700` | `Blue/600` | Stroke for informational blocks |
| `Border/Success` | `Green/600` | `Green/500` | Success — validation, completed |
| `Border/Warning` | `Orange/700` | `Orange/600` | Warning |
| `Border/Error` | `Red/700` | `Red/600` | Error — invalid input, destructive border |
| `Border/Transparent` | `#000000` @ 5% | `Grey 850` @ 90% | Technically transparent border — reserves 1px without a visual effect (prevents layout shift when `Active`/`Error` appears). Dark re-pointed from `White 8%` in 3.10.0 |

**Border selection rules:**
1. Stroke thickness in the DS is `0.5px` or `1px`. Other values — only in approved exceptions.
2. `Border/Transparent` is the only way to "hide" a stroke without changing the element's size.
3. Status tokens `Inform/Success/Warning/Error` are used in pairs with the matching `TextAndIcon/*` status — consistency is required.

---

## 8. Group `DoubleColor`

Paired tokens for two-color components (icon + backing). 4 tokens.

| Token | Light | Dark | Usage |
|---|---|---|---|
| `DoubleColor/Outline` | `Grey/900` | `Drive Green/250` | Stroke/outline (icon line) |
| `DoubleColor/Outline Inverse` | `Drive Green/250` | `Grey/900` | Inverse outline — when the component is placed on a dark/brand background |
| `DoubleColor/Bg` | `Drive Green/150` | `Transparent/Drive Green 0` | Fill background (icon backing) |
| `DoubleColor/Bg Inverse` | `Transparent/Drive Green 0` | `Drive Green/150` | Inverse fill — the backing "disappears" on a dark background, leaving only the outline |

**DoubleColor usage rules:**
1. Always used as a **pair**: `Outline` + `Bg` **or** `Outline Inverse` + `Bg Inverse`. Mixing pairs from different modes is not allowed.
2. Pair selection is based on the parent background: light background → regular pair, dark/brand background → Inverse.
3. In Dark theme, `Bg` becomes transparent (`Transparent/Drive Green 0`) and `Bg Inverse` becomes filled (`Drive Green/150`). This is an intentional inversion — do not change manually.

---

## 8.5 Pastel + Accent — the colour constructor

`Pastel` (§9) and `Accent` (§10) are not two separate palettes — they are **one
two-axis system** for building tonal compositions. Read them together.

**Two axes:**

| Axis | Values | Carries |
|---|---|---|
| **Tone** | Blue · Orange · Red · Green · Drive Green | *meaning / category* — info, warning, error, success, brand |
| **Intensity** | `Pastel 1` → `Pastel 2` → `Accent 1` → `Accent 2` | *priority* — how much the element should stand out |

Tone is fixed per composition (you stay in one family); intensity is the dial you
turn. Lower intensity recedes, higher intensity asserts. **Intensity is not
decoration — it is the on-screen language of importance.**

### Rule A — layering within one element

Build a single component by climbing the intensity scale with nesting depth, staying
in one tone. The container takes the softest step; nested elements step up; the
accent detail (icon, indicator) sits at the top.

> **Example — `Tips` block (one tone: Blue)**
> - block background → `Pastel/Blue 1`
> - button on the block → `Pastel/Blue 2`
> - icon inside → `Accent/Blue 2`
>
> The intensity ladder mirrors the nesting ladder. Never cross tones inside one
> composition (no `Pastel/Blue 1` + `Accent/Red 2`).

### Rule B — relative hierarchy between elements

On a screen with several blocks **of the same tone**, intensity sets their relative
priority. A `Pastel` block reads as "for your information / background"; an `Accent`
block reads as "this is the main thing / CTA". The eye ranks them by saturation
automatically — so use the dial to say *which element matters more*, not just to
colour them.

The extreme of Rule B is taking a **whole surface** to the top of the scale: an
entire promotional bottom sheet filled with `Accent` reads instantly as a
limited-time / promo story — the whole block is the signal.

### Choosing where to sit on the scale

- Element should **not compete** with its surroundings (ambient info, passive banner)
  → `Pastel`.
- Element **must be noticed** (status, CTA, promo, the one action that matters)
  → `Accent`.
- Two elements of one tone need a **clear winner** → softer on `Pastel`, the lead on
  `Accent`.

Then drop to §9 / §10 for the exact `1` vs `2` step and the Light/Dark values.

---

## 9. Group `Pastel`

12 pastel backgrounds for informational blocks, promo tags, and non-intrusive banners.
The **lower half** of the constructor's intensity axis (see §8.5).

| Token | Light | Dark (alpha) |
|---|---|---|
| `Pastel/Blue 1` | `Blue/100` | `Transparent/Blue 700 (28%)` |
| `Pastel/Blue 2` | `Blue/200` | `Transparent/Blue 700 (41%)` |
| `Pastel/Orange 1` | `Orange/100` | `Transparent/Orange 700 (20%)` |
| `Pastel/Orange 2` | `Orange/200` | `Transparent/Orange 700 (36%)` |
| `Pastel/Red 1` | `Red/100` | `Transparent/Red 700 (23%)` |
| `Pastel/Red 2` | `Red/200` | `Transparent/Red 700 (32%)` |
| `Pastel/Green 1` | `Green/100` | `Transparent/Green 700 (22%)` |
| `Pastel/Green 2` | `Green/200` | `Transparent/Green 700 (30%)` |
| `Pastel/Drive Green 1` | `Drive Green/100` | `Transparent/Drive Green 250 (11%)` |
| `Pastel/Drive Green 2` | `Drive Green/150` | `Transparent/Drive Green 250 (15%)` |
| `Pastel/Yellow 1` | `Yellow/100` | `Transparent/Yellow 250 (25%)` |
| `Pastel/Yellow 2` | `Yellow/200` | `Transparent/Yellow 250 (47%)` |

**Pastel selection rules:**
1. Pastel is **background only**. For text/icons on top of pastel, use the corresponding `Accent/*` from the same family (Blue → Blue, Red → Red, etc.).
2. Within each family: `1` is lighter/more subtle, `2` is denser/more prominent. Never combine `Pastel/Blue 1` + `Accent/Red 2` or vice versa — color semantics must match (one tone, see §8.5).
3. The `Drive Green` family is reserved for the delivery vertical (InDrive Courier / Delivery). Do not use in the taxi flow by default.
4. In Dark theme, Pastel is implemented through alpha primitives (`Transparent/*`) — do not replace with solid colors.
5. The Yellow family's dark alpha base is its **250** step (like Drive Green), not a 700 — yellow is a light hue, its identity step sits high on the ramp.

---

## 10. Group `Accent`

12 accent colors — high-contrast, for icons and text on pastel backgrounds, statuses, and CTA highlights.
The **upper half** of the constructor's intensity axis (see §8.5).

| Token | Light | Dark |
|---|---|---|
| `Accent/Blue 1` | `Blue/500` | `Blue/400` |
| `Accent/Blue 2` | `Blue/700` | `Blue/600` |
| `Accent/Orange 1` | `Orange/500` | `Orange/400` |
| `Accent/Orange 2` | `Orange/700` | `Orange/600` |
| `Accent/Red 1` | `Red/500` | `Red/400` |
| `Accent/Red 2` | `Red/700` | `Red/600` |
| `Accent/Green 1` | `Green/500` | `Green/400` |
| `Accent/Green 2` | `Green/700` | `Green/600` |
| `Accent/Drive Green 1` | `Drive Green/500` | `Drive Green/400` |
| `Accent/Drive Green 2` | `Drive Green/600` | `Drive Green/500` |
| `Accent/Yellow 1` | `Yellow/250` | `Yellow/200` |
| `Accent/Yellow 2` | `Yellow/400` | `Yellow/300` |

**Accent selection rules:**
1. Within a family: `1` is lighter/highlighted, `2` is denser/saturated. `2` is used for text and icons on `Pastel/*`, `1` — for accents on dark backgrounds.
2. `Accent/Blue 2`, `Accent/Orange 2`, `Accent/Red 2`, `Accent/Green 2` share their primitives with `Border/Inform`, `Border/Warning`, `Border/Error`, `Border/Success`. When changing an Accent, always check the related Border.
3. `Accent/Drive Green` — only in InDrive Courier / Delivery.
4. **`Accent/Blue 2` is back as the generic blue accent** (3.13.0). Its 3.11.0 rename to `Accent/Safety` is reverted: the Safety team's tokens moved to their own `Safety/*` group (§10.6) and the accent scale is uniform again (`Blue/700` / `Blue/600`).
5. The Yellow accents sit **higher on the ramp** than other families (`250`/`400`, not `500`/`700`): yellow is the lightest hue, its chroma peak lives in the light zone, and its darks are mustard, not amber.

---

## 10.5 Group `Constant`

18 theme-fixed colour steps — the same value in Light and Dark. Three intensity steps per family,
mapped to the primitive ramp as `1` = 200, `2` = 300, `3` = 600:

| Family | 1 | 2 | 3 |
|---|---|---|---|
| `Constant/Blue` | `Blue/200` | `Blue/300` | `Blue/600` |
| `Constant/Orange` | `Orange/200` | `Orange/300` | `Orange/600` |
| `Constant/Red` | `Red/200` | `Red/300` | `Red/600` |
| `Constant/Green` | `Green/200` | `Green/300` | `Green/600` |
| `Constant/Drive Green` | `Drive Green/200` | `Drive Green/300` | `Drive Green/600` |
| `Constant/Yellow` | `Yellow/200` | `Yellow/300` | `Yellow/600` |

**Constant selection rules:**
1. For elements that must keep one colour in **both** themes — artwork fills, map overlays, media
   chrome — the same role `Always*` plays for backgrounds and text.
2. Not a substitute for `Pastel`/`Accent` in themed UI: a surface that should react to the theme
   keeps the themed pair. Reach for `Constant` only when theme-reaction is the bug, not the feature.

---

## 10.6 Group `Safety` *(new in 3.13.0)*

The Safety team's own tokens — the blue is under their jurisdiction and does not follow the
generic accent stepping.

| Token | Light | Dark | Usage |
|---|---|---|---|
| `Safety/Safety 1` | `Blue/100` (via `Pastel/Blue 1`) | `Transparent/Blue 700 (28%)` | Pastel base for Safety surfaces — mirrors `Pastel/Blue 1` |
| `Safety/Safety 2` | `Blue/700` | `Blue/700` | The Safety accent — theme-fixed (ex `Accent/Safety`) |

**Notes:**
1. In Figma `Safety/Safety 1` (Light) aliases the semantic `Pastel/Blue 1`, not a primitive. The
   repo model is semantic → primitive only, so the sync dereferences it one level to `Blue/100`
   (the sync script does this automatically and prints an `ℹ Dereferenced` line).
2. `Safety/Safety 2` keeps `Blue/700` in **both** themes — the one accent that does not step to
   600 in Dark. Do not use it as a generic blue accent; that role is `Accent/Blue 2` again.

---

## 10.7 Group `Shadow` *(new in 3.13.0)*

| Token | Light | Dark | Usage |
|---|---|---|---|
| `Shadow/Primary` | `Transparent/Black 5%` | `Transparent/Black 0%` | The elevation shadow **colour**. In Dark it is fully transparent — shadows dissolve, and elevation is carried by surface lightness instead (see `Surface/Floating`, §5) |

**Notes:**
1. This token is the shadow *colour only*. Shadow **geometry** (offset/blur/spread) stays in the
   elevation tokens (`--shadow-s/m/l/pressed`, `tokens/src/effects/elevation.json`) — the two are
   separate namespaces in CSS (`--shadow-primary` vs `--shadow-s`).
2. The elevation box-shadows do not yet consume this colour — wiring `elevation.json` to
   `Shadow/Primary` (and thereby getting theme-aware shadows) is a separate follow-up decision.

---

## 11. Primitives

The `Primitives` collection inside `🌈 Colors 3.13.0` exists only in the `Variables panel` — it is not on the board. It contains the base color scale (steps from 50 to 900) and alpha utilities. Primitives are **not applied directly** in layouts — only as a foundation for semantic tokens.

### 11.1 Base colors

| Primitive | HEX |
|---|---|
| `Black` | `#000000` |
| `White` | `#FFFFFF` |

### 11.2 Grey

| Step | HEX |
|---|---|
| `Grey/900` | `#181818` |
| `Grey/875` | `#1C1C1C` |
| `Grey/850` | `#303030` |
| `Grey/800` | `#535353` |
| `Grey/700` | `#6C6C6C` |
| `Grey/600` | `#81807B` |
| `Grey/500` | `#9D9C95` |
| `Grey/400` | `#B2B1A9` |
| `Grey/300` | `#C6C4BC` |
| `Grey/250` | `#CFCEC5` |
| `Grey/200` | `#E0DED5` |
| `Grey/150` | `#E6E5DC` |
| `Grey/100` | `#F2F1EB` |
| `Grey/75` | `#F3F2ED` |
| `Grey/50` | `#F9F8F6` |

### 11.3 Graphite

| Step | HEX |
|---|---|
| `Graphite/900` | `#15191E` |
| `Graphite/850` | `#323941` |
| `Graphite/800` | `#4D535B` |
| `Graphite/700` | `#676C73` |
| `Graphite/600` | `#7B8189` |
| `Graphite/500` | `#979CA3` |
| `Graphite/400` | `#ADB1B7` |
| `Graphite/300` | `#C1C4C8` |
| `Graphite/250` | `#CBCED1` |
| `Graphite/200` | `#DCDEE0` |
| `Graphite/150` | `#E3E5E6` |
| `Graphite/100` | `#EAEBEC` |
| `Graphite/75` | `#F1F2F3` |
| `Graphite/50` | `#F8F8F9` |

### 11.4 Red

| Step | HEX |
|---|---|
| `Red/850` | `#6E1A1D` |
| `Red/800` | `#AA1E2A` |
| `Red/700` | `#FE003B` |
| `Red/600` | `#FF3E4E` |
| `Red/500` | `#FF525D` |
| `Red/400` | `#FF7074` |
| `Red/300` | `#FF9F9E` |
| `Red/250` | `#FFB9B8` |
| `Red/200` | `#FFD1D0` |
| `Red/150` | `#FFDAD9` |
| `Red/100` | `#FFE8E8` |
| `Red/75` | `#FFEDED` |
| `Red/50` | `#FFF6F6` |

### 11.5 Blue

| Step | HEX |
|---|---|
| `Blue/850` | `#2E327C` |
| `Blue/800` | `#3A46C6` |
| `Blue/700` | `#3F62FF` |
| `Blue/600` | `#4980FF` |
| `Blue/500` | `#5696FF` |
| `Blue/400` | `#64ABFF` |
| `Blue/300` | `#85C4FF` |
| `Blue/250` | `#9ED5FF` |
| `Blue/200` | `#BBE5FF` |
| `Blue/150` | `#C5EBFF` |
| `Blue/100` | `#D1F1FF` |
| `Blue/75` | `#E0F6FF` |
| `Blue/50` | `#EFFBFF` |

### 11.6 Drive Green

| Step | HEX |
|---|---|
| `Drive Green/900` | `#181A08` |
| `Drive Green/850` | `#3B4117` |
| `Drive Green/800` | `#525B1A` |
| `Drive Green/700` | `#6C7A1D` |
| `Drive Green/600` | `#83971C` |
| `Drive Green/500` | `#8DA522` |
| `Drive Green/400` | `#9CBA24` |
| `Drive Green/300` | `#B6E421` |
| `Drive Green/250` | `#C1F11D` |
| `Drive Green/200` | `#CAFA51` |
| `Drive Green/150` | `#D6FB94` |
| `Drive Green/100` | `#DBFDA6` |
| `Drive Green/75` | `#E9FED0` |
| `Drive Green/50` | `#F0FFDF` |

### 11.7 Green

| Step | HEX |
|---|---|
| `Green/850` | `#1E4E2E` |
| `Green/800` | `#007C1F` |
| `Green/700` | `#00973B` |
| `Green/600` | `#27B24F` |
| `Green/500` | `#3CBB5B` |
| `Green/400` | `#4EC769` |
| `Green/300` | `#6ED982` |
| `Green/250` | `#8FEA9D` |
| `Green/200` | `#AFF1B8` |
| `Green/150` | `#C4F3C9` |
| `Green/100` | `#D5F5D8` |
| `Green/75` | `#E4F8E6` |
| `Green/50` | `#F2FCF3` |

### 11.8 Orange

| Step | HEX |
|---|---|
| `Orange/850` | `#8C1F08` |
| `Orange/800` | `#DA3200` |
| `Orange/700` | `#FF5827` |
| `Orange/600` | `#FF7643` |
| `Orange/500` | `#FF8858` |
| `Orange/400` | `#FF9A64` |
| `Orange/300` | `#FFAF7A` |
| `Orange/250` | `#FFC392` |
| `Orange/200` | `#FFDAB6` |
| `Orange/150` | `#FFE3C1` |
| `Orange/100` | `#FFECCF` |
| `Orange/75` | `#FCF1D4` |
| `Orange/50` | `#FEF9E6` |

### 11.8a Yellow

Added in 3.11.0. Built in OKLCH on the palette's own law: the shared light-zone lightness ladder,
a deep branch riding one notch above Orange (yellow is the lightest hue), chroma at ~97% of the
sRGB gamut ceiling per step, and a mustard hue (~95.5°) held through the dark zone — the Green
family's no-drift strategy, keeping the darks clear of Drive Green's olive zone.

| Step | HEX |
|---|---|
| `Yellow/850` | `#605006` |
| `Yellow/800` | `#937C0E` |
| `Yellow/700` | `#B69A14` |
| `Yellow/600` | `#C3A516` |
| `Yellow/500` | `#CEAE18` |
| `Yellow/400` | `#D7B71F` |
| `Yellow/300` | `#E3C32D` |
| `Yellow/250` | `#EFD14A` |
| `Yellow/200` | `#FAE372` |
| `Yellow/150` | `#FAEA97` |
| `Yellow/100` | `#FBF1B7` |
| `Yellow/75` | `#F9F3CD` |
| `Yellow/50` | `#FDFAE1` |

### 11.9 Transparent (alpha utilities)

Semi-transparent layers used to compose overlay, pressed, and skeleton tokens.

| Primitive | Base color | Opacity | Used in |
|---|---|---|---|
| `Transparent/Orange 700` | `#FF5827` | 20% | — |
| `Transparent/Orange 700` | `#FF5827` | 36% | — |
| `Transparent/Orange 700` | `#FF5827` | 46% | — |
| `Transparent/Blue 700` | `#3F62FF` | 28% | — |
| `Transparent/Blue 700` | `#3F62FF` | 41% | — |
| `Transparent/Blue 700` | `#3F62FF` | 53% | — |
| `Transparent/Red 700` | `#FE003B` | 23% | — |
| `Transparent/Red 700` | `#FE003B` | 32% | — |
| `Transparent/Red 700` | `#FE003B` | 43% | — |
| `Transparent/Green 700` | `#00973B` | 22% | — |
| `Transparent/Green 700` | `#00973B` | 30% | — |
| `Transparent/Green 700` | `#00973B` | 42% | — |
| `Transparent/Drive Green 250` | `#C1F11D` | 0% | `DoubleColor/Bg Inverse` |
| `Transparent/Drive Green 250` | `#C1F11D` | 8% | — |
| `Transparent/Drive Green 250` | `#C1F11D` | 11% | — |
| `Transparent/Drive Green 250` | `#C1F11D` | 15% | — |
| `Transparent/Grey 800` | `#53534F` | 8% | — |
| `Transparent/Grey 800` | `#53534F` | 16% | `Surface/Overlay`, bottom-sheet backdrop |
| `Transparent/Grey 800` | `#53534F` | 24% | Reserved for denser dimming overlays |
| `Transparent/Grey 800` | `#53534F` | 32% | — |
| `Transparent/Grey 850` | `#31302E` | 90% | — |
| `Transparent/White` | `#FFFFFF` | 8% | — |
| `Transparent/White` | `#FFFFFF` | 16% | `Surface/WhiteOverlay` |
| `Transparent/White` | `#FFFFFF` | 24% | `Skeleton/WhiteOverlay` |
| `Transparent/White` | `#FFFFFF` | 32% | — |
| `Transparent/White` | `#FFFFFF` | 56% | `Skeleton/Wave` |
| `Transparent/Graphite 900` | `#15191E` | 80% | — |
| `Transparent/Black` | `#000000` | 5% | — |
| `Transparent/Black` | `#000000` | 20% | — |
| `Transparent/Black` | `#000000` | 75% | — |

### 11.10 Gradient

| Primitive | Base color | Opacity |
|---|---|---|
| `Gradient/Primary` | `#000000` | 20% |

**Rules for working with Primitives:**
1. Use only as an alias for semantic tokens. Direct application to a fill / stroke layer is not allowed.
2. A new alpha step is added to `Primitives`, then a semantic token with a role-based name is created on top of it.
3. Do not decrease / increase the opacity of a layer to which a `Transparent/*` token is already applied — this results in double multiplication.

---

## 12. Token selection — decision tree

1. **Is it text or an icon?** → `TextAndIcon/*`.
2. **Is it the background of an entire screen/large section?** → `Background/*`.
3. **Is it a card, sheet, modal, or element on top of a background?** → `Surface/*`.
4. **Is it a stroke?** → `Border/*`.
5. **Is it a loading state?** → `Skeleton/*`.
6. **Is it a two-color icon (outline + backing)?** → `DoubleColor/*` (as a pair).
7. **Is it a subtle informational background under text?** → `Pastel/*` + `Accent/*` for text.
8. **Is it a bright accent / status / CTA?** → `Accent/*`.

---

## 13. Alpha and transparency

Alpha tokens always have a suffix in HEX (last 2 characters) or a visible `Opacity` in the Figma card:

| Token | Value | Opacity |
|---|---|---|
| `Surface/Overlay` | `#53534F29` | 16% |
| `Surface/WhiteOverlay` | `#FFFFFF29` | 16% |
| `Skeleton/WhiteOverlay` | `#FFFFFF3D` | 24% |
| `Skeleton/Wave` | `#FFFFFF8F` | 56% |
| `Border/Transparent` | `#0000000D` | 5% |
| `DoubleColor/Bg Inverse` | `#D6FB9400` | 0% |

**Rules:**
1. Opacity is defined **inside the token**. You cannot additionally reduce the opacity of the layer in Figma — this will result in double multiplication.
2. For new transparent tokens, use the step `5 / 16 / 24 / 40 / 56 / 72 / 88 %` — this is the accepted Oymyakon scale.

---

## 14. Contrast and a11y

1. The contrast of `TextAndIcon/Primary` against `Background/Primary` has been verified and meets WCAG AA (Day and Night).
2. The pair `TextAndIcon/Secondary` + `Background/Primary` — **AA for large text** (≥ 18pt or 14pt Bold). For small body text (12–14pt) use `Primary`.
3. The pair `TextAndIcon/Disabled` + any Background does not pass AA — this is acceptable, as Disabled is by spec not meant to be readable.
4. `TextAndIcon/Brand` (`#C1F11D`) **does not pass** AA on light backgrounds. Use only on `Background/InversePrimary` / `Background/AlwaysGraphite`.
5. When adding a status color, verify the pair with its `Background/*` through a contrast checker.

---

## 15. What is prohibited

- Inserting HEX directly into a component's fill / stroke — only through a token.
- Using a Day token together with a Night token manually (except `Always*`).
- Applying `TextAndIcon/Brand` on a light background.
- Replacing the transparent `DoubleColor/Bg Inverse` with an opaque color — the meaning of the inversion is lost.
- Mixing Pastel and Accent families of different colors (`Pastel/Blue 1` + `Accent/Red 2`).
- Using `Accent/Drive Green` outside the delivery vertical.
- Naming a token by its value (`gray-191817`) or by a component (`cell-bg`) — the name describes the **role**, not the visual.
- Creating "local" color variables at the screen/component level outside the `🌈 Colors` file.
- Decreasing / increasing the opacity of a layer on top of an alpha token.
- Using a Day token in the Night theme, even if it "looks fine."

---

## 16. Ready-Go checklist before publishing a layout / component

- [ ] All fill / stroke / text colors are bound to semantic tokens (in Dev Mode names are visible, not HEX).
- [ ] For each surface the correct Background → Surface → Text&Icon hierarchy is specified (layer order is respected).
- [ ] Component is verified in Day and Night (preview of both themes).
- [ ] Status states use the linked pair Text&Icon + Border (Success + Success, Error + Error, etc.).
- [ ] Disabled state — `TextAndIcon/Disabled` + muted Background or Overlay.
- [ ] Skeleton state uses `Skeleton/OnWhite` or `Skeleton/WhiteOverlay` + `Skeleton/Wave` with motion token.
- [ ] DoubleColor icons use the Outline + Bg pair of the same mode.
- [ ] Pastel backgrounds are accompanied by Accent text of the same family.
- [ ] No local-level variables and no raw HEX.
- [ ] Contrast verified for all status pairs and for `TextAndIcon/Secondary`.

---

## 17. History log

| Version | Date | Author | Change |
|---|---|---|---|
| 3.4.0 | 2026-04-23 | Eugene Beloussov | First version of rules based on `🌈 Colors 3.4.0`. All semantic groups described (Text&Icons, Background, Surface, Skeleton, Border, DoubleColor, Pastel, Accent), two-level Primitives → Semantic tokens model established (the `Primitives` collection with alpha utilities), selection rules, a11y, and prohibitions documented. |
| 3.4.1 | 2026-04-23 | Eugene Beloussov | Section 11 "Primitives" updated: full color scales added (Black, White, Grey 50–900, Graphite 50–900, Red 50–850, Blue 50–850, Drive Green 50–900, Green 50–850, Orange 50–850), Transparent utilities list expanded (Orange, Blue, Red, Green, Drive Green, Grey, White, Graphite 4–5), Gradient/Primary added. |
| 3.4.2 | 2026-04-23 | Eugene Beloussov | Oymyakon semantic palette updated: all tokens migrated from HEX to primitive aliases; Dark column added for all groups (TextAndIcon, Background, Surface, Skeleton, Border, DoubleColor, Pastel, Accent); theme terminology changed from Day/Night to Light/Dark; Background expanded to 9 tokens (PopUp added); Surface reduced to 5 tokens (duplicated Border/Default removed); DoubleColor updated to account for inversion in Dark theme. |
| 3.5.0 | 2026-09-02 | Eugene Beloussov | Synced to `🌈 Colors 3.13.0` (was 3.11.0; includes the 3.12.0 line). New primitive `Transparent/Black 0%`. New semantics: `Surface/InverseOverlay` (`White 8%` / `Black 5%` — overlay for inverse surfaces), **group `Shadow`** (`Shadow/Primary` `Black 5%` / `Black 0%` — the elevation shadow *colour*, dissolves in Dark; geometry stays in `elevation.json`), **group `Safety`** (`Safety 1` pastel base, `Safety 2` `Blue/700` theme-fixed). **`Accent/Safety` reverted to `Accent/Blue 2`** (`Blue/700` / `Blue/600`) — Safety moved to its own group; no repo CSS consumed `--accent-safety`. `Safety 1` Light aliases the semantic `Pastel/Blue 1` in Figma — dereferenced to `Blue/100` in the repo (house rule: semantic → primitive), and `sync_colors.py` now does one-level dereference automatically. §10.6 / §10.7 added. |
| 3.4.5 | 2026-08-25 | Eugene Beloussov | Synced to `🌈 Colors 3.11.0`. New primitive family **Yellow 50–850** (OKLCH, mustard darks) + `Transparent/Yellow 250 (25/36/47%)`, `Transparent/White 68%`, `Transparent/Red 700 (43%)` (replaces 45%). New semantics: `Pastel/Yellow 1-2`, `Accent/Yellow 1-2` (250/400 — the light-hue exception), `Constant/*` group (18, theme-fixed, §10.5), `TextAndIcon/Yellow`, `TextAndIcon/Transparent`. **`Accent/Blue 2` renamed to `Accent/Safety`** (Safety team jurisdiction; Dark pinned to `Blue/700`) — repo annotation chrome migrated to the value-identical `Border/Inform`. The red-alpha name↔value drift ((26%)=0.23, (34%)=0.32) was fixed upstream the same day — renamed to (23%)/(32%) and re-synced. |
| 3.4.4 | 2026-08-05 | Eugene Beloussov | Synced to `🌈 Colors 3.10.0` (was 3.8.0). New: primitive `Grey/870` `#242424`; semantic `Surface/Floating` (Light `White` / Dark `Grey/870` — the floating-surface token, elevation through lightness) and `Surface/DarkOverlay` (`Transparent/Black 20%` both themes). Re-pointed: `Border/Transparent` Dark `White 8%` → `Grey 850 (90%)`. §5 Surface table extended to 8 tokens (ContrastOverlay row added — it had been noted in 3.4.3 but never tabled). Everything else verified byte-identical against the full palette dump. First consumer: Floating Button 3.0.3. |
| 3.4.3 | 2026-06-24 | Eugene Beloussov | Synced to `🌈 Colors 3.8.0`: Grey scale hex updated (900 #181818, 875 #1C1C1C, 850 #303030, 800 #535353, 700 #6C6C6C); §11 Transparent table rebuilt to the 700-based structure with real stored alphas; Pastel/Accent tables refreshed (Pastel Light → 100/200 steps, Dark → `Transparent/<tone> 700 (N%)`; Accent Dark 2-steps → 600). Added §8.5 "Pastel + Accent — the colour constructor": the two-axis model (tone × intensity), Rule A (layering within one element) and Rule B (relative hierarchy between elements). New tokens noted: `Surface/ContrastOverlay`, `Transparent/Black 20%`. |

> New updates are formatted as a separate `Update X.Y` frame in `🌈 Colors` (see `spec-rules.md`, section 5.15), then transferred to this document.

---

## Generated tokens — `tokens/generated/primitives.css`

```css
/* ================================================================
 * Oymyakon Design System — Color Tokens (primitives.css)
 * AUTO-GENERATED by build-dtcg.js — DO NOT EDIT MANUALLY
 * Source: tokens/src/color/primitives.json
 * ================================================================ */


:root {

  /* ── grey ── */
  --p-grey-50: oklch(0.979336 0.002775 84.6018);
  --p-grey-75: oklch(0.960533 0.006642 97.5311);
  --p-grey-100: oklch(0.957255 0.007957 99.0448);
  --p-grey-150: oklch(0.920191 0.012012 101.6158);
  --p-grey-200: oklch(0.899663 0.012233 96.5231);
  --p-grey-250: oklch(0.849676 0.012255 101.6257);
  --p-grey-300: oklch(0.819645 0.011178 95.2706);
  --p-grey-400: oklch(0.758892 0.011218 100.9856);
  --p-grey-500: oklch(0.691509 0.010063 100.159);
  --p-grey-600: oklch(0.599194 0.007498 97.5261);
  --p-grey-700: oklch(0.531282 0 0);
  --p-grey-800: oklch(0.442255 0 0);
  --p-grey-850: oklch(0.309186 0 0);
  --p-grey-870: oklch(0.260325 0 0);
  --p-grey-875: oklch(0.22645 0 0);
  --p-grey-900: oklch(0.209036 0 0);

  /* ── green ── */
  --p-green-50: oklch(0.981129 0.015796 148.6948);
  --p-green-75: oklch(0.95952 0.031737 148.3569);
  --p-green-100: oklch(0.939321 0.051094 147.8669);
  --p-green-150: oklch(0.920229 0.07441 147.8893);
  --p-green-200: oklch(0.899207 0.102057 148.2878);
  --p-green-250: oklch(0.860558 0.137757 148.0026);
  --p-green-300: oklch(0.800128 0.157402 148.1225);
  --p-green-400: oklch(0.739376 0.171134 148.0907);
  --p-green-500: oklch(0.701039 0.17502 147.9507);
  --p-green-600: oklch(0.670903 0.180498 147.9749);
  --p-green-700: oklch(0.589888 0.170782 148.0055);
  --p-green-800: oklch(0.509603 0.160042 145.0648);
  --p-green-850: oklch(0.381281 0.075615 152.0749);

  /* ── orange ── */
  --p-orange-50: oklch(0.980928 0.025381 94.771);
  --p-orange-75: oklch(0.959299 0.039651 89.7036);
  --p-orange-100: oklch(0.950847 0.043181 78.4948);
  --p-orange-150: oklch(0.930262 0.054108 72.4528);
  --p-orange-200: oklch(0.910606 0.062695 66.105);
  --p-orange-250: oklch(0.860173 0.093741 60.3172);
  --p-orange-300: oklch(0.819765 0.116267 53.9001);
  --p-orange-400: oklch(0.780286 0.139591 47.9578);
  --p-orange-500: oklch(0.749734 0.157721 41.9839);
  --p-orange-600: oklch(0.720724 0.179597 40.0692);
  --p-orange-700: oklch(0.680597 0.211154 36.0554);
  --p-orange-800: oklch(0.580052 0.208999 33.9058);
  --p-orange-850: oklch(0.420641 0.147741 32.9807);

  /* ── red ── */
  --p-red-50: oklch(0.980118 0.009627 16.8625);
  --p-red-75: oklch(0.960385 0.019536 17.2791);
  --p-red-100: oklch(0.949495 0.025148 17.4363);
  --p-red-150: oklch(0.91905 0.041319 19.6732);
  --p-red-200: oklch(0.899935 0.051986 19.5531);
  --p-red-250: oklch(0.850306 0.08151 19.7883);
  --p-red-300: oklch(0.799425 0.114854 20.5459);
  --p-red-400: oklch(0.719836 0.174726 20.8397);
  --p-red-500: oklch(0.680415 0.208409 21.1786);
  --p-red-600: oklch(0.66003 0.226842 22.0438);
  --p-red-700: oklch(0.629722 0.253597 21.9052);
  --p-red-800: oklch(0.479966 0.173999 23.1133);
  --p-red-850: oklch(0.360278 0.117304 23.5325);

  /* ── blue ── */
  --p-blue-50: oklch(0.980318 0.013824 219.8632);
  --p-blue-75: oklch(0.95972 0.026175 224.3424);
  --p-blue-100: oklch(0.939426 0.03849 226.1012);
  --p-blue-150: oklch(0.919317 0.048159 230.9497);
  --p-blue-200: oklch(0.900603 0.056563 235.4711);
  --p-blue-250: oklch(0.849826 0.081871 241.8078);
  --p-blue-300: oklch(0.800174 0.106295 247.7087);
  --p-blue-400: oklch(0.730928 0.142378 253.7769);
  --p-blue-500: oklch(0.680526 0.16904 259.7982);
  --p-blue-600: oklch(0.630301 0.198086 263.9704);
  --p-blue-700: oklch(0.569961 0.235447 268.0698);
  --p-blue-800: oklch(0.469226 0.196587 272.0944);
  --p-blue-850: oklch(0.359793 0.123485 275.9323);

  /* ── driveGreen ── */
  --p-drive-green-50: oklch(0.980546 0.04467 127.8436);
  --p-drive-green-75: oklch(0.969965 0.063905 127.6098);
  --p-drive-green-100: oklch(0.949666 0.116617 125.9214);
  --p-drive-green-150: oklch(0.939009 0.13522 125.0894);
  --p-drive-green-200: oklch(0.921171 0.19701 124.0193);
  --p-drive-green-250: oklch(0.892457 0.214284 123.2374);
  --p-drive-green-300: oklch(0.855757 0.203974 123.4407);
  --p-drive-green-400: oklch(0.740872 0.167354 121.0609);
  --p-drive-green-500: oklch(0.680267 0.150409 120.0328);
  --p-drive-green-600: oklch(0.638896 0.14112 119.062);
  --p-drive-green-700: oklch(0.549921 0.115224 117.9443);
  --p-drive-green-800: oklch(0.449295 0.087913 116.8582);
  --p-drive-green-850: oklch(0.359384 0.062982 116.4907);
  --p-drive-green-900: oklch(0.210217 0.031978 114.391);

  /* ── base ── */
  --p-white: oklch(1 0 0);
  --p-black: oklch(0 0 0);

  /* ── graphite ── */
  --p-graphite-50: oklch(0.979409 0.0014 285.0159);
  --p-graphite-75: oklch(0.96067 0.001797 248.5508);
  --p-graphite-100: oklch(0.939586 0.001805 248.5328);
  --p-graphite-150: oklch(0.920652 0.002624 229.7774);
  --p-graphite-200: oklch(0.899628 0.003566 248.1992);
  --p-graphite-250: oklch(0.84995 0.005382 248.0992);
  --p-graphite-300: oklch(0.819137 0.006576 255.5701);
  --p-graphite-400: oklch(0.759018 0.009737 258.3796);
  --p-graphite-500: oklch(0.690871 0.011808 256.7514);
  --p-graphite-600: oklch(0.60085 0.01414 255.5807);
  --p-graphite-700: oklch(0.529333 0.012615 256.7616);
  --p-graphite-800: oklch(0.439786 0.015286 255.6113);
  --p-graphite-850: oklch(0.34122 0.017005 251.8375);
  --p-graphite-900: oklch(0.211483 0.011669 254.1066);

  /* ── transparent ── */
  --p-transparent-orange-700-20: oklch(0.680597 0.211154 36.0554 / 0.2);
  --p-transparent-orange-700-36: oklch(0.680597 0.211154 36.0554 / 0.36);
  --p-transparent-orange-700-46: oklch(0.680597 0.211154 36.0554 / 0.46);
  --p-transparent-blue-700-28: oklch(0.569961 0.235447 268.0698 / 0.28);
  --p-transparent-blue-700-41: oklch(0.569961 0.235447 268.0698 / 0.41);
  --p-transparent-blue-700-53: oklch(0.569961 0.235447 268.0698 / 0.53);
  --p-transparent-red-700-23: oklch(0.629722 0.253597 21.9052 / 0.23);
  --p-transparent-red-700-32: oklch(0.629722 0.253597 21.9052 / 0.32);
  --p-transparent-red-700-43: oklch(0.629722 0.253597 21.9052 / 0.43);
  --p-transparent-green-700-22: oklch(0.589888 0.170782 148.0055 / 0.22);
  --p-transparent-green-700-30: oklch(0.589888 0.170782 148.0055 / 0.3);
  --p-transparent-green-700-42: oklch(0.589888 0.170782 148.0055 / 0.42);
  --p-transparent-drive-green-250-0: oklch(0.892457 0.214284 123.2374 / 0);
  --p-transparent-drive-green-250-8: oklch(0.892457 0.214284 123.2374 / 0.08);
  --p-transparent-drive-green-250-11: oklch(0.892457 0.214284 123.2374 / 0.11);
  --p-transparent-drive-green-250-15: oklch(0.892457 0.214284 123.2374 / 0.15);
  --p-transparent-grey-800-8: oklch(0.440927 0.006389 106.7995 / 0.08);
  --p-transparent-grey-800-16: oklch(0.440927 0.006389 106.7995 / 0.16);
  --p-transparent-grey-800-24: oklch(0.440927 0.006389 106.7995 / 0.24);
  --p-transparent-grey-800-32: oklch(0.440927 0.006389 106.7995 / 0.32);
  --p-transparent-grey-850-90: oklch(0.309483 0.003776 84.5922 / 0.9);
  --p-transparent-white-8: oklch(1 0 0 / 0.08);
  --p-transparent-white-16: oklch(1 0 0 / 0.16);
  --p-transparent-white-24: oklch(1 0 0 / 0.24);
  --p-transparent-white-32: oklch(1 0 0 / 0.32);
  --p-transparent-white-56: oklch(1 0 0 / 0.56);
  --p-transparent-white-68: oklch(1 0 0 / 0.68);
  --p-transparent-graphite-900-80: oklch(0.211483 0.011669 254.1066 / 0.8);
  --p-transparent-black-0: oklch(0 0 0 / 0);
  --p-transparent-black-5: oklch(0 0 0 / 0.05);
  --p-transparent-black-20: oklch(0 0 0 / 0.2);
  --p-transparent-black-75: oklch(0 0 0 / 0.75);
  --p-transparent-yellow-250-25: oklch(0.862535 0.15215 96.4025 / 0.25);
  --p-transparent-yellow-250-36: oklch(0.862535 0.15215 96.4025 / 0.36);
  --p-transparent-yellow-250-47: oklch(0.862535 0.15215 96.4025 / 0.47);

  /* ── gradient ── */
  --p-gradient-primary: oklch(0 0 0 / 0.2);

  /* ── yellow ── */
  --p-yellow-50: oklch(0.980866 0.032713 101.4323);
  --p-yellow-75: oklch(0.95921 0.049732 99.8809);
  --p-yellow-100: oklch(0.952191 0.074831 99.4569);
  --p-yellow-150: oklch(0.93167 0.104485 98.6577);
  --p-yellow-200: oklch(0.912519 0.135379 98.022);
  --p-yellow-250: oklch(0.862535 0.15215 96.4025);
  --p-yellow-300: oklch(0.821128 0.157842 96.0565);
  --p-yellow-400: oklch(0.784519 0.154855 95.6865);
  --p-yellow-500: oklch(0.756988 0.150847 95.1894);
  --p-yellow-600: oklch(0.727387 0.145053 95.4219);
  --p-yellow-700: oklch(0.691256 0.137802 95.4947);
  --p-yellow-800: oklch(0.590619 0.117716 95.4918);
  --p-yellow-850: oklch(0.434834 0.086512 95.1637);
}
```

---

## Generated tokens — `tokens/generated/semantic.css`

```css
/* ================================================================
 * Oymyakon Design System — Color Tokens (semantic.css)
 * AUTO-GENERATED by build-dtcg.js — DO NOT EDIT MANUALLY
 * Source: tokens/src/color/semantic.json
 * ================================================================ */


/* Light theme */
:root {

  /* ── background ── */
  --background-primary: var(--p-white);
  --background-base-grey: var(--p-grey-100);
  --background-inverse-primary: var(--p-grey-875);
  --background-base-white: var(--p-white);
  --background-brand: var(--p-drive-green-250);
  --background-secondary: var(--p-grey-200);
  --background-always-light: var(--p-white);
  --background-pop-up: var(--p-transparent-black-75);
  --background-always-graphite: var(--p-graphite-850);
  --background-always-dark: var(--p-grey-875);

  /* ── textAndIcon ── */
  --text-and-icon-primary: var(--p-grey-900);
  --text-and-icon-secondary: var(--p-grey-700);
  --text-and-icon-accent: var(--p-blue-700);
  --text-and-icon-brand: var(--p-drive-green-250);
  --text-and-icon-success: var(--p-green-700);
  --text-and-icon-warning: var(--p-orange-700);
  --text-and-icon-error: var(--p-red-700);
  --text-and-icon-disabled: var(--p-grey-400);
  --text-and-icon-inverse-primary: var(--p-white);
  --text-and-icon-always-dark: var(--p-grey-900);
  --text-and-icon-always-light: var(--p-white);
  --text-and-icon-graphite: var(--p-graphite-850);
  --text-and-icon-yellow: var(--p-yellow-250);
  --text-and-icon-transparent: var(--p-transparent-black-75);

  /* ── surface ── */
  --surface-on-white: var(--p-grey-100);
  --surface-on-grey: var(--p-white);
  --surface-overlay: var(--p-transparent-grey-800-8);
  --surface-white-overlay: var(--p-transparent-white-16);
  --surface-pressed-overlay: var(--p-black);
  --surface-contrast-overlay: var(--p-transparent-black-20);
  --surface-dark-overlay: var(--p-transparent-black-20);
  --surface-floating: var(--p-white);
  --surface-inverse-overlay: var(--p-transparent-white-8);

  /* ── border ── */
  --border-default: var(--p-grey-150);
  --border-active: var(--p-grey-900);
  --border-inform: var(--p-blue-700);
  --border-success: var(--p-green-600);
  --border-warning: var(--p-orange-700);
  --border-error: var(--p-red-700);
  --border-transparent: var(--p-transparent-black-5);

  /* ── pastel ── */
  --pastel-blue1: var(--p-blue-100);
  --pastel-blue2: var(--p-blue-200);
  --pastel-orange1: var(--p-orange-100);
  --pastel-orange2: var(--p-orange-200);
  --pastel-red1: var(--p-red-100);
  --pastel-red2: var(--p-red-200);
  --pastel-green1: var(--p-green-100);
  --pastel-green2: var(--p-green-200);
  --pastel-drive-green1: var(--p-drive-green-100);
  --pastel-drive-green2: var(--p-drive-green-150);
  --pastel-yellow1: var(--p-yellow-100);
  --pastel-yellow2: var(--p-yellow-200);

  /* ── accent ── */
  --accent-blue1: var(--p-blue-500);
  --accent-orange1: var(--p-orange-500);
  --accent-red1: var(--p-red-500);
  --accent-green1: var(--p-green-500);
  --accent-drive-green1: var(--p-drive-green-500);
  --accent-blue2: var(--p-blue-700);
  --accent-orange2: var(--p-orange-700);
  --accent-red2: var(--p-red-700);
  --accent-green2: var(--p-green-700);
  --accent-drive-green2: var(--p-drive-green-600);
  --accent-yellow1: var(--p-yellow-250);
  --accent-yellow2: var(--p-yellow-400);

  /* ── doubleColor ── */
  --double-color-outline: var(--p-grey-900);
  --double-color-bg-inverse: var(--p-transparent-drive-green-250-0);
  --double-color-bg: var(--p-drive-green-150);
  --double-color-outline-inverse: var(--p-drive-green-250);

  /* ── skeleton ── */
  --skeleton-on-white: var(--p-grey-100);
  --skeleton-white-overlay: var(--p-transparent-white-24);
  --skeleton-wave: var(--p-transparent-white-56);

  /* ── constant ── */
  --constant-blue1: var(--p-blue-200);
  --constant-blue2: var(--p-blue-300);
  --constant-blue3: var(--p-blue-600);
  --constant-orange1: var(--p-orange-200);
  --constant-orange2: var(--p-orange-300);
  --constant-orange3: var(--p-orange-600);
  --constant-red1: var(--p-red-200);
  --constant-red2: var(--p-red-300);
  --constant-red3: var(--p-red-600);
  --constant-green1: var(--p-green-200);
  --constant-green2: var(--p-green-300);
  --constant-green3: var(--p-green-600);
  --constant-drive-green1: var(--p-drive-green-200);
  --constant-drive-green2: var(--p-drive-green-300);
  --constant-drive-green3: var(--p-drive-green-600);
  --constant-yellow1: var(--p-yellow-200);
  --constant-yellow2: var(--p-yellow-300);
  --constant-yellow3: var(--p-yellow-600);

  /* ── safety ── */
  --safety-safety1: var(--p-blue-100);
  --safety-safety2: var(--p-blue-700);

  /* ── shadow ── */
  --shadow-primary: var(--p-transparent-black-5);
}

/* Dark theme */
[data-theme="dark"], .theme-dark {

  /* ── background ── */
  --background-primary: var(--p-grey-875);
  --background-base-grey: var(--p-black);
  --background-inverse-primary: var(--p-white);
  --background-base-white: var(--p-black);
  --background-brand: var(--p-drive-green-250);
  --background-secondary: var(--p-transparent-grey-800-32);
  --background-always-light: var(--p-white);
  --background-pop-up: var(--p-transparent-black-75);
  --background-always-graphite: var(--p-graphite-850);
  --background-always-dark: var(--p-grey-875);

  /* ── textAndIcon ── */
  --text-and-icon-primary: var(--p-white);
  --text-and-icon-secondary: var(--p-grey-400);
  --text-and-icon-accent: var(--p-blue-600);
  --text-and-icon-brand: var(--p-drive-green-250);
  --text-and-icon-success: var(--p-green-500);
  --text-and-icon-warning: var(--p-orange-600);
  --text-and-icon-error: var(--p-red-600);
  --text-and-icon-disabled: var(--p-grey-300);
  --text-and-icon-inverse-primary: var(--p-grey-900);
  --text-and-icon-always-dark: var(--p-grey-900);
  --text-and-icon-always-light: var(--p-white);
  --text-and-icon-graphite: var(--p-grey-600);
  --text-and-icon-yellow: var(--p-yellow-250);
  --text-and-icon-transparent: var(--p-transparent-white-68);

  /* ── surface ── */
  --surface-on-white: var(--p-grey-850);
  --surface-on-grey: var(--p-grey-800);
  --surface-overlay: var(--p-transparent-white-16);
  --surface-white-overlay: var(--p-transparent-white-16);
  --surface-pressed-overlay: var(--p-black);
  --surface-contrast-overlay: var(--p-transparent-white-24);
  --surface-dark-overlay: var(--p-transparent-black-20);
  --surface-floating: var(--p-grey-870);
  --surface-inverse-overlay: var(--p-transparent-black-5);

  /* ── border ── */
  --border-default: var(--p-grey-800);
  --border-active: var(--p-white);
  --border-inform: var(--p-blue-600);
  --border-success: var(--p-green-500);
  --border-warning: var(--p-orange-600);
  --border-error: var(--p-red-600);
  --border-transparent: var(--p-transparent-grey-850-90);

  /* ── pastel ── */
  --pastel-blue1: var(--p-transparent-blue-700-28);
  --pastel-blue2: var(--p-transparent-blue-700-41);
  --pastel-orange1: var(--p-transparent-orange-700-20);
  --pastel-orange2: var(--p-transparent-orange-700-36);
  --pastel-red1: var(--p-transparent-red-700-23);
  --pastel-red2: var(--p-transparent-red-700-32);
  --pastel-green1: var(--p-transparent-green-700-22);
  --pastel-green2: var(--p-transparent-green-700-30);
  --pastel-drive-green1: var(--p-transparent-drive-green-250-11);
  --pastel-drive-green2: var(--p-transparent-drive-green-250-15);
  --pastel-yellow1: var(--p-transparent-yellow-250-25);
  --pastel-yellow2: var(--p-transparent-yellow-250-47);

  /* ── accent ── */
  --accent-blue1: var(--p-blue-400);
  --accent-orange1: var(--p-orange-400);
  --accent-red1: var(--p-red-400);
  --accent-green1: var(--p-green-400);
  --accent-drive-green1: var(--p-drive-green-400);
  --accent-blue2: var(--p-blue-600);
  --accent-orange2: var(--p-orange-600);
  --accent-red2: var(--p-red-600);
  --accent-green2: var(--p-green-600);
  --accent-drive-green2: var(--p-drive-green-500);
  --accent-yellow1: var(--p-yellow-200);
  --accent-yellow2: var(--p-yellow-300);

  /* ── doubleColor ── */
  --double-color-outline: var(--p-drive-green-250);
  --double-color-bg-inverse: var(--p-drive-green-150);
  --double-color-bg: var(--p-transparent-drive-green-250-0);
  --double-color-outline-inverse: var(--p-grey-900);

  /* ── skeleton ── */
  --skeleton-on-white: var(--p-grey-850);
  --skeleton-white-overlay: var(--p-transparent-white-24);
  --skeleton-wave: var(--p-transparent-white-16);

  /* ── constant ── */
  --constant-blue1: var(--p-blue-200);
  --constant-blue2: var(--p-blue-300);
  --constant-blue3: var(--p-blue-600);
  --constant-orange1: var(--p-orange-200);
  --constant-orange2: var(--p-orange-300);
  --constant-orange3: var(--p-orange-600);
  --constant-red1: var(--p-red-200);
  --constant-red2: var(--p-red-300);
  --constant-red3: var(--p-red-600);
  --constant-green1: var(--p-green-200);
  --constant-green2: var(--p-green-300);
  --constant-green3: var(--p-green-600);
  --constant-drive-green1: var(--p-drive-green-200);
  --constant-drive-green2: var(--p-drive-green-300);
  --constant-drive-green3: var(--p-drive-green-600);
  --constant-yellow1: var(--p-yellow-200);
  --constant-yellow2: var(--p-yellow-300);
  --constant-yellow3: var(--p-yellow-600);

  /* ── safety ── */
  --safety-safety1: var(--p-transparent-blue-700-28);
  --safety-safety2: var(--p-blue-700);

  /* ── shadow ── */
  --shadow-primary: var(--p-transparent-black-0);
}
```
