@fayz-ai/storefront 0.9.0 → 0.10.0

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 (368) hide show
  1. package/README.md +3 -3
  2. package/dist/app/createStorefrontApp.d.ts +65 -0
  3. package/dist/app/createStorefrontApp.d.ts.map +1 -0
  4. package/dist/{define.d.ts → app/define.d.ts} +3 -3
  5. package/dist/app/define.d.ts.map +1 -0
  6. package/dist/app/hydration.d.ts +37 -0
  7. package/dist/app/hydration.d.ts.map +1 -0
  8. package/dist/app/prerender.d.ts +57 -0
  9. package/dist/app/prerender.d.ts.map +1 -0
  10. package/dist/{router.d.ts → app/router.d.ts} +140 -113
  11. package/dist/app/router.d.ts.map +1 -0
  12. package/dist/{scaffold.d.ts → app/scaffold.d.ts} +2 -2
  13. package/dist/app/scaffold.d.ts.map +1 -0
  14. package/dist/app/serving.d.ts +70 -0
  15. package/dist/app/serving.d.ts.map +1 -0
  16. package/dist/app/static-render.d.ts +46 -0
  17. package/dist/app/static-render.d.ts.map +1 -0
  18. package/dist/blocks/block-at-path.d.ts +59 -0
  19. package/dist/blocks/block-at-path.d.ts.map +1 -0
  20. package/dist/blocks/page-blocks.d.ts +163 -0
  21. package/dist/blocks/page-blocks.d.ts.map +1 -0
  22. package/dist/blocks/page-data.d.ts +105 -0
  23. package/dist/blocks/page-data.d.ts.map +1 -0
  24. package/dist/{blocks.d.ts → blocks/registry.d.ts} +1 -1
  25. package/dist/blocks/registry.d.ts.map +1 -0
  26. package/dist/{sections.d.ts → blocks/sections.d.ts} +40 -2
  27. package/dist/blocks/sections.d.ts.map +1 -0
  28. package/dist/chunk-6B7H3IZ6.js +10232 -0
  29. package/dist/chunk-6B7H3IZ6.js.map +1 -0
  30. package/dist/chunk-6IXTENLB.js +162 -0
  31. package/dist/chunk-6IXTENLB.js.map +1 -0
  32. package/dist/components/PaymentTerms.d.ts +34 -0
  33. package/dist/components/PaymentTerms.d.ts.map +1 -0
  34. package/dist/components/SmoothImage.d.ts +1 -1
  35. package/dist/components/SmoothImage.d.ts.map +1 -1
  36. package/dist/components/account/CustomerAccountShell.d.ts.map +1 -0
  37. package/dist/components/account/SignInModal.d.ts.map +1 -0
  38. package/dist/components/cart/CartDrawer.d.ts.map +1 -0
  39. package/dist/components/cart/QuantityInput.d.ts.map +1 -0
  40. package/dist/components/checkout/DeliveryEstimator.d.ts.map +1 -0
  41. package/dist/components/collection/CategoryShowcase.d.ts +44 -0
  42. package/dist/components/collection/CategoryShowcase.d.ts.map +1 -0
  43. package/dist/components/collection/FiltersPanel.d.ts +19 -0
  44. package/dist/components/collection/FiltersPanel.d.ts.map +1 -0
  45. package/dist/components/collection/ProductGrid.d.ts.map +1 -0
  46. package/dist/components/layout/PageBodyBlocks.d.ts +40 -0
  47. package/dist/components/layout/PageBodyBlocks.d.ts.map +1 -0
  48. package/dist/components/layout/SearchOverlay.d.ts +13 -0
  49. package/dist/components/layout/SearchOverlay.d.ts.map +1 -0
  50. package/dist/components/layout/StorefrontErrorBoundary.d.ts.map +1 -0
  51. package/dist/components/layout/StorefrontFooter.d.ts.map +1 -0
  52. package/dist/components/layout/StorefrontHeader.d.ts.map +1 -0
  53. package/dist/components/layout/Toaster.d.ts.map +1 -0
  54. package/dist/components/marketing/CollectionSections.d.ts +463 -0
  55. package/dist/components/marketing/CollectionSections.d.ts.map +1 -0
  56. package/dist/components/marketing/ConversionSections.d.ts +221 -0
  57. package/dist/components/marketing/ConversionSections.d.ts.map +1 -0
  58. package/dist/components/marketing/EditorialSections.d.ts +248 -0
  59. package/dist/components/marketing/EditorialSections.d.ts.map +1 -0
  60. package/dist/components/marketing/EntityList.d.ts +97 -0
  61. package/dist/components/marketing/EntityList.d.ts.map +1 -0
  62. package/dist/components/marketing/FormBlock.d.ts +167 -0
  63. package/dist/components/marketing/FormBlock.d.ts.map +1 -0
  64. package/dist/components/marketing/HeroSection.d.ts +125 -0
  65. package/dist/components/marketing/HeroSection.d.ts.map +1 -0
  66. package/dist/components/marketing/MediaCarousel.d.ts +135 -0
  67. package/dist/components/marketing/MediaCarousel.d.ts.map +1 -0
  68. package/dist/components/marketing/MiscSections.d.ts +252 -0
  69. package/dist/components/marketing/MiscSections.d.ts.map +1 -0
  70. package/dist/components/order/OrderTrackingTimeline.d.ts.map +1 -0
  71. package/dist/components/product/ProductCard.d.ts +14 -0
  72. package/dist/components/product/ProductCard.d.ts.map +1 -0
  73. package/dist/components/product/ProductEnquiryForm.d.ts.map +1 -0
  74. package/dist/components/product/ProductGallery.d.ts +36 -0
  75. package/dist/components/product/ProductGallery.d.ts.map +1 -0
  76. package/dist/components/{ProductOptionSelector.d.ts → product/ProductOptionSelector.d.ts} +1 -1
  77. package/dist/components/product/ProductOptionSelector.d.ts.map +1 -0
  78. package/dist/components/product/ProductRail.d.ts +93 -0
  79. package/dist/components/product/ProductRail.d.ts.map +1 -0
  80. package/dist/components/product/ProductReviews.d.ts +39 -0
  81. package/dist/components/product/ProductReviews.d.ts.map +1 -0
  82. package/dist/components/product/ProductSlider.d.ts +169 -0
  83. package/dist/components/product/ProductSlider.d.ts.map +1 -0
  84. package/dist/components/product/ProductSpecs.d.ts.map +1 -0
  85. package/dist/components/product/RelatedProducts.d.ts.map +1 -0
  86. package/dist/{auth.d.ts → data/auth.d.ts} +9 -0
  87. package/dist/data/auth.d.ts.map +1 -0
  88. package/dist/data/facets.d.ts +39 -0
  89. package/dist/data/facets.d.ts.map +1 -0
  90. package/dist/data/loaders.d.ts +56 -0
  91. package/dist/data/loaders.d.ts.map +1 -0
  92. package/dist/data/order-status.d.ts.map +1 -0
  93. package/dist/data/product-options.d.ts +36 -0
  94. package/dist/data/product-options.d.ts.map +1 -0
  95. package/dist/diagnostics/seo-audit.d.ts +54 -0
  96. package/dist/diagnostics/seo-audit.d.ts.map +1 -0
  97. package/dist/diagnostics/seo-audit.js +3 -0
  98. package/dist/diagnostics/seo-audit.js.map +1 -0
  99. package/dist/document/change.d.ts +100 -0
  100. package/dist/document/change.d.ts.map +1 -0
  101. package/dist/{config.d.ts → document/config.d.ts} +126 -7
  102. package/dist/document/config.d.ts.map +1 -0
  103. package/dist/document/describe.d.ts +135 -0
  104. package/dist/document/describe.d.ts.map +1 -0
  105. package/dist/document/overlay.d.ts +58 -0
  106. package/dist/document/overlay.d.ts.map +1 -0
  107. package/dist/{presets.d.ts → document/presets.d.ts} +2 -2
  108. package/dist/document/presets.d.ts.map +1 -0
  109. package/dist/document/render.d.ts +171 -0
  110. package/dist/document/render.d.ts.map +1 -0
  111. package/dist/document/round-trip.d.ts +46 -0
  112. package/dist/document/round-trip.d.ts.map +1 -0
  113. package/dist/document/sections.d.ts +194 -0
  114. package/dist/document/sections.d.ts.map +1 -0
  115. package/dist/document/upgrade.d.ts +112 -0
  116. package/dist/document/upgrade.d.ts.map +1 -0
  117. package/dist/document/validate.d.ts +24 -0
  118. package/dist/document/validate.d.ts.map +1 -0
  119. package/dist/{component-contracts.d.ts → extend/component-contracts.d.ts} +74 -22
  120. package/dist/extend/component-contracts.d.ts.map +1 -0
  121. package/dist/extend/component-override.d.ts +38 -0
  122. package/dist/extend/component-override.d.ts.map +1 -0
  123. package/dist/extend/component-selectors.d.ts.map +1 -0
  124. package/dist/extend/editor-bridge.d.ts +59 -0
  125. package/dist/extend/editor-bridge.d.ts.map +1 -0
  126. package/dist/extend/extension-points.d.ts +103 -0
  127. package/dist/extend/extension-points.d.ts.map +1 -0
  128. package/dist/extend/slots.d.ts +216 -0
  129. package/dist/extend/slots.d.ts.map +1 -0
  130. package/dist/hooks/index.d.ts +25 -6
  131. package/dist/hooks/index.d.ts.map +1 -1
  132. package/dist/hooks/use-address.d.ts +26 -0
  133. package/dist/hooks/use-address.d.ts.map +1 -0
  134. package/dist/hooks/use-cart.d.ts +3 -0
  135. package/dist/hooks/use-cart.d.ts.map +1 -0
  136. package/dist/hooks/use-catalog.d.ts +24 -0
  137. package/dist/hooks/use-catalog.d.ts.map +1 -0
  138. package/dist/hooks/use-categories.d.ts +19 -0
  139. package/dist/hooks/use-categories.d.ts.map +1 -0
  140. package/dist/hooks/use-checkout.d.ts +41 -0
  141. package/dist/hooks/use-checkout.d.ts.map +1 -0
  142. package/dist/hooks/use-discount-validator.d.ts +20 -0
  143. package/dist/hooks/use-discount-validator.d.ts.map +1 -0
  144. package/dist/hooks/use-enquiry.d.ts +7 -0
  145. package/dist/hooks/use-enquiry.d.ts.map +1 -0
  146. package/dist/hooks/{useMyOrders.d.ts → use-my-orders.d.ts} +1 -1
  147. package/dist/hooks/use-my-orders.d.ts.map +1 -0
  148. package/dist/hooks/use-order.d.ts +17 -0
  149. package/dist/hooks/use-order.d.ts.map +1 -0
  150. package/dist/hooks/use-payment-methods.d.ts +19 -0
  151. package/dist/hooks/use-payment-methods.d.ts.map +1 -0
  152. package/dist/hooks/use-policies.d.ts +25 -0
  153. package/dist/hooks/use-policies.d.ts.map +1 -0
  154. package/dist/hooks/use-product.d.ts +15 -0
  155. package/dist/hooks/use-product.d.ts.map +1 -0
  156. package/dist/hooks/{useProducts.d.ts → use-products.d.ts} +1 -1
  157. package/dist/hooks/use-products.d.ts.map +1 -0
  158. package/dist/hooks/use-region.d.ts +15 -0
  159. package/dist/hooks/use-region.d.ts.map +1 -0
  160. package/dist/hooks/use-shipping.d.ts +29 -0
  161. package/dist/hooks/use-shipping.d.ts.map +1 -0
  162. package/dist/hooks/use-storefront-actions.d.ts +12 -0
  163. package/dist/hooks/use-storefront-actions.d.ts.map +1 -0
  164. package/dist/hooks/use-storefront-head.d.ts +19 -0
  165. package/dist/hooks/use-storefront-head.d.ts.map +1 -0
  166. package/dist/hooks/use-storefront.d.ts +3 -0
  167. package/dist/hooks/use-storefront.d.ts.map +1 -0
  168. package/dist/index.d.ts +123 -54
  169. package/dist/index.d.ts.map +1 -1
  170. package/dist/index.js +1311 -5012
  171. package/dist/index.js.map +1 -1
  172. package/dist/lib/format.d.ts.map +1 -0
  173. package/dist/lib/motion.d.ts.map +1 -0
  174. package/dist/lib/seo.d.ts +26 -0
  175. package/dist/lib/seo.d.ts.map +1 -0
  176. package/dist/{testids.d.ts → lib/testids.d.ts} +21 -0
  177. package/dist/lib/testids.d.ts.map +1 -0
  178. package/dist/{theme.d.ts → lib/theme.d.ts} +41 -3
  179. package/dist/lib/theme.d.ts.map +1 -0
  180. package/dist/render.d.ts +5 -0
  181. package/dist/render.d.ts.map +1 -0
  182. package/dist/render.js +359 -0
  183. package/dist/render.js.map +1 -0
  184. package/dist/stores/cart.store.d.ts +6 -2
  185. package/dist/stores/cart.store.d.ts.map +1 -1
  186. package/dist/stores/catalog.store.d.ts +11 -0
  187. package/dist/stores/catalog.store.d.ts.map +1 -1
  188. package/dist/views/CatalogPage.d.ts.map +1 -0
  189. package/dist/views/CheckoutPage.d.ts.map +1 -0
  190. package/dist/views/ContentPage.d.ts +11 -0
  191. package/dist/views/ContentPage.d.ts.map +1 -0
  192. package/dist/views/HomePage.d.ts +9 -0
  193. package/dist/views/HomePage.d.ts.map +1 -0
  194. package/dist/views/MyPurchasesPage.d.ts.map +1 -0
  195. package/dist/views/NotFoundPage.d.ts.map +1 -0
  196. package/dist/{pages → views}/OrderConfirmationPage.d.ts.map +1 -1
  197. package/dist/{pages → views}/PolicyPage.d.ts.map +1 -1
  198. package/dist/views/ProductDetailPage.d.ts.map +1 -0
  199. package/dist/views/StorefrontPage.d.ts +35 -0
  200. package/dist/views/StorefrontPage.d.ts.map +1 -0
  201. package/dist/workflows/checkout.d.ts +1 -1
  202. package/dist/workflows/checkout.d.ts.map +1 -1
  203. package/package.json +21 -14
  204. package/dist/auth.d.ts.map +0 -1
  205. package/dist/blocks.d.ts.map +0 -1
  206. package/dist/component-contracts.d.ts.map +0 -1
  207. package/dist/component-selectors.d.ts.map +0 -1
  208. package/dist/components/CartDrawer.d.ts.map +0 -1
  209. package/dist/components/CustomerAccountShell.d.ts.map +0 -1
  210. package/dist/components/DeliveryEstimator.d.ts.map +0 -1
  211. package/dist/components/FiltersPanel.d.ts +0 -3
  212. package/dist/components/FiltersPanel.d.ts.map +0 -1
  213. package/dist/components/OrderTrackingTimeline.d.ts.map +0 -1
  214. package/dist/components/ProductCard.d.ts +0 -4
  215. package/dist/components/ProductCard.d.ts.map +0 -1
  216. package/dist/components/ProductEnquiryForm.d.ts.map +0 -1
  217. package/dist/components/ProductGallery.d.ts +0 -22
  218. package/dist/components/ProductGallery.d.ts.map +0 -1
  219. package/dist/components/ProductGrid.d.ts.map +0 -1
  220. package/dist/components/ProductOptionSelector.d.ts.map +0 -1
  221. package/dist/components/ProductSpecs.d.ts.map +0 -1
  222. package/dist/components/QuantityInput.d.ts.map +0 -1
  223. package/dist/components/RelatedProducts.d.ts.map +0 -1
  224. package/dist/components/SignInModal.d.ts.map +0 -1
  225. package/dist/components/StorefrontErrorBoundary.d.ts.map +0 -1
  226. package/dist/components/StorefrontFooter.d.ts.map +0 -1
  227. package/dist/components/StorefrontHeader.d.ts.map +0 -1
  228. package/dist/components/Toaster.d.ts.map +0 -1
  229. package/dist/components/sections/CategoryShowcase.d.ts +0 -6
  230. package/dist/components/sections/CategoryShowcase.d.ts.map +0 -1
  231. package/dist/components/sections/HeroSection.d.ts +0 -9
  232. package/dist/components/sections/HeroSection.d.ts.map +0 -1
  233. package/dist/components/sections/MediaCarousel.d.ts +0 -11
  234. package/dist/components/sections/MediaCarousel.d.ts.map +0 -1
  235. package/dist/components/sections/MiscSections.d.ts +0 -33
  236. package/dist/components/sections/MiscSections.d.ts.map +0 -1
  237. package/dist/components/sections/ProductRail.d.ts +0 -9
  238. package/dist/components/sections/ProductRail.d.ts.map +0 -1
  239. package/dist/components/sections/ProductSlider.d.ts +0 -15
  240. package/dist/components/sections/ProductSlider.d.ts.map +0 -1
  241. package/dist/config.d.ts.map +0 -1
  242. package/dist/createStorefrontApp.d.ts +0 -28
  243. package/dist/createStorefrontApp.d.ts.map +0 -1
  244. package/dist/define.d.ts.map +0 -1
  245. package/dist/format.d.ts.map +0 -1
  246. package/dist/hooks/useCategories.d.ts +0 -6
  247. package/dist/hooks/useCategories.d.ts.map +0 -1
  248. package/dist/hooks/useDiscountValidator.d.ts +0 -14
  249. package/dist/hooks/useDiscountValidator.d.ts.map +0 -1
  250. package/dist/hooks/useMyOrders.d.ts.map +0 -1
  251. package/dist/hooks/useProduct.d.ts +0 -7
  252. package/dist/hooks/useProduct.d.ts.map +0 -1
  253. package/dist/hooks/useProducts.d.ts.map +0 -1
  254. package/dist/hooks/useStorefront.d.ts +0 -35
  255. package/dist/hooks/useStorefront.d.ts.map +0 -1
  256. package/dist/hooks/useStorefrontHead.d.ts +0 -11
  257. package/dist/hooks/useStorefrontHead.d.ts.map +0 -1
  258. package/dist/motion.d.ts.map +0 -1
  259. package/dist/order-status.d.ts.map +0 -1
  260. package/dist/pages/CatalogPage.d.ts.map +0 -1
  261. package/dist/pages/CheckoutPage.d.ts.map +0 -1
  262. package/dist/pages/HomePage.d.ts +0 -9
  263. package/dist/pages/HomePage.d.ts.map +0 -1
  264. package/dist/pages/MyPurchasesPage.d.ts.map +0 -1
  265. package/dist/pages/NotFoundPage.d.ts.map +0 -1
  266. package/dist/pages/ProductDetailPage.d.ts.map +0 -1
  267. package/dist/presets.d.ts.map +0 -1
  268. package/dist/product-options.d.ts +0 -12
  269. package/dist/product-options.d.ts.map +0 -1
  270. package/dist/router.d.ts.map +0 -1
  271. package/dist/scaffold.d.ts.map +0 -1
  272. package/dist/sections.d.ts.map +0 -1
  273. package/dist/testids.d.ts.map +0 -1
  274. package/dist/theme.d.ts.map +0 -1
  275. package/src/auth.ts +0 -227
  276. package/src/blocks.tsx +0 -51
  277. package/src/catalog.ts +0 -3
  278. package/src/component-contracts.ts +0 -154
  279. package/src/component-selectors.ts +0 -31
  280. package/src/components/CartDrawer.tsx +0 -279
  281. package/src/components/CustomerAccountShell.tsx +0 -102
  282. package/src/components/DeliveryEstimator.tsx +0 -157
  283. package/src/components/FiltersPanel.tsx +0 -109
  284. package/src/components/OrderTrackingTimeline.tsx +0 -135
  285. package/src/components/Price.tsx +0 -32
  286. package/src/components/ProductCard.tsx +0 -120
  287. package/src/components/ProductEnquiryForm.tsx +0 -175
  288. package/src/components/ProductGallery.tsx +0 -174
  289. package/src/components/ProductGrid.tsx +0 -43
  290. package/src/components/ProductOptionSelector.tsx +0 -50
  291. package/src/components/ProductSpecs.tsx +0 -75
  292. package/src/components/QuantityInput.tsx +0 -52
  293. package/src/components/RelatedProducts.tsx +0 -40
  294. package/src/components/SignInModal.tsx +0 -120
  295. package/src/components/SmoothImage.tsx +0 -59
  296. package/src/components/StorefrontErrorBoundary.tsx +0 -51
  297. package/src/components/StorefrontFooter.tsx +0 -110
  298. package/src/components/StorefrontHeader.tsx +0 -477
  299. package/src/components/Toaster.tsx +0 -60
  300. package/src/components/sections/CategoryShowcase.tsx +0 -80
  301. package/src/components/sections/HeroSection.tsx +0 -193
  302. package/src/components/sections/MediaCarousel.tsx +0 -141
  303. package/src/components/sections/MiscSections.tsx +0 -158
  304. package/src/components/sections/ProductRail.tsx +0 -81
  305. package/src/components/sections/ProductSlider.tsx +0 -119
  306. package/src/config.ts +0 -229
  307. package/src/createStorefrontApp.tsx +0 -247
  308. package/src/define.ts +0 -34
  309. package/src/format.ts +0 -7
  310. package/src/hooks/index.ts +0 -6
  311. package/src/hooks/useCategories.ts +0 -26
  312. package/src/hooks/useDiscountValidator.ts +0 -43
  313. package/src/hooks/useMyOrders.ts +0 -41
  314. package/src/hooks/useProduct.ts +0 -36
  315. package/src/hooks/useProducts.ts +0 -39
  316. package/src/hooks/useStorefront.ts +0 -58
  317. package/src/hooks/useStorefrontHead.ts +0 -25
  318. package/src/index.ts +0 -202
  319. package/src/motion.tsx +0 -94
  320. package/src/order-status.ts +0 -33
  321. package/src/pages/CatalogPage.tsx +0 -118
  322. package/src/pages/CheckoutPage.tsx +0 -689
  323. package/src/pages/HomePage.tsx +0 -16
  324. package/src/pages/MyPurchasesPage.tsx +0 -311
  325. package/src/pages/NotFoundPage.tsx +0 -25
  326. package/src/pages/OrderConfirmationPage.tsx +0 -190
  327. package/src/pages/PolicyPage.tsx +0 -47
  328. package/src/pages/ProductDetailPage.tsx +0 -264
  329. package/src/presets.ts +0 -324
  330. package/src/product-options.ts +0 -63
  331. package/src/router.ts +0 -49
  332. package/src/scaffold.tsx +0 -115
  333. package/src/sections.ts +0 -116
  334. package/src/shop.ts +0 -4
  335. package/src/stores/cart.store.ts +0 -185
  336. package/src/stores/catalog.store.ts +0 -39
  337. package/src/stores/delivery.store.ts +0 -152
  338. package/src/stores/session.store.ts +0 -28
  339. package/src/stores/toast.store.ts +0 -43
  340. package/src/testids.ts +0 -136
  341. package/src/theme.ts +0 -194
  342. package/src/ui.ts +0 -5
  343. package/src/workflows/checkout.ts +0 -119
  344. /package/dist/components/{CustomerAccountShell.d.ts → account/CustomerAccountShell.d.ts} +0 -0
  345. /package/dist/components/{SignInModal.d.ts → account/SignInModal.d.ts} +0 -0
  346. /package/dist/components/{CartDrawer.d.ts → cart/CartDrawer.d.ts} +0 -0
  347. /package/dist/components/{QuantityInput.d.ts → cart/QuantityInput.d.ts} +0 -0
  348. /package/dist/components/{DeliveryEstimator.d.ts → checkout/DeliveryEstimator.d.ts} +0 -0
  349. /package/dist/components/{ProductGrid.d.ts → collection/ProductGrid.d.ts} +0 -0
  350. /package/dist/components/{StorefrontErrorBoundary.d.ts → layout/StorefrontErrorBoundary.d.ts} +0 -0
  351. /package/dist/components/{StorefrontFooter.d.ts → layout/StorefrontFooter.d.ts} +0 -0
  352. /package/dist/components/{StorefrontHeader.d.ts → layout/StorefrontHeader.d.ts} +0 -0
  353. /package/dist/components/{Toaster.d.ts → layout/Toaster.d.ts} +0 -0
  354. /package/dist/components/{OrderTrackingTimeline.d.ts → order/OrderTrackingTimeline.d.ts} +0 -0
  355. /package/dist/components/{ProductEnquiryForm.d.ts → product/ProductEnquiryForm.d.ts} +0 -0
  356. /package/dist/components/{ProductSpecs.d.ts → product/ProductSpecs.d.ts} +0 -0
  357. /package/dist/components/{RelatedProducts.d.ts → product/RelatedProducts.d.ts} +0 -0
  358. /package/dist/{order-status.d.ts → data/order-status.d.ts} +0 -0
  359. /package/dist/{component-selectors.d.ts → extend/component-selectors.d.ts} +0 -0
  360. /package/dist/{format.d.ts → lib/format.d.ts} +0 -0
  361. /package/dist/{motion.d.ts → lib/motion.d.ts} +0 -0
  362. /package/dist/{pages → views}/CatalogPage.d.ts +0 -0
  363. /package/dist/{pages → views}/CheckoutPage.d.ts +0 -0
  364. /package/dist/{pages → views}/MyPurchasesPage.d.ts +0 -0
  365. /package/dist/{pages → views}/NotFoundPage.d.ts +0 -0
  366. /package/dist/{pages → views}/OrderConfirmationPage.d.ts +0 -0
  367. /package/dist/{pages → views}/PolicyPage.d.ts +0 -0
  368. /package/dist/{pages → views}/ProductDetailPage.d.ts +0 -0
@@ -1,193 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react'
2
- import { ChevronLeft, ChevronRight } from 'lucide-react'
3
- import type { HeroSlide } from '../../sections'
4
- import type { HeroVariant } from '../../theme'
5
- import { bannerPlaceholder } from '../../sections'
6
- import { useStorefrontConfig } from '../../config'
7
- import { prefersReducedMotion } from '../../motion'
8
- import { Link } from '../../router'
9
- import { TID } from '../../testids'
10
- import { SmoothImage } from '../SmoothImage'
11
-
12
- function slideImage(slide: HeroSlide, w = 1600, h = 700): string {
13
- return slide.image ?? bannerPlaceholder(slide.title, slide.hue ?? 200, (slide.hue ?? 200) + 40, w, h)
14
- }
15
-
16
- function SlideCopy({ slide, active }: { slide: HeroSlide; active: boolean }) {
17
- const stagger = (i: number) =>
18
- active ? { className: 'animate-fade-up', style: { animationDelay: `${i * 120}ms` } } : { className: 'opacity-0' }
19
-
20
- const inner = (
21
- <>
22
- <h2 className={`sf-heading text-3xl font-bold leading-tight tracking-tight sm:text-5xl ${stagger(0).className}`} style={stagger(0).style}>
23
- {slide.title}
24
- </h2>
25
- {slide.subtitle && (
26
- <p className={`mt-3 max-w-md text-base sm:text-lg ${stagger(1).className}`} style={stagger(1).style}>
27
- {slide.subtitle}
28
- </p>
29
- )}
30
- {slide.cta && (
31
- <div className={stagger(2).className} style={stagger(2).style}>
32
- <Link
33
- to={slide.href ?? '/catalog'}
34
- className="sf-cta mt-6 inline-block bg-primary px-8 py-3.5 font-semibold text-primary-foreground shadow-lg transition-all hover:-translate-y-0.5 hover:shadow-xl"
35
- style={{ borderRadius: 'var(--sf-radius-button)' }}
36
- >
37
- {slide.cta}
38
- </Link>
39
- </div>
40
- )}
41
- </>
42
- )
43
- if (slide.boxed) {
44
- return (
45
- <div className="border border-foreground/30 bg-background/90 p-8 backdrop-blur-sm sm:p-10">{inner}</div>
46
- )
47
- }
48
- return <div className="text-white">{inner}</div>
49
- }
50
-
51
- export function HeroSection({
52
- variant,
53
- slides,
54
- height = 'tall',
55
- }: {
56
- variant: HeroVariant
57
- slides: HeroSlide[]
58
- height?: 'tall' | 'medium'
59
- }) {
60
- const [index, setIndex] = useState(0)
61
- const [loadedSlides, setLoadedSlides] = useState<Record<number, boolean>>({})
62
- const config = useStorefrontConfig()
63
- const interacted = useRef(false)
64
- const hClass = height === 'tall' ? 'h-[72vh] min-h-[440px]' : 'h-[48vh] min-h-[340px]'
65
- const revealImages = config.imageLoading.mode !== 'none'
66
- const revealStyle = (loaded: boolean): React.CSSProperties | undefined =>
67
- revealImages
68
- ? {
69
- filter: config.imageLoading.blur && !loaded ? 'blur(10px)' : 'blur(0px)',
70
- transition: `opacity 700ms ease, filter ${config.imageLoading.durationMs}ms ${config.imageLoading.easing}`,
71
- }
72
- : undefined
73
-
74
- // Auto-advance until the visitor takes over; never under reduced motion.
75
- useEffect(() => {
76
- if (variant !== 'slider' || slides.length < 2 || prefersReducedMotion()) return
77
- const timer = setInterval(() => {
78
- if (!interacted.current) setIndex((i) => (i + 1) % slides.length)
79
- }, 7000)
80
- return () => clearInterval(timer)
81
- }, [variant, slides.length])
82
-
83
- const goTo = (i: number) => {
84
- interacted.current = true
85
- setIndex((i + slides.length) % slides.length)
86
- }
87
-
88
- if (slides.length === 0) return null
89
-
90
- if (variant === 'split') {
91
- return (
92
- <section data-testid={TID.hero} className="grid gap-px sm:grid-cols-2">
93
- {slides.slice(0, 2).map((slide, i) => (
94
- <Link
95
- key={i}
96
- to={slide.href ?? '/catalog'}
97
- className="group relative block h-[42vh] min-h-[320px] overflow-hidden"
98
- >
99
- <SmoothImage
100
- src={slideImage(slide, 900, 700)}
101
- alt={slide.title}
102
- className="h-full w-full object-cover transition-transform duration-700 ease-out group-hover:scale-105"
103
- />
104
- <div className="absolute inset-0 flex flex-col items-center justify-center bg-gradient-to-t from-black/65 via-black/25 to-black/10 p-6 text-center text-white">
105
- <h2
106
- className="sf-heading animate-fade-up text-3xl font-bold uppercase tracking-wide drop-shadow-md sm:text-4xl"
107
- style={{ animationDelay: `${i * 150}ms` }}
108
- >
109
- {slide.title}
110
- </h2>
111
- {slide.subtitle && (
112
- <p className="animate-fade-up mt-2 max-w-sm drop-shadow" style={{ animationDelay: `${i * 150 + 120}ms` }}>
113
- {slide.subtitle}
114
- </p>
115
- )}
116
- <span className="mt-4 inline-block border-b-2 border-white/0 pb-0.5 text-sm font-semibold uppercase tracking-wider opacity-0 transition-all duration-300 group-hover:border-white group-hover:opacity-100">
117
- Explorar →
118
- </span>
119
- </div>
120
- </Link>
121
- ))}
122
- </section>
123
- )
124
- }
125
-
126
- const active = slides[Math.min(index, slides.length - 1)]!
127
-
128
- return (
129
- <section data-testid={TID.hero} className={`relative w-full overflow-hidden ${hClass}`}>
130
- {/* stacked slides, crossfade + Ken Burns on the active one */}
131
- {slides.map((slide, i) => (
132
- <img
133
- key={i}
134
- src={slideImage(slide)}
135
- alt={slide.title}
136
- aria-hidden={i !== index}
137
- loading={i === 0 ? 'eager' : 'lazy'}
138
- decoding="async"
139
- onLoad={() => setLoadedSlides((current) => ({ ...current, [i]: true }))}
140
- style={revealStyle(Boolean(loadedSlides[i]))}
141
- className={`absolute inset-0 h-full w-full object-cover transition-opacity duration-700 ${
142
- i === index && (!revealImages || loadedSlides[i]) ? 'animate-kenburns opacity-100' : 'opacity-0'
143
- }`}
144
- />
145
- ))}
146
- <div
147
- className={`absolute inset-0 flex items-end p-6 sm:p-12 ${
148
- active.boxed ? '' : 'bg-gradient-to-t from-black/60 via-black/20 to-transparent'
149
- }`}
150
- >
151
- <div className="mx-auto w-full max-w-7xl">
152
- <div className="max-w-xl">
153
- <SlideCopy key={index} slide={active} active />
154
- </div>
155
- </div>
156
- </div>
157
-
158
- {variant === 'slider' && slides.length > 1 && (
159
- <>
160
- <button
161
- type="button"
162
- aria-label="Slide anterior"
163
- data-testid={TID.heroPrev}
164
- onClick={() => goTo(index - 1)}
165
- className="absolute left-4 top-1/2 -translate-y-1/2 rounded-full bg-white/85 p-2.5 shadow transition-transform hover:scale-110 hover:bg-white"
166
- >
167
- <ChevronLeft className="h-5 w-5 text-gray-900" />
168
- </button>
169
- <button
170
- type="button"
171
- aria-label="Próximo slide"
172
- data-testid={TID.heroNext}
173
- onClick={() => goTo(index + 1)}
174
- className="absolute right-4 top-1/2 -translate-y-1/2 rounded-full bg-white/85 p-2.5 shadow transition-transform hover:scale-110 hover:bg-white"
175
- >
176
- <ChevronRight className="h-5 w-5 text-gray-900" />
177
- </button>
178
- <div className="absolute bottom-4 left-1/2 flex -translate-x-1/2 gap-2">
179
- {slides.map((_, i) => (
180
- <button
181
- key={i}
182
- type="button"
183
- aria-label={`Ir para o slide ${i + 1}`}
184
- onClick={() => goTo(i)}
185
- className={`h-2 rounded-full transition-all duration-300 ${i === index ? 'w-7 bg-white' : 'w-2 bg-white/60 hover:bg-white/80'}`}
186
- />
187
- ))}
188
- </div>
189
- </>
190
- )}
191
- </section>
192
- )
193
- }
@@ -1,141 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react'
2
- import { ChevronLeft, ChevronRight } from 'lucide-react'
3
- import { Link } from '../../router'
4
- import { TID } from '../../testids'
5
- import { prefersReducedMotion } from '../../motion'
6
- import type { MediaCarouselItem } from '../../sections'
7
- import { useStorefrontConfig } from '../../config'
8
-
9
- export interface MediaCarouselProps {
10
- items: MediaCarouselItem[]
11
- height?: 'medium' | 'tall' | 'screen'
12
- autoplayMs?: number
13
- overlay?: 'dark' | 'soft' | 'none'
14
- className?: string
15
- }
16
-
17
- const heightClass = {
18
- medium: 'h-[58vh] min-h-[420px]',
19
- tall: 'h-[74vh] min-h-[520px]',
20
- screen: 'min-h-[calc(100vh-64px)]',
21
- }
22
-
23
- const alignClass = {
24
- start: 'items-start text-left',
25
- center: 'items-center text-center',
26
- end: 'items-end text-right',
27
- }
28
-
29
- export function MediaCarousel({
30
- items,
31
- height = 'tall',
32
- autoplayMs = 7000,
33
- overlay = 'dark',
34
- className = '',
35
- }: MediaCarouselProps) {
36
- const [index, setIndex] = useState(0)
37
- const [loadedItems, setLoadedItems] = useState<Record<number, boolean>>({})
38
- const config = useStorefrontConfig()
39
- const interacted = useRef(false)
40
- const revealImages = config.imageLoading.mode !== 'none'
41
- const revealStyle = (loaded: boolean): React.CSSProperties | undefined =>
42
- revealImages
43
- ? {
44
- filter: config.imageLoading.blur && !loaded ? 'blur(10px)' : 'blur(0px)',
45
- transition: `opacity 700ms ease, filter ${config.imageLoading.durationMs}ms ${config.imageLoading.easing}`,
46
- }
47
- : undefined
48
-
49
- useEffect(() => {
50
- if (items.length < 2 || autoplayMs <= 0 || prefersReducedMotion()) return
51
- const timer = setInterval(() => {
52
- if (!interacted.current) setIndex((i) => (i + 1) % items.length)
53
- }, autoplayMs)
54
- return () => clearInterval(timer)
55
- }, [autoplayMs, items.length])
56
-
57
- if (items.length === 0) return null
58
-
59
- const active = items[Math.min(index, items.length - 1)]!
60
- const goTo = (next: number) => {
61
- interacted.current = true
62
- setIndex((next + items.length) % items.length)
63
- }
64
- const overlayClass =
65
- overlay === 'dark'
66
- ? 'bg-gradient-to-r from-black/70 via-black/25 to-black/25'
67
- : overlay === 'soft'
68
- ? 'bg-gradient-to-t from-black/45 via-black/10 to-transparent'
69
- : ''
70
-
71
- return (
72
- <section data-testid={TID.mediaCarousel} className={`relative isolate overflow-hidden ${heightClass[height]} ${className}`}>
73
- {items.map((item, i) => (
74
- <img
75
- key={`${item.title}-${i}`}
76
- src={item.image}
77
- alt={item.imageAlt ?? item.title}
78
- aria-hidden={i !== index}
79
- loading={i === 0 ? 'eager' : 'lazy'}
80
- decoding="async"
81
- onLoad={() => setLoadedItems((current) => ({ ...current, [i]: true }))}
82
- style={revealStyle(Boolean(loadedItems[i]))}
83
- className={`absolute inset-0 -z-10 h-full w-full object-cover transition-opacity duration-700 ${
84
- i === index && (!revealImages || loadedItems[i]) ? 'opacity-100' : 'opacity-0'
85
- }`}
86
- />
87
- ))}
88
- <div className={`absolute inset-0 -z-10 ${overlayClass}`} />
89
- <div className={`flex h-full px-5 py-16 sm:px-10 lg:px-16 ${alignClass[active.align ?? 'start']}`}>
90
- <div className="my-auto max-w-2xl text-white drop-shadow-md">
91
- {active.eyebrow && (
92
- <p className="mb-4 text-xs font-semibold uppercase tracking-[0.24em] text-white/80">{active.eyebrow}</p>
93
- )}
94
- <h1 className="sf-heading text-5xl font-normal leading-[0.95] sm:text-7xl lg:text-8xl">{active.title}</h1>
95
- {active.subtitle && <p className="mt-5 max-w-xl text-base leading-8 text-white/88 sm:text-lg">{active.subtitle}</p>}
96
- {active.cta && (
97
- <Link
98
- to={active.href ?? '/catalog'}
99
- className="mt-8 inline-flex border border-white/75 px-6 py-3 text-xs font-semibold uppercase tracking-[0.18em] text-white transition hover:bg-white hover:text-black"
100
- >
101
- {active.cta}
102
- </Link>
103
- )}
104
- </div>
105
- </div>
106
- {items.length > 1 && (
107
- <>
108
- <button
109
- type="button"
110
- aria-label="Previous slide"
111
- data-testid={TID.mediaCarouselPrev}
112
- onClick={() => goTo(index - 1)}
113
- className="absolute left-4 top-1/2 inline-flex h-10 w-10 -translate-y-1/2 items-center justify-center border border-white/60 bg-black/20 text-white backdrop-blur transition hover:bg-white hover:text-black"
114
- >
115
- <ChevronLeft className="h-5 w-5" />
116
- </button>
117
- <button
118
- type="button"
119
- aria-label="Next slide"
120
- data-testid={TID.mediaCarouselNext}
121
- onClick={() => goTo(index + 1)}
122
- className="absolute right-4 top-1/2 inline-flex h-10 w-10 -translate-y-1/2 items-center justify-center border border-white/60 bg-black/20 text-white backdrop-blur transition hover:bg-white hover:text-black"
123
- >
124
- <ChevronRight className="h-5 w-5" />
125
- </button>
126
- <div className="absolute bottom-5 left-1/2 flex -translate-x-1/2 gap-2">
127
- {items.map((item, i) => (
128
- <button
129
- key={`${item.title}-dot-${i}`}
130
- type="button"
131
- aria-label={`Go to slide ${i + 1}`}
132
- onClick={() => goTo(i)}
133
- className={`h-2 rounded-full transition-all ${i === index ? 'w-8 bg-white' : 'w-2 bg-white/55 hover:bg-white'}`}
134
- />
135
- ))}
136
- </div>
137
- </>
138
- )}
139
- </section>
140
- )
141
- }
@@ -1,158 +0,0 @@
1
- import React, { useState } from 'react'
2
- import { getLucideIcon } from '@fayz-ai/ui/icons'
3
- import { bannerPlaceholder } from '../../sections'
4
- import { Reveal } from '../../motion'
5
- import { Link } from '../../router'
6
- import { TID } from '../../testids'
7
- import { SmoothImage } from '../SmoothImage'
8
-
9
- function Icon({ name, className }: { name: string; className?: string }) {
10
- const C = getLucideIcon(name)
11
- return C ? <C className={className} /> : null
12
- }
13
-
14
- export function BenefitsRow({ items }: { items: Array<{ icon: string; title: string; text?: string }> }) {
15
- return (
16
- <section data-testid={TID.benefits} className="border-y bg-card">
17
- <div className="mx-auto grid max-w-7xl grid-cols-1 gap-6 px-4 py-9 sm:grid-cols-3 sm:px-6">
18
- {items.slice(0, 4).map((item, i) => (
19
- <Reveal key={i} delay={i * 120} className="flex items-center justify-center gap-3 text-center sm:text-left">
20
- <span className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-primary/10">
21
- <Icon name={item.icon} className="h-6 w-6 text-primary" />
22
- </span>
23
- <div>
24
- <p className="font-semibold">{item.title}</p>
25
- {item.text && <p className="text-sm text-muted-foreground">{item.text}</p>}
26
- </div>
27
- </Reveal>
28
- ))}
29
- </div>
30
- </section>
31
- )
32
- }
33
-
34
- export function PromoBanner({
35
- title,
36
- subtitle,
37
- eyebrow,
38
- cta,
39
- href,
40
- image,
41
- hue = 160,
42
- }: {
43
- title: string
44
- subtitle?: string
45
- eyebrow?: string
46
- cta?: string
47
- href?: string
48
- image?: string
49
- hue?: number
50
- }) {
51
- return (
52
- <section data-testid={TID.promoBanner} className="group relative my-12 overflow-hidden">
53
- <SmoothImage
54
- src={image ?? bannerPlaceholder(title, hue, hue + 50, 1600, 420)}
55
- alt={title}
56
- className="h-80 w-full object-cover transition-transform duration-700 ease-out group-hover:scale-105"
57
- />
58
- <div className="absolute inset-0 flex flex-col items-center justify-center bg-gradient-to-t from-black/65 via-black/35 to-black/20 p-6 text-center text-white">
59
- <Reveal>
60
- {eyebrow && (
61
- <p className="mb-2 text-xs font-semibold uppercase tracking-[0.25em] text-white/80">{eyebrow}</p>
62
- )}
63
- <h2 className="sf-heading text-3xl font-bold drop-shadow sm:text-5xl">{title}</h2>
64
- {subtitle && <p className="mt-3 max-w-lg text-white/90">{subtitle}</p>}
65
- {cta && (
66
- <Link
67
- to={href ?? '/catalog'}
68
- className="sf-cta mt-6 inline-block bg-white px-8 py-3 font-semibold text-gray-900 shadow-lg transition-all hover:-translate-y-0.5 hover:shadow-xl"
69
- style={{ borderRadius: 'var(--sf-radius-button)' }}
70
- >
71
- {cta}
72
- </Link>
73
- )}
74
- </Reveal>
75
- </div>
76
- </section>
77
- )
78
- }
79
-
80
- export function ManifestoBlock({ title, text }: { title?: string; text: string }) {
81
- return (
82
- <section data-testid={TID.manifesto} className="mx-auto max-w-3xl px-4 py-14 text-center sm:px-6">
83
- {title && <h2 className="sf-heading mb-5 text-2xl font-bold">{title}</h2>}
84
- <p className="sf-heading text-xl leading-relaxed text-muted-foreground sm:text-2xl">{text}</p>
85
- </section>
86
- )
87
- }
88
-
89
- export function Testimonials({ title, items }: { title?: string; items: Array<{ quote: string; author: string }> }) {
90
- return (
91
- <section data-testid={TID.testimonials} className="bg-muted/50 py-14">
92
- <div className="mx-auto max-w-7xl px-4 sm:px-6">
93
- {title && (
94
- <Reveal>
95
- <h2 className="sf-heading mb-10 text-center text-3xl font-bold">{title}</h2>
96
- </Reveal>
97
- )}
98
- <div className="grid gap-6 md:grid-cols-3">
99
- {items.slice(0, 3).map((t, i) => (
100
- <Reveal key={i} delay={i * 130}>
101
- <figure
102
- className="h-full bg-card p-7 shadow-sm transition-shadow hover:shadow-md"
103
- style={{ borderRadius: 'var(--sf-radius-card)' }}
104
- >
105
- <div className="mb-3 text-primary" aria-hidden>★★★★★</div>
106
- <blockquote className="leading-relaxed">“{t.quote}”</blockquote>
107
- <figcaption className="mt-4 text-sm font-semibold text-muted-foreground">— {t.author}</figcaption>
108
- </figure>
109
- </Reveal>
110
- ))}
111
- </div>
112
- </div>
113
- </section>
114
- )
115
- }
116
-
117
- export function NewsletterBand({ title, subtitle }: { title?: string; subtitle?: string }) {
118
- const [email, setEmail] = useState('')
119
- const [done, setDone] = useState(false)
120
- return (
121
- <section data-testid={TID.newsletter} className="bg-primary py-16 text-primary-foreground">
122
- <Reveal className="mx-auto max-w-xl px-4 text-center sm:px-6">
123
- <h2 className="sf-heading text-3xl font-bold">{title ?? 'Receba nossas novidades'}</h2>
124
- {subtitle && <p className="mt-2 opacity-90">{subtitle}</p>}
125
- {done ? (
126
- <p data-testid={TID.newsletterDone} className="mt-6 font-medium">Inscrição confirmada! 🎉</p>
127
- ) : (
128
- <form
129
- className="mt-6 flex gap-2"
130
- onSubmit={(e) => {
131
- e.preventDefault()
132
- if (email.trim()) setDone(true)
133
- }}
134
- >
135
- <input
136
- data-testid={TID.newsletterEmail}
137
- type="email"
138
- required
139
- placeholder="Seu e-mail"
140
- value={email}
141
- onChange={(e) => setEmail(e.target.value)}
142
- className="flex-1 border-0 bg-white/95 px-4 py-3 text-sm text-gray-900 outline-none"
143
- style={{ borderRadius: 'var(--sf-radius-input)' }}
144
- />
145
- <button
146
- type="submit"
147
- data-testid={TID.newsletterSubmit}
148
- className="sf-cta bg-foreground px-6 py-3 text-sm font-semibold text-background"
149
- style={{ borderRadius: 'var(--sf-radius-button)' }}
150
- >
151
- Assinar
152
- </button>
153
- </form>
154
- )}
155
- </Reveal>
156
- </section>
157
- )
158
- }
@@ -1,81 +0,0 @@
1
- import React, { useMemo } from 'react'
2
- import { useProducts } from '../../hooks/useProducts'
3
- import { getStorefrontComponents, useStorefrontConfig } from '../../config'
4
- import { useStorefrontActions } from '../../hooks/useStorefront'
5
- import { ProductCard } from '../ProductCard'
6
- import { Reveal } from '../../motion'
7
- import { Link } from '../../router'
8
- import { TID } from '../../testids'
9
-
10
- export function ProductRail({
11
- title,
12
- subtitle,
13
- eyebrow,
14
- filter = 'all',
15
- limit = 4,
16
- }: {
17
- title: string
18
- subtitle?: string
19
- eyebrow?: string
20
- filter?: 'sale' | 'new' | 'all'
21
- limit?: number
22
- }) {
23
- const config = useStorefrontConfig()
24
- const actions = useStorefrontActions()
25
- const components = getStorefrontComponents(config)
26
- const ProductCardComponent = components.ProductCard ?? ProductCard
27
- const { products, loading } = useProducts(
28
- filter === 'new'
29
- ? { status: 'active', orderBy: 'created_at', order: 'desc' }
30
- : { status: 'active' },
31
- )
32
-
33
- const visible = useMemo(() => {
34
- let list = products
35
- if (filter === 'sale') list = list.filter((p) => p.compareAtPrice != null && p.compareAtPrice > p.price)
36
- return list.slice(0, limit)
37
- }, [products, filter, limit])
38
-
39
- if (!loading && visible.length === 0) return null
40
-
41
- return (
42
- <section data-testid={TID.productRail} className="mx-auto max-w-7xl px-4 py-14 sm:px-6">
43
- <Reveal className="mb-10 text-center">
44
- {eyebrow && (
45
- <p className="mb-2 text-xs font-semibold uppercase tracking-[0.2em] text-primary">{eyebrow}</p>
46
- )}
47
- <h2 className="sf-heading text-3xl font-bold tracking-tight">{title}</h2>
48
- {subtitle && <p className="mt-2 text-muted-foreground">{subtitle}</p>}
49
- </Reveal>
50
- {loading ? (
51
- <div className="grid grid-cols-2 gap-5 md:grid-cols-4">
52
- {Array.from({ length: limit }, (_, i) => (
53
- <div key={i} className="aspect-[3/4] animate-pulse bg-muted" style={{ borderRadius: 'var(--sf-radius-card)' }} />
54
- ))}
55
- </div>
56
- ) : (
57
- <div className="grid grid-cols-2 gap-5 md:grid-cols-4">
58
- {visible.map((p, i) => (
59
- <Reveal key={p.id} delay={i * 90}>
60
- <ProductCardComponent
61
- product={p}
62
- config={config}
63
- commerceMode={config.commerceMode}
64
- actions={actions}
65
- />
66
- </Reveal>
67
- ))}
68
- </div>
69
- )}
70
- <Reveal className="mt-10 text-center" delay={200}>
71
- <Link
72
- to={config.catalogPath}
73
- className="sf-cta inline-block border border-foreground/30 px-7 py-2.5 text-sm font-semibold transition-all hover:-translate-y-0.5 hover:bg-foreground hover:text-background hover:shadow"
74
- style={{ borderRadius: 'var(--sf-radius-button)' }}
75
- >
76
- Ver tudo
77
- </Link>
78
- </Reveal>
79
- </section>
80
- )
81
- }