@farming-labs/nuxt-theme 0.0.50 → 0.0.52
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/package.json +2 -2
- package/src/components/DocsContent.vue +112 -0
- package/src/components/DocsPage.vue +94 -0
- package/src/themes/colorful.js +1 -0
- package/src/themes/darksharp.js +1 -0
- package/src/themes/default.js +1 -0
- package/src/themes/greentree.js +1 -0
- package/src/themes/pixel-border.js +3 -1
- package/styles/docs.css +238 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farming-labs/nuxt-theme",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.52",
|
|
4
4
|
"description": "Nuxt/Vue UI components for @farming-labs/docs — layout, sidebar, TOC, search, and theme toggle",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"docs",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"sugar-high": "^0.9.5",
|
|
63
|
-
"@farming-labs/docs": "0.0.
|
|
63
|
+
"@farming-labs/docs": "0.0.52"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"nuxt": ">=3.0.0",
|
|
@@ -20,6 +20,7 @@ const props = defineProps<{
|
|
|
20
20
|
editOnGithub?: string;
|
|
21
21
|
lastModified?: string;
|
|
22
22
|
entry?: string;
|
|
23
|
+
slug?: string;
|
|
23
24
|
locale?: string;
|
|
24
25
|
};
|
|
25
26
|
config?: Record<string, unknown> | null;
|
|
@@ -29,6 +30,7 @@ const route = useRoute();
|
|
|
29
30
|
const openDropdownMenu = ref(false);
|
|
30
31
|
const copyLabel = ref("Copy page");
|
|
31
32
|
const copied = ref(false);
|
|
33
|
+
const selectedFeedback = ref<"positive" | "negative" | null>(null);
|
|
32
34
|
|
|
33
35
|
const titleSuffix = computed(() =>
|
|
34
36
|
props.config?.metadata?.titleTemplate
|
|
@@ -145,6 +147,35 @@ const showPageActions = computed(
|
|
|
145
147
|
);
|
|
146
148
|
const showActionsAbove = computed(() => pageActionsPosition.value === "above-title" && showPageActions.value);
|
|
147
149
|
const showActionsBelow = computed(() => pageActionsPosition.value === "below-title" && showPageActions.value);
|
|
150
|
+
const feedbackConfig = computed(() => {
|
|
151
|
+
const defaults = {
|
|
152
|
+
enabled: false,
|
|
153
|
+
question: "How is this guide?",
|
|
154
|
+
positiveLabel: "Good",
|
|
155
|
+
negativeLabel: "Bad",
|
|
156
|
+
onFeedback: undefined as ((payload: Record<string, unknown>) => void) | undefined,
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const feedback = props.config?.feedback as Record<string, unknown> | boolean | null | undefined;
|
|
160
|
+
if (feedback === undefined || feedback === false) return defaults;
|
|
161
|
+
if (feedback === true) return { ...defaults, enabled: true };
|
|
162
|
+
if (typeof feedback !== "object" || feedback === null) return defaults;
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
enabled: feedback.enabled !== false,
|
|
166
|
+
question: String((feedback as { question?: string }).question ?? defaults.question),
|
|
167
|
+
positiveLabel: String(
|
|
168
|
+
feedback.positiveLabel ?? defaults.positiveLabel,
|
|
169
|
+
),
|
|
170
|
+
negativeLabel: String(
|
|
171
|
+
feedback.negativeLabel ?? defaults.negativeLabel,
|
|
172
|
+
),
|
|
173
|
+
onFeedback:
|
|
174
|
+
typeof feedback.onFeedback === "function"
|
|
175
|
+
? (feedback.onFeedback as (payload: Record<string, unknown>) => void)
|
|
176
|
+
: undefined,
|
|
177
|
+
};
|
|
178
|
+
});
|
|
148
179
|
|
|
149
180
|
useHead({
|
|
150
181
|
title: () => `${props.data.title}${titleSuffix.value}`,
|
|
@@ -201,6 +232,43 @@ function openInProvider(provider: { name: string; urlTemplate: string }) {
|
|
|
201
232
|
closeDropdown();
|
|
202
233
|
}
|
|
203
234
|
|
|
235
|
+
function handleFeedback(value: "positive" | "negative") {
|
|
236
|
+
selectedFeedback.value = value;
|
|
237
|
+
|
|
238
|
+
const pathname =
|
|
239
|
+
typeof window !== "undefined"
|
|
240
|
+
? window.location.pathname.replace(/\/$/, "") || "/"
|
|
241
|
+
: props.data.slug
|
|
242
|
+
? `/${entry.value}/${props.data.slug}`
|
|
243
|
+
: `/${entry.value}`;
|
|
244
|
+
|
|
245
|
+
const payload = {
|
|
246
|
+
value,
|
|
247
|
+
title: props.data.title,
|
|
248
|
+
description: props.data.description,
|
|
249
|
+
url: typeof window !== "undefined" ? window.location.href : pathname,
|
|
250
|
+
pathname,
|
|
251
|
+
path: pathname,
|
|
252
|
+
entry: entry.value,
|
|
253
|
+
slug: props.data.slug ?? "",
|
|
254
|
+
locale: props.data.locale,
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
try {
|
|
258
|
+
feedbackConfig.value.onFeedback?.(payload);
|
|
259
|
+
} catch {}
|
|
260
|
+
|
|
261
|
+
try {
|
|
262
|
+
if (typeof window !== "undefined" && (window as any).__fdOnFeedback__) {
|
|
263
|
+
(window as any).__fdOnFeedback__(payload);
|
|
264
|
+
}
|
|
265
|
+
} catch {}
|
|
266
|
+
|
|
267
|
+
if (typeof window !== "undefined") {
|
|
268
|
+
window.dispatchEvent(new CustomEvent("fd:feedback", { detail: payload }));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
204
272
|
function handleClickOutside(e: MouseEvent) {
|
|
205
273
|
const target = e.target as Node;
|
|
206
274
|
if (openDropdownMenu.value && !(target as Element).closest?.(".fd-page-action-dropdown")) {
|
|
@@ -354,5 +422,49 @@ onUnmounted(() => {
|
|
|
354
422
|
</template>
|
|
355
423
|
|
|
356
424
|
<div v-html="htmlWithoutFirstH1" />
|
|
425
|
+
|
|
426
|
+
<section v-if="feedbackConfig.enabled" class="fd-feedback" aria-label="Page feedback">
|
|
427
|
+
<div class="fd-feedback-content">
|
|
428
|
+
<p class="fd-feedback-question">{{ feedbackConfig.question }}</p>
|
|
429
|
+
<div class="fd-feedback-actions" role="group" :aria-label="feedbackConfig.question">
|
|
430
|
+
<button
|
|
431
|
+
type="button"
|
|
432
|
+
class="fd-page-action-btn"
|
|
433
|
+
:aria-pressed="selectedFeedback === 'positive'"
|
|
434
|
+
:data-selected="selectedFeedback === 'positive' ? 'true' : undefined"
|
|
435
|
+
@click="handleFeedback('positive')"
|
|
436
|
+
>
|
|
437
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
438
|
+
<path
|
|
439
|
+
d="M7 21H5a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h2m0 11V10m0 11h9.28a2 2 0 0 0 1.97-1.66l1.2-7A2 2 0 0 0 17.48 10H13V6.5a2.5 2.5 0 0 0-2.5-2.5L7 10"
|
|
440
|
+
stroke="currentColor"
|
|
441
|
+
stroke-width="2"
|
|
442
|
+
stroke-linecap="round"
|
|
443
|
+
stroke-linejoin="round"
|
|
444
|
+
/>
|
|
445
|
+
</svg>
|
|
446
|
+
<span>{{ feedbackConfig.positiveLabel }}</span>
|
|
447
|
+
</button>
|
|
448
|
+
<button
|
|
449
|
+
type="button"
|
|
450
|
+
class="fd-page-action-btn"
|
|
451
|
+
:aria-pressed="selectedFeedback === 'negative'"
|
|
452
|
+
:data-selected="selectedFeedback === 'negative' ? 'true' : undefined"
|
|
453
|
+
@click="handleFeedback('negative')"
|
|
454
|
+
>
|
|
455
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
456
|
+
<path
|
|
457
|
+
d="M17 3h2a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-2M17 3v11m0-11H7.72a2 2 0 0 0-1.97 1.66l-1.2 7A2 2 0 0 0 6.52 14H11v3.5a2.5 2.5 0 0 0 2.5 2.5L17 14"
|
|
458
|
+
stroke="currentColor"
|
|
459
|
+
stroke-width="2"
|
|
460
|
+
stroke-linecap="round"
|
|
461
|
+
stroke-linejoin="round"
|
|
462
|
+
/>
|
|
463
|
+
</svg>
|
|
464
|
+
<span>{{ feedbackConfig.negativeLabel }}</span>
|
|
465
|
+
</button>
|
|
466
|
+
</div>
|
|
467
|
+
</div>
|
|
468
|
+
</section>
|
|
357
469
|
</DocsPage>
|
|
358
470
|
</template>
|
|
@@ -70,6 +70,24 @@ function scanHeadings() {
|
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
function setHoverLinkOpen(root: HTMLElement, open: boolean) {
|
|
74
|
+
const trigger = root.querySelector(".fd-hover-link-trigger");
|
|
75
|
+
const popover = root.querySelector(".fd-hover-link-popover");
|
|
76
|
+
if (!(trigger instanceof HTMLElement) || !(popover instanceof HTMLElement)) return;
|
|
77
|
+
|
|
78
|
+
root.classList.toggle("fd-hover-link-open", open);
|
|
79
|
+
trigger.setAttribute("aria-expanded", String(open));
|
|
80
|
+
popover.setAttribute("aria-hidden", String(!open));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function closeOpenHoverLinks(event: Event) {
|
|
84
|
+
document.querySelectorAll("[data-hover-link].fd-hover-link-open").forEach((root) => {
|
|
85
|
+
if (!(root instanceof HTMLElement)) return;
|
|
86
|
+
if (event.target instanceof Node && root.contains(event.target)) return;
|
|
87
|
+
setHoverLinkOpen(root, false);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
73
91
|
function wireInteractive() {
|
|
74
92
|
requestAnimationFrame(() => {
|
|
75
93
|
document.querySelectorAll(".fd-copy-btn").forEach((btn) => {
|
|
@@ -122,6 +140,82 @@ function wireInteractive() {
|
|
|
122
140
|
const localized = withLang(href);
|
|
123
141
|
if (localized) link.setAttribute("href", localized);
|
|
124
142
|
});
|
|
143
|
+
|
|
144
|
+
document.querySelectorAll("[data-hover-link]").forEach((root) => {
|
|
145
|
+
if (!(root instanceof HTMLElement)) return;
|
|
146
|
+
if (root.dataset.fdHoverLinkBound === "true") return;
|
|
147
|
+
root.dataset.fdHoverLinkBound = "true";
|
|
148
|
+
|
|
149
|
+
const trigger = root.querySelector(".fd-hover-link-trigger");
|
|
150
|
+
const popover = root.querySelector(".fd-hover-link-popover");
|
|
151
|
+
if (!(trigger instanceof HTMLElement) || !(popover instanceof HTMLElement)) return;
|
|
152
|
+
|
|
153
|
+
let closeTimer = 0;
|
|
154
|
+
const containsTarget = (target: EventTarget | null) => target instanceof Node && root.contains(target);
|
|
155
|
+
const clearCloseTimer = () => {
|
|
156
|
+
if (closeTimer !== 0) {
|
|
157
|
+
window.clearTimeout(closeTimer);
|
|
158
|
+
closeTimer = 0;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const openPopover = () => {
|
|
163
|
+
clearCloseTimer();
|
|
164
|
+
setHoverLinkOpen(root, true);
|
|
165
|
+
};
|
|
166
|
+
const closePopover = () => {
|
|
167
|
+
clearCloseTimer();
|
|
168
|
+
setHoverLinkOpen(root, false);
|
|
169
|
+
};
|
|
170
|
+
const closePopoverSoon = () => {
|
|
171
|
+
clearCloseTimer();
|
|
172
|
+
closeTimer = window.setTimeout(closePopover, 90);
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
trigger.addEventListener("pointerenter", openPopover);
|
|
176
|
+
trigger.addEventListener("pointerleave", (event) => {
|
|
177
|
+
if (containsTarget(event.relatedTarget)) return;
|
|
178
|
+
closePopoverSoon();
|
|
179
|
+
});
|
|
180
|
+
trigger.addEventListener("focus", (event) => {
|
|
181
|
+
if (!(event.currentTarget instanceof HTMLElement)) return;
|
|
182
|
+
if (typeof event.currentTarget.matches === "function" && !event.currentTarget.matches(":focus-visible")) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
openPopover();
|
|
186
|
+
});
|
|
187
|
+
trigger.addEventListener("blur", (event) => {
|
|
188
|
+
if (containsTarget(event.relatedTarget)) return;
|
|
189
|
+
closePopoverSoon();
|
|
190
|
+
});
|
|
191
|
+
trigger.addEventListener("click", (event) => {
|
|
192
|
+
event.preventDefault();
|
|
193
|
+
openPopover();
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
popover.addEventListener("pointerenter", openPopover);
|
|
197
|
+
popover.addEventListener("pointerleave", (event) => {
|
|
198
|
+
if (containsTarget(event.relatedTarget)) return;
|
|
199
|
+
closePopoverSoon();
|
|
200
|
+
});
|
|
201
|
+
popover.addEventListener("focusin", openPopover);
|
|
202
|
+
popover.addEventListener("focusout", (event) => {
|
|
203
|
+
if (containsTarget(event.relatedTarget)) return;
|
|
204
|
+
closePopoverSoon();
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
root.addEventListener("keydown", (event) => {
|
|
208
|
+
if (event.key !== "Escape") return;
|
|
209
|
+
closePopover();
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
if (document.documentElement.dataset.fdHoverLinkGlobalBound !== "true") {
|
|
214
|
+
document.documentElement.dataset.fdHoverLinkGlobalBound = "true";
|
|
215
|
+
|
|
216
|
+
document.addEventListener("pointerdown", closeOpenHoverLinks);
|
|
217
|
+
document.addEventListener("focusin", closeOpenHoverLinks);
|
|
218
|
+
}
|
|
125
219
|
});
|
|
126
220
|
}
|
|
127
221
|
|
package/src/themes/colorful.js
CHANGED
package/src/themes/darksharp.js
CHANGED
package/src/themes/default.js
CHANGED
package/src/themes/greentree.js
CHANGED
|
@@ -27,7 +27,9 @@ const PixelBorderUIDefaults = {
|
|
|
27
27
|
toc: { enabled: true, depth: 3 },
|
|
28
28
|
header: { height: 56, sticky: true },
|
|
29
29
|
},
|
|
30
|
-
components: {
|
|
30
|
+
components: {
|
|
31
|
+
HoverLink: { linkLabel: "Open page", showIndicator: false },
|
|
32
|
+
},
|
|
31
33
|
};
|
|
32
34
|
|
|
33
35
|
export const pixelBorder = createTheme({
|
package/styles/docs.css
CHANGED
|
@@ -649,10 +649,19 @@ samp {
|
|
|
649
649
|
color: var(--color-fd-foreground);
|
|
650
650
|
}
|
|
651
651
|
|
|
652
|
+
.fd-page-action-btn[data-selected="true"] {
|
|
653
|
+
color: var(--color-fd-accent-foreground);
|
|
654
|
+
background: var(--color-fd-accent);
|
|
655
|
+
}
|
|
656
|
+
|
|
652
657
|
.fd-page-action-btn svg {
|
|
653
658
|
flex-shrink: 0;
|
|
654
659
|
}
|
|
655
660
|
|
|
661
|
+
.fd-page-action-btn[data-selected="true"] svg {
|
|
662
|
+
color: currentColor;
|
|
663
|
+
}
|
|
664
|
+
|
|
656
665
|
.fd-page-action-dropdown {
|
|
657
666
|
position: relative;
|
|
658
667
|
}
|
|
@@ -720,6 +729,35 @@ samp {
|
|
|
720
729
|
margin-bottom: 1rem;
|
|
721
730
|
}
|
|
722
731
|
|
|
732
|
+
.fd-feedback {
|
|
733
|
+
margin-top: 2rem;
|
|
734
|
+
padding-top: 1.25rem;
|
|
735
|
+
border-top: 1px solid var(--color-fd-border);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.fd-feedback-content {
|
|
739
|
+
display: flex;
|
|
740
|
+
align-items: center;
|
|
741
|
+
justify-content: space-between;
|
|
742
|
+
gap: 1rem;
|
|
743
|
+
flex-wrap: wrap;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
.fd-feedback-question {
|
|
747
|
+
margin: 0;
|
|
748
|
+
font-size: 0.9375rem;
|
|
749
|
+
font-weight: 600;
|
|
750
|
+
line-height: 1.5;
|
|
751
|
+
color: var(--color-fd-foreground);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
.fd-feedback-actions {
|
|
755
|
+
display: inline-flex;
|
|
756
|
+
align-items: center;
|
|
757
|
+
gap: 0.5rem;
|
|
758
|
+
flex-wrap: wrap;
|
|
759
|
+
}
|
|
760
|
+
|
|
723
761
|
/* ─── Breadcrumb ─────────────────────────────────────────────────────── */
|
|
724
762
|
|
|
725
763
|
.fd-breadcrumb {
|
|
@@ -919,6 +957,206 @@ samp {
|
|
|
919
957
|
opacity: 0.8;
|
|
920
958
|
}
|
|
921
959
|
|
|
960
|
+
.fd-hover-link {
|
|
961
|
+
position: relative;
|
|
962
|
+
display: inline-block;
|
|
963
|
+
vertical-align: baseline;
|
|
964
|
+
max-width: 100%;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
.fd-hover-link-trigger {
|
|
968
|
+
display: inline !important;
|
|
969
|
+
border: none;
|
|
970
|
+
background: transparent;
|
|
971
|
+
padding: 0;
|
|
972
|
+
margin: 0;
|
|
973
|
+
color: var(--color-fd-foreground);
|
|
974
|
+
cursor: pointer;
|
|
975
|
+
text-decoration: underline;
|
|
976
|
+
text-decoration-style: dashed;
|
|
977
|
+
text-decoration-thickness: 0.08em;
|
|
978
|
+
text-underline-offset: 0.22em;
|
|
979
|
+
text-decoration-color: color-mix(in srgb, var(--color-fd-foreground) 46%, transparent);
|
|
980
|
+
font: inherit;
|
|
981
|
+
line-height: inherit;
|
|
982
|
+
vertical-align: baseline;
|
|
983
|
+
appearance: none;
|
|
984
|
+
transition: text-decoration-color 180ms ease, opacity 180ms ease;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
.fd-hover-link-trigger:hover,
|
|
988
|
+
.fd-hover-link-trigger:focus-visible,
|
|
989
|
+
.fd-hover-link-open > .fd-hover-link-trigger {
|
|
990
|
+
text-decoration-color: color-mix(in srgb, var(--color-fd-foreground) 68%, transparent);
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
.fd-hover-link-trigger:focus-visible {
|
|
994
|
+
outline: none;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
.fd-hover-link-popover {
|
|
998
|
+
--fd-hover-link-rest-x: -50%;
|
|
999
|
+
--fd-hover-link-rest-y: 8px;
|
|
1000
|
+
--fd-hover-link-open-x: -50%;
|
|
1001
|
+
--fd-hover-link-open-y: 0;
|
|
1002
|
+
position: absolute;
|
|
1003
|
+
top: calc(100% + var(--fd-hover-link-side-offset, 12px));
|
|
1004
|
+
left: 50%;
|
|
1005
|
+
z-index: 40;
|
|
1006
|
+
width: min(22rem, calc(100vw - 2rem));
|
|
1007
|
+
max-width: min(22rem, calc(100vw - 2rem));
|
|
1008
|
+
opacity: 0;
|
|
1009
|
+
visibility: hidden;
|
|
1010
|
+
pointer-events: none;
|
|
1011
|
+
transform: translate3d(var(--fd-hover-link-rest-x), var(--fd-hover-link-rest-y), 0);
|
|
1012
|
+
transition: opacity 180ms ease, transform 180ms ease, visibility 180ms linear;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
.fd-hover-link[data-align="start"] > .fd-hover-link-popover {
|
|
1016
|
+
left: 0;
|
|
1017
|
+
--fd-hover-link-rest-x: 0;
|
|
1018
|
+
--fd-hover-link-open-x: 0;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
.fd-hover-link[data-align="end"] > .fd-hover-link-popover {
|
|
1022
|
+
left: auto;
|
|
1023
|
+
right: 0;
|
|
1024
|
+
--fd-hover-link-rest-x: 0;
|
|
1025
|
+
--fd-hover-link-open-x: 0;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
.fd-hover-link[data-side="top"] > .fd-hover-link-popover {
|
|
1029
|
+
top: auto;
|
|
1030
|
+
bottom: calc(100% + var(--fd-hover-link-side-offset, 12px));
|
|
1031
|
+
--fd-hover-link-rest-y: -8px;
|
|
1032
|
+
--fd-hover-link-open-y: 0;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
.fd-hover-link[data-side="right"] > .fd-hover-link-popover {
|
|
1036
|
+
top: 50%;
|
|
1037
|
+
left: calc(100% + var(--fd-hover-link-side-offset, 12px));
|
|
1038
|
+
right: auto;
|
|
1039
|
+
--fd-hover-link-rest-x: 8px;
|
|
1040
|
+
--fd-hover-link-rest-y: -50%;
|
|
1041
|
+
--fd-hover-link-open-x: 0;
|
|
1042
|
+
--fd-hover-link-open-y: -50%;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
.fd-hover-link[data-side="right"][data-align="start"] > .fd-hover-link-popover {
|
|
1046
|
+
top: 0;
|
|
1047
|
+
--fd-hover-link-rest-y: 0;
|
|
1048
|
+
--fd-hover-link-open-y: 0;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
.fd-hover-link[data-side="right"][data-align="end"] > .fd-hover-link-popover {
|
|
1052
|
+
top: auto;
|
|
1053
|
+
bottom: 0;
|
|
1054
|
+
--fd-hover-link-rest-y: 0;
|
|
1055
|
+
--fd-hover-link-open-y: 0;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
.fd-hover-link[data-side="left"] > .fd-hover-link-popover {
|
|
1059
|
+
top: 50%;
|
|
1060
|
+
left: auto;
|
|
1061
|
+
right: calc(100% + var(--fd-hover-link-side-offset, 12px));
|
|
1062
|
+
--fd-hover-link-rest-x: -8px;
|
|
1063
|
+
--fd-hover-link-rest-y: -50%;
|
|
1064
|
+
--fd-hover-link-open-x: 0;
|
|
1065
|
+
--fd-hover-link-open-y: -50%;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
.fd-hover-link[data-side="left"][data-align="start"] > .fd-hover-link-popover {
|
|
1069
|
+
top: 0;
|
|
1070
|
+
--fd-hover-link-rest-y: 0;
|
|
1071
|
+
--fd-hover-link-open-y: 0;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
.fd-hover-link[data-side="left"][data-align="end"] > .fd-hover-link-popover {
|
|
1075
|
+
top: auto;
|
|
1076
|
+
bottom: 0;
|
|
1077
|
+
--fd-hover-link-rest-y: 0;
|
|
1078
|
+
--fd-hover-link-open-y: 0;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
.fd-hover-link-open > .fd-hover-link-popover {
|
|
1082
|
+
opacity: 1;
|
|
1083
|
+
visibility: visible;
|
|
1084
|
+
pointer-events: auto;
|
|
1085
|
+
transform: translate3d(var(--fd-hover-link-open-x), var(--fd-hover-link-open-y), 0);
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
.fd-hover-link-card {
|
|
1089
|
+
display: flex;
|
|
1090
|
+
flex-direction: column;
|
|
1091
|
+
gap: 0.75rem;
|
|
1092
|
+
width: 100%;
|
|
1093
|
+
border-radius: calc(var(--radius, 0.75rem) + 2px);
|
|
1094
|
+
border: 1px solid color-mix(in srgb, var(--color-fd-border) 88%, transparent);
|
|
1095
|
+
background: var(--color-fd-popover, var(--color-fd-background));
|
|
1096
|
+
color: var(--color-fd-popover-foreground, var(--color-fd-foreground));
|
|
1097
|
+
padding: 0.95rem 1rem;
|
|
1098
|
+
box-shadow: 0 20px 45px color-mix(in srgb, var(--color-fd-background) 78%, transparent);
|
|
1099
|
+
backdrop-filter: blur(14px);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
.fd-hover-link-body {
|
|
1103
|
+
display: flex;
|
|
1104
|
+
flex-direction: column;
|
|
1105
|
+
gap: 0.35rem;
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
.fd-hover-link-preview-label {
|
|
1109
|
+
font-size: 0.68rem;
|
|
1110
|
+
text-transform: uppercase;
|
|
1111
|
+
letter-spacing: 0.1em;
|
|
1112
|
+
font-family: var(--fd-font-mono, var(--font-geist-mono, ui-monospace, monospace));
|
|
1113
|
+
color: color-mix(in srgb, var(--color-fd-popover-foreground, var(--color-fd-foreground)) 55%, transparent);
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
.fd-hover-link-title,
|
|
1117
|
+
.fd-hover-link-cta {
|
|
1118
|
+
text-decoration: none !important;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
.fd-hover-link-title {
|
|
1122
|
+
color: var(--color-fd-popover-foreground, var(--color-fd-foreground));
|
|
1123
|
+
font-size: 1rem;
|
|
1124
|
+
font-weight: 600 !important;
|
|
1125
|
+
line-height: 1.3;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
.fd-hover-link-title:hover,
|
|
1129
|
+
.fd-hover-link-cta:hover {
|
|
1130
|
+
opacity: 1;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
.fd-hover-link-description {
|
|
1134
|
+
font-size: 0.92rem;
|
|
1135
|
+
line-height: 1.6;
|
|
1136
|
+
color: color-mix(in srgb, var(--color-fd-popover-foreground, var(--color-fd-foreground)) 74%, transparent);
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
.fd-hover-link-footer {
|
|
1140
|
+
display: flex;
|
|
1141
|
+
align-items: center;
|
|
1142
|
+
justify-content: space-between;
|
|
1143
|
+
gap: 0.75rem;
|
|
1144
|
+
padding-top: 0.25rem;
|
|
1145
|
+
border-top: 1px solid color-mix(in srgb, var(--color-fd-border) 72%, transparent);
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
.fd-hover-link-cta {
|
|
1149
|
+
display: inline-flex !important;
|
|
1150
|
+
align-items: center;
|
|
1151
|
+
gap: 0.4rem;
|
|
1152
|
+
color: var(--color-fd-primary);
|
|
1153
|
+
font-size: 0.8rem;
|
|
1154
|
+
font-weight: 600 !important;
|
|
1155
|
+
text-transform: uppercase;
|
|
1156
|
+
letter-spacing: 0.08em;
|
|
1157
|
+
font-family: var(--fd-font-mono, var(--font-geist-mono, ui-monospace, monospace));
|
|
1158
|
+
}
|
|
1159
|
+
|
|
922
1160
|
.fd-page-body h1 {
|
|
923
1161
|
font-size: var(--fd-h1-size, 2.25rem);
|
|
924
1162
|
font-weight: var(--fd-h1-weight, 700);
|