@trishchuk/coolors-mcp 1.0.0 → 1.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.
Files changed (140) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +20 -8
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +22 -8
  3. package/.github/pull_request_template.md +33 -8
  4. package/.github/workflows/ci.yml +107 -104
  5. package/.github/workflows/deploy-docs.yml +14 -11
  6. package/.github/workflows/release.yml +25 -23
  7. package/README.md +149 -15
  8. package/dist/bin/server.js +997 -256
  9. package/dist/bin/server.js.map +1 -1
  10. package/dist/{chunk-P3ARRKLS.js → chunk-HOMDMKUY.js} +3 -1
  11. package/dist/{chunk-P3ARRKLS.js.map → chunk-HOMDMKUY.js.map} +1 -1
  12. package/dist/{chunk-IQ7NN26V.js → chunk-LHW2ZTOU.js} +14 -2
  13. package/dist/chunk-LHW2ZTOU.js.map +1 -0
  14. package/dist/color/index.js +1 -1
  15. package/dist/coolors-mcp.d.ts +4 -4
  16. package/dist/coolors-mcp.js +1 -1
  17. package/docs/.vitepress/components/ClientGrid.vue +9 -3
  18. package/docs/.vitepress/components/CodeBlock.vue +51 -44
  19. package/docs/.vitepress/components/ConfigModal.vue +151 -67
  20. package/docs/.vitepress/components/DiagramModal.vue +186 -154
  21. package/docs/.vitepress/components/TroubleshootingModal.vue +101 -96
  22. package/docs/.vitepress/config.js +171 -141
  23. package/docs/.vitepress/theme/FundingLayout.vue +65 -54
  24. package/docs/.vitepress/theme/Layout.vue +21 -21
  25. package/docs/.vitepress/theme/components/AdBanner.vue +73 -52
  26. package/docs/.vitepress/theme/components/AdPlaceholder.vue +3 -3
  27. package/docs/.vitepress/theme/components/FundingEffects.vue +77 -53
  28. package/docs/.vitepress/theme/components/FundingHero.vue +78 -63
  29. package/docs/.vitepress/theme/components/SupportSection.vue +106 -89
  30. package/docs/.vitepress/theme/custom-app.css +19 -12
  31. package/docs/.vitepress/theme/custom.css +33 -25
  32. package/docs/.vitepress/theme/index.js +19 -16
  33. package/docs/concepts/accessibility.md +59 -47
  34. package/docs/concepts/color-spaces.md +28 -6
  35. package/docs/concepts/distance-metrics.md +45 -30
  36. package/docs/concepts/hct.md +30 -27
  37. package/docs/concepts/image-analysis.md +52 -21
  38. package/docs/concepts/material-design.md +43 -17
  39. package/docs/concepts/theme-matching.md +64 -40
  40. package/docs/examples/basic-colors.md +92 -108
  41. package/docs/examples/creating-themes.md +104 -108
  42. package/docs/examples/css-refactoring.md +33 -29
  43. package/docs/examples/image-extraction.md +145 -138
  44. package/docs/getting-started.md +45 -34
  45. package/docs/index.md +5 -1
  46. package/docs/installation.md +15 -1
  47. package/docs/tools/accessibility.md +74 -68
  48. package/docs/tools/image-extraction.md +62 -54
  49. package/docs/tools/theme-matching.md +45 -42
  50. package/eslint.config.ts +13 -0
  51. package/jsr.json +1 -1
  52. package/package.json +17 -13
  53. package/src/bin/server.ts +13 -1
  54. package/src/color/__tests__/extract-colors.test.ts +20 -30
  55. package/src/color/apca.ts +105 -0
  56. package/src/color/color-blindness.ts +109 -0
  57. package/src/coolors-mcp.ts +1 -1
  58. package/src/session.ts +10 -2
  59. package/src/theme/matcher.ts +1 -1
  60. package/src/theme/refactor.ts +1 -1
  61. package/src/theme/types.ts +3 -0
  62. package/src/tools/__tests__/cohesion.test.ts +97 -0
  63. package/src/tools/__tests__/color-blindness.test.ts +45 -0
  64. package/src/tools/__tests__/color-conversion.test.ts +38 -0
  65. package/src/tools/__tests__/contrast-checker.test.ts +56 -0
  66. package/src/tools/__tests__/palette-export.test.ts +54 -0
  67. package/src/tools/adjust-color.tool.ts +80 -0
  68. package/src/tools/cohesion.tools.ts +380 -0
  69. package/src/tools/color-blindness.tool.ts +168 -0
  70. package/src/tools/color-conversion.tool.ts +1 -1
  71. package/src/tools/contrast-checker.tool.ts +53 -14
  72. package/src/tools/dislike-analyzer.tool.ts +41 -54
  73. package/src/tools/image-extraction.tools.ts +62 -115
  74. package/src/tools/index.ts +15 -2
  75. package/src/tools/palette-export.tool.ts +174 -0
  76. package/src/tools/palette-with-locks.tool.ts +8 -6
  77. package/src/types.ts +2 -3
  78. package/tsconfig.json +12 -2
  79. package/vitest.config.js +1 -3
  80. package/.claude/settings.local.json +0 -39
  81. package/.env +0 -2
  82. package/.mcp.json +0 -12
  83. package/CLAUDE.md +0 -201
  84. package/DOCUMENTATION.md +0 -274
  85. package/GEMINI.md +0 -54
  86. package/demo/content_based_color.png +0 -0
  87. package/demo/music-player.html +0 -621
  88. package/demo/podcast-player.html +0 -903
  89. package/dist/chunk-IQ7NN26V.js.map +0 -1
  90. package/docs/.vitepress/cache/deps/@braintree_sanitize-url.js +0 -93
  91. package/docs/.vitepress/cache/deps/@braintree_sanitize-url.js.map +0 -7
  92. package/docs/.vitepress/cache/deps/_metadata.json +0 -127
  93. package/docs/.vitepress/cache/deps/chunk-BUSYA2B4.js +0 -9
  94. package/docs/.vitepress/cache/deps/chunk-BUSYA2B4.js.map +0 -7
  95. package/docs/.vitepress/cache/deps/chunk-JD3CXNQ6.js +0 -12683
  96. package/docs/.vitepress/cache/deps/chunk-JD3CXNQ6.js.map +0 -7
  97. package/docs/.vitepress/cache/deps/chunk-SYPOPCWC.js +0 -9719
  98. package/docs/.vitepress/cache/deps/chunk-SYPOPCWC.js.map +0 -7
  99. package/docs/.vitepress/cache/deps/cytoscape-cose-bilkent.js +0 -4710
  100. package/docs/.vitepress/cache/deps/cytoscape-cose-bilkent.js.map +0 -7
  101. package/docs/.vitepress/cache/deps/cytoscape.js +0 -30278
  102. package/docs/.vitepress/cache/deps/cytoscape.js.map +0 -7
  103. package/docs/.vitepress/cache/deps/dayjs.js +0 -285
  104. package/docs/.vitepress/cache/deps/dayjs.js.map +0 -7
  105. package/docs/.vitepress/cache/deps/debug.js +0 -468
  106. package/docs/.vitepress/cache/deps/debug.js.map +0 -7
  107. package/docs/.vitepress/cache/deps/package.json +0 -3
  108. package/docs/.vitepress/cache/deps/prismjs.js +0 -1466
  109. package/docs/.vitepress/cache/deps/prismjs.js.map +0 -7
  110. package/docs/.vitepress/cache/deps/prismjs_components_prism-bash.js +0 -228
  111. package/docs/.vitepress/cache/deps/prismjs_components_prism-bash.js.map +0 -7
  112. package/docs/.vitepress/cache/deps/prismjs_components_prism-javascript.js +0 -142
  113. package/docs/.vitepress/cache/deps/prismjs_components_prism-javascript.js.map +0 -7
  114. package/docs/.vitepress/cache/deps/prismjs_components_prism-json.js +0 -27
  115. package/docs/.vitepress/cache/deps/prismjs_components_prism-json.js.map +0 -7
  116. package/docs/.vitepress/cache/deps/prismjs_components_prism-python.js +0 -65
  117. package/docs/.vitepress/cache/deps/prismjs_components_prism-python.js.map +0 -7
  118. package/docs/.vitepress/cache/deps/prismjs_components_prism-typescript.js +0 -53
  119. package/docs/.vitepress/cache/deps/prismjs_components_prism-typescript.js.map +0 -7
  120. package/docs/.vitepress/cache/deps/prismjs_components_prism-yaml.js +0 -73
  121. package/docs/.vitepress/cache/deps/prismjs_components_prism-yaml.js.map +0 -7
  122. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +0 -4507
  123. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +0 -7
  124. package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +0 -584
  125. package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +0 -7
  126. package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js +0 -1146
  127. package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map +0 -7
  128. package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js +0 -1667
  129. package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map +0 -7
  130. package/docs/.vitepress/cache/deps/vitepress___minisearch.js +0 -1814
  131. package/docs/.vitepress/cache/deps/vitepress___minisearch.js.map +0 -7
  132. package/docs/.vitepress/cache/deps/vue.js +0 -344
  133. package/docs/.vitepress/cache/deps/vue.js.map +0 -7
  134. package/examples/theme-matching.md +0 -113
  135. package/mcp-config.json +0 -8
  136. package/note.md +0 -35
  137. package/research_results.md +0 -53
  138. package/src/tools/colors.ts +0 -31
  139. package/src/tools/registry.ts +0 -142
  140. package/src/tools/simple-tools.ts +0 -37
@@ -37,7 +37,7 @@ Intuitive color model for human understanding.
37
37
  }
38
38
  ```
39
39
 
40
- ## LAB (CIE L*a*b*)
40
+ ## LAB (CIE L*a*b\*)
41
41
 
42
42
  Perceptually uniform color space based on human vision.
43
43
 
@@ -104,33 +104,38 @@ HSL ↔ RGB ↔ HEX
104
104
  const hex = "#6366F1";
105
105
 
106
106
  // To RGB
107
- "rgb(99, 102, 241)"
107
+ ("rgb(99, 102, 241)");
108
108
 
109
109
  // To HSL
110
- "hsl(239, 84%, 67%)"
110
+ ("hsl(239, 84%, 67%)");
111
111
 
112
112
  // To LAB
113
- "lab(47.9, 35.2, -65.7)"
113
+ ("lab(47.9, 35.2, -65.7)");
114
114
 
115
115
  // To HCT
116
- "hct(265.8, 87.2, 47.9)"
116
+ ("hct(265.8, 87.2, 47.9)");
117
117
  ```
118
118
 
119
119
  ## Choosing the Right Color Space
120
120
 
121
121
  ### For Color Picking
122
+
122
123
  Use **HSL** - intuitive for users to understand and manipulate.
123
124
 
124
125
  ### For Color Matching
126
+
125
127
  Use **LAB** or **HCT** - perceptually uniform for accurate comparisons.
126
128
 
127
129
  ### For UI Themes
130
+
128
131
  Use **HCT** - designed for interface design with predictable contrast.
129
132
 
130
133
  ### For Web/Digital
134
+
131
135
  Use **RGB/Hex** - native format for browsers and displays.
132
136
 
133
137
  ### For Print
138
+
134
139
  Use **LAB** - device-independent and accurate for print reproduction.
135
140
 
136
141
  ## Perceptual Distance Metrics
@@ -138,42 +143,53 @@ Use **LAB** - device-independent and accurate for print reproduction.
138
143
  Different color spaces affect distance calculations:
139
144
 
140
145
  ### RGB Distance (Euclidean)
146
+
141
147
  Simple but perceptually inaccurate:
148
+
142
149
  ```
143
150
  distance = √((r₂-r₁)² + (g₂-g₁)² + (b₂-b₁)²)
144
151
  ```
145
152
 
146
153
  ### Delta E (LAB-based)
154
+
147
155
  Industry standard for color difference:
156
+
148
157
  - **Delta E 76**: Original formula
149
158
  - **Delta E 94**: Improved for textiles
150
159
  - **Delta E 2000**: Most accurate, accounts for human perception
151
160
 
152
161
  ### HCT Distance
162
+
153
163
  Weighted for UI applications:
164
+
154
165
  ```
155
166
  distance = √((h₂-h₁)² + (c₂-c₁)² + 2×(t₂-t₁)²)
156
167
  ```
168
+
157
169
  Tone is weighted 2x because lightness differences are more noticeable in UI.
158
170
 
159
171
  ## Color Space Limitations
160
172
 
161
173
  ### RGB Limitations
174
+
162
175
  - Not perceptually uniform
163
176
  - Difficult for humans to predict color changes
164
177
  - Poor for color difference calculations
165
178
 
166
179
  ### HSL Limitations
180
+
167
181
  - Saturation and lightness are not perceptually uniform
168
182
  - Colors with same L value may appear different brightness
169
183
  - Not suitable for accessibility calculations
170
184
 
171
185
  ### LAB Limitations
186
+
172
187
  - Can represent impossible colors
173
188
  - Less intuitive for designers
174
189
  - Blue region has known inaccuracies
175
190
 
176
191
  ### HCT Advantages
192
+
177
193
  - Specifically designed for UI/UX
178
194
  - Predictable contrast ratios
179
195
  - Perceptually uniform
@@ -182,7 +198,9 @@ Tone is weighted 2x because lightness differences are more noticeable in UI.
182
198
  ## Practical Applications
183
199
 
184
200
  ### Theme Generation
201
+
185
202
  HCT enables predictable theme generation:
203
+
186
204
  ```javascript
187
205
  // Generate accessible color variations
188
206
  const baseHCT = { h: 265, c: 50, t: 50 };
@@ -195,13 +213,17 @@ const dark = { ...baseHCT, t: 20 };
195
213
  ```
196
214
 
197
215
  ### Color Harmonies
216
+
198
217
  Different spaces excel at different harmonies:
218
+
199
219
  - **HSL**: Best for analogous colors (rotate hue)
200
220
  - **HCT**: Best for tonal variations (adjust tone)
201
221
  - **LAB**: Best for perceptual interpolation
202
222
 
203
223
  ### Gradient Generation
224
+
204
225
  Color space affects gradient smoothness:
226
+
205
227
  - **RGB**: Can produce muddy colors in middle
206
228
  - **HSL**: Can produce unnatural brightness shifts
207
229
  - **LAB/HCT**: Smooth perceptual transitions
@@ -219,4 +241,4 @@ Color space affects gradient smoothness:
219
241
  - [HCT Color System](./hct.md) - Deep dive into HCT
220
242
  - [Material Design](./material-design.md) - Using HCT in practice
221
243
  - [Accessibility](./accessibility.md) - Color contrast and WCAG
222
- - [Theme Matching](./theme-matching.md) - Algorithm details
244
+ - [Theme Matching](./theme-matching.md) - Algorithm details
@@ -17,16 +17,19 @@ distance = √((r₂-r₁)² + (g₂-g₁)² + (b₂-b₁)²)
17
17
  ```
18
18
 
19
19
  **Pros:**
20
+
20
21
  - Fast to compute
21
22
  - Simple to understand
22
23
  - Good for rough comparisons
23
24
 
24
25
  **Cons:**
26
+
25
27
  - Not perceptually uniform
26
28
  - Poor for subtle color differences
27
29
  - Doesn't match human vision
28
30
 
29
31
  **When to use:**
32
+
30
33
  - Quick filtering
31
34
  - Performance-critical applications
32
35
  - When accuracy isn't crucial
@@ -40,11 +43,13 @@ The original perceptual color difference formula using LAB color space:
40
43
  ```
41
44
 
42
45
  **Characteristics:**
46
+
43
47
  - First attempt at perceptual uniformity
44
48
  - Simple LAB distance calculation
45
49
  - Threshold: ΔE < 2.3 is barely perceptible
46
50
 
47
51
  **When to use:**
52
+
48
53
  - Basic perceptual matching
49
54
  - Legacy systems
50
55
  - When computation speed matters
@@ -58,11 +63,13 @@ Improved formula with weighting factors for different color attributes:
58
63
  ```
59
64
 
60
65
  **Improvements:**
66
+
61
67
  - Separate weights for lightness, chroma, hue
62
68
  - Better for textiles and graphics
63
69
  - More accurate than CIE76
64
70
 
65
71
  **When to use:**
72
+
66
73
  - Textile industry
67
74
  - Graphic arts
68
75
  - Better accuracy than CIE76
@@ -77,12 +84,14 @@ The most accurate standard for color difference, addressing perceptual non-unifo
77
84
  ```
78
85
 
79
86
  **Features:**
87
+
80
88
  - Rotation term for blue region
81
89
  - Lightness, chroma, hue corrections
82
90
  - Most accurate for human perception
83
91
  - Industry standard
84
92
 
85
93
  **When to use:**
94
+
86
95
  - Color matching applications
87
96
  - Quality control
88
97
  - When accuracy is paramount
@@ -98,11 +107,13 @@ distance = √((Δh × wₕ)² + (Δc × wᴄ)² + (Δt × wᴛ)²)
98
107
  ```
99
108
 
100
109
  **Advantages:**
110
+
101
111
  - Optimized for UI colors
102
112
  - Tone component predicts contrast
103
113
  - Better for Material Design
104
114
 
105
115
  **When to use:**
116
+
106
117
  - UI/UX design
107
118
  - Material Design systems
108
119
  - Theme matching
@@ -112,14 +123,14 @@ distance = √((Δh × wₕ)² + (Δc × wᴄ)² + (Δt × wᴛ)²)
112
123
 
113
124
  Different ΔE values represent different levels of color difference:
114
125
 
115
- | ΔE Value | Perception | Use Case |
116
- |----------|------------|----------|
117
- | 0-1 | Not perceptible | Exact matches |
118
- | 1-2 | Barely perceptible | Very close matches |
119
- | 2-3.5 | Perceptible by experts | Close matches |
120
- | 3.5-5 | Noticeable difference | Acceptable matches |
121
- | 5-10 | Clear difference | Related colors |
122
- | >10 | Different colors | Distinct colors |
126
+ | ΔE Value | Perception | Use Case |
127
+ | -------- | ---------------------- | ------------------ |
128
+ | 0-1 | Not perceptible | Exact matches |
129
+ | 1-2 | Barely perceptible | Very close matches |
130
+ | 2-3.5 | Perceptible by experts | Close matches |
131
+ | 3.5-5 | Noticeable difference | Acceptable matches |
132
+ | 5-10 | Clear difference | Related colors |
133
+ | >10 | Different colors | Distinct colors |
123
134
 
124
135
  ## Metric Comparison
125
136
 
@@ -211,14 +222,14 @@ Is performance critical?
211
222
 
212
223
  ### Use Case Guidelines
213
224
 
214
- | Use Case | Recommended Metric | Reason |
215
- |----------|-------------------|---------|
216
- | CSS color matching | Delta E 2000 | Accuracy |
217
- | Real-time filtering | Euclidean | Speed |
218
- | Theme generation | HCT | UI optimization |
219
- | Print color matching | Delta E 2000 | Industry standard |
220
- | Palette creation | HCT | Perceptual uniformity |
221
- | Image quantization | Delta E 76 | Balance |
225
+ | Use Case | Recommended Metric | Reason |
226
+ | -------------------- | ------------------ | --------------------- |
227
+ | CSS color matching | Delta E 2000 | Accuracy |
228
+ | Real-time filtering | Euclidean | Speed |
229
+ | Theme generation | HCT | UI optimization |
230
+ | Print color matching | Delta E 2000 | Industry standard |
231
+ | Palette creation | HCT | Perceptual uniformity |
232
+ | Image quantization | Delta E 76 | Balance |
222
233
 
223
234
  ## Implementation Examples
224
235
 
@@ -226,14 +237,14 @@ Is performance critical?
226
237
 
227
238
  ```javascript
228
239
  function findSimilarColors(targetColor, palette, threshold = 5) {
229
- return palette.filter(color => {
230
- const distance = colorDistance(targetColor, color, 'deltaE2000');
240
+ return palette.filter((color) => {
241
+ const distance = colorDistance(targetColor, color, "deltaE2000");
231
242
  return distance < threshold;
232
243
  });
233
244
  }
234
245
 
235
246
  // Usage
236
- const similar = findSimilarColors('#6366f1', myPalette, 10);
247
+ const similar = findSimilarColors("#6366f1", myPalette, 10);
237
248
  // Returns colors within ΔE 10 of target
238
249
  ```
239
250
 
@@ -243,11 +254,11 @@ const similar = findSimilarColors('#6366f1', myPalette, 10);
243
254
  function clusterColors(colors, maxDistance = 5) {
244
255
  const clusters = [];
245
256
 
246
- colors.forEach(color => {
257
+ colors.forEach((color) => {
247
258
  let added = false;
248
259
 
249
260
  for (const cluster of clusters) {
250
- const distance = colorDistance(color, cluster.center, 'deltaE2000');
261
+ const distance = colorDistance(color, cluster.center, "deltaE2000");
251
262
  if (distance < maxDistance) {
252
263
  cluster.colors.push(color);
253
264
  added = true;
@@ -258,7 +269,7 @@ function clusterColors(colors, maxDistance = 5) {
258
269
  if (!added) {
259
270
  clusters.push({
260
271
  center: color,
261
- colors: [color]
272
+ colors: [color],
262
273
  });
263
274
  }
264
275
  });
@@ -281,7 +292,7 @@ function interpolatePerceptual(color1, color2, steps) {
281
292
  const lab = {
282
293
  l: lab1.l + (lab2.l - lab1.l) * t,
283
294
  a: lab1.a + (lab2.a - lab1.a) * t,
284
- b: lab1.b + (lab2.b - lab1.b) * t
295
+ b: lab1.b + (lab2.b - lab1.b) * t,
285
296
  };
286
297
  colors.push(labToRgb(lab));
287
298
  }
@@ -313,16 +324,16 @@ Distance perception changes based on viewing conditions:
313
324
 
314
325
  ```javascript
315
326
  function contextualDistance(color1, color2, context) {
316
- switch(context) {
317
- case 'small-text':
327
+ switch (context) {
328
+ case "small-text":
318
329
  // Need larger differences for readability
319
330
  return colorDistance(color1, color2) * 1.5;
320
331
 
321
- case 'large-area':
332
+ case "large-area":
322
333
  // Subtle differences more noticeable
323
334
  return colorDistance(color1, color2) * 0.8;
324
335
 
325
- case 'dark-mode':
336
+ case "dark-mode":
326
337
  // Adjust for dark backgrounds
327
338
  return adjustedDarkModeDistance(color1, color2);
328
339
 
@@ -343,8 +354,8 @@ function multiFactorDistance(color1, color2) {
343
354
  const semantic = getSemanticDistance(color1, color2);
344
355
 
345
356
  return {
346
- overall: (perceptual * 0.6 + contrast * 0.3 + semantic * 0.1),
347
- components: { perceptual, contrast, semantic }
357
+ overall: perceptual * 0.6 + contrast * 0.3 + semantic * 0.1,
358
+ components: { perceptual, contrast, semantic },
348
359
  };
349
360
  }
350
361
  ```
@@ -352,18 +363,22 @@ function multiFactorDistance(color1, color2) {
352
363
  ## Common Pitfalls
353
364
 
354
365
  ### RGB Distance Misuse
366
+
355
367
  ❌ Don't use RGB distance for perceptual matching
356
368
  ✅ Use Delta E or HCT distance instead
357
369
 
358
370
  ### Ignoring Context
371
+
359
372
  ❌ Don't use the same threshold for all use cases
360
373
  ✅ Adjust thresholds based on application
361
374
 
362
375
  ### Over-Engineering
376
+
363
377
  ❌ Don't always use the most complex metric
364
378
  ✅ Choose based on actual requirements
365
379
 
366
380
  ### Wrong Color Space
381
+
367
382
  ❌ Don't interpolate in RGB for gradients
368
383
  ✅ Use LAB or HCT for smooth transitions
369
384
 
@@ -381,4 +396,4 @@ function multiFactorDistance(color1, color2) {
381
396
  - [Color Spaces](./color-spaces.md) - Understanding different color models
382
397
  - [HCT System](./hct.md) - Google's perceptual color space
383
398
  - [Theme Matching](./theme-matching.md) - Using distance for matching
384
- - [Accessibility](./accessibility.md) - Contrast and perception
399
+ - [Accessibility](./accessibility.md) - Contrast and perception
@@ -50,7 +50,7 @@ Tone Difference | Approximate Contrast Ratio
50
50
  const primary = { h: 265, c: 50, t: 50 };
51
51
 
52
52
  // Guaranteed accessible combinations
53
- const onPrimary = { h: 265, c: 50, t: 100 }; // t: 50 → 100 = 50 diff = 4.5:1
53
+ const onPrimary = { h: 265, c: 50, t: 100 }; // t: 50 → 100 = 50 diff = 4.5:1
54
54
  const primaryContainer = { h: 265, c: 25, t: 90 }; // Lower chroma, high tone
55
55
  const onPrimaryContainer = { h: 265, c: 50, t: 10 }; // t: 90 → 10 = 80 diff = 7:1+
56
56
  ```
@@ -62,11 +62,13 @@ HCT is the foundation of Material Design 3's color system:
62
62
  ### Tonal Palettes
63
63
 
64
64
  Material Design uses 13 standard tones:
65
+
65
66
  ```
66
67
  [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 95, 99, 100]
67
68
  ```
68
69
 
69
70
  Each tone has specific use cases:
71
+
70
72
  - **0-10**: On-colors for light surfaces
71
73
  - **20-40**: Accent and emphasis colors
72
74
  - **50**: Medium, often primary color
@@ -79,16 +81,16 @@ HCT enables semantic color roles with guaranteed contrast:
79
81
 
80
82
  ```javascript
81
83
  // Primary color family
82
- primary: tone(40) // Main brand color
83
- onPrimary: tone(100) // Text on primary
84
- primaryContainer: tone(90) // Light container
85
- onPrimaryContainer: tone(10) // Text on container
84
+ primary: tone(40); // Main brand color
85
+ onPrimary: tone(100); // Text on primary
86
+ primaryContainer: tone(90); // Light container
87
+ onPrimaryContainer: tone(10); // Text on container
86
88
 
87
89
  // Surface colors
88
- surface: tone(99) // Main background
89
- onSurface: tone(10) // Text on surface
90
- surfaceVariant: tone(95) // Secondary background
91
- onSurfaceVariant: tone(30) // Secondary text
90
+ surface: tone(99); // Main background
91
+ onSurface: tone(10); // Text on surface
92
+ surfaceVariant: tone(95); // Secondary background
93
+ onSurfaceVariant: tone(30); // Secondary text
92
94
  ```
93
95
 
94
96
  ## Chroma Behavior
@@ -106,6 +108,7 @@ Chroma in HCT represents color intensity, but unlike saturation in HSL, it maint
106
108
  ### Chroma and Tone Interaction
107
109
 
108
110
  Maximum achievable chroma varies by tone:
111
+
109
112
  ```
110
113
  Tone 0-10: Low max chroma (dark colors can't be very colorful)
111
114
  Tone 40-60: Highest max chroma (mid-tones most colorful)
@@ -128,7 +131,7 @@ function generateTheme(sourceColor) {
128
131
  tertiary: { h: hct.h + 120, c: hct.c * 0.7, t: 40 },
129
132
  error: { h: 25, c: 84, t: 40 },
130
133
  neutral: { h: hct.h, c: 4, t: 50 },
131
- neutralVariant: { h: hct.h, c: 8, t: 50 }
134
+ neutralVariant: { h: hct.h, c: 8, t: 50 },
132
135
  };
133
136
  }
134
137
  ```
@@ -139,8 +142,7 @@ Create accessible color variations:
139
142
 
140
143
  ```javascript
141
144
  function createAccessiblePair(baseHct, contrastRatio = 4.5) {
142
- const toneDiff = contrastRatio >= 7 ? 70 :
143
- contrastRatio >= 4.5 ? 50 : 40;
145
+ const toneDiff = contrastRatio >= 7 ? 70 : contrastRatio >= 4.5 ? 50 : 40;
144
146
 
145
147
  const lighter = { ...baseHct, t: Math.min(100, baseHct.t + toneDiff) };
146
148
  const darker = { ...baseHct, t: Math.max(0, baseHct.t - toneDiff) };
@@ -172,21 +174,21 @@ function harmonize(color1Hct, color2Hct) {
172
174
 
173
175
  ### HCT vs LAB
174
176
 
175
- | Aspect | HCT | LAB |
176
- |--------|-----|-----|
177
- | Perceptual Uniformity | ✅ Optimized for UI | ✅ General purpose |
178
- | Contrast Prediction | ✅ Direct tone mapping | ❌ Requires calculation |
179
- | UI Optimization | ✅ Designed for screens | ❌ Designed for all media |
180
- | Impossible Colors | ❌ None | ✅ Can represent |
177
+ | Aspect | HCT | LAB |
178
+ | --------------------- | ----------------------- | ------------------------- |
179
+ | Perceptual Uniformity | ✅ Optimized for UI | ✅ General purpose |
180
+ | Contrast Prediction | ✅ Direct tone mapping | ❌ Requires calculation |
181
+ | UI Optimization | ✅ Designed for screens | ❌ Designed for all media |
182
+ | Impossible Colors | ❌ None | ✅ Can represent |
181
183
 
182
184
  ### HCT vs HSL
183
185
 
184
- | Aspect | HCT | HSL |
185
- |--------|-----|-----|
186
- | Perceptual Uniformity | ✅ Yes | ❌ No |
187
- | Lightness Accuracy | ✅ Perceptual | ❌ Mathematical |
188
- | Contrast Prediction | ✅ Built-in | ❌ Requires calculation |
189
- | Designer Familiarity | 🔶 Learning curve | ✅ Well known |
186
+ | Aspect | HCT | HSL |
187
+ | --------------------- | ----------------- | ----------------------- |
188
+ | Perceptual Uniformity | ✅ Yes | ❌ No |
189
+ | Lightness Accuracy | ✅ Perceptual | ❌ Mathematical |
190
+ | Contrast Prediction | ✅ Built-in | ❌ Requires calculation |
191
+ | Designer Familiarity | 🔶 Learning curve | ✅ Well known |
190
192
 
191
193
  ## Advanced Concepts
192
194
 
@@ -197,6 +199,7 @@ HCT is built on the CAM16 color appearance model, which models how humans percei
197
199
  ### Viewing Conditions
198
200
 
199
201
  HCT assumes standard viewing conditions:
202
+
200
203
  - Average surround
201
204
  - Adapting luminance of 200 cd/m²
202
205
  - 20% background luminance
@@ -238,9 +241,9 @@ const darkSurface = { h: 265, c: 0, t: 10 };
238
241
 
239
242
  ```javascript
240
243
  // Standard error colors in HCT
241
- const error = { h: 25, c: 84, t: 40 }; // Red-orange, high chroma
244
+ const error = { h: 25, c: 84, t: 40 }; // Red-orange, high chroma
242
245
  const errorContainer = { h: 25, c: 30, t: 90 }; // Muted, light
243
- const onError = { h: 25, c: 0, t: 100 }; // White
246
+ const onError = { h: 25, c: 0, t: 100 }; // White
244
247
  const onErrorContainer = { h: 25, c: 84, t: 10 }; // Dark red
245
248
  ```
246
249
 
@@ -258,4 +261,4 @@ Coolors MCP implements HCT using Google's Material Color Utilities algorithms:
258
261
  - [Color Spaces](./color-spaces.md) - Comparison with other color models
259
262
  - [Material Design](./material-design.md) - HCT in Material Design 3
260
263
  - [Accessibility](./accessibility.md) - Using tone for contrast
261
- - [Theme Matching](./theme-matching.md) - HCT-based matching algorithm
264
+ - [Theme Matching](./theme-matching.md) - HCT-based matching algorithm