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