@mohasinac/appkit 4.53.2 → 4.54.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 (350) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/server/features/auth/capabilities.js +7 -5
  3. package/dist/_internal/server/features/checkout/actions.d.ts +22 -6
  4. package/dist/_internal/server/features/checkout/actions.js +96 -51
  5. package/dist/_internal/server/features/checkout/index.d.ts +1 -1
  6. package/dist/_internal/server/features/checkout/index.js +1 -1
  7. package/dist/_internal/server/features/checkout/supplier-identity.js +28 -6
  8. package/dist/_internal/server/features/orders/adapters.js +1 -3
  9. package/dist/_internal/server/features/products/listing-tab-counts.js +81 -25
  10. package/dist/_internal/server/features/search/index-build/sources.js +43 -2
  11. package/dist/_internal/server/features/site-settings/adapters.js +1 -1
  12. package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
  13. package/dist/_internal/server/features/stores/adapters.js +0 -1
  14. package/dist/_internal/server/jobs/core/analyticsAlertEvaluate.js +2 -5
  15. package/dist/_internal/server/jobs/core/jobRunners.js +0 -10
  16. package/dist/_internal/server/jobs/core/onOrderCreate.js +10 -104
  17. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +0 -2
  18. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +0 -1
  19. package/dist/_internal/server/jobs/core/onScamReportCreate.js +0 -1
  20. package/dist/_internal/server/jobs/core/onScamReportRejected.js +0 -1
  21. package/dist/_internal/server/jobs/core/onScamReportVerified.js +0 -1
  22. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +0 -1
  23. package/dist/_internal/server/jobs/core/pendingOrderTimeout.js +0 -1
  24. package/dist/_internal/server/notifications/channel-health.d.ts +7 -3
  25. package/dist/_internal/server/notifications/channel-health.js +2 -2
  26. package/dist/_internal/server/notifications/send-guard.d.ts +1 -1
  27. package/dist/_internal/server/notifications/send-guard.js +2 -4
  28. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  29. package/dist/_internal/shared/actions/action-registry.js +128 -28
  30. package/dist/_internal/shared/checkout/order-math.d.ts +1 -1
  31. package/dist/_internal/shared/checkout/order-math.js +1 -1
  32. package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
  33. package/dist/_internal/shared/features/checkout/config.d.ts +0 -2
  34. package/dist/_internal/shared/features/checkout/config.js +0 -2
  35. package/dist/_internal/shared/features/messaging/config.d.ts +7 -5
  36. package/dist/_internal/shared/features/messaging/config.js +1 -4
  37. package/dist/_internal/shared/features/site-settings/fees.d.ts +0 -2
  38. package/dist/_internal/shared/features/site-settings/fees.js +0 -2
  39. package/dist/_internal/shared/features/site-settings/supplier-of-record.d.ts +56 -0
  40. package/dist/_internal/shared/features/site-settings/supplier-of-record.js +57 -0
  41. package/dist/_internal/shared/fees/calculator.d.ts +0 -8
  42. package/dist/_internal/shared/fees/calculator.js +0 -7
  43. package/dist/_internal/shared/listing-types/tiers.d.ts +94 -0
  44. package/dist/_internal/shared/listing-types/tiers.js +150 -0
  45. package/dist/cli/index.js +0 -2
  46. package/dist/client.d.ts +25 -4
  47. package/dist/client.js +36 -5
  48. package/dist/constants/api-endpoints.d.ts +21 -15
  49. package/dist/constants/api-endpoints.js +7 -8
  50. package/dist/constants/field-names.d.ts +1 -0
  51. package/dist/constants/field-names.js +1 -0
  52. package/dist/constants/notification-types.d.ts +1 -1
  53. package/dist/constants/notification-types.js +1 -1
  54. package/dist/core/integration-keys.d.ts +5 -5
  55. package/dist/core/integration-keys.js +21 -10
  56. package/dist/features/about/components/FeesView.js +0 -6
  57. package/dist/features/about/components/GuidesHubView.js +15 -2
  58. package/dist/features/account/components/NotificationPreferencesPanel.js +3 -4
  59. package/dist/features/account/components/UserOrdersView.js +26 -7
  60. package/dist/features/account/types/index.d.ts +0 -2
  61. package/dist/features/addresses/utils/postal-autofill.d.ts +39 -0
  62. package/dist/features/addresses/utils/postal-autofill.js +54 -0
  63. package/dist/features/admin/actions/notification-actions.d.ts +2 -8
  64. package/dist/features/admin/actions/notification-actions.js +9 -104
  65. package/dist/features/admin/components/AdminGuideHubView.js +1 -8
  66. package/dist/features/admin/components/AdminOrderEditorView.d.ts +1 -1
  67. package/dist/features/admin/components/AdminOrdersView.js +0 -2
  68. package/dist/features/admin/components/AdminSectionsView.js +3 -2
  69. package/dist/features/admin/components/AdminSiteSettingsView.js +22 -68
  70. package/dist/features/admin/components/AdminStoreEditorView.js +72 -34
  71. package/dist/features/admin/components/OwnerQuickActions.d.ts +29 -0
  72. package/dist/features/admin/components/OwnerQuickActions.js +142 -0
  73. package/dist/features/admin/components/sections/adminSectionsTypes.js +13 -4
  74. package/dist/features/admin/components/sections/icon-options.d.ts +21 -0
  75. package/dist/features/admin/components/sections/icon-options.js +23 -0
  76. package/dist/features/admin/components/sections/sectionTemplates.js +4 -1
  77. package/dist/features/admin/constants/site-settings-tabs.d.ts +7 -12
  78. package/dist/features/admin/constants/site-settings-tabs.js +6 -12
  79. package/dist/features/admin/repository/site-settings.repository.js +1 -1
  80. package/dist/features/admin/schemas/admin-editor-forms.d.ts +1 -1
  81. package/dist/features/admin/schemas/admin-editor-forms.js +4 -1
  82. package/dist/features/admin/schemas/admin-user-form.d.ts +0 -61
  83. package/dist/features/admin/schemas/admin-user-form.js +3 -44
  84. package/dist/features/admin/schemas/firestore.d.ts +28 -54
  85. package/dist/features/admin/schemas/firestore.js +40 -18
  86. package/dist/features/auctions/components/AuctionDetailPageView.js +4 -3
  87. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -1
  88. package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -2
  89. package/dist/features/auth/checkout-value-otp.d.ts +1 -1
  90. package/dist/features/auth/checkout-value-otp.js +1 -1
  91. package/dist/features/auth/permissions/constants.d.ts +29 -2
  92. package/dist/features/auth/permissions/constants.js +67 -1
  93. package/dist/features/blog/components/BlogFeaturedCard.d.ts +11 -1
  94. package/dist/features/blog/components/BlogFeaturedCard.js +9 -2
  95. package/dist/features/cart/components/CartDrawer.js +3 -2
  96. package/dist/features/cart/components/CartGroupLineRow.js +2 -1
  97. package/dist/features/cart/components/CartPriceBreakdown.d.ts +0 -2
  98. package/dist/features/cart/components/CartPriceBreakdown.js +1 -1
  99. package/dist/features/cart/components/StoreAddonsPicker.d.ts +2 -5
  100. package/dist/features/cart/components/StoreAddonsPicker.js +4 -5
  101. package/dist/features/cart/hooks/useAddToCart.js +10 -5
  102. package/dist/features/cart/repository/cart.repository.js +1 -2
  103. package/dist/features/cart/schemas/firestore.d.ts +1 -2
  104. package/dist/features/cart/utils/pending-ops.d.ts +11 -1
  105. package/dist/features/cart/utils/pending-ops.js +14 -2
  106. package/dist/features/categories/components/BrandDetailPageView.js +2 -1
  107. package/dist/features/categories/components/BundleDetailView.js +2 -1
  108. package/dist/features/categories/components/CategoryDetailPageView.js +2 -1
  109. package/dist/features/categories/components/CategoryGrid.d.ts +11 -1
  110. package/dist/features/categories/components/CategoryGrid.js +9 -2
  111. package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +10 -5
  112. package/dist/features/checkout/actions/checkout-value-otp-actions.js +2 -88
  113. package/dist/features/classified/components/ClassifiedDetailPageView.js +2 -1
  114. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +2 -1
  115. package/dist/features/events/components/EventCard.d.ts +11 -1
  116. package/dist/features/events/components/EventCard.js +9 -2
  117. package/dist/features/grouped/components/GroupedListingDetailView.js +3 -1
  118. package/dist/features/homepage/components/CTABannerSection.d.ts +3 -1
  119. package/dist/features/homepage/components/CTABannerSection.js +6 -3
  120. package/dist/features/homepage/components/HeroCarousel.js +8 -6
  121. package/dist/features/homepage/components/MarketplaceHomepageView.js +33 -7
  122. package/dist/features/homepage/components/SectionCarousel.js +13 -5
  123. package/dist/features/homepage/components/SecurityHighlightsSection.d.ts +8 -3
  124. package/dist/features/homepage/components/SecurityHighlightsSection.js +2 -2
  125. package/dist/features/homepage/components/StatsCounterSection.d.ts +9 -4
  126. package/dist/features/homepage/components/StatsCounterSection.js +2 -2
  127. package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
  128. package/dist/features/homepage/components/TrustFeaturesSection.d.ts +18 -4
  129. package/dist/features/homepage/components/TrustFeaturesSection.js +5 -5
  130. package/dist/features/homepage/components/WelcomeSection.d.ts +13 -2
  131. package/dist/features/homepage/components/WelcomeSection.js +3 -3
  132. package/dist/features/homepage/components/WhatsAppCommunitySection.d.ts +28 -0
  133. package/dist/features/homepage/components/WhatsAppCommunitySection.js +42 -6
  134. package/dist/features/homepage/components/WhatsAppGlyph.d.ts +20 -0
  135. package/dist/features/homepage/components/WhatsAppGlyph.js +20 -0
  136. package/dist/features/homepage/constants/hero-carousel-styles.d.ts +8 -6
  137. package/dist/features/homepage/constants/hero-carousel-styles.js +8 -6
  138. package/dist/features/homepage/constants/section-copy.d.ts +12 -10
  139. package/dist/features/homepage/constants/section-copy.js +28 -6
  140. package/dist/features/homepage/constants/stat-icons.d.ts +12 -0
  141. package/dist/features/homepage/constants/stat-icons.js +17 -0
  142. package/dist/features/homepage/constants/trust-icon-aliases.d.ts +8 -0
  143. package/dist/features/homepage/constants/trust-icon-aliases.js +75 -0
  144. package/dist/features/homepage/lib/section-defaults.d.ts +16 -1
  145. package/dist/features/homepage/lib/section-defaults.js +24 -4
  146. package/dist/features/homepage/lib/section-renderer.js +48 -8
  147. package/dist/features/homepage/schemas/firestore.d.ts +18 -1
  148. package/dist/features/layout/AppLayoutShell.js +2 -1
  149. package/dist/features/layout/BottomActions.d.ts +1 -0
  150. package/dist/features/layout/BottomActions.js +330 -0
  151. package/dist/features/layout/BottomChrome.d.ts +45 -0
  152. package/dist/features/layout/BottomChrome.js +5 -17
  153. package/dist/features/layout/SideActionDock.js +36 -13
  154. package/dist/features/layout/index.d.ts +2 -7
  155. package/dist/features/layout/index.js +7 -7
  156. package/dist/features/layout/useIsDesktop.d.ts +36 -0
  157. package/dist/features/layout/useIsDesktop.js +48 -0
  158. package/dist/features/live/components/LiveItemDetailPageView.js +2 -1
  159. package/dist/features/orders/actions/refund-actions.js +0 -1
  160. package/dist/features/orders/components/OrderAddonBadges.d.ts +1 -3
  161. package/dist/features/orders/components/OrderAddonBadges.js +3 -4
  162. package/dist/features/orders/components/OrderPaymentSummary.js +15 -2
  163. package/dist/features/orders/components/YourPurchaseStrip.d.ts +24 -0
  164. package/dist/features/orders/components/YourPurchaseStrip.js +77 -0
  165. package/dist/features/orders/components/index.d.ts +2 -1
  166. package/dist/features/orders/components/index.js +1 -1
  167. package/dist/features/orders/repository/orders.repository.d.ts +0 -8
  168. package/dist/features/orders/repository/orders.repository.js +0 -2
  169. package/dist/features/orders/schemas/firestore.d.ts +17 -9
  170. package/dist/features/orders/types/index.d.ts +2 -5
  171. package/dist/features/orders/utils/order-announcement-message.d.ts +18 -0
  172. package/dist/features/orders/utils/order-announcement-message.js +16 -0
  173. package/dist/features/orders/utils/payment-proof-message.d.ts +20 -0
  174. package/dist/features/orders/utils/payment-proof-message.js +17 -0
  175. package/dist/features/parts/components/PartDetailPageView.js +96 -1
  176. package/dist/features/parts/schemas/firestore.d.ts +247 -0
  177. package/dist/features/parts/schemas/firestore.js +6 -6
  178. package/dist/features/pre-orders/components/MarketplacePreorderCard.d.ts +11 -1
  179. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +10 -3
  180. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +4 -3
  181. package/dist/features/products/api/[id]/route.js +8 -1
  182. package/dist/features/products/api/route.js +16 -4
  183. package/dist/features/products/components/AvailabilityScopeHint.js +1 -1
  184. package/dist/features/products/components/InteractiveProductCard.d.ts +7 -1
  185. package/dist/features/products/components/InteractiveProductCard.js +16 -4
  186. package/dist/features/products/components/MarketplaceBundleCard.d.ts +11 -1
  187. package/dist/features/products/components/MarketplaceBundleCard.js +9 -2
  188. package/dist/features/products/components/MarketplacePrizeDrawCard.d.ts +11 -1
  189. package/dist/features/products/components/MarketplacePrizeDrawCard.js +9 -2
  190. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
  191. package/dist/features/products/components/ProductDetailPageView.js +27 -2
  192. package/dist/features/products/components/ProductGrid.d.ts +14 -1
  193. package/dist/features/products/components/ProductGrid.js +22 -5
  194. package/dist/features/products/components/ProductsIndexListing.js +2 -2
  195. package/dist/features/reviews/api/[id]/route.js +83 -23
  196. package/dist/features/reviews/components/PurchaseReviewAffordance.d.ts +6 -0
  197. package/dist/features/reviews/components/PurchaseReviewAffordance.js +42 -0
  198. package/dist/features/reviews/components/ReviewFormDrawer.d.ts +34 -0
  199. package/dist/features/reviews/components/ReviewFormDrawer.js +127 -0
  200. package/dist/features/reviews/components/index.d.ts +4 -0
  201. package/dist/features/reviews/components/index.js +2 -0
  202. package/dist/features/scams/schemas/index.d.ts +10 -10
  203. package/dist/features/search/action-index/settings-entries.js +0 -9
  204. package/dist/features/seller/actions/seller-actions.d.ts +1 -1
  205. package/dist/features/seller/actions/seller-actions.js +49 -3
  206. package/dist/features/seller/components/SellerPayoutSettingsView.js +30 -2
  207. package/dist/features/seller/components/SellerProductShell.d.ts +17 -1
  208. package/dist/features/seller/hooks/useStoreListingEntitlements.d.ts +8 -0
  209. package/dist/features/seller/hooks/useStoreListingEntitlements.js +70 -0
  210. package/dist/features/store-extensions/repository/store-extensions.repositories.d.ts +1 -6
  211. package/dist/features/store-extensions/repository/store-extensions.repositories.js +1 -10
  212. package/dist/features/store-extensions/schemas/firestore.d.ts +1 -17
  213. package/dist/features/store-extensions/schemas/firestore.js +0 -10
  214. package/dist/features/stores/components/InteractiveStoreCard.d.ts +11 -1
  215. package/dist/features/stores/components/InteractiveStoreCard.js +9 -2
  216. package/dist/features/stores/components/StoreCapabilitiesGuideView.js +0 -1
  217. package/dist/features/stores/components/StoreGuideHubView.js +2 -8
  218. package/dist/features/stores/components/StoreSettingsGuideView.js +2 -6
  219. package/dist/features/stores/components/index.d.ts +0 -2
  220. package/dist/features/stores/components/index.js +0 -1
  221. package/dist/features/stores/repository/store.repository.d.ts +1 -26
  222. package/dist/features/stores/repository/store.repository.js +5 -60
  223. package/dist/features/stores/schemas/firestore.d.ts +6 -25
  224. package/dist/features/stores/schemas/firestore.js +6 -3
  225. package/dist/features/stores/schemas/index.d.ts +1 -87
  226. package/dist/features/stores/schemas/index.js +10 -15
  227. package/dist/features/tester/seed-data/authored/admin__site-system.js +0 -48
  228. package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +0 -40
  229. package/dist/features/tester/seed-data/authored/selling__quick-add-minimum-details.js +0 -16
  230. package/dist/features/tester/seed-data/authored/selling__seller-guide.js +1 -1
  231. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +0 -79
  232. package/dist/features/tester/seed-data/authored/selling__seller-orders.js +1 -1
  233. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +415 -69
  234. package/dist/index.d.ts +20 -32
  235. package/dist/index.js +34 -43
  236. package/dist/next/routing/route-map.d.ts +2 -8
  237. package/dist/next/routing/route-map.js +21 -4
  238. package/dist/providers/db-firebase/base.repository.d.ts +1 -1
  239. package/dist/providers/db-firebase/base.repository.js +1 -1
  240. package/dist/providers/payment-razorpay/index.d.ts +125 -0
  241. package/dist/providers/payment-razorpay/index.js +232 -0
  242. package/dist/providers/payment-razorpay/signature.d.ts +53 -0
  243. package/dist/providers/payment-razorpay/signature.js +71 -0
  244. package/dist/providers/shipping-shiprocket/index.d.ts +98 -0
  245. package/dist/providers/shipping-shiprocket/index.js +356 -0
  246. package/dist/providers.d.ts +3 -0
  247. package/dist/providers.js +3 -0
  248. package/dist/react/hooks/useCanSeePrices.d.ts +0 -27
  249. package/dist/react/hooks/useCanSeePrices.js +25 -0
  250. package/dist/repositories/index.d.ts +1 -1
  251. package/dist/repositories/index.js +1 -1
  252. package/dist/schemas/registry.d.ts +10 -115
  253. package/dist/schemas/registry.js +1 -2
  254. package/dist/security/pii-encrypt.js +1 -1
  255. package/dist/seed/_helpers/category-forest.js +27 -0
  256. package/dist/seed/_helpers/category-parts-glossary-map.js +1816 -88
  257. package/dist/seed/_helpers/category-parts.d.ts +1 -1
  258. package/dist/seed/_helpers/category-parts.js +13399 -3019
  259. package/dist/seed/carousel-slides-seed-data.js +47 -10
  260. package/dist/seed/categories-seed-data.js +48 -6
  261. package/dist/seed/faq-seed-data.js +2 -2
  262. package/dist/seed/homepage-sections-seed-data.js +286 -54
  263. package/dist/seed/index.d.ts +1 -1
  264. package/dist/seed/index.js +1 -1
  265. package/dist/seed/manifest.d.ts +1 -1
  266. package/dist/seed/manifest.js +1 -2
  267. package/dist/seed/model-composition-seed-data.js +6 -8
  268. package/dist/seed/part-glossary/chunk0.d.ts +9 -0
  269. package/dist/seed/part-glossary/chunk0.js +35448 -0
  270. package/dist/seed/part-glossary/chunk1.d.ts +9 -0
  271. package/dist/seed/part-glossary/chunk1.js +40494 -0
  272. package/dist/seed/part-glossary/chunk2.d.ts +9 -0
  273. package/dist/seed/part-glossary/chunk2.js +51242 -0
  274. package/dist/seed/part-glossary/chunk3.d.ts +9 -0
  275. package/dist/seed/part-glossary/chunk3.js +53337 -0
  276. package/dist/seed/part-glossary/chunk4.d.ts +9 -0
  277. package/dist/seed/part-glossary/chunk4.js +51454 -0
  278. package/dist/seed/part-glossary-seed-data.d.ts +1 -1
  279. package/dist/seed/part-glossary-seed-data.js +23 -47483
  280. package/dist/seed/products-catalogue-seed-data.d.ts +5 -5
  281. package/dist/seed/products-catalogue-seed-data.js +63936 -13803
  282. package/dist/seed/site-settings-seed-data.js +34 -35
  283. package/dist/seed/store-extensions-seed-data.d.ts +1 -2
  284. package/dist/seed/store-extensions-seed-data.js +1 -23
  285. package/dist/seed/stores-seed-data.js +0 -1
  286. package/dist/server-entry.d.ts +1 -1
  287. package/dist/server-entry.js +1 -1
  288. package/dist/server.d.ts +8 -10
  289. package/dist/server.js +16 -22
  290. package/dist/styles.css +392 -43
  291. package/dist/tailwind-utilities.css +1 -1
  292. package/dist/tokens/themes/default-dark.js +1 -1
  293. package/dist/tokens/themes/default-light.js +2 -1
  294. package/dist/tokens/tokens.css +6 -2
  295. package/dist/ui/components/Button.d.ts +11 -0
  296. package/dist/ui/components/Button.js +11 -0
  297. package/dist/ui/components/Button.style.css +29 -0
  298. package/dist/ui/components/CarouselNav.d.ts +57 -0
  299. package/dist/ui/components/CarouselNav.js +25 -0
  300. package/dist/ui/components/CarouselNav.style.css +265 -0
  301. package/dist/ui/components/GatedPrice.js +30 -3
  302. package/dist/ui/components/GatedPrice.style.css +43 -40
  303. package/dist/ui/components/HorizontalScroller.d.ts +12 -1
  304. package/dist/ui/components/HorizontalScroller.js +43 -3
  305. package/dist/ui/components/ImageMosaic.d.ts +8 -1
  306. package/dist/ui/components/ImageMosaic.js +3 -2
  307. package/dist/ui/components/ImageMosaic.style.css +22 -0
  308. package/dist/ui/components/Layout.style.css +6 -0
  309. package/dist/ui/components/Semantic.d.ts +3 -2
  310. package/dist/ui/components/Semantic.js +1 -0
  311. package/dist/ui/components/Typography.d.ts +2 -0
  312. package/dist/ui/components/Typography.js +2 -0
  313. package/dist/ui/components/Typography.style.css +19 -0
  314. package/dist/ui/components/index.style.css +1 -0
  315. package/dist/ui/index.d.ts +3 -1
  316. package/dist/ui/index.js +4 -0
  317. package/package.json +3 -2
  318. package/dist/_internal/server/jobs/core/whatsappCatalogImport.d.ts +0 -27
  319. package/dist/_internal/server/jobs/core/whatsappCatalogImport.js +0 -172
  320. package/dist/_internal/server/jobs/core/whatsappNotify.d.ts +0 -35
  321. package/dist/_internal/server/jobs/core/whatsappNotify.js +0 -140
  322. package/dist/features/admin/components/AdminWhatsAppGuideView.d.ts +0 -2
  323. package/dist/features/admin/components/AdminWhatsAppGuideView.js +0 -35
  324. package/dist/features/orders/components/MarketplaceOrderCard.d.ts +0 -36
  325. package/dist/features/orders/components/MarketplaceOrderCard.js +0 -57
  326. package/dist/features/stores/components/StoreWhatsAppGuideView.d.ts +0 -3
  327. package/dist/features/stores/components/StoreWhatsAppGuideView.js +0 -12
  328. package/dist/features/whatsapp-bot/api/send-status/route.d.ts +0 -12
  329. package/dist/features/whatsapp-bot/api/send-status/route.js +0 -38
  330. package/dist/features/whatsapp-bot/api/webhook/route.d.ts +0 -12
  331. package/dist/features/whatsapp-bot/api/webhook/route.js +0 -43
  332. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.d.ts +0 -6
  333. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +0 -270
  334. package/dist/features/whatsapp-bot/components/WhatsAppChatButton.d.ts +0 -9
  335. package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +0 -7
  336. package/dist/features/whatsapp-bot/components/index.d.ts +0 -3
  337. package/dist/features/whatsapp-bot/components/index.js +0 -2
  338. package/dist/features/whatsapp-bot/helpers/payment-proof-message.d.ts +0 -14
  339. package/dist/features/whatsapp-bot/helpers/payment-proof-message.js +0 -17
  340. package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +0 -52
  341. package/dist/features/whatsapp-bot/helpers/whatsapp.js +0 -283
  342. package/dist/features/whatsapp-bot/index.d.ts +0 -3
  343. package/dist/features/whatsapp-bot/index.js +0 -3
  344. package/dist/features/whatsapp-bot/manifest.d.ts +0 -2
  345. package/dist/features/whatsapp-bot/manifest.js +0 -13
  346. package/dist/features/whatsapp-bot/messages/en.json +0 -7
  347. package/dist/features/whatsapp-bot/server.d.ts +0 -7
  348. package/dist/features/whatsapp-bot/server.js +0 -7
  349. package/dist/features/whatsapp-bot/types/index.d.ts +0 -126
  350. package/dist/features/whatsapp-bot/types/index.js +0 -1
@@ -110,7 +110,7 @@ export const DEFAULT_DARK_THEME = {
110
110
  "accent-banner": "linear-gradient(to right, var(--appkit-color-primary), var(--appkit-color-secondary))",
111
111
  promotion: "linear-gradient(to bottom right, var(--appkit-color-error), var(--appkit-color-primary), var(--appkit-color-warning))",
112
112
  spotlight: "linear-gradient(to bottom right, rgba(6,182,212,0.10), var(--appkit-color-bg), rgba(6,182,212,0.10))",
113
- "whatsapp-card": "linear-gradient(to bottom right, var(--appkit-color-success), var(--appkit-color-success))",
113
+ "whatsapp-card": "linear-gradient(135deg, var(--appkit-color-whatsapp) 0%, var(--appkit-color-whatsapp-light) 48%, var(--appkit-color-whatsapp-dark) 100%)",
114
114
  glass: "linear-gradient(to bottom right, color-mix(in srgb, var(--appkit-color-surface) 85%, transparent), color-mix(in srgb, var(--appkit-color-surface) 65%, transparent))",
115
115
  "card-indigo": "linear-gradient(to bottom right, rgba(239,68,68,0.10), var(--appkit-color-surface), var(--appkit-color-surface))",
116
116
  "card-teal": "linear-gradient(to bottom right, rgba(6,182,212,0.10), var(--appkit-color-surface), var(--appkit-color-surface))",
@@ -68,6 +68,7 @@ export const DEFAULT_LIGHT_THEME = {
68
68
  "appkit-color-star": "#facc15",
69
69
  "appkit-color-whatsapp-light": "#1ebe5d",
70
70
  "appkit-color-whatsapp-bg": "#ECE5DD",
71
+ "appkit-color-whatsapp-dark": "#075E54",
71
72
  "appkit-color-focus-ring": "#0d9488",
72
73
  "appkit-shadow-glow": "0 0 0 1px rgba(13,148,136,0.10), 0 4px 16px -4px rgba(13,148,136,0.20)",
73
74
  "appkit-shadow-glow-pink": "0 0 0 1px rgba(192,38,211,0.12), 0 4px 16px -4px rgba(192,38,211,0.22)",
@@ -116,7 +117,7 @@ export const DEFAULT_LIGHT_THEME = {
116
117
  "accent-banner": "linear-gradient(to right, var(--appkit-color-primary), var(--appkit-color-secondary))",
117
118
  promotion: "linear-gradient(to bottom right, var(--appkit-color-error), var(--appkit-color-primary), var(--appkit-color-warning))",
118
119
  spotlight: "linear-gradient(to bottom right, var(--appkit-color-info-surface), var(--appkit-color-bg), var(--appkit-color-info-surface))",
119
- "whatsapp-card": "linear-gradient(to bottom right, var(--appkit-color-success), var(--appkit-color-success))",
120
+ "whatsapp-card": "linear-gradient(135deg, var(--appkit-color-whatsapp) 0%, var(--appkit-color-whatsapp-light) 48%, var(--appkit-color-whatsapp-dark) 100%)",
120
121
  glass: "linear-gradient(to bottom right, color-mix(in srgb, var(--appkit-color-surface) 85%, transparent), color-mix(in srgb, var(--appkit-color-surface) 65%, transparent))",
121
122
  "card-indigo": "linear-gradient(to bottom right, var(--appkit-color-primary-50), var(--appkit-color-surface), var(--appkit-color-surface))",
122
123
  "card-teal": "linear-gradient(to bottom right, var(--appkit-color-secondary-50), var(--appkit-color-surface), var(--appkit-color-surface))",
@@ -217,6 +217,10 @@
217
217
  --appkit-color-whatsapp: #25D366;
218
218
  --appkit-color-whatsapp-light: #1ebe5d;
219
219
  --appkit-color-whatsapp-bg: #ECE5DD;
220
+ /* WhatsApp's own deep teal. Needed as a third gradient stop: a green
221
+ darkened with color-mix() reads olive, not teal, so the brand's dark end
222
+ cannot be derived from --appkit-color-whatsapp. */
223
+ --appkit-color-whatsapp-dark: #075E54;
220
224
  --appkit-color-youtube: #FF0000;
221
225
  --appkit-gradient-instagram: linear-gradient(to bottom right, #a855f7, #ec4899, #fb923c);
222
226
  }
@@ -346,7 +350,7 @@
346
350
  --appkit-gradient-accent-banner: linear-gradient(to right, var(--appkit-color-primary), var(--appkit-color-secondary));
347
351
  --appkit-gradient-promotion: linear-gradient(to bottom right, var(--appkit-color-error), var(--appkit-color-primary), var(--appkit-color-warning));
348
352
  --appkit-gradient-spotlight: linear-gradient(to bottom right, var(--appkit-color-info-surface), var(--appkit-color-bg), var(--appkit-color-info-surface));
349
- --appkit-gradient-whatsapp-card: linear-gradient(to bottom right, var(--appkit-color-success), var(--appkit-color-success));
353
+ --appkit-gradient-whatsapp-card: linear-gradient(135deg, var(--appkit-color-whatsapp) 0%, var(--appkit-color-whatsapp-light) 48%, var(--appkit-color-whatsapp-dark) 100%);
350
354
  --appkit-gradient-glass: linear-gradient(to bottom right, color-mix(in srgb, var(--appkit-color-surface) 85%, transparent), color-mix(in srgb, var(--appkit-color-surface) 65%, transparent));
351
355
  --appkit-gradient-card-indigo: linear-gradient(to bottom right, var(--appkit-color-primary-50), var(--appkit-color-surface), var(--appkit-color-surface));
352
356
  --appkit-gradient-card-teal: linear-gradient(to bottom right, var(--appkit-color-secondary-50), var(--appkit-color-surface), var(--appkit-color-surface));
@@ -459,7 +463,7 @@
459
463
  --appkit-gradient-accent-banner: linear-gradient(to right, var(--appkit-color-primary), var(--appkit-color-secondary));
460
464
  --appkit-gradient-promotion: linear-gradient(to bottom right, var(--appkit-color-error), var(--appkit-color-primary), var(--appkit-color-warning));
461
465
  --appkit-gradient-spotlight: linear-gradient(to bottom right, rgba(6,182,212,0.10), var(--appkit-color-bg), rgba(6,182,212,0.10));
462
- --appkit-gradient-whatsapp-card: linear-gradient(to bottom right, var(--appkit-color-success), var(--appkit-color-success));
466
+ --appkit-gradient-whatsapp-card: linear-gradient(135deg, var(--appkit-color-whatsapp) 0%, var(--appkit-color-whatsapp-light) 48%, var(--appkit-color-whatsapp-dark) 100%);
463
467
  --appkit-gradient-glass: linear-gradient(to bottom right, color-mix(in srgb, var(--appkit-color-surface) 85%, transparent), color-mix(in srgb, var(--appkit-color-surface) 65%, transparent));
464
468
  --appkit-gradient-card-indigo: linear-gradient(to bottom right, rgba(239,68,68,0.10), var(--appkit-color-surface), var(--appkit-color-surface));
465
469
  --appkit-gradient-card-teal: linear-gradient(to bottom right, rgba(6,182,212,0.10), var(--appkit-color-surface), var(--appkit-color-surface));
@@ -16,6 +16,17 @@ declare const UI_BUTTON: {
16
16
  readonly ghost: "appkit-button--ghost";
17
17
  readonly danger: "appkit-button--danger";
18
18
  readonly warning: "appkit-button--warning";
19
+ /**
20
+ * A surface-coloured pill for use ON a dark or branded background.
21
+ *
22
+ * WHY: all six variants above are tuned for a light page surface and none
23
+ * is legible on a branded one, which is why call sites were overriding the
24
+ * variant with `!important` instead — `WhatsAppCommunitySection` carried
25
+ * four (`!bg-…whatsapp !text-white !border-0`) because a green button on a
26
+ * green card is invisible. Inverting the pairing (surface fill, themed ink)
27
+ * is legible on any backdrop and needs no overrides.
28
+ */
29
+ readonly inverse: "appkit-button--inverse";
19
30
  };
20
31
  readonly sizes: {
21
32
  readonly sm: "appkit-button--sm";
@@ -41,6 +41,17 @@ const UI_BUTTON = {
41
41
  ghost: "appkit-button--ghost",
42
42
  danger: "appkit-button--danger",
43
43
  warning: "appkit-button--warning",
44
+ /**
45
+ * A surface-coloured pill for use ON a dark or branded background.
46
+ *
47
+ * WHY: all six variants above are tuned for a light page surface and none
48
+ * is legible on a branded one, which is why call sites were overriding the
49
+ * variant with `!important` instead — `WhatsAppCommunitySection` carried
50
+ * four (`!bg-…whatsapp !text-white !border-0`) because a green button on a
51
+ * green card is invisible. Inverting the pairing (surface fill, themed ink)
52
+ * is legible on any backdrop and needs no overrides.
53
+ */
54
+ inverse: "appkit-button--inverse",
44
55
  },
45
56
  sizes: {
46
57
  sm: "appkit-button--sm",
@@ -198,6 +198,35 @@
198
198
  color: inherit;
199
199
  }
200
200
 
201
+ /*
202
+ * `inverse` — a surface-coloured pill for a dark or branded backdrop.
203
+ *
204
+ * The pairing is deliberately the inverse of `primary`: the FILL comes from
205
+ * the page surface and the INK from body text, so it contrasts against
206
+ * whatever colour the card behind it is, in both themes, with no per-call-site
207
+ * override. Four `!important` declarations in WhatsAppCommunitySection and one
208
+ * `!bg-primary` on a TextLink in WelcomeSection existed only because this
209
+ * variant did not.
210
+ *
211
+ * No border: a 1px border between a white pill and a saturated card reads as
212
+ * a seam rather than an edge.
213
+ */
214
+ .appkit-button.appkit-button--inverse {
215
+ background: var(--appkit-color-surface);
216
+ border-color: transparent;
217
+ color: var(--appkit-color-text);
218
+ }
219
+
220
+ .appkit-button.appkit-button--inverse:hover:not(:disabled) {
221
+ background: color-mix(in srgb, var(--appkit-color-surface) 92%, var(--appkit-color-text));
222
+ }
223
+
224
+ /* Same child-inheritance rule the warning variant needs: a nested element with
225
+ no appkit class of its own must not fall back to the themed body colour. */
226
+ .appkit-button.appkit-button--inverse :not([class*="appkit-"]) {
227
+ color: inherit;
228
+ }
229
+
201
230
  .appkit-button__spinner {
202
231
  width: 1rem;
203
232
  height: 1rem;
@@ -0,0 +1,57 @@
1
+ import React from "react";
2
+ /**
3
+ * CarouselNav — the one carousel position/navigation control.
4
+ *
5
+ * Presentational ONLY: it owns no scroll state and no timers. A hero passes its
6
+ * slide index; a rail passes `Math.round(scrollLeft / clientWidth)`. See
7
+ * CarouselNav.style.css for why three separate implementations was the defect
8
+ * this replaces.
9
+ *
10
+ * ## 🛑 Not `<Progress>`
11
+ *
12
+ * `Progress` is `role="progressbar"` with `aria-valuenow` — a claim that
13
+ * something is LOADING. An autoplay timer is decorative chrome; announcing it
14
+ * as progress tells a screen-reader user the page is busy when it is not. The
15
+ * fill here is `aria-hidden` and the segments carry the real semantics.
16
+ *
17
+ * @tag domain:ui
18
+ * @tag layer:component
19
+ * @tag pattern:presentational
20
+ * @tag access:client
21
+ * @tag sideEffects:none
22
+ */
23
+ /** Over imagery, or on a themed page surface. See the CSS for the tone maps. */
24
+ export type CarouselNavTone = "on-media" | "on-surface";
25
+ /**
26
+ * Above this many positions the segment rail becomes unhittable slivers and
27
+ * overflows a phone, so the component switches to a meter plus a counter.
28
+ */
29
+ export declare const CAROUSEL_RAIL_MAX = 8;
30
+ export interface CarouselNavProps {
31
+ /** Total positions. Below 2 the component renders nothing. */
32
+ count: number;
33
+ /** Current zero-based position. */
34
+ index: number;
35
+ /** Jump to a position. Omit to render the rail as a non-interactive readout. */
36
+ onSelect?: (index: number) => void;
37
+ onPrev?: () => void;
38
+ onNext?: () => void;
39
+ tone?: CarouselNavTone;
40
+ /**
41
+ * Autoplay delay in ms, used ONLY to time the fill inside the active segment.
42
+ * Omit or pass 0 when there is no autoplay — the active segment then renders
43
+ * solid instead of animating. This must be the SAME value that drives the
44
+ * caller's timer; a literal here is the 4s-vs-6000ms desync this replaces.
45
+ */
46
+ progressMs?: number;
47
+ /** Freezes the fill. Pass the same flag that suspends the caller's timer. */
48
+ paused?: boolean;
49
+ /** Disables `prev` at the first position / `next` at the last. Ignored when `loop`. */
50
+ atStart?: boolean;
51
+ atEnd?: boolean;
52
+ loop?: boolean;
53
+ /** Names the control group. Required — "carousel" alone is not a name. */
54
+ ariaLabel: string;
55
+ className?: string;
56
+ }
57
+ export declare function CarouselNav({ count, index, onSelect, onPrev, onNext, tone, progressMs, paused, atStart, atEnd, loop, ariaLabel, className, }: CarouselNavProps): React.JSX.Element | null;
@@ -0,0 +1,25 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { ChevronLeft, ChevronRight } from "lucide-react";
4
+ import { ICON_SIZE } from "../icons/icon-registry.js";
5
+ /**
6
+ * Above this many positions the segment rail becomes unhittable slivers and
7
+ * overflows a phone, so the component switches to a meter plus a counter.
8
+ */
9
+ export const CAROUSEL_RAIL_MAX = 8;
10
+ export function CarouselNav({ count, index, onSelect, onPrev, onNext, tone = "on-surface", progressMs = 0, paused = false, atStart = false, atEnd = false, loop = false, ariaLabel, className = "", }) {
11
+ if (count < 2)
12
+ return null;
13
+ const current = Math.min(Math.max(index, 0), count - 1);
14
+ const hasAutoplay = progressMs > 0;
15
+ const useRail = count <= CAROUSEL_RAIL_MAX;
16
+ const prevDisabled = !loop && atStart;
17
+ const nextDisabled = !loop && atEnd;
18
+ return (_jsxs("div", { className: `appkit-carousel-nav ${className}`, "data-tone": tone, "data-paused": paused ? "true" : "false", "data-autoplay": hasAutoplay ? "true" : "false", style: { "--appkit-carousel-progress-duration": `${progressMs}ms` }, role: "group", "aria-label": ariaLabel, children: [onPrev && (_jsx("button", { type: "button", className: "appkit-carousel-nav__arrow", onClick: onPrev, disabled: prevDisabled, "aria-label": "Previous", children: _jsx(ChevronLeft, { className: ICON_SIZE.lg, "aria-hidden": "true" }) })), useRail ? (_jsx("div", { className: "appkit-carousel-nav__rail", children: Array.from({ length: count }, (_, i) => {
19
+ const isCurrent = i === current;
20
+ return (_jsx("button", { type: "button", className: "appkit-carousel-nav__seg", "aria-current": isCurrent ? "true" : undefined, "aria-label": `Go to ${i + 1} of ${count}`, onClick: onSelect ? () => onSelect(i) : undefined, disabled: !onSelect, children: _jsx("span", { className: "appkit-carousel-nav__bar", children: isCurrent && hasAutoplay && (_jsx("span", { className: "appkit-carousel-nav__fill", "aria-hidden": "true" }, `fill-${current}`)) }) }, i));
21
+ }) })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "appkit-carousel-nav__meter", "aria-hidden": "true", children: _jsx("span", { className: "appkit-carousel-nav__meter-thumb", style: {
22
+ left: `${(current / count) * 100}%`,
23
+ width: `${(1 / count) * 100}%`,
24
+ } }) }), _jsxs("span", { className: "appkit-carousel-nav__count", children: [current + 1, " / ", count] })] })), onNext && (_jsx("button", { type: "button", className: "appkit-carousel-nav__arrow", onClick: onNext, disabled: nextDisabled, "aria-label": "Next", children: _jsx(ChevronRight, { className: ICON_SIZE.lg, "aria-hidden": "true" }) }))] }));
25
+ }
@@ -0,0 +1,265 @@
1
+ /*
2
+ * CarouselNav — the ONE carousel position/navigation control.
3
+ *
4
+ * ## 🛑 What it replaces, and why three implementations was the bug
5
+ *
6
+ * There were three unrelated indicator systems on the homepage alone:
7
+ *
8
+ * 1. `features/homepage/constants/hero-carousel-styles.ts` — bespoke Tailwind
9
+ * pill dots plus a separate progress bar, and BOTH arrows stacked in one
10
+ * bottom corner beside the dots.
11
+ * 2. `HorizontalScroller.style.css` — 36px translucent circles at mid-height,
12
+ * `display:none` below 640px, with a 6px scrollbar as the only position
13
+ * cue. Used by SectionCarousel, ShopByCategorySection, BrandsSection and
14
+ * CustomCardsSection, i.e. nearly every rail on the site.
15
+ * 3. `TestimonialsCarousel` — `overflow-x-auto scrollbar-none`, nothing at
16
+ * all, so there was no indication that content continued off-screen.
17
+ *
18
+ * The thing that had to be shared is the APPEARANCE; the call sites differ only
19
+ * in their STATE SOURCE (a hero knows its slide index, a rail derives one from
20
+ * `scrollLeft / clientWidth`). That split is what a presentational primitive is
21
+ * for, and it is why this is a new component rather than two restyles.
22
+ *
23
+ * ## 🛑 Segments, not dots — the active segment IS the progress track
24
+ *
25
+ * The hero previously rendered a progress bar as a child of the active dot and
26
+ * drove it with `animate-[progress-fill_4s_linear_forwards]` — a hardcoded 4s
27
+ * against a seeded `autoplayDelayMs` of 6000, so the bar finished two seconds
28
+ * before the slide moved. A literal cannot track a runtime value. Here the fill
29
+ * is the active segment itself and its duration comes from
30
+ * `--appkit-carousel-progress-duration`, set by the component from the real
31
+ * delay, so the two cannot disagree.
32
+ *
33
+ * ## 🛑 Arrows sit IN the row, not over the track
34
+ *
35
+ * Absolutely-positioning a 44px circle over a single-column card is what forced
36
+ * `display:none` below 640px in the first place, and it also cost every rail
37
+ * 2 × 44px of wrapper gutter to reserve space for controls a phone never saw.
38
+ * In flow, there is no breakpoint at which an affordance disappears and no
39
+ * gutter to reserve — and the arrows stop overlaying product art at a contrast
40
+ * nobody can predict.
41
+ */
42
+
43
+ .appkit-carousel-nav {
44
+ --appkit-carousel-seg-w: 1.5rem;
45
+ --appkit-carousel-seg-w-active: 2.5rem;
46
+ --appkit-carousel-seg-h: 0.1875rem; /* 3px */
47
+ --appkit-carousel-arrow-size: 2.75rem; /* 44px — WCAG 2.5.8 target size */
48
+ /* Overridden inline by the component from the REAL autoplay delay. 0ms means
49
+ "no autoplay", which the [data-autoplay="false"] rule below renders as a
50
+ solid active segment rather than an animation of zero length. */
51
+ --appkit-carousel-progress-duration: 0ms;
52
+
53
+ display: flex;
54
+ align-items: center;
55
+ justify-content: center;
56
+ gap: var(--appkit-space-3, 0.75rem);
57
+ min-height: var(--appkit-carousel-arrow-size);
58
+ }
59
+
60
+ /* --- Tone: the ONLY colour decision in this file ------------------------- */
61
+
62
+ /* Over imagery — white ink on a blurred dark scrim, theme-invariant because a
63
+ product photo is neither light nor dark in a way CSS can know. */
64
+ .appkit-carousel-nav[data-tone="on-media"] {
65
+ --appkit-carousel-track: color-mix(in srgb, #fff 32%, transparent);
66
+ --appkit-carousel-fill: #fff;
67
+ --appkit-carousel-arrow-bg: color-mix(in srgb, #000 38%, transparent);
68
+ --appkit-carousel-arrow-ink: #fff;
69
+ --appkit-carousel-arrow-edge: color-mix(in srgb, #fff 45%, transparent);
70
+ }
71
+
72
+ /* On a themed page surface — follows the active theme in both directions. */
73
+ .appkit-carousel-nav[data-tone="on-surface"] {
74
+ --appkit-carousel-track: var(--appkit-color-border, #e4e4e7);
75
+ --appkit-carousel-fill: var(--appkit-color-primary, #0d9488);
76
+ --appkit-carousel-arrow-bg: var(--appkit-color-surface, #ffffff);
77
+ --appkit-carousel-arrow-ink: var(--appkit-color-text, #18181b);
78
+ --appkit-carousel-arrow-edge: var(--appkit-color-border, #e4e4e7);
79
+ }
80
+
81
+ /* --- Segment rail -------------------------------------------------------- */
82
+
83
+ .appkit-carousel-nav__rail {
84
+ display: flex;
85
+ align-items: center;
86
+ /* `safe center` rather than `center`: a centred overflowing flex row pushes
87
+ its LEADING items past the start edge, where they are unreachable by any
88
+ scroll gesture. See scripts/audit-centred-scroller.mjs. */
89
+ justify-content: safe center;
90
+ gap: var(--appkit-space-1-5, 0.375rem);
91
+ min-width: 0;
92
+ }
93
+
94
+ /*
95
+ * A 3px bar inside a 44px transparent hit box — the TARGET is the button, the
96
+ * VISUAL is the bar. The dots this replaces were `w-2 h-2` with `!min-h-0`,
97
+ * i.e. they actively defeated Button's own minimum target height to reach an
98
+ * 8px tap target.
99
+ */
100
+ .appkit-carousel-nav__seg {
101
+ display: flex;
102
+ align-items: center;
103
+ padding-block: calc((var(--appkit-carousel-arrow-size) - var(--appkit-carousel-seg-h)) / 2);
104
+ padding-inline: 0;
105
+ background: none;
106
+ border: 0;
107
+ cursor: pointer;
108
+ -webkit-tap-highlight-color: transparent;
109
+ }
110
+
111
+ .appkit-carousel-nav__bar {
112
+ position: relative;
113
+ display: block;
114
+ overflow: hidden;
115
+ width: var(--appkit-carousel-seg-w);
116
+ height: var(--appkit-carousel-seg-h);
117
+ border-radius: 9999px;
118
+ background: var(--appkit-carousel-track);
119
+ transition:
120
+ width 420ms cubic-bezier(0.22, 1, 0.36, 1),
121
+ background 180ms linear;
122
+ }
123
+
124
+ .appkit-carousel-nav__seg:hover .appkit-carousel-nav__bar,
125
+ .appkit-carousel-nav__seg:focus-visible .appkit-carousel-nav__bar {
126
+ background: color-mix(in srgb, var(--appkit-carousel-fill) 55%, transparent);
127
+ }
128
+
129
+ .appkit-carousel-nav__seg[aria-current="true"] .appkit-carousel-nav__bar {
130
+ width: var(--appkit-carousel-seg-w-active);
131
+ background: color-mix(in srgb, var(--appkit-carousel-fill) 28%, transparent);
132
+ }
133
+
134
+ /*
135
+ * `scaleX`, not `width`: it is compositor-only, and it leaves the bar's own
136
+ * `width` transition free to animate the 1.5rem → 2.5rem expansion at the same
137
+ * time without the two fighting over one property.
138
+ */
139
+ .appkit-carousel-nav__fill {
140
+ position: absolute;
141
+ inset: 0;
142
+ transform-origin: left center;
143
+ background: var(--appkit-carousel-fill);
144
+ animation: appkit-carousel-fill var(--appkit-carousel-progress-duration, 0ms) linear forwards;
145
+ }
146
+
147
+ /* Hover-pause previously stopped the setInterval and left the bar filling, so
148
+ the indicator claimed the slide was about to advance while it was held. */
149
+ .appkit-carousel-nav[data-paused="true"] .appkit-carousel-nav__fill {
150
+ animation-play-state: paused;
151
+ }
152
+
153
+ .appkit-carousel-nav[data-autoplay="false"] .appkit-carousel-nav__fill {
154
+ animation: none;
155
+ transform: scaleX(1);
156
+ }
157
+
158
+ @keyframes appkit-carousel-fill {
159
+ from {
160
+ transform: scaleX(0);
161
+ }
162
+ to {
163
+ transform: scaleX(1);
164
+ }
165
+ }
166
+
167
+ /* --- Arrows -------------------------------------------------------------- */
168
+
169
+ .appkit-carousel-nav__arrow {
170
+ display: inline-flex;
171
+ flex: none;
172
+ align-items: center;
173
+ justify-content: center;
174
+ width: var(--appkit-carousel-arrow-size);
175
+ height: var(--appkit-carousel-arrow-size);
176
+ border-radius: 9999px;
177
+ border: 0;
178
+ background: var(--appkit-carousel-arrow-bg);
179
+ color: var(--appkit-carousel-arrow-ink);
180
+ box-shadow:
181
+ inset 0 0 0 1px var(--appkit-carousel-arrow-edge),
182
+ 0 1px 2px color-mix(in srgb, #000 8%, transparent);
183
+ backdrop-filter: blur(10px) saturate(140%);
184
+ cursor: pointer;
185
+ transition:
186
+ transform 180ms cubic-bezier(0.22, 1, 0.36, 1),
187
+ background 180ms linear;
188
+ }
189
+
190
+ .appkit-carousel-nav__arrow:hover:not(:disabled) {
191
+ transform: scale(1.06);
192
+ }
193
+
194
+ .appkit-carousel-nav__arrow:active:not(:disabled) {
195
+ transform: scale(0.94);
196
+ }
197
+
198
+ .appkit-carousel-nav__arrow:disabled,
199
+ .appkit-carousel-nav__arrow[aria-disabled="true"] {
200
+ opacity: 0.4;
201
+ pointer-events: none;
202
+ }
203
+
204
+ /* --- Counter mode ------------------------------------------------------- */
205
+
206
+ /*
207
+ * Above CAROUSEL_RAIL_MAX positions the segments become unhittable slivers and
208
+ * the row overflows a phone, so a long rail shows one continuous meter plus a
209
+ * tabular "4 / 17" instead. Dropping to a counter is a real affordance; a row
210
+ * of forty 2px dots is not.
211
+ */
212
+ .appkit-carousel-nav__meter {
213
+ position: relative;
214
+ overflow: hidden;
215
+ width: clamp(4rem, 18vw, 9rem);
216
+ height: var(--appkit-carousel-seg-h);
217
+ border-radius: 9999px;
218
+ background: var(--appkit-carousel-track);
219
+ }
220
+
221
+ .appkit-carousel-nav__meter-thumb {
222
+ position: absolute;
223
+ inset-block: 0;
224
+ border-radius: 9999px;
225
+ background: var(--appkit-carousel-fill);
226
+ transition: left 320ms cubic-bezier(0.22, 1, 0.36, 1);
227
+ }
228
+
229
+ .appkit-carousel-nav__count {
230
+ font-variant-numeric: tabular-nums;
231
+ font-size: var(--appkit-text-xs, 0.75rem);
232
+ color: var(--appkit-carousel-arrow-ink);
233
+ white-space: nowrap;
234
+ }
235
+
236
+ /* --- Compact (phones) --------------------------------------------------- */
237
+
238
+ @media (max-width: 639px) {
239
+ .appkit-carousel-nav {
240
+ --appkit-carousel-seg-w: 1rem;
241
+ --appkit-carousel-seg-w-active: 1.75rem;
242
+ gap: var(--appkit-space-2, 0.5rem);
243
+ }
244
+ }
245
+
246
+ /* --- Inside a HorizontalScroller ---------------------------------------- */
247
+
248
+ /* Breathing room between the rail and its indicator. A margin here rather than
249
+ a gap on `.appkit-hscroller`, because that wrapper is also the positioning
250
+ context for the absolute arrows and a gap would move them. */
251
+ .appkit-hscroller__nav {
252
+ margin-top: var(--appkit-space-3, 0.75rem);
253
+ }
254
+
255
+ @media (prefers-reduced-motion: reduce) {
256
+ .appkit-carousel-nav__fill {
257
+ animation: none;
258
+ transform: scaleX(1);
259
+ }
260
+ .appkit-carousel-nav__bar,
261
+ .appkit-carousel-nav__meter-thumb,
262
+ .appkit-carousel-nav__arrow {
263
+ transition: none;
264
+ }
265
+ }
@@ -1,8 +1,11 @@
1
1
  "use client";
2
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import React from "react";
3
4
  import { Span } from "./Typography.js";
4
5
  import { Row } from "./Layout.js";
5
- import { ROUTES } from "../../next/routing/route-map.js";
6
+ import { Icon } from "./Icon.js";
7
+ import { IconButton, ICON_BUTTON_ICON_SIZE } from "./IconButton.js";
8
+ import { LoginRequiredModal } from "./LoginRequiredModal.js";
6
9
  import { getDefaultCurrency } from "../../core/baseline-resolver.js";
7
10
  import { formatCurrency, formatPercentage } from "../../utils/number.formatter.js";
8
11
  import { useCanSeePrices } from "../../react/hooks/useCanSeePrices.js";
@@ -24,6 +27,30 @@ import { useCanSeePrices } from "../../react/hooks/useCanSeePrices.js";
24
27
  // audit-dead-css-ok: selector target for the paywall JSON-LD, never styled
25
28
  export const GATED_PRICE_CLASS = "appkit-gated-price";
26
29
  const DEFAULT_LABEL = "Sign in to see price";
30
+ /**
31
+ * The signed-out state: a closed eye you can press, not a line of refusal copy.
32
+ *
33
+ * 🛑 WHY AN ICON AND NOT THE SENTENCE. The prompt used to be a full
34
+ * "🔒 Sign in to see price" link in `--appkit-color-primary`, repeated once per
35
+ * card. On a 24-card grid that is 24 lines of brand-coloured refusal, each
36
+ * wider than the price it stands in for — so the grid's loudest element became
37
+ * the thing the visitor cannot have, and the rows it sat in changed width with
38
+ * the copy. An eye occupies roughly a price's worth of space, reads as "there
39
+ * is something here", and says it once per card without shouting.
40
+ *
41
+ * 🛑 THE ASK IS ON THE CLICK, NOT ON THE PAGE. Pressing it opens the shared
42
+ * sign-in modal rather than navigating away: a visitor who taps a price on a
43
+ * listing page wants the price, not to lose their place in the catalogue. The
44
+ * modal is rendered only while open, so a grid of 24 gated prices mounts 24
45
+ * buttons and zero modals.
46
+ *
47
+ * The accessible name is still the full sentence — the icon is the visual
48
+ * economy, not an information loss.
49
+ */
50
+ function GatedPriceReveal({ label }) {
51
+ const [asking, setAsking] = React.useState(false);
52
+ return (_jsxs(_Fragment, { children: [_jsx(IconButton, { size: "sm", variant: "outline", rounded: "lg", "aria-label": label, title: label, onClick: () => setAsking(true), icon: _jsx(Icon, { name: "hide", size: ICON_BUTTON_ICON_SIZE.sm }) }), asking && (_jsx(LoginRequiredModal, { isOpen: true, onClose: () => setAsking(false), message: `${label}. Sign in or create an account to see prices across the site.` }))] }));
53
+ }
27
54
  /**
28
55
  * Renders its children only when the viewer may see prices; renders NOTHING
29
56
  * otherwise — no prompt, no placeholder.
@@ -65,7 +92,7 @@ export function GatedPrice({ amount, currency = getDefaultCurrency(), originalAm
65
92
  return (_jsx(Span, { className: `${rootClass} appkit-gated-price__pending`, "aria-hidden": "true" }));
66
93
  }
67
94
  if (!canSeePrices) {
68
- return (_jsx("a", { href: String(ROUTES.AUTH.LOGIN), className: `${rootClass} appkit-gated-price__prompt`, children: label }));
95
+ return (_jsx(Span, { className: `${rootClass} appkit-gated-price__prompt`, children: _jsx(GatedPriceReveal, { label: label }) }));
69
96
  }
70
97
  if (children !== undefined) {
71
98
  return _jsx(Span, { className: rootClass, children: children });
@@ -1,40 +1,43 @@
1
- /**
2
- * Sign-in gate for money amounts on public listing surfaces.
3
- *
4
- * The pending state must occupy the SAME vertical space as a rendered price, or
5
- * every card in a grid reflows once the session resolves. It is deliberately a
6
- * silent placeholder rather than a shimmer: the wait is short, and an animated
7
- * skeleton on 24 cards reads as a page that failed to load.
8
- */
9
- .appkit-gated-price__pending {
10
- display: inline-block;
11
- min-width: 5rem;
12
- height: 1.25rem;
13
- border-radius: 0.25rem;
14
- background: var(--appkit-color-surface-muted);
15
- }
16
-
17
- .appkit-gated-price__prompt {
18
- display: inline-flex;
19
- align-items: center;
20
- gap: 0.25rem;
21
- font-size: 0.8125rem;
22
- font-weight: 600;
23
- line-height: 1.25rem;
24
- color: var(--appkit-color-primary);
25
- text-decoration: none;
26
- cursor: pointer;
27
- }
28
-
29
- .appkit-gated-price__prompt:hover {
30
- text-decoration: underline;
31
- }
32
-
33
- /* A lock glyph via ::before rather than an icon component: this renders inside
34
- card grids, where 24 extra SVG trees per page is real weight for decoration
35
- that carries no meaning the label doesn't already state. */
36
- .appkit-gated-price__prompt::before {
37
- content: "\1F512";
38
- font-size: 0.75rem;
39
- line-height: 1;
40
- }
1
+ /**
2
+ * Sign-in gate for money amounts on public listing surfaces.
3
+ *
4
+ * The pending state must occupy the SAME vertical space as a rendered price, or
5
+ * every card in a grid reflows once the session resolves. It is deliberately a
6
+ * silent placeholder rather than a shimmer: the wait is short, and an animated
7
+ * skeleton on 24 cards reads as a page that failed to load.
8
+ */
9
+ .appkit-gated-price__pending {
10
+ display: inline-block;
11
+ min-width: 5rem;
12
+ height: 1.25rem;
13
+ border-radius: 0.25rem;
14
+ /* 🛑 `--appkit-color-surface-muted` is NOT a token — 15 uses, 0 definitions,
15
+ and `audit-undefined-css-vars` ratchets it down. An undefined custom
16
+ property with no fallback makes the whole declaration invalid, so this
17
+ placeholder had no background at all and the grid still reflowed on
18
+ resolve, which is the one job it has. */
19
+ background: var(--appkit-color-surface-input);
20
+ }
21
+
22
+ .appkit-gated-price__prompt {
23
+ display: inline-flex;
24
+ align-items: center;
25
+ /*
26
+ * The eye is a 2rem IconButton while `__pending` above is a 1.25rem price
27
+ * line, so a GUEST's row grows by 0.75rem once the session resolves. That is
28
+ * deliberate and is the lesser of the two: the alternative is making
29
+ * `__pending` 2rem, which shifts the row for SIGNED-IN users — the ones who
30
+ * end up looking at real content. The guest shift happens once per load and
31
+ * applies to every card identically, so the grid moves as one rather than
32
+ * going ragged.
33
+ */
34
+ line-height: 1.25rem;
35
+ }
36
+
37
+ /*
38
+ * 🛑 The eye itself has NO rules here, on purpose. It is an `<IconButton
39
+ * size="sm" variant="outline">`, so its box, ink, hover and focus ring all
40
+ * come from the design system — a second, private set of button styles for
41
+ * one control is exactly how a UI ends up with two kinds of icon button that
42
+ * drift apart. This wrapper only has to keep the row's height stable.
43
+ */
@@ -36,5 +36,16 @@ export interface HorizontalScrollerProps<T = unknown> {
36
36
  itemClassName?: string;
37
37
  /** When the scroller reaches the last item, snap instantly back to the first instead of stopping. */
38
38
  loop?: boolean;
39
+ /**
40
+ * Render a `CarouselNav` position indicator below the rail.
41
+ *
42
+ * Opt-in rather than default: this is a visible layout change and the rail is
43
+ * used on roughly every listing surface in the app. Pair it with
44
+ * `showArrows={false}` — the in-flow nav carries its own arrows, so leaving
45
+ * both on gives a surface two sets of controls that do the same thing.
46
+ */
47
+ showNav?: boolean;
48
+ /** Names the nav group. Defaults to a generic label; pass the rail's subject. */
49
+ navAriaLabel?: string;
39
50
  }
40
- export declare function HorizontalScroller<T = unknown>({ children, className, gap, snapToItems, showArrows, arrowSize, arrowStyle, showScrollbar, scrollContainerRef: externalRef, onScroll, items, renderItem, keyExtractor, perView, rows, autoScroll, autoScrollInterval, minItemWidth, pauseOnHover, itemClassName, loop, }: HorizontalScrollerProps<T>): import("react").JSX.Element;
51
+ export declare function HorizontalScroller<T = unknown>({ children, className, gap, snapToItems, showArrows, arrowSize, arrowStyle, showScrollbar, scrollContainerRef: externalRef, onScroll, items, renderItem, keyExtractor, perView, rows, autoScroll, autoScrollInterval, minItemWidth, pauseOnHover, itemClassName, loop, showNav, navAriaLabel, }: HorizontalScrollerProps<T>): import("react").JSX.Element;