@hyvor/design 2.1.14 → 2.1.16
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/components/ButtonGroup/ButtonGroup.svelte +5 -4
- package/dist/components/ButtonGroup/ButtonGroup.svelte.d.ts +1 -0
- package/dist/components/DetailCard/DetailCard.svelte +2 -1
- package/dist/components/Dropdown/DropdownContent.svelte +22 -6
- package/dist/marketing/AllFeaturesAccordion/AllFeaturesAccordion.svelte +30 -0
- package/dist/marketing/AllFeaturesAccordion/AllFeaturesAccordionFeature.svelte +15 -2
- package/dist/marketing/Footer/Footer.svelte +28 -1
- package/dist/marketing/Footer/FooterLinkList.svelte +5 -1
- package/dist/marketing/Header/Header.svelte +21 -4
- package/dist/marketing/Header/HeaderLanguageToggle.svelte +50 -29
- package/dist/marketing/Header/HeaderMobileSection.svelte +108 -0
- package/dist/marketing/Header/HeaderMobileSection.svelte.d.ts +12 -0
- package/dist/marketing/Header/HeaderNavMenu.svelte +54 -0
- package/dist/marketing/Header/HeaderNavMenu.svelte.d.ts +12 -0
- package/dist/marketing/Header/breakpoint.d.ts +1 -0
- package/dist/marketing/Header/breakpoint.js +2 -0
- package/dist/marketing/LogoStrip/LogoStrip.svelte +48 -24
- package/dist/marketing/Testimonials/Testimonials.svelte +320 -160
- package/dist/marketing/Testimonials/Testimonials.svelte.d.ts +7 -0
- package/dist/marketing/index.d.ts +1 -0
- package/dist/marketing/index.js +1 -0
- package/package.json +1 -1
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
type: 'text';
|
|
4
4
|
name: string;
|
|
5
5
|
role: string;
|
|
6
|
+
company?: string;
|
|
7
|
+
companyUrl?: string;
|
|
8
|
+
imageUrl?: string;
|
|
9
|
+
summary?: string;
|
|
6
10
|
quote: string;
|
|
7
11
|
}
|
|
8
12
|
|
|
@@ -10,6 +14,9 @@
|
|
|
10
14
|
type: 'video';
|
|
11
15
|
name: string;
|
|
12
16
|
role: string;
|
|
17
|
+
company: string;
|
|
18
|
+
companyUrl?: string;
|
|
19
|
+
imageUrl?: string;
|
|
13
20
|
videoUrl?: string;
|
|
14
21
|
posterUrl?: string;
|
|
15
22
|
summary?: string;
|
|
@@ -31,37 +38,13 @@
|
|
|
31
38
|
handwrittenNames = true
|
|
32
39
|
}: Props = $props();
|
|
33
40
|
|
|
34
|
-
function identicon(seed: string) {
|
|
35
|
-
let hash = 0;
|
|
36
|
-
for (let i = 0; i < seed.length; i++) {
|
|
37
|
-
hash = (hash * 31 + seed.charCodeAt(i)) | 0;
|
|
38
|
-
}
|
|
39
|
-
const hue = Math.abs(hash) % 360;
|
|
40
|
-
const cells: { x: number; y: number }[] = [];
|
|
41
|
-
for (let col = 0; col < 3; col++) {
|
|
42
|
-
for (let row = 0; row < 5; row++) {
|
|
43
|
-
const bit = (hash >> (col * 5 + row)) & 1;
|
|
44
|
-
if (!bit) continue;
|
|
45
|
-
cells.push({ x: col, y: row });
|
|
46
|
-
if (col < 2) cells.push({ x: 4 - col, y: row });
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return {
|
|
50
|
-
bg: `hsl(${hue} 45% 92%)`,
|
|
51
|
-
fg: `hsl(${hue} 50% 40%)`,
|
|
52
|
-
cells
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
let scrollEl: HTMLDivElement | undefined = $state();
|
|
57
|
-
let dragging = $state(false);
|
|
58
|
-
let dragStartX = 0;
|
|
59
|
-
let dragStartScroll = 0;
|
|
60
|
-
|
|
61
41
|
let started: boolean[] = $state(reviews.map(() => false));
|
|
62
42
|
let playing: boolean[] = $state(reviews.map(() => false));
|
|
63
43
|
let videoEls: (HTMLVideoElement | undefined)[] = $state([]);
|
|
64
44
|
|
|
45
|
+
let rowEl: HTMLDivElement | undefined = $state();
|
|
46
|
+
let activeIndex = $state(0);
|
|
47
|
+
|
|
65
48
|
function play(i: number) {
|
|
66
49
|
started[i] = true;
|
|
67
50
|
videoEls[i]?.play().catch(() => {});
|
|
@@ -76,23 +59,48 @@
|
|
|
76
59
|
playing[i] = false;
|
|
77
60
|
}
|
|
78
61
|
|
|
79
|
-
function
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
62
|
+
function onCardClick(e: MouseEvent, i: number) {
|
|
63
|
+
if ((e.target as HTMLElement).closest('a')) return;
|
|
64
|
+
if (!started[i]) {
|
|
65
|
+
play(i);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const video = videoEls[i];
|
|
69
|
+
if (!video) return;
|
|
70
|
+
if (playing[i]) {
|
|
71
|
+
video.pause();
|
|
72
|
+
} else {
|
|
73
|
+
video.play().catch(() => {});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function onCardKeydown(e: KeyboardEvent, i: number) {
|
|
78
|
+
if (e.key !== 'Enter' && e.key !== ' ') return;
|
|
79
|
+
e.preventDefault();
|
|
80
|
+
onCardClick(e as unknown as MouseEvent, i);
|
|
87
81
|
}
|
|
88
82
|
|
|
89
|
-
function
|
|
90
|
-
if (!
|
|
91
|
-
|
|
83
|
+
function goTo(i: number) {
|
|
84
|
+
if (!rowEl) return;
|
|
85
|
+
const card = rowEl.children[i] as HTMLElement | undefined;
|
|
86
|
+
card?.scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' });
|
|
87
|
+
activeIndex = i;
|
|
92
88
|
}
|
|
93
89
|
|
|
94
|
-
function
|
|
95
|
-
|
|
90
|
+
function onRowScroll() {
|
|
91
|
+
if (!rowEl) return;
|
|
92
|
+
const rowCenter = rowEl.getBoundingClientRect().left + rowEl.clientWidth / 2;
|
|
93
|
+
let closest = 0;
|
|
94
|
+
let closestDist = Infinity;
|
|
95
|
+
Array.from(rowEl.children).forEach((child, i) => {
|
|
96
|
+
const rect = (child as HTMLElement).getBoundingClientRect();
|
|
97
|
+
const dist = Math.abs(rect.left + rect.width / 2 - rowCenter);
|
|
98
|
+
if (dist < closestDist) {
|
|
99
|
+
closestDist = dist;
|
|
100
|
+
closest = i;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
activeIndex = closest;
|
|
96
104
|
}
|
|
97
105
|
</script>
|
|
98
106
|
|
|
@@ -102,92 +110,142 @@
|
|
|
102
110
|
{/if}
|
|
103
111
|
</svelte:head>
|
|
104
112
|
|
|
113
|
+
{#snippet meta(review: Review)}
|
|
114
|
+
<div class="role">
|
|
115
|
+
{review.role}, <br />
|
|
116
|
+
{#if review.companyUrl}
|
|
117
|
+
<a
|
|
118
|
+
class="company"
|
|
119
|
+
href={review.companyUrl}
|
|
120
|
+
target="_blank"
|
|
121
|
+
rel="nofollow noopener noreferrer"
|
|
122
|
+
>
|
|
123
|
+
{review.company}
|
|
124
|
+
</a>
|
|
125
|
+
{:else}
|
|
126
|
+
{review.company}
|
|
127
|
+
{/if}
|
|
128
|
+
</div>
|
|
129
|
+
{/snippet}
|
|
130
|
+
|
|
105
131
|
<section class="hds-testimonials" class:handwritten={handwrittenNames}>
|
|
106
132
|
<div class="hds-container head">
|
|
107
133
|
<p class="label">{label}</p>
|
|
108
134
|
<h2>{@html title}</h2>
|
|
109
135
|
</div>
|
|
110
136
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
{#if review.type === 'text'}
|
|
125
|
-
{@const av = identicon(review.name)}
|
|
126
|
-
<figure class="card text-card hds-box">
|
|
127
|
-
<svg class="avatar" viewBox="0 0 5 5" style="background: {av.bg}" aria-hidden="true">
|
|
128
|
-
{#each av.cells as cell}
|
|
129
|
-
<rect x={cell.x} y={cell.y} width="1" height="1" fill={av.fg} />
|
|
130
|
-
{/each}
|
|
131
|
-
</svg>
|
|
132
|
-
<blockquote>“{review.quote}”</blockquote>
|
|
133
|
-
<figcaption>
|
|
134
|
-
<span class="name">{review.name}</span>
|
|
135
|
-
<span class="role">{review.role}</span>
|
|
136
|
-
</figcaption>
|
|
137
|
-
</figure>
|
|
138
|
-
{:else}
|
|
139
|
-
<figure class="card video-card hds-box" class:playing={playing[i]}>
|
|
140
|
-
{#if started[i]}
|
|
141
|
-
<!-- svelte-ignore a11y_media_has_caption -->
|
|
142
|
-
<video
|
|
143
|
-
class="video"
|
|
144
|
-
src={review.videoUrl}
|
|
145
|
-
poster={review.posterUrl}
|
|
146
|
-
controls={playing[i]}
|
|
147
|
-
playsinline
|
|
148
|
-
bind:this={videoEls[i]}
|
|
149
|
-
use:autoplayVideo
|
|
150
|
-
onplay={() => (playing[i] = true)}
|
|
151
|
-
onpause={(e) => onVideoPause(e, i)}
|
|
152
|
-
onended={() => (playing[i] = false)}
|
|
153
|
-
></video>
|
|
154
|
-
{:else}
|
|
155
|
-
<div class="poster">
|
|
156
|
-
<img src={review.posterUrl} alt="" />
|
|
157
|
-
</div>
|
|
158
|
-
{/if}
|
|
159
|
-
|
|
160
|
-
{#if !playing[i]}
|
|
161
|
-
<div class="poster-scrim"></div>
|
|
162
|
-
|
|
163
|
-
{#if !started[i] && review.summary}
|
|
164
|
-
<p class="video-summary">"{review.summary}"</p>
|
|
137
|
+
<div class="hds-container-max cards-wrap">
|
|
138
|
+
<div
|
|
139
|
+
class="cards-row"
|
|
140
|
+
bind:this={rowEl}
|
|
141
|
+
onscroll={onRowScroll}
|
|
142
|
+
role="region"
|
|
143
|
+
aria-label={label}
|
|
144
|
+
>
|
|
145
|
+
{#each reviews as review, i}
|
|
146
|
+
{#if review.type === 'text'}
|
|
147
|
+
<figure class="card text-card hds-box">
|
|
148
|
+
{#if review.imageUrl}
|
|
149
|
+
<img class="avatar photo card-avatar" src={review.imageUrl} alt={review.name} />
|
|
165
150
|
{/if}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
<
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
viewBox="0 0 16 16"
|
|
176
|
-
fill="currentColor"
|
|
177
|
-
aria-hidden="true"
|
|
178
|
-
>
|
|
179
|
-
<path d="M5 3.5v9l8-4.5-8-4.5z" />
|
|
180
|
-
</svg>
|
|
181
|
-
</button>
|
|
182
|
-
|
|
151
|
+
<svg class="quote-mark" viewBox="0 0 24 24" aria-hidden="true">
|
|
152
|
+
<path
|
|
153
|
+
d="M10 7c-3.3 0-6 2.7-6 6v4h6v-6H7c0-1.7 1.3-3 3-3V7zm10 0c-3.3 0-6 2.7-6 6v4h6v-6h-3c0-1.7 1.3-3 3-3V7z"
|
|
154
|
+
/>
|
|
155
|
+
</svg>
|
|
156
|
+
{#if review.summary}
|
|
157
|
+
<p class="text-summary">{review.summary}</p>
|
|
158
|
+
{/if}
|
|
159
|
+
<blockquote>“{review.quote}”</blockquote>
|
|
183
160
|
<figcaption>
|
|
184
|
-
<span class="
|
|
185
|
-
|
|
161
|
+
<span class="caption-text">
|
|
162
|
+
<span class="name">{review.name}</span>
|
|
163
|
+
{@render meta(review)}
|
|
164
|
+
</span>
|
|
186
165
|
</figcaption>
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
166
|
+
</figure>
|
|
167
|
+
{:else}
|
|
168
|
+
<!-- svelte-ignore a11y_no_noninteractive_element_to_interactive_role -->
|
|
169
|
+
<figure
|
|
170
|
+
class="card video-card hds-box"
|
|
171
|
+
class:playing={playing[i]}
|
|
172
|
+
role="button"
|
|
173
|
+
tabindex="0"
|
|
174
|
+
aria-label={playing[i]
|
|
175
|
+
? 'Pause video testimonial'
|
|
176
|
+
: started[i]
|
|
177
|
+
? 'Resume video testimonial'
|
|
178
|
+
: 'Play video testimonial'}
|
|
179
|
+
onclick={(e) => onCardClick(e, i)}
|
|
180
|
+
onkeydown={(e) => onCardKeydown(e, i)}
|
|
181
|
+
>
|
|
182
|
+
{#if started[i]}
|
|
183
|
+
<!-- svelte-ignore a11y_media_has_caption -->
|
|
184
|
+
<video
|
|
185
|
+
class="video"
|
|
186
|
+
src={review.videoUrl}
|
|
187
|
+
poster={review.posterUrl}
|
|
188
|
+
playsinline
|
|
189
|
+
bind:this={videoEls[i]}
|
|
190
|
+
use:autoplayVideo
|
|
191
|
+
onplay={() => (playing[i] = true)}
|
|
192
|
+
onpause={(e) => onVideoPause(e, i)}
|
|
193
|
+
onended={() => (playing[i] = false)}
|
|
194
|
+
></video>
|
|
195
|
+
{:else}
|
|
196
|
+
<div class="poster">
|
|
197
|
+
<img src={review.posterUrl} alt="" />
|
|
198
|
+
</div>
|
|
199
|
+
{/if}
|
|
200
|
+
|
|
201
|
+
{#if !playing[i]}
|
|
202
|
+
<div class="poster-scrim"></div>
|
|
203
|
+
|
|
204
|
+
{#if review.summary}
|
|
205
|
+
<p class="video-summary">“{review.summary}”</p>
|
|
206
|
+
{/if}
|
|
207
|
+
|
|
208
|
+
<div class="play-btn" aria-hidden="true">
|
|
209
|
+
<svg
|
|
210
|
+
width="20"
|
|
211
|
+
height="20"
|
|
212
|
+
viewBox="0 0 16 16"
|
|
213
|
+
fill="currentColor"
|
|
214
|
+
aria-hidden="true"
|
|
215
|
+
>
|
|
216
|
+
<path d="M5 3.5v9l8-4.5-8-4.5z" />
|
|
217
|
+
</svg>
|
|
218
|
+
</div>
|
|
219
|
+
|
|
220
|
+
<figcaption>
|
|
221
|
+
{#if review.imageUrl}
|
|
222
|
+
<img class="avatar photo" src={review.imageUrl} alt={review.name} />
|
|
223
|
+
{/if}
|
|
224
|
+
<span class="caption-text">
|
|
225
|
+
<span class="name">{review.name}</span>
|
|
226
|
+
{@render meta(review)}
|
|
227
|
+
</span>
|
|
228
|
+
</figcaption>
|
|
229
|
+
{/if}
|
|
230
|
+
</figure>
|
|
231
|
+
{/if}
|
|
232
|
+
{/each}
|
|
233
|
+
</div>
|
|
234
|
+
|
|
235
|
+
{#if reviews.length > 1}
|
|
236
|
+
<div class="dots" role="tablist" aria-label="Testimonials navigation">
|
|
237
|
+
{#each reviews as _, i}
|
|
238
|
+
<button
|
|
239
|
+
class="dot"
|
|
240
|
+
class:active={i === activeIndex}
|
|
241
|
+
role="tab"
|
|
242
|
+
aria-selected={i === activeIndex}
|
|
243
|
+
aria-label={`Go to testimonial ${i + 1}`}
|
|
244
|
+
onclick={() => goTo(i)}
|
|
245
|
+
></button>
|
|
246
|
+
{/each}
|
|
247
|
+
</div>
|
|
248
|
+
{/if}
|
|
191
249
|
</div>
|
|
192
250
|
</section>
|
|
193
251
|
|
|
@@ -196,6 +254,7 @@
|
|
|
196
254
|
background: var(--accent-lightest);
|
|
197
255
|
padding: 100px 0 96px;
|
|
198
256
|
overflow: hidden;
|
|
257
|
+
scroll-margin-top: calc(var(--header-height, 55px) + 20px);
|
|
199
258
|
}
|
|
200
259
|
|
|
201
260
|
.head {
|
|
@@ -221,31 +280,17 @@
|
|
|
221
280
|
font-family: var(--font-serif);
|
|
222
281
|
}
|
|
223
282
|
|
|
224
|
-
.
|
|
225
|
-
|
|
283
|
+
.cards-wrap {
|
|
284
|
+
padding: 32px 15px 4px;
|
|
285
|
+
box-sizing: border-box;
|
|
286
|
+
}
|
|
226
287
|
|
|
288
|
+
.cards-row {
|
|
227
289
|
display: flex;
|
|
290
|
+
flex-wrap: wrap;
|
|
228
291
|
align-items: stretch;
|
|
292
|
+
justify-content: center;
|
|
229
293
|
gap: 20px;
|
|
230
|
-
overflow-x: auto;
|
|
231
|
-
overflow-y: visible;
|
|
232
|
-
scroll-behavior: smooth;
|
|
233
|
-
cursor: grab;
|
|
234
|
-
padding: 32px var(--side-padding) 36px;
|
|
235
|
-
scrollbar-width: none;
|
|
236
|
-
-webkit-overflow-scrolling: touch;
|
|
237
|
-
touch-action: pan-y;
|
|
238
|
-
user-select: none;
|
|
239
|
-
-webkit-user-select: none;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
.scroll-row.dragging {
|
|
243
|
-
cursor: grabbing;
|
|
244
|
-
scroll-behavior: auto;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
.scroll-row::-webkit-scrollbar {
|
|
248
|
-
display: none;
|
|
249
294
|
}
|
|
250
295
|
|
|
251
296
|
.card {
|
|
@@ -261,11 +306,29 @@
|
|
|
261
306
|
}
|
|
262
307
|
|
|
263
308
|
.text-card {
|
|
309
|
+
height: auto;
|
|
310
|
+
min-height: 440px;
|
|
264
311
|
padding: 28px;
|
|
265
312
|
display: flex;
|
|
266
313
|
flex-direction: column;
|
|
267
314
|
}
|
|
268
315
|
|
|
316
|
+
.quote-mark {
|
|
317
|
+
width: 40px;
|
|
318
|
+
height: 40px;
|
|
319
|
+
margin-bottom: 20px;
|
|
320
|
+
fill: var(--accent);
|
|
321
|
+
opacity: 0.14;
|
|
322
|
+
flex-shrink: 0;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.card-avatar {
|
|
326
|
+
position: absolute;
|
|
327
|
+
top: 28px;
|
|
328
|
+
right: 28px;
|
|
329
|
+
z-index: 1;
|
|
330
|
+
}
|
|
331
|
+
|
|
269
332
|
.avatar {
|
|
270
333
|
width: 46px;
|
|
271
334
|
height: 46px;
|
|
@@ -275,48 +338,91 @@
|
|
|
275
338
|
shape-rendering: crispEdges;
|
|
276
339
|
}
|
|
277
340
|
|
|
341
|
+
.avatar.photo {
|
|
342
|
+
object-fit: cover;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.text-summary {
|
|
346
|
+
margin: 0 0 14px;
|
|
347
|
+
font-family: var(--font-serif);
|
|
348
|
+
font-size: 18px;
|
|
349
|
+
font-weight: 800;
|
|
350
|
+
line-height: 1.25;
|
|
351
|
+
letter-spacing: -0.01em;
|
|
352
|
+
color: var(--text);
|
|
353
|
+
}
|
|
354
|
+
|
|
278
355
|
blockquote {
|
|
279
356
|
font-size: 16px;
|
|
280
357
|
line-height: 1.7;
|
|
281
358
|
color: var(--text);
|
|
282
|
-
margin:
|
|
359
|
+
margin: 0 0 20px;
|
|
283
360
|
flex: 1;
|
|
361
|
+
font-family: var(--font-serif);
|
|
284
362
|
}
|
|
285
363
|
|
|
286
364
|
.text-card figcaption {
|
|
365
|
+
display: flex;
|
|
366
|
+
align-items: center;
|
|
367
|
+
gap: 12px;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.caption-text {
|
|
287
371
|
display: flex;
|
|
288
372
|
flex-direction: column;
|
|
289
|
-
|
|
373
|
+
justify-content: center;
|
|
374
|
+
gap: 2px;
|
|
375
|
+
min-width: 0;
|
|
290
376
|
}
|
|
291
377
|
|
|
292
378
|
.name {
|
|
293
379
|
font-size: 16px;
|
|
294
380
|
font-weight: 600;
|
|
295
381
|
color: var(--text);
|
|
296
|
-
line-height: 1.
|
|
382
|
+
line-height: 1.3;
|
|
297
383
|
}
|
|
298
384
|
|
|
299
385
|
.handwritten .name {
|
|
300
386
|
font-family: 'Caveat', cursive;
|
|
301
387
|
font-size: 28px;
|
|
302
388
|
font-weight: 600;
|
|
389
|
+
line-height: 1.15;
|
|
303
390
|
}
|
|
304
391
|
|
|
305
392
|
.role {
|
|
306
|
-
font-size:
|
|
393
|
+
font-size: 14px;
|
|
394
|
+
line-height: 1.35;
|
|
307
395
|
color: var(--text-light);
|
|
396
|
+
margin-top: 4px;
|
|
397
|
+
font-family: var(--font-serif);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
.company {
|
|
401
|
+
align-self: flex-start;
|
|
402
|
+
font-size: 13px;
|
|
403
|
+
line-height: 1.35;
|
|
404
|
+
font-weight: 500;
|
|
405
|
+
color: var(--text);
|
|
406
|
+
text-decoration: none;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
a.company:hover {
|
|
410
|
+
text-decoration: underline;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.handwritten .company {
|
|
414
|
+
font-weight: 600;
|
|
308
415
|
}
|
|
309
416
|
|
|
310
417
|
.video-card {
|
|
311
|
-
width: 280px;
|
|
312
418
|
overflow: hidden;
|
|
313
419
|
padding: 0;
|
|
420
|
+
cursor: pointer;
|
|
314
421
|
}
|
|
315
422
|
|
|
316
|
-
.video-card
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
z-index: 1;
|
|
423
|
+
.video-card:focus-visible {
|
|
424
|
+
outline: 2px solid var(--accent);
|
|
425
|
+
outline-offset: 2px;
|
|
320
426
|
}
|
|
321
427
|
|
|
322
428
|
.poster {
|
|
@@ -344,13 +450,12 @@
|
|
|
344
450
|
right: 20px;
|
|
345
451
|
margin: 0;
|
|
346
452
|
font-family: var(--font-serif);
|
|
347
|
-
font-size:
|
|
453
|
+
font-size: 16px;
|
|
348
454
|
font-weight: 800;
|
|
349
455
|
line-height: 1.25;
|
|
350
456
|
letter-spacing: -0.01em;
|
|
351
457
|
color: #fff;
|
|
352
458
|
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
|
|
353
|
-
font-style: italic;
|
|
354
459
|
}
|
|
355
460
|
|
|
356
461
|
.play-btn {
|
|
@@ -400,7 +505,12 @@
|
|
|
400
505
|
padding: 40px 20px 20px;
|
|
401
506
|
background: linear-gradient(to top, rgba(0, 0, 0, 0.75), transparent);
|
|
402
507
|
display: flex;
|
|
403
|
-
|
|
508
|
+
align-items: center;
|
|
509
|
+
gap: 12px;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
.video-card .avatar.photo {
|
|
513
|
+
border: 2px solid rgba(255, 255, 255, 0.7);
|
|
404
514
|
}
|
|
405
515
|
|
|
406
516
|
.video-card .name {
|
|
@@ -411,11 +521,30 @@
|
|
|
411
521
|
color: rgba(255, 255, 255, 0.75);
|
|
412
522
|
}
|
|
413
523
|
|
|
414
|
-
|
|
415
|
-
.
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
524
|
+
.video-card .company {
|
|
525
|
+
color: rgba(255, 255, 255, 0.9);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.dots {
|
|
529
|
+
display: none;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
.dot {
|
|
533
|
+
width: 8px;
|
|
534
|
+
height: 8px;
|
|
535
|
+
padding: 0;
|
|
536
|
+
border: none;
|
|
537
|
+
border-radius: 50%;
|
|
538
|
+
background: var(--border);
|
|
539
|
+
cursor: pointer;
|
|
540
|
+
transition:
|
|
541
|
+
background 0.2s,
|
|
542
|
+
transform 0.2s;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.dot.active {
|
|
546
|
+
background: var(--accent);
|
|
547
|
+
transform: scale(1.3);
|
|
419
548
|
}
|
|
420
549
|
|
|
421
550
|
@media (max-width: 768px) {
|
|
@@ -429,13 +558,44 @@
|
|
|
429
558
|
height: 400px;
|
|
430
559
|
}
|
|
431
560
|
|
|
432
|
-
.
|
|
433
|
-
|
|
561
|
+
.text-card {
|
|
562
|
+
height: auto;
|
|
563
|
+
min-height: 400px;
|
|
434
564
|
}
|
|
565
|
+
}
|
|
435
566
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
567
|
+
@media (max-width: 640px) {
|
|
568
|
+
.cards-wrap {
|
|
569
|
+
padding: 24px 0 4px;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
.cards-row {
|
|
573
|
+
flex-wrap: nowrap;
|
|
574
|
+
justify-content: flex-start;
|
|
575
|
+
overflow-x: auto;
|
|
576
|
+
scroll-snap-type: x mandatory;
|
|
577
|
+
-webkit-overflow-scrolling: touch;
|
|
578
|
+
scrollbar-width: none;
|
|
579
|
+
padding: 0 24px;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
.cards-row::-webkit-scrollbar {
|
|
583
|
+
display: none;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
.card {
|
|
587
|
+
flex: 0 0 calc(100% - 32px);
|
|
588
|
+
width: calc(100% - 32px);
|
|
589
|
+
max-width: 360px;
|
|
590
|
+
scroll-snap-align: center;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
.dots {
|
|
594
|
+
display: flex;
|
|
595
|
+
justify-content: center;
|
|
596
|
+
align-items: center;
|
|
597
|
+
gap: 8px;
|
|
598
|
+
margin-top: 20px;
|
|
439
599
|
}
|
|
440
600
|
}
|
|
441
601
|
</style>
|
|
@@ -2,12 +2,19 @@ interface TextReview {
|
|
|
2
2
|
type: 'text';
|
|
3
3
|
name: string;
|
|
4
4
|
role: string;
|
|
5
|
+
company?: string;
|
|
6
|
+
companyUrl?: string;
|
|
7
|
+
imageUrl?: string;
|
|
8
|
+
summary?: string;
|
|
5
9
|
quote: string;
|
|
6
10
|
}
|
|
7
11
|
interface VideoReview {
|
|
8
12
|
type: 'video';
|
|
9
13
|
name: string;
|
|
10
14
|
role: string;
|
|
15
|
+
company: string;
|
|
16
|
+
companyUrl?: string;
|
|
17
|
+
imageUrl?: string;
|
|
11
18
|
videoUrl?: string;
|
|
12
19
|
posterUrl?: string;
|
|
13
20
|
summary?: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { default as Accordion } from './DetailsAccordion/DetailsAccordion.svelte';
|
|
2
2
|
export { default as Header } from './Header/Header.svelte';
|
|
3
3
|
export { default as HeaderNavLink } from './Header/HeaderNavLink.svelte';
|
|
4
|
+
export { default as HeaderNavMenu } from './Header/HeaderNavMenu.svelte';
|
|
4
5
|
export { default as HeaderLanguageToggle } from './Header/HeaderLanguageToggle.svelte';
|
|
5
6
|
export { buildLocalizedUrl } from './Header/language.js';
|
|
6
7
|
export type { LanguageOption } from './Header/language.js';
|
package/dist/marketing/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export { default as Accordion } from './DetailsAccordion/DetailsAccordion.svelte
|
|
|
3
3
|
// ## Header
|
|
4
4
|
export { default as Header } from './Header/Header.svelte';
|
|
5
5
|
export { default as HeaderNavLink } from './Header/HeaderNavLink.svelte';
|
|
6
|
+
export { default as HeaderNavMenu } from './Header/HeaderNavMenu.svelte';
|
|
6
7
|
export { default as HeaderLanguageToggle } from './Header/HeaderLanguageToggle.svelte';
|
|
7
8
|
export { buildLocalizedUrl } from './Header/language.js';
|
|
8
9
|
// ## Footer
|