@hyvor/design 2.1.9 → 2.1.10
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/dist/cloud/HyvorBar/BarSupport.svelte +1 -1
- package/dist/components/ColorPicker/ColorPicker.svelte +68 -9
- package/dist/components/ColorPicker/ColorPicker.svelte.d.ts +3 -0
- package/dist/index.css +4 -0
- package/dist/marketing/AllFeaturesAccordion/AllFeaturesAccordion.svelte +251 -0
- package/dist/marketing/AllFeaturesAccordion/AllFeaturesAccordion.svelte.d.ts +23 -0
- package/dist/marketing/AllFeaturesAccordion/AllFeaturesAccordionFeature.svelte +70 -0
- package/dist/marketing/AllFeaturesAccordion/AllFeaturesAccordionFeature.svelte.d.ts +10 -0
- package/dist/marketing/FAQ/FAQ.svelte +227 -0
- package/dist/marketing/FAQ/FAQ.svelte.d.ts +13 -0
- package/dist/marketing/FeatureSplit/FeatureSplit.svelte +325 -0
- package/dist/marketing/FeatureSplit/FeatureSplit.svelte.d.ts +24 -0
- package/dist/marketing/Footer/Footer.svelte +395 -98
- package/dist/marketing/Footer/Footer.svelte.d.ts +18 -2
- package/dist/marketing/Footer/FooterLinkList.svelte +10 -3
- package/dist/marketing/FullTrialSignup/FullTrialSignup.svelte +164 -0
- package/dist/marketing/FullTrialSignup/FullTrialSignup.svelte.d.ts +18 -0
- package/dist/marketing/Header/Header.svelte +72 -28
- package/dist/marketing/Header/Header.svelte.d.ts +5 -2
- package/dist/marketing/Header/HeaderLanguageToggle.svelte +119 -0
- package/dist/marketing/Header/HeaderLanguageToggle.svelte.d.ts +14 -0
- package/dist/marketing/Header/HeaderNavLink.svelte +149 -0
- package/dist/marketing/Header/HeaderNavLink.svelte.d.ts +18 -0
- package/dist/marketing/Header/language.d.ts +16 -0
- package/dist/marketing/Header/language.js +28 -0
- package/dist/marketing/Hero/Hero.svelte +349 -0
- package/dist/marketing/Hero/Hero.svelte.d.ts +16 -0
- package/dist/marketing/LogoStrip/LogoStrip.svelte +199 -0
- package/dist/marketing/LogoStrip/LogoStrip.svelte.d.ts +19 -0
- package/dist/marketing/Seal/CcpaSeal.svelte +29 -0
- package/dist/marketing/Seal/CcpaSeal.svelte.d.ts +6 -0
- package/dist/marketing/Seal/GdprSeal.svelte +60 -0
- package/dist/marketing/Seal/GdprSeal.svelte.d.ts +6 -0
- package/dist/marketing/Seal/IsoSeal.svelte +44 -0
- package/dist/marketing/Seal/IsoSeal.svelte.d.ts +6 -0
- package/dist/marketing/Seal/Seal.svelte +62 -0
- package/dist/marketing/Seal/Seal.svelte.d.ts +8 -0
- package/dist/marketing/Seal/SsoSeal.svelte +31 -0
- package/dist/marketing/Seal/SsoSeal.svelte.d.ts +6 -0
- package/dist/marketing/Seal/ccpa.svg +131 -0
- package/dist/marketing/SpotlightSplit/SpotlightSplit.svelte +256 -0
- package/dist/marketing/SpotlightSplit/SpotlightSplit.svelte.d.ts +19 -0
- package/dist/marketing/Testimonials/Testimonials.svelte +441 -0
- package/dist/marketing/Testimonials/Testimonials.svelte.d.ts +24 -0
- package/dist/marketing/index.d.ts +20 -2
- package/dist/marketing/index.js +26 -2
- package/dist/marketing/social.d.ts +1 -1
- package/dist/marketing/social.js +1 -1
- package/package.json +1 -1
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import Container from '../Container/Container.svelte';
|
|
4
|
+
import IconEnvelope from '@hyvor/icons/IconEnvelope';
|
|
3
5
|
import IconCopy from '@hyvor/icons/IconCopy';
|
|
4
6
|
import IconDiscord from '@hyvor/icons/IconDiscord';
|
|
5
|
-
import IconEnvelope from '@hyvor/icons/IconEnvelope';
|
|
6
7
|
import IconGithub from '@hyvor/icons/IconGithub';
|
|
7
8
|
import IconLinkedin from '@hyvor/icons/IconLinkedin';
|
|
8
9
|
import IconTwitterX from '@hyvor/icons/IconTwitterX';
|
|
9
10
|
import IconYoutube from '@hyvor/icons/IconYoutube';
|
|
10
|
-
import
|
|
11
|
+
import IconBluesky from '@hyvor/icons/IconBluesky';
|
|
12
|
+
import IconLockFill from '@hyvor/icons/IconLockFill';
|
|
11
13
|
import IconButton from '../../components/IconButton/IconButton.svelte';
|
|
12
14
|
import Tooltip from '../../components/Tooltip/Tooltip.svelte';
|
|
13
15
|
import LanguageToggle from '../../components/Internationalization/LanguageToggle.svelte';
|
|
14
|
-
import IconBluesky from '@hyvor/icons/IconBluesky';
|
|
15
16
|
import { SOCIAL_LINKS, type Socials } from '../social.js';
|
|
16
17
|
import Affiliate from '../Affiliate/Affiliate.svelte';
|
|
17
18
|
import RecordVisit from './RecordVisit.svelte';
|
|
@@ -19,104 +20,208 @@
|
|
|
19
20
|
const year = new Date().getFullYear();
|
|
20
21
|
|
|
21
22
|
interface Props {
|
|
23
|
+
name?: string;
|
|
24
|
+
subname?: string;
|
|
25
|
+
product?: string;
|
|
26
|
+
instance?: string;
|
|
27
|
+
logo?: string;
|
|
28
|
+
background?: string;
|
|
29
|
+
backgroundDark?: string;
|
|
30
|
+
card?: boolean;
|
|
22
31
|
email?: string | null;
|
|
23
32
|
social?: Partial<Socials>;
|
|
24
|
-
|
|
33
|
+
languageToggle?: boolean;
|
|
34
|
+
gdpr?: boolean;
|
|
25
35
|
affiliate?: boolean;
|
|
26
36
|
recordVisit?: boolean;
|
|
37
|
+
children?: Snippet;
|
|
27
38
|
max?: boolean;
|
|
39
|
+
logoAltText?: string;
|
|
40
|
+
copyEmailLabel?: string;
|
|
41
|
+
copiedLabel?: string;
|
|
42
|
+
gdprText?: string;
|
|
43
|
+
fromFranceText?: string;
|
|
28
44
|
}
|
|
29
45
|
|
|
30
46
|
let {
|
|
47
|
+
name = 'HYVOR',
|
|
48
|
+
subname,
|
|
49
|
+
product,
|
|
50
|
+
instance = 'https://hyvor.com',
|
|
51
|
+
logo,
|
|
52
|
+
background,
|
|
53
|
+
backgroundDark,
|
|
54
|
+
card = false,
|
|
31
55
|
email = null,
|
|
32
|
-
social =
|
|
33
|
-
|
|
56
|
+
social = {},
|
|
57
|
+
languageToggle = true,
|
|
58
|
+
gdpr = true,
|
|
34
59
|
affiliate = true,
|
|
35
60
|
recordVisit = true,
|
|
36
|
-
|
|
61
|
+
children,
|
|
62
|
+
max = true,
|
|
63
|
+
logoAltText = 'Logo',
|
|
64
|
+
copyEmailLabel = 'Copy email',
|
|
65
|
+
copiedLabel = 'Copied!',
|
|
66
|
+
gdprText = 'GDPR Compliant',
|
|
67
|
+
fromFranceText = 'From France'
|
|
37
68
|
}: Props = $props();
|
|
69
|
+
const mascotLogo = $derived(
|
|
70
|
+
logo || (product ? `${instance}/api/public/logo/${product}.svg` : undefined)
|
|
71
|
+
);
|
|
38
72
|
|
|
39
|
-
|
|
40
|
-
...SOCIAL_LINKS,
|
|
41
|
-
...social
|
|
42
|
-
};
|
|
73
|
+
const socialLinks = $derived({ ...SOCIAL_LINKS, ...social });
|
|
43
74
|
|
|
44
|
-
|
|
75
|
+
const SOCIAL_PLATFORMS = [
|
|
76
|
+
{ key: 'x', icon: IconTwitterX, label: 'X (Twitter)' },
|
|
77
|
+
{ key: 'github', icon: IconGithub, label: 'GitHub' },
|
|
78
|
+
{ key: 'discord', icon: IconDiscord, label: 'Discord' },
|
|
79
|
+
{ key: 'linkedin', icon: IconLinkedin, label: 'LinkedIn' },
|
|
80
|
+
{ key: 'youtube', icon: IconYoutube, label: 'YouTube' },
|
|
81
|
+
{ key: 'bluesky', icon: IconBluesky, label: 'Bluesky' }
|
|
82
|
+
] as const satisfies { key: keyof Socials; icon: unknown; label: string }[];
|
|
45
83
|
|
|
46
|
-
|
|
47
|
-
|
|
84
|
+
let emailCopied = $state(false);
|
|
85
|
+
function handleCopyEmail() {
|
|
86
|
+
if (!email) return;
|
|
87
|
+
navigator.clipboard.writeText(email);
|
|
48
88
|
emailCopied = true;
|
|
49
|
-
setTimeout(() =>
|
|
50
|
-
|
|
51
|
-
|
|
89
|
+
setTimeout(() => (emailCopied = false), 1000);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let mascotInView = $state(false);
|
|
93
|
+
function onView(node: HTMLElement, callback: () => void) {
|
|
94
|
+
const observer = new IntersectionObserver(
|
|
95
|
+
(entries) => {
|
|
96
|
+
if (entries[0]?.isIntersecting) {
|
|
97
|
+
setTimeout(callback, 400);
|
|
98
|
+
observer.disconnect();
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{ threshold: 0.3 }
|
|
102
|
+
);
|
|
103
|
+
observer.observe(node);
|
|
104
|
+
return {
|
|
105
|
+
destroy() {
|
|
106
|
+
observer.disconnect();
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function starPath(outerR: number, innerR: number) {
|
|
112
|
+
const points: string[] = [];
|
|
113
|
+
for (let i = 0; i < 10; i++) {
|
|
114
|
+
const angle = -Math.PI / 2 + (i * Math.PI) / 5;
|
|
115
|
+
const r = i % 2 === 0 ? outerR : innerR;
|
|
116
|
+
points.push(`${(r * Math.cos(angle)).toFixed(2)},${(r * Math.sin(angle)).toFixed(2)}`);
|
|
117
|
+
}
|
|
118
|
+
return `M${points.join('L')}Z`;
|
|
52
119
|
}
|
|
120
|
+
const gdprStarPath = starPath(1.7, 0.68);
|
|
121
|
+
|
|
122
|
+
// positions for the 12-star EU ring on the small GDPR badge
|
|
123
|
+
const gdprStars = Array.from({ length: 12 }, (_, i) => {
|
|
124
|
+
const angle = (i * 30 * Math.PI) / 180;
|
|
125
|
+
return {
|
|
126
|
+
x: 16 + 12 * Math.cos(angle),
|
|
127
|
+
y: 16 + 12 * Math.sin(angle)
|
|
128
|
+
};
|
|
129
|
+
});
|
|
53
130
|
</script>
|
|
54
131
|
|
|
55
|
-
<footer>
|
|
56
|
-
|
|
57
|
-
<div class="
|
|
58
|
-
<
|
|
59
|
-
{
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
<Tooltip text={emailCopied ? 'Copied!' : 'Copy email'} position="top">
|
|
68
|
-
<IconButton
|
|
69
|
-
size="small"
|
|
70
|
-
variant="invisible"
|
|
71
|
-
on:click={handleCopy}
|
|
72
|
-
on:mouseleave={() => (emailCopied = false)}
|
|
73
|
-
>
|
|
74
|
-
<IconCopy size={12} />
|
|
75
|
-
</IconButton>
|
|
76
|
-
</Tooltip>
|
|
77
|
-
</div>
|
|
78
|
-
{/if}
|
|
132
|
+
<div class="footer-outer">
|
|
133
|
+
{#if mascotLogo}
|
|
134
|
+
<div class="mascot-wrap" use:onView={() => (mascotInView = true)}>
|
|
135
|
+
<img
|
|
136
|
+
src={mascotLogo}
|
|
137
|
+
alt="{name} {logoAltText}"
|
|
138
|
+
width="100"
|
|
139
|
+
height="100"
|
|
140
|
+
class:in-view={mascotInView}
|
|
141
|
+
/>
|
|
142
|
+
</div>
|
|
143
|
+
{/if}
|
|
79
144
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
{#if social.blueksy}
|
|
88
|
-
<a href={social.blueksy} target="_blank" rel="nofollow"><IconBluesky /></a>
|
|
89
|
-
{/if}
|
|
90
|
-
{#if social.x}
|
|
91
|
-
<a href={social.x} target="_blank" rel="nofollow"><IconTwitterX /></a>
|
|
145
|
+
<footer class:card style:--footer-bg={background} style:--footer-bg-dark={backgroundDark}>
|
|
146
|
+
<Container {max}>
|
|
147
|
+
<div class="top-row">
|
|
148
|
+
<div class="brand">
|
|
149
|
+
<span>{name}</span>
|
|
150
|
+
{#if subname}
|
|
151
|
+
<div class="subname">{subname}</div>
|
|
92
152
|
{/if}
|
|
93
|
-
|
|
94
|
-
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<div class="top-row-right">
|
|
156
|
+
{#if email}
|
|
157
|
+
<div class="email-wrap">
|
|
158
|
+
<a class="email" href="mailto:{email}">
|
|
159
|
+
<IconEnvelope size={14} />
|
|
160
|
+
{email}
|
|
161
|
+
</a>
|
|
162
|
+
<Tooltip text={emailCopied ? copiedLabel : copyEmailLabel} position="top">
|
|
163
|
+
<IconButton
|
|
164
|
+
size="small"
|
|
165
|
+
variant="invisible"
|
|
166
|
+
color="input"
|
|
167
|
+
onclick={handleCopyEmail}
|
|
168
|
+
onmouseleave={() => (emailCopied = false)}
|
|
169
|
+
>
|
|
170
|
+
<IconCopy size={12} />
|
|
171
|
+
</IconButton>
|
|
172
|
+
</Tooltip>
|
|
173
|
+
</div>
|
|
95
174
|
{/if}
|
|
96
|
-
|
|
97
|
-
|
|
175
|
+
|
|
176
|
+
<div class="socials">
|
|
177
|
+
{#each SOCIAL_PLATFORMS as platform (platform.key)}
|
|
178
|
+
{@const href = socialLinks[platform.key]}
|
|
179
|
+
{#if href}
|
|
180
|
+
<a {href} target="_blank" rel="nofollow" aria-label={platform.label}>
|
|
181
|
+
<platform.icon size={16} />
|
|
182
|
+
</a>
|
|
183
|
+
{/if}
|
|
184
|
+
{/each}
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
{#if languageToggle}
|
|
188
|
+
<span class="language-toggle-wrap">
|
|
189
|
+
<LanguageToggle align="end" position="top" staticPage />
|
|
190
|
+
</span>
|
|
98
191
|
{/if}
|
|
99
192
|
</div>
|
|
100
193
|
</div>
|
|
101
194
|
|
|
102
|
-
<div class="footer-
|
|
103
|
-
|
|
104
|
-
<LanguageToggle align="end" position="top" staticPage />
|
|
105
|
-
</span>
|
|
195
|
+
<div class="footer-center">
|
|
196
|
+
{@render children?.()}
|
|
106
197
|
</div>
|
|
107
|
-
</div>
|
|
108
198
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
199
|
+
<div class="bottom-bar">
|
|
200
|
+
<div>HYVOR © {year}</div>
|
|
201
|
+
|
|
202
|
+
{#if gdpr}
|
|
203
|
+
<div class="bottom-center">
|
|
204
|
+
<a class="gdpr-chip" href="https://hyvor.com/compliance" target="_blank">
|
|
205
|
+
<span class="gdpr-chip-icon">
|
|
206
|
+
<svg class="ring" viewBox="0 0 32 32" aria-hidden="true">
|
|
207
|
+
<circle cx="16" cy="16" r="16" fill="#173a8a" />
|
|
208
|
+
{#each gdprStars as s}
|
|
209
|
+
<path d={gdprStarPath} fill="#ffcd3c" transform="translate({s.x}, {s.y})" />
|
|
210
|
+
{/each}
|
|
211
|
+
</svg>
|
|
212
|
+
<span class="lock"><IconLockFill size={10} /></span>
|
|
213
|
+
</span>
|
|
214
|
+
<span class="gdpr-chip-text">{gdprText}</span>
|
|
215
|
+
</a>
|
|
216
|
+
</div>
|
|
217
|
+
{/if}
|
|
112
218
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
219
|
+
<div class="bottom-right">
|
|
220
|
+
<div class="france">{fromFranceText} <span class="flag">🇫🇷</span></div>
|
|
221
|
+
</div>
|
|
116
222
|
</div>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
</Container>
|
|
223
|
+
</Container>
|
|
224
|
+
</footer>
|
|
120
225
|
|
|
121
226
|
{#if affiliate}
|
|
122
227
|
<Affiliate />
|
|
@@ -125,57 +230,249 @@
|
|
|
125
230
|
{#if recordVisit}
|
|
126
231
|
<RecordVisit />
|
|
127
232
|
{/if}
|
|
128
|
-
</
|
|
233
|
+
</div>
|
|
129
234
|
|
|
130
235
|
<style>
|
|
131
|
-
footer {
|
|
132
|
-
|
|
236
|
+
.footer-outer {
|
|
237
|
+
position: relative;
|
|
238
|
+
margin-top: 100px;
|
|
133
239
|
}
|
|
134
240
|
|
|
135
|
-
.
|
|
136
|
-
|
|
241
|
+
.mascot-wrap {
|
|
242
|
+
position: absolute;
|
|
243
|
+
z-index: 10;
|
|
137
244
|
display: flex;
|
|
138
|
-
|
|
245
|
+
justify-content: center;
|
|
246
|
+
pointer-events: none;
|
|
247
|
+
left: 0;
|
|
248
|
+
bottom: 100%;
|
|
249
|
+
transform: translate(-35%, 45%) rotate(20deg);
|
|
139
250
|
}
|
|
140
|
-
|
|
251
|
+
|
|
252
|
+
.mascot-wrap img {
|
|
253
|
+
opacity: 0;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.mascot-wrap img.in-view {
|
|
257
|
+
animation: mascot-tilt-in 0.8s ease forwards;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
@keyframes mascot-tilt-in {
|
|
261
|
+
0% {
|
|
262
|
+
opacity: 0;
|
|
263
|
+
transform: rotate(-14deg) scale(0.9) translateY(16px);
|
|
264
|
+
}
|
|
265
|
+
55% {
|
|
266
|
+
opacity: 1;
|
|
267
|
+
transform: rotate(10deg) scale(1.06) translateY(-4px);
|
|
268
|
+
}
|
|
269
|
+
100% {
|
|
270
|
+
opacity: 1;
|
|
271
|
+
transform: rotate(0deg) scale(1) translateY(0);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
@media (prefers-reduced-motion: reduce) {
|
|
276
|
+
.mascot-wrap img {
|
|
277
|
+
opacity: 1;
|
|
278
|
+
}
|
|
279
|
+
.mascot-wrap img.in-view {
|
|
280
|
+
animation: none;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
footer {
|
|
285
|
+
--footer-text: var(--text);
|
|
286
|
+
--footer-text-strong: var(--text);
|
|
287
|
+
--footer-muted: var(--text-light);
|
|
288
|
+
--footer-border: var(--border);
|
|
289
|
+
--footer-hover: var(--accent);
|
|
290
|
+
|
|
291
|
+
position: relative;
|
|
292
|
+
z-index: 1;
|
|
293
|
+
background: var(--footer-bg, transparent);
|
|
294
|
+
color: var(--footer-text);
|
|
141
295
|
padding-top: 50px;
|
|
142
296
|
}
|
|
143
|
-
|
|
144
|
-
|
|
297
|
+
|
|
298
|
+
:global(:root.dark) footer {
|
|
299
|
+
background: var(--footer-bg-dark, var(--footer-bg, transparent));
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
footer.card {
|
|
303
|
+
--footer-text: rgba(255, 255, 255, 0.75);
|
|
304
|
+
--footer-text-strong: #fff;
|
|
305
|
+
--footer-muted: rgba(255, 255, 255, 0.45);
|
|
306
|
+
--footer-border: rgba(255, 255, 255, 0.08);
|
|
307
|
+
--footer-hover: #fff;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.top-row {
|
|
311
|
+
display: flex;
|
|
312
|
+
align-items: center;
|
|
313
|
+
justify-content: space-between;
|
|
314
|
+
flex-wrap: wrap;
|
|
315
|
+
gap: 20px;
|
|
316
|
+
padding-bottom: 40px;
|
|
317
|
+
border-bottom: 1px solid var(--footer-border);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.brand {
|
|
321
|
+
font-size: 16px;
|
|
322
|
+
font-weight: 700;
|
|
323
|
+
color: var(--footer-text-strong);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.subname {
|
|
327
|
+
font-size: 13px;
|
|
328
|
+
font-weight: 400;
|
|
329
|
+
color: var(--footer-muted);
|
|
145
330
|
}
|
|
146
|
-
|
|
331
|
+
|
|
332
|
+
.top-row-right {
|
|
147
333
|
display: flex;
|
|
334
|
+
align-items: center;
|
|
335
|
+
gap: 24px;
|
|
336
|
+
flex-wrap: wrap;
|
|
148
337
|
}
|
|
338
|
+
|
|
149
339
|
.email-wrap {
|
|
150
340
|
display: inline-flex;
|
|
151
341
|
align-items: center;
|
|
152
|
-
gap:
|
|
153
|
-
margin-bottom: 15px;
|
|
342
|
+
gap: 2px;
|
|
154
343
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
344
|
+
|
|
345
|
+
.email {
|
|
346
|
+
display: inline-flex;
|
|
347
|
+
align-items: center;
|
|
348
|
+
gap: 6px;
|
|
349
|
+
font-size: 13px;
|
|
350
|
+
color: var(--footer-text);
|
|
160
351
|
}
|
|
161
|
-
|
|
162
|
-
|
|
352
|
+
|
|
353
|
+
.email:hover {
|
|
354
|
+
color: var(--footer-hover);
|
|
163
355
|
}
|
|
164
|
-
|
|
165
|
-
|
|
356
|
+
|
|
357
|
+
.socials {
|
|
358
|
+
display: flex;
|
|
359
|
+
align-items: center;
|
|
360
|
+
gap: 14px;
|
|
166
361
|
}
|
|
167
362
|
|
|
168
|
-
.
|
|
169
|
-
|
|
170
|
-
padding-bottom: 30px;
|
|
363
|
+
.socials a {
|
|
364
|
+
color: var(--footer-text);
|
|
171
365
|
display: flex;
|
|
172
366
|
}
|
|
173
|
-
|
|
174
|
-
|
|
367
|
+
|
|
368
|
+
.socials a:hover {
|
|
369
|
+
color: var(--footer-hover);
|
|
175
370
|
}
|
|
176
371
|
|
|
177
372
|
.language-toggle-wrap {
|
|
178
|
-
margin-left: 8px;
|
|
179
373
|
font-size: 18px;
|
|
180
374
|
}
|
|
375
|
+
|
|
376
|
+
.footer-center {
|
|
377
|
+
display: flex;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.footer-center:not(:empty) {
|
|
381
|
+
padding: 48px 0;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.footer-center:not(:empty) + .bottom-bar {
|
|
385
|
+
border-top: 1px solid var(--footer-border);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.bottom-bar {
|
|
389
|
+
display: flex;
|
|
390
|
+
align-items: center;
|
|
391
|
+
justify-content: space-between;
|
|
392
|
+
flex-wrap: wrap;
|
|
393
|
+
gap: 10px;
|
|
394
|
+
padding: 24px 0 32px;
|
|
395
|
+
font-size: 13px;
|
|
396
|
+
color: var(--footer-muted);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.bottom-right {
|
|
400
|
+
display: flex;
|
|
401
|
+
align-items: center;
|
|
402
|
+
gap: 16px;
|
|
403
|
+
flex-wrap: wrap;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.france {
|
|
407
|
+
display: inline-flex;
|
|
408
|
+
align-items: center;
|
|
409
|
+
gap: 6px;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.gdpr-chip {
|
|
413
|
+
display: inline-flex;
|
|
414
|
+
align-items: center;
|
|
415
|
+
gap: 8px;
|
|
416
|
+
padding: 5px 12px 5px 5px;
|
|
417
|
+
border-radius: 100px;
|
|
418
|
+
background: #1f2f57;
|
|
419
|
+
color: #fff;
|
|
420
|
+
opacity: 0.9;
|
|
421
|
+
transition: opacity 0.15s ease;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.gdpr-chip:hover {
|
|
425
|
+
opacity: 1;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.gdpr-chip-icon {
|
|
429
|
+
position: relative;
|
|
430
|
+
width: 22px;
|
|
431
|
+
height: 22px;
|
|
432
|
+
flex-shrink: 0;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.gdpr-chip-icon .ring {
|
|
436
|
+
position: absolute;
|
|
437
|
+
inset: 0;
|
|
438
|
+
width: 100%;
|
|
439
|
+
height: 100%;
|
|
440
|
+
display: block;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.gdpr-chip-icon .lock {
|
|
444
|
+
position: absolute;
|
|
445
|
+
inset: 0;
|
|
446
|
+
display: flex;
|
|
447
|
+
align-items: center;
|
|
448
|
+
justify-content: center;
|
|
449
|
+
color: #fff;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.gdpr-chip-text {
|
|
453
|
+
font-size: 11px;
|
|
454
|
+
font-weight: 800;
|
|
455
|
+
letter-spacing: 0.02em;
|
|
456
|
+
color: #fff;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.flag {
|
|
460
|
+
color: initial;
|
|
461
|
+
filter: none;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
@media (max-width: 560px) {
|
|
465
|
+
.mascot-wrap {
|
|
466
|
+
margin-bottom: -40px;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
footer {
|
|
470
|
+
padding-top: 130px;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.top-row {
|
|
474
|
+
flex-direction: column;
|
|
475
|
+
align-items: flex-start;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
181
478
|
</style>
|
|
@@ -1,12 +1,28 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
import { type Socials } from '../social.js';
|
|
2
3
|
interface Props {
|
|
4
|
+
name?: string;
|
|
5
|
+
subname?: string;
|
|
6
|
+
product?: string;
|
|
7
|
+
instance?: string;
|
|
8
|
+
logo?: string;
|
|
9
|
+
background?: string;
|
|
10
|
+
backgroundDark?: string;
|
|
11
|
+
card?: boolean;
|
|
3
12
|
email?: string | null;
|
|
4
13
|
social?: Partial<Socials>;
|
|
5
|
-
|
|
14
|
+
languageToggle?: boolean;
|
|
15
|
+
gdpr?: boolean;
|
|
6
16
|
affiliate?: boolean;
|
|
7
17
|
recordVisit?: boolean;
|
|
18
|
+
children?: Snippet;
|
|
8
19
|
max?: boolean;
|
|
20
|
+
logoAltText?: string;
|
|
21
|
+
copyEmailLabel?: string;
|
|
22
|
+
copiedLabel?: string;
|
|
23
|
+
gdprText?: string;
|
|
24
|
+
fromFranceText?: string;
|
|
9
25
|
}
|
|
10
|
-
declare const Footer: import("svelte").Component<Props, {}, "
|
|
26
|
+
declare const Footer: import("svelte").Component<Props, {}, "">;
|
|
11
27
|
type Footer = ReturnType<typeof Footer>;
|
|
12
28
|
export default Footer;
|
|
@@ -17,12 +17,16 @@
|
|
|
17
17
|
<style>
|
|
18
18
|
.link-list {
|
|
19
19
|
flex: 1;
|
|
20
|
+
min-width: 150px;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
.title {
|
|
23
|
-
font-
|
|
24
|
+
font-size: 12px;
|
|
25
|
+
font-weight: 700;
|
|
24
26
|
text-transform: uppercase;
|
|
25
|
-
|
|
27
|
+
letter-spacing: 0.05em;
|
|
28
|
+
color: var(--footer-muted, var(--text-light));
|
|
29
|
+
margin-bottom: 14px;
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
.links {
|
|
@@ -32,9 +36,12 @@
|
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
.links :global(a) {
|
|
35
|
-
|
|
39
|
+
font-size: 14px;
|
|
40
|
+
color: var(--footer-text, var(--text-light));
|
|
41
|
+
margin-top: 10px;
|
|
36
42
|
}
|
|
37
43
|
.links :global(a:hover) {
|
|
44
|
+
color: var(--footer-text-strong, var(--text));
|
|
38
45
|
text-decoration: underline;
|
|
39
46
|
}
|
|
40
47
|
</style>
|