@pradip1995/theme-sahsha 3.1.2 → 3.1.3
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/package.json
CHANGED
|
@@ -32,9 +32,16 @@ const CollectionsShowcaseClient = ({
|
|
|
32
32
|
}: CollectionsShowcaseClientProps) => {
|
|
33
33
|
const viewportRef = useRef<HTMLDivElement>(null)
|
|
34
34
|
const [activeId, setActiveId] = useState(() => getDefaultActiveTabId(tabs))
|
|
35
|
+
const [contentAnimating, setContentAnimating] = useState(false)
|
|
35
36
|
|
|
36
37
|
const activeProducts = productsByCollection[activeId] ?? []
|
|
37
38
|
|
|
39
|
+
const handleTabClick = (tabId: string) => {
|
|
40
|
+
if (tabId === activeId) return
|
|
41
|
+
setActiveId(tabId)
|
|
42
|
+
setContentAnimating(true)
|
|
43
|
+
}
|
|
44
|
+
|
|
38
45
|
useEffect(() => {
|
|
39
46
|
const viewport = viewportRef.current
|
|
40
47
|
if (viewport) {
|
|
@@ -42,6 +49,13 @@ const CollectionsShowcaseClient = ({
|
|
|
42
49
|
}
|
|
43
50
|
}, [activeId])
|
|
44
51
|
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (!contentAnimating) return
|
|
54
|
+
|
|
55
|
+
const timer = window.setTimeout(() => setContentAnimating(false), 360)
|
|
56
|
+
return () => window.clearTimeout(timer)
|
|
57
|
+
}, [contentAnimating, activeId])
|
|
58
|
+
|
|
45
59
|
const scrollByPage = (direction: "prev" | "next") => {
|
|
46
60
|
const viewport = viewportRef.current
|
|
47
61
|
if (!viewport) return
|
|
@@ -69,9 +83,9 @@ const CollectionsShowcaseClient = ({
|
|
|
69
83
|
type="button"
|
|
70
84
|
className={`collections-showcase__tab${isActive ? " is-active" : ""}`}
|
|
71
85
|
aria-current={isActive ? "true" : undefined}
|
|
72
|
-
onClick={() =>
|
|
86
|
+
onClick={() => handleTabClick(tab.id)}
|
|
73
87
|
>
|
|
74
|
-
{tab.title}
|
|
88
|
+
<span className="collections-showcase__tab-label">{tab.title}</span>
|
|
75
89
|
</button>
|
|
76
90
|
)
|
|
77
91
|
})}
|
|
@@ -88,7 +102,12 @@ const CollectionsShowcaseClient = ({
|
|
|
88
102
|
</button>
|
|
89
103
|
|
|
90
104
|
<div ref={viewportRef} className="collections-showcase__viewport">
|
|
91
|
-
<div
|
|
105
|
+
<div
|
|
106
|
+
key={activeId}
|
|
107
|
+
className={`collections-showcase__track${
|
|
108
|
+
contentAnimating ? " collections-showcase__track--enter" : ""
|
|
109
|
+
}`}
|
|
110
|
+
>
|
|
92
111
|
{activeProducts.length > 0 ? (
|
|
93
112
|
activeProducts.map((product) => (
|
|
94
113
|
<div key={product.id} className="collections-showcase__slide">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
|
-
import { useRef } from "react"
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react"
|
|
4
4
|
import { ChevronLeft, ChevronRight } from "lucide-react"
|
|
5
5
|
import { HttpTypes } from "@medusajs/types"
|
|
6
6
|
import type { ProductCardRating } from "@core/types/product-card"
|
|
@@ -12,36 +12,160 @@ type ProductCarouselProps = {
|
|
|
12
12
|
ratings?: ProductCardRating[]
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
const AUTO_SCROLL_MS = 4200
|
|
16
|
+
const AUTO_SCROLL_RESUME_MS = 5000
|
|
17
|
+
|
|
15
18
|
const ProductCarousel = ({ products, region, ratings }: ProductCarouselProps) => {
|
|
16
19
|
const viewportRef = useRef<HTMLDivElement>(null)
|
|
17
20
|
const trackRef = useRef<HTMLDivElement>(null)
|
|
21
|
+
const pauseAutoScrollRef = useRef(false)
|
|
22
|
+
const resumeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
23
|
+
const [canScrollLeft, setCanScrollLeft] = useState(false)
|
|
24
|
+
const [canScrollRight, setCanScrollRight] = useState(true)
|
|
25
|
+
const [reduceMotion, setReduceMotion] = useState(false)
|
|
18
26
|
|
|
19
|
-
const
|
|
27
|
+
const getSlideStep = useCallback(() => {
|
|
20
28
|
const viewport = viewportRef.current
|
|
21
29
|
const track = trackRef.current
|
|
22
|
-
if (!viewport || !track) return
|
|
30
|
+
if (!viewport || !track) return 0
|
|
23
31
|
|
|
24
32
|
const firstSlide = track.querySelector<HTMLElement>(".bestsellers-carousel__slide")
|
|
25
|
-
if (!firstSlide) return
|
|
33
|
+
if (!firstSlide) return viewport.clientWidth * 0.85
|
|
26
34
|
|
|
27
35
|
const trackStyles = getComputedStyle(track)
|
|
28
36
|
const gap =
|
|
29
37
|
Number.parseFloat(trackStyles.columnGap || trackStyles.gap || "0") || 0
|
|
30
|
-
const slideStep = firstSlide.offsetWidth + gap
|
|
31
38
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
return firstSlide.offsetWidth + gap
|
|
40
|
+
}, [])
|
|
41
|
+
|
|
42
|
+
const updateScrollState = useCallback(() => {
|
|
43
|
+
const viewport = viewportRef.current
|
|
44
|
+
if (!viewport) return
|
|
45
|
+
|
|
46
|
+
const { scrollLeft, scrollWidth, clientWidth } = viewport
|
|
47
|
+
const maxScroll = scrollWidth - clientWidth
|
|
48
|
+
|
|
49
|
+
setCanScrollLeft(scrollLeft > 4)
|
|
50
|
+
setCanScrollRight(scrollLeft < maxScroll - 4)
|
|
51
|
+
}, [])
|
|
52
|
+
|
|
53
|
+
const pauseAutoScroll = useCallback(() => {
|
|
54
|
+
pauseAutoScrollRef.current = true
|
|
55
|
+
|
|
56
|
+
if (resumeTimerRef.current) {
|
|
57
|
+
clearTimeout(resumeTimerRef.current)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
resumeTimerRef.current = setTimeout(() => {
|
|
61
|
+
pauseAutoScrollRef.current = false
|
|
62
|
+
}, AUTO_SCROLL_RESUME_MS)
|
|
63
|
+
}, [])
|
|
64
|
+
|
|
65
|
+
const scrollBySlide = useCallback(
|
|
66
|
+
(direction: "prev" | "next") => {
|
|
67
|
+
const viewport = viewportRef.current
|
|
68
|
+
if (!viewport) return
|
|
69
|
+
|
|
70
|
+
pauseAutoScroll()
|
|
71
|
+
|
|
72
|
+
const slideStep = getSlideStep()
|
|
73
|
+
viewport.scrollBy({
|
|
74
|
+
left: direction === "next" ? slideStep : -slideStep,
|
|
75
|
+
behavior: "smooth",
|
|
76
|
+
})
|
|
77
|
+
},
|
|
78
|
+
[getSlideStep, pauseAutoScroll]
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
const media = window.matchMedia("(prefers-reduced-motion: reduce)")
|
|
83
|
+
const update = () => setReduceMotion(media.matches)
|
|
84
|
+
update()
|
|
85
|
+
media.addEventListener("change", update)
|
|
86
|
+
return () => media.removeEventListener("change", update)
|
|
87
|
+
}, [])
|
|
88
|
+
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
const viewport = viewportRef.current
|
|
91
|
+
if (!viewport) return
|
|
92
|
+
|
|
93
|
+
updateScrollState()
|
|
94
|
+
|
|
95
|
+
const onScroll = () => updateScrollState()
|
|
96
|
+
viewport.addEventListener("scroll", onScroll, { passive: true })
|
|
97
|
+
window.addEventListener("resize", updateScrollState)
|
|
98
|
+
|
|
99
|
+
return () => {
|
|
100
|
+
viewport.removeEventListener("scroll", onScroll)
|
|
101
|
+
window.removeEventListener("resize", updateScrollState)
|
|
102
|
+
}
|
|
103
|
+
}, [products, updateScrollState])
|
|
104
|
+
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (reduceMotion || products.length < 3) return
|
|
107
|
+
|
|
108
|
+
const viewport = viewportRef.current
|
|
109
|
+
if (!viewport) return
|
|
110
|
+
|
|
111
|
+
const tick = () => {
|
|
112
|
+
if (pauseAutoScrollRef.current) return
|
|
113
|
+
|
|
114
|
+
const { scrollLeft, scrollWidth, clientWidth } = viewport
|
|
115
|
+
const maxScroll = scrollWidth - clientWidth
|
|
116
|
+
const step = getSlideStep()
|
|
117
|
+
|
|
118
|
+
if (maxScroll <= 0) return
|
|
119
|
+
|
|
120
|
+
if (scrollLeft >= maxScroll - 4) {
|
|
121
|
+
viewport.scrollTo({ left: 0, behavior: "smooth" })
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
viewport.scrollBy({ left: step, behavior: "smooth" })
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const intervalId = window.setInterval(tick, AUTO_SCROLL_MS)
|
|
129
|
+
|
|
130
|
+
return () => window.clearInterval(intervalId)
|
|
131
|
+
}, [reduceMotion, products, getSlideStep])
|
|
132
|
+
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
return () => {
|
|
135
|
+
if (resumeTimerRef.current) {
|
|
136
|
+
clearTimeout(resumeTimerRef.current)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}, [])
|
|
37
140
|
|
|
38
141
|
return (
|
|
39
|
-
<div
|
|
142
|
+
<div
|
|
143
|
+
className="bestsellers-carousel"
|
|
144
|
+
onMouseEnter={pauseAutoScroll}
|
|
145
|
+
onTouchStart={pauseAutoScroll}
|
|
146
|
+
onPointerDown={pauseAutoScroll}
|
|
147
|
+
>
|
|
148
|
+
<div
|
|
149
|
+
className={`bestsellers-carousel__fade bestsellers-carousel__fade--left${
|
|
150
|
+
canScrollLeft ? " is-visible" : ""
|
|
151
|
+
}`}
|
|
152
|
+
aria-hidden
|
|
153
|
+
/>
|
|
154
|
+
<div
|
|
155
|
+
className={`bestsellers-carousel__fade bestsellers-carousel__fade--right${
|
|
156
|
+
canScrollRight ? " is-visible" : ""
|
|
157
|
+
}`}
|
|
158
|
+
aria-hidden
|
|
159
|
+
/>
|
|
160
|
+
|
|
40
161
|
<button
|
|
41
162
|
type="button"
|
|
42
|
-
className=
|
|
163
|
+
className={`bestsellers-carousel__nav bestsellers-carousel__nav--prev${
|
|
164
|
+
canScrollLeft ? "" : " is-hidden"
|
|
165
|
+
}`}
|
|
43
166
|
onClick={() => scrollBySlide("prev")}
|
|
44
167
|
aria-label="Previous products"
|
|
168
|
+
tabIndex={canScrollLeft ? 0 : -1}
|
|
45
169
|
>
|
|
46
170
|
<ChevronLeft size={20} strokeWidth={1.75} />
|
|
47
171
|
</button>
|
|
@@ -66,9 +190,12 @@ const ProductCarousel = ({ products, region, ratings }: ProductCarouselProps) =>
|
|
|
66
190
|
|
|
67
191
|
<button
|
|
68
192
|
type="button"
|
|
69
|
-
className=
|
|
193
|
+
className={`bestsellers-carousel__nav bestsellers-carousel__nav--next${
|
|
194
|
+
canScrollRight ? "" : " is-hidden"
|
|
195
|
+
}`}
|
|
70
196
|
onClick={() => scrollBySlide("next")}
|
|
71
197
|
aria-label="Next products"
|
|
198
|
+
tabIndex={canScrollRight ? 0 : -1}
|
|
72
199
|
>
|
|
73
200
|
<ChevronRight size={20} strokeWidth={1.75} />
|
|
74
201
|
</button>
|
package/src/tokens/theme.css
CHANGED
|
@@ -2583,9 +2583,21 @@ body.mobile-menu-open .promo-bar {
|
|
|
2583
2583
|
}
|
|
2584
2584
|
}
|
|
2585
2585
|
|
|
2586
|
+
@keyframes collections-showcase-tab-enter {
|
|
2587
|
+
from {
|
|
2588
|
+
opacity: 0;
|
|
2589
|
+
transform: translateY(10px);
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
to {
|
|
2593
|
+
opacity: 1;
|
|
2594
|
+
transform: translateY(0);
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
|
|
2586
2598
|
.collections-showcase__tab {
|
|
2587
2599
|
margin: 0;
|
|
2588
|
-
padding: 0;
|
|
2600
|
+
padding: 0 0 0.4rem;
|
|
2589
2601
|
border: none;
|
|
2590
2602
|
background: none;
|
|
2591
2603
|
cursor: pointer;
|
|
@@ -2597,22 +2609,83 @@ body.mobile-menu-open .promo-bar {
|
|
|
2597
2609
|
line-height: 1.1;
|
|
2598
2610
|
letter-spacing: 0.01em;
|
|
2599
2611
|
color: #c8c8c8;
|
|
2600
|
-
|
|
2612
|
+
position: relative;
|
|
2613
|
+
transition:
|
|
2614
|
+
color 0.28s ease,
|
|
2615
|
+
transform 0.2s cubic-bezier(0.34, 1.4, 0.64, 1);
|
|
2601
2616
|
-webkit-tap-highlight-color: transparent;
|
|
2602
2617
|
outline: none;
|
|
2603
2618
|
box-shadow: none;
|
|
2604
2619
|
}
|
|
2605
2620
|
|
|
2621
|
+
.collections-showcase__tab-label {
|
|
2622
|
+
display: inline-block;
|
|
2623
|
+
transition: transform 0.2s cubic-bezier(0.34, 1.4, 0.64, 1);
|
|
2624
|
+
}
|
|
2625
|
+
|
|
2626
|
+
.collections-showcase__tab::after {
|
|
2627
|
+
content: "";
|
|
2628
|
+
position: absolute;
|
|
2629
|
+
left: 0;
|
|
2630
|
+
right: 0;
|
|
2631
|
+
bottom: 0;
|
|
2632
|
+
height: 2px;
|
|
2633
|
+
border-radius: 999px;
|
|
2634
|
+
background: currentColor;
|
|
2635
|
+
transform: scaleX(0);
|
|
2636
|
+
transform-origin: center;
|
|
2637
|
+
transition: transform 0.32s cubic-bezier(0.34, 1.2, 0.64, 1);
|
|
2638
|
+
}
|
|
2639
|
+
|
|
2606
2640
|
.collections-showcase__tab.is-active {
|
|
2607
2641
|
color: #1a1a1a;
|
|
2608
2642
|
font-weight: 500;
|
|
2609
2643
|
}
|
|
2610
2644
|
|
|
2645
|
+
.collections-showcase__tab.is-active::after {
|
|
2646
|
+
transform: scaleX(1);
|
|
2647
|
+
}
|
|
2648
|
+
|
|
2611
2649
|
.collections-showcase__tab:hover:not(.is-active),
|
|
2612
2650
|
.collections-showcase__tab:focus-visible:not(.is-active) {
|
|
2613
2651
|
color: #9a9a9a;
|
|
2614
2652
|
}
|
|
2615
2653
|
|
|
2654
|
+
.collections-showcase__tab:hover .collections-showcase__tab-label,
|
|
2655
|
+
.collections-showcase__tab:focus-visible .collections-showcase__tab-label {
|
|
2656
|
+
transform: translateY(-1px);
|
|
2657
|
+
}
|
|
2658
|
+
|
|
2659
|
+
.collections-showcase__tab:active .collections-showcase__tab-label {
|
|
2660
|
+
transform: scale(0.96);
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2663
|
+
.collections-showcase__tab.is-active:active .collections-showcase__tab-label {
|
|
2664
|
+
transform: scale(0.98);
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
.collections-showcase__track--enter {
|
|
2668
|
+
animation: collections-showcase-tab-enter 0.36s cubic-bezier(0.22, 1, 0.36, 1) both;
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2672
|
+
.collections-showcase__tab,
|
|
2673
|
+
.collections-showcase__tab-label,
|
|
2674
|
+
.collections-showcase__tab::after {
|
|
2675
|
+
transition: none;
|
|
2676
|
+
}
|
|
2677
|
+
|
|
2678
|
+
.collections-showcase__tab:hover .collections-showcase__tab-label,
|
|
2679
|
+
.collections-showcase__tab:focus-visible .collections-showcase__tab-label,
|
|
2680
|
+
.collections-showcase__tab:active .collections-showcase__tab-label {
|
|
2681
|
+
transform: none;
|
|
2682
|
+
}
|
|
2683
|
+
|
|
2684
|
+
.collections-showcase__track--enter {
|
|
2685
|
+
animation: none;
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
|
|
2616
2689
|
.collections-showcase__tab:focus,
|
|
2617
2690
|
.collections-showcase__tab:focus-visible {
|
|
2618
2691
|
outline: none;
|
|
@@ -3038,7 +3111,10 @@ body.mobile-menu-open .promo-bar {
|
|
|
3038
3111
|
overflow: hidden;
|
|
3039
3112
|
background: var(--color-brand-cream);
|
|
3040
3113
|
box-shadow: 0 4px 20px rgba(90, 42, 67, 0.07);
|
|
3041
|
-
|
|
3114
|
+
transform-origin: center;
|
|
3115
|
+
transition:
|
|
3116
|
+
box-shadow 0.35s ease,
|
|
3117
|
+
transform 0.28s cubic-bezier(0.34, 1.2, 0.64, 1);
|
|
3042
3118
|
}
|
|
3043
3119
|
|
|
3044
3120
|
.shop-by-category__card--top .shop-by-category__frame,
|
|
@@ -3048,7 +3124,13 @@ body.mobile-menu-open .promo-bar {
|
|
|
3048
3124
|
|
|
3049
3125
|
.shop-by-category__card:hover .shop-by-category__frame {
|
|
3050
3126
|
box-shadow: 0 12px 36px rgba(90, 42, 67, 0.15);
|
|
3051
|
-
transform: translateY(-3px);
|
|
3127
|
+
transform: translateY(-3px) scale(1.02);
|
|
3128
|
+
}
|
|
3129
|
+
|
|
3130
|
+
.shop-by-category__card:active .shop-by-category__frame {
|
|
3131
|
+
box-shadow: 0 6px 24px rgba(90, 42, 67, 0.12);
|
|
3132
|
+
transform: translateY(-1px) scale(0.98);
|
|
3133
|
+
transition-duration: 0.15s;
|
|
3052
3134
|
}
|
|
3053
3135
|
|
|
3054
3136
|
.shop-by-category__image {
|
|
@@ -3219,6 +3301,25 @@ body.mobile-menu-open .promo-bar {
|
|
|
3219
3301
|
}
|
|
3220
3302
|
}
|
|
3221
3303
|
|
|
3304
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3305
|
+
.shop-by-category__frame,
|
|
3306
|
+
.shop-by-category__image,
|
|
3307
|
+
.shop-by-category__overlay,
|
|
3308
|
+
.shop-by-category__count,
|
|
3309
|
+
.shop-by-category__cta {
|
|
3310
|
+
transition: none;
|
|
3311
|
+
}
|
|
3312
|
+
|
|
3313
|
+
.shop-by-category__card:hover .shop-by-category__frame,
|
|
3314
|
+
.shop-by-category__card:active .shop-by-category__frame {
|
|
3315
|
+
transform: none;
|
|
3316
|
+
}
|
|
3317
|
+
|
|
3318
|
+
.shop-by-category__card:hover .shop-by-category__image {
|
|
3319
|
+
transform: none;
|
|
3320
|
+
}
|
|
3321
|
+
}
|
|
3322
|
+
|
|
3222
3323
|
/* ── Account login / register (Sahsha split layout) ──────── */
|
|
3223
3324
|
.account-login {
|
|
3224
3325
|
display: flex;
|
|
@@ -5220,6 +5321,8 @@ body.mobile-menu-open .promo-bar {
|
|
|
5220
5321
|
position: sticky !important;
|
|
5221
5322
|
top: calc(var(--header-height) + var(--promo-bar-height, 0px) + 20px) !important;
|
|
5222
5323
|
align-self: flex-start !important;
|
|
5324
|
+
width: 100% !important;
|
|
5325
|
+
min-width: 0 !important;
|
|
5223
5326
|
height: fit-content !important;
|
|
5224
5327
|
max-height: calc(100vh - var(--header-height) - var(--promo-bar-height, 0px) - 40px) !important;
|
|
5225
5328
|
overflow: visible !important;
|
|
@@ -5230,6 +5333,7 @@ body.mobile-menu-open .promo-bar {
|
|
|
5230
5333
|
.product-details-scroll {
|
|
5231
5334
|
flex: 1;
|
|
5232
5335
|
min-width: 0;
|
|
5336
|
+
width: 100% !important;
|
|
5233
5337
|
height: auto !important;
|
|
5234
5338
|
max-height: none !important;
|
|
5235
5339
|
overflow: visible !important;
|
|
@@ -5244,12 +5348,21 @@ body.mobile-menu-open .promo-bar {
|
|
|
5244
5348
|
}
|
|
5245
5349
|
|
|
5246
5350
|
.product-gallery__stage-img {
|
|
5247
|
-
max-height:
|
|
5351
|
+
max-height: min(
|
|
5352
|
+
calc(100vh - var(--header-height) - var(--promo-bar-height, 0px) - 5rem),
|
|
5353
|
+
680px
|
|
5354
|
+
);
|
|
5248
5355
|
}
|
|
5249
5356
|
|
|
5250
5357
|
.product-gallery__thumbs--scrollable {
|
|
5251
|
-
height:
|
|
5252
|
-
|
|
5358
|
+
height: min(
|
|
5359
|
+
calc(100vh - var(--header-height) - var(--promo-bar-height, 0px) - 5rem),
|
|
5360
|
+
680px
|
|
5361
|
+
);
|
|
5362
|
+
max-height: min(
|
|
5363
|
+
calc(100vh - var(--header-height) - var(--promo-bar-height, 0px) - 5rem),
|
|
5364
|
+
680px
|
|
5365
|
+
);
|
|
5253
5366
|
}
|
|
5254
5367
|
}
|
|
5255
5368
|
|
|
@@ -5281,15 +5394,18 @@ body.mobile-menu-open .promo-bar {
|
|
|
5281
5394
|
@media (min-width: 1024px) {
|
|
5282
5395
|
.product-gallery {
|
|
5283
5396
|
display: grid;
|
|
5284
|
-
grid-template-columns: 5.25rem
|
|
5397
|
+
grid-template-columns: 5.25rem auto;
|
|
5285
5398
|
gap: 0.375rem;
|
|
5286
5399
|
align-items: start;
|
|
5400
|
+
width: fit-content;
|
|
5401
|
+
max-width: 100%;
|
|
5287
5402
|
background: #ffffff;
|
|
5288
5403
|
}
|
|
5289
5404
|
|
|
5290
5405
|
.product-gallery--single {
|
|
5291
5406
|
display: block;
|
|
5292
|
-
|
|
5407
|
+
width: fit-content;
|
|
5408
|
+
max-width: 100%;
|
|
5293
5409
|
}
|
|
5294
5410
|
|
|
5295
5411
|
.product-gallery__stage {
|
|
@@ -5314,8 +5430,14 @@ body.mobile-menu-open .promo-bar {
|
|
|
5314
5430
|
}
|
|
5315
5431
|
|
|
5316
5432
|
.product-gallery__thumbs--scrollable {
|
|
5317
|
-
height: min(
|
|
5318
|
-
|
|
5433
|
+
height: min(
|
|
5434
|
+
calc(100vh - var(--header-height) - var(--promo-bar-height, 0px) - 5rem),
|
|
5435
|
+
680px
|
|
5436
|
+
);
|
|
5437
|
+
max-height: min(
|
|
5438
|
+
calc(100vh - var(--header-height) - var(--promo-bar-height, 0px) - 5rem),
|
|
5439
|
+
680px
|
|
5440
|
+
);
|
|
5319
5441
|
}
|
|
5320
5442
|
|
|
5321
5443
|
.product-gallery__thumbs--static {
|
|
@@ -5365,16 +5487,18 @@ body.mobile-menu-open .promo-bar {
|
|
|
5365
5487
|
display: flex;
|
|
5366
5488
|
align-items: flex-start;
|
|
5367
5489
|
justify-content: center;
|
|
5368
|
-
width:
|
|
5490
|
+
width: fit-content;
|
|
5491
|
+
max-width: 100%;
|
|
5369
5492
|
min-height: 0;
|
|
5370
5493
|
overflow: visible;
|
|
5371
5494
|
}
|
|
5372
5495
|
|
|
5373
5496
|
.product-gallery__stage-img {
|
|
5374
5497
|
display: block;
|
|
5375
|
-
width:
|
|
5498
|
+
width: auto;
|
|
5499
|
+
max-width: 100%;
|
|
5376
5500
|
height: auto !important;
|
|
5377
|
-
max-height: min(
|
|
5501
|
+
max-height: min(70vh, 640px);
|
|
5378
5502
|
object-fit: contain !important;
|
|
5379
5503
|
object-position: center top;
|
|
5380
5504
|
}
|
|
@@ -11022,17 +11146,77 @@ body.checkout-modal-open nav {
|
|
|
11022
11146
|
.bestsellers-carousel {
|
|
11023
11147
|
position: relative;
|
|
11024
11148
|
container-type: inline-size;
|
|
11025
|
-
|
|
11149
|
+
}
|
|
11150
|
+
|
|
11151
|
+
.new-arrivals .bestsellers-carousel,
|
|
11152
|
+
.bestsellers .bestsellers-carousel {
|
|
11153
|
+
margin-inline: -0.5rem;
|
|
11154
|
+
padding-inline: 0.5rem;
|
|
11155
|
+
}
|
|
11156
|
+
|
|
11157
|
+
@media (min-width: 640px) {
|
|
11158
|
+
.new-arrivals .bestsellers-carousel,
|
|
11159
|
+
.bestsellers .bestsellers-carousel {
|
|
11160
|
+
margin-inline: -0.75rem;
|
|
11161
|
+
padding-inline: 0.75rem;
|
|
11162
|
+
}
|
|
11163
|
+
}
|
|
11164
|
+
|
|
11165
|
+
@media (min-width: 1024px) {
|
|
11166
|
+
.new-arrivals .bestsellers-carousel,
|
|
11167
|
+
.bestsellers .bestsellers-carousel {
|
|
11168
|
+
margin-inline: -1rem;
|
|
11169
|
+
padding-inline: 1rem;
|
|
11170
|
+
}
|
|
11171
|
+
}
|
|
11172
|
+
|
|
11173
|
+
.bestsellers-carousel__fade {
|
|
11174
|
+
position: absolute;
|
|
11175
|
+
top: 0;
|
|
11176
|
+
bottom: 0.25rem;
|
|
11177
|
+
z-index: 1;
|
|
11178
|
+
width: 2.5rem;
|
|
11179
|
+
pointer-events: none;
|
|
11180
|
+
opacity: 0;
|
|
11181
|
+
transition: opacity 0.3s ease;
|
|
11182
|
+
}
|
|
11183
|
+
|
|
11184
|
+
.bestsellers-carousel__fade.is-visible {
|
|
11185
|
+
opacity: 1;
|
|
11186
|
+
}
|
|
11187
|
+
|
|
11188
|
+
.bestsellers-carousel__fade--left {
|
|
11189
|
+
left: 0;
|
|
11190
|
+
background: linear-gradient(
|
|
11191
|
+
to right,
|
|
11192
|
+
var(--color-page-bg, #faf9f7) 0%,
|
|
11193
|
+
transparent 100%
|
|
11194
|
+
);
|
|
11195
|
+
}
|
|
11196
|
+
|
|
11197
|
+
.bestsellers-carousel__fade--right {
|
|
11198
|
+
right: 0;
|
|
11199
|
+
background: linear-gradient(
|
|
11200
|
+
to left,
|
|
11201
|
+
var(--color-page-bg, #faf9f7) 0%,
|
|
11202
|
+
transparent 100%
|
|
11203
|
+
);
|
|
11026
11204
|
}
|
|
11027
11205
|
|
|
11028
11206
|
.bestsellers-carousel__viewport {
|
|
11029
11207
|
overflow-x: auto;
|
|
11030
11208
|
overflow-y: hidden;
|
|
11031
|
-
scroll-snap-type: x
|
|
11209
|
+
scroll-snap-type: x proximity;
|
|
11032
11210
|
scroll-behavior: smooth;
|
|
11211
|
+
scroll-padding-inline: 0.5rem;
|
|
11033
11212
|
-webkit-overflow-scrolling: touch;
|
|
11034
11213
|
scrollbar-width: none;
|
|
11035
11214
|
overscroll-behavior-x: contain;
|
|
11215
|
+
cursor: grab;
|
|
11216
|
+
}
|
|
11217
|
+
|
|
11218
|
+
.bestsellers-carousel__viewport:active {
|
|
11219
|
+
cursor: grabbing;
|
|
11036
11220
|
}
|
|
11037
11221
|
|
|
11038
11222
|
.bestsellers-carousel__viewport::-webkit-scrollbar {
|
|
@@ -11044,11 +11228,13 @@ body.checkout-modal-open nav {
|
|
|
11044
11228
|
gap: 0.75rem;
|
|
11045
11229
|
width: max-content;
|
|
11046
11230
|
padding-bottom: 0.25rem;
|
|
11231
|
+
padding-inline-end: 0.5rem;
|
|
11047
11232
|
}
|
|
11048
11233
|
|
|
11049
11234
|
@media (min-width: 768px) {
|
|
11050
11235
|
.bestsellers-carousel__track {
|
|
11051
11236
|
gap: 1rem;
|
|
11237
|
+
padding-inline-end: 1rem;
|
|
11052
11238
|
}
|
|
11053
11239
|
}
|
|
11054
11240
|
|
|
@@ -11059,7 +11245,6 @@ body.checkout-modal-open nav {
|
|
|
11059
11245
|
min-width: 0;
|
|
11060
11246
|
overflow: hidden;
|
|
11061
11247
|
scroll-snap-align: start;
|
|
11062
|
-
scroll-snap-stop: always;
|
|
11063
11248
|
}
|
|
11064
11249
|
|
|
11065
11250
|
.bestsellers-carousel__slide .product-card {
|
|
@@ -11128,6 +11313,12 @@ body.checkout-modal-open nav {
|
|
|
11128
11313
|
transform: translateY(-1px);
|
|
11129
11314
|
}
|
|
11130
11315
|
|
|
11316
|
+
.bestsellers-carousel__nav.is-hidden {
|
|
11317
|
+
opacity: 0;
|
|
11318
|
+
visibility: hidden;
|
|
11319
|
+
pointer-events: none;
|
|
11320
|
+
}
|
|
11321
|
+
|
|
11131
11322
|
/* ── Promotional Banners ─────────────────────────────────── */
|
|
11132
11323
|
.promo-banners {
|
|
11133
11324
|
width: 100%;
|