@stackonward/cli 1.2.1 → 1.3.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.
- package/dist/index.js +17 -10
- package/dist/index.js.map +1 -1
- package/dist/resources/components/nuxt/site-source/app/app.vue +9 -6
- package/dist/resources/components/nuxt/site-source/app/assets/css/site-shell.css +268 -33
- package/dist/resources/components/nuxt/site-source/app/components/site/ApplicationHeader.vue +7 -4
- package/dist/resources/components/nuxt/site-source/app/components/site/ApplicationShell.vue +1 -1
- package/dist/resources/components/nuxt/site-source/app/components/site/ApplicationSidebar.vue +4 -3
- package/dist/resources/components/nuxt/site-source/app/components/site/BackToTop.vue +4 -12
- package/dist/resources/components/nuxt/site-source/app/components/site/ConsentSettingsButton.vue +24 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/ContentArticlePage.vue +18 -6
- package/dist/resources/components/nuxt/site-source/app/components/site/ContentListPage.vue +2 -2
- package/dist/resources/components/nuxt/site-source/app/components/site/CookieConsent.vue +44 -4
- package/dist/resources/components/nuxt/site-source/app/components/site/LocaleSwitcher.vue +57 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/MarketingFooter.vue +11 -9
- package/dist/resources/components/nuxt/site-source/app/components/site/MarketingHeader.vue +31 -19
- package/dist/resources/components/nuxt/site-source/app/components/site/MarketingShell.vue +7 -9
- package/dist/resources/components/nuxt/site-source/app/components/site/SiteBrand.vue +3 -2
- package/dist/resources/components/nuxt/site-source/app/components/site/StaticPage.vue +2 -1
- package/dist/resources/components/nuxt/site-source/app/components/site/ThemeSwitcher.vue +63 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/ToastViewport.vue +3 -2
- package/dist/resources/components/nuxt/site-source/app/composables/useConsent.ts +299 -51
- package/dist/resources/components/nuxt/site-source/app/composables/useNavigation.ts +49 -6
- package/dist/resources/components/nuxt/site-source/app/composables/useSeo.ts +4 -2
- package/dist/resources/components/nuxt/site-source/app/composables/useSiteShell.ts +29 -11
- package/dist/resources/components/nuxt/site-source/app/plugins/consent.ts +43 -0
- package/dist/resources/components/nuxt/site-source/app/types/site-shell.ts +146 -59
- package/dist/resources/components/registry.json +30 -0
- package/dist/resources/registry.json +3 -3
- package/dist/resources/templates/nuxt/app/app.config.ts +83 -38
- package/dist/resources/templates/nuxt/app/i18n/locales/en.json +124 -0
- package/dist/resources/templates/nuxt/app/pages/legal/cookies.vue +68 -0
- package/dist/resources/templates/nuxt/nuxt.config.ts +16 -0
- package/dist/resources/templates/nuxt/package.json +2 -2
- package/dist/resources/templates/nuxt/test/unit/consent.test.ts +289 -0
- package/dist/resources/templates/nuxt/vitest.config.ts +6 -0
- package/package.json +3 -3
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
const site = useSiteShell();
|
|
3
|
+
const { localeProperties, t } = useI18n();
|
|
4
|
+
const localeHead = useLocaleHead({ seo: true });
|
|
3
5
|
|
|
4
6
|
useHead(() => ({
|
|
5
|
-
htmlAttrs:
|
|
6
|
-
lang: site.value.defaultLocale,
|
|
7
|
-
},
|
|
7
|
+
htmlAttrs: localeHead.value.htmlAttrs,
|
|
8
8
|
titleTemplate: (title?: string) => (title ? `${title} | ${site.value.name}` : site.value.name),
|
|
9
9
|
meta: [
|
|
10
|
-
|
|
10
|
+
...(localeHead.value.meta || []),
|
|
11
|
+
{ name: "description", content: t(site.value.descriptionKey) },
|
|
11
12
|
{ property: "og:site_name", content: site.value.name },
|
|
12
13
|
{ property: "og:type", content: "website" },
|
|
13
14
|
],
|
|
15
|
+
link: localeHead.value.link || [],
|
|
14
16
|
script: site.value.url
|
|
15
17
|
? [
|
|
16
18
|
{
|
|
@@ -20,8 +22,8 @@ useHead(() => ({
|
|
|
20
22
|
"@type": "WebSite",
|
|
21
23
|
name: site.value.name,
|
|
22
24
|
url: site.value.url,
|
|
23
|
-
description: site.value.
|
|
24
|
-
inLanguage: site.value.defaultLocale,
|
|
25
|
+
description: t(site.value.descriptionKey),
|
|
26
|
+
inLanguage: localeProperties.value.language || site.value.defaultLocale,
|
|
25
27
|
}),
|
|
26
28
|
},
|
|
27
29
|
]
|
|
@@ -32,6 +34,7 @@ useHead(() => ({
|
|
|
32
34
|
<template>
|
|
33
35
|
<UApp>
|
|
34
36
|
<div class="site-root">
|
|
37
|
+
<a class="skip-link" href="#site-content">{{ t("site.skipToContent") }}</a>
|
|
35
38
|
<NuxtLoadingIndicator color="var(--site-color-primary)" />
|
|
36
39
|
<NuxtLayout>
|
|
37
40
|
<NuxtPage />
|
|
@@ -90,6 +90,24 @@
|
|
|
90
90
|
color-scheme: light;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
.dark {
|
|
94
|
+
--site-color-bg: #0b0f14;
|
|
95
|
+
--site-color-bg-soft: #101720;
|
|
96
|
+
--site-color-surface: #121922;
|
|
97
|
+
--site-color-surface-muted: #18212c;
|
|
98
|
+
--site-color-surface-elevated: #202c38;
|
|
99
|
+
--site-color-text: #f5f7fa;
|
|
100
|
+
--site-color-muted: #aab6c3;
|
|
101
|
+
--site-color-dimmed: #7f8c99;
|
|
102
|
+
--site-color-border: #2b3947;
|
|
103
|
+
--site-color-border-strong: #405163;
|
|
104
|
+
--site-shadow-soft: 0 18px 44px rgb(0 0 0 / 34%);
|
|
105
|
+
--site-shadow-strong: 0 30px 70px rgb(0 0 0 / 46%);
|
|
106
|
+
--ui-border-muted: #202c38;
|
|
107
|
+
|
|
108
|
+
color-scheme: dark;
|
|
109
|
+
}
|
|
110
|
+
|
|
93
111
|
* {
|
|
94
112
|
box-sizing: border-box;
|
|
95
113
|
}
|
|
@@ -137,6 +155,24 @@ summary {
|
|
|
137
155
|
min-height: 100dvh;
|
|
138
156
|
}
|
|
139
157
|
|
|
158
|
+
.skip-link {
|
|
159
|
+
position: fixed;
|
|
160
|
+
top: 12px;
|
|
161
|
+
left: 12px;
|
|
162
|
+
z-index: 100;
|
|
163
|
+
min-height: 44px;
|
|
164
|
+
border-radius: var(--site-radius-md);
|
|
165
|
+
background: var(--site-color-surface);
|
|
166
|
+
padding: 11px 16px;
|
|
167
|
+
color: var(--site-color-text);
|
|
168
|
+
box-shadow: var(--site-shadow-soft);
|
|
169
|
+
transform: translateY(calc(-100% - 20px));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.skip-link:focus {
|
|
173
|
+
transform: translateY(0);
|
|
174
|
+
}
|
|
175
|
+
|
|
140
176
|
.base-button,
|
|
141
177
|
.icon-button {
|
|
142
178
|
display: inline-flex;
|
|
@@ -178,7 +214,7 @@ summary {
|
|
|
178
214
|
|
|
179
215
|
.base-button--secondary {
|
|
180
216
|
border-color: rgb(168 101 80 / 34%);
|
|
181
|
-
background:
|
|
217
|
+
background: color-mix(in srgb, var(--site-color-surface) 82%, transparent);
|
|
182
218
|
color: var(--site-color-primary);
|
|
183
219
|
}
|
|
184
220
|
|
|
@@ -193,7 +229,7 @@ summary {
|
|
|
193
229
|
height: 44px;
|
|
194
230
|
border-color: rgb(168 101 80 / 22%);
|
|
195
231
|
border-radius: var(--site-radius-md);
|
|
196
|
-
background:
|
|
232
|
+
background: color-mix(in srgb, var(--site-color-surface) 78%, transparent);
|
|
197
233
|
color: var(--site-color-primary);
|
|
198
234
|
}
|
|
199
235
|
|
|
@@ -251,7 +287,7 @@ summary {
|
|
|
251
287
|
top: 0;
|
|
252
288
|
z-index: 40;
|
|
253
289
|
border-bottom: 1px solid rgb(219 227 232 / 82%);
|
|
254
|
-
background:
|
|
290
|
+
background: color-mix(in srgb, var(--site-color-surface) 88%, transparent);
|
|
255
291
|
backdrop-filter: blur(18px);
|
|
256
292
|
}
|
|
257
293
|
|
|
@@ -316,7 +352,7 @@ summary {
|
|
|
316
352
|
gap: 6px;
|
|
317
353
|
border: 1px solid var(--site-color-border);
|
|
318
354
|
border-radius: var(--site-radius-lg);
|
|
319
|
-
background:
|
|
355
|
+
background: color-mix(in srgb, var(--site-color-surface) 98%, transparent);
|
|
320
356
|
padding: 8px;
|
|
321
357
|
box-shadow: var(--site-shadow-soft);
|
|
322
358
|
transform: translateX(-50%);
|
|
@@ -345,7 +381,91 @@ summary {
|
|
|
345
381
|
}
|
|
346
382
|
|
|
347
383
|
.marketing-header__actions > .base-button--secondary {
|
|
348
|
-
background:
|
|
384
|
+
background: color-mix(in srgb, var(--site-color-surface) 78%, transparent);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.marketing-header__preferences,
|
|
388
|
+
.mobile-nav__preferences {
|
|
389
|
+
display: flex;
|
|
390
|
+
align-items: center;
|
|
391
|
+
gap: 8px;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
.site-preference {
|
|
395
|
+
position: relative;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.site-preference > summary {
|
|
399
|
+
display: inline-flex;
|
|
400
|
+
min-height: 44px;
|
|
401
|
+
align-items: center;
|
|
402
|
+
gap: 7px;
|
|
403
|
+
border: 1px solid var(--site-color-border);
|
|
404
|
+
border-radius: var(--site-radius-md);
|
|
405
|
+
background: color-mix(in srgb, var(--site-color-surface) 84%, transparent);
|
|
406
|
+
padding: 0 10px;
|
|
407
|
+
color: var(--site-color-text);
|
|
408
|
+
cursor: pointer;
|
|
409
|
+
font-size: 14px;
|
|
410
|
+
font-weight: 600;
|
|
411
|
+
list-style: none;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.site-preference > summary::-webkit-details-marker {
|
|
415
|
+
display: none;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.site-preference[open] > summary,
|
|
419
|
+
.site-preference > summary:hover {
|
|
420
|
+
border-color: var(--site-color-border-strong);
|
|
421
|
+
background: var(--site-color-surface-muted);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.site-preference__chevron {
|
|
425
|
+
transition: transform var(--site-transition-fast);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.site-preference[open] .site-preference__chevron {
|
|
429
|
+
transform: rotate(180deg);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
.site-preference__menu {
|
|
433
|
+
position: absolute;
|
|
434
|
+
top: calc(100% + 8px);
|
|
435
|
+
right: 0;
|
|
436
|
+
z-index: 60;
|
|
437
|
+
display: grid;
|
|
438
|
+
width: max-content;
|
|
439
|
+
min-width: 180px;
|
|
440
|
+
gap: 4px;
|
|
441
|
+
border: 1px solid var(--site-color-border);
|
|
442
|
+
border-radius: var(--site-radius-lg);
|
|
443
|
+
background: var(--site-color-surface);
|
|
444
|
+
padding: 6px;
|
|
445
|
+
box-shadow: var(--site-shadow-soft);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
.site-preference__menu button {
|
|
449
|
+
display: flex;
|
|
450
|
+
min-height: 44px;
|
|
451
|
+
align-items: center;
|
|
452
|
+
gap: 8px;
|
|
453
|
+
border: 0;
|
|
454
|
+
border-radius: var(--site-radius-md);
|
|
455
|
+
background: transparent;
|
|
456
|
+
padding: 0 10px;
|
|
457
|
+
color: var(--site-color-text);
|
|
458
|
+
cursor: pointer;
|
|
459
|
+
text-align: start;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.site-preference__menu button:hover,
|
|
463
|
+
.site-preference__menu button[aria-pressed="true"] {
|
|
464
|
+
background: var(--site-color-surface-muted);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.site-preference__check {
|
|
468
|
+
margin-inline-start: auto;
|
|
349
469
|
}
|
|
350
470
|
|
|
351
471
|
.marketing-header__menu-button {
|
|
@@ -358,7 +478,7 @@ summary {
|
|
|
358
478
|
|
|
359
479
|
.marketing-footer {
|
|
360
480
|
border-top: 1px solid var(--site-color-border);
|
|
361
|
-
background: linear-gradient(180deg, var(--site-color-surface),
|
|
481
|
+
background: linear-gradient(180deg, var(--site-color-surface), var(--site-color-bg-soft));
|
|
362
482
|
color: var(--site-color-text);
|
|
363
483
|
}
|
|
364
484
|
|
|
@@ -397,15 +517,25 @@ summary {
|
|
|
397
517
|
}
|
|
398
518
|
|
|
399
519
|
.marketing-footer__social a,
|
|
400
|
-
.marketing-footer__legal a
|
|
520
|
+
.marketing-footer__legal a,
|
|
521
|
+
.consent-settings-button {
|
|
401
522
|
color: var(--site-color-muted);
|
|
402
523
|
}
|
|
403
524
|
|
|
404
525
|
.marketing-footer__social a:hover,
|
|
405
|
-
.marketing-footer__legal a:hover
|
|
526
|
+
.marketing-footer__legal a:hover,
|
|
527
|
+
.consent-settings-button:hover {
|
|
406
528
|
color: var(--site-color-accent);
|
|
407
529
|
}
|
|
408
530
|
|
|
531
|
+
.consent-settings-button {
|
|
532
|
+
min-height: 44px;
|
|
533
|
+
border: 0;
|
|
534
|
+
background: transparent;
|
|
535
|
+
padding: 0;
|
|
536
|
+
cursor: pointer;
|
|
537
|
+
}
|
|
538
|
+
|
|
409
539
|
.marketing-footer__nav {
|
|
410
540
|
display: grid;
|
|
411
541
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
@@ -450,9 +580,6 @@ summary {
|
|
|
450
580
|
}
|
|
451
581
|
|
|
452
582
|
.back-to-top {
|
|
453
|
-
position: fixed;
|
|
454
|
-
right: 24px;
|
|
455
|
-
z-index: 45;
|
|
456
583
|
display: grid;
|
|
457
584
|
width: 44px;
|
|
458
585
|
height: 44px;
|
|
@@ -572,19 +699,60 @@ summary {
|
|
|
572
699
|
}
|
|
573
700
|
|
|
574
701
|
.site-consent {
|
|
575
|
-
position: fixed;
|
|
576
|
-
right: 24px;
|
|
577
|
-
bottom: 24px;
|
|
578
|
-
z-index: 50;
|
|
579
702
|
display: grid;
|
|
580
|
-
width:
|
|
581
|
-
max-
|
|
703
|
+
width: 100%;
|
|
704
|
+
max-height: min(70dvh, 560px);
|
|
582
705
|
gap: 14px;
|
|
583
706
|
border: 1px solid var(--site-color-border);
|
|
584
707
|
border-radius: var(--site-radius-lg);
|
|
585
|
-
background:
|
|
708
|
+
background: color-mix(in srgb, var(--site-color-surface) 96%, transparent);
|
|
586
709
|
padding: 16px;
|
|
587
710
|
box-shadow: var(--site-shadow-strong);
|
|
711
|
+
overflow-y: auto;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
.site-floating-stack {
|
|
715
|
+
position: fixed;
|
|
716
|
+
inset-block-end: max(24px, env(safe-area-inset-bottom));
|
|
717
|
+
inset-inline-end: max(24px, env(safe-area-inset-right));
|
|
718
|
+
z-index: 50;
|
|
719
|
+
display: flex;
|
|
720
|
+
width: min(430px, calc(100vw - 48px));
|
|
721
|
+
max-height: calc(100dvh - 48px - env(safe-area-inset-bottom));
|
|
722
|
+
align-items: flex-end;
|
|
723
|
+
flex-direction: column;
|
|
724
|
+
gap: 12px;
|
|
725
|
+
pointer-events: none;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
.site-floating-stack > * {
|
|
729
|
+
pointer-events: auto;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
.site-consent__header {
|
|
733
|
+
display: flex;
|
|
734
|
+
align-items: flex-start;
|
|
735
|
+
justify-content: space-between;
|
|
736
|
+
gap: 12px;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
.site-consent__header h2 {
|
|
740
|
+
margin: 0;
|
|
741
|
+
color: var(--site-color-text);
|
|
742
|
+
font-size: 18px;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
.site-consent__close {
|
|
746
|
+
display: grid;
|
|
747
|
+
width: 44px;
|
|
748
|
+
height: 44px;
|
|
749
|
+
flex: 0 0 auto;
|
|
750
|
+
place-items: center;
|
|
751
|
+
border: 0;
|
|
752
|
+
border-radius: 50%;
|
|
753
|
+
background: var(--site-color-surface-muted);
|
|
754
|
+
color: var(--site-color-text);
|
|
755
|
+
cursor: pointer;
|
|
588
756
|
}
|
|
589
757
|
|
|
590
758
|
.site-consent__message {
|
|
@@ -593,6 +761,23 @@ summary {
|
|
|
593
761
|
line-height: 1.55;
|
|
594
762
|
}
|
|
595
763
|
|
|
764
|
+
.site-consent__policy {
|
|
765
|
+
width: fit-content;
|
|
766
|
+
color: var(--site-color-primary);
|
|
767
|
+
font-weight: 650;
|
|
768
|
+
text-decoration: underline;
|
|
769
|
+
text-underline-offset: 3px;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
.site-consent__status {
|
|
773
|
+
margin: 0;
|
|
774
|
+
border-inline-start: 3px solid var(--site-color-warning);
|
|
775
|
+
padding-inline-start: 10px;
|
|
776
|
+
color: var(--site-color-muted);
|
|
777
|
+
font-size: 14px;
|
|
778
|
+
line-height: 1.5;
|
|
779
|
+
}
|
|
780
|
+
|
|
596
781
|
.site-consent__actions {
|
|
597
782
|
display: flex;
|
|
598
783
|
flex-wrap: wrap;
|
|
@@ -600,14 +785,6 @@ summary {
|
|
|
600
785
|
gap: 10px;
|
|
601
786
|
}
|
|
602
787
|
|
|
603
|
-
@media (width <= 520px) {
|
|
604
|
-
.site-consent {
|
|
605
|
-
right: 16px;
|
|
606
|
-
left: 16px;
|
|
607
|
-
width: auto;
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
|
|
611
788
|
.application-shell {
|
|
612
789
|
height: 100dvh;
|
|
613
790
|
min-height: 0;
|
|
@@ -625,7 +802,7 @@ summary {
|
|
|
625
802
|
align-items: center;
|
|
626
803
|
gap: 16px;
|
|
627
804
|
border-bottom: 1px solid var(--site-color-border);
|
|
628
|
-
background:
|
|
805
|
+
background: color-mix(in srgb, var(--site-color-surface) 90%, transparent);
|
|
629
806
|
padding: 0 20px;
|
|
630
807
|
backdrop-filter: blur(16px);
|
|
631
808
|
}
|
|
@@ -851,6 +1028,38 @@ summary {
|
|
|
851
1028
|
font-weight: 450;
|
|
852
1029
|
}
|
|
853
1030
|
|
|
1031
|
+
.storage-inventory {
|
|
1032
|
+
width: 100%;
|
|
1033
|
+
margin: 20px 0;
|
|
1034
|
+
overflow-x: auto;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
.storage-inventory table {
|
|
1038
|
+
width: 100%;
|
|
1039
|
+
min-width: 720px;
|
|
1040
|
+
border-collapse: collapse;
|
|
1041
|
+
color: var(--site-color-muted);
|
|
1042
|
+
font-size: 14px;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
.storage-inventory th,
|
|
1046
|
+
.storage-inventory td {
|
|
1047
|
+
border-bottom: 1px solid var(--site-color-border);
|
|
1048
|
+
padding: 12px;
|
|
1049
|
+
text-align: start;
|
|
1050
|
+
vertical-align: top;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
.storage-inventory thead th {
|
|
1054
|
+
color: var(--site-color-text);
|
|
1055
|
+
font-weight: 650;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
.storage-inventory code {
|
|
1059
|
+
color: var(--site-color-text);
|
|
1060
|
+
white-space: nowrap;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
854
1063
|
@media (width <= 860px) {
|
|
855
1064
|
:root {
|
|
856
1065
|
--site-shell-header-height: 64px;
|
|
@@ -870,6 +1079,7 @@ summary {
|
|
|
870
1079
|
}
|
|
871
1080
|
|
|
872
1081
|
.marketing-header__nav,
|
|
1082
|
+
.marketing-header__preferences,
|
|
873
1083
|
.marketing-header__actions > .base-button {
|
|
874
1084
|
display: none;
|
|
875
1085
|
}
|
|
@@ -886,7 +1096,7 @@ summary {
|
|
|
886
1096
|
display: none;
|
|
887
1097
|
width: min(100%, 100vw);
|
|
888
1098
|
border-top: 1px solid var(--site-color-border);
|
|
889
|
-
background:
|
|
1099
|
+
background: color-mix(in srgb, var(--site-color-surface) 98%, transparent);
|
|
890
1100
|
padding: 10px 12px 18px;
|
|
891
1101
|
}
|
|
892
1102
|
|
|
@@ -915,6 +1125,25 @@ summary {
|
|
|
915
1125
|
cursor: pointer;
|
|
916
1126
|
}
|
|
917
1127
|
|
|
1128
|
+
.mobile-nav__preferences {
|
|
1129
|
+
padding: 8px 12px 0;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
.mobile-nav__preferences .site-preference {
|
|
1133
|
+
flex: 1;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
.mobile-nav__preferences .site-preference > summary {
|
|
1137
|
+
width: 100%;
|
|
1138
|
+
justify-content: center;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
.mobile-nav__preferences .site-preference__menu {
|
|
1142
|
+
right: auto;
|
|
1143
|
+
left: 0;
|
|
1144
|
+
width: 100%;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
918
1147
|
.marketing-footer__inner,
|
|
919
1148
|
.marketing-footer__nav,
|
|
920
1149
|
.content-list__grid {
|
|
@@ -998,11 +1227,6 @@ summary {
|
|
|
998
1227
|
.content-article__related > h2 {
|
|
999
1228
|
width: min(100% - 32px, 960px);
|
|
1000
1229
|
}
|
|
1001
|
-
|
|
1002
|
-
.site-consent {
|
|
1003
|
-
right: 16px;
|
|
1004
|
-
bottom: 102px;
|
|
1005
|
-
}
|
|
1006
1230
|
}
|
|
1007
1231
|
|
|
1008
1232
|
@media (width <= 520px) {
|
|
@@ -1022,6 +1246,17 @@ summary {
|
|
|
1022
1246
|
.site-consent__actions .base-button {
|
|
1023
1247
|
flex: 1;
|
|
1024
1248
|
}
|
|
1249
|
+
|
|
1250
|
+
.site-floating-stack {
|
|
1251
|
+
inset-block-end: max(16px, env(safe-area-inset-bottom));
|
|
1252
|
+
inset-inline: 16px;
|
|
1253
|
+
width: auto;
|
|
1254
|
+
max-height: calc(100dvh - 32px - env(safe-area-inset-bottom));
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
.site-preference__current {
|
|
1258
|
+
display: none;
|
|
1259
|
+
}
|
|
1025
1260
|
}
|
|
1026
1261
|
|
|
1027
1262
|
@media (prefers-reduced-motion: reduce) {
|
package/dist/resources/components/nuxt/site-source/app/components/site/ApplicationHeader.vue
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
const site = useSiteShell();
|
|
3
|
+
const { t } = useI18n();
|
|
3
4
|
|
|
4
5
|
defineEmits<{
|
|
5
6
|
toggleSidebar: [];
|
|
@@ -12,7 +13,7 @@ defineEmits<{
|
|
|
12
13
|
<button
|
|
13
14
|
type="button"
|
|
14
15
|
class="icon-button application-header__menu-button"
|
|
15
|
-
aria-label="
|
|
16
|
+
:aria-label="t('navigation.toggleSidebar')"
|
|
16
17
|
@click="$emit('toggleSidebar')"
|
|
17
18
|
>
|
|
18
19
|
<span aria-hidden="true">☰</span>
|
|
@@ -26,9 +27,11 @@ defineEmits<{
|
|
|
26
27
|
|
|
27
28
|
<div class="application-header__right">
|
|
28
29
|
<slot name="actions">
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
<ThemeSwitcher />
|
|
31
|
+
<LocaleSwitcher />
|
|
32
|
+
<NuxtLinkLocale :to="site.homePath" class="base-button base-button--secondary">
|
|
33
|
+
{{ t("site.openMarketingSite") }}
|
|
34
|
+
</NuxtLinkLocale>
|
|
32
35
|
</slot>
|
|
33
36
|
</div>
|
|
34
37
|
</header>
|
package/dist/resources/components/nuxt/site-source/app/components/site/ApplicationSidebar.vue
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
const { appNavGroups } = useNavigation();
|
|
3
|
+
const { t } = useI18n();
|
|
3
4
|
|
|
4
5
|
defineEmits<{
|
|
5
6
|
navigate: [];
|
|
@@ -7,7 +8,7 @@ defineEmits<{
|
|
|
7
8
|
</script>
|
|
8
9
|
|
|
9
10
|
<template>
|
|
10
|
-
<aside class="application-sidebar" aria-label="
|
|
11
|
+
<aside class="application-sidebar" :aria-label="t('navigation.application')">
|
|
11
12
|
<nav class="application-sidebar__nav">
|
|
12
13
|
<section
|
|
13
14
|
v-for="group in appNavGroups"
|
|
@@ -15,7 +16,7 @@ defineEmits<{
|
|
|
15
16
|
class="application-sidebar__group"
|
|
16
17
|
>
|
|
17
18
|
<h2 v-if="group.label">{{ group.label }}</h2>
|
|
18
|
-
<
|
|
19
|
+
<NuxtLinkLocale
|
|
19
20
|
v-for="item in group.items"
|
|
20
21
|
:key="item.to"
|
|
21
22
|
:to="item.to"
|
|
@@ -33,7 +34,7 @@ defineEmits<{
|
|
|
33
34
|
}}</span>
|
|
34
35
|
<span>{{ item.label }}</span>
|
|
35
36
|
<small v-if="item.badge">{{ item.badge }}</small>
|
|
36
|
-
</
|
|
37
|
+
</NuxtLinkLocale>
|
|
37
38
|
</section>
|
|
38
39
|
</nav>
|
|
39
40
|
</aside>
|
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
const props = withDefaults(
|
|
3
|
-
defineProps<{
|
|
4
|
-
bottomOffset?: number;
|
|
5
|
-
}>(),
|
|
6
|
-
{
|
|
7
|
-
bottomOffset: 24,
|
|
8
|
-
},
|
|
9
|
-
);
|
|
10
|
-
|
|
11
2
|
const isVisible = ref(false);
|
|
3
|
+
const { t } = useI18n();
|
|
12
4
|
|
|
13
5
|
function updateVisibility(): void {
|
|
14
6
|
isVisible.value = window.scrollY > 320;
|
|
15
7
|
}
|
|
16
8
|
|
|
17
9
|
function scrollToTop(): void {
|
|
18
|
-
window.
|
|
10
|
+
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
11
|
+
window.scrollTo({ top: 0, behavior: reducedMotion ? "auto" : "smooth" });
|
|
19
12
|
}
|
|
20
13
|
|
|
21
14
|
onMounted(() => {
|
|
@@ -33,8 +26,7 @@ onBeforeUnmount(() => {
|
|
|
33
26
|
type="button"
|
|
34
27
|
class="back-to-top"
|
|
35
28
|
:class="{ 'back-to-top--visible': isVisible }"
|
|
36
|
-
:
|
|
37
|
-
aria-label="Back to top"
|
|
29
|
+
:aria-label="t('site.backToTop')"
|
|
38
30
|
@click="scrollToTop"
|
|
39
31
|
>
|
|
40
32
|
<UIcon name="i-lucide-chevron-up" class="back-to-top__icon" />
|
package/dist/resources/components/nuxt/site-source/app/components/site/ConsentSettingsButton.vue
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const site = useSiteShell();
|
|
3
|
+
const analytics = useAnalytics();
|
|
4
|
+
const consent = useConsent();
|
|
5
|
+
const { t } = useI18n();
|
|
6
|
+
|
|
7
|
+
const visible = computed(
|
|
8
|
+
() =>
|
|
9
|
+
site.value.consent.enabled &&
|
|
10
|
+
analytics.status.value !== "disabled" &&
|
|
11
|
+
consent.state.value.ready,
|
|
12
|
+
);
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<button
|
|
17
|
+
v-if="visible"
|
|
18
|
+
type="button"
|
|
19
|
+
class="consent-settings-button"
|
|
20
|
+
@click="consent.openSettings"
|
|
21
|
+
>
|
|
22
|
+
{{ t("consent.settings") }}
|
|
23
|
+
</button>
|
|
24
|
+
</template>
|
package/dist/resources/components/nuxt/site-source/app/components/site/ContentArticlePage.vue
CHANGED
|
@@ -5,6 +5,7 @@ defineProps<{
|
|
|
5
5
|
article: ContentArticle;
|
|
6
6
|
related?: ContentListItem[];
|
|
7
7
|
}>();
|
|
8
|
+
const { t } = useI18n();
|
|
8
9
|
</script>
|
|
9
10
|
|
|
10
11
|
<template>
|
|
@@ -13,9 +14,16 @@ defineProps<{
|
|
|
13
14
|
<p v-if="article.category" class="page-heading__eyebrow">{{ article.category }}</p>
|
|
14
15
|
<h1>{{ article.title }}</h1>
|
|
15
16
|
<p v-if="article.description">{{ article.description }}</p>
|
|
16
|
-
<span
|
|
17
|
+
<span
|
|
18
|
+
v-if="article.author || article.date || article.updatedAt"
|
|
19
|
+
class="content-article__meta"
|
|
20
|
+
>
|
|
17
21
|
{{
|
|
18
|
-
[
|
|
22
|
+
[
|
|
23
|
+
article.author,
|
|
24
|
+
article.date,
|
|
25
|
+
article.updatedAt && t("content.updated", { date: article.updatedAt }),
|
|
26
|
+
]
|
|
19
27
|
.filter(Boolean)
|
|
20
28
|
.join(" · ")
|
|
21
29
|
}}
|
|
@@ -26,14 +34,18 @@ defineProps<{
|
|
|
26
34
|
<slot />
|
|
27
35
|
</div>
|
|
28
36
|
|
|
29
|
-
<aside
|
|
30
|
-
|
|
37
|
+
<aside
|
|
38
|
+
v-if="related?.length"
|
|
39
|
+
class="content-article__related"
|
|
40
|
+
:aria-label="t('content.relatedRegion')"
|
|
41
|
+
>
|
|
42
|
+
<h2>{{ t("content.related") }}</h2>
|
|
31
43
|
<div class="content-list__grid">
|
|
32
|
-
<
|
|
44
|
+
<NuxtLinkLocale v-for="item in related" :key="item.to" :to="item.to" class="content-card">
|
|
33
45
|
<small v-if="item.category">{{ item.category }}</small>
|
|
34
46
|
<h3>{{ item.title }}</h3>
|
|
35
47
|
<p v-if="item.description">{{ item.description }}</p>
|
|
36
|
-
</
|
|
48
|
+
</NuxtLinkLocale>
|
|
37
49
|
</div>
|
|
38
50
|
</aside>
|
|
39
51
|
</article>
|
|
@@ -17,14 +17,14 @@ defineProps<{
|
|
|
17
17
|
</header>
|
|
18
18
|
|
|
19
19
|
<div class="content-list__grid">
|
|
20
|
-
<
|
|
20
|
+
<NuxtLinkLocale v-for="item in items" :key="item.to" :to="item.to" class="content-card">
|
|
21
21
|
<small v-if="item.category">{{ item.category }}</small>
|
|
22
22
|
<h2>{{ item.title }}</h2>
|
|
23
23
|
<p v-if="item.description">{{ item.description }}</p>
|
|
24
24
|
<span v-if="item.date || item.author">
|
|
25
25
|
{{ [item.author, item.date].filter(Boolean).join(" · ") }}
|
|
26
26
|
</span>
|
|
27
|
-
</
|
|
27
|
+
</NuxtLinkLocale>
|
|
28
28
|
</div>
|
|
29
29
|
</section>
|
|
30
30
|
</template>
|