@kiva/kv-tokens 4.0.3 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/dist/make-kit/guidelines/Guidelines.md +13 -0
- package/dist/make-kit/guidelines/foundations/color-themes.md +317 -0
- package/dist/make-kit/guidelines/foundations/color.md +235 -0
- package/dist/make-kit/guidelines/foundations/layout.md +194 -0
- package/dist/make-kit/guidelines/foundations/radius.md +176 -0
- package/dist/make-kit/guidelines/foundations/spacing.md +210 -0
- package/dist/make-kit/guidelines/foundations/tailwind.md +226 -0
- package/dist/make-kit/guidelines/foundations/typography.md +257 -0
- package/dist/make-kit/guidelines/setup.md +34 -0
- package/dist/make-kit/styles.css +4912 -0
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -65,6 +65,7 @@ Our Tailwind config has some differences to the standard install. Notably
|
|
|
65
65
|
| `@kiva/kv-tokens/js` | `dist/js/tokens.js` | Generated JS tokens (flat + nested) |
|
|
66
66
|
| `@kiva/kv-tokens/css` | `dist/css/tokens.css` | Themed CSS custom properties |
|
|
67
67
|
| `@kiva/kv-tokens/scss` | `dist/scss/tokens.scss` | SCSS `$variable` map |
|
|
68
|
+
| `@kiva/kv-tokens/make-kit/*` | `dist/make-kit/*` | Figma Make kit (guidelines + style context) |
|
|
68
69
|
|
|
69
70
|
## Importing Source Tokens
|
|
70
71
|
|
|
@@ -99,6 +100,36 @@ Or read them off disk from `node_modules/@kiva/kv-tokens/tokens/…` — useful
|
|
|
99
100
|
|
|
100
101
|
For the transformed, resolved-values-with-code-facing-names shape used by component code, prefer the default export of `@kiva/kv-tokens` or the flat-and-nested `@kiva/kv-tokens/js` module.
|
|
101
102
|
|
|
103
|
+
## Figma Make kit
|
|
104
|
+
|
|
105
|
+
`npm run build` emits `dist/make-kit/`, a [Figma Make kit](https://developers.figma.com/docs/code/write-design-system-guidelines/) built from the design-system skills in [`docs/skills/`](docs/skills):
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
dist/make-kit/
|
|
109
|
+
├── styles.css # compiled Tailwind stylesheet (base + utilities + type + theme vars)
|
|
110
|
+
└── guidelines/
|
|
111
|
+
├── Guidelines.md # routing document Make reads first (replaces Make's auto-created stub)
|
|
112
|
+
├── setup.md # how to consume the kit (styles.css, tw- prefix, theming)
|
|
113
|
+
└── foundations/*.md # one file per design foundation
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
A skill is included in the kit when its frontmatter sets `make_kit.include: true` (with a `category` and `order`); skills without that block are excluded. Adding a new tagged skill makes it appear in the kit — and in the `Guidelines.md` routing — on the next build, with no script changes. The transform logic lives in [`build/make-kit-transform.js`](build/make-kit-transform.js); the orchestrator is [`build/build-make-kit.js`](build/build-make-kit.js).
|
|
117
|
+
|
|
118
|
+
`styles.css` is the Kiva Tailwind preset compiled to a full stylesheet — base layer (fonts, headings), `tw-`-prefixed token utilities, the `tw-text-*` type system (with responsive variants), and every theme's color variables — so Make can match the design system's measurements and type whether or not it runs Tailwind itself. The safelist of utilities to emit is generated from the token scales ([`build/make-kit-safelist.js`](build/make-kit-safelist.js)), so it stays in sync as tokens change.
|
|
119
|
+
|
|
120
|
+
### Importing into Figma Make
|
|
121
|
+
|
|
122
|
+
Figma Make has no API to pull these in by path — you upload/drag the files into the kit. One-time setup:
|
|
123
|
+
|
|
124
|
+
1. **Get the files:** `npm i @kiva/kv-tokens`, then copy from `node_modules/@kiva/kv-tokens/dist/make-kit/` (the `guidelines/` files and `styles.css`).
|
|
125
|
+
2. In Figma Make: **Settings → Create a kit**.
|
|
126
|
+
3. Open the **Code** view → the **`guidelines/`** folder. **Upload or drag in** `setup.md` and the `foundations/*.md` files, and replace the auto-created `Guidelines.md` with ours (or paste its contents in).
|
|
127
|
+
4. Add **`styles.css`** to the project as the kit's style context (drag it into the file explorer).
|
|
128
|
+
5. *(Optional)* The kit import modal also accepts npm packages and library styles, but Make kits currently support **React** codebases only — so `@kiva/kv-tokens` (a Tailwind/token package, not React) isn't added here; the compiled `styles.css` is the delivery.
|
|
129
|
+
6. **Test** (prompt Make to build something and confirm it matches), then **Publish kit** to your team/org. Teammates pick it via **"Select a Make kit"** in a Make file.
|
|
130
|
+
|
|
131
|
+
See [Get started with Make kits](https://help.figma.com/hc/en-us/articles/39241689698839-Get-started-with-Make-kits) and [Add guidelines to Figma Make](https://help.figma.com/hc/en-us/articles/33665861260823-Add-guidelines-to-Figma-Make).
|
|
132
|
+
|
|
102
133
|
## Local Development
|
|
103
134
|
|
|
104
135
|
The `dist/` directory is gitignored but regenerated automatically by the `prepare` lifecycle script whenever you run `npm install` — both at the monorepo root and inside this package. After a fresh clone, `npm install` leaves `dist/` ready to use, so downstream workspace packages like [`@kiva/kv-components`](../kv-components/) can consume tokens without a separate build step.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Kiva Design System — Guidelines
|
|
2
|
+
|
|
3
|
+
Guidelines for building with Kiva's design system in Figma Make. Each file below covers one foundation; read the one relevant to the decision you are making. Style context (CSS custom properties for every token) is in `../styles.css`. Read `setup.md` first for how to consume the system.
|
|
4
|
+
|
|
5
|
+
## Foundations
|
|
6
|
+
|
|
7
|
+
- [tailwind](foundations/tailwind.md) — How to use Tailwind CSS v3 when it is backed by Kiva's design tokens — what the @kiva/kv-tokens preset changes about stock Tailwind (the tw- prefix, themable colors compiled to CSS custom properties, disabled core plugins, token-driven scales, an opinionated base layer), how to wire the preset into a project, and how the preset is compiled from DTCG tokens. Mechanical and integration-focused; for which token to pick, defer to the per-topic skills (color, spacing, radius, typography, layout).
|
|
8
|
+
- [color](foundations/color.md) — Semantic color system from the Kiva design system — primitive palettes (eco-green, marigold, desert-rose, stone, gray, neutral), the five themes (Default, Green Light, Green Dark, Marigold, Stone Light), the role/slot/state token grammar, accessibility levels per pairing, and rules for picking a token by purpose rather than hex value. Sourced from Figma; values describe design intent and may diverge from current code implementation.
|
|
9
|
+
- [color-themes](foundations/color-themes.md) — Per-theme semantic color token tables from the Kiva design system — every token in Default, Green Light, Green Dark, Marigold, and Stone Light, with hex value, primitive source, and Figma-authored description. Plus the shadow color tokens. The reference companion to the conceptual `color` skill.
|
|
10
|
+
- [typography](foundations/typography.md) — Semantic typography guidelines from the Kiva design system — type scale, heading hierarchy, font families, pairing rules, and HTML/Tailwind mappings. Sourced from Figma; values describe design intent and may diverge from current code implementation.
|
|
11
|
+
- [spacing](foundations/spacing.md) — Semantic spacing system from the Kiva design system — token categories (Structure, Component Gap, Component Inset, Micro), the 4px-grain ramp, responsive per-tier values, and rules for picking a token by spatial relationship rather than pixel value. Sourced from Figma; values describe design intent and may diverge from current code implementation.
|
|
12
|
+
- [layout](foundations/layout.md) — Layout grid system from the Kiva design system — breakpoint tiers (XS/SM/MD/LG/XL), columns, gutters, margins, nested grids, and rules for aligning content within the grid. Sourced from Figma; values describe design intent and may diverge from current code implementation.
|
|
13
|
+
- [radius](foundations/radius.md) — Border-radius token system from the Kiva design system — the 8-step scale from none (0px) to full (9999px), per-component use cases, the inner-radius formula for nested elements, and rules for keeping corners consistent. Sourced from Figma; values describe design intent and may diverge from current code implementation.
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# Kiva Color — Theme Token Tables
|
|
2
|
+
|
|
3
|
+
**When to use:** When implementing or designing in a specific theme and you need the full token list for that theme — every text, background, border, and underline slot with its hex, primitive token, and intended usage description. Load this alongside the `color` skill whenever you need the canonical data, not just the framework. Sourced from Figma; values describe design intent and may diverge from current code implementation.
|
|
4
|
+
|
|
5
|
+
This is the data companion to [color](color.md). Load that first for the *why* (principles, token grammar, accessibility framework, best practices, code-state caveats); load this when you need the full per-theme token list.
|
|
6
|
+
|
|
7
|
+
Five themes are documented below in the order they appear in Figma, followed by the shadow color tokens. Each table is reproduced from the Figma "Color Themes and Usage" panel and uses the format:
|
|
8
|
+
|
|
9
|
+
| Token | Hex | Primitive | Description |
|
|
10
|
+
|
|
11
|
+
The **Token** column is the semantic name a designer or engineer references. The **Primitive** column shows which raw value powers it — useful when tracing how the system composes, and the only place opacity-based disabled tokens (e.g., `color/gray/800-1` = `#212121 (30%)`) are visible.
|
|
12
|
+
|
|
13
|
+
**Wiring colors without the Tailwind preset?** These hex and primitive values are your fallback. See [color → Using with Tailwind](color.md#using-with-tailwind): when the `@kiva/kv-tokens` preset isn't registered, the themable `tw-bg-*` / `tw-text-*` utilities don't exist, so you either pull the CSS custom properties from `@kiva/kv-tokens/css` or apply the hex values in the tables below directly (losing runtime theming).
|
|
14
|
+
|
|
15
|
+
## Source-of-truth caveats
|
|
16
|
+
|
|
17
|
+
Several rows in the Figma source have obvious copy-paste or transcription errors. These are surfaced in **Figma source caveats** at the bottom of each theme rather than transcribed verbatim. When in doubt, treat the **Primitive** column as the canonical answer — primitive token names rarely have typos, and the hex/description should match the primitive.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Default theme
|
|
22
|
+
|
|
23
|
+
**White base · Used across all standard page layouts.**
|
|
24
|
+
|
|
25
|
+
The fully populated theme. Every other theme inherits from this one and only redefines the tokens that differ. Forms and text fields render in this theme regardless of the surrounding section.
|
|
26
|
+
|
|
27
|
+
### Text
|
|
28
|
+
|
|
29
|
+
| Token | Hex | Primitive | Description |
|
|
30
|
+
|---|---|---|---|
|
|
31
|
+
| `text/primary` | `#223829` | `color/eco-green/4` | Primary text for all body copy, headlines, and icons. The darkest eco-green value. Use it for all high-importance content. |
|
|
32
|
+
| `text/primary-inverse` | `#EDF4F1` | `color/eco-green/1` | Inverted text color for dark buttons and dark backgrounds. Used on dark surfaces (like `background/primary-inverse`) to maintain contrast. |
|
|
33
|
+
| `text/secondary` | `#505050` | `color/gray/600` | Medium-contrast supportive text. Used for secondary labels, subtitles, metadata, and placeholder text. |
|
|
34
|
+
| `text/tertiary` | `#757575` | `color/gray/500` | Low-contrast text for subtle information. Used for hints or non-essential decorative text. |
|
|
35
|
+
| `text/action` | `#276A43` | `color/eco-green/3` | Brand-colored interactive text. Used for links, clickable labels, and active navigation items. |
|
|
36
|
+
| `text/action-highlight` | `#223829` | `color/eco-green/4` | Darker brand text for active/pressed states. Used when the mouse hovers over links, secondary buttons, or clickable labels. |
|
|
37
|
+
| `text/action-disabled` | `#212121` (30%) | `color/gray/800-1` | Disabled text within Default sections. Opacity-based — the intentionally low contrast communicates unavailability. |
|
|
38
|
+
|
|
39
|
+
### Text — Alerts
|
|
40
|
+
|
|
41
|
+
| Token | Hex | Primitive | Description |
|
|
42
|
+
|---|---|---|---|
|
|
43
|
+
| `text/caution` | `#593207` | `color/marigold/4` | Dark text for warning context. Used for warning messages or status labels that require user attention. |
|
|
44
|
+
| `text/caution-highlight` | `#996210` | `color/marigold/3` | Hover state for warning-related text. Enhances visibility for interactive warning elements during hover. |
|
|
45
|
+
| `text/danger` | `#5C2A22` | `color/desert-rose/4` | Dark text for error context. Used for error messages, critical alerts, and destructive action labels. |
|
|
46
|
+
| `text/danger-highlight` | `#A24536` | `color/desert-rose/3` | Hover state for error-related text. Visual feedback for interactive destructive or error-prone elements. |
|
|
47
|
+
|
|
48
|
+
### Background
|
|
49
|
+
|
|
50
|
+
| Token | Hex | Primitive | Description |
|
|
51
|
+
|---|---|---|---|
|
|
52
|
+
| `background/primary` | `#FFFFFF` | `color/neutral/white` | Main application surface. The base color for the entire page or main content areas. |
|
|
53
|
+
| `background/primary-inverse` | `#223829` | `color/eco-green/4` | High-contrast dark surface. Use for high-emphasis containers like dark headers, sidebars, or hero cards. |
|
|
54
|
+
| `background/secondary` | `#EDF4F1` | `color/eco-green/1` | Subtle secondary surface. Use for section backgrounds, form inputs, or to differentiate cards from the main page. |
|
|
55
|
+
| `background/tertiary` | `#C4C4C4` | `color/gray/300` | Low-priority decorative surface. Use inside a component (e.g., the track behind a progress bar) or for a disabled button surface. Not for page or section backgrounds. |
|
|
56
|
+
| `background/action` | `#276A43` | `color/eco-green/3` | Brand-colored action surface. The base color for primary buttons, active toggles, and brand-heavy elements. Pair text with `text/primary-inverse`. |
|
|
57
|
+
| `background/action-highlight` | `#223829` | `color/eco-green/4` | Hover state for action surfaces. Specifically for primary button hover and interactive brand surfaces. |
|
|
58
|
+
| `background/action-secondary` | `#FFFFFF` | `color/neutral/white` | Surface color for secondary button default state within Default sections. |
|
|
59
|
+
| `background/action-secondary-highlight` | `#EDF4F1` | `color/eco-green/1` | Hover state for secondary surfaces. Feedback color for interactive cards or buttons on hover. |
|
|
60
|
+
| `background/primary-disabled` | `#276A43` (30%) | `color/eco-green/3-1` | Disabled or inactive state for primary button (30% opacity). |
|
|
61
|
+
|
|
62
|
+
### Background — Alerts
|
|
63
|
+
|
|
64
|
+
| Token | Hex | Primitive | Description |
|
|
65
|
+
|---|---|---|---|
|
|
66
|
+
| `background/caution` | `#F8CD69` | `color/marigold/2` | Subtle amber background. Background color for warning banners, toast notifications, and alert callouts. |
|
|
67
|
+
| `background/caution-highlight` | `#F8F2E6` | `color/marigold/1` | Hover state for warning surfaces. Feedback color for interactive warning cards or actionable alerts on hover. |
|
|
68
|
+
| `background/danger` | `#E0988D` | `color/desert-rose/2` | Subtle red background. Background color for error banners, destructive action dialogs, or invalid states. |
|
|
69
|
+
| `background/danger-highlight` | `#F9F0EF` | `color/desert-rose/1` | Soft red background. The standard error alert surface — paired with `text/danger` for the body copy of an error message. |
|
|
70
|
+
|
|
71
|
+
### Border
|
|
72
|
+
|
|
73
|
+
| Token | Hex | Primitive | Description |
|
|
74
|
+
|---|---|---|---|
|
|
75
|
+
| `border/primary` | `#505050` | `color/gray/600` | High-contrast border. Use for component outlines, input field borders, and strong layout dividers. |
|
|
76
|
+
| `border/primary-inverse` | `#FFFFFF` | `color/neutral/white` | Inverted border for dark surfaces. Contrast border for elements placed on dark-themed containers. |
|
|
77
|
+
| `border/secondary` | `#757575` | `color/gray/500` | Medium-contrast border. Use for card borders, internal table dividers, and secondary component outlines. |
|
|
78
|
+
| `border/secondary-disabled` | `#212121` (30%) | `color/gray/800-1` | Disabled or inactive state for secondary button (30% opacity). |
|
|
79
|
+
| `border/tertiary` | `#C4C4C4` | `color/gray/300` | Low-contrast subtle border. Use for low-emphasis decorative lines or subtle element separation. |
|
|
80
|
+
| `border/action` | `#276A43` | `color/eco-green/3` | Brand-colored border. Use for active focus states, selection rings, and brand-themed outlines. |
|
|
81
|
+
| `border/action-highlight` | `#223829` | `color/eco-green/4` | Hover state for Default action borders. Darker green that darkens the outline on interaction. Apply on `:hover` and `:active` only. |
|
|
82
|
+
|
|
83
|
+
### Border — Alerts
|
|
84
|
+
|
|
85
|
+
| Token | Hex | Primitive | Description |
|
|
86
|
+
|---|---|---|---|
|
|
87
|
+
| `border/caution` | `#F8CD69` | `color/marigold/2` | Dark border for warning-related components. Borders on warning banners, alert cards, or validation states. |
|
|
88
|
+
| `border/caution-highlight` | `#F8F2E6` | `color/marigold/1` | Hover state for warning-related borders. Visual feedback for interactive warning components on hover. |
|
|
89
|
+
| `border/danger` | `#E0988D` | `color/desert-rose/2` | Dark border for error-related components. Borders on invalid input fields, error banners, or critical alert containers. |
|
|
90
|
+
| `border/danger-highlight` | `#F9F0EF` | `color/desert-rose/1` | Hover state for error-related borders. Visual feedback for interactive destructive or error components on hover. |
|
|
91
|
+
|
|
92
|
+
### Underline
|
|
93
|
+
|
|
94
|
+
| Token | Hex | Primitive | Description |
|
|
95
|
+
|---|---|---|---|
|
|
96
|
+
| `heading-underline-primary` | `#2AA967` | `color/eco-green/default` | Brand-colored heading accent. A decorative variable used for brand underlines beneath main titles. |
|
|
97
|
+
|
|
98
|
+
### Figma source caveats — Default
|
|
99
|
+
|
|
100
|
+
- `background/danger-highlight` in the Figma table copies `background/danger`'s description verbatim. The corrected description above reflects how the token is actually used (soft error alert surface).
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Green Light theme
|
|
105
|
+
|
|
106
|
+
**Light tint surface · Secondary sections, soft brand presence.**
|
|
107
|
+
|
|
108
|
+
Green Light has only two unique tokens. Everything else — text, action, alerts, borders — is inherited from Default. Use Green Light for sections that need a subtle brand tint without owning the page atmosphere.
|
|
109
|
+
|
|
110
|
+
### Background
|
|
111
|
+
|
|
112
|
+
| Token | Hex | Primitive | Description |
|
|
113
|
+
|---|---|---|---|
|
|
114
|
+
| `background/primary` | `#EDF4F1` | `color/eco-green/1` | Light green section background. The base surface for all Green Light theme sections. |
|
|
115
|
+
| `background/primary-inverse` | `#FFFFFF` | `color/neutral/white` | Theme-specific secondary surface. Provides contrast against `background/primary` for cards and inputs. |
|
|
116
|
+
|
|
117
|
+
> **Why Green Light has only two unique tokens.** Green Light inherits all text, border, and alert tokens from the Default theme — they are identical in value and usage. Only `background/primary` and `background/primary-inverse` differ, because they define the section's surface color. The shared tokens are not duplicated here to avoid confusion — refer to the Default theme tables above for everything else.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Green Dark theme
|
|
122
|
+
|
|
123
|
+
**Dark green base · For high-emphasis sections, hero areas · Never full page.**
|
|
124
|
+
|
|
125
|
+
Green Dark inverts the text/background relationship and brightens the action color so it remains legible against the dark surface. Reserved for section-level emphasis; never apply to a full page. Forms still render in Default — re-wrap form children in a Default-themed container.
|
|
126
|
+
|
|
127
|
+
### Text
|
|
128
|
+
|
|
129
|
+
| Token | Hex | Primitive | Description |
|
|
130
|
+
|---|---|---|---|
|
|
131
|
+
| `text/primary` | `#EDF4F1` | `color/eco-green/1` | Primary text on dark green surfaces. Use for body copy, headlines, and icons in Green Dark sections. |
|
|
132
|
+
| `text/primary-inverse` | `#223829` | `color/eco-green/4` | Dark text color. Used for contrast when text is placed on rare light-colored components within a Green Dark section. |
|
|
133
|
+
| `text/secondary` | `#C4C4C4` | `color/gray/300` | Subtle light gray text. Used for secondary labels, metadata, and supporting information. |
|
|
134
|
+
| `text/tertiary` | `#E0E0E0` | `color/gray/200` | Low-contrast muted text. Used for hints or non-essential decorative text. |
|
|
135
|
+
| `text/action` | `#78C79F` | `color/eco-green/2` | Bright accent green. High-visibility interactive color for links and active navigation tabs against dark surfaces. |
|
|
136
|
+
| `text/action-highlight` | `#EDF4F1` | `color/eco-green/1` | Hover state for action text. Strong feedback color when hovering over interactive links in Green Dark sections. |
|
|
137
|
+
| `text/action-disabled` | `#212121` (30%) | `color/gray/800-1` | Disabled text within Green Dark sections. Opacity-based — the low contrast communicates unavailability. |
|
|
138
|
+
|
|
139
|
+
### Background
|
|
140
|
+
|
|
141
|
+
| Token | Hex | Primitive | Description |
|
|
142
|
+
|---|---|---|---|
|
|
143
|
+
| `background/primary` | `#223829` | `color/eco-green/4` | Dark green base surface. The main background for Green Dark section content areas. |
|
|
144
|
+
| `background/primary-inverse` | `#FFFFFF` | `color/neutral/white` | Pure white surface. High-contrast callouts or special containers needing maximum attention within a dark section. |
|
|
145
|
+
| `background/secondary` | `#276A43` | `color/eco-green/3` | Subtle secondary surface. Use for nested cards, form inputs, or to differentiate sub-regions from the main dark surface. |
|
|
146
|
+
| `background/tertiary` | `#C4C4C4` | `color/gray/300` | Low-priority decorative surface. Use inside a component (e.g., progress bar track) or for a disabled button surface. |
|
|
147
|
+
| `background/action` | `#78C79F` | `color/eco-green/2` | Bright action surface. High-visibility background for primary buttons to stand out against dark environments. |
|
|
148
|
+
| `background/action-highlight` | `#EDF4F1` | `color/eco-green/1` | Hover state for action surfaces. Specifically for primary button hover and active brand surfaces. |
|
|
149
|
+
| `background/action-secondary` | `#223829` | `color/eco-green/4` | Surface color for secondary button default state within Green Dark sections. |
|
|
150
|
+
| `background/action-secondary-highlight` | `#276A43` | `color/eco-green/3` | Hover state for secondary surfaces. Feedback color for interactive cards or buttons on hover. |
|
|
151
|
+
| `background/primary-disabled` | `#276A43` (30%) | `color/eco-green/3-1` | Disabled or inactive state for primary button (30% opacity). |
|
|
152
|
+
|
|
153
|
+
### Border
|
|
154
|
+
|
|
155
|
+
| Token | Hex | Primitive | Description |
|
|
156
|
+
|---|---|---|---|
|
|
157
|
+
| `border/primary` | `#EDF4F1` | `color/eco-green/1` | Light green border. Primary component boundaries and strong dividers for Green Dark layouts. |
|
|
158
|
+
| `border/primary-inverse` | `#223829` | `color/eco-green/4` | Dark border color. Inverted border for elements placed on rare light-colored containers within a Green Dark section. |
|
|
159
|
+
| `border/secondary` | `#276A43` | `color/eco-green/3` | Muted brand green border. Subtle separation for secondary UI elements or nested sections. |
|
|
160
|
+
| `border/secondary-disabled` | `#212121` (30%) | `color/gray/800-1` | Disabled or inactive state for secondary button (30% opacity). |
|
|
161
|
+
| `border/tertiary` | `#78C79F` | `color/eco-green/2` | Low-contrast subtle border. Use for low-emphasis decorative lines or subtle element separation. |
|
|
162
|
+
| `border/action` | `#78C79F` | `color/eco-green/2` | Bright interactive border. Used for active selection borders and focus rings in Green Dark sections. |
|
|
163
|
+
| `border/action-highlight` | `#EDF4F1` | `color/eco-green/1` | Hover state for Green Dark action borders. Lighter green that lightens the outline on interaction. Apply on `:hover` and `:active` only. |
|
|
164
|
+
|
|
165
|
+
### Underline
|
|
166
|
+
|
|
167
|
+
| Token | Hex | Primitive | Description |
|
|
168
|
+
|---|---|---|---|
|
|
169
|
+
| `heading-underline-primary` | `#2AA967` | `color/eco-green/default` | Brand-colored heading accent. A decorative variable used for brand underlines beneath main titles. |
|
|
170
|
+
|
|
171
|
+
### Figma source caveats — Green Dark
|
|
172
|
+
|
|
173
|
+
- The Figma table renders `text/action`, `background/action`, `border/tertiary`, and `border/action` with hex `#276A43` (an `#` typo also appears as `##276A43`), but their primitive is `color/eco-green/2`. The shipped code resolves `eco-green/2` to `#78C79F`, which matches the visual in the Figma chips. The hex column above has been corrected to `#78C79F`; if you are reading the Figma table, ignore the textual hex and trust the primitive + chip.
|
|
174
|
+
- `background/primary-disabled`'s Figma description ("Hover state for error surfaces…") was copy-pasted from another row. The corrected description above reflects how the token is actually used.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Marigold theme
|
|
179
|
+
|
|
180
|
+
**Warm amber surface for marketing, decoration, warning purposes.**
|
|
181
|
+
|
|
182
|
+
Warm amber atmosphere for marketing pages, donation flows, and storytelling. Note that **the code names this theme `marigold-light`** even though Figma drops the `-light` suffix.
|
|
183
|
+
|
|
184
|
+
### Text
|
|
185
|
+
|
|
186
|
+
| Token | Hex | Primitive | Description |
|
|
187
|
+
|---|---|---|---|
|
|
188
|
+
| `text/primary` | `#593207` | `color/marigold/4` | Primary text for body copy, headlines, and icons within Marigold sections. The darkest marigold value. |
|
|
189
|
+
| `text/primary-inverse` | `#F8F2E6` | `color/marigold/1` | Light marigold text for content placed on dark marigold surfaces (`background/primary-inverse`). Use exclusively on dark amber backgrounds — never on light surfaces where it becomes unreadable. |
|
|
190
|
+
| `text/secondary` | `#505050` | `color/gray/600` | Mid-contrast supporting text within Marigold sections — labels, subtitles, metadata. |
|
|
191
|
+
| `text/tertiary` | `#757575` | `color/gray/500` | Low-contrast muted text. Used for hints or non-essential decorative text. |
|
|
192
|
+
| `text/action` | `#996210` | `color/marigold/3` | Deep gold interactive text. Used for interactive links and active navigation labels. |
|
|
193
|
+
| `text/action-highlight` | `#593207` | `color/marigold/4` | Hover and pressed state for `text/action` within Marigold sections. Darker value ensures increased contrast on interaction. Apply on `:hover` and `:active` only — not for static emphasis. |
|
|
194
|
+
| `text/action-disabled` | `#212121` (30%) | `color/gray/800-1` | Disabled text within Marigold sections. Opacity-based — the low contrast communicates unavailability. |
|
|
195
|
+
|
|
196
|
+
### Background
|
|
197
|
+
|
|
198
|
+
| Token | Hex | Primitive | Description |
|
|
199
|
+
|---|---|---|---|
|
|
200
|
+
| `background/primary` | `#F8F2E6` | `color/marigold/1` | Light amber section background. The base surface for Marigold sections. Use for warning-context sections, standout CTAs, or promotional sections. |
|
|
201
|
+
| `background/primary-inverse` | `#593207` | `color/marigold/4` | Dark amber surface for high-emphasis containers within a Marigold section — banners, callout cards, or feature highlights. |
|
|
202
|
+
| `background/secondary` | `#FFFFFF` | `color/neutral/white` | Subtle secondary surface. Use for nested cards, form inputs, or to differentiate sub-regions from the main amber surface. |
|
|
203
|
+
| `background/tertiary` | `#C4C4C4` | `color/gray/300` | Low-priority decorative surface. Use inside a component (e.g., progress bar track) or for a disabled button surface. |
|
|
204
|
+
| `background/action` | `#996210` | `color/marigold/3` | Golden action surface. Base color for primary buttons and active UI elements. |
|
|
205
|
+
| `background/action-highlight` | `#593207` | `color/marigold/4` | Hover state for action surfaces. Feedback color for interactive surfaces and buttons on hover. |
|
|
206
|
+
| `background/action-secondary` | `#F8F2E6` | `color/marigold/1` | Surface color for secondary button default state within Marigold sections. |
|
|
207
|
+
| `background/action-secondary-highlight` | `#FFFFFF` | `color/neutral/white` | Hover state for secondary buttons within Marigold sections. Visual feedback that the outlined button is interactive. Apply on `:hover` and `:active` only. |
|
|
208
|
+
| `background/primary-disabled` | `#996210` (30%) | `color/marigold/3-1` | Disabled state surface for Marigold primary buttons. Low opacity signals unavailability. |
|
|
209
|
+
|
|
210
|
+
### Border
|
|
211
|
+
|
|
212
|
+
| Token | Hex | Primitive | Description |
|
|
213
|
+
|---|---|---|---|
|
|
214
|
+
| `border/primary` | `#996210` | `color/marigold/3` | Deep gold border. Main border color for defining component boundaries within Marigold sections. |
|
|
215
|
+
| `border/primary-inverse` | `#F8F2E6` | `color/marigold/1` | Light marigold inverted border. Used for elements placed on dark amber surfaces. |
|
|
216
|
+
| `border/secondary` | `#F8CD69` | `color/marigold/2` | Medium-contrast border. Use for card borders, internal table dividers, and secondary component outlines. |
|
|
217
|
+
| `border/secondary-disabled` | `#212121` (30%) | `color/gray/800-1` | Disabled or inactive state for secondary button (30% opacity). |
|
|
218
|
+
| `border/tertiary` | `#FFFFFF` | `color/neutral/white` | Low-contrast subtle border for this theme. Use for low-emphasis decorative lines or subtle element separation. |
|
|
219
|
+
| `border/action` | `#996210` | `color/marigold/3` | Brand-colored border for this theme. Use for active focus states, selection rings, and brand-themed outlines. |
|
|
220
|
+
| `border/action-highlight` | `#593207` | `color/marigold/4` | Hover state for Marigold action borders. Darker amber that darkens the outline on interaction. Apply on `:hover` and `:active` only. |
|
|
221
|
+
|
|
222
|
+
### Underline
|
|
223
|
+
|
|
224
|
+
| Token | Hex | Primitive | Description |
|
|
225
|
+
|---|---|---|---|
|
|
226
|
+
| `heading-underline-primary` | `#F8CD69` | `color/marigold/2` | Brand-colored heading accent. A decorative variable used for brand underlines beneath main titles. |
|
|
227
|
+
|
|
228
|
+
### Figma source caveats — Marigold
|
|
229
|
+
|
|
230
|
+
- The Figma table renders `border/primary-inverse` with hex `#223829` (an eco-green value) and description "Brand gold accent. Specific decorative underline for headings." Both fields appear pasted from another token; the primitive `color/marigold/1` and the surrounding Marigold palette make `#F8F2E6` the correct value. Corrected above.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Stone Light theme
|
|
235
|
+
|
|
236
|
+
**Neutral warm stone · Earth-toned content.**
|
|
237
|
+
|
|
238
|
+
Editorial and story atmosphere where green would compete with imagery. Note that **the code names this theme `stone-light`** which matches Figma's naming (unlike Marigold).
|
|
239
|
+
|
|
240
|
+
### Text
|
|
241
|
+
|
|
242
|
+
| Token | Hex | Primitive | Description |
|
|
243
|
+
|---|---|---|---|
|
|
244
|
+
| `text/primary` | `#2E271E` | `color/stone/4` | Primary text for body copy, headlines, and icons within Stone Light sections. The darkest stone value. |
|
|
245
|
+
| `text/primary-inverse` | `#F3F1EF` | `color/stone/1` | Light stone text. Used for contrast when text is placed on dark stone surfaces (`background/primary-inverse`). |
|
|
246
|
+
| `text/secondary` | `#505050` | `color/gray/600` | Subtle gray text. Used for secondary labels, metadata, and supporting information. |
|
|
247
|
+
| `text/tertiary` | `#757575` | `color/gray/500` | Low-contrast muted text. Used for hints or non-essential decorative text. |
|
|
248
|
+
| `text/action` | `#635544` | `color/stone/3` | Interactive text for links and clickable labels. Passes AA on `background/primary` and `background/secondary`. Do not use on `background/tertiary` (`#C4C4C4`) — contrast fails there. |
|
|
249
|
+
| `text/action-highlight` | `#2E271E` | `color/stone/4` | Hover and pressed state for `text/action` within Stone sections. Apply on `:hover` and `:active` only. |
|
|
250
|
+
| `text/action-disabled` | `#212121` (30%) | `color/gray/800-1` | Disabled text within Stone sections. Opacity-based — the low contrast communicates unavailability. |
|
|
251
|
+
|
|
252
|
+
### Background
|
|
253
|
+
|
|
254
|
+
| Token | Hex | Primitive | Description |
|
|
255
|
+
|---|---|---|---|
|
|
256
|
+
| `background/primary` | `#F3F1EF` | `color/stone/1` | Warm stone section background. Base surface for Stone Light sections — testimonials, partner areas, neutral content bands. |
|
|
257
|
+
| `background/primary-inverse` | `#2E271E` | `color/stone/4` | Dark stone surface for high-emphasis containers within Stone sections. Creates strong contrast — use only when genuine emphasis is needed. |
|
|
258
|
+
| `background/secondary` | `#FFFFFF` | `color/neutral/white` | Subtle secondary surface. Use for nested cards, form inputs, or to differentiate sub-regions from the main stone surface. |
|
|
259
|
+
| `background/tertiary` | `#C4C4C4` | `color/gray/300` | Low-priority decorative surface. Use inside a component (e.g., progress bar track) or for a disabled button surface. |
|
|
260
|
+
| `background/action` | `#635544` | `color/stone/3` | Muted stone action surface. Primary button fill for Stone theme buttons. |
|
|
261
|
+
| `background/action-highlight` | `#2E271E` | `color/stone/4` | Hover state for action surfaces. Visual feedback for interactive buttons or cards on hover. |
|
|
262
|
+
| `background/action-secondary` | `#F3F1EF` | `color/stone/1` | Surface color for secondary button default state within Stone sections. |
|
|
263
|
+
| `background/action-secondary-highlight` | `#FFFFFF` | `color/neutral/white` | Hover state for secondary surfaces. Visual feedback for interactive cards or outlined buttons on hover. |
|
|
264
|
+
| `background/primary-disabled` | `#635544` (30%) | `color/stone/3-1` | Disabled or inactive state for primary button (30% opacity). |
|
|
265
|
+
|
|
266
|
+
### Border
|
|
267
|
+
|
|
268
|
+
| Token | Hex | Primitive | Description |
|
|
269
|
+
|---|---|---|---|
|
|
270
|
+
| `border/primary` | `#635544` | `color/stone/3` | Muted stone border. Used for component outlines and layout dividers within Stone sections. |
|
|
271
|
+
| `border/primary-inverse` | `#2E271E` | `color/stone/4` | Dark stone border. Inverted border for elements placed on light stone containers. |
|
|
272
|
+
| `border/secondary` | `#AA9E8D` | `color/stone/2` | Muted stone border. Subtle separation for secondary UI elements or nested sections. |
|
|
273
|
+
| `border/secondary-disabled` | `#212121` (30%) | `color/gray/800-1` | Disabled or inactive state for secondary button (30% opacity). |
|
|
274
|
+
| `border/tertiary` | `#FFFFFF` | `color/neutral/white` | Low-contrast subtle border. Use for low-emphasis decorative lines or subtle element separation. |
|
|
275
|
+
| `border/action` | `#635544` | `color/stone/3` | Muted stone interactive border. Base color for action selection borders and primary button outlines. |
|
|
276
|
+
| `border/action-highlight` | `#2E271E` | `color/stone/4` | Hover state for Stone action borders. Visual feedback when hovering over interactive brand elements (e.g., secondary buttons). |
|
|
277
|
+
|
|
278
|
+
### Underline
|
|
279
|
+
|
|
280
|
+
| Token | Hex | Primitive | Description |
|
|
281
|
+
|---|---|---|---|
|
|
282
|
+
| `heading-underline-primary` | `#AA9E8D` | `color/stone/2` | Brand-colored heading accent. A decorative variable used for brand underlines beneath main titles. |
|
|
283
|
+
|
|
284
|
+
### Figma source caveats — Stone Light
|
|
285
|
+
|
|
286
|
+
- `background/action-secondary-highlight` and `background/primary-disabled` descriptions in Figma are copy-pasted from other rows ("Hover state for warning surfaces…" and "Hover state for error surfaces…"). The corrected descriptions above reflect actual use.
|
|
287
|
+
- `border/secondary`'s Figma description refers to "muted brand green border" — left-over text from the Green Dark table. Corrected to "muted stone border."
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Shadow colors
|
|
292
|
+
|
|
293
|
+
Three color tokens drive elevation. Apply the shadow token via the relevant component or utility rather than hand-rolling an `rgba()` — that way dark-theme shadows can be retuned without component rewrites.
|
|
294
|
+
|
|
295
|
+
| Token | Hex | Primitive | Description |
|
|
296
|
+
|---|---|---|---|
|
|
297
|
+
| `shadow/default` | `#000000` (8%) | `color/shadow/default` | Default elevation shadow. Apply to cards, sticky elements, and any surface that should read as "lifted off the page." |
|
|
298
|
+
| `shadow/hover` | `#000000` (16%) | `color/shadow/hover` | Stronger shadow for hover and interactive emphasis. Adds visible lift on `:hover` for cards and buttons. |
|
|
299
|
+
| `shadow/click-active` | `#000000` (8%) | `color/shadow/click-active` | Pressed-state shadow. Used on `:active` to communicate the surface has been pushed back toward the page. |
|
|
300
|
+
|
|
301
|
+
### Figma source caveats — Shadow
|
|
302
|
+
|
|
303
|
+
- The Figma shadow table has the description and primitive-token columns swapped between the `shadow/hover` and `shadow/click-active` rows. The (semantic name, hex) pairings by row position are canonical and have been used above; the `:hover`-typically-stronger-than-`:active` convention confirms the assignment.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Figma source reference
|
|
308
|
+
|
|
309
|
+
- Color Themes and Usage: node `17950:8787`
|
|
310
|
+
- Default theme table: `18644:1206`
|
|
311
|
+
- Green Dark theme table: `18703:11854`
|
|
312
|
+
- Green Light theme table: `18712:12784`
|
|
313
|
+
- Marigold theme table: `18703:12254`
|
|
314
|
+
- Stone Light theme table: `18703:12497`
|
|
315
|
+
- Shadow token table: `18712:12793`
|
|
316
|
+
|
|
317
|
+
File: `TPmBUB4olYPMF6glEhBGDG` (Ecosystem 2026 — WIP)
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Kiva Color
|
|
2
|
+
|
|
3
|
+
**When to use:** When designing or implementing anything that has color — backgrounds, text, borders, button surfaces, alert states, themed sections — or when picking between two tokens that look similar. Use it before reaching for a hex value, before applying a theme to a section, and any time a color decision crosses a semantic line (action vs. caution, primary vs. secondary, default vs. inverse). Reference design intent first; verify token names against current code before relying on them.
|
|
4
|
+
|
|
5
|
+
## Source of truth
|
|
6
|
+
|
|
7
|
+
This skill captures the **semantic color system** as defined in Figma (the Kiva Ecosystem 2026 file). Figma is the canonical source for design intent: which primitives exist, which themes are supported, what each semantic token means, when to use it, and how tokens compose into accessible pairings.
|
|
8
|
+
|
|
9
|
+
Hex values and token names in this document reflect the Figma specifications. The shipped code in `@kiva/kv-tokens` may temporarily lag behind these specs while the token sync work is in progress. **Verify any token reference against the current code before depending on it.** See "Outstanding discrepancies" at the end of this skill for known gaps, and "Using with Tailwind" for code naming and the shipped utility surface.
|
|
10
|
+
|
|
11
|
+
## Why color matters
|
|
12
|
+
|
|
13
|
+
Color does work on Kiva that the rest of the system can't: it tells a lender which button advances the lending flow, signals to a borrower that a field is in error, and separates a marigold "story" section from a default "form" section without needing a single word of copy. The semantic color system encodes that work in token names — `background/action` is *the* button color in whatever theme is active, not "green" — so the same component behaves correctly under any of the five themes.
|
|
14
|
+
|
|
15
|
+
Common alternative names you may see used interchangeably: **color palette**, **color variables**, **design tokens**, **swatches**, **semantic colors**.
|
|
16
|
+
|
|
17
|
+
## Design principles
|
|
18
|
+
|
|
19
|
+
1. **Name the purpose, not the hue.** Use `text/action` for an interactive link, not "green" — the token resolves to the right color per theme. If you ever find yourself picking a token because it "looks right," step back and pick by intent.
|
|
20
|
+
2. **Themes scope intent.** A theme is a coordinated set of role/slot tokens tuned for one page atmosphere. The token name stays the same across themes; the value changes. Compose pages from themed *sections*, don't repaint individual components.
|
|
21
|
+
3. **Semantic meanings don't theme.** Error stays red, warning stays amber. Caution and danger token values are stable across themes precisely because the meaning is stable.
|
|
22
|
+
4. **Always reference semantic tokens, not primitives.** Primitives exist to *build* semantic tokens. Components should never reach past the semantic layer into a raw `eco-green/3` or `gray/500`.
|
|
23
|
+
|
|
24
|
+
## Primitives
|
|
25
|
+
|
|
26
|
+
Primitive tokens are the raw values that power every semantic token. Use these only when defining new semantic tokens — components should always consume the semantic layer.
|
|
27
|
+
|
|
28
|
+
| Family | Step | Hex | | Family | Step | Hex |
|
|
29
|
+
|---|---|---|---|---|---|---|
|
|
30
|
+
| **eco-green** | 1 | `#EDF4F1` | | **stone** | 1 | `#F3F1EF` |
|
|
31
|
+
| | 2 | `#78C79F` | | | default | `#DFD0BC` |
|
|
32
|
+
| | default | `#2AA967` | | | 2 | `#AA9E8D` |
|
|
33
|
+
| | 3 | `#276A43` | | | 3 | `#635544` |
|
|
34
|
+
| | 4 | `#223829` | | | 4 | `#2E271E` |
|
|
35
|
+
| **marigold** | 1 | `#F8F2E6` | | **gray** | 50 | `#FAFAFA` |
|
|
36
|
+
| | 2 | `#F8CD69` | | | 100 | `#F5F5F5` |
|
|
37
|
+
| | default | `#F4B539` | | | 200 | `#E0E0E0` |
|
|
38
|
+
| | 3 | `#996210` | | | 300 | `#C4C4C4` |
|
|
39
|
+
| | 4 | `#593207` | | | 400 | `#9E9E9E` |
|
|
40
|
+
| **desert-rose** | 1 | `#F9F0EF` | | | 500 | `#757575` |
|
|
41
|
+
| | 2 | `#E0988D` | | | 600 | `#505050` |
|
|
42
|
+
| | default | `#C45F4F` | | | 700 | `#454545` |
|
|
43
|
+
| | 3 | `#A24536` | | | 800 | `#212121` |
|
|
44
|
+
| | 4 | `#5C2A22` | | **neutral** | white | `#FFFFFF` |
|
|
45
|
+
| | | | | | black | `#000000` |
|
|
46
|
+
|
|
47
|
+
The stone family uses an out-of-order step naming (`1`, `default`, `2`, `3`, `4`) so the lighter swatch keeps the visual position designers expect. Don't try to "fix" it.
|
|
48
|
+
|
|
49
|
+
> **Figma label typo for `eco-green/2`.** The Color Overview panel renders the text label `#C7EDD7` on top of the `eco-green/2` swatch, but the swatch's *actual fill* is `#78C79F` (the value above). The label is stale; the chip color, the Figma `color/eco-green/2` variable, and the shipped code (`tokens/core/color.json`) all agree on `#78C79F`. Use `#78C79F`.
|
|
50
|
+
|
|
51
|
+
## Themes
|
|
52
|
+
|
|
53
|
+
Five themes are supported. Each is suited to a specific page atmosphere; choose one as the section's base and let the semantic tokens do the rest.
|
|
54
|
+
|
|
55
|
+
| Theme | Atmosphere | Use for |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| **Default** | White background, neutral and trustworthy | Forms, dashboards, primary content surfaces. The required theme for any form or text field. |
|
|
58
|
+
| **Green Light** | Light green tinted surfaces | Secondary sections that lean on brand color without dominating. Inherits Default's text, action, and caution tokens. |
|
|
59
|
+
| **Green Dark** | Dark green sections | High-emphasis brand moments (impact stats, partner CTAs). Section-level only — never the whole page. |
|
|
60
|
+
| **Marigold** | Warm amber accents | Marketing, donation, warmth-forward stories. |
|
|
61
|
+
| **Stone Light** | Neutral warm stone | Editorial / story content where green would compete with imagery. |
|
|
62
|
+
|
|
63
|
+
## Token grammar
|
|
64
|
+
|
|
65
|
+
Every semantic token reads as **role / slot / state-modifier**:
|
|
66
|
+
|
|
67
|
+
| Part | Meaning | Examples |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| **Role** | What kind of property the token paints. | `text`, `background`, `border`, `heading-underline`, `shadow` |
|
|
70
|
+
| **Slot** | What the color communicates. | `primary`, `secondary`, `tertiary`, `action`, `caution`, `danger` |
|
|
71
|
+
| **State modifier** *(optional)* | Interaction or context variant. | `highlight` (hover / pressed), `inverse` (on opposite-tone surface), `disabled`, `secondary` (alternate emphasis within a state) |
|
|
72
|
+
|
|
73
|
+
A few practical reads:
|
|
74
|
+
|
|
75
|
+
- `text/primary` — the standard body copy color for the current theme.
|
|
76
|
+
- `background/action-highlight` — the button surface under a hover or pressed state.
|
|
77
|
+
- `border/primary-inverse` — the border color used when the component sits on a dark surface in the current theme.
|
|
78
|
+
- `text/danger` — the foreground for an error message; pair with `background/danger-highlight` for the standard alert surface.
|
|
79
|
+
|
|
80
|
+
## Per-theme token tables
|
|
81
|
+
|
|
82
|
+
Every theme's full token list — name, hex, primitive source, and Figma-authored description for every text / background / border / underline token — lives in the companion reference file [color-themes.md](color-themes.md). That file is the data layer; this file is the framework.
|
|
83
|
+
|
|
84
|
+
A quick orientation before you load it:
|
|
85
|
+
|
|
86
|
+
- **Default** is the base. Every other theme inherits Default and only redefines the tokens that differ.
|
|
87
|
+
- **Green Light** is the smallest theme — only two unique tokens (`background/primary`, `background/primary-inverse`). Everything else falls back to Default.
|
|
88
|
+
- **Green Dark**, **Marigold**, and **Stone Light** each define their own full set of text / background / border tokens plus `heading-underline-primary`.
|
|
89
|
+
- **Alert tokens** (`text/caution(+-highlight)`, `text/danger(+-highlight)`, `background/caution(+-highlight)`, `background/danger(+-highlight)`, `border/caution(+-highlight)`, `border/danger(+-highlight)`) are defined on Default only and used unchanged across themes — caution stays amber, danger stays desert-rose. See "Preserve semantic color meaning" below.
|
|
90
|
+
|
|
91
|
+
The companion file also documents `shadow/default`, `shadow/hover`, and `shadow/click-active` and calls out the (several) Figma copy-paste errors in the source table.
|
|
92
|
+
|
|
93
|
+
## The disabled-state pattern
|
|
94
|
+
|
|
95
|
+
Disabled tokens (`text/action-disabled`, `background/primary-disabled`, `border/secondary-disabled`) are not full new color values — they are an **existing primitive at reduced opacity**. The Figma table renders this as a primitive name with a `-1` suffix (e.g., `color/gray/800-1` = `#212121` at 30%; `color/eco-green/3-1` = `#276A43` at 30%).
|
|
96
|
+
|
|
97
|
+
The takeaway: a disabled state is the active-state color washed down — not a separately tuned gray. If you find yourself reaching for a custom disabled color, use the matching `*-disabled` token instead.
|
|
98
|
+
|
|
99
|
+
## Shadow tokens (interaction-driven)
|
|
100
|
+
|
|
101
|
+
Three color tokens drive elevation: `shadow/default` (resting), `shadow/hover` (lifted on hover), `shadow/click-active` (pressed). The naming is **interaction-state-based**, not severity-based. Full descriptions in [color-themes.md](color-themes.md#shadow-colors).
|
|
102
|
+
|
|
103
|
+
## Accessibility
|
|
104
|
+
|
|
105
|
+
Every meaningful foreground/background pairing in the Figma "Color Accessibility" panel is rated against **WCAG 2.1 AA (4.5:1)** and **AAA (7:1)** for normal body text.
|
|
106
|
+
|
|
107
|
+
| Badge | Meaning | Safe for |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| **Pass** | Ratio ≥ 7:1 (passes AA and AAA) | All text, all sizes. |
|
|
110
|
+
| **AA only** | 4.5:1 ≤ ratio < 7:1 | Normal body text; not for extended reading at small sizes or thin weights. |
|
|
111
|
+
| **Large only** | 3:1 ≤ ratio < 4.5:1 | Large text (≥ 18pt or ≥ 14pt bold), icons, decorative type — never small body copy. |
|
|
112
|
+
| **Fail** | Ratio < 4.5:1 (below AA) | Non-text decorative use only, or intentionally low-emphasis states (e.g., disabled). |
|
|
113
|
+
|
|
114
|
+
A "Fail" is not automatically a bug. Some pairings fail on purpose — disabled controls, decorative panels — but a few are dangerous and should never be used for readable content. The Figma panel calls those out individually; treat its annotations as authoritative for which "Fail" pairings are acceptable.
|
|
115
|
+
|
|
116
|
+
Notable real-world callouts from the Figma rating tables:
|
|
117
|
+
|
|
118
|
+
- **Default theme:** `text/tertiary` on `background/secondary` is `4.1:1` and on `background/tertiary` is `2.6:1` — both flagged **Fail** in Figma with the note "Does not pass AA at any text size." Don't use `text/tertiary` for readable copy on those surfaces; use `text/primary` or `text/secondary` instead. (The 4.1:1 ratio technically clears 3:1 for large text, but the design system team is explicit that this pairing should not be used for readable text — heed the explicit guidance.)
|
|
119
|
+
- **Green Light:** inherits Default's text/action/caution ratings — refer to Default for those, not duplicated in the Green Light table.
|
|
120
|
+
- **Green Dark:** has a critically low pairing (`text/primary` on `background/tertiary` at `1.5:1`) explicitly flagged "must never be used." Treat the warning as load-bearing.
|
|
121
|
+
- **Marigold:** `text/tertiary` pairings drop into Large-only or Fail; keep tertiary text off Marigold body surfaces.
|
|
122
|
+
- **Stone Light:** similar caution around `text/tertiary` — Large-only on `background/primary`, Fail on `background/tertiary`.
|
|
123
|
+
- **Alerts:** the alert tokens (`text/caution(+-highlight)`, `text/danger(+-highlight)`) are defined on Default and used across themes. They pass AA on their paired alert backgrounds.
|
|
124
|
+
|
|
125
|
+
When in doubt, look the pairing up in the Figma table before approving it for body copy.
|
|
126
|
+
|
|
127
|
+
## Best practices
|
|
128
|
+
|
|
129
|
+
### Limit 1–2 primary themes per page
|
|
130
|
+
|
|
131
|
+
- **Do** keep a page visually cohesive by anchoring it in one to two primary themes, with an optional tertiary theme for emphasis if needed.
|
|
132
|
+
- **Don't** stack multiple themed sections (Default → Green Dark → Stone Light → Marigold) in a single page — the page reads as a swatchbook.
|
|
133
|
+
|
|
134
|
+
### Buttons adapt to their theme context
|
|
135
|
+
|
|
136
|
+
- **Do** use the theme's `background/action` and `text/action` tokens — the button reads as "primary" in whatever theme it sits in.
|
|
137
|
+
- **Don't** hard-pin a button to a specific brand color or override `background/action` to enforce a global "primary green." Doing so breaks contrast guarantees in dark themes and defeats the point of theming.
|
|
138
|
+
|
|
139
|
+
### Don't mix theme content within a single section
|
|
140
|
+
|
|
141
|
+
- **Do** keep all content inside one section on the same theme. Theme switches should align with section boundaries.
|
|
142
|
+
- **Don't** drop a Green Dark card into a Default section just to call attention to it — use spacing, hierarchy, or a sectioning component instead.
|
|
143
|
+
|
|
144
|
+
### All forms and text fields follow the Default theme
|
|
145
|
+
|
|
146
|
+
- **Do** render forms and inputs in Default theme, even when the surrounding section uses another theme.
|
|
147
|
+
- **Don't** apply alternate themes to inputs, selects, or controls. Input contrast and focus states are tuned only against Default; off-theme inputs fail accessibility and read as broken.
|
|
148
|
+
|
|
149
|
+
### Dark theme is for sections, not pages
|
|
150
|
+
|
|
151
|
+
- **Do** use Green Dark to highlight specific sections.
|
|
152
|
+
- **Don't** stack multiple Green Dark sections back to back without a visual break — the page loses rhythm and the dark sections stop reading as emphasized.
|
|
153
|
+
|
|
154
|
+
### Preserve semantic color meaning
|
|
155
|
+
|
|
156
|
+
- **Do** keep alert colors stable — caution is amber, danger is desert-rose, success is eco-green. Use `text/danger` and the danger backgrounds only for error states.
|
|
157
|
+
- **Don't** redefine what a color represents per context (e.g., using desert-rose as a brand accent in a marketing band). The same color must mean the same thing everywhere or the system stops communicating.
|
|
158
|
+
|
|
159
|
+
## How to use in Figma
|
|
160
|
+
|
|
161
|
+
### Picking the right token
|
|
162
|
+
|
|
163
|
+
Tokens are namespaced in the Figma variable picker by role. Search keywords:
|
|
164
|
+
|
|
165
|
+
- `text` for foregrounds, `background` (or `bg`) for surfaces, `border` for outlines.
|
|
166
|
+
- Add the slot to narrow further: `text/action`, `background/primary-inverse`, `border/danger-highlight`.
|
|
167
|
+
|
|
168
|
+
If the variable picker shows two tokens with the same hex value, pick by *role*, not by value — `border/secondary` and `text/secondary` resolve to the same gray today but will diverge if the secondary text ramp shifts.
|
|
169
|
+
|
|
170
|
+
### Theming a section
|
|
171
|
+
|
|
172
|
+
1. Wrap the section frame in a component or auto-layout container themed via Figma variable modes.
|
|
173
|
+
2. Switch the mode to the target theme (`default`, `green-light`, `green-dark`, `marigold`, `stone-light`).
|
|
174
|
+
3. Every variable-bound color in that subtree updates automatically.
|
|
175
|
+
4. Forms inside the section still use Default — re-wrap form children in a Default-themed container.
|
|
176
|
+
|
|
177
|
+
### Before handoff
|
|
178
|
+
|
|
179
|
+
Walk the file and check fills, strokes, and text colors for raw hex values. **Re-bind any raw value to a variable** — a raw hex is a detached color decision that won't follow updates and gives engineering nothing to map to. The Figma panel calls this out explicitly; treat it as a hard gate on hand-off.
|
|
180
|
+
|
|
181
|
+
## Using with Tailwind
|
|
182
|
+
|
|
183
|
+
The color utilities come from the `@kiva/kv-tokens` Tailwind preset. Haven't registered it yet? See [tailwind → Consuming the preset](tailwind.md#consuming-the-preset). Not using the preset? See [Without the preset](#without-the-preset) below.
|
|
184
|
+
|
|
185
|
+
**Themable colors** are exposed as `tw-text-{slot}`, `tw-bg-{slot}`, `tw-border-{slot}`, `tw-divide-{slot}`, and `tw-ring-{slot}` — e.g. `tw-bg-primary`, `tw-text-action`, `tw-border-danger-highlight`. The slot names match the semantic token names in [color-themes.md](color-themes.md) (with `background/` → `bg-`). They compile to `rgb(var(--token))` and resolve at runtime from CSS custom properties, so they follow the active theme — reach for them by default. See [tailwind → Color is semantic, themable, and runtime-resolved](tailwind.md#color-is-semantic-themable-and-runtime-resolved), and [tailwind → Make themable colors resolve](tailwind.md#3-make-themable-colors-resolve-required-for-color-to-render) for how the custom properties get onto the page (`KvThemeProvider` does this in components).
|
|
186
|
+
|
|
187
|
+
**Primitive (non-themed) utilities** — `tw-bg-eco-green-3`, `tw-text-marigold-DEFAULT`, `tw-bg-gray-100`, etc. — resolve directly to primitive values and do **not** change with theme. Use sparingly; components should consume semantic tokens, not primitives.
|
|
188
|
+
|
|
189
|
+
**Theme names: type the code name, not the Figma name.** When importing themes from `@kiva/kv-tokens` (e.g. `marigoldLightTheme`) or referencing one in code:
|
|
190
|
+
|
|
191
|
+
| Figma (design intent) | Code (what to type) |
|
|
192
|
+
|---|---|
|
|
193
|
+
| Default | `DEFAULT` |
|
|
194
|
+
| Green Light | `green-light` |
|
|
195
|
+
| Green Dark | `green-dark` |
|
|
196
|
+
| Marigold | `marigold-light` *(code suffixes `-light`)* |
|
|
197
|
+
| Stone Light | `stone-light` |
|
|
198
|
+
|
|
199
|
+
Legacy themes still exported in code (`dark`, `dark-green`, `dark-mint`, `dark-stone`, `mint`, `stone-dark`) predate the five-theme system and are kept for backwards compatibility — **don't pick them for new work.**
|
|
200
|
+
|
|
201
|
+
**Authoritative sources** (verify before depending):
|
|
202
|
+
|
|
203
|
+
- `@kiva/kv-tokens/tokens/core/color.json` — primitive palette declarations.
|
|
204
|
+
- `@kiva/kv-tokens/dist/js/tokens.js` (`colors.theme.*`) — the built, per-theme semantic token tree.
|
|
205
|
+
- `@kiva/kv-tokens/configs/kivaColors.js` — turns each theme into CSS custom properties and exposes the Tailwind color choices.
|
|
206
|
+
- `@kiva/kv-tokens/configs/tailwind.config.js` — wires the custom properties into the `tw-text-*` / `tw-bg-*` / `tw-border-*` / `tw-divide-*` / `tw-ring-*` utilities.
|
|
207
|
+
- [`KvThemeProvider.vue`](../../../kv-components/src/vue/KvThemeProvider.vue) — sets the theme custom properties on a subtree.
|
|
208
|
+
|
|
209
|
+
### Without the preset
|
|
210
|
+
|
|
211
|
+
- **Kiva (or Kiva-adjacent) repo, preset not registered yet:** install and register it — [tailwind → Consuming the preset](tailwind.md#consuming-the-preset).
|
|
212
|
+
- **Stock-Tailwind / non-Kiva project:** the themable utilities won't exist. Either import the shipped custom properties from `@kiva/kv-tokens/css` ([`dist/css/tokens.css`](../../dist/css/tokens.css), which ships a `:root` block plus `[data-theme="…"]` blocks) and reference `var(--token)` yourself, or use the static hex values from [color-themes.md](color-themes.md). The hex route loses runtime theming and the values are point-in-time.
|
|
213
|
+
|
|
214
|
+
## Outstanding discrepancies
|
|
215
|
+
|
|
216
|
+
- **`heading-underline/primary` is the only `heading-underline` token shipped,** and only Default, Marigold, and Stone Light (plus legacy `stone-dark`) define it; other themes fall back to whatever the parent provides.
|
|
217
|
+
- **Semantic tokens defined in Figma but not yet in the shipped `colors.theme.*` tree:**
|
|
218
|
+
- `text/action-disabled` (all themes)
|
|
219
|
+
- `background/action-secondary`, `background/action-secondary-highlight`, `background/primary-disabled` (all themes except Green Light)
|
|
220
|
+
- `border/secondary-disabled`, `border/tertiary` (Green Dark, Marigold, Stone Light)
|
|
221
|
+
- `text/secondary`, `text/tertiary`, `background/tertiary`, `border/tertiary` (Green Dark, Marigold, Stone Light)
|
|
222
|
+
|
|
223
|
+
These can be added without breaking changes since they're new entries.
|
|
224
|
+
- **Shadow tokens are not yet color-tokenized.** `boxShadow.DEFAULT` and `boxShadow.lg` in `tailwind.config.js` are hardcoded `rgb(0 0 0 / 0.08)`; the `shadow/default`, `shadow/hover`, `shadow/click-active` semantic tokens described in Figma have no code entry yet.
|
|
225
|
+
|
|
226
|
+
When you find a divergence between this skill and the shipped tokens/components, flag it — closing those gaps is part of the long-running token sync work, and each instance is a data point.
|
|
227
|
+
|
|
228
|
+
## Figma source references
|
|
229
|
+
|
|
230
|
+
- Color Overview: node `18445:832`
|
|
231
|
+
- Color Themes and Usage: node `17950:8787`
|
|
232
|
+
- Color Accessibility: node `18829:465`
|
|
233
|
+
- Color Guidelines: node `18296:7293`
|
|
234
|
+
|
|
235
|
+
File: `TPmBUB4olYPMF6glEhBGDG` (Ecosystem 2026 — WIP)
|