@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pradip1995/theme-sahsha",
3
- "version": "3.1.2",
3
+ "version": "3.1.3",
4
4
  "description": "Sahsha storefront theme — Impulse-based editorial layout, luxury nav, and brand tokens",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -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={() => setActiveId(tab.id)}
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 className="collections-showcase__track">
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 scrollBySlide = (direction: "prev" | "next") => {
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
- viewport.scrollBy({
33
- left: direction === "next" ? slideStep : -slideStep,
34
- behavior: "smooth",
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 className="bestsellers-carousel">
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="bestsellers-carousel__nav bestsellers-carousel__nav--prev"
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="bestsellers-carousel__nav bestsellers-carousel__nav--next"
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>
@@ -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
- transition: color 0.25s ease, font-weight 0.25s ease;
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
- transition: box-shadow 0.4s ease, transform 0.4s ease;
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: calc(100vh - var(--header-height) - var(--promo-bar-height, 0px) - 4rem);
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: calc(100vh - var(--header-height) - var(--promo-bar-height, 0px) - 4rem);
5252
- max-height: calc(100vh - var(--header-height) - var(--promo-bar-height, 0px) - 4rem);
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 minmax(0, 1fr);
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
- grid-template-columns: 1fr;
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(33.125rem, 95vh, 1200px);
5318
- max-height: min(33.125rem, 95vh, 1200px);
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: 100%;
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: 100%;
5498
+ width: auto;
5499
+ max-width: 100%;
5376
5500
  height: auto !important;
5377
- max-height: min(95vh, 1200px);
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
- overflow: hidden;
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 mandatory;
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%;