@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
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div
2
+ <div
3
3
  class="funding-hero"
4
4
  @mouseenter="handleMouseEnter"
5
5
  @mousemove="handleMouseMove"
@@ -10,44 +10,48 @@
10
10
  <div class="hero-glow"></div>
11
11
  <div class="hero-particles"></div>
12
12
  </div>
13
-
13
+
14
14
  <div class="hero-content">
15
15
  <h1 class="hero-title">
16
16
  <span class="title-main">Support Development</span>
17
17
  <span class="title-sub">of Coolors MCP</span>
18
18
  </h1>
19
-
19
+
20
20
  <p class="hero-description">
21
21
  Every contribution helps maintain, improve and expand this project
22
22
  </p>
23
-
23
+
24
24
  <div class="hero-actions">
25
- <a
26
- href="https://github.com/sponsors/x51xxx"
25
+ <a
26
+ href="https://github.com/sponsors/x51xxx"
27
27
  target="_blank"
28
28
  rel="noopener"
29
29
  class="action-button action-primary"
30
30
  >
31
31
  <svg class="button-icon" viewBox="0 0 16 16" fill="currentColor">
32
- <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/>
32
+ <path
33
+ d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
34
+ />
33
35
  </svg>
34
36
  Sponsor on GitHub
35
37
  </a>
36
38
 
37
- <a
38
- href="https://github.com/x51xxx/coolors-mcp"
39
+ <a
40
+ href="https://github.com/x51xxx/coolors-mcp"
39
41
  target="_blank"
40
42
  rel="noopener"
41
43
  class="action-button action-primary"
42
44
  >
43
45
  <svg class="button-icon" viewBox="0 0 22 22" fill="currentColor">
44
- <path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/>
46
+ <path
47
+ d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"
48
+ />
45
49
  </svg>
46
50
  Star on GitHub
47
51
  </a>
48
-
49
- <a
50
- href="https://ko-fi.com/jamubc"
52
+
53
+ <a
54
+ href="https://ko-fi.com/jamubc"
51
55
  target="_blank"
52
56
  rel="noopener"
53
57
  class="action-button action-secondary"
@@ -61,55 +65,55 @@
61
65
  </template>
62
66
 
63
67
  <script setup>
64
- import { ref, onMounted, onUnmounted } from 'vue'
68
+ import { ref, onMounted, onUnmounted } from "vue";
65
69
 
66
- const heroRef = ref(null)
70
+ const heroRef = ref(null);
67
71
 
68
72
  const handleMouseEnter = (e) => {
69
- if (!heroRef.value) return
70
-
71
- const rect = heroRef.value.getBoundingClientRect()
72
- const x = e.clientX - rect.left
73
- const y = e.clientY - rect.top
74
-
75
- heroRef.value.style.setProperty('--mouse-x', `${x}px`)
76
- heroRef.value.style.setProperty('--mouse-y', `${y}px`)
77
- heroRef.value.classList.add('mouse-over')
78
- }
73
+ if (!heroRef.value) return;
74
+
75
+ const rect = heroRef.value.getBoundingClientRect();
76
+ const x = e.clientX - rect.left;
77
+ const y = e.clientY - rect.top;
78
+
79
+ heroRef.value.style.setProperty("--mouse-x", `${x}px`);
80
+ heroRef.value.style.setProperty("--mouse-y", `${y}px`);
81
+ heroRef.value.classList.add("mouse-over");
82
+ };
79
83
 
80
84
  const handleMouseMove = (e) => {
81
- if (!heroRef.value) return
82
-
83
- const rect = heroRef.value.getBoundingClientRect()
84
- const x = e.clientX - rect.left
85
- const y = e.clientY - rect.top
86
-
87
- heroRef.value.style.setProperty('--mouse-x', `${x}px`)
88
- heroRef.value.style.setProperty('--mouse-y', `${y}px`)
89
- }
85
+ if (!heroRef.value) return;
86
+
87
+ const rect = heroRef.value.getBoundingClientRect();
88
+ const x = e.clientX - rect.left;
89
+ const y = e.clientY - rect.top;
90
+
91
+ heroRef.value.style.setProperty("--mouse-x", `${x}px`);
92
+ heroRef.value.style.setProperty("--mouse-y", `${y}px`);
93
+ };
90
94
 
91
95
  const handleMouseLeave = () => {
92
- if (!heroRef.value) return
93
- heroRef.value.classList.remove('mouse-over')
94
- }
96
+ if (!heroRef.value) return;
97
+ heroRef.value.classList.remove("mouse-over");
98
+ };
95
99
 
96
100
  // Create floating particles
97
101
  onMounted(() => {
98
- if (!heroRef.value) return
99
-
100
- const particlesContainer = heroRef.value.querySelector('.hero-particles')
101
- const particleCount = 20
102
-
102
+ if (!heroRef.value) return;
103
+
104
+ const particlesContainer = heroRef.value.querySelector(".hero-particles");
105
+ const particleCount = 20;
106
+
103
107
  for (let i = 0; i < particleCount; i++) {
104
- const particle = document.createElement('div')
105
- particle.className = 'particle'
106
- particle.style.setProperty('--delay', `${Math.random() * 10}s`)
107
- particle.style.setProperty('--duration', `${15 + Math.random() * 20}s`)
108
- particle.style.left = `${Math.random() * 100}%`
109
- particle.style.animationDelay = `${Math.random() * 10}s`
110
- particlesContainer.appendChild(particle)
108
+ const particle = document.createElement("div");
109
+ particle.className = "particle";
110
+ particle.style.setProperty("--delay", `${Math.random() * 10}s`);
111
+ particle.style.setProperty("--duration", `${15 + Math.random() * 20}s`);
112
+ particle.style.left = `${Math.random() * 100}%`;
113
+ particle.style.animationDelay = `${Math.random() * 10}s`;
114
+ particlesContainer.appendChild(particle);
111
115
  }
112
- })
116
+ });
113
117
  </script>
114
118
 
115
119
  <style scoped>
@@ -208,7 +212,12 @@ onMounted(() => {
208
212
  display: block;
209
213
  font-size: 48px;
210
214
  font-weight: 800;
211
- background: linear-gradient(135deg, var(--vp-c-brand) 0%, #ff6b35 50%, #ff8c00 100%);
215
+ background: linear-gradient(
216
+ 135deg,
217
+ var(--vp-c-brand) 0%,
218
+ #ff6b35 50%,
219
+ #ff8c00 100%
220
+ );
212
221
  -webkit-background-clip: text;
213
222
  background-clip: text;
214
223
  -webkit-text-fill-color: transparent;
@@ -217,9 +226,15 @@ onMounted(() => {
217
226
  }
218
227
 
219
228
  @keyframes shimmer {
220
- 0% { background-position: 0% 50%; }
221
- 50% { background-position: 100% 50%; }
222
- 100% { background-position: 0% 50%; }
229
+ 0% {
230
+ background-position: 0% 50%;
231
+ }
232
+ 50% {
233
+ background-position: 100% 50%;
234
+ }
235
+ 100% {
236
+ background-position: 0% 50%;
237
+ }
223
238
  }
224
239
 
225
240
  .title-sub {
@@ -267,7 +282,7 @@ onMounted(() => {
267
282
 
268
283
  .action-primary:hover {
269
284
  transform: translateY(-2px);
270
- box-shadow:
285
+ box-shadow:
271
286
  0 8px 24px rgba(66, 184, 131, 0.3),
272
287
  0 0 40px rgba(255, 140, 0, 0.2);
273
288
  }
@@ -281,7 +296,7 @@ onMounted(() => {
281
296
  .action-secondary:hover {
282
297
  border-color: rgba(255, 140, 0, 0.6);
283
298
  transform: translateY(-2px);
284
- box-shadow:
299
+ box-shadow:
285
300
  0 0 30px rgba(255, 140, 0, 0.15),
286
301
  inset 0 0 20px rgba(255, 140, 0, 0.05);
287
302
  }
@@ -308,7 +323,7 @@ html:not(.dark) .particle {
308
323
 
309
324
  html:not(.dark) .action-secondary:hover {
310
325
  border-color: rgba(66, 139, 202, 0.6);
311
- box-shadow:
326
+ box-shadow:
312
327
  0 0 30px rgba(66, 139, 202, 0.1),
313
328
  inset 0 0 20px rgba(66, 139, 202, 0.03);
314
329
  }
@@ -318,28 +333,28 @@ html:not(.dark) .action-secondary:hover {
318
333
  .funding-hero {
319
334
  padding: 60px 20px;
320
335
  }
321
-
336
+
322
337
  .title-main {
323
338
  font-size: 36px;
324
339
  }
325
-
340
+
326
341
  .title-sub {
327
342
  font-size: 20px;
328
343
  }
329
-
344
+
330
345
  .hero-description {
331
346
  font-size: 16px;
332
347
  }
333
-
348
+
334
349
  .hero-actions {
335
350
  flex-direction: column;
336
351
  align-items: center;
337
352
  }
338
-
353
+
339
354
  .action-button {
340
355
  width: 100%;
341
356
  max-width: 300px;
342
357
  justify-content: center;
343
358
  }
344
359
  }
345
- </style>
360
+ </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div
2
+ <div
3
3
  class="support-section"
4
4
  @mouseenter="handleSectionMouseEnter"
5
5
  @mousemove="handleSectionMouseMove"
@@ -11,11 +11,12 @@
11
11
  <div class="support-text">
12
12
  <h3 class="support-title">Support Coolors MCP</h3>
13
13
  <p class="support-description">
14
- Does coolors-mcp help you?<br><br>Your support helps maintain & improve this open source project.
14
+ Does coolors-mcp help you?<br /><br />Your support helps maintain &
15
+ improve this open source project.
15
16
  </p>
16
17
  </div>
17
- <a
18
- href="/coolors-mcp/funding"
18
+ <a
19
+ href="/coolors-mcp/funding"
19
20
  class="transparency-link"
20
21
  @mouseenter="handleMouseEnter"
21
22
  @mousemove="handleMouseMove"
@@ -25,21 +26,22 @@
25
26
  <span class="link-text">See how funds are used →</span>
26
27
  </a>
27
28
  </div>
28
-
29
+
29
30
  <div class="support-options">
30
- <a
31
+ <a
31
32
  href="https://github.com/sponsors/x51xxx"
32
- target="_blank"
33
+ target="_blank"
33
34
  rel="noopener"
34
35
  class="support-button support-button--primary"
35
36
  title="Sponsor on GitHub"
36
37
  >
37
38
  <svg class="support-icon" viewBox="0 0 16 16" fill="currentColor">
38
- <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/>
39
+ <path
40
+ d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
41
+ />
39
42
  </svg>
40
43
  <span class="button-text">Sponsor on GitHub</span>
41
44
  </a>
42
-
43
45
  </div>
44
46
 
45
47
  <div class="support-benefits">
@@ -49,7 +51,9 @@
49
51
  </p>
50
52
  <p class="support-benefit">
51
53
  <span class="benefit-icon">✓</span>
52
- <span>Keeps the project actively maintained as CLI tools evolve </span>
54
+ <span
55
+ >Keeps the project actively maintained as CLI tools evolve
56
+ </span>
53
57
  </p>
54
58
  </div>
55
59
  </div>
@@ -57,66 +61,66 @@
57
61
  </template>
58
62
 
59
63
  <script setup>
60
- import { ref } from 'vue'
64
+ import { ref } from "vue";
61
65
 
62
- const linkRef = ref(null)
63
- const sectionRef = ref(null)
66
+ const linkRef = ref(null);
67
+ const sectionRef = ref(null);
64
68
 
65
69
  const handleMouseEnter = (e) => {
66
- if (!linkRef.value) return
67
-
68
- const rect = linkRef.value.getBoundingClientRect()
69
- const x = e.clientX - rect.left
70
- const percentage = (x / rect.width) * 100
71
-
72
- linkRef.value.style.setProperty('--mouse-x', `${percentage}%`)
73
- linkRef.value.classList.add('mouse-over')
74
- }
70
+ if (!linkRef.value) return;
71
+
72
+ const rect = linkRef.value.getBoundingClientRect();
73
+ const x = e.clientX - rect.left;
74
+ const percentage = (x / rect.width) * 100;
75
+
76
+ linkRef.value.style.setProperty("--mouse-x", `${percentage}%`);
77
+ linkRef.value.classList.add("mouse-over");
78
+ };
75
79
 
76
80
  const handleMouseMove = (e) => {
77
- if (!linkRef.value) return
78
-
79
- const rect = linkRef.value.getBoundingClientRect()
80
- const x = e.clientX - rect.left
81
- const percentage = (x / rect.width) * 100
82
-
83
- linkRef.value.style.setProperty('--mouse-x', `${percentage}%`)
84
- }
81
+ if (!linkRef.value) return;
82
+
83
+ const rect = linkRef.value.getBoundingClientRect();
84
+ const x = e.clientX - rect.left;
85
+ const percentage = (x / rect.width) * 100;
86
+
87
+ linkRef.value.style.setProperty("--mouse-x", `${percentage}%`);
88
+ };
85
89
 
86
90
  const handleMouseLeave = () => {
87
- if (!linkRef.value) return
91
+ if (!linkRef.value) return;
88
92
  // Keep the last mouse position, just remove the hover class
89
- linkRef.value.classList.remove('mouse-over')
90
- }
93
+ linkRef.value.classList.remove("mouse-over");
94
+ };
91
95
 
92
96
  const handleSectionMouseEnter = (e) => {
93
- if (!sectionRef.value) return
94
-
95
- const rect = sectionRef.value.getBoundingClientRect()
96
- const x = e.clientX - rect.left
97
- const y = e.clientY - rect.top
98
-
99
- sectionRef.value.style.setProperty('--section-mouse-x', `${x}px`)
100
- sectionRef.value.style.setProperty('--section-mouse-y', `${y}px`)
101
- sectionRef.value.classList.add('mouse-over')
102
- }
97
+ if (!sectionRef.value) return;
98
+
99
+ const rect = sectionRef.value.getBoundingClientRect();
100
+ const x = e.clientX - rect.left;
101
+ const y = e.clientY - rect.top;
102
+
103
+ sectionRef.value.style.setProperty("--section-mouse-x", `${x}px`);
104
+ sectionRef.value.style.setProperty("--section-mouse-y", `${y}px`);
105
+ sectionRef.value.classList.add("mouse-over");
106
+ };
103
107
 
104
108
  const handleSectionMouseMove = (e) => {
105
- if (!sectionRef.value) return
106
-
107
- const rect = sectionRef.value.getBoundingClientRect()
108
- const x = e.clientX - rect.left
109
- const y = e.clientY - rect.top
110
-
111
- sectionRef.value.style.setProperty('--section-mouse-x', `${x}px`)
112
- sectionRef.value.style.setProperty('--section-mouse-y', `${y}px`)
113
- }
109
+ if (!sectionRef.value) return;
110
+
111
+ const rect = sectionRef.value.getBoundingClientRect();
112
+ const x = e.clientX - rect.left;
113
+ const y = e.clientY - rect.top;
114
+
115
+ sectionRef.value.style.setProperty("--section-mouse-x", `${x}px`);
116
+ sectionRef.value.style.setProperty("--section-mouse-y", `${y}px`);
117
+ };
114
118
 
115
119
  const handleSectionMouseLeave = () => {
116
- if (!sectionRef.value) return
120
+ if (!sectionRef.value) return;
117
121
  // Keep the last mouse position, just remove the hover class
118
- sectionRef.value.classList.remove('mouse-over')
119
- }
122
+ sectionRef.value.classList.remove("mouse-over");
123
+ };
120
124
  </script>
121
125
 
122
126
  <style scoped>
@@ -135,7 +139,7 @@ const handleSectionMouseLeave = () => {
135
139
  }
136
140
 
137
141
  .support-section::before {
138
- content: '';
142
+ content: "";
139
143
  position: absolute;
140
144
  top: 0;
141
145
  left: 0;
@@ -164,12 +168,17 @@ const handleSectionMouseLeave = () => {
164
168
  }
165
169
 
166
170
  @keyframes shimmer {
167
- 0%, 100% { opacity: 1; }
168
- 50% { opacity: 0.7; }
171
+ 0%,
172
+ 100% {
173
+ opacity: 1;
174
+ }
175
+ 50% {
176
+ opacity: 0.7;
177
+ }
169
178
  }
170
179
 
171
180
  .support-section::after {
172
- content: '';
181
+ content: "";
173
182
  position: absolute;
174
183
  top: -2px;
175
184
  left: -2px;
@@ -282,8 +291,13 @@ const handleSectionMouseLeave = () => {
282
291
  }
283
292
 
284
293
  @keyframes pulse {
285
- 0%, 100% { filter: contrast(1.2) brightness(1.1); }
286
- 50% { filter: contrast(1.3) brightness(1.2); }
294
+ 0%,
295
+ 100% {
296
+ filter: contrast(1.2) brightness(1.1);
297
+ }
298
+ 50% {
299
+ filter: contrast(1.3) brightness(1.2);
300
+ }
287
301
  }
288
302
 
289
303
  .support-options {
@@ -315,7 +329,7 @@ const handleSectionMouseLeave = () => {
315
329
  .support-button--primary:hover {
316
330
  background: var(--vp-c-brand-dark);
317
331
  transform: translateY(-2px);
318
- box-shadow:
332
+ box-shadow:
319
333
  0 4px 12px rgba(66, 184, 131, 0.3),
320
334
  0 0 20px rgba(218, 119, 86, 0.4),
321
335
  0 0 30px rgba(71, 150, 227, 0.3),
@@ -324,15 +338,16 @@ const handleSectionMouseLeave = () => {
324
338
  }
325
339
 
326
340
  @keyframes glow {
327
- 0%, 100% {
328
- box-shadow:
341
+ 0%,
342
+ 100% {
343
+ box-shadow:
329
344
  0 4px 12px rgba(66, 184, 131, 0.3),
330
345
  0 0 20px rgba(218, 119, 86, 0.4),
331
346
  0 0 30px rgba(71, 150, 227, 0.3),
332
347
  0 0 40px rgba(255, 140, 0, 0.2);
333
348
  }
334
- 50% {
335
- box-shadow:
349
+ 50% {
350
+ box-shadow:
336
351
  0 4px 16px rgba(66, 184, 131, 0.4),
337
352
  0 0 25px rgba(218, 119, 86, 0.5),
338
353
  0 0 35px rgba(71, 150, 227, 0.4),
@@ -350,7 +365,7 @@ const handleSectionMouseLeave = () => {
350
365
  background: var(--vp-c-bg-mute);
351
366
  border-color: rgba(255, 140, 0, 0.6);
352
367
  transform: translateY(-2px);
353
- box-shadow:
368
+ box-shadow:
354
369
  0 0 20px rgba(255, 140, 0, 0.2),
355
370
  inset 0 0 20px rgba(255, 140, 0, 0.05);
356
371
  }
@@ -390,23 +405,23 @@ const handleSectionMouseLeave = () => {
390
405
  padding: 20px 16px;
391
406
  margin: 24px 0 16px;
392
407
  }
393
-
408
+
394
409
  .support-header {
395
410
  flex-direction: column;
396
411
  align-items: flex-start;
397
412
  gap: 12px;
398
413
  }
399
-
414
+
400
415
  .support-options {
401
416
  width: 100%;
402
417
  flex-direction: column;
403
418
  }
404
-
419
+
405
420
  .support-button {
406
421
  width: 100%;
407
422
  justify-content: center;
408
423
  }
409
-
424
+
410
425
  .support-benefits {
411
426
  padding-top: 12px;
412
427
  }
@@ -435,7 +450,6 @@ html.dark .support-button--secondary {
435
450
  border-color: rgba(255, 255, 255, 0.1);
436
451
  }
437
452
 
438
-
439
453
  html.dark .support-button--primary {
440
454
  background: rgba(58, 80, 172, 0.05);
441
455
  }
@@ -447,20 +461,24 @@ html:not(.dark) .support-button--primary {
447
461
 
448
462
  html:not(.dark) .support-button--primary:hover {
449
463
  color: #000000;
450
- box-shadow:
464
+ box-shadow:
451
465
  0 4px 12px rgba(71, 150, 227, 0.5),
452
466
  0 0 25px rgba(218, 119, 86, 0.7),
453
467
  0 0 35px rgba(66, 139, 202, 0.6),
454
468
  inset 0 1px 0 rgba(255, 255, 255, 0.3);
455
- background: linear-gradient(135deg, var(--vp-c-brand-dark) 0%, var(--vp-c-brand) 100%);
469
+ background: linear-gradient(
470
+ 135deg,
471
+ var(--vp-c-brand-dark) 0%,
472
+ var(--vp-c-brand) 100%
473
+ );
456
474
  }
457
475
 
458
476
  /* Light mode specific adjustments for mouse effects */
459
477
  html:not(.dark) .support-section::before {
460
478
  background: radial-gradient(
461
479
  600px circle at var(--section-mouse-x) var(--section-mouse-y),
462
- rgba(66, 139, 202, 0.08), /* Blue instead of orange */
463
- rgba(71, 150, 227, 0.05) 40%,
480
+ rgba(66, 139, 202, 0.08),
481
+ /* Blue instead of orange */ rgba(71, 150, 227, 0.05) 40%,
464
482
  transparent 65%
465
483
  );
466
484
  }
@@ -468,22 +486,21 @@ html:not(.dark) .support-section::before {
468
486
  html:not(.dark) .support-section::after {
469
487
  background: radial-gradient(
470
488
  400px circle at var(--section-mouse-x) var(--section-mouse-y),
471
- rgba(66, 139, 202, 0.15), /* Blue accent */
472
- rgba(71, 150, 227, 0.08) 40%,
489
+ rgba(66, 139, 202, 0.15),
490
+ /* Blue accent */ rgba(71, 150, 227, 0.08) 40%,
473
491
  transparent 65%
474
492
  );
475
493
  }
476
494
 
477
-
478
495
  html:not(.dark) .transparency-link.mouse-over .link-text {
479
496
  background: radial-gradient(
480
497
  ellipse 150% 100% at var(--mouse-x) 50%,
481
- #1e3a8a 0%, /* Very dark blue */
482
- #1d4ed8 10%, /* Dark blue */
483
- #1e40af 20%, /* Muted dark blue */
484
- #0c2a5d 30%, /* Deep navy blue */
485
- #082f49 40%, /* Midnight blue */
486
- var(--vp-c-brand) 60%
498
+ #1e3a8a 0%,
499
+ /* Very dark blue */ #1d4ed8 10%,
500
+ /* Dark blue */ #1e40af 20%,
501
+ /* Muted dark blue */ #0c2a5d 30%,
502
+ /* Deep navy blue */ #082f49 40%,
503
+ /* Midnight blue */ var(--vp-c-brand) 60%
487
504
  );
488
505
  background-size: 150% 100%;
489
506
  -webkit-background-clip: text;
@@ -499,13 +516,13 @@ html:not(.dark) .transparency-link:not(.mouse-over) .link-text {
499
516
  }
500
517
 
501
518
  html:not(.dark) .support-section.mouse-over .support-title {
502
- text-shadow: 0 0 20px rgba(66, 139, 202, 0.2); /* Blue shadow */
519
+ text-shadow: 0 0 20px rgba(66, 139, 202, 0.2); /* Blue shadow */
503
520
  }
504
521
 
505
522
  html:not(.dark) .support-button--secondary:hover {
506
- border-color: rgba(66, 139, 202, 0.6); /* Blue border */
507
- box-shadow:
523
+ border-color: rgba(66, 139, 202, 0.6); /* Blue border */
524
+ box-shadow:
508
525
  0 0 20px rgba(66, 139, 202, 0.15),
509
526
  inset 0 0 20px rgba(66, 139, 202, 0.03);
510
527
  }
511
- </style>
528
+ </style>