@trishchuk/coolors-mcp 1.0.0 → 1.0.1
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/.claude/settings.local.json +2 -6
- package/.github/ISSUE_TEMPLATE/bug_report.md +20 -8
- package/.github/ISSUE_TEMPLATE/feature_request.md +22 -8
- package/.github/pull_request_template.md +33 -8
- package/.github/workflows/ci.yml +97 -97
- package/.github/workflows/deploy-docs.yml +9 -9
- package/.github/workflows/release.yml +15 -15
- package/README.md +26 -1
- package/TOOLS_UK.md +233 -0
- package/docs/.vitepress/cache/deps/@braintree_sanitize-url.js +30 -12
- package/docs/.vitepress/cache/deps/_metadata.json +1 -1
- package/docs/.vitepress/cache/deps/chunk-BUSYA2B4.js +9 -6
- package/docs/.vitepress/cache/deps/chunk-JD3CXNQ6.js +2543 -1612
- package/docs/.vitepress/cache/deps/chunk-SYPOPCWC.js +3508 -2529
- package/docs/.vitepress/cache/deps/cytoscape-cose-bilkent.js +1902 -1003
- package/docs/.vitepress/cache/deps/cytoscape.js +13303 -7347
- package/docs/.vitepress/cache/deps/dayjs.js +494 -272
- package/docs/.vitepress/cache/deps/debug.js +82 -38
- package/docs/.vitepress/cache/deps/prismjs.js +444 -272
- package/docs/.vitepress/cache/deps/prismjs_components_prism-bash.js +80 -73
- package/docs/.vitepress/cache/deps/prismjs_components_prism-javascript.js +93 -62
- package/docs/.vitepress/cache/deps/prismjs_components_prism-json.js +13 -13
- package/docs/.vitepress/cache/deps/prismjs_components_prism-python.js +34 -27
- package/docs/.vitepress/cache/deps/prismjs_components_prism-typescript.js +20 -17
- package/docs/.vitepress/cache/deps/prismjs_components_prism-yaml.js +75 -41
- package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +2005 -1438
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +2 -2
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js +566 -229
- package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js +382 -270
- package/docs/.vitepress/cache/deps/vitepress___minisearch.js +334 -125
- package/docs/.vitepress/cache/deps/vue.js +2 -2
- package/docs/.vitepress/components/ClientGrid.vue +9 -3
- package/docs/.vitepress/components/CodeBlock.vue +51 -44
- package/docs/.vitepress/components/ConfigModal.vue +151 -67
- package/docs/.vitepress/components/DiagramModal.vue +186 -154
- package/docs/.vitepress/components/TroubleshootingModal.vue +101 -96
- package/docs/.vitepress/config.js +171 -141
- package/docs/.vitepress/theme/FundingLayout.vue +65 -54
- package/docs/.vitepress/theme/Layout.vue +21 -21
- package/docs/.vitepress/theme/components/AdBanner.vue +73 -52
- package/docs/.vitepress/theme/components/AdPlaceholder.vue +3 -3
- package/docs/.vitepress/theme/components/FundingEffects.vue +77 -53
- package/docs/.vitepress/theme/components/FundingHero.vue +78 -63
- package/docs/.vitepress/theme/components/SupportSection.vue +106 -89
- package/docs/.vitepress/theme/custom-app.css +19 -12
- package/docs/.vitepress/theme/custom.css +33 -25
- package/docs/.vitepress/theme/index.js +19 -16
- package/docs/concepts/accessibility.md +59 -47
- package/docs/concepts/color-spaces.md +28 -6
- package/docs/concepts/distance-metrics.md +45 -30
- package/docs/concepts/hct.md +30 -27
- package/docs/concepts/image-analysis.md +52 -21
- package/docs/concepts/material-design.md +43 -17
- package/docs/concepts/theme-matching.md +64 -40
- package/docs/examples/basic-colors.md +92 -108
- package/docs/examples/creating-themes.md +104 -108
- package/docs/examples/css-refactoring.md +33 -29
- package/docs/examples/image-extraction.md +145 -138
- package/docs/getting-started.md +45 -34
- package/docs/index.md +5 -1
- package/docs/installation.md +15 -1
- package/docs/tools/accessibility.md +74 -68
- package/docs/tools/image-extraction.md +62 -54
- package/docs/tools/theme-matching.md +45 -42
- package/note.md +1 -2
- package/package.json +2 -2
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="funding-layout">
|
|
3
3
|
<transition name="fade">
|
|
4
|
-
<button
|
|
4
|
+
<button
|
|
5
5
|
v-if="showReturnButton"
|
|
6
6
|
@click="goBack"
|
|
7
7
|
class="return-button"
|
|
8
8
|
title="Return to previous page"
|
|
9
9
|
>
|
|
10
|
-
<svg
|
|
11
|
-
|
|
10
|
+
<svg
|
|
11
|
+
width="20"
|
|
12
|
+
height="20"
|
|
13
|
+
viewBox="0 0 24 24"
|
|
14
|
+
fill="none"
|
|
15
|
+
stroke="currentColor"
|
|
16
|
+
stroke-width="2"
|
|
17
|
+
>
|
|
18
|
+
<path d="M19 12H5M5 12L12 19M5 12L12 5" />
|
|
12
19
|
</svg>
|
|
13
20
|
<span>Return</span>
|
|
14
21
|
</button>
|
|
15
22
|
</transition>
|
|
16
|
-
|
|
23
|
+
|
|
17
24
|
<FundingHero />
|
|
18
|
-
|
|
19
|
-
<div
|
|
25
|
+
|
|
26
|
+
<div
|
|
20
27
|
class="funding-content"
|
|
21
28
|
@mouseenter="handleMouseEnter"
|
|
22
29
|
@mousemove="handleMouseMove"
|
|
@@ -25,75 +32,75 @@
|
|
|
25
32
|
>
|
|
26
33
|
<Content />
|
|
27
34
|
</div>
|
|
28
|
-
|
|
35
|
+
|
|
29
36
|
<FundingEffects />
|
|
30
37
|
</div>
|
|
31
38
|
</template>
|
|
32
39
|
|
|
33
40
|
<script setup>
|
|
34
|
-
import { ref, onMounted, onUnmounted } from
|
|
35
|
-
import { Content, useRouter } from
|
|
36
|
-
import FundingHero from
|
|
37
|
-
import FundingEffects from
|
|
41
|
+
import { ref, onMounted, onUnmounted } from "vue";
|
|
42
|
+
import { Content, useRouter } from "vitepress";
|
|
43
|
+
import FundingHero from "./components/FundingHero.vue";
|
|
44
|
+
import FundingEffects from "./components/FundingEffects.vue";
|
|
38
45
|
|
|
39
|
-
const contentRef = ref(null)
|
|
40
|
-
const showReturnButton = ref(false)
|
|
41
|
-
const router = useRouter()
|
|
46
|
+
const contentRef = ref(null);
|
|
47
|
+
const showReturnButton = ref(false);
|
|
48
|
+
const router = useRouter();
|
|
42
49
|
|
|
43
50
|
const goBack = () => {
|
|
44
51
|
if (window.history.length > 1) {
|
|
45
|
-
window.history.back()
|
|
52
|
+
window.history.back();
|
|
46
53
|
} else {
|
|
47
|
-
router.go(
|
|
54
|
+
router.go("/coolors-mcp/");
|
|
48
55
|
}
|
|
49
|
-
}
|
|
56
|
+
};
|
|
50
57
|
|
|
51
58
|
// Show return button after scroll
|
|
52
59
|
onMounted(() => {
|
|
53
60
|
const handleScroll = () => {
|
|
54
|
-
showReturnButton.value = window.scrollY > 100
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
window.addEventListener(
|
|
58
|
-
|
|
61
|
+
showReturnButton.value = window.scrollY > 100;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
window.addEventListener("scroll", handleScroll);
|
|
65
|
+
|
|
59
66
|
// Add page transition class
|
|
60
|
-
document.body.classList.add(
|
|
67
|
+
document.body.classList.add("page-transition-active");
|
|
61
68
|
setTimeout(() => {
|
|
62
|
-
document.body.classList.remove(
|
|
63
|
-
}, 600)
|
|
64
|
-
|
|
69
|
+
document.body.classList.remove("page-transition-active");
|
|
70
|
+
}, 600);
|
|
71
|
+
|
|
65
72
|
onUnmounted(() => {
|
|
66
|
-
window.removeEventListener(
|
|
67
|
-
})
|
|
68
|
-
})
|
|
73
|
+
window.removeEventListener("scroll", handleScroll);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
69
76
|
|
|
70
77
|
const handleMouseEnter = (e) => {
|
|
71
|
-
if (!contentRef.value) return
|
|
72
|
-
|
|
73
|
-
const rect = contentRef.value.getBoundingClientRect()
|
|
74
|
-
const x = e.clientX - rect.left
|
|
75
|
-
const y = e.clientY - rect.top
|
|
76
|
-
|
|
77
|
-
contentRef.value.style.setProperty(
|
|
78
|
-
contentRef.value.style.setProperty(
|
|
79
|
-
contentRef.value.classList.add(
|
|
80
|
-
}
|
|
78
|
+
if (!contentRef.value) return;
|
|
79
|
+
|
|
80
|
+
const rect = contentRef.value.getBoundingClientRect();
|
|
81
|
+
const x = e.clientX - rect.left;
|
|
82
|
+
const y = e.clientY - rect.top;
|
|
83
|
+
|
|
84
|
+
contentRef.value.style.setProperty("--content-mouse-x", `${x}px`);
|
|
85
|
+
contentRef.value.style.setProperty("--content-mouse-y", `${y}px`);
|
|
86
|
+
contentRef.value.classList.add("mouse-over");
|
|
87
|
+
};
|
|
81
88
|
|
|
82
89
|
const handleMouseMove = (e) => {
|
|
83
|
-
if (!contentRef.value) return
|
|
84
|
-
|
|
85
|
-
const rect = contentRef.value.getBoundingClientRect()
|
|
86
|
-
const x = e.clientX - rect.left
|
|
87
|
-
const y = e.clientY - rect.top
|
|
88
|
-
|
|
89
|
-
contentRef.value.style.setProperty(
|
|
90
|
-
contentRef.value.style.setProperty(
|
|
91
|
-
}
|
|
90
|
+
if (!contentRef.value) return;
|
|
91
|
+
|
|
92
|
+
const rect = contentRef.value.getBoundingClientRect();
|
|
93
|
+
const x = e.clientX - rect.left;
|
|
94
|
+
const y = e.clientY - rect.top;
|
|
95
|
+
|
|
96
|
+
contentRef.value.style.setProperty("--content-mouse-x", `${x}px`);
|
|
97
|
+
contentRef.value.style.setProperty("--content-mouse-y", `${y}px`);
|
|
98
|
+
};
|
|
92
99
|
|
|
93
100
|
const handleMouseLeave = () => {
|
|
94
|
-
if (!contentRef.value) return
|
|
95
|
-
contentRef.value.classList.remove(
|
|
96
|
-
}
|
|
101
|
+
if (!contentRef.value) return;
|
|
102
|
+
contentRef.value.classList.remove("mouse-over");
|
|
103
|
+
};
|
|
97
104
|
</script>
|
|
98
105
|
|
|
99
106
|
<style scoped>
|
|
@@ -169,7 +176,7 @@ const handleMouseLeave = () => {
|
|
|
169
176
|
}
|
|
170
177
|
|
|
171
178
|
.funding-content::before {
|
|
172
|
-
content:
|
|
179
|
+
content: "";
|
|
173
180
|
position: absolute;
|
|
174
181
|
top: 0;
|
|
175
182
|
left: -100px;
|
|
@@ -217,7 +224,11 @@ html:not(.dark) .funding-content::before {
|
|
|
217
224
|
margin: 64px 0 32px;
|
|
218
225
|
padding: 0 24px;
|
|
219
226
|
text-align: center;
|
|
220
|
-
background: linear-gradient(
|
|
227
|
+
background: linear-gradient(
|
|
228
|
+
135deg,
|
|
229
|
+
var(--vp-c-text-1) 0%,
|
|
230
|
+
var(--vp-c-brand) 100%
|
|
231
|
+
);
|
|
221
232
|
-webkit-background-clip: text;
|
|
222
233
|
background-clip: text;
|
|
223
234
|
-webkit-text-fill-color: transparent;
|
|
@@ -248,4 +259,4 @@ html:not(.dark) .funding-content::before {
|
|
|
248
259
|
.funding-layout strong {
|
|
249
260
|
color: var(--vp-c-text-1);
|
|
250
261
|
}
|
|
251
|
-
</style>
|
|
262
|
+
</style>
|
|
@@ -5,15 +5,13 @@
|
|
|
5
5
|
<span v-if="!isHomePage" class="replacement-title">Documentation</span>
|
|
6
6
|
</template>
|
|
7
7
|
<template #nav-bar-content-before>
|
|
8
|
-
<div class="nav-warning">
|
|
9
|
-
🏷️ <span>1.0.0</span>
|
|
10
|
-
</div>
|
|
8
|
+
<div class="nav-warning">🏷️ <span>1.0.0</span></div>
|
|
11
9
|
</template>
|
|
12
10
|
<template #sidebar-nav-after>
|
|
13
11
|
<!-- Sidebar ad placement - most non-intrusive -->
|
|
14
|
-
<AdBanner
|
|
12
|
+
<AdBanner
|
|
15
13
|
v-if="!isHomePage"
|
|
16
|
-
type="carbon"
|
|
14
|
+
type="carbon"
|
|
17
15
|
position="sidebar"
|
|
18
16
|
:dismissible="true"
|
|
19
17
|
:hide-on-paths="['/', '/getting-started']"
|
|
@@ -27,21 +25,23 @@
|
|
|
27
25
|
</template>
|
|
28
26
|
|
|
29
27
|
<script setup>
|
|
30
|
-
import { computed } from
|
|
31
|
-
import { useRoute, useData } from
|
|
32
|
-
import DefaultTheme from
|
|
33
|
-
import AdBanner from
|
|
34
|
-
import SupportSection from
|
|
35
|
-
import FundingHero from
|
|
36
|
-
import FundingEffects from
|
|
37
|
-
import FundingLayout from
|
|
38
|
-
|
|
39
|
-
const { Layout } = DefaultTheme
|
|
40
|
-
const route = useRoute()
|
|
41
|
-
const { frontmatter } = useData()
|
|
42
|
-
|
|
43
|
-
const isHomePage = computed(
|
|
44
|
-
|
|
28
|
+
import { computed } from "vue";
|
|
29
|
+
import { useRoute, useData } from "vitepress";
|
|
30
|
+
import DefaultTheme from "vitepress/theme";
|
|
31
|
+
import AdBanner from "./components/AdBanner.vue";
|
|
32
|
+
import SupportSection from "./components/SupportSection.vue";
|
|
33
|
+
import FundingHero from "./components/FundingHero.vue";
|
|
34
|
+
import FundingEffects from "./components/FundingEffects.vue";
|
|
35
|
+
import FundingLayout from "./FundingLayout.vue";
|
|
36
|
+
|
|
37
|
+
const { Layout } = DefaultTheme;
|
|
38
|
+
const route = useRoute();
|
|
39
|
+
const { frontmatter } = useData();
|
|
40
|
+
|
|
41
|
+
const isHomePage = computed(
|
|
42
|
+
() => route.path === "/" || route.path === "/coolors-mcp/",
|
|
43
|
+
);
|
|
44
|
+
const isFundingPage = computed(() => route.path.includes("/funding"));
|
|
45
45
|
</script>
|
|
46
46
|
|
|
47
47
|
<style>
|
|
@@ -131,4 +131,4 @@ html.dark .nav-warning {
|
|
|
131
131
|
display: none;
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
-
</style>
|
|
134
|
+
</style>
|
|
@@ -4,8 +4,15 @@
|
|
|
4
4
|
<div v-if="type === 'github-sponsors'" class="sponsor-banner">
|
|
5
5
|
<div class="sponsor-content">
|
|
6
6
|
<span class="sponsor-icon">💖</span>
|
|
7
|
-
<span class="sponsor-text"
|
|
8
|
-
|
|
7
|
+
<span class="sponsor-text"
|
|
8
|
+
>Support this project on GitHub Sponsors</span
|
|
9
|
+
>
|
|
10
|
+
<a
|
|
11
|
+
:href="githubSponsorsUrl"
|
|
12
|
+
target="_blank"
|
|
13
|
+
rel="noopener"
|
|
14
|
+
class="sponsor-button"
|
|
15
|
+
>
|
|
9
16
|
Sponsor
|
|
10
17
|
</a>
|
|
11
18
|
</div>
|
|
@@ -17,100 +24,106 @@
|
|
|
17
24
|
<!-- Carbon will inject content here -->
|
|
18
25
|
</div>
|
|
19
26
|
</div>
|
|
20
|
-
|
|
21
27
|
|
|
22
28
|
<!-- Dismissible close button -->
|
|
23
|
-
<button
|
|
29
|
+
<button
|
|
30
|
+
v-if="dismissible"
|
|
31
|
+
@click="dismissAd"
|
|
32
|
+
class="ad-close"
|
|
33
|
+
aria-label="Close ad"
|
|
34
|
+
>
|
|
24
35
|
×
|
|
25
36
|
</button>
|
|
26
37
|
</div>
|
|
27
38
|
</template>
|
|
28
39
|
|
|
29
40
|
<script setup>
|
|
30
|
-
import { ref, computed, onMounted } from
|
|
41
|
+
import { ref, computed, onMounted } from "vue";
|
|
31
42
|
|
|
32
43
|
const props = defineProps({
|
|
33
44
|
type: {
|
|
34
45
|
type: String,
|
|
35
|
-
default:
|
|
36
|
-
validator: (value) => [
|
|
46
|
+
default: "github-sponsors", // 'github-sponsors', 'carbon'
|
|
47
|
+
validator: (value) => ["github-sponsors", "carbon"].includes(value),
|
|
37
48
|
},
|
|
38
49
|
position: {
|
|
39
50
|
type: String,
|
|
40
|
-
default:
|
|
41
|
-
validator: (value) =>
|
|
51
|
+
default: "top", // 'top', 'bottom', 'sidebar', 'inline'
|
|
52
|
+
validator: (value) =>
|
|
53
|
+
["top", "bottom", "sidebar", "inline"].includes(value),
|
|
42
54
|
},
|
|
43
55
|
githubSponsorsUrl: {
|
|
44
56
|
type: String,
|
|
45
|
-
default:
|
|
57
|
+
default: "https://github.com/sponsors/jamubc",
|
|
46
58
|
},
|
|
47
59
|
dismissible: {
|
|
48
60
|
type: Boolean,
|
|
49
|
-
default: true
|
|
61
|
+
default: true,
|
|
50
62
|
},
|
|
51
63
|
showOnPaths: {
|
|
52
64
|
type: Array,
|
|
53
|
-
default: () => [] // Empty array means show on all paths
|
|
65
|
+
default: () => [], // Empty array means show on all paths
|
|
54
66
|
},
|
|
55
67
|
hideOnPaths: {
|
|
56
68
|
type: Array,
|
|
57
|
-
default: () => [
|
|
69
|
+
default: () => ["/"], // Hide on home page by default
|
|
58
70
|
},
|
|
59
|
-
})
|
|
71
|
+
});
|
|
60
72
|
|
|
61
|
-
const isDismissed = ref(false)
|
|
62
|
-
const storageKey = `ad-dismissed-${props.type}-${props.position}
|
|
73
|
+
const isDismissed = ref(false);
|
|
74
|
+
const storageKey = `ad-dismissed-${props.type}-${props.position}`;
|
|
63
75
|
|
|
64
|
-
const bannerClass = computed(() => `ad-banner--${props.position}`)
|
|
76
|
+
const bannerClass = computed(() => `ad-banner--${props.position}`);
|
|
65
77
|
|
|
66
78
|
const shouldShowAd = computed(() => {
|
|
67
|
-
if (isDismissed.value) return false
|
|
68
|
-
|
|
79
|
+
if (isDismissed.value) return false;
|
|
80
|
+
|
|
69
81
|
// Check if we're in browser environment
|
|
70
|
-
if (typeof window ===
|
|
71
|
-
|
|
72
|
-
const currentPath = window.location.pathname
|
|
73
|
-
|
|
82
|
+
if (typeof window === "undefined") return false;
|
|
83
|
+
|
|
84
|
+
const currentPath = window.location.pathname;
|
|
85
|
+
|
|
74
86
|
// If showOnPaths is specified, only show on those paths
|
|
75
87
|
if (props.showOnPaths.length > 0) {
|
|
76
|
-
return props.showOnPaths.some(path => currentPath.includes(path))
|
|
88
|
+
return props.showOnPaths.some((path) => currentPath.includes(path));
|
|
77
89
|
}
|
|
78
|
-
|
|
90
|
+
|
|
79
91
|
// If hideOnPaths is specified, hide on those paths
|
|
80
92
|
if (props.hideOnPaths.length > 0) {
|
|
81
|
-
return !props.hideOnPaths.some(path => currentPath.includes(path))
|
|
93
|
+
return !props.hideOnPaths.some((path) => currentPath.includes(path));
|
|
82
94
|
}
|
|
83
|
-
|
|
84
|
-
return true
|
|
85
|
-
})
|
|
95
|
+
|
|
96
|
+
return true;
|
|
97
|
+
});
|
|
86
98
|
|
|
87
99
|
const dismissAd = () => {
|
|
88
|
-
isDismissed.value = true
|
|
89
|
-
if (typeof localStorage !==
|
|
90
|
-
localStorage.setItem(storageKey,
|
|
100
|
+
isDismissed.value = true;
|
|
101
|
+
if (typeof localStorage !== "undefined") {
|
|
102
|
+
localStorage.setItem(storageKey, "true");
|
|
91
103
|
}
|
|
92
|
-
}
|
|
104
|
+
};
|
|
93
105
|
|
|
94
106
|
onMounted(() => {
|
|
95
107
|
// Check if ad was previously dismissed
|
|
96
|
-
if (typeof localStorage !==
|
|
97
|
-
const dismissed = localStorage.getItem(storageKey)
|
|
98
|
-
if (dismissed ===
|
|
99
|
-
isDismissed.value = true
|
|
108
|
+
if (typeof localStorage !== "undefined") {
|
|
109
|
+
const dismissed = localStorage.getItem(storageKey);
|
|
110
|
+
if (dismissed === "true") {
|
|
111
|
+
isDismissed.value = true;
|
|
100
112
|
}
|
|
101
113
|
}
|
|
102
|
-
|
|
114
|
+
|
|
103
115
|
// Load Carbon Ads script if needed
|
|
104
|
-
if (props.type ===
|
|
105
|
-
const script = document.createElement(
|
|
106
|
-
script.id =
|
|
107
|
-
script.async = true
|
|
108
|
-
script.type =
|
|
109
|
-
script.src =
|
|
110
|
-
|
|
111
|
-
|
|
116
|
+
if (props.type === "carbon" && !document.getElementById("carbon-script")) {
|
|
117
|
+
const script = document.createElement("script");
|
|
118
|
+
script.id = "carbon-script";
|
|
119
|
+
script.async = true;
|
|
120
|
+
script.type = "text/javascript";
|
|
121
|
+
script.src =
|
|
122
|
+
"//cdn.carbonads.com/carbon.js?serve=YOUR_CARBON_ID&placement=YOUR_PLACEMENT";
|
|
123
|
+
script.setAttribute("id", "_carbonads_js");
|
|
124
|
+
document.head.appendChild(script);
|
|
112
125
|
}
|
|
113
|
-
})
|
|
126
|
+
});
|
|
114
127
|
</script>
|
|
115
128
|
|
|
116
129
|
<style scoped>
|
|
@@ -164,7 +177,11 @@ onMounted(() => {
|
|
|
164
177
|
display: flex;
|
|
165
178
|
align-items: center;
|
|
166
179
|
justify-content: space-between;
|
|
167
|
-
background: linear-gradient(
|
|
180
|
+
background: linear-gradient(
|
|
181
|
+
135deg,
|
|
182
|
+
rgba(66, 184, 131, 0.1) 0%,
|
|
183
|
+
rgba(53, 73, 94, 0.1) 100%
|
|
184
|
+
);
|
|
168
185
|
}
|
|
169
186
|
|
|
170
187
|
.sponsor-content {
|
|
@@ -294,13 +311,13 @@ onMounted(() => {
|
|
|
294
311
|
max-width: none;
|
|
295
312
|
margin: 16px;
|
|
296
313
|
}
|
|
297
|
-
|
|
314
|
+
|
|
298
315
|
.sponsor-content {
|
|
299
316
|
flex-direction: column;
|
|
300
317
|
gap: 8px;
|
|
301
318
|
text-align: center;
|
|
302
319
|
}
|
|
303
|
-
|
|
320
|
+
|
|
304
321
|
.sponsor-text {
|
|
305
322
|
font-size: 13px;
|
|
306
323
|
}
|
|
@@ -312,6 +329,10 @@ html.dark .ad-banner--top {
|
|
|
312
329
|
}
|
|
313
330
|
|
|
314
331
|
html.dark .sponsor-banner {
|
|
315
|
-
background: linear-gradient(
|
|
332
|
+
background: linear-gradient(
|
|
333
|
+
135deg,
|
|
334
|
+
rgba(66, 184, 131, 0.15) 0%,
|
|
335
|
+
rgba(53, 73, 94, 0.15) 100%
|
|
336
|
+
);
|
|
316
337
|
}
|
|
317
|
-
</style>
|
|
338
|
+
</style>
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
</div>
|
|
11
11
|
</div>
|
|
12
|
-
<a
|
|
13
|
-
href="https://github.com/sponsors/jamubc"
|
|
12
|
+
<a
|
|
13
|
+
href="https://github.com/sponsors/jamubc"
|
|
14
14
|
class="placeholder-cta"
|
|
15
15
|
target="_blank"
|
|
16
16
|
rel="noopener"
|
|
@@ -75,4 +75,4 @@
|
|
|
75
75
|
.VPSidebar .ad-placeholder {
|
|
76
76
|
max-width: 250px;
|
|
77
77
|
}
|
|
78
|
-
</style>
|
|
78
|
+
</style>
|
|
@@ -5,43 +5,46 @@
|
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script setup>
|
|
8
|
-
import { onMounted } from
|
|
8
|
+
import { onMounted } from "vue";
|
|
9
9
|
|
|
10
10
|
onMounted(() => {
|
|
11
11
|
// Add intersection observer for scroll animations
|
|
12
|
-
const observer = new IntersectionObserver(
|
|
13
|
-
entries
|
|
14
|
-
|
|
15
|
-
entry.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
const observer = new IntersectionObserver(
|
|
13
|
+
(entries) => {
|
|
14
|
+
entries.forEach((entry) => {
|
|
15
|
+
if (entry.isIntersecting) {
|
|
16
|
+
entry.target.classList.add("visible");
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
},
|
|
20
|
+
{ threshold: 0.1 },
|
|
21
|
+
);
|
|
22
|
+
|
|
20
23
|
// Observe all cards
|
|
21
|
-
const cards = document.querySelectorAll(
|
|
22
|
-
cards.forEach(card => observer.observe(card))
|
|
23
|
-
|
|
24
|
+
const cards = document.querySelectorAll(".funding-card, .contribute-card");
|
|
25
|
+
cards.forEach((card) => observer.observe(card));
|
|
26
|
+
|
|
24
27
|
// Add hover effects to cards
|
|
25
|
-
cards.forEach(card => {
|
|
26
|
-
card.addEventListener(
|
|
27
|
-
const rect = card.getBoundingClientRect()
|
|
28
|
-
const x = e.clientX - rect.left
|
|
29
|
-
const y = e.clientY - rect.top
|
|
30
|
-
|
|
31
|
-
card.style.setProperty(
|
|
32
|
-
card.style.setProperty(
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
card.addEventListener(
|
|
36
|
-
const rect = card.getBoundingClientRect()
|
|
37
|
-
const x = e.clientX - rect.left
|
|
38
|
-
const y = e.clientY - rect.top
|
|
39
|
-
|
|
40
|
-
card.style.setProperty(
|
|
41
|
-
card.style.setProperty(
|
|
42
|
-
})
|
|
43
|
-
})
|
|
44
|
-
})
|
|
28
|
+
cards.forEach((card) => {
|
|
29
|
+
card.addEventListener("mouseenter", (e) => {
|
|
30
|
+
const rect = card.getBoundingClientRect();
|
|
31
|
+
const x = e.clientX - rect.left;
|
|
32
|
+
const y = e.clientY - rect.top;
|
|
33
|
+
|
|
34
|
+
card.style.setProperty("--card-mouse-x", `${x}px`);
|
|
35
|
+
card.style.setProperty("--card-mouse-y", `${y}px`);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
card.addEventListener("mousemove", (e) => {
|
|
39
|
+
const rect = card.getBoundingClientRect();
|
|
40
|
+
const x = e.clientX - rect.left;
|
|
41
|
+
const y = e.clientY - rect.top;
|
|
42
|
+
|
|
43
|
+
card.style.setProperty("--card-mouse-x", `${x}px`);
|
|
44
|
+
card.style.setProperty("--card-mouse-y", `${y}px`);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
|
45
48
|
</script>
|
|
46
49
|
|
|
47
50
|
<style>
|
|
@@ -67,7 +70,7 @@ onMounted(() => {
|
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
.funding-card::before {
|
|
70
|
-
content:
|
|
73
|
+
content: "";
|
|
71
74
|
position: absolute;
|
|
72
75
|
top: 0;
|
|
73
76
|
left: 0;
|
|
@@ -123,7 +126,7 @@ onMounted(() => {
|
|
|
123
126
|
.support-button--primary:hover {
|
|
124
127
|
background: var(--vp-c-brand-dark);
|
|
125
128
|
transform: translateY(-2px);
|
|
126
|
-
box-shadow:
|
|
129
|
+
box-shadow:
|
|
127
130
|
0 4px 12px rgba(66, 184, 131, 0.3),
|
|
128
131
|
0 0 20px rgba(218, 119, 86, 0.4),
|
|
129
132
|
0 0 30px rgba(71, 150, 227, 0.3),
|
|
@@ -132,15 +135,16 @@ onMounted(() => {
|
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
@keyframes glow {
|
|
135
|
-
0%,
|
|
136
|
-
|
|
138
|
+
0%,
|
|
139
|
+
100% {
|
|
140
|
+
box-shadow:
|
|
137
141
|
0 4px 12px rgba(66, 184, 131, 0.3),
|
|
138
142
|
0 0 20px rgba(218, 119, 86, 0.4),
|
|
139
143
|
0 0 30px rgba(71, 150, 227, 0.3),
|
|
140
144
|
0 0 40px rgba(255, 140, 0, 0.2);
|
|
141
145
|
}
|
|
142
|
-
50% {
|
|
143
|
-
box-shadow:
|
|
146
|
+
50% {
|
|
147
|
+
box-shadow:
|
|
144
148
|
0 4px 16px rgba(66, 184, 131, 0.4),
|
|
145
149
|
0 0 25px rgba(218, 119, 86, 0.5),
|
|
146
150
|
0 0 35px rgba(71, 150, 227, 0.4),
|
|
@@ -188,7 +192,7 @@ onMounted(() => {
|
|
|
188
192
|
}
|
|
189
193
|
|
|
190
194
|
.contribute-card::before {
|
|
191
|
-
content:
|
|
195
|
+
content: "";
|
|
192
196
|
position: absolute;
|
|
193
197
|
top: 0;
|
|
194
198
|
left: 0;
|
|
@@ -248,7 +252,7 @@ onMounted(() => {
|
|
|
248
252
|
}
|
|
249
253
|
|
|
250
254
|
.progress-fill::after {
|
|
251
|
-
content:
|
|
255
|
+
content: "";
|
|
252
256
|
position: absolute;
|
|
253
257
|
top: 0;
|
|
254
258
|
left: 0;
|
|
@@ -264,12 +268,18 @@ onMounted(() => {
|
|
|
264
268
|
}
|
|
265
269
|
|
|
266
270
|
@keyframes progress {
|
|
267
|
-
from {
|
|
271
|
+
from {
|
|
272
|
+
width: 0;
|
|
273
|
+
}
|
|
268
274
|
}
|
|
269
275
|
|
|
270
276
|
@keyframes shimmer-progress {
|
|
271
|
-
0% {
|
|
272
|
-
|
|
277
|
+
0% {
|
|
278
|
+
transform: translateX(-100%);
|
|
279
|
+
}
|
|
280
|
+
100% {
|
|
281
|
+
transform: translateX(100%);
|
|
282
|
+
}
|
|
273
283
|
}
|
|
274
284
|
|
|
275
285
|
/* Light mode adjustments */
|
|
@@ -301,7 +311,7 @@ html:not(.dark) .contribute-card:hover {
|
|
|
301
311
|
|
|
302
312
|
html:not(.dark) .support-button-secondary:hover {
|
|
303
313
|
border-color: rgba(66, 139, 202, 0.6);
|
|
304
|
-
box-shadow:
|
|
314
|
+
box-shadow:
|
|
305
315
|
0 0 30px rgba(66, 139, 202, 0.1),
|
|
306
316
|
inset 0 0 20px rgba(66, 139, 202, 0.03);
|
|
307
317
|
}
|
|
@@ -311,12 +321,26 @@ html:not(.dark) .progress-fill {
|
|
|
311
321
|
}
|
|
312
322
|
|
|
313
323
|
/* Stagger animations */
|
|
314
|
-
.funding-card:nth-child(1) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
.
|
|
321
|
-
|
|
322
|
-
|
|
324
|
+
.funding-card:nth-child(1) {
|
|
325
|
+
transition-delay: 0.1s;
|
|
326
|
+
}
|
|
327
|
+
.funding-card:nth-child(2) {
|
|
328
|
+
transition-delay: 0.2s;
|
|
329
|
+
}
|
|
330
|
+
.funding-card:nth-child(3) {
|
|
331
|
+
transition-delay: 0.3s;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.contribute-card:nth-child(1) {
|
|
335
|
+
transition-delay: 0.1s;
|
|
336
|
+
}
|
|
337
|
+
.contribute-card:nth-child(2) {
|
|
338
|
+
transition-delay: 0.2s;
|
|
339
|
+
}
|
|
340
|
+
.contribute-card:nth-child(3) {
|
|
341
|
+
transition-delay: 0.3s;
|
|
342
|
+
}
|
|
343
|
+
.contribute-card:nth-child(4) {
|
|
344
|
+
transition-delay: 0.4s;
|
|
345
|
+
}
|
|
346
|
+
</style>
|