picasso-skill 2.4.0 → 2.6.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/agents/picasso.md +26 -542
- package/commands/godmode.md +3 -13
- package/commands/roast.md +3 -14
- package/commands/score.md +3 -18
- package/commands/steal.md +3 -31
- package/package.json +1 -1
- package/references/accessibility-wcag.md +3 -0
- package/references/code-typography.md +36 -166
- package/references/color-and-contrast.md +78 -345
- package/references/generative-art.md +49 -561
- package/references/modern-css-performance.md +46 -258
- package/references/motion-and-animation.md +225 -88
- package/references/navigation-patterns.md +29 -186
- package/references/performance-optimization.md +42 -678
- package/references/react-patterns.md +56 -216
- package/references/responsive-design.md +77 -379
- package/references/sensory-design.md +62 -263
- package/references/ux-writing.md +64 -354
- package/references/animation-performance.md +0 -244
- package/references/interaction-design.md +0 -162
|
@@ -1,23 +1,10 @@
|
|
|
1
1
|
# Color and Contrast Reference
|
|
2
2
|
|
|
3
|
-
## Table of Contents
|
|
4
|
-
1. Color Space and Manipulation
|
|
5
|
-
2. Palette Construction
|
|
6
|
-
3. Tinted Neutrals
|
|
7
|
-
4. Dark Mode
|
|
8
|
-
5. Accessibility
|
|
9
|
-
6. CSS Variables Pattern
|
|
10
|
-
7. Curated Color Palettes
|
|
11
|
-
8. Wide Gamut Colors (P3)
|
|
12
|
-
9. `light-dark()` CSS Function
|
|
13
|
-
10. `color-mix()` for Runtime Blending
|
|
14
|
-
11. Common Mistakes
|
|
15
|
-
|
|
16
3
|
---
|
|
17
4
|
|
|
18
|
-
## 1. Color Space
|
|
5
|
+
## 1. Color Space
|
|
19
6
|
|
|
20
|
-
Use OKLCH for perceptually uniform color. Unlike HSL, OKLCH ensures
|
|
7
|
+
Use OKLCH for perceptually uniform color. Unlike HSL, OKLCH ensures colors at the same lightness value actually appear equally bright.
|
|
21
8
|
|
|
22
9
|
```css
|
|
23
10
|
/* OKLCH: lightness (0-1), chroma (0-0.4), hue (0-360) */
|
|
@@ -26,7 +13,7 @@ Use OKLCH for perceptually uniform color. Unlike HSL, OKLCH ensures that colors
|
|
|
26
13
|
--accent-muted: oklch(0.75 0.08 25); /* same hue, much less chroma */
|
|
27
14
|
```
|
|
28
15
|
|
|
29
|
-
|
|
16
|
+
Adjust lightness for tints/shades, chroma for saturation, hue for variation.
|
|
30
17
|
|
|
31
18
|
---
|
|
32
19
|
|
|
@@ -38,35 +25,31 @@ For programmatic palette generation, adjust lightness for tints/shades, chroma f
|
|
|
38
25
|
- 10% accent (CTAs, active states, highlights)
|
|
39
26
|
|
|
40
27
|
### Building a Palette
|
|
41
|
-
1. Start with the accent color (
|
|
42
|
-
2. Derive
|
|
28
|
+
1. Start with the accent color (brand or action color)
|
|
29
|
+
2. Derive surface color: very low chroma version of the accent hue
|
|
43
30
|
3. Build neutral scale: tinted toward the accent hue (never pure gray)
|
|
44
|
-
4. Add
|
|
45
|
-
5. Generate dark mode
|
|
31
|
+
4. Add semantic layer: success (green), warning (amber), error (red), info (blue)
|
|
32
|
+
5. Generate dark mode by inverting the lightness scale, not the colors
|
|
46
33
|
|
|
47
34
|
### Token Structure
|
|
48
35
|
```css
|
|
49
36
|
:root {
|
|
50
37
|
/* Surfaces */
|
|
51
|
-
--surface-0: oklch(0.99 0.005 80);
|
|
52
|
-
--surface-1: oklch(0.97 0.008 80);
|
|
53
|
-
--surface-2: oklch(0.94 0.01 80);
|
|
54
|
-
--surface-3: oklch(0.90 0.012 80);
|
|
55
|
-
|
|
38
|
+
--surface-0: oklch(0.99 0.005 80); /* page bg */
|
|
39
|
+
--surface-1: oklch(0.97 0.008 80); /* card bg */
|
|
40
|
+
--surface-2: oklch(0.94 0.01 80); /* elevated/hover */
|
|
41
|
+
--surface-3: oklch(0.90 0.012 80); /* active/selected */
|
|
56
42
|
/* Text */
|
|
57
43
|
--text-primary: oklch(0.15 0.02 80);
|
|
58
44
|
--text-secondary: oklch(0.40 0.02 80);
|
|
59
45
|
--text-tertiary: oklch(0.55 0.015 80);
|
|
60
|
-
|
|
61
46
|
/* Accent */
|
|
62
47
|
--accent: oklch(0.55 0.25 30);
|
|
63
48
|
--accent-hover: oklch(0.50 0.28 30);
|
|
64
49
|
--accent-subtle: oklch(0.92 0.04 30);
|
|
65
|
-
|
|
66
50
|
/* Borders */
|
|
67
51
|
--border: oklch(0.88 0.01 80);
|
|
68
52
|
--border-strong: oklch(0.78 0.015 80);
|
|
69
|
-
|
|
70
53
|
/* Semantic */
|
|
71
54
|
--success: oklch(0.55 0.18 145);
|
|
72
55
|
--warning: oklch(0.65 0.18 70);
|
|
@@ -78,400 +61,150 @@ For programmatic palette generation, adjust lightness for tints/shades, chroma f
|
|
|
78
61
|
|
|
79
62
|
## 3. Tinted Neutrals
|
|
80
63
|
|
|
81
|
-
Never use pure gray
|
|
64
|
+
Never use pure gray. Always tint neutrals toward the dominant hue.
|
|
82
65
|
|
|
83
|
-
**Warm neutrals** (
|
|
84
|
-
**Cool neutrals** (
|
|
85
|
-
**Neutral neutrals** (
|
|
66
|
+
- **Warm neutrals** (amber/brown): editorial, luxury, organic brands
|
|
67
|
+
- **Cool neutrals** (blue/slate): tech, data, professional tools
|
|
68
|
+
- **Neutral neutrals** (accent hue, very low chroma): most versatile
|
|
86
69
|
|
|
87
70
|
```css
|
|
88
|
-
/*
|
|
89
|
-
--
|
|
90
|
-
|
|
91
|
-
/* Instead of #f5f5f5 */
|
|
92
|
-
--surface-bg: oklch(0.97 0.005 260); /* cool-tinted light */
|
|
71
|
+
--text-primary: oklch(0.25 0.015 260); /* cool-tinted dark, not #333 */
|
|
72
|
+
--surface-bg: oklch(0.97 0.005 260); /* cool-tinted light, not #f5f5f5 */
|
|
93
73
|
```
|
|
94
74
|
|
|
95
75
|
---
|
|
96
76
|
|
|
97
77
|
## 4. Dark Mode
|
|
98
78
|
|
|
99
|
-
Dark mode is not "invert everything."
|
|
79
|
+
Dark mode is not "invert everything." Rules:
|
|
100
80
|
|
|
101
|
-
1. Surface colors get darker but retain
|
|
102
|
-
2. Text
|
|
103
|
-
3. Accent colors
|
|
104
|
-
4.
|
|
105
|
-
5. Elevation
|
|
106
|
-
6. Images
|
|
107
|
-
|
|
108
|
-
```css
|
|
109
|
-
[data-theme="dark"] {
|
|
110
|
-
--surface-0: oklch(0.13 0.01 260);
|
|
111
|
-
--surface-1: oklch(0.17 0.012 260);
|
|
112
|
-
--surface-2: oklch(0.21 0.015 260);
|
|
113
|
-
--text-primary: oklch(0.93 0.01 260);
|
|
114
|
-
--text-secondary: oklch(0.70 0.01 260);
|
|
115
|
-
--border: oklch(0.25 0.01 260);
|
|
116
|
-
}
|
|
117
|
-
```
|
|
81
|
+
1. Surface colors get darker but retain hue tint
|
|
82
|
+
2. Text: never pure white (use oklch lightness 0.93-0.97)
|
|
83
|
+
3. Accent colors need a lightness bump (+0.05 to +0.10) to maintain contrast
|
|
84
|
+
4. Replace shadows with subtle inner glows or border effects
|
|
85
|
+
5. Elevation goes lighter (higher surfaces = lighter), opposite of light mode
|
|
86
|
+
6. Images may need `filter: brightness(0.9)`
|
|
118
87
|
|
|
119
88
|
---
|
|
120
89
|
|
|
121
90
|
## 5. Accessibility
|
|
122
91
|
|
|
123
92
|
### Contrast Requirements (WCAG 2.2)
|
|
124
|
-
- Normal text (<24px or <18.66px bold): 4.5:1 minimum
|
|
125
|
-
- Large text (>=24px or >=18.66px bold): 3:1 minimum
|
|
126
|
-
- UI components and graphical objects: 3:1 minimum
|
|
127
|
-
- Focus indicators: 3:1 against adjacent colors
|
|
93
|
+
- Normal text (<24px or <18.66px bold): **4.5:1** minimum
|
|
94
|
+
- Large text (>=24px or >=18.66px bold): **3:1** minimum
|
|
95
|
+
- UI components and graphical objects: **3:1** minimum
|
|
96
|
+
- Focus indicators: **3:1** against adjacent colors
|
|
128
97
|
|
|
129
|
-
###
|
|
130
|
-
|
|
98
|
+
### Quick Heuristic
|
|
99
|
+
OKLCH lightness difference of 0.40+ between text and background usually passes AA. For precise checking, use APCA when possible.
|
|
131
100
|
|
|
132
101
|
### Color Blindness
|
|
133
|
-
Never use color as the only
|
|
102
|
+
Never use color as the only information channel. Pair with icons, patterns, or text labels. Test with deuteranopia/protanopia simulator.
|
|
134
103
|
|
|
135
104
|
---
|
|
136
105
|
|
|
137
106
|
## 6. CSS Variables Pattern
|
|
138
107
|
|
|
139
|
-
Define all colors as CSS custom properties. Group by function, not
|
|
108
|
+
Define all colors as CSS custom properties. Group by function, not color name.
|
|
140
109
|
|
|
141
110
|
```css
|
|
142
111
|
/* Good: semantic naming */
|
|
143
|
-
--color-surface: ...;
|
|
144
|
-
--color-text: ...;
|
|
145
|
-
--color-accent: ...;
|
|
146
|
-
--color-border: ...;
|
|
147
|
-
|
|
112
|
+
--color-surface: ...; --color-text: ...; --color-accent: ...;
|
|
148
113
|
/* Bad: literal naming */
|
|
149
|
-
--blue: ...;
|
|
150
|
-
--dark-gray: ...;
|
|
151
|
-
--light-blue: ...;
|
|
114
|
+
--blue: ...; --dark-gray: ...; --light-blue: ...;
|
|
152
115
|
```
|
|
153
116
|
|
|
154
|
-
For component
|
|
155
|
-
```css
|
|
156
|
-
.card {
|
|
157
|
-
--card-bg: var(--surface-1);
|
|
158
|
-
--card-border: var(--border);
|
|
159
|
-
background: var(--card-bg);
|
|
160
|
-
border: 1px solid var(--card-border);
|
|
161
|
-
}
|
|
162
|
-
.card.highlighted {
|
|
163
|
-
--card-bg: var(--accent-subtle);
|
|
164
|
-
--card-border: var(--accent);
|
|
165
|
-
}
|
|
166
|
-
```
|
|
117
|
+
For component overrides, use local custom properties that reference global tokens.
|
|
167
118
|
|
|
168
119
|
---
|
|
169
120
|
|
|
170
121
|
## 7. Curated Color Palettes
|
|
171
122
|
|
|
172
|
-
Ten tested OKLCH palettes
|
|
123
|
+
Ten tested OKLCH palettes. Each includes surface, text, accent, border, and semantic tokens. Copy the one that fits your domain, adjust chroma and hue to taste.
|
|
173
124
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
--success: oklch(0.55 0.16 155);
|
|
187
|
-
--warning: oklch(0.68 0.16 75);
|
|
188
|
-
--error: oklch(0.55 0.20 25);
|
|
189
|
-
}
|
|
190
|
-
```
|
|
125
|
+
| # | Name | Vibe | Good For |
|
|
126
|
+
|---|------|------|----------|
|
|
127
|
+
| 1 | Warm Terracotta | Earthy, grounded | Lifestyle, wellness, real estate |
|
|
128
|
+
| 2 | Forest Green | Natural, trustworthy | Fintech, health, environmental |
|
|
129
|
+
| 3 | Amber Gold | Premium, confident | Finance, luxury SaaS, productivity |
|
|
130
|
+
| 4 | Coral Salmon | Warm, energetic | Social apps, creative tools, food |
|
|
131
|
+
| 5 | Deep Teal | Calm, authoritative | Health tech, enterprise, legal |
|
|
132
|
+
| 6 | Slate Blue | Professional, systematic | Project management, B2B SaaS |
|
|
133
|
+
| 7 | Burgundy | Sophisticated, editorial | Wine/food, publishing, fashion |
|
|
134
|
+
| 8 | Sage | Soft, restorative | Wellness, meditation, journaling |
|
|
135
|
+
| 9 | Charcoal + Orange | Bold, industrial | Dev tools, gaming, analytics |
|
|
136
|
+
| 10 | Monochrome B&W | Stark, typographic | Portfolios, photography, editorial |
|
|
191
137
|
|
|
192
|
-
###
|
|
193
|
-
**Vibe**: Natural, sustainable, trustworthy. Good for fintech, health, environmental, agriculture.
|
|
138
|
+
### Example: Warm Terracotta
|
|
194
139
|
```css
|
|
195
140
|
:root {
|
|
196
|
-
--surface-0: oklch(0.98 0.
|
|
197
|
-
--
|
|
198
|
-
--
|
|
199
|
-
--
|
|
200
|
-
--
|
|
201
|
-
--accent-hover: oklch(0.46 0.16 155);
|
|
202
|
-
--accent-subtle: oklch(0.93 0.04 155);
|
|
203
|
-
--border: oklch(0.88 0.012 145);
|
|
204
|
-
--success: oklch(0.55 0.16 145);
|
|
205
|
-
--warning: oklch(0.66 0.16 80);
|
|
206
|
-
--error: oklch(0.55 0.20 25);
|
|
141
|
+
--surface-0: oklch(0.98 0.008 55); --surface-1: oklch(0.95 0.012 55);
|
|
142
|
+
--text-primary: oklch(0.18 0.025 55); --text-secondary: oklch(0.42 0.02 55);
|
|
143
|
+
--accent: oklch(0.58 0.16 45); --accent-hover: oklch(0.52 0.18 45);
|
|
144
|
+
--accent-subtle: oklch(0.93 0.04 45); --border: oklch(0.87 0.015 55);
|
|
145
|
+
--success: oklch(0.55 0.16 155); --warning: oklch(0.68 0.16 75); --error: oklch(0.55 0.20 25);
|
|
207
146
|
}
|
|
208
147
|
```
|
|
209
148
|
|
|
210
|
-
|
|
211
|
-
**Vibe**: Premium, confident, optimistic. Good for finance, luxury SaaS, productivity tools.
|
|
212
|
-
```css
|
|
213
|
-
:root {
|
|
214
|
-
--surface-0: oklch(0.99 0.005 85);
|
|
215
|
-
--surface-1: oklch(0.96 0.01 85);
|
|
216
|
-
--text-primary: oklch(0.16 0.02 85);
|
|
217
|
-
--text-secondary: oklch(0.40 0.018 85);
|
|
218
|
-
--accent: oklch(0.68 0.18 75);
|
|
219
|
-
--accent-hover: oklch(0.62 0.20 75);
|
|
220
|
-
--accent-subtle: oklch(0.94 0.04 75);
|
|
221
|
-
--border: oklch(0.88 0.012 85);
|
|
222
|
-
--success: oklch(0.55 0.16 150);
|
|
223
|
-
--warning: oklch(0.68 0.18 75);
|
|
224
|
-
--error: oklch(0.55 0.20 28);
|
|
225
|
-
}
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### 7.4 Coral Salmon
|
|
229
|
-
**Vibe**: Warm, energetic, approachable. Good for social apps, creative tools, food and hospitality.
|
|
230
|
-
```css
|
|
231
|
-
:root {
|
|
232
|
-
--surface-0: oklch(0.98 0.006 30);
|
|
233
|
-
--surface-1: oklch(0.96 0.01 30);
|
|
234
|
-
--text-primary: oklch(0.18 0.02 30);
|
|
235
|
-
--text-secondary: oklch(0.42 0.018 30);
|
|
236
|
-
--accent: oklch(0.65 0.20 25);
|
|
237
|
-
--accent-hover: oklch(0.58 0.22 25);
|
|
238
|
-
--accent-subtle: oklch(0.94 0.04 25);
|
|
239
|
-
--border: oklch(0.88 0.012 30);
|
|
240
|
-
--success: oklch(0.55 0.16 150);
|
|
241
|
-
--warning: oklch(0.66 0.16 75);
|
|
242
|
-
--error: oklch(0.52 0.22 20);
|
|
243
|
-
}
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### 7.5 Deep Teal
|
|
247
|
-
**Vibe**: Calm, medical, authoritative. Good for health tech, enterprise SaaS, data platforms, legal.
|
|
248
|
-
```css
|
|
249
|
-
:root {
|
|
250
|
-
--surface-0: oklch(0.98 0.005 195);
|
|
251
|
-
--surface-1: oklch(0.96 0.008 195);
|
|
252
|
-
--text-primary: oklch(0.16 0.025 200);
|
|
253
|
-
--text-secondary: oklch(0.40 0.02 200);
|
|
254
|
-
--accent: oklch(0.52 0.12 195);
|
|
255
|
-
--accent-hover: oklch(0.46 0.14 195);
|
|
256
|
-
--accent-subtle: oklch(0.93 0.03 195);
|
|
257
|
-
--border: oklch(0.88 0.01 195);
|
|
258
|
-
--success: oklch(0.55 0.14 155);
|
|
259
|
-
--warning: oklch(0.66 0.16 75);
|
|
260
|
-
--error: oklch(0.55 0.20 25);
|
|
261
|
-
}
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
### 7.6 Slate Blue
|
|
265
|
-
**Vibe**: Professional, systematic, dependable. Good for project management, B2B SaaS, documentation.
|
|
266
|
-
```css
|
|
267
|
-
:root {
|
|
268
|
-
--surface-0: oklch(0.98 0.005 250);
|
|
269
|
-
--surface-1: oklch(0.96 0.008 250);
|
|
270
|
-
--text-primary: oklch(0.17 0.02 250);
|
|
271
|
-
--text-secondary: oklch(0.42 0.018 250);
|
|
272
|
-
--accent: oklch(0.55 0.14 250);
|
|
273
|
-
--accent-hover: oklch(0.49 0.16 250);
|
|
274
|
-
--accent-subtle: oklch(0.93 0.03 250);
|
|
275
|
-
--border: oklch(0.88 0.01 250);
|
|
276
|
-
--success: oklch(0.55 0.16 150);
|
|
277
|
-
--warning: oklch(0.66 0.16 75);
|
|
278
|
-
--error: oklch(0.55 0.20 25);
|
|
279
|
-
}
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
### 7.7 Burgundy
|
|
283
|
-
**Vibe**: Sophisticated, editorial, rich. Good for wine/food, publishing, luxury, fashion.
|
|
284
|
-
```css
|
|
285
|
-
:root {
|
|
286
|
-
--surface-0: oklch(0.98 0.006 10);
|
|
287
|
-
--surface-1: oklch(0.96 0.01 10);
|
|
288
|
-
--text-primary: oklch(0.16 0.025 10);
|
|
289
|
-
--text-secondary: oklch(0.40 0.02 10);
|
|
290
|
-
--accent: oklch(0.42 0.16 15);
|
|
291
|
-
--accent-hover: oklch(0.36 0.18 15);
|
|
292
|
-
--accent-subtle: oklch(0.93 0.04 15);
|
|
293
|
-
--border: oklch(0.87 0.012 10);
|
|
294
|
-
--success: oklch(0.55 0.16 150);
|
|
295
|
-
--warning: oklch(0.66 0.16 75);
|
|
296
|
-
--error: oklch(0.50 0.20 25);
|
|
297
|
-
}
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
### 7.8 Sage
|
|
301
|
-
**Vibe**: Soft, organic, restorative. Good for wellness, meditation, journaling, therapy platforms.
|
|
302
|
-
```css
|
|
303
|
-
:root {
|
|
304
|
-
--surface-0: oklch(0.98 0.006 130);
|
|
305
|
-
--surface-1: oklch(0.95 0.012 130);
|
|
306
|
-
--text-primary: oklch(0.20 0.02 130);
|
|
307
|
-
--text-secondary: oklch(0.42 0.018 130);
|
|
308
|
-
--accent: oklch(0.58 0.10 130);
|
|
309
|
-
--accent-hover: oklch(0.52 0.12 130);
|
|
310
|
-
--accent-subtle: oklch(0.93 0.03 130);
|
|
311
|
-
--border: oklch(0.88 0.01 130);
|
|
312
|
-
--success: oklch(0.55 0.14 150);
|
|
313
|
-
--warning: oklch(0.66 0.15 75);
|
|
314
|
-
--error: oklch(0.55 0.18 25);
|
|
315
|
-
}
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
### 7.9 Charcoal with Orange Accent
|
|
319
|
-
**Vibe**: Bold, industrial, high-contrast. Good for dev tools, gaming, analytics, creative coding.
|
|
320
|
-
```css
|
|
321
|
-
:root {
|
|
322
|
-
--surface-0: oklch(0.97 0.003 60);
|
|
323
|
-
--surface-1: oklch(0.94 0.005 60);
|
|
324
|
-
--text-primary: oklch(0.15 0.01 60);
|
|
325
|
-
--text-secondary: oklch(0.40 0.01 60);
|
|
326
|
-
--accent: oklch(0.65 0.22 55);
|
|
327
|
-
--accent-hover: oklch(0.58 0.24 55);
|
|
328
|
-
--accent-subtle: oklch(0.94 0.04 55);
|
|
329
|
-
--border: oklch(0.86 0.008 60);
|
|
330
|
-
--success: oklch(0.55 0.16 150);
|
|
331
|
-
--warning: oklch(0.66 0.18 70);
|
|
332
|
-
--error: oklch(0.55 0.22 25);
|
|
333
|
-
}
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
### 7.10 Monochrome Black and White
|
|
337
|
-
**Vibe**: Stark, typographic, gallery-like. Good for portfolios, photography, editorial, minimal SaaS.
|
|
338
|
-
```css
|
|
339
|
-
:root {
|
|
340
|
-
--surface-0: oklch(0.99 0.000 0);
|
|
341
|
-
--surface-1: oklch(0.96 0.000 0);
|
|
342
|
-
--text-primary: oklch(0.13 0.000 0);
|
|
343
|
-
--text-secondary: oklch(0.45 0.000 0);
|
|
344
|
-
--accent: oklch(0.15 0.000 0);
|
|
345
|
-
--accent-hover: oklch(0.25 0.000 0);
|
|
346
|
-
--accent-subtle: oklch(0.93 0.000 0);
|
|
347
|
-
--border: oklch(0.85 0.000 0);
|
|
348
|
-
--success: oklch(0.50 0.14 150);
|
|
349
|
-
--warning: oklch(0.62 0.14 75);
|
|
350
|
-
--error: oklch(0.50 0.18 25);
|
|
351
|
-
}
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
For the monochrome palette, the accent is near-black. CTAs rely on fill weight (solid black buttons with white text) rather than color. Semantic colors (success, warning, error) break the monochrome intentionally so they remain functional.
|
|
149
|
+
All 10 palettes follow this same token structure. To use a different palette, change the hue and chroma values while keeping the lightness relationships consistent. For monochrome, accent is near-black; CTAs use fill weight (solid black button, white text).
|
|
355
150
|
|
|
356
151
|
---
|
|
357
152
|
|
|
358
153
|
## 8. Wide Gamut Colors (P3)
|
|
359
154
|
|
|
360
|
-
|
|
361
|
-
Display P3 is a color space that covers roughly 25% more visible colors than sRGB. Modern Apple devices, most OLED screens, and recent monitors support it. Colors outside the sRGB gamut appear more vivid without being oversaturated.
|
|
362
|
-
|
|
363
|
-
### CSS Syntax
|
|
364
|
-
```css
|
|
365
|
-
/* Display P3 via color() function */
|
|
366
|
-
--accent: color(display-p3 0.92 0.34 0.15); /* vivid orange impossible in sRGB */
|
|
367
|
-
--success: color(display-p3 0.18 0.75 0.35); /* richer green */
|
|
368
|
-
--highlight: color(display-p3 1 0.85 0); /* pure P3 yellow */
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
### Feature Detection
|
|
372
|
-
```css
|
|
373
|
-
@media (color-gamut: p3) {
|
|
374
|
-
:root {
|
|
375
|
-
--accent: color(display-p3 0.92 0.34 0.15);
|
|
376
|
-
--success: color(display-p3 0.18 0.75 0.35);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
```
|
|
155
|
+
Display P3 covers ~25% more visible colors than sRGB. Supported on modern Apple devices and most OLED screens.
|
|
380
156
|
|
|
381
|
-
### Progressive Enhancement
|
|
382
|
-
|
|
157
|
+
### Progressive Enhancement
|
|
158
|
+
OKLCH values automatically map to the widest gamut available. Pushing chroma beyond ~0.15-0.20 often enters P3 territory. Override for wide gamut:
|
|
383
159
|
|
|
384
160
|
```css
|
|
385
|
-
:root {
|
|
386
|
-
/* sRGB fallback (works everywhere) */
|
|
387
|
-
--accent: oklch(0.65 0.22 35);
|
|
388
|
-
--success: oklch(0.55 0.18 150);
|
|
389
|
-
--highlight: oklch(0.82 0.18 90);
|
|
390
|
-
}
|
|
391
|
-
|
|
392
161
|
@media (color-gamut: p3) {
|
|
393
|
-
:root {
|
|
394
|
-
/* P3 override (wider gamut screens) */
|
|
395
|
-
--accent: oklch(0.65 0.27 35); /* push chroma beyond sRGB limit */
|
|
396
|
-
--success: oklch(0.55 0.22 150);
|
|
397
|
-
--highlight: oklch(0.82 0.22 90);
|
|
398
|
-
}
|
|
162
|
+
:root { --accent: oklch(0.65 0.27 35); /* higher chroma for P3 */ }
|
|
399
163
|
}
|
|
400
164
|
```
|
|
401
165
|
|
|
402
|
-
Note: OKLCH values automatically map to the widest gamut the browser and display support. Increasing chroma beyond ~0.15-0.20 (depending on hue) often pushes into P3 territory. This makes OKLCH the ideal space for progressive enhancement because you write one value and the browser resolves it to the best available gamut.
|
|
403
|
-
|
|
404
166
|
### When to Use P3
|
|
405
|
-
- Hero gradients
|
|
406
|
-
- Success/error states that need to
|
|
407
|
-
- Brand colors
|
|
408
|
-
- Image overlays and tinted surfaces that blend with wide-gamut photography
|
|
167
|
+
- Hero gradients, accent splashes where vibrancy matters
|
|
168
|
+
- Success/error states that need to pop
|
|
169
|
+
- Brand colors designed in P3
|
|
409
170
|
|
|
410
171
|
### When NOT to Use P3
|
|
411
|
-
- Body text
|
|
412
|
-
- Border and surface tokens (subtle differences, not worth the complexity)
|
|
413
|
-
- Any context where the sRGB version already looks correct
|
|
172
|
+
- Body text, borders, surfaces (negligible perceptual difference)
|
|
414
173
|
|
|
415
174
|
---
|
|
416
175
|
|
|
417
176
|
## 9. `light-dark()` CSS Function
|
|
418
177
|
|
|
419
|
-
|
|
178
|
+
Returns one of two values depending on `color-scheme`. Eliminates duplicate variable declarations for simple color flips.
|
|
420
179
|
|
|
421
180
|
```css
|
|
422
|
-
:root {
|
|
423
|
-
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
.surface {
|
|
427
|
-
background: light-dark(oklch(0.97 0.005 260), oklch(0.17 0.012 260));
|
|
428
|
-
}
|
|
429
|
-
.text {
|
|
430
|
-
color: light-dark(oklch(0.20 0.015 260), oklch(0.93 0.01 260));
|
|
431
|
-
}
|
|
432
|
-
.border {
|
|
433
|
-
border-color: light-dark(oklch(0.88 0.01 260), oklch(0.25 0.01 260));
|
|
434
|
-
}
|
|
181
|
+
:root { color-scheme: light dark; }
|
|
182
|
+
.surface { background: light-dark(oklch(0.97 0.005 260), oklch(0.17 0.012 260)); }
|
|
435
183
|
```
|
|
436
184
|
|
|
437
|
-
Use
|
|
438
|
-
|
|
439
|
-
Browser support: baseline since March 2024 (Chrome 123, Firefox 120, Safari 17.5).
|
|
185
|
+
Use for simple flips (surfaces, text, borders). For complex theme differences, use `[data-theme="dark"]` selectors. Baseline since March 2024.
|
|
440
186
|
|
|
441
187
|
---
|
|
442
188
|
|
|
443
189
|
## 10. `color-mix()` for Runtime Blending
|
|
444
190
|
|
|
445
|
-
|
|
191
|
+
Blend colors at runtime without intermediate tokens. Always use `in oklch` for perceptually uniform results.
|
|
446
192
|
|
|
447
193
|
```css
|
|
448
|
-
|
|
449
|
-
.
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
/* Subtle tint: mix accent into white */
|
|
454
|
-
.surface-tinted {
|
|
455
|
-
background: color-mix(in oklch, var(--accent), white 92%);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
/* Disabled: reduce opacity feel by mixing with the surface */
|
|
459
|
-
.btn:disabled {
|
|
460
|
-
background: color-mix(in oklch, var(--accent), var(--surface-0) 60%);
|
|
461
|
-
}
|
|
194
|
+
.btn:hover { background: color-mix(in oklch, var(--accent), black 15%); }
|
|
195
|
+
.surface-tinted { background: color-mix(in oklch, var(--accent), white 92%); }
|
|
196
|
+
.btn:disabled { background: color-mix(in oklch, var(--accent), var(--surface-0) 60%); }
|
|
462
197
|
```
|
|
463
198
|
|
|
464
|
-
Always specify `in oklch` for perceptually uniform blending. Mixing `in srgb` produces muddier results, especially across hues.
|
|
465
|
-
|
|
466
199
|
---
|
|
467
200
|
|
|
468
201
|
## 11. Common Mistakes
|
|
469
202
|
|
|
470
|
-
- Using pure black (#000) for text (use tinted near-black
|
|
471
|
-
-
|
|
472
|
-
- Applying opacity
|
|
473
|
-
-
|
|
203
|
+
- Using pure black (#000) for text (use tinted near-black)
|
|
204
|
+
- Gray text on colored backgrounds (low contrast)
|
|
205
|
+
- Applying opacity for lighter colors (use chroma reduction instead)
|
|
206
|
+
- Too many accent colors (one primary, one secondary max)
|
|
474
207
|
- Forgetting to test dark mode after building light mode
|
|
475
|
-
-
|
|
476
|
-
-
|
|
477
|
-
- Using `color-mix(in srgb
|
|
208
|
+
- Full saturation on large surfaces (eye strain; reserve full chroma for small accents)
|
|
209
|
+
- No hover/focus states with visible color change
|
|
210
|
+
- Using `color-mix(in srgb)` instead of `color-mix(in oklch)` (muddier results)
|