srcdev-nuxt-components 9.0.14 → 9.0.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.
Files changed (108) hide show
  1. package/.claude/settings.json +25 -0
  2. package/.claude/skills/component-aria-landmark.md +68 -0
  3. package/.claude/skills/component-dynamic-slots.md +150 -0
  4. package/.claude/skills/component-local-style-override.md +126 -0
  5. package/.claude/skills/component-prop-driven-container-layout.md +42 -0
  6. package/.claude/skills/components/accordian-core.md +159 -0
  7. package/.claude/skills/components/contact-section.md +101 -0
  8. package/.claude/skills/components/expanding-panel.md +156 -0
  9. package/.claude/skills/components/eyebrow-text.md +25 -0
  10. package/.claude/skills/components/hero-text.md +25 -0
  11. package/.claude/skills/components/layout-grid-by-cols.md +147 -0
  12. package/.claude/skills/components/layout-row.md +35 -0
  13. package/.claude/skills/components/link-text.md +33 -0
  14. package/.claude/skills/components/page-hero-highlights.md +224 -0
  15. package/.claude/skills/components/services-card.md +28 -0
  16. package/.claude/skills/components/services-section.md +25 -0
  17. package/.claude/skills/components/stepper-list.md +227 -0
  18. package/.claude/skills/css-grid-max-width-gutters.md +67 -0
  19. package/.claude/skills/index.md +14 -3
  20. package/.claude/skills/storybook-add-story.md +60 -0
  21. package/.claude/skills/testing-add-unit-test.md +56 -0
  22. package/app/assets/styles/setup/01.config/index.css +0 -1
  23. package/app/assets/styles/setup/03.theming/default/_dark.css +2 -2
  24. package/app/assets/styles/setup/04.elements/forms/02.typography.css +1 -0
  25. package/app/assets/styles/setup/05.typography/02.utility-classes/_font-classes-page-link.css +14 -14
  26. package/app/assets/styles/setup/index.css +0 -1
  27. package/app/components/01.atoms/card/CardCore.vue +92 -0
  28. package/app/components/01.atoms/card/stories/CardCore.stories.ts +132 -0
  29. package/app/components/01.atoms/card/tests/CardCore.spec.ts +207 -0
  30. package/app/components/01.atoms/card/tests/__snapshots__/CardCore.spec.ts.snap +43 -0
  31. package/app/components/01.atoms/content-wrappers/content-columns-2/ContentColumns2.vue +51 -0
  32. package/app/components/01.atoms/content-wrappers/content-columns-2/stories/ContentColumns2.stories.ts +110 -0
  33. package/app/components/01.atoms/content-wrappers/content-columns-2/tests/ContentColumns2.spec.ts +105 -0
  34. package/app/components/01.atoms/content-wrappers/content-columns-2/tests/__snapshots__/ContentColumns2.spec.ts.snap +14 -0
  35. package/app/components/01.atoms/content-wrappers/content-width/ContentWidth.vue +88 -0
  36. package/app/components/01.atoms/content-wrappers/content-width/stories/ContentWidth.stories.ts +362 -0
  37. package/app/components/01.atoms/content-wrappers/content-width/tests/ContentWidth.spec.ts +132 -0
  38. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/LayoutGridByCols.vue +71 -0
  39. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/stories/LayoutGridByCols.stories.ts +219 -0
  40. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/LayoutGridByCols.spec.ts +174 -0
  41. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/__snapshots__/LayoutGrid.spec.ts.snap +36 -0
  42. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/__snapshots__/LayoutGridByCols.spec.ts.snap +36 -0
  43. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/LayoutGridByWidth.vue +70 -0
  44. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/stories/LayoutGridByWidth.stories.ts +220 -0
  45. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/LayoutGridByWidth.spec.ts +174 -0
  46. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGrid.spec.ts.snap +36 -0
  47. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGridByCols.spec.ts.snap +36 -0
  48. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGridByWidth.spec.ts.snap +36 -0
  49. package/app/components/01.atoms/text-blocks/eyebrow-text/stories/EyebrowText.stories.ts +1 -1
  50. package/app/components/01.atoms/text-blocks/hero-text/stories/HeroText.stories.ts +1 -1
  51. package/app/components/01.atoms/text-blocks/link-text/stories/LinkText.stories.ts +1 -1
  52. package/app/components/02.molecules/contact-section/stories/ContactSection.stories.ts +5 -0
  53. package/app/components/02.molecules/contact-section/tests/ContactSection.spec.ts +15 -0
  54. package/app/components/02.molecules/contact-section/tests/ContactSection.vue +25 -17
  55. package/app/components/{accordian → 02.molecules/expandable/accordian}/stories/AccordianCore.stories.ts +1 -1
  56. package/app/components/02.molecules/expandable/expanding-panel/stories/ExpandingPanel.stories.ts +245 -0
  57. package/app/components/02.molecules/expandable/expanding-panel/tests/ExpandingPanel.spec.ts +351 -0
  58. package/app/components/02.molecules/expandable/expanding-panel/tests/__snapshots__/ExpandingPanel.spec.ts.snap +38 -0
  59. package/app/components/02.molecules/navigation/navigation-horizontal/NavigationHorizontal.vue +139 -0
  60. package/app/components/02.molecules/navigation/navigation-horizontal/NavigationHorizontalAdvanced.vue +172 -0
  61. package/app/components/02.molecules/profile-section/ProfileSection.vue +2 -3
  62. package/app/components/02.molecules/profile-section/tests/ProfileSection.spec.ts +2 -2
  63. package/app/components/02.molecules/stepper-list/StepperList.vue +131 -92
  64. package/app/components/02.molecules/stepper-list/stories/StepperList.stories.ts +31 -0
  65. package/app/components/02.molecules/stepper-list/tests/StepperList.spec.ts +24 -0
  66. package/app/components/02.molecules/stepper-list/tests/__snapshots__/StepperList.spec.ts.snap +22 -9
  67. package/app/components/03.organisms/image-galleries/slider-gallery/SliderGallery.vue +782 -0
  68. package/app/components/03.organisms/image-galleries/slider-gallery/stories/SliderGallery.stories.ts +233 -0
  69. package/app/components/03.organisms/image-galleries/slider-gallery/tests/SliderGallery.spec.ts +226 -0
  70. package/app/components/03.organisms/image-galleries/slider-gallery/tests/__snapshots__/SliderGallery.spec.ts.snap +69 -0
  71. package/app/components/03.organisms/services/services-grids/ServicesCardGrid.vue +1 -1
  72. package/app/components/03.organisms/services/services-grids/ServicesSectionGrid.vue +1 -1
  73. package/app/components/03.organisms/services/services-section/ServicesSection.vue +2 -3
  74. package/app/components/04.templates/page-hero-highlights/PageHeroHighlights.vue +239 -0
  75. package/app/components/04.templates/page-hero-highlights/stories/PageHeroHighlights.stories.ts +404 -0
  76. package/app/components/04.templates/page-hero-highlights/tests/PageHeroHighlights.spec.ts +198 -0
  77. package/app/components/04.templates/page-hero-highlights/tests/__snapshots__/PageHeroHighlights.spec.ts.snap +19 -0
  78. package/app/components/container-glow/ContainerGlowCore.vue +20 -27
  79. package/app/components/forms/input-button/InputButtonCore.vue +105 -104
  80. package/app/components/glowing-border/stories/GlowingBorder.stories.ts +21 -21
  81. package/app/composables/useAriaLabelledById.ts +13 -0
  82. package/app/layouts/default.vue +8 -3
  83. package/app/pages/forms/examples/buttons/index.vue +6 -6
  84. package/app/pages/forms/examples/material/checkbox-radio-panels.vue +3 -3
  85. package/app/pages/forms/examples/material/text-fields.vue +607 -610
  86. package/app/pages/page-hero-highlights.vue +81 -0
  87. package/app/pages/ui/{display-card.vue → card-core.vue} +15 -15
  88. package/app/pages/ui/contact-section.vue +1 -1
  89. package/app/pages/ui/container-glow.vue +1 -1
  90. package/app/pages/ui/content-width.vue +126 -0
  91. package/app/pages/ui/glowing-border.vue +9 -9
  92. package/app/pages/ui/navigation/navigation-horizontal.vue +493 -0
  93. package/app/pages/ui/services/services-section/[slug].vue +3 -1
  94. package/nuxt.config.ts +4 -1
  95. package/package.json +2 -2
  96. package/app/assets/styles/setup/01.config/_basic-resets.css +0 -9
  97. package/app/components/content-columns/TwoColumns.vue +0 -59
  98. package/app/components/content-columns/stories/TwoColumns.stories.ts +0 -561
  99. package/app/components/content-containers/ContentContainer.vue +0 -89
  100. package/app/components/content-containers/stories/ContentContainer.stories.ts +0 -465
  101. package/app/components/content-grid/ContentGrid.vue +0 -85
  102. package/app/components/display-card/DisplayCard.vue +0 -122
  103. package/app/components/image-galleries/SliderGallery.vue +0 -786
  104. package/app/pages/ui/content-container.vue +0 -112
  105. /package/app/components/{accordian → 02.molecules/expandable/accordian}/AccordianCore.vue +0 -0
  106. /package/app/components/{accordian → 02.molecules/expandable/accordian}/tests/AccordianCore.spec.ts +0 -0
  107. /package/app/components/{accordian → 02.molecules/expandable/accordian}/tests/__snapshots__/AccordianCore.spec.ts.snap +0 -0
  108. /package/app/components/{expanding-panel → 02.molecules/expandable/expanding-panel}/ExpandingPanel.vue +0 -0
@@ -0,0 +1,782 @@
1
+ <template>
2
+ <div ref="sliderGalleryWrapper" class="slider-gallery" :class="[elementClasses]">
3
+ <div class="loading-state" :class="[{ galleryLoaded: !galleryLoaded }]">
4
+ <div class="loading-spinner"></div>
5
+ <p>Loading gallery...</p>
6
+ </div>
7
+
8
+ <div v-if="showGallery" class="gallery-content" :class="[{ galleryLoaded: !galleryLoaded }]">
9
+ <div ref="sliderGalleryImagesList" class="list">
10
+ <div v-for="(item, index) in galleryData" :key="index" class="item">
11
+ <NuxtImg :src="item.src" :alt="item.alt" @load="handleImageLoad(index)" @error="handleImageError(index)" />
12
+ <div class="content" :class="item.textBrightness">
13
+ <div v-show="item.stylist !== ''" class="author" :class="item.textBrightness">{{ item.stylist }}</div>
14
+ <div v-show="item.title !== ''" class="title" :class="item.textBrightness">{{ item.title }}</div>
15
+ <div v-show="item.category !== ''" class="topic" :class="item.textBrightness">{{ item.category }}</div>
16
+ <div v-show="item.description !== ''" class="description" :class="item.textBrightness">
17
+ {{ item.description }}
18
+ </div>
19
+ <div class="buttons" :class="item.textBrightness">
20
+ <button>SEE MORE</button>
21
+ </div>
22
+ </div>
23
+ </div>
24
+ </div>
25
+
26
+ <div ref="sliderGalleryThumbnailsList" class="thumbnail">
27
+ <div v-for="(item, index) in galleryData" :key="index" class="item">
28
+ <div class="inner">
29
+ <NuxtImg :src="item.src" :alt="item.alt" loading="lazy" />
30
+ <div class="content" :class="item.textBrightness">
31
+ <div v-show="item.thumbnail?.title !== ''" class="title" :class="item.textBrightness">
32
+ {{ item.thumbnail?.title }}
33
+ </div>
34
+ <div v-show="item.thumbnail?.description !== ''" class="description" :class="item.textBrightness">
35
+ {{ item.thumbnail?.description }}
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ </div>
41
+
42
+ <div class="arrows">
43
+ <button id="prev" ref="prevDom" aria-label="Previous image" @click.prevent="doPrevious()">
44
+ <Icon name="ic:outline-keyboard-arrow-left" class="arrows-icon" />
45
+ </button>
46
+ <button id="next" ref="nextDom" aria-label="Next image" @click.prevent="doNext()">
47
+ <Icon name="ic:outline-keyboard-arrow-right" class="arrows-icon" />
48
+ </button>
49
+ </div>
50
+
51
+ <div class="time"></div>
52
+ </div>
53
+ </div>
54
+ </template>
55
+
56
+ <script setup lang="ts">
57
+ import type { IGalleryData } from "../../../../types/components";
58
+
59
+ interface Props {
60
+ autoRun?: boolean;
61
+ autoRunInterval?: number;
62
+ animationDuration?: number;
63
+ styleClassPassthrough?: string | string[];
64
+ }
65
+
66
+ const props = withDefaults(defineProps<Props>(), {
67
+ autoRun: true,
68
+ autoRunInterval: 7000,
69
+ animationDuration: 3000,
70
+ styleClassPassthrough: () => [],
71
+ });
72
+
73
+ const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
74
+ const galleryData = defineModel<IGalleryData[]>("galleryData");
75
+
76
+ const sliderGalleryWrapper = useTemplateRef("sliderGalleryWrapper");
77
+ const sliderGalleryImagesList = useTemplateRef("sliderGalleryImagesList");
78
+ const sliderGalleryThumbnailsList = useTemplateRef("sliderGalleryThumbnailsList");
79
+
80
+ const transitionRunning = ref(false);
81
+ const galleryLoaded = ref(true);
82
+ const showGallery = ref(false);
83
+ const loadedImages = new Set<number>();
84
+ const preloadedImages: HTMLImageElement[] = [];
85
+
86
+ onMounted(async () => {
87
+ await nextTick();
88
+
89
+ // If no images or galleryData is empty, stop loading
90
+ if (!galleryData.value || galleryData.value.length === 0) {
91
+ galleryLoaded.value = false;
92
+ return;
93
+ }
94
+
95
+ // Create an array to hold image loading promises
96
+ const imageLoadPromises: Promise<void>[] = [];
97
+
98
+ // Preload the first image at minimum
99
+ const firstImageIndex = 0;
100
+ if (galleryData.value[firstImageIndex]) {
101
+ const img = new Image();
102
+ img.src = galleryData.value[firstImageIndex].src;
103
+
104
+ const promise = new Promise<void>((resolve) => {
105
+ img.onload = () => {
106
+ loadedImages.add(firstImageIndex);
107
+ resolve();
108
+ };
109
+ img.onerror = () => {
110
+ loadedImages.add(firstImageIndex); // Count as loaded anyway
111
+ resolve();
112
+ };
113
+ });
114
+
115
+ imageLoadPromises.push(promise);
116
+ preloadedImages.push(img);
117
+ }
118
+
119
+ // Wait for at least the first image to load
120
+ await Promise.race(imageLoadPromises);
121
+
122
+ setTimeout(() => {
123
+ galleryLoaded.value = false;
124
+ }, 500);
125
+
126
+ showGallery.value = true;
127
+ sliderGalleryWrapper.value?.addEventListener("keydown", handleKeyDown);
128
+ });
129
+
130
+ const handleImageLoad = (index: number) => {
131
+ loadedImages.add(index);
132
+ };
133
+
134
+ const handleImageError = (index: number) => {
135
+ loadedImages.add(index);
136
+ };
137
+
138
+ const doNext = () => {
139
+ if (transitionRunning.value) return;
140
+ showSlider("next");
141
+ };
142
+
143
+ const doPrevious = () => {
144
+ if (transitionRunning.value) return;
145
+ showSlider("prev");
146
+ };
147
+
148
+ let runTimeOut: ReturnType<typeof setTimeout> | undefined;
149
+ let runNextAuto: ReturnType<typeof setTimeout> | null = null;
150
+
151
+ function showSlider(type: string) {
152
+ transitionRunning.value = true;
153
+
154
+ const currentSliderItems = Array.from(sliderGalleryImagesList.value?.children || []);
155
+ const currentThumbnailItems = Array.from(sliderGalleryThumbnailsList.value?.children || []);
156
+
157
+ if (type === "next") {
158
+ if (currentSliderItems.length) {
159
+ const firstItem = currentSliderItems[0];
160
+ if (firstItem) {
161
+ sliderGalleryImagesList.value?.appendChild(firstItem);
162
+ }
163
+ }
164
+
165
+ if (currentThumbnailItems.length) {
166
+ const firstThumb = currentThumbnailItems[0];
167
+ if (firstThumb) {
168
+ sliderGalleryThumbnailsList.value?.appendChild(firstThumb);
169
+ }
170
+ }
171
+
172
+ sliderGalleryWrapper.value?.classList.add("next");
173
+ } else {
174
+ if (currentSliderItems.length) {
175
+ const lastItem = currentSliderItems[currentSliderItems.length - 1];
176
+ if (lastItem) {
177
+ lastItem.classList.add("prepend-item");
178
+ sliderGalleryImagesList.value?.prepend(lastItem);
179
+ }
180
+ }
181
+
182
+ if (currentThumbnailItems.length) {
183
+ const lastThumb = currentThumbnailItems[currentThumbnailItems.length - 1];
184
+ if (lastThumb) {
185
+ lastThumb.classList.add("prepend-item");
186
+ sliderGalleryThumbnailsList.value?.prepend(lastThumb);
187
+ }
188
+ }
189
+
190
+ void sliderGalleryWrapper.value?.offsetWidth; // Force reflow
191
+ sliderGalleryWrapper.value?.classList.add("prev");
192
+ }
193
+
194
+ clearTimeout(runTimeOut);
195
+ runTimeOut = setTimeout(() => {
196
+ if (sliderGalleryWrapper.value) {
197
+ sliderGalleryWrapper.value.classList.remove("next");
198
+ sliderGalleryWrapper.value.classList.remove("prev");
199
+
200
+ const items = sliderGalleryImagesList.value?.querySelectorAll(".prepend-item");
201
+ items?.forEach((item) => item.classList.remove("prepend-item"));
202
+
203
+ const thumbs = sliderGalleryThumbnailsList.value?.querySelectorAll(".prepend-item");
204
+ thumbs?.forEach((thumb) => thumb.classList.remove("prepend-item"));
205
+ }
206
+ transitionRunning.value = false;
207
+ }, props.animationDuration);
208
+
209
+ // Reset auto-run timer
210
+ if (runNextAuto) clearTimeout(runNextAuto);
211
+ runNextAuto = setTimeout(() => {
212
+ if (!props.autoRun || galleryLoaded.value) return;
213
+ doNext();
214
+ }, props.autoRunInterval);
215
+ }
216
+
217
+ // Add keyboard navigation event handlers
218
+ const handleKeyDown = (event: KeyboardEvent) => {
219
+ // Don't process key events if transition is running or gallery isn't loaded
220
+ if (transitionRunning.value || galleryLoaded.value) {
221
+ return;
222
+ }
223
+
224
+ if (event.key === "ArrowLeft") {
225
+ doPrevious();
226
+ } else if (event.key === "ArrowRight") {
227
+ doNext();
228
+ }
229
+ };
230
+
231
+ // Initialize auto-run only after loading completes
232
+ watch(galleryLoaded, (newValue) => {
233
+ if (!newValue && props.autoRun) {
234
+ if (runNextAuto) clearTimeout(runNextAuto);
235
+ runNextAuto = setTimeout(() => {
236
+ doNext();
237
+ }, props.autoRunInterval);
238
+ }
239
+ });
240
+
241
+ watch(
242
+ () => props.styleClassPassthrough,
243
+ () => {
244
+ resetElementClasses(props.styleClassPassthrough);
245
+ }
246
+ );
247
+
248
+ onBeforeUnmount(() => {
249
+ showGallery.value = false;
250
+ clearTimeout(runTimeOut);
251
+ if (runNextAuto) clearTimeout(runNextAuto);
252
+ sliderGalleryWrapper.value?.removeEventListener("keydown", handleKeyDown);
253
+ });
254
+ </script>
255
+
256
+ <style lang="css">
257
+ @layer components {
258
+ .slider-gallery {
259
+ --_animationDuration: v-bind(animationDuration + "ms");
260
+
261
+ --_thumbnailAspectRatio: 150 /220;
262
+
263
+ --_thumbnailWidth: var(--_thumbnailMobileWidth, 100px);
264
+ --_thumbnailHeight: var(--_thumbnailMobileHeight, 165px);
265
+
266
+ height: 100svh;
267
+ width: 100vw;
268
+ overflow: hidden;
269
+ position: absolute;
270
+ inset: 0 0 0 0;
271
+
272
+ z-index: 9999;
273
+ container-type: inline-size;
274
+
275
+ .loading-state {
276
+ position: absolute;
277
+ inset: 0 0 0 0;
278
+ z-index: 1000;
279
+ display: flex;
280
+ flex-direction: column;
281
+ background-color: var(--page-bg);
282
+ align-items: center;
283
+ justify-content: center;
284
+ color: var(--colour-text-default);
285
+ opacity: 1;
286
+ transition:
287
+ display 0.5s,
288
+ opacity 0.5s;
289
+ transition-behavior: allow-discrete;
290
+
291
+ &.galleryLoaded {
292
+ display: none;
293
+ opacity: 0;
294
+ }
295
+
296
+ .loading-spinner {
297
+ width: 50px;
298
+ height: 50px;
299
+ border: 5px solid rgba(0, 0, 0, 0.1);
300
+ border-radius: 50%;
301
+ border-top-color: #f1683a;
302
+ animation: spinner 1s ease-in-out infinite;
303
+ margin-bottom: 20px;
304
+ }
305
+
306
+ p {
307
+ font-size: 1.2em;
308
+ font-weight: 500;
309
+ }
310
+ }
311
+
312
+ .gallery-content {
313
+ width: 100%;
314
+ height: 100%;
315
+ position: relative;
316
+ /* opacity: 0; */
317
+ /* transition: opacity 0.5s ease-in-out; */
318
+
319
+ /* Removed empty ruleset for .galleryLoaded */
320
+ }
321
+
322
+ .list {
323
+ .item {
324
+ width: 100%;
325
+ height: 100%;
326
+ position: absolute;
327
+ inset: 0 0 0 0;
328
+
329
+ &:nth-child(1) {
330
+ z-index: 1;
331
+
332
+ .content {
333
+ .author,
334
+ .title,
335
+ .topic,
336
+ .description,
337
+ .buttons {
338
+ transform: translateY(50px);
339
+ filter: blur(20px);
340
+ opacity: 0;
341
+ animation: showContent 0.5s 1s linear 1 forwards;
342
+ }
343
+
344
+ .title {
345
+ animation-delay: 1.2s !important;
346
+ }
347
+ .topic {
348
+ animation-delay: 1.4s !important;
349
+ }
350
+ .description {
351
+ animation-delay: 1.6s !important;
352
+ }
353
+ .buttons {
354
+ animation-delay: 1.8s !important;
355
+ }
356
+ }
357
+ }
358
+
359
+ img {
360
+ width: 100%;
361
+ height: 100%;
362
+ object-fit: cover;
363
+ }
364
+
365
+ .content {
366
+ position: absolute;
367
+ top: 20%;
368
+ width: 1140px;
369
+ max-width: 80%;
370
+ left: 50%;
371
+ transform: translateX(-50%);
372
+ padding-right: 30%;
373
+ box-sizing: border-box;
374
+ text-shadow: 0 5px 10px #0004;
375
+
376
+ &.light {
377
+ color: #fff;
378
+ }
379
+ &.dark {
380
+ color: #000;
381
+ }
382
+
383
+ .author {
384
+ font-weight: bold;
385
+ letter-spacing: 10px;
386
+
387
+ &.light {
388
+ color: #fff;
389
+ }
390
+ &.dark {
391
+ color: #000;
392
+ }
393
+ }
394
+
395
+ .title {
396
+ font-size: 5em;
397
+ font-weight: bold;
398
+ line-height: 1.3em;
399
+
400
+ &.light {
401
+ color: #fff;
402
+ }
403
+ &.dark {
404
+ color: #000;
405
+ }
406
+ }
407
+ .topic {
408
+ font-size: 5em;
409
+ font-weight: bold;
410
+ line-height: 1.3em;
411
+
412
+ &.light {
413
+ color: #fff;
414
+ }
415
+ &.dark {
416
+ color: #000;
417
+ }
418
+ }
419
+
420
+ .buttons {
421
+ display: grid;
422
+ grid-template-columns: repeat(2, 130px);
423
+ grid-template-rows: 40px;
424
+ gap: 5px;
425
+ margin-top: 20px;
426
+
427
+ button {
428
+ background-color: #99999975;
429
+ border: 1px solid #fff;
430
+ color: #fff;
431
+ letter-spacing: 3px;
432
+ font-weight: 500;
433
+
434
+ &.light {
435
+ color: #fff;
436
+ }
437
+ &.dark {
438
+ color: #000;
439
+ }
440
+ }
441
+ }
442
+ }
443
+ }
444
+ }
445
+
446
+ .thumbnail {
447
+ position: absolute;
448
+ bottom: 50px;
449
+ left: 50%;
450
+ width: max-content;
451
+ z-index: 100;
452
+ display: flex;
453
+ gap: 20px;
454
+
455
+ @container (width >= 1024px) {
456
+ --_thumbnailWidth: var(--_thumbnailDesktopWidth, 150px);
457
+ --_thumbnailHeight: var(--_thumbnailDesktopHeight, 220px);
458
+ }
459
+
460
+ .item {
461
+ width: var(--_thumbnailWidth);
462
+ height: var(--_thumbnailHeight);
463
+ flex-shrink: 0;
464
+ position: relative;
465
+
466
+ border: var(--_thumbnailBorder, 1px solid transparent);
467
+ outline: var(--_thumbnailOutline, 1px solid transparent);
468
+ border-radius: var(--_thumbnailBorderRadius, 20px);
469
+ overflow: hidden;
470
+
471
+ .inner {
472
+ position: absolute;
473
+ inset: 0 0 0 0;
474
+ background-color: #0004;
475
+ z-index: 2;
476
+ }
477
+
478
+ img {
479
+ width: 100%;
480
+ height: 100%;
481
+ object-fit: cover;
482
+ }
483
+
484
+ .content {
485
+ position: absolute;
486
+ bottom: 10px;
487
+ left: 10px;
488
+ right: 10px;
489
+
490
+ .title {
491
+ font-weight: 500;
492
+
493
+ &.light {
494
+ color: #fff;
495
+ }
496
+ &.dark {
497
+ color: #000;
498
+ }
499
+ }
500
+
501
+ .description {
502
+ font-weight: 300;
503
+
504
+ &.light {
505
+ color: #fff;
506
+ }
507
+ &.dark {
508
+ color: #000;
509
+ }
510
+ }
511
+ }
512
+ }
513
+ }
514
+
515
+ /* arrows */
516
+ .arrows {
517
+ position: absolute;
518
+ top: 80%;
519
+ right: 52%;
520
+ z-index: 100;
521
+ width: 300px;
522
+ max-width: 30%;
523
+ display: flex;
524
+ gap: 20px;
525
+ align-items: center;
526
+
527
+ button {
528
+ display: grid;
529
+ justify-content: center;
530
+ align-items: center;
531
+ width: 40px;
532
+ height: 40px;
533
+ border-radius: 50%;
534
+ background-color: #eee4;
535
+ color: #fff;
536
+ font-family: monospace;
537
+ font-weight: bold;
538
+ transition: 0.5s;
539
+
540
+ border-width: 2px;
541
+ border-style: solid;
542
+ border-color: white;
543
+
544
+ &#prev {
545
+ --_translateX: -2px;
546
+ }
547
+
548
+ &#next {
549
+ --_translateX: 2px;
550
+ }
551
+
552
+ &:hover {
553
+ background-color: #fff;
554
+ color: #000;
555
+ }
556
+
557
+ .arrows-icon {
558
+ color: currentColor;
559
+ font-weight: 900;
560
+ height: 40px;
561
+ width: 40px;
562
+ translate: var(--_translateX) -3px;
563
+ }
564
+ }
565
+ }
566
+
567
+ .time {
568
+ position: absolute;
569
+ z-index: 1000;
570
+ width: 0%;
571
+ height: 3px;
572
+ background-color: #f1683a;
573
+ left: 0;
574
+ top: 0;
575
+ }
576
+
577
+ /* Slider carousel animations */
578
+ &.next {
579
+ .list {
580
+ .item {
581
+ &:nth-child(1) {
582
+ img {
583
+ width: var(--_thumbnailWidth);
584
+ height: var(--_thumbnailHeight);
585
+ position: absolute;
586
+ bottom: 50px;
587
+ left: 50%;
588
+ border-radius: 30px;
589
+ animation: showImage 0.5s linear 1 forwards;
590
+ }
591
+ }
592
+ }
593
+ }
594
+
595
+ .arrows {
596
+ button {
597
+ pointer-events: none;
598
+ }
599
+ }
600
+
601
+ .thumbnail {
602
+ animation: effectNext 0.5s linear 1 forwards;
603
+
604
+ .item {
605
+ &:nth-last-child(1) {
606
+ overflow: hidden;
607
+ animation: showThumbnail 0.5s linear 1 forwards;
608
+ }
609
+ }
610
+ }
611
+
612
+ .time {
613
+ animation: runningTime var(--_animationDuration) linear 1 forwards;
614
+ }
615
+ }
616
+
617
+ &.prev {
618
+ .list {
619
+ .item {
620
+ &:nth-child(2) {
621
+ z-index: 2;
622
+
623
+ img {
624
+ animation: outFrame 0.5s linear 1 forwards;
625
+ position: absolute;
626
+ bottom: 0;
627
+ left: 0;
628
+ }
629
+
630
+ .content {
631
+ .author,
632
+ .title,
633
+ .topic,
634
+ .description,
635
+ .buttons {
636
+ animation: contentOut 1.5s linear 1 forwards !important;
637
+ }
638
+ }
639
+ }
640
+ img {
641
+ z-index: 100;
642
+ }
643
+ }
644
+
645
+ .item.prepend-item {
646
+ z-index: 1; /* Ensure it's visible */
647
+ /* Any initial styles needed */
648
+ }
649
+ }
650
+
651
+ .arrows {
652
+ button {
653
+ pointer-events: none;
654
+ }
655
+ }
656
+
657
+ .thumbnail {
658
+ /* Add a transform to the entire thumbnail container */
659
+ animation: effectPrev 0.5s linear 1 forwards;
660
+
661
+ .item {
662
+ &:first-child {
663
+ /* Add the animated border effect */
664
+ &::before {
665
+ animation: countdownBorder 7s linear 1 forwards;
666
+ }
667
+ }
668
+ &:nth-child(1) {
669
+ overflow: hidden;
670
+ animation: showThumbnailPrev 0.5s linear 1 forwards;
671
+ }
672
+ }
673
+
674
+ .item.prepend-item {
675
+ opacity: 0;
676
+ transform: translateX(-20px);
677
+ /* Initial state for thumbnail animation */
678
+ }
679
+ }
680
+ .time {
681
+ animation: runningTime var(--_animationDuration) linear 1 forwards;
682
+ }
683
+ }
684
+ }
685
+
686
+ @keyframes showContent {
687
+ to {
688
+ transform: translateY(0px);
689
+ filter: blur(0px);
690
+ opacity: 1;
691
+ }
692
+ }
693
+
694
+ @keyframes showImage {
695
+ to {
696
+ bottom: 0;
697
+ left: 0;
698
+ width: 100%;
699
+ height: 100%;
700
+ border-radius: 0;
701
+ }
702
+ }
703
+
704
+ @keyframes showThumbnail {
705
+ from {
706
+ width: 0;
707
+ opacity: 0;
708
+ }
709
+ }
710
+
711
+ @keyframes effectNext {
712
+ from {
713
+ transform: translateX(calc(1 * var(--_thumbnailWidth)));
714
+ }
715
+ }
716
+
717
+ @keyframes runningTime {
718
+ from {
719
+ width: 100%;
720
+ }
721
+ to {
722
+ width: 0;
723
+ }
724
+ }
725
+
726
+ @keyframes outFrame {
727
+ to {
728
+ width: var(--_thumbnailWidth);
729
+ height: var(--_thumbnailHeight);
730
+ bottom: 50px;
731
+ left: 50%;
732
+ border-radius: 20px;
733
+ }
734
+ }
735
+
736
+ @keyframes contentOut {
737
+ to {
738
+ transform: translateY(calc(-1 * var(--_thumbnailWidth)));
739
+ filter: blur(20px);
740
+ opacity: 0;
741
+ }
742
+ }
743
+
744
+ @keyframes effectPrev {
745
+ from {
746
+ transform: translateX(calc(-1 * var(--_thumbnailWidth)));
747
+ }
748
+ to {
749
+ transform: translateX(0);
750
+ }
751
+ }
752
+
753
+ @keyframes showThumbnailPrev {
754
+ from {
755
+ opacity: 0;
756
+ transform: translateX(-20px);
757
+ }
758
+ to {
759
+ opacity: 1;
760
+ transform: translateX(0);
761
+ }
762
+ }
763
+
764
+ @keyframes spinner {
765
+ 0% {
766
+ transform: rotate(0deg);
767
+ }
768
+ 100% {
769
+ transform: rotate(360deg);
770
+ }
771
+ }
772
+
773
+ @media screen and (max-width: 678px) {
774
+ .slider-gallery .list .item .content {
775
+ padding-right: 0;
776
+ }
777
+ .slider-gallery .list .item .content .title {
778
+ font-size: 30px;
779
+ }
780
+ }
781
+ }
782
+ </style>