@pradip1995/theme-valero 1.0.1

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 (44) hide show
  1. package/README.md +16 -0
  2. package/package.json +59 -0
  3. package/src/blocks/home/Features/index.tsx +61 -0
  4. package/src/blocks/home/Hero/index.tsx +102 -0
  5. package/src/blocks/home/LovedByMoms/index.tsx +407 -0
  6. package/src/blocks/home/NewArrivals/index.tsx +48 -0
  7. package/src/blocks/home/ShopByAge/index.tsx +128 -0
  8. package/src/blocks/home/ShopByCategory/index.tsx +409 -0
  9. package/src/blocks/home/Testimonials/index.tsx +697 -0
  10. package/src/blocks/home/WhyChooseUs/index.tsx +62 -0
  11. package/src/layouts/MainLayoutShell.tsx +14 -0
  12. package/src/primitives/Button.tsx +30 -0
  13. package/src/primitives/Card.tsx +32 -0
  14. package/src/primitives/index.ts +2 -0
  15. package/src/slots/account/ForgotPassword/index.tsx +1 -0
  16. package/src/slots/account/Login/index.tsx +1 -0
  17. package/src/slots/account/LoginTemplate/index.tsx +44 -0
  18. package/src/slots/account/Register/index.tsx +1 -0
  19. package/src/slots/cart/CartItem/index.tsx +11 -0
  20. package/src/slots/cart/CartSummary/index.tsx +13 -0
  21. package/src/slots/checkout/CheckoutForm/index.tsx +1 -0
  22. package/src/slots/checkout/CheckoutSummary/index.tsx +1 -0
  23. package/src/slots/layout/Footer/index.tsx +104 -0
  24. package/src/slots/layout/Nav/index.tsx +97 -0
  25. package/src/slots/layout/PromoBar/index.tsx +19 -0
  26. package/src/slots/layout/PromoBar/promo-bar-content.tsx +174 -0
  27. package/src/slots/order/OrderDetails/index.tsx +12 -0
  28. package/src/slots/product/ProductActions/ProductCTASection.tsx +191 -0
  29. package/src/slots/product/ProductActions/ProductDetailsSection.tsx +137 -0
  30. package/src/slots/product/ProductActions/ProductFeaturePanel.tsx +245 -0
  31. package/src/slots/product/ProductActions/ProductHighlightsSection.tsx +99 -0
  32. package/src/slots/product/ProductActions/ProductOptionsSection.tsx +234 -0
  33. package/src/slots/product/ProductActions/ProductPriceSection.tsx +53 -0
  34. package/src/slots/product/ProductActions/ProductTrustSection.tsx +84 -0
  35. package/src/slots/product/ProductActions/index.tsx +161 -0
  36. package/src/slots/product/ProductCard/index.tsx +132 -0
  37. package/src/slots/product/ProductInfo/index.tsx +40 -0
  38. package/src/templates/StorePage/index.tsx +154 -0
  39. package/src/tokens/colors.js +16 -0
  40. package/src/tokens/colors.ts +21 -0
  41. package/src/tokens/fonts.ts +13 -0
  42. package/src/tokens/index.ts +3 -0
  43. package/src/tokens/spacing.ts +9 -0
  44. package/src/tokens/theme.css +91 -0
@@ -0,0 +1,697 @@
1
+ "use client"
2
+
3
+ import { useState, useEffect } from "react"
4
+ import Image from "next/image"
5
+
6
+ interface Testimonial {
7
+ id: string
8
+ text: string
9
+ name: string
10
+ rating: number
11
+ avatar?: string
12
+ }
13
+
14
+ interface TestimonialsProps {
15
+ initialData?: {
16
+ title: string
17
+ testimonials: Testimonial[]
18
+ } | null
19
+ }
20
+
21
+ const Testimonials = ({ initialData }: TestimonialsProps) => {
22
+ // Fallback to default testimonials if API returns empty
23
+ const defaultTestimonials: Testimonial[] = [
24
+ {
25
+ id: "1",
26
+ text: "Absolutely love the quality! The rompers are so soft, and the colors stay vibrant even after multiple washes. My little one looks adorable.",
27
+ name: "Priya S.",
28
+ rating: 5,
29
+ },
30
+ {
31
+ id: "2",
32
+ text: "The sizing guide was perfect. Shipping was super fast, received it in 2 days. The packaging was also very cute and sustainable.",
33
+ name: "Rahul M.",
34
+ rating: 5,
35
+ },
36
+ {
37
+ id: "3",
38
+ text: "Finally found trendy clothes for my toddler that are comfortable. ChocoMelon is my go-to for birthday outfits now!",
39
+ name: "Anita K.",
40
+ rating: 4.5,
41
+ },
42
+ {
43
+ id: "4",
44
+ text: "Best quality kids clothing I've ever bought. The fabric is so soft and the designs are adorable. Highly recommend!",
45
+ name: "Sneha P.",
46
+ rating: 5,
47
+ },
48
+ {
49
+ id: "5",
50
+ text: "My daughter loves wearing these clothes. They're comfortable for play and stylish enough for special occasions.",
51
+ name: "Rajesh K.",
52
+ rating: 5,
53
+ },
54
+ ]
55
+
56
+ const [currentIndex, setCurrentIndex] = useState(0)
57
+ const [title, setTitle] = useState<string>(initialData?.title || "Happy Parents Say About Us")
58
+ const [testimonials, setTestimonials] = useState<Testimonial[]>(
59
+ initialData?.testimonials && initialData.testimonials.length > 0
60
+ ? initialData.testimonials
61
+ : defaultTestimonials
62
+ )
63
+ // Always start with 1 to ensure consistent SSR/client hydration
64
+ const [itemsPerView, setItemsPerView] = useState(1)
65
+
66
+ useEffect(() => {
67
+ // Update itemsPerView based on window width after mount
68
+ const updateItemsPerView = () => {
69
+ if (window.innerWidth >= 768) {
70
+ setItemsPerView(3)
71
+ } else if (window.innerWidth >= 400) {
72
+ setItemsPerView(2)
73
+ } else {
74
+ setItemsPerView(1)
75
+ }
76
+ }
77
+
78
+ updateItemsPerView()
79
+ window.addEventListener('resize', updateItemsPerView)
80
+
81
+ return () => window.removeEventListener('resize', updateItemsPerView)
82
+ }, [])
83
+
84
+ const displayTestimonials = testimonials.length > 0 ? testimonials : defaultTestimonials
85
+
86
+ const getDisplayTestimonials = () => {
87
+ const endIndex = currentIndex + itemsPerView
88
+ if (endIndex <= displayTestimonials.length) {
89
+ return displayTestimonials.slice(currentIndex, endIndex)
90
+ }
91
+ return [...displayTestimonials.slice(currentIndex), ...displayTestimonials.slice(0, endIndex - displayTestimonials.length)]
92
+ }
93
+
94
+ const nextTestimonials = () => {
95
+ setCurrentIndex((prev) => (prev + itemsPerView) % Math.max(displayTestimonials.length, 1))
96
+ }
97
+
98
+ const prevTestimonials = () => {
99
+ setCurrentIndex((prev) => (prev - itemsPerView + displayTestimonials.length) % Math.max(displayTestimonials.length, 1))
100
+ }
101
+
102
+ const visibleTestimonials = getDisplayTestimonials()
103
+ // For 340px-399px range (itemsPerView = 1), always show navigation if more than 1 testimonial exists
104
+ const hasMore = itemsPerView === 1
105
+ ? displayTestimonials.length > 1
106
+ : displayTestimonials.length > itemsPerView
107
+
108
+ const getInitials = (name: string) => {
109
+ return name.charAt(0).toUpperCase()
110
+ }
111
+
112
+ const renderStars = (rating: number, testimonialId: string) => {
113
+ const fullStars = Math.floor(rating)
114
+ const hasHalfStar = rating % 1 !== 0
115
+
116
+ return (
117
+ <div className="flex gap-0.5 sm:gap-1 items-center">
118
+ {[...Array(5)].map((_, i) => {
119
+ if (i < fullStars) {
120
+ return (
121
+ <svg
122
+ key={i}
123
+ className="testimonial-star w-3 h-3 sm:w-4 sm:h-4 text-yellow-400 fill-current"
124
+ viewBox="0 0 20 20"
125
+ fill="currentColor"
126
+ >
127
+ <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
128
+ </svg>
129
+ )
130
+ } else if (i === fullStars && hasHalfStar) {
131
+ return (
132
+ <svg
133
+ key={i}
134
+ className="testimonial-star w-3 h-3 sm:w-4 sm:h-4 text-yellow-400"
135
+ viewBox="0 0 20 20"
136
+ fill="currentColor"
137
+ >
138
+ <defs>
139
+ <linearGradient id={`half-${i}-${testimonialId}`}>
140
+ <stop offset="50%" stopColor="currentColor" />
141
+ <stop offset="50%" stopColor="transparent" stopOpacity="1" />
142
+ </linearGradient>
143
+ </defs>
144
+ <path
145
+ fill={`url(#half-${i}-${testimonialId})`}
146
+ d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"
147
+ />
148
+ </svg>
149
+ )
150
+ } else {
151
+ return (
152
+ <svg
153
+ key={i}
154
+ className="testimonial-star w-3 h-3 sm:w-4 sm:h-4 text-gray-300"
155
+ viewBox="0 0 20 20"
156
+ fill="currentColor"
157
+ >
158
+ <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
159
+ </svg>
160
+ )
161
+ }
162
+ })}
163
+ </div>
164
+ )
165
+ }
166
+
167
+ return (
168
+ <>
169
+ <style dangerouslySetInnerHTML={{
170
+ __html: `
171
+ @media (min-width: 340px) and (max-width: 399px) {
172
+ .testimonials-outer-section {
173
+ padding-left: 0.5rem !important;
174
+ padding-right: 0.5rem !important;
175
+ }
176
+ .testimonials-container {
177
+ max-width: 100% !important;
178
+ padding: 1rem !important;
179
+ }
180
+ .testimonials-title {
181
+ font-size: 1.125rem !important;
182
+ margin-bottom: 1.25rem !important;
183
+ }
184
+ .testimonials-large-quote {
185
+ font-size: 2.5rem !important;
186
+ top: -0.5rem !important;
187
+ }
188
+ .testimonials-grid {
189
+ display: flex !important;
190
+ flex-wrap: nowrap !important;
191
+ flex-direction: row !important;
192
+ justify-content: flex-start !important;
193
+ align-items: stretch !important;
194
+ gap: 0 !important;
195
+ margin-bottom: 1.25rem !important;
196
+ overflow: visible !important;
197
+ width: 100% !important;
198
+ position: relative !important;
199
+ }
200
+ .testimonial-card {
201
+ width: 100% !important;
202
+ max-width: 100% !important;
203
+ min-width: 100% !important;
204
+ flex: 0 0 100% !important;
205
+ flex-shrink: 0 !important;
206
+ height: auto !important;
207
+ min-height: 180px !important;
208
+ padding: 0.875rem !important;
209
+ border-radius: 1.125rem !important;
210
+ margin: 0 !important;
211
+ display: block !important;
212
+ }
213
+ /* Force only first card to show at 340px-399px */
214
+ .testimonials-grid > .testimonial-card:nth-child(n+2) {
215
+ display: none !important;
216
+ visibility: hidden !important;
217
+ opacity: 0 !important;
218
+ width: 0 !important;
219
+ height: 0 !important;
220
+ overflow: hidden !important;
221
+ margin: 0 !important;
222
+ padding: 0 !important;
223
+ }
224
+ .testimonial-small-quote {
225
+ font-size: 1.75rem !important;
226
+ top: 0.625rem !important;
227
+ left: 0.625rem !important;
228
+ }
229
+ .testimonial-text {
230
+ font-size: 0.6875rem !important;
231
+ min-height: 55px !important;
232
+ margin-bottom: 0.625rem !important;
233
+ }
234
+ .testimonial-avatar {
235
+ width: 2.25rem !important;
236
+ height: 2.25rem !important;
237
+ }
238
+ .testimonial-name {
239
+ font-size: 0.6875rem !important;
240
+ }
241
+ .testimonial-star {
242
+ width: 0.6875rem !important;
243
+ height: 0.6875rem !important;
244
+ }
245
+ .testimonial-avatar-initials {
246
+ font-size: 0.6875rem !important;
247
+ }
248
+ .testimonial-star-container {
249
+ gap: 0.125rem !important;
250
+ }
251
+ .testimonials-nav-button {
252
+ width: 2rem !important;
253
+ height: 2rem !important;
254
+ display: flex !important;
255
+ }
256
+ .testimonials-nav-svg {
257
+ width: 1rem !important;
258
+ height: 1rem !important;
259
+ }
260
+ .testimonials-nav-container {
261
+ display: flex !important;
262
+ justify-content: center !important;
263
+ align-items: center !important;
264
+ gap: 0.75rem !important;
265
+ margin-top: 1rem !important;
266
+ visibility: visible !important;
267
+ opacity: 1 !important;
268
+ }
269
+ }
270
+ @media (min-width: 400px) and (max-width: 639px) {
271
+ .testimonials-outer-section {
272
+ padding-left: 0.5rem !important;
273
+ padding-right: 0.5rem !important;
274
+ }
275
+ .testimonials-container {
276
+ max-width: 100% !important;
277
+ padding: 0.75rem !important;
278
+ }
279
+ .testimonials-title {
280
+ font-size: 1.25rem !important;
281
+ margin-bottom: 1.25rem !important;
282
+ }
283
+ .testimonials-large-quote {
284
+ font-size: 3rem !important;
285
+ top: -0.5rem !important;
286
+ }
287
+ .testimonials-grid {
288
+ display: flex !important;
289
+ flex-wrap: wrap !important;
290
+ gap: 0.625rem !important;
291
+ margin-bottom: 1.25rem !important;
292
+ justify-content: center !important;
293
+ }
294
+ .testimonial-card {
295
+ width: calc(50% - 0.3125rem) !important;
296
+ max-width: calc(50% - 0.3125rem) !important;
297
+ min-width: 0 !important;
298
+ flex: 0 0 calc(50% - 0.3125rem) !important;
299
+ height: auto !important;
300
+ min-height: 200px !important;
301
+ padding: 0.75rem !important;
302
+ border-radius: 1.125rem !important;
303
+ display: block !important;
304
+ }
305
+ .testimonial-card:not(:first-child):not(:nth-child(2)) {
306
+ display: none !important;
307
+ }
308
+ .testimonial-small-quote {
309
+ font-size: 1.75rem !important;
310
+ top: 0.5rem !important;
311
+ left: 0.5rem !important;
312
+ }
313
+ .testimonial-text {
314
+ font-size: 0.625rem !important;
315
+ min-height: 55px !important;
316
+ margin-bottom: 0.5rem !important;
317
+ line-height: 1.4 !important;
318
+ }
319
+ .testimonial-avatar {
320
+ width: 2rem !important;
321
+ height: 2rem !important;
322
+ }
323
+ .testimonial-name {
324
+ font-size: 0.625rem !important;
325
+ }
326
+ .testimonial-star {
327
+ width: 0.6875rem !important;
328
+ height: 0.6875rem !important;
329
+ }
330
+ .testimonial-avatar-initials {
331
+ font-size: 0.6875rem !important;
332
+ }
333
+ .testimonial-star-container {
334
+ gap: 0.125rem !important;
335
+ }
336
+ .testimonials-nav-button {
337
+ width: 1.75rem !important;
338
+ height: 1.75rem !important;
339
+ }
340
+ .testimonials-nav-svg {
341
+ width: 0.75rem !important;
342
+ height: 0.75rem !important;
343
+ }
344
+ }
345
+ @media (min-width: 640px) and (max-width: 767px) {
346
+ .testimonials-container {
347
+ max-width: 100% !important;
348
+ padding: 1.5rem !important;
349
+ }
350
+ .testimonials-title {
351
+ font-size: 1.75rem !important;
352
+ margin-bottom: 2rem !important;
353
+ }
354
+ .testimonials-large-quote {
355
+ font-size: 4rem !important;
356
+ top: -0.75rem !important;
357
+ }
358
+ .testimonials-grid {
359
+ gap: 1.25rem !important;
360
+ margin-bottom: 2rem !important;
361
+ }
362
+ .testimonial-card {
363
+ width: calc(50% - 0.625rem) !important;
364
+ max-width: calc(50% - 0.625rem) !important;
365
+ min-width: 0 !important;
366
+ height: auto !important;
367
+ min-height: 240px !important;
368
+ padding: 1.25rem !important;
369
+ border-radius: 1.5rem !important;
370
+ }
371
+ .testimonial-small-quote {
372
+ font-size: 2.5rem !important;
373
+ top: 1rem !important;
374
+ left: 1rem !important;
375
+ }
376
+ .testimonial-text {
377
+ font-size: 0.8125rem !important;
378
+ min-height: 70px !important;
379
+ margin-bottom: 1rem !important;
380
+ }
381
+ .testimonial-avatar {
382
+ width: 2.75rem !important;
383
+ height: 2.75rem !important;
384
+ }
385
+ .testimonial-name {
386
+ font-size: 0.8125rem !important;
387
+ }
388
+ .testimonial-star {
389
+ width: 0.875rem !important;
390
+ height: 0.875rem !important;
391
+ }
392
+ .testimonial-avatar-initials {
393
+ font-size: 0.875rem !important;
394
+ }
395
+ .testimonial-star-container {
396
+ gap: 0.125rem !important;
397
+ }
398
+ .testimonials-nav-button {
399
+ width: 2.5rem !important;
400
+ height: 2.5rem !important;
401
+ }
402
+ .testimonials-nav-svg {
403
+ width: 1.125rem !important;
404
+ height: 1.125rem !important;
405
+ }
406
+ }
407
+ @media (min-width: 768px) and (max-width: 1023px) {
408
+ .testimonials-outer-section {
409
+ padding-left: 1rem !important;
410
+ padding-right: 1rem !important;
411
+ }
412
+ .testimonials-container {
413
+ max-width: 100% !important;
414
+ padding: 1rem !important;
415
+ }
416
+ .testimonials-title {
417
+ font-size: 1.5rem !important;
418
+ margin-bottom: 1.5rem !important;
419
+ }
420
+ .testimonials-large-quote {
421
+ font-size: 3.5rem !important;
422
+ top: -0.5rem !important;
423
+ }
424
+ .testimonials-grid {
425
+ gap: 0.75rem !important;
426
+ margin-bottom: 1.5rem !important;
427
+ justify-content: center !important;
428
+ }
429
+ .testimonial-card {
430
+ width: calc(33.333% - 0.5rem) !important;
431
+ max-width: calc(33.333% - 0.5rem) !important;
432
+ min-width: 0 !important;
433
+ flex: 0 0 calc(33.333% - 0.5rem) !important;
434
+ height: auto !important;
435
+ min-height: 220px !important;
436
+ padding: 0.875rem !important;
437
+ border-radius: 1.25rem !important;
438
+ }
439
+ .testimonial-small-quote {
440
+ font-size: 2rem !important;
441
+ top: 0.625rem !important;
442
+ left: 0.625rem !important;
443
+ }
444
+ .testimonial-text {
445
+ font-size: 0.6875rem !important;
446
+ min-height: 60px !important;
447
+ margin-bottom: 0.625rem !important;
448
+ line-height: 1.4 !important;
449
+ }
450
+ .testimonial-avatar {
451
+ width: 2.25rem !important;
452
+ height: 2.25rem !important;
453
+ }
454
+ .testimonial-name {
455
+ font-size: 0.6875rem !important;
456
+ }
457
+ .testimonial-star {
458
+ width: 0.75rem !important;
459
+ height: 0.75rem !important;
460
+ }
461
+ .testimonial-avatar-initials {
462
+ font-size: 0.75rem !important;
463
+ }
464
+ .testimonial-star-container {
465
+ gap: 0.125rem !important;
466
+ }
467
+ .testimonials-nav-button {
468
+ width: 2rem !important;
469
+ height: 2rem !important;
470
+ }
471
+ .testimonials-nav-svg {
472
+ width: 0.875rem !important;
473
+ height: 0.875rem !important;
474
+ }
475
+ }
476
+ @media (min-width: 1024px) and (max-width: 1440px) {
477
+ .testimonials-container {
478
+ max-width: 1360px !important;
479
+ padding: 2rem !important;
480
+ }
481
+ .testimonials-title {
482
+ font-size: 2.25rem !important;
483
+ margin-bottom: 3rem !important;
484
+ }
485
+ .testimonials-large-quote {
486
+ font-size: 6rem !important;
487
+ }
488
+ .testimonials-grid {
489
+ gap: 1.5rem !important;
490
+ margin-bottom: 2rem !important;
491
+ }
492
+ .testimonial-card {
493
+ width: calc(33.333% - 1rem) !important;
494
+ max-width: calc(33.333% - 1rem) !important;
495
+ min-width: 0 !important;
496
+ height: auto !important;
497
+ min-height: 260px !important;
498
+ padding: 1.5rem !important;
499
+ border-radius: 1.875rem !important;
500
+ }
501
+ .testimonial-small-quote {
502
+ font-size: 3rem !important;
503
+ top: 1rem !important;
504
+ left: 1rem !important;
505
+ }
506
+ .testimonial-text {
507
+ font-size: 0.875rem !important;
508
+ min-height: 80px !important;
509
+ margin-bottom: 1rem !important;
510
+ }
511
+ .testimonial-avatar {
512
+ width: 3rem !important;
513
+ height: 3rem !important;
514
+ }
515
+ .testimonial-name {
516
+ font-size: 0.875rem !important;
517
+ }
518
+ .testimonial-star {
519
+ width: 1rem !important;
520
+ height: 1rem !important;
521
+ }
522
+ .testimonial-avatar-initials {
523
+ font-size: 1rem !important;
524
+ }
525
+ .testimonial-star-container {
526
+ gap: 0.25rem !important;
527
+ }
528
+ .testimonials-nav-button {
529
+ width: 2.5rem !important;
530
+ height: 2.5rem !important;
531
+ }
532
+ .testimonials-nav-svg {
533
+ width: 1.25rem !important;
534
+ height: 1.25rem !important;
535
+ }
536
+ }
537
+ @media (min-width: 1441px) {
538
+ .testimonials-container {
539
+ max-width: 1360px !important;
540
+ padding: 2rem !important;
541
+ }
542
+ .testimonials-title {
543
+ font-size: 2.5rem !important;
544
+ margin-bottom: 3rem !important;
545
+ }
546
+ .testimonials-large-quote {
547
+ font-size: 8rem !important;
548
+ }
549
+ .testimonials-grid {
550
+ gap: 1.5rem !important;
551
+ margin-bottom: 2rem !important;
552
+ }
553
+ .testimonial-card {
554
+ width: calc(33.333% - 1rem) !important;
555
+ max-width: 400px !important;
556
+ min-width: 0 !important;
557
+ height: 268px !important;
558
+ padding: 1.5rem !important;
559
+ border-radius: 1.875rem !important;
560
+ }
561
+ .testimonial-small-quote {
562
+ font-size: 4rem !important;
563
+ }
564
+ .testimonial-text {
565
+ font-size: 0.875rem !important;
566
+ min-height: 80px !important;
567
+ }
568
+ .testimonial-star {
569
+ width: 1rem !important;
570
+ height: 1rem !important;
571
+ }
572
+ .testimonial-avatar-initials {
573
+ font-size: 1.125rem !important;
574
+ }
575
+ .testimonial-star-container {
576
+ gap: 0.25rem !important;
577
+ }
578
+ }
579
+ `
580
+ }} />
581
+ <div className="w-full py-8 sm:py-12 md:py-14 lg:py-16 px-4 sm:px-6 md:px-8 lg:px-12 xl:px-16 testimonials-outer-section bg-page-bg">
582
+ <div className="w-full flex justify-center">
583
+ <div className="relative w-full testimonials-container" style={{ maxWidth: '1360px' }}>
584
+ {/* Large Quotation Marks */}
585
+ <div className="absolute top-0 left-0 testimonials-large-quote font-bold text-purple-600 opacity-20 hidden sm:block font-quote leading-none">
586
+ "
587
+ </div>
588
+ <div className="absolute top-0 right-0 testimonials-large-quote font-bold text-purple-600 opacity-20 hidden sm:block font-quote leading-none">
589
+ "
590
+ </div>
591
+
592
+ {/* Title */}
593
+ <h2 className="text-xl sm:text-2xl md:text-3xl lg:text-4xl font-bold text-center mb-6 sm:mb-8 md:mb-10 lg:mb-12 relative z-10 testimonials-title text-heading">
594
+ {title}
595
+ </h2>
596
+
597
+ {/* Testimonials Grid */}
598
+ <div className="relative z-10">
599
+ <div className="flex flex-wrap justify-center testimonials-grid gap-4 sm:gap-5 md:gap-6">
600
+ {visibleTestimonials.map((testimonial) => (
601
+ <div
602
+ key={testimonial.id}
603
+ className="bg-white group relative testimonial-card w-full sm:w-auto transition-all duration-500 ease-out sm:hover:-translate-y-3 sm:hover:scale-[1.03] shadow-md hover:shadow-[0_25px_50px_-12px_rgba(29,78,216,0.15)] border border-transparent z-10 hover:z-20 cursor-default"
604
+ >
605
+ {/* Small Quotation Mark */}
606
+ <div
607
+ className="absolute top-3 sm:top-4 left-3 sm:left-4 testimonial-small-quote font-bold text-purple-600 opacity-30 transition-all duration-500 ease-out group-hover:opacity-50 group-hover:scale-125 group-hover:-translate-y-1 group-hover:-translate-x-1 font-quote leading-none"
608
+ >
609
+ "
610
+ </div>
611
+
612
+ {/* Review Content */}
613
+ <div className="relative z-10 mt-4 sm:mt-6 transition-transform duration-500 group-hover:translate-x-1">
614
+ <p className="text-xs sm:text-sm leading-relaxed mb-3 sm:mb-4 italic testimonial-text" >
615
+ {testimonial.text}
616
+ </p>
617
+
618
+ {/* Reviewer Info */}
619
+ <div className="flex items-center gap-2 sm:gap-3 mt-3 sm:mt-4">
620
+ <div className="testimonial-avatar w-10 h-10 sm:w-12 sm:h-12 rounded-full bg-purple-100 flex items-center justify-center flex-shrink-0 border-2 border-brand-accent-border transition-all duration-500 group-hover:border-brand-accent/40 group-hover:shadow-[0_0_15px_rgba(29,78,216,0.2)]">
621
+ {testimonial.avatar ? (
622
+ <Image
623
+ src={testimonial.avatar}
624
+ alt={testimonial.name}
625
+ width={48}
626
+ height={48}
627
+ className="w-full h-full rounded-full object-cover transition-transform duration-500 group-hover:scale-110"
628
+ />
629
+ ) : (
630
+ <span className="text-purple-700 font-bold testimonial-avatar-initials text-xs sm:text-sm md:text-base lg:text-lg transition-transform duration-500 group-hover:scale-110">
631
+ {getInitials(testimonial.name)}
632
+ </span>
633
+ )}
634
+ </div>
635
+ <div className="flex-1 min-w-0 transition-transform duration-500 group-hover:translate-x-1">
636
+ <p className="text-gray-900 font-bold text-xs sm:text-sm testimonial-name truncate transition-colors duration-300 group-hover:text-brand-accent">
637
+ {testimonial.name}
638
+ </p>
639
+ {/* Star Rating */}
640
+ <div className="testimonial-star-container transition-transform duration-500 group-hover:scale-105 origin-left">
641
+ {renderStars(testimonial.rating, testimonial.id)}
642
+ </div>
643
+ </div>
644
+ </div>
645
+ </div>
646
+ </div>
647
+ ))}
648
+ </div>
649
+
650
+ {/* Navigation Arrows */}
651
+ {hasMore && (
652
+ <div className="flex justify-center items-center gap-3 sm:gap-4 mt-4 sm:mt-6 testimonials-nav-container">
653
+ <button
654
+ onClick={prevTestimonials}
655
+ className="testimonials-nav-button w-8 h-8 sm:w-10 sm:h-10 rounded-full bg-white border-2 border-gray-300 flex items-center justify-center transition-colors hover:bg-purple-600 hover:border-purple-600 hover:text-white"
656
+ aria-label="Previous testimonials"
657
+ >
658
+ <svg
659
+ className="testimonials-nav-svg w-4 h-4 sm:w-5 sm:h-5"
660
+ viewBox="0 0 24 24"
661
+ fill="none"
662
+ stroke="currentColor"
663
+ strokeWidth="2"
664
+ strokeLinecap="round"
665
+ strokeLinejoin="round"
666
+ >
667
+ <path d="M19 12H5M12 19l-7-7 7-7" />
668
+ </svg>
669
+ </button>
670
+ <button
671
+ onClick={nextTestimonials}
672
+ className="testimonials-nav-button w-8 h-8 sm:w-10 sm:h-10 rounded-full border-2 border-brand-accent flex items-center justify-center text-white transition-colors bg-brand-accent hover:bg-brand-accent-hover"
673
+ aria-label="Next testimonials"
674
+ >
675
+ <svg
676
+ className="testimonials-nav-svg w-4 h-4 sm:w-5 sm:h-5"
677
+ viewBox="0 0 24 24"
678
+ fill="none"
679
+ stroke="currentColor"
680
+ strokeWidth="2"
681
+ strokeLinecap="round"
682
+ strokeLinejoin="round"
683
+ >
684
+ <path d="M5 12h14M12 5l7 7-7 7" />
685
+ </svg>
686
+ </button>
687
+ </div>
688
+ )}
689
+ </div>
690
+ </div>
691
+ </div>
692
+ </div>
693
+ </>
694
+ )
695
+ }
696
+
697
+ export default Testimonials