@trishchuk/coolors-mcp 1.0.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 (197) hide show
  1. package/.claude/settings.local.json +39 -0
  2. package/.env +2 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +73 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.md +71 -0
  5. package/.github/pull_request_template.md +97 -0
  6. package/.github/workflows/ci.yml +127 -0
  7. package/.github/workflows/deploy-docs.yml +56 -0
  8. package/.github/workflows/release.yml +99 -0
  9. package/.mcp.json +12 -0
  10. package/.prettierignore +1 -0
  11. package/CLAUDE.md +201 -0
  12. package/DOCUMENTATION.md +274 -0
  13. package/GEMINI.md +54 -0
  14. package/LICENSE +21 -0
  15. package/README.md +401 -0
  16. package/demo/content_based_color.png +0 -0
  17. package/demo/music-player.html +621 -0
  18. package/demo/podcast-player.html +903 -0
  19. package/dist/bin/coolors-mcp.d.ts +1 -0
  20. package/dist/bin/coolors-mcp.js +154 -0
  21. package/dist/bin/coolors-mcp.js.map +1 -0
  22. package/dist/bin/server.d.ts +1 -0
  23. package/dist/bin/server.js +3292 -0
  24. package/dist/bin/server.js.map +1 -0
  25. package/dist/chunk-IQ7NN26V.js +114 -0
  26. package/dist/chunk-IQ7NN26V.js.map +1 -0
  27. package/dist/chunk-P3ARRKLS.js +1214 -0
  28. package/dist/chunk-P3ARRKLS.js.map +1 -0
  29. package/dist/color/index.d.ts +716 -0
  30. package/dist/color/index.js +153 -0
  31. package/dist/color/index.js.map +1 -0
  32. package/dist/coolors-mcp.d.ts +136 -0
  33. package/dist/coolors-mcp.js +7 -0
  34. package/dist/coolors-mcp.js.map +1 -0
  35. package/docs/.vitepress/cache/deps/@braintree_sanitize-url.js +93 -0
  36. package/docs/.vitepress/cache/deps/@braintree_sanitize-url.js.map +7 -0
  37. package/docs/.vitepress/cache/deps/_metadata.json +127 -0
  38. package/docs/.vitepress/cache/deps/chunk-BUSYA2B4.js +9 -0
  39. package/docs/.vitepress/cache/deps/chunk-BUSYA2B4.js.map +7 -0
  40. package/docs/.vitepress/cache/deps/chunk-JD3CXNQ6.js +12683 -0
  41. package/docs/.vitepress/cache/deps/chunk-JD3CXNQ6.js.map +7 -0
  42. package/docs/.vitepress/cache/deps/chunk-SYPOPCWC.js +9719 -0
  43. package/docs/.vitepress/cache/deps/chunk-SYPOPCWC.js.map +7 -0
  44. package/docs/.vitepress/cache/deps/cytoscape-cose-bilkent.js +4710 -0
  45. package/docs/.vitepress/cache/deps/cytoscape-cose-bilkent.js.map +7 -0
  46. package/docs/.vitepress/cache/deps/cytoscape.js +30278 -0
  47. package/docs/.vitepress/cache/deps/cytoscape.js.map +7 -0
  48. package/docs/.vitepress/cache/deps/dayjs.js +285 -0
  49. package/docs/.vitepress/cache/deps/dayjs.js.map +7 -0
  50. package/docs/.vitepress/cache/deps/debug.js +468 -0
  51. package/docs/.vitepress/cache/deps/debug.js.map +7 -0
  52. package/docs/.vitepress/cache/deps/package.json +3 -0
  53. package/docs/.vitepress/cache/deps/prismjs.js +1466 -0
  54. package/docs/.vitepress/cache/deps/prismjs.js.map +7 -0
  55. package/docs/.vitepress/cache/deps/prismjs_components_prism-bash.js +228 -0
  56. package/docs/.vitepress/cache/deps/prismjs_components_prism-bash.js.map +7 -0
  57. package/docs/.vitepress/cache/deps/prismjs_components_prism-javascript.js +142 -0
  58. package/docs/.vitepress/cache/deps/prismjs_components_prism-javascript.js.map +7 -0
  59. package/docs/.vitepress/cache/deps/prismjs_components_prism-json.js +27 -0
  60. package/docs/.vitepress/cache/deps/prismjs_components_prism-json.js.map +7 -0
  61. package/docs/.vitepress/cache/deps/prismjs_components_prism-python.js +65 -0
  62. package/docs/.vitepress/cache/deps/prismjs_components_prism-python.js.map +7 -0
  63. package/docs/.vitepress/cache/deps/prismjs_components_prism-typescript.js +53 -0
  64. package/docs/.vitepress/cache/deps/prismjs_components_prism-typescript.js.map +7 -0
  65. package/docs/.vitepress/cache/deps/prismjs_components_prism-yaml.js +73 -0
  66. package/docs/.vitepress/cache/deps/prismjs_components_prism-yaml.js.map +7 -0
  67. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +4507 -0
  68. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
  69. package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +584 -0
  70. package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +7 -0
  71. package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js +1146 -0
  72. package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map +7 -0
  73. package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js +1667 -0
  74. package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map +7 -0
  75. package/docs/.vitepress/cache/deps/vitepress___minisearch.js +1814 -0
  76. package/docs/.vitepress/cache/deps/vitepress___minisearch.js.map +7 -0
  77. package/docs/.vitepress/cache/deps/vue.js +344 -0
  78. package/docs/.vitepress/cache/deps/vue.js.map +7 -0
  79. package/docs/.vitepress/components/ClientGrid.vue +125 -0
  80. package/docs/.vitepress/components/CodeBlock.vue +231 -0
  81. package/docs/.vitepress/components/ConfigModal.vue +477 -0
  82. package/docs/.vitepress/components/DiagramModal.vue +528 -0
  83. package/docs/.vitepress/components/TroubleshootingModal.vue +472 -0
  84. package/docs/.vitepress/config.js +162 -0
  85. package/docs/.vitepress/theme/FundingLayout.vue +251 -0
  86. package/docs/.vitepress/theme/Layout.vue +134 -0
  87. package/docs/.vitepress/theme/components/AdBanner.vue +317 -0
  88. package/docs/.vitepress/theme/components/AdPlaceholder.vue +78 -0
  89. package/docs/.vitepress/theme/components/FundingEffects.vue +322 -0
  90. package/docs/.vitepress/theme/components/FundingHero.vue +345 -0
  91. package/docs/.vitepress/theme/components/SupportSection.vue +511 -0
  92. package/docs/.vitepress/theme/custom-app.css +339 -0
  93. package/docs/.vitepress/theme/custom.css +699 -0
  94. package/docs/.vitepress/theme/index.js +25 -0
  95. package/docs/README.md +198 -0
  96. package/docs/concepts/accessibility.md +473 -0
  97. package/docs/concepts/color-spaces.md +222 -0
  98. package/docs/concepts/distance-metrics.md +384 -0
  99. package/docs/concepts/hct.md +261 -0
  100. package/docs/concepts/image-analysis.md +396 -0
  101. package/docs/concepts/material-design.md +306 -0
  102. package/docs/concepts/theme-matching.md +399 -0
  103. package/docs/examples/basic-colors.md +490 -0
  104. package/docs/examples/creating-themes.md +898 -0
  105. package/docs/examples/css-refactoring.md +824 -0
  106. package/docs/examples/image-extraction.md +882 -0
  107. package/docs/getting-started.md +366 -0
  108. package/docs/index.md +190 -0
  109. package/docs/installation.md +157 -0
  110. package/docs/tools/README.md +234 -0
  111. package/docs/tools/accessibility.md +614 -0
  112. package/docs/tools/color-operations.md +374 -0
  113. package/docs/tools/image-extraction.md +624 -0
  114. package/docs/tools/material-design.md +347 -0
  115. package/docs/tools/theme-matching.md +552 -0
  116. package/eslint.config.ts +14 -0
  117. package/examples/theme-matching.md +113 -0
  118. package/jsr.json +7 -0
  119. package/mcp-config.json +8 -0
  120. package/note.md +35 -0
  121. package/package.json +122 -0
  122. package/research_results.md +53 -0
  123. package/src/bin/coolors-mcp.ts +194 -0
  124. package/src/bin/server.ts +61 -0
  125. package/src/color/__tests__/conversions-argb.test.ts +198 -0
  126. package/src/color/__tests__/extract-colors.test.ts +360 -0
  127. package/src/color/__tests__/image-utils.test.ts +242 -0
  128. package/src/color/__tests__/reference-colors.test.ts +278 -0
  129. package/src/color/__tests__/round-trip.test.ts +197 -0
  130. package/src/color/conversions.test.ts +402 -0
  131. package/src/color/conversions.ts +393 -0
  132. package/src/color/dislike/__tests__/dislike-analyzer.test.ts +248 -0
  133. package/src/color/dislike/dislike-analyzer.ts +114 -0
  134. package/src/color/extract-colors.ts +228 -0
  135. package/src/color/hct/__tests__/hct-class.test.ts +232 -0
  136. package/src/color/hct/harmonization.ts +204 -0
  137. package/src/color/hct/hct-class.ts +109 -0
  138. package/src/color/hct/hct-solver.ts +168 -0
  139. package/src/color/hct/index.ts +39 -0
  140. package/src/color/hct/tonal-palette.ts +211 -0
  141. package/src/color/hct/types.ts +88 -0
  142. package/src/color/image-utils.ts +79 -0
  143. package/src/color/index.ts +87 -0
  144. package/src/color/material-theme.ts +157 -0
  145. package/src/color/metrics.test.ts +276 -0
  146. package/src/color/metrics.ts +281 -0
  147. package/src/color/quantize/__tests__/quantizer_celebi.test.ts +195 -0
  148. package/src/color/quantize/lab_point_provider.ts +55 -0
  149. package/src/color/quantize/point_provider.ts +27 -0
  150. package/src/color/quantize/quantizer_celebi.ts +51 -0
  151. package/src/color/quantize/quantizer_celebi_test.ts +71 -0
  152. package/src/color/quantize/quantizer_map.ts +47 -0
  153. package/src/color/quantize/quantizer_wsmeans.ts +232 -0
  154. package/src/color/quantize/quantizer_wu.ts +472 -0
  155. package/src/color/score/__tests__/score.test.ts +224 -0
  156. package/src/color/score/score.ts +175 -0
  157. package/src/color/types.ts +151 -0
  158. package/src/color/utils/color_utils.ts +292 -0
  159. package/src/color/utils/math_utils.ts +145 -0
  160. package/src/color/utils.test.ts +403 -0
  161. package/src/color/utils.ts +315 -0
  162. package/src/constants.ts +5 -0
  163. package/src/coolors-mcp.ts +37 -0
  164. package/src/examples/addition.ts +333 -0
  165. package/src/examples/color-demo.ts +125 -0
  166. package/src/examples/custom-logger.ts +201 -0
  167. package/src/examples/oauth-server.ts +113 -0
  168. package/src/examples/session-context.ts +269 -0
  169. package/src/session.ts +116 -0
  170. package/src/theme/__tests__/matcher.test.ts +180 -0
  171. package/src/theme/__tests__/parser.test.ts +148 -0
  172. package/src/theme/__tests__/refactor.test.ts +224 -0
  173. package/src/theme/index.ts +34 -0
  174. package/src/theme/matcher.ts +395 -0
  175. package/src/theme/parser.ts +392 -0
  176. package/src/theme/refactor.ts +360 -0
  177. package/src/theme/types.ts +152 -0
  178. package/src/tools/__tests__/gradient-generator.test.ts +206 -0
  179. package/src/tools/__tests__/palette-with-locks.test.ts +109 -0
  180. package/src/tools/color-conversion.tool.ts +54 -0
  181. package/src/tools/color-distance.tool.ts +41 -0
  182. package/src/tools/colors.ts +31 -0
  183. package/src/tools/contrast-checker.tool.ts +37 -0
  184. package/src/tools/dislike-analyzer.tool.ts +247 -0
  185. package/src/tools/gradient-generator.tool.ts +250 -0
  186. package/src/tools/image-extraction.tools.ts +289 -0
  187. package/src/tools/index.ts +39 -0
  188. package/src/tools/material-theme.tools.ts +250 -0
  189. package/src/tools/palette-generator.tool.ts +135 -0
  190. package/src/tools/palette-with-locks.tool.ts +221 -0
  191. package/src/tools/registry.ts +142 -0
  192. package/src/tools/simple-tools.ts +37 -0
  193. package/src/tools/theme-matching.tools.ts +334 -0
  194. package/src/types.ts +182 -0
  195. package/src/utils.ts +22 -0
  196. package/tsconfig.json +8 -0
  197. package/vitest.config.js +15 -0
@@ -0,0 +1,824 @@
1
+ # CSS Refactoring Examples
2
+
3
+ Learn how to modernize your CSS by replacing hardcoded colors with theme variables using Coolors MCP's intelligent matching and refactoring tools.
4
+
5
+ ## Quick Start
6
+
7
+ ### Simple Color Replacement
8
+
9
+ Replace a single hardcoded color with a theme variable:
10
+
11
+ ```javascript
12
+ // Find matching theme variable
13
+ "What theme variable matches #6366f1?"
14
+
15
+ // With theme CSS
16
+ const theme = `
17
+ :root {
18
+ --color-primary-500: #6366f1;
19
+ --color-primary-600: #4f46e5;
20
+ }
21
+ `;
22
+
23
+ // Result: --color-primary-500 (100% confidence)
24
+ ```
25
+
26
+ ### Automatic CSS Refactoring
27
+
28
+ Refactor an entire stylesheet:
29
+
30
+ ```javascript
31
+ "Refactor this CSS to use theme variables:
32
+ .button {
33
+ background: #6366f1;
34
+ color: #ffffff;
35
+ border: 1px solid #4f46e5;
36
+ }"
37
+
38
+ // Automatically replaces with:
39
+ .button {
40
+ background: var(--color-primary-500);
41
+ color: var(--color-white);
42
+ border: 1px solid var(--color-primary-600);
43
+ }
44
+ ```
45
+
46
+ ## Complete Refactoring Examples
47
+
48
+ ### Component Stylesheet
49
+
50
+ #### Before (Hardcoded Colors)
51
+
52
+ ```css
53
+ /* card.css - Original */
54
+ .card {
55
+ background: #ffffff;
56
+ border: 1px solid #e5e7eb;
57
+ border-radius: 8px;
58
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
59
+ }
60
+
61
+ .card-header {
62
+ background: #f9fafb;
63
+ border-bottom: 1px solid #e5e7eb;
64
+ padding: 16px;
65
+ }
66
+
67
+ .card-title {
68
+ color: #1f2937;
69
+ font-size: 18px;
70
+ font-weight: 600;
71
+ }
72
+
73
+ .card-body {
74
+ padding: 16px;
75
+ color: #4b5563;
76
+ }
77
+
78
+ .card-footer {
79
+ background: #f9fafb;
80
+ border-top: 1px solid #e5e7eb;
81
+ padding: 12px 16px;
82
+ }
83
+
84
+ .card-link {
85
+ color: #6366f1;
86
+ text-decoration: none;
87
+ }
88
+
89
+ .card-link:hover {
90
+ color: #4f46e5;
91
+ text-decoration: underline;
92
+ }
93
+ ```
94
+
95
+ #### Theme Variables
96
+
97
+ ```css
98
+ /* theme.css */
99
+ :root {
100
+ /* Surfaces */
101
+ --color-surface: #ffffff;
102
+ --color-surface-variant: #f9fafb;
103
+
104
+ /* Borders */
105
+ --color-border: #e5e7eb;
106
+
107
+ /* Text */
108
+ --color-text-primary: #1f2937;
109
+ --color-text-secondary: #4b5563;
110
+
111
+ /* Brand */
112
+ --color-primary-500: #6366f1;
113
+ --color-primary-600: #4f46e5;
114
+
115
+ /* Shadows */
116
+ --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
117
+
118
+ /* Spacing */
119
+ --spacing-3: 12px;
120
+ --spacing-4: 16px;
121
+
122
+ /* Typography */
123
+ --font-size-lg: 18px;
124
+ --font-weight-semibold: 600;
125
+ }
126
+ ```
127
+
128
+ #### After (Refactored)
129
+
130
+ ```css
131
+ /* card.css - Refactored */
132
+ .card {
133
+ background: var(--color-surface);
134
+ border: 1px solid var(--color-border);
135
+ border-radius: 8px;
136
+ box-shadow: var(--shadow-sm);
137
+ }
138
+
139
+ .card-header {
140
+ background: var(--color-surface-variant);
141
+ border-bottom: 1px solid var(--color-border);
142
+ padding: var(--spacing-4);
143
+ }
144
+
145
+ .card-title {
146
+ color: var(--color-text-primary);
147
+ font-size: var(--font-size-lg);
148
+ font-weight: var(--font-weight-semibold);
149
+ }
150
+
151
+ .card-body {
152
+ padding: var(--spacing-4);
153
+ color: var(--color-text-secondary);
154
+ }
155
+
156
+ .card-footer {
157
+ background: var(--color-surface-variant);
158
+ border-top: 1px solid var(--color-border);
159
+ padding: var(--spacing-3) var(--spacing-4);
160
+ }
161
+
162
+ .card-link {
163
+ color: var(--color-primary-500);
164
+ text-decoration: none;
165
+ }
166
+
167
+ .card-link:hover {
168
+ color: var(--color-primary-600);
169
+ text-decoration: underline;
170
+ }
171
+ ```
172
+
173
+ ### Form Styles Refactoring
174
+
175
+ #### Before
176
+
177
+ ```css
178
+ /* forms.css - Original */
179
+ .form-group {
180
+ margin-bottom: 24px;
181
+ }
182
+
183
+ .form-label {
184
+ color: #374151;
185
+ font-size: 14px;
186
+ font-weight: 500;
187
+ margin-bottom: 8px;
188
+ }
189
+
190
+ .form-input {
191
+ background: #ffffff;
192
+ border: 1px solid #d1d5db;
193
+ border-radius: 6px;
194
+ color: #1f2937;
195
+ padding: 8px 12px;
196
+ width: 100%;
197
+ }
198
+
199
+ .form-input:focus {
200
+ border-color: #6366f1;
201
+ outline: 2px solid rgba(99, 102, 241, 0.2);
202
+ outline-offset: 2px;
203
+ }
204
+
205
+ .form-input:disabled {
206
+ background: #f3f4f6;
207
+ color: #9ca3af;
208
+ cursor: not-allowed;
209
+ }
210
+
211
+ .form-error {
212
+ color: #ef4444;
213
+ font-size: 12px;
214
+ margin-top: 4px;
215
+ }
216
+
217
+ .form-hint {
218
+ color: #6b7280;
219
+ font-size: 12px;
220
+ margin-top: 4px;
221
+ }
222
+ ```
223
+
224
+ #### After (With Original as Comments)
225
+
226
+ ```css
227
+ /* forms.css - Refactored with preservation */
228
+ .form-group {
229
+ margin-bottom: 24px;
230
+ }
231
+
232
+ .form-label {
233
+ color: var(--color-text-secondary); /* was: #374151 */
234
+ font-size: var(--font-size-sm); /* was: 14px */
235
+ font-weight: var(--font-weight-medium); /* was: 500 */
236
+ margin-bottom: var(--spacing-2); /* was: 8px */
237
+ }
238
+
239
+ .form-input {
240
+ background: var(--color-surface); /* was: #ffffff */
241
+ border: 1px solid var(--color-border-light); /* was: #d1d5db */
242
+ border-radius: var(--radius-md); /* was: 6px */
243
+ color: var(--color-text-primary); /* was: #1f2937 */
244
+ padding: var(--spacing-2) var(--spacing-3); /* was: 8px 12px */
245
+ width: 100%;
246
+ }
247
+
248
+ .form-input:focus {
249
+ border-color: var(--color-primary-500); /* was: #6366f1 */
250
+ outline: 2px solid var(--color-primary-100); /* was: rgba(99, 102, 241, 0.2) */
251
+ outline-offset: 2px;
252
+ }
253
+
254
+ .form-input:disabled {
255
+ background: var(--color-gray-100); /* was: #f3f4f6 */
256
+ color: var(--color-text-disabled); /* was: #9ca3af */
257
+ cursor: not-allowed;
258
+ }
259
+
260
+ .form-error {
261
+ color: var(--color-error); /* was: #ef4444 */
262
+ font-size: var(--font-size-xs); /* was: 12px */
263
+ margin-top: var(--spacing-1); /* was: 4px */
264
+ }
265
+
266
+ .form-hint {
267
+ color: var(--color-text-muted); /* was: #6b7280 */
268
+ font-size: var(--font-size-xs); /* was: 12px */
269
+ margin-top: var(--spacing-1); /* was: 4px */
270
+ }
271
+ ```
272
+
273
+ ## Batch Color Processing
274
+
275
+ ### Finding All Unique Colors
276
+
277
+ ```javascript
278
+ // Extract all colors from CSS
279
+ "Find all unique colors in this CSS file"
280
+
281
+ const css = `
282
+ .header { background: #1f2937; color: #ffffff; }
283
+ .nav { background: #374151; border-bottom: 1px solid #4b5563; }
284
+ .link { color: #6366f1; }
285
+ .link:hover { color: #4f46e5; }
286
+ .footer { background: #1f2937; color: #9ca3af; }
287
+ `;
288
+
289
+ // Result:
290
+ {
291
+ uniqueColors: [
292
+ "#1f2937", // Used 2 times
293
+ "#ffffff", // Used 1 time
294
+ "#374151", // Used 1 time
295
+ "#4b5563", // Used 1 time
296
+ "#6366f1", // Used 1 time
297
+ "#4f46e5", // Used 1 time
298
+ "#9ca3af" // Used 1 time
299
+ ],
300
+ suggestions: [
301
+ "Color #1f2937 is used multiple times - consider creating a variable",
302
+ "7 unique colors found - consider consolidating similar shades"
303
+ ]
304
+ }
305
+ ```
306
+
307
+ ### Batch Matching to Theme
308
+
309
+ ```javascript
310
+ // Match multiple colors at once
311
+ const colors = ["#6366f1", "#ec4899", "#10b981", "#f59e0b"];
312
+ const theme = `
313
+ :root {
314
+ --primary: #6366f1;
315
+ --accent: #ec4899;
316
+ --success: #10b981;
317
+ --warning: #f59e0b;
318
+ }
319
+ `;
320
+
321
+ // Results with confidence scores
322
+ [
323
+ { color: "#6366f1", match: "--primary", confidence: 100 },
324
+ { color: "#ec4899", match: "--accent", confidence: 100 },
325
+ { color: "#10b981", match: "--success", confidence: 100 },
326
+ { color: "#f59e0b", match: "--warning", confidence: 100 }
327
+ ]
328
+ ```
329
+
330
+ ## Migration Strategies
331
+
332
+ ### Progressive Enhancement
333
+
334
+ Start with high-confidence matches and gradually include lower confidence ones:
335
+
336
+ ```javascript
337
+ // Step 1: Replace exact matches (100% confidence)
338
+ const exactMatches = refactorCSS(css, theme, { minConfidence: 100 });
339
+
340
+ // Step 2: Review and approve near matches (85-99% confidence)
341
+ const nearMatches = refactorCSS(css, theme, { minConfidence: 85 });
342
+
343
+ // Step 3: Handle remaining colors manually or create new variables
344
+ const remaining = findUnmatchedColors(css, theme);
345
+ ```
346
+
347
+ ### Department-by-Department Migration
348
+
349
+ Migrate large codebases incrementally:
350
+
351
+ ```javascript
352
+ // 1. Start with utility classes
353
+ refactorFile('styles/utilities.css', theme);
354
+
355
+ // 2. Then base components
356
+ refactorFile('styles/buttons.css', theme);
357
+ refactorFile('styles/forms.css', theme);
358
+
359
+ // 3. Finally, complex components
360
+ refactorFile('styles/navigation.css', theme);
361
+ refactorFile('styles/modals.css', theme);
362
+ ```
363
+
364
+ ### Creating Missing Variables
365
+
366
+ When colors don't match existing theme:
367
+
368
+ ```javascript
369
+ // Identify unmatched colors
370
+ const unmatched = [
371
+ { color: "#7c3aed", usage: ["buttons", "links"] },
372
+ { color: "#0ea5e9", usage: ["alerts", "badges"] }
373
+ ];
374
+
375
+ // Generate appropriate variables
376
+ const newVariables = `
377
+ /* Additional theme colors */
378
+ --color-purple-500: #7c3aed;
379
+ --color-sky-500: #0ea5e9;
380
+ `;
381
+
382
+ // Update theme and re-refactor
383
+ const updatedTheme = theme + newVariables;
384
+ refactorCSS(css, updatedTheme);
385
+ ```
386
+
387
+ ## Context-Aware Refactoring
388
+
389
+ ### Semantic Matching
390
+
391
+ The refactoring tool understands context:
392
+
393
+ ```javascript
394
+ // Border colors prefer border variables
395
+ .card { border: 1px solid #e5e7eb; }
396
+ // → border: 1px solid var(--color-border);
397
+
398
+ // Text colors prefer text variables
399
+ .title { color: #1f2937; }
400
+ // → color: var(--color-text-primary);
401
+
402
+ // Backgrounds prefer surface variables
403
+ .modal { background: #ffffff; }
404
+ // → background: var(--color-surface);
405
+ ```
406
+
407
+ ### Confidence Levels
408
+
409
+ Understanding match confidence:
410
+
411
+ | Confidence | Meaning | Action |
412
+ |------------|---------|--------|
413
+ | 100% | Exact match | Auto-replace |
414
+ | 95-99% | Very close (ΔE < 2) | Auto-replace with comment |
415
+ | 85-94% | Close (ΔE < 5) | Suggest replacement |
416
+ | 70-84% | Similar (ΔE < 10) | Manual review |
417
+ | <70% | Different | Keep original |
418
+
419
+ ### Handling Edge Cases
420
+
421
+ #### Gradients
422
+
423
+ ```css
424
+ /* Before */
425
+ .gradient {
426
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
427
+ }
428
+
429
+ /* After */
430
+ .gradient {
431
+ background: linear-gradient(
432
+ 135deg,
433
+ var(--color-purple-500) 0%,
434
+ var(--color-purple-700) 100%
435
+ );
436
+ }
437
+ ```
438
+
439
+ #### RGBA Colors
440
+
441
+ ```css
442
+ /* Before */
443
+ .overlay {
444
+ background: rgba(0, 0, 0, 0.5);
445
+ border: 1px solid rgba(255, 255, 255, 0.2);
446
+ }
447
+
448
+ /* After */
449
+ .overlay {
450
+ background: rgba(var(--color-black-rgb), 0.5);
451
+ border: 1px solid rgba(var(--color-white-rgb), 0.2);
452
+ }
453
+
454
+ /* Where theme includes: */
455
+ :root {
456
+ --color-black-rgb: 0, 0, 0;
457
+ --color-white-rgb: 255, 255, 255;
458
+ }
459
+ ```
460
+
461
+ #### Box Shadows
462
+
463
+ ```css
464
+ /* Before */
465
+ .card {
466
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
467
+ }
468
+
469
+ /* After */
470
+ .card {
471
+ box-shadow: var(--shadow-md);
472
+ }
473
+ ```
474
+
475
+ ## Real-World Refactoring
476
+
477
+ ### E-commerce Site
478
+
479
+ ```css
480
+ /* Original product card */
481
+ .product-card {
482
+ background: white;
483
+ border: 1px solid #e0e0e0;
484
+ border-radius: 8px;
485
+ }
486
+
487
+ .product-image {
488
+ background: #f5f5f5;
489
+ }
490
+
491
+ .product-title {
492
+ color: #333333;
493
+ font-size: 18px;
494
+ }
495
+
496
+ .product-price {
497
+ color: #0066cc;
498
+ font-size: 24px;
499
+ font-weight: bold;
500
+ }
501
+
502
+ .product-sale-badge {
503
+ background: #ff4444;
504
+ color: white;
505
+ padding: 4px 8px;
506
+ }
507
+
508
+ .product-add-to-cart {
509
+ background: #00aa00;
510
+ color: white;
511
+ padding: 12px 24px;
512
+ }
513
+ ```
514
+
515
+ ```css
516
+ /* Refactored with design system */
517
+ .product-card {
518
+ background: var(--color-surface);
519
+ border: 1px solid var(--color-border);
520
+ border-radius: var(--radius-lg);
521
+ }
522
+
523
+ .product-image {
524
+ background: var(--color-surface-variant);
525
+ }
526
+
527
+ .product-title {
528
+ color: var(--color-text-primary);
529
+ font-size: var(--font-size-lg);
530
+ }
531
+
532
+ .product-price {
533
+ color: var(--color-primary);
534
+ font-size: var(--font-size-2xl);
535
+ font-weight: var(--font-weight-bold);
536
+ }
537
+
538
+ .product-sale-badge {
539
+ background: var(--color-error);
540
+ color: var(--color-on-error);
541
+ padding: var(--spacing-1) var(--spacing-2);
542
+ }
543
+
544
+ .product-add-to-cart {
545
+ background: var(--color-success);
546
+ color: var(--color-on-success);
547
+ padding: var(--spacing-3) var(--spacing-6);
548
+ }
549
+ ```
550
+
551
+ ### Dashboard Application
552
+
553
+ ```css
554
+ /* Original dashboard styles */
555
+ .dashboard {
556
+ background: #f8f9fa;
557
+ }
558
+
559
+ .sidebar {
560
+ background: #2c3e50;
561
+ color: #ecf0f1;
562
+ }
563
+
564
+ .sidebar-item:hover {
565
+ background: #34495e;
566
+ }
567
+
568
+ .sidebar-item.active {
569
+ background: #3498db;
570
+ }
571
+
572
+ .metric-card {
573
+ background: white;
574
+ border: 1px solid #dee2e6;
575
+ }
576
+
577
+ .metric-value {
578
+ color: #2c3e50;
579
+ font-size: 32px;
580
+ }
581
+
582
+ .metric-change.positive {
583
+ color: #27ae60;
584
+ }
585
+
586
+ .metric-change.negative {
587
+ color: #e74c3c;
588
+ }
589
+ ```
590
+
591
+ ```css
592
+ /* Refactored with consistent theme */
593
+ .dashboard {
594
+ background: var(--color-background);
595
+ }
596
+
597
+ .sidebar {
598
+ background: var(--color-surface-inverse);
599
+ color: var(--color-on-surface-inverse);
600
+ }
601
+
602
+ .sidebar-item:hover {
603
+ background: var(--color-surface-inverse-hover);
604
+ }
605
+
606
+ .sidebar-item.active {
607
+ background: var(--color-primary);
608
+ }
609
+
610
+ .metric-card {
611
+ background: var(--color-surface);
612
+ border: 1px solid var(--color-outline);
613
+ }
614
+
615
+ .metric-value {
616
+ color: var(--color-on-surface);
617
+ font-size: var(--font-size-4xl);
618
+ }
619
+
620
+ .metric-change.positive {
621
+ color: var(--color-success);
622
+ }
623
+
624
+ .metric-change.negative {
625
+ color: var(--color-error);
626
+ }
627
+ ```
628
+
629
+ ## Automation Scripts
630
+
631
+ ### Full Project Refactoring
632
+
633
+ ```javascript
634
+ // refactor-project.js
635
+ const { refactorCSS, generateReport } = require('coolors-mcp');
636
+ const fs = require('fs');
637
+ const path = require('path');
638
+
639
+ async function refactorProject(srcDir, themeFile) {
640
+ const theme = fs.readFileSync(themeFile, 'utf-8');
641
+ const cssFiles = findCSSFiles(srcDir);
642
+ const results = [];
643
+
644
+ for (const file of cssFiles) {
645
+ const original = fs.readFileSync(file, 'utf-8');
646
+ const refactored = await refactorCSS(original, theme, {
647
+ minConfidence: 85,
648
+ preserveOriginal: true,
649
+ generateReport: true
650
+ });
651
+
652
+ // Backup original
653
+ fs.writeFileSync(`${file}.backup`, original);
654
+
655
+ // Write refactored
656
+ fs.writeFileSync(file, refactored.css);
657
+
658
+ results.push({
659
+ file,
660
+ changes: refactored.changes.length,
661
+ confidence: refactored.averageConfidence
662
+ });
663
+ }
664
+
665
+ return generateReport(results);
666
+ }
667
+ ```
668
+
669
+ ### Pre-commit Hook
670
+
671
+ ```javascript
672
+ // .husky/pre-commit
673
+ #!/bin/sh
674
+
675
+ # Check for hardcoded colors in staged CSS files
676
+ staged_css=$(git diff --cached --name-only --diff-filter=ACM | grep '\.css$')
677
+
678
+ if [ -n "$staged_css" ]; then
679
+ for file in $staged_css; do
680
+ # Check for hex colors not using variables
681
+ if grep -E '#[0-9a-fA-F]{3,6}(?![0-9a-fA-F])' "$file" | grep -v 'var(--'; then
682
+ echo "⚠️ Warning: Hardcoded colors found in $file"
683
+ echo "Consider using theme variables instead"
684
+ exit 1
685
+ fi
686
+ done
687
+ fi
688
+ ```
689
+
690
+ ## Best Practices
691
+
692
+ ### 1. Start with a Complete Theme
693
+
694
+ Before refactoring, ensure your theme covers all use cases:
695
+
696
+ ```css
697
+ :root {
698
+ /* Surface colors */
699
+ --color-surface: #ffffff;
700
+ --color-surface-variant: #f5f5f5;
701
+ --color-surface-inverse: #1a1a1a;
702
+
703
+ /* Text colors */
704
+ --color-text-primary: #1a1a1a;
705
+ --color-text-secondary: #666666;
706
+ --color-text-disabled: #999999;
707
+
708
+ /* Interactive colors */
709
+ --color-primary: #6366f1;
710
+ --color-primary-hover: #4f46e5;
711
+ --color-primary-active: #4338ca;
712
+
713
+ /* Semantic colors */
714
+ --color-success: #10b981;
715
+ --color-warning: #f59e0b;
716
+ --color-error: #ef4444;
717
+ --color-info: #3b82f6;
718
+ }
719
+ ```
720
+
721
+ ### 2. Use Semantic Naming
722
+
723
+ Choose variable names that describe purpose, not appearance:
724
+
725
+ ```css
726
+ /* Good */
727
+ --color-text-primary
728
+ --color-surface-elevated
729
+ --color-interactive-hover
730
+
731
+ /* Avoid */
732
+ --color-black
733
+ --color-gray-light
734
+ --color-blue-dark
735
+ ```
736
+
737
+ ### 3. Preserve Original Values
738
+
739
+ Keep original values as comments for reference:
740
+
741
+ ```css
742
+ .button {
743
+ background: var(--color-primary); /* was: #6366f1 */
744
+ }
745
+ ```
746
+
747
+ ### 4. Test After Refactoring
748
+
749
+ Always verify visual appearance after refactoring:
750
+
751
+ ```javascript
752
+ // Visual regression test
753
+ const screenshots = {
754
+ before: captureScreenshots(originalCSS),
755
+ after: captureScreenshots(refactoredCSS)
756
+ };
757
+
758
+ const differences = compareScreenshots(screenshots);
759
+ if (differences.length > 0) {
760
+ console.warn('Visual differences detected:', differences);
761
+ }
762
+ ```
763
+
764
+ ### 5. Document Your Theme
765
+
766
+ Include documentation with your theme variables:
767
+
768
+ ```css
769
+ :root {
770
+ /* Primary brand color - used for CTAs and primary actions */
771
+ --color-primary: #6366f1;
772
+
773
+ /* Text on primary color - must meet WCAG AA */
774
+ --color-on-primary: #ffffff;
775
+
776
+ /* Surface colors - ordered by elevation */
777
+ --color-surface-0: #ffffff; /* Base level */
778
+ --color-surface-1: #fafafa; /* Slightly elevated */
779
+ --color-surface-2: #f5f5f5; /* More elevated */
780
+ }
781
+ ```
782
+
783
+ ## Troubleshooting
784
+
785
+ ### Common Issues and Solutions
786
+
787
+ #### Low Confidence Matches
788
+
789
+ **Problem**: Most matches have <70% confidence
790
+ **Solution**:
791
+ - Check if theme has enough color variations
792
+ - Consider adding intermediate shades
793
+ - Use more specific theme variables
794
+
795
+ #### Wrong Semantic Matches
796
+
797
+ **Problem**: Border colors matching to text variables
798
+ **Solution**:
799
+ - Use clearer variable naming conventions
800
+ - Provide context parameter when matching
801
+ - Create role-specific variables
802
+
803
+ #### Performance with Large Files
804
+
805
+ **Problem**: Slow refactoring for large CSS files
806
+ **Solution**:
807
+ - Split CSS into smaller modules
808
+ - Process files in parallel
809
+ - Cache theme parsing results
810
+
811
+ #### Gradient Refactoring
812
+
813
+ **Problem**: Complex gradients not refactoring correctly
814
+ **Solution**:
815
+ - Define gradient variables directly
816
+ - Use CSS custom properties for gradient stops
817
+ - Consider keeping complex gradients as-is
818
+
819
+ ## Next Steps
820
+
821
+ - Learn about [Creating Themes](./creating-themes.md) to build comprehensive design systems
822
+ - Explore [Image Extraction](./image-extraction.md) for dynamic theme generation
823
+ - Read [Theme Matching Concepts](../concepts/theme-matching.md) to understand the algorithms
824
+ - Check [Material Design Tools](../tools/material-design.md) for advanced theming