@mohasinac/appkit 2.7.27 → 2.7.30

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 (359) hide show
  1. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +1 -1
  2. package/dist/_internal/server/features/checkout/actions.js +42 -35
  3. package/dist/_internal/server/features/classified/adapters.d.ts +21 -0
  4. package/dist/_internal/server/features/classified/adapters.js +24 -0
  5. package/dist/_internal/server/features/classified/index.d.ts +3 -0
  6. package/dist/_internal/server/features/classified/index.js +3 -0
  7. package/dist/_internal/server/features/classified/metadata.d.ts +8 -0
  8. package/dist/_internal/server/features/classified/metadata.js +43 -0
  9. package/dist/_internal/server/features/classified/og.d.ts +30 -0
  10. package/dist/_internal/server/features/classified/og.js +76 -0
  11. package/dist/_internal/server/features/digital-code/adapters.d.ts +21 -0
  12. package/dist/_internal/server/features/digital-code/adapters.js +29 -0
  13. package/dist/_internal/server/features/digital-code/index.d.ts +3 -0
  14. package/dist/_internal/server/features/digital-code/index.js +3 -0
  15. package/dist/_internal/server/features/digital-code/metadata.d.ts +8 -0
  16. package/dist/_internal/server/features/digital-code/metadata.js +36 -0
  17. package/dist/_internal/server/features/digital-code/og.d.ts +27 -0
  18. package/dist/_internal/server/features/digital-code/og.js +77 -0
  19. package/dist/_internal/server/features/live/adapters.d.ts +21 -0
  20. package/dist/_internal/server/features/live/adapters.js +34 -0
  21. package/dist/_internal/server/features/live/index.d.ts +3 -0
  22. package/dist/_internal/server/features/live/index.js +3 -0
  23. package/dist/_internal/server/features/live/metadata.d.ts +8 -0
  24. package/dist/_internal/server/features/live/metadata.js +39 -0
  25. package/dist/_internal/server/features/live/og.d.ts +27 -0
  26. package/dist/_internal/server/features/live/og.js +72 -0
  27. package/dist/_internal/server/features/promotions/actions.js +4 -3
  28. package/dist/_internal/server/jobs/core/onOrderCreate.js +19 -16
  29. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +25 -22
  30. package/dist/_internal/server/jobs/core/onProductWrite.js +48 -58
  31. package/dist/_internal/shared/actions/action-registry.js +310 -8
  32. package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
  33. package/dist/_internal/shared/features/brands/schema.d.ts +5 -5
  34. package/dist/_internal/shared/features/cart/schema.d.ts +18 -18
  35. package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
  36. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +38 -38
  37. package/dist/_internal/shared/features/events/schema.d.ts +8 -8
  38. package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
  39. package/dist/_internal/shared/features/products/schema.d.ts +42 -42
  40. package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
  41. package/dist/_internal/shared/features/reviews/schema.d.ts +1 -1
  42. package/dist/_internal/shared/media/limits.js +4 -3
  43. package/dist/client.d.ts +2 -0
  44. package/dist/client.js +1 -0
  45. package/dist/configs/next.js +4 -0
  46. package/dist/constants/table-keys.d.ts +6 -0
  47. package/dist/constants/table-keys.js +9 -0
  48. package/dist/core/hooks/useSyncManager.js +9 -8
  49. package/dist/features/about/components/FeesView.js +10 -7
  50. package/dist/features/about/components/HelpPageView.js +10 -1
  51. package/dist/features/about/components/HowAuctionsWorkView.js +10 -1
  52. package/dist/features/about/components/HowCheckoutWorksView.js +10 -1
  53. package/dist/features/about/components/HowOffersWorkView.js +10 -1
  54. package/dist/features/about/components/HowOrdersWorkView.js +10 -1
  55. package/dist/features/about/components/HowPayoutsWorkView.js +10 -1
  56. package/dist/features/about/components/HowPreOrdersWorkView.js +10 -1
  57. package/dist/features/about/components/HowReviewsWorkView.js +10 -1
  58. package/dist/features/about/components/PublicProfileView.js +44 -14
  59. package/dist/features/about/components/SecurityPrivacyView.js +7 -1
  60. package/dist/features/account/components/AddressesIndexListing.js +2 -2
  61. package/dist/features/account/components/NotificationBell.js +27 -16
  62. package/dist/features/account/components/NotificationPreferencesPanel.d.ts +9 -0
  63. package/dist/features/account/components/NotificationPreferencesPanel.js +91 -0
  64. package/dist/features/account/components/UserSidebar.js +4 -4
  65. package/dist/features/account/components/UserSupportView.js +16 -6
  66. package/dist/features/account/components/index.d.ts +2 -0
  67. package/dist/features/account/components/index.js +1 -0
  68. package/dist/features/account/schemas/index.d.ts +4 -4
  69. package/dist/features/account/types/index.d.ts +34 -0
  70. package/dist/features/admin/actions/admin-actions.js +4 -3
  71. package/dist/features/admin/actions/notification-actions.d.ts +24 -22
  72. package/dist/features/admin/actions/notification-actions.js +122 -22
  73. package/dist/features/admin/components/AdminAdEditorView.js +29 -15
  74. package/dist/features/admin/components/AdminAdsView.js +22 -28
  75. package/dist/features/admin/components/AdminAllEventEntriesView.js +6 -1
  76. package/dist/features/admin/components/AdminBidsView.js +10 -3
  77. package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
  78. package/dist/features/admin/components/AdminBlogView.js +8 -3
  79. package/dist/features/admin/components/AdminBrandsView.js +7 -2
  80. package/dist/features/admin/components/AdminBundleEditorView.js +5 -2
  81. package/dist/features/admin/components/AdminCarouselEditorView.js +6 -3
  82. package/dist/features/admin/components/AdminCarouselView.js +13 -7
  83. package/dist/features/admin/components/AdminCategoriesView.js +8 -3
  84. package/dist/features/admin/components/AdminCategoryEditorView.js +2 -2
  85. package/dist/features/admin/components/AdminContactView.js +6 -1
  86. package/dist/features/admin/components/AdminCouponEditorView.js +8 -2
  87. package/dist/features/admin/components/AdminCouponsView.js +6 -1
  88. package/dist/features/admin/components/AdminEmployeeEditorView.js +12 -9
  89. package/dist/features/admin/components/AdminFaqEditorView.js +2 -2
  90. package/dist/features/admin/components/AdminFaqsView.js +7 -2
  91. package/dist/features/admin/components/AdminFeaturesView.js +4 -3
  92. package/dist/features/admin/components/AdminMediaView.js +9 -8
  93. package/dist/features/admin/components/AdminNavigationView.js +10 -17
  94. package/dist/features/admin/components/AdminNewsletterView.js +6 -1
  95. package/dist/features/admin/components/AdminNotificationsView.js +11 -3
  96. package/dist/features/admin/components/AdminOrdersView.js +6 -1
  97. package/dist/features/admin/components/AdminPayoutsView.js +10 -3
  98. package/dist/features/admin/components/AdminPrizeDrawsView.js +10 -3
  99. package/dist/features/admin/components/AdminProductsView.js +18 -12
  100. package/dist/features/admin/components/AdminReviewsView.js +33 -24
  101. package/dist/features/admin/components/AdminScammerEditorView.js +3 -2
  102. package/dist/features/admin/components/AdminScammersView.js +28 -26
  103. package/dist/features/admin/components/AdminSectionsView.js +112 -99
  104. package/dist/features/admin/components/AdminSessionsView.js +10 -3
  105. package/dist/features/admin/components/AdminSidebar.js +4 -4
  106. package/dist/features/admin/components/AdminSiteSettingsView.js +45 -4
  107. package/dist/features/admin/components/AdminStoresView.js +6 -1
  108. package/dist/features/admin/components/AdminSublistingCategoriesView.js +0 -1
  109. package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
  110. package/dist/features/admin/components/AdminSupportTicketsView.js +32 -34
  111. package/dist/features/admin/components/AdminTeamView.js +6 -1
  112. package/dist/features/admin/components/AdminUserEditorView.js +8 -15
  113. package/dist/features/admin/components/AdminUsersView.js +6 -1
  114. package/dist/features/admin/components/AdminViewCards.js +4 -3
  115. package/dist/features/admin/components/DashboardStats.js +2 -2
  116. package/dist/features/admin/components/DataTable.js +2 -2
  117. package/dist/features/admin/components/sections/adminSectionsTypes.js +4 -3
  118. package/dist/features/admin/repository/chat.repository.js +8 -8
  119. package/dist/features/admin/repository/site-settings.repository.d.ts +1 -0
  120. package/dist/features/admin/repository/site-settings.repository.js +11 -9
  121. package/dist/features/admin/schemas/firestore.d.ts +38 -0
  122. package/dist/features/admin/schemas/firestore.js +15 -0
  123. package/dist/features/auctions/components/AuctionDetailPageView.js +13 -19
  124. package/dist/features/auctions/components/MarketplaceAuctionCard.js +18 -9
  125. package/dist/features/auctions/components/MarketplaceAuctionGrid.js +3 -2
  126. package/dist/features/auctions/components/index.d.ts +0 -1
  127. package/dist/features/auctions/components/index.js +0 -1
  128. package/dist/features/auctions/schemas/index.d.ts +14 -14
  129. package/dist/features/auth/actions/realtime-token-actions.js +19 -4
  130. package/dist/features/auth/components/RegisterForm.js +8 -4
  131. package/dist/features/auth/consent-otp.d.ts +2 -0
  132. package/dist/features/auth/consent-otp.js +8 -0
  133. package/dist/features/auth/schemas/firestore.d.ts +2 -0
  134. package/dist/features/auth/schemas/firestore.js +18 -25
  135. package/dist/features/auth/schemas/index.d.ts +2 -2
  136. package/dist/features/before-after/api/[id]/route.js +8 -6
  137. package/dist/features/before-after/schemas/index.d.ts +2 -2
  138. package/dist/features/blog/actions/blog-actions.d.ts +3 -3
  139. package/dist/features/blog/components/BlogIndexListing.js +21 -2
  140. package/dist/features/blog/components/BlogPostForm.js +11 -5
  141. package/dist/features/blog/components/BlogPostView.js +10 -2
  142. package/dist/features/blog/schemas/index.d.ts +18 -18
  143. package/dist/features/cart/components/CartDrawer.js +3 -2
  144. package/dist/features/cart/repository/cart.repository.js +4 -3
  145. package/dist/features/cart/utils/pending-ops.d.ts +1 -1
  146. package/dist/features/categories/api/[id]/route.js +4 -3
  147. package/dist/features/categories/api/route.js +4 -3
  148. package/dist/features/categories/components/BrandDetailPageView.js +2 -2
  149. package/dist/features/categories/components/BrandDetailTabs.js +2 -2
  150. package/dist/features/categories/components/BundleCollage.d.ts +8 -0
  151. package/dist/features/categories/components/BundleCollage.js +50 -0
  152. package/dist/features/categories/components/BundleDetailView.js +2 -10
  153. package/dist/features/categories/components/BundleItemsPicker.js +20 -13
  154. package/dist/features/categories/components/CategoriesIndexListing.js +28 -9
  155. package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
  156. package/dist/features/categories/components/CategoryDetailTabs.js +2 -2
  157. package/dist/features/categories/components/CategoryProductsListing.js +52 -13
  158. package/dist/features/categories/components/index.d.ts +2 -0
  159. package/dist/features/categories/components/index.js +1 -0
  160. package/dist/features/categories/schemas/index.d.ts +6 -6
  161. package/dist/features/checkout/actions/checkout-actions.js +4 -3
  162. package/dist/features/checkout/hooks/usePaymentCheckout.js +31 -22
  163. package/dist/features/classified/components/ClassifiedFilters.d.ts +8 -0
  164. package/dist/features/classified/components/ClassifiedFilters.js +19 -0
  165. package/dist/features/classified/components/ClassifiedIndexListing.d.ts +4 -0
  166. package/dist/features/classified/components/ClassifiedIndexListing.js +110 -0
  167. package/dist/features/classified/components/ClassifiedListView.d.ts +6 -0
  168. package/dist/features/classified/components/ClassifiedListView.js +43 -0
  169. package/dist/features/classified/components/index.d.ts +6 -0
  170. package/dist/features/classified/components/index.js +3 -0
  171. package/dist/features/collections/api/[slug]/route.js +16 -12
  172. package/dist/features/collections/schemas/index.d.ts +5 -5
  173. package/dist/features/consultation/api/[id]/route.js +12 -9
  174. package/dist/features/consultation/components/ConsultationForm.js +3 -2
  175. package/dist/features/consultation/schemas/index.d.ts +6 -6
  176. package/dist/features/contact/email.js +77 -116
  177. package/dist/features/copilot/components/AdminCopilotView.js +12 -2
  178. package/dist/features/corporate/api/[id]/route.js +12 -9
  179. package/dist/features/corporate/components/CorporateInquiryForm.js +2 -1
  180. package/dist/features/digital-codes/components/DigitalCodeFilters.d.ts +8 -0
  181. package/dist/features/digital-codes/components/DigitalCodeFilters.js +16 -0
  182. package/dist/features/digital-codes/components/DigitalCodesIndexListing.d.ts +4 -0
  183. package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +107 -0
  184. package/dist/features/digital-codes/components/DigitalCodesListView.d.ts +6 -0
  185. package/dist/features/digital-codes/components/DigitalCodesListView.js +37 -0
  186. package/dist/features/digital-codes/components/index.d.ts +6 -0
  187. package/dist/features/digital-codes/components/index.js +3 -0
  188. package/dist/features/events/actions/event-actions.js +4 -3
  189. package/dist/features/events/components/AdminEventEditorView.js +3 -2
  190. package/dist/features/events/components/AdminEventsView.js +4 -2
  191. package/dist/features/events/components/EventPollWidget.js +5 -5
  192. package/dist/features/events/components/EventsIndexListing.js +2 -2
  193. package/dist/features/events/schemas/index.d.ts +20 -20
  194. package/dist/features/faq/actions/faq-actions.d.ts +8 -8
  195. package/dist/features/faq/components/ContactCTA.js +3 -1
  196. package/dist/features/faq/components/FAQAccordion.js +1 -1
  197. package/dist/features/faq/schemas/index.d.ts +4 -4
  198. package/dist/features/filters/AsyncFacetSection.d.ts +18 -0
  199. package/dist/features/filters/AsyncFacetSection.js +65 -0
  200. package/dist/features/forms/Checkbox.js +2 -2
  201. package/dist/features/forms/Input.js +2 -2
  202. package/dist/features/forms/Radio.js +5 -5
  203. package/dist/features/forms/Select.js +2 -2
  204. package/dist/features/forms/Slider.js +2 -2
  205. package/dist/features/forms/Textarea.js +2 -2
  206. package/dist/features/homepage/api/[id]/route.js +4 -3
  207. package/dist/features/homepage/api/sections/[id]/route.js +12 -9
  208. package/dist/features/homepage/components/AdSlot.js +2 -1
  209. package/dist/features/homepage/components/AdvertisementBanner.js +5 -3
  210. package/dist/features/homepage/components/BrandsSection.js +2 -2
  211. package/dist/features/homepage/components/CTABannerSection.js +2 -2
  212. package/dist/features/homepage/components/CharacterHotspot.d.ts +2 -2
  213. package/dist/features/homepage/components/CharacterHotspot.js +119 -157
  214. package/dist/features/homepage/components/CharacterHotspotForm.js +25 -20
  215. package/dist/features/homepage/components/CustomCardsSection.js +8 -6
  216. package/dist/features/homepage/components/FeaturedProductsSection.js +2 -2
  217. package/dist/features/homepage/components/GoogleReviewsSection.js +3 -3
  218. package/dist/features/homepage/components/HeroBanner.js +5 -4
  219. package/dist/features/homepage/components/HeroCarousel.js +13 -26
  220. package/dist/features/homepage/components/HowItWorksSection.js +4 -2
  221. package/dist/features/homepage/components/SocialFeedSection.js +2 -2
  222. package/dist/features/homepage/components/SocialPostCard.js +3 -2
  223. package/dist/features/homepage/lib/social-feed-fetcher.js +6 -3
  224. package/dist/features/layout/AppLayoutShell.d.ts +8 -2
  225. package/dist/features/layout/AppLayoutShell.js +54 -78
  226. package/dist/features/layout/BottomActions.js +43 -48
  227. package/dist/features/live/components/LiveItemFilters.d.ts +8 -0
  228. package/dist/features/live/components/LiveItemFilters.js +23 -0
  229. package/dist/features/live/components/LiveItemsIndexListing.d.ts +4 -0
  230. package/dist/features/live/components/LiveItemsIndexListing.js +108 -0
  231. package/dist/features/live/components/LiveItemsListView.d.ts +6 -0
  232. package/dist/features/live/components/LiveItemsListView.js +43 -0
  233. package/dist/features/live/components/index.d.ts +6 -0
  234. package/dist/features/live/components/index.js +3 -0
  235. package/dist/features/media/MediaLightbox.js +8 -14
  236. package/dist/features/media/types/index.d.ts +2 -2
  237. package/dist/features/media/upload/CameraCapture.js +2 -2
  238. package/dist/features/media/upload/ImageUpload.js +4 -2
  239. package/dist/features/media/upload/MediaUploadField.js +24 -8
  240. package/dist/features/media/upload/MediaUploadList.js +1 -1
  241. package/dist/features/orders/actions/order-actions.js +4 -3
  242. package/dist/features/orders/components/MarketplaceOrderCard.js +2 -1
  243. package/dist/features/orders/components/OrderFilters.js +12 -9
  244. package/dist/features/orders/schemas/index.d.ts +6 -6
  245. package/dist/features/pre-orders/api/[id]/route.js +12 -9
  246. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -4
  247. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +27 -20
  248. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +17 -52
  249. package/dist/features/pre-orders/components/PreorderCard.d.ts +0 -9
  250. package/dist/features/pre-orders/components/PreorderCard.js +2 -13
  251. package/dist/features/pre-orders/components/index.d.ts +1 -1
  252. package/dist/features/pre-orders/components/index.js +1 -1
  253. package/dist/features/pre-orders/schemas/index.d.ts +10 -10
  254. package/dist/features/products/api/[id]/route.js +9 -7
  255. package/dist/features/products/api/route.js +1 -1
  256. package/dist/features/products/columns/productTableColumns.js +2 -2
  257. package/dist/features/products/components/AuctionsIndexListing.js +15 -51
  258. package/dist/features/products/components/BidHistory.js +2 -2
  259. package/dist/features/products/components/CompareOverlay.js +3 -2
  260. package/dist/features/products/components/MakeOfferButton.js +20 -14
  261. package/dist/features/products/components/MarketplacePrizeDrawCard.js +2 -1
  262. package/dist/features/products/components/PrizeDrawCollage.d.ts +1 -15
  263. package/dist/features/products/components/PrizeDrawCollage.js +54 -14
  264. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
  265. package/dist/features/products/components/PrizeDrawEntryActions.js +2 -1
  266. package/dist/features/products/components/PrizeDrawItemsEditor.js +9 -7
  267. package/dist/features/products/components/PrizeDrawsIndexListing.js +18 -51
  268. package/dist/features/products/components/PrizeRevealModal.js +24 -14
  269. package/dist/features/products/components/ProductDetailPageView.js +2 -1
  270. package/dist/features/products/components/ProductFilters.js +8 -6
  271. package/dist/features/products/components/ProductForm.js +12 -10
  272. package/dist/features/products/components/ProductGalleryClient.js +2 -1
  273. package/dist/features/products/components/ProductGrid.js +11 -14
  274. package/dist/features/products/components/ProductsIndexListing.js +16 -52
  275. package/dist/features/products/components/ProductsIndexPageView.js +2 -2
  276. package/dist/features/products/schemas/index.d.ts +56 -56
  277. package/dist/features/products/schemas/product-features.validators.d.ts +14 -14
  278. package/dist/features/promotions/components/CouponsIndexListing.js +1 -1
  279. package/dist/features/promotions/schemas/index.d.ts +6 -6
  280. package/dist/features/reviews/actions/review-actions.js +6 -5
  281. package/dist/features/reviews/api/[id]/route.js +4 -3
  282. package/dist/features/reviews/components/ReviewDetailPageView.js +2 -2
  283. package/dist/features/reviews/components/ReviewDetailShell.js +6 -3
  284. package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
  285. package/dist/features/reviews/schemas/index.d.ts +6 -6
  286. package/dist/features/scams/components/ScamProfileView.js +19 -10
  287. package/dist/features/scams/components/ScamRegistryView.js +2 -1
  288. package/dist/features/search/components/Search.d.ts +1 -1
  289. package/dist/features/search/components/Search.js +56 -49
  290. package/dist/features/search/schemas/index.d.ts +5 -5
  291. package/dist/features/seller/actions/offer-actions.js +11 -9
  292. package/dist/features/seller/components/SellerAddressesView.js +6 -4
  293. package/dist/features/seller/components/SellerBidsView.js +2 -2
  294. package/dist/features/seller/components/SellerCouponsView.js +1 -1
  295. package/dist/features/seller/components/SellerOffersPanel.js +6 -1
  296. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  297. package/dist/features/seller/components/SellerPayoutSettingsView.js +3 -3
  298. package/dist/features/seller/components/SellerPreOrdersView.js +5 -4
  299. package/dist/features/seller/components/SellerPrizeDrawsView.js +5 -4
  300. package/dist/features/seller/components/SellerProductShell.d.ts +19 -1
  301. package/dist/features/seller/components/SellerProductShell.js +75 -9
  302. package/dist/features/seller/components/SellerProductsView.js +10 -11
  303. package/dist/features/seller/components/SellerShippingView.js +3 -3
  304. package/dist/features/seller/components/SellerSidebar.js +10 -7
  305. package/dist/features/seller/components/SellerStorefrontView.js +3 -3
  306. package/dist/features/seller/schemas/index.d.ts +4 -4
  307. package/dist/features/shell/FormShell.js +2 -1
  308. package/dist/features/shell/QuickFormDrawer.js +4 -3
  309. package/dist/features/shell/StepForm.js +4 -3
  310. package/dist/features/stores/actions/store-query-actions.js +4 -3
  311. package/dist/features/stores/components/StoreAboutView.js +2 -1
  312. package/dist/features/stores/components/StoreAuctionsListing.js +43 -64
  313. package/dist/features/stores/components/StoreDetailLayoutView.js +2 -2
  314. package/dist/features/stores/components/StorePreOrdersListing.js +33 -57
  315. package/dist/features/stores/components/StoreProductsListing.js +16 -49
  316. package/dist/features/stores/components/StoresIndexListing.js +2 -2
  317. package/dist/features/stores/schemas/index.d.ts +2 -2
  318. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +8 -7
  319. package/dist/features/wishlist/hooks/useGuestWishlist.d.ts +5 -5
  320. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +6 -6
  321. package/dist/features/wishlist/utils/guest-wishlist.d.ts +5 -5
  322. package/dist/index.d.ts +21 -3
  323. package/dist/index.js +1737 -1725
  324. package/dist/monitoring/server-logger.js +5 -9
  325. package/dist/next/api/apiHandler.js +56 -37
  326. package/dist/next/components/GlobalError.js +2 -1
  327. package/dist/next/routing/route-map.d.ts +27 -0
  328. package/dist/next/routing/route-map.js +10 -0
  329. package/dist/react/ErrorBoundary.js +2 -1
  330. package/dist/react/contexts/SessionContext.js +38 -28
  331. package/dist/react/hooks/useCamera.d.ts +1 -1
  332. package/dist/react/hooks/useCamera.js +8 -7
  333. package/dist/seed/site-settings-seed-data.js +6 -0
  334. package/dist/server-entry.d.ts +3 -0
  335. package/dist/server-entry.js +3 -0
  336. package/dist/server.d.ts +12 -0
  337. package/dist/server.js +15 -0
  338. package/dist/tailwind-utilities.css +1 -1
  339. package/dist/ui/DataTable.js +28 -7
  340. package/dist/ui/components/Button.d.ts +8 -1
  341. package/dist/ui/components/Button.js +47 -8
  342. package/dist/ui/components/CollageLightbox.d.ts +18 -0
  343. package/dist/ui/components/CollageLightbox.js +41 -0
  344. package/dist/ui/components/Dropdown.js +7 -6
  345. package/dist/ui/components/ImageLightbox.d.ts +7 -1
  346. package/dist/ui/components/ImageLightbox.js +15 -5
  347. package/dist/ui/components/PageLoader.js +4 -3
  348. package/dist/ui/components/PaginatedMultiSelect.d.ts +28 -0
  349. package/dist/ui/components/PaginatedMultiSelect.js +141 -0
  350. package/dist/ui/components/PaginatedMultiSelect.style.css +272 -0
  351. package/dist/ui/components/Semantic.js +1 -1
  352. package/dist/ui/components/SideDrawer.js +17 -15
  353. package/dist/ui/components/index.style.css +1 -0
  354. package/dist/ui/index.d.ts +2 -0
  355. package/dist/ui/index.js +1 -0
  356. package/dist/utils/number.formatter.js +5 -13
  357. package/dist/utils/string.formatter.js +21 -18
  358. package/dist/validation/schemas.d.ts +2 -2
  359. package/package.json +1 -1
@@ -10,15 +10,18 @@
10
10
  */
11
11
  import { NextResponse } from "next/server.js";
12
12
  import { getProviders } from "../../../../../contracts";
13
+ const ERR_SECTION_ID_REQUIRED = "Section ID is required";
14
+ const ERR_DB_NOT_CONFIGURED = "Database provider not configured";
15
+ const ERR_INTERNAL_SERVER_ERROR = "Internal server error";
13
16
  export async function GET(request, { params }) {
14
17
  try {
15
18
  const { id } = await params;
16
19
  if (!id) {
17
- return NextResponse.json({ success: false, error: "Section ID required" }, { status: 400 });
20
+ return NextResponse.json({ success: false, error: ERR_SECTION_ID_REQUIRED }, { status: 400 });
18
21
  }
19
22
  const { db } = getProviders();
20
23
  if (!db)
21
- return NextResponse.json({ success: false, error: "DB not configured" }, { status: 503 });
24
+ return NextResponse.json({ success: false, error: ERR_DB_NOT_CONFIGURED }, { status: 503 });
22
25
  const repo = db.getRepository("homepage_sections");
23
26
  const section = await repo.findById(id);
24
27
  if (!section) {
@@ -32,7 +35,7 @@ export async function GET(request, { params }) {
32
35
  catch (error) {
33
36
  return NextResponse.json({
34
37
  success: false,
35
- error: error instanceof Error ? error.message : "Internal server error",
38
+ error: error instanceof Error ? error.message : ERR_INTERNAL_SERVER_ERROR,
36
39
  }, { status: 500 });
37
40
  }
38
41
  }
@@ -40,12 +43,12 @@ export async function PATCH(request, { params }) {
40
43
  try {
41
44
  const { id } = await params;
42
45
  if (!id) {
43
- return NextResponse.json({ success: false, error: "Section ID required" }, { status: 400 });
46
+ return NextResponse.json({ success: false, error: ERR_SECTION_ID_REQUIRED }, { status: 400 });
44
47
  }
45
48
  const body = await request.json();
46
49
  const { db } = getProviders();
47
50
  if (!db)
48
- return NextResponse.json({ success: false, error: "DB not configured" }, { status: 503 });
51
+ return NextResponse.json({ success: false, error: ERR_DB_NOT_CONFIGURED }, { status: 503 });
49
52
  const repo = db.getRepository("homepage_sections");
50
53
  const updated = await repo.update(id, body);
51
54
  if (!updated) {
@@ -59,7 +62,7 @@ export async function PATCH(request, { params }) {
59
62
  catch (error) {
60
63
  return NextResponse.json({
61
64
  success: false,
62
- error: error instanceof Error ? error.message : "Internal server error",
65
+ error: error instanceof Error ? error.message : ERR_INTERNAL_SERVER_ERROR,
63
66
  }, { status: 500 });
64
67
  }
65
68
  }
@@ -67,11 +70,11 @@ export async function DELETE(request, { params }) {
67
70
  try {
68
71
  const { id } = await params;
69
72
  if (!id) {
70
- return NextResponse.json({ success: false, error: "Section ID required" }, { status: 400 });
73
+ return NextResponse.json({ success: false, error: ERR_SECTION_ID_REQUIRED }, { status: 400 });
71
74
  }
72
75
  const { db } = getProviders();
73
76
  if (!db)
74
- return NextResponse.json({ success: false, error: "DB not configured" }, { status: 503 });
77
+ return NextResponse.json({ success: false, error: ERR_DB_NOT_CONFIGURED }, { status: 503 });
75
78
  const repo = db.getRepository("homepage_sections");
76
79
  await repo.delete(id);
77
80
  return NextResponse.json({
@@ -82,7 +85,7 @@ export async function DELETE(request, { params }) {
82
85
  catch (error) {
83
86
  return NextResponse.json({
84
87
  success: false,
85
- error: error instanceof Error ? error.message : "Internal server error",
88
+ error: error instanceof Error ? error.message : ERR_INTERNAL_SERVER_ERROR,
86
89
  }, { status: 500 });
87
90
  }
88
91
  }
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useRef, useState } from "react";
4
4
  import { getAdSlot, isAdSlotRenderable } from "../ad-registry";
5
5
  import { useActiveAd } from "../hooks/useActiveAd";
6
+ import { Text } from "../../../ui";
6
7
  // ---------------------------------------------------------------------------
7
8
  // Sub-renderers
8
9
  // ---------------------------------------------------------------------------
@@ -31,7 +32,7 @@ function ManualAdBanner({ ad }) {
31
32
  const { creative } = ad;
32
33
  if (!creative)
33
34
  return null;
34
- return (_jsxs("a", { href: creative.ctaHref || "#", target: creative.ctaHref ? "_blank" : undefined, rel: "noopener noreferrer", className: "flex items-center gap-3 w-full overflow-hidden rounded-lg bg-zinc-100 dark:bg-zinc-800 px-4 py-3 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors no-underline", children: [creative.imageUrl ? (_jsx("img", { src: creative.imageUrl, alt: creative.title || "Advertisement", className: "h-14 w-14 rounded object-cover flex-shrink-0", loading: "lazy" })) : null, _jsxs("div", { className: "flex-1 min-w-0", children: [creative.title ? (_jsx("p", { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 truncate", children: creative.title })) : null, creative.body ? (_jsx("p", { className: "text-xs text-zinc-500 dark:text-zinc-400 truncate", children: creative.body })) : null] }), creative.ctaLabel ? (_jsx("span", { className: "flex-shrink-0 rounded-md bg-primary px-3 py-1.5 text-xs font-semibold text-white", children: creative.ctaLabel })) : null] }));
35
+ return (_jsxs("a", { href: creative.ctaHref || "#", target: creative.ctaHref ? "_blank" : undefined, rel: "noopener noreferrer", className: "flex items-center gap-3 w-full overflow-hidden rounded-lg bg-zinc-100 dark:bg-zinc-800 px-4 py-3 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors no-underline", children: [creative.imageUrl ? (_jsx("img", { src: creative.imageUrl, alt: creative.title || "Advertisement", className: "h-14 w-14 rounded object-cover flex-shrink-0", loading: "lazy" })) : null, _jsxs("div", { className: "flex-1 min-w-0", children: [creative.title ? (_jsx(Text, { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 truncate", children: creative.title })) : null, creative.body ? (_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 truncate", children: creative.body })) : null] }), creative.ctaLabel ? (_jsx("span", { className: "flex-shrink-0 rounded-md bg-primary px-3 py-1.5 text-xs font-semibold text-white", children: creative.ctaLabel })) : null] }));
35
36
  }
36
37
  // ---------------------------------------------------------------------------
37
38
  // Primary component
@@ -3,18 +3,20 @@ import { THEME_CONSTANTS } from "../../../tokens";
3
3
  import { Button, Heading, Row, Section, Span, Text } from "../../../ui";
4
4
  import { MediaImage } from "../../media/MediaImage";
5
5
  import { ArrowRight, Sparkles } from "lucide-react";
6
+ // --- Constants ---------------------------------------------------------------
7
+ const CLS_CONTAINER = "w-full max-w-7xl mx-auto";
6
8
  // --- Component ---------------------------------------------------------------
7
9
  export function AdvertisementBanner({ title, subtitle, ctaLabel = "Shop now", onCtaClick, backgroundImage, backgroundColor, tagLabel, isLoading = false, compact = false, className = "", }) {
8
10
  const wrapClass = "bg-gradient-to-br from-amber-50/40 to-orange-50/20 dark:from-amber-950/10 dark:to-orange-950/5";
9
11
  if (isLoading) {
10
- return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: "w-full max-w-7xl mx-auto", "data-section": "advertisementbanner-div-297", children: _jsx("div", { className: "h-72 bg-zinc-200 dark:bg-slate-700 rounded-2xl animate-pulse" }) }) }));
12
+ return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: CLS_CONTAINER, "data-section": "advertisementbanner-div-297", children: _jsx("div", { className: "h-72 bg-zinc-200 dark:bg-slate-700 rounded-2xl animate-pulse" }) }) }));
11
13
  }
12
14
  // -- Split layout: when a backgroundImage is provided --
13
15
  if (backgroundImage) {
14
- return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: "w-full max-w-7xl mx-auto", "data-section": "advertisementbanner-div-298", children: _jsx("div", { className: "relative overflow-hidden rounded-2xl bg-zinc-900 shadow-xl", "data-section": "advertisementbanner-div-299", children: _jsxs("div", { className: `${THEME_CONSTANTS.grid.cols2Md} min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-300", children: [_jsxs("div", { className: `relative ${THEME_CONSTANTS.card.aspectBanner} order-last md:order-first min-h-0 min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-301", children: [_jsx(MediaImage, { src: backgroundImage, alt: title, size: "banner", priority: true }), _jsx("div", { className: "hidden md:block absolute inset-y-0 right-0 w-24 bg-gradient-to-r from-transparent to-zinc-900/60 pointer-events-none" })] }), _jsxs("div", { className: "relative flex flex-col justify-center px-8 py-10 md:px-12 md:py-14", "data-section": "advertisementbanner-div-302", children: [_jsx("div", { className: "absolute top-0 right-0 w-32 h-32 opacity-10 pointer-events-none bg-[radial-gradient(circle,_white_1px,_transparent_1px)] bg-[length:12px_12px]", "aria-hidden": true }), tagLabel && (_jsxs("div", { className: "inline-flex items-center gap-1.5 self-start bg-white/10 text-white/80 text-xs font-semibold uppercase tracking-widest px-3 py-1 rounded-full mb-5 backdrop-blur-sm", "data-section": "advertisementbanner-div-303", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), tagLabel] })), _jsx(Heading, { level: 2, variant: "none", className: "text-3xl md:text-4xl lg:text-5xl font-extrabold text-white mb-4 leading-tight", children: title }), subtitle && (_jsx(Text, { variant: "none", className: "text-white/75 text-base md:text-lg mb-8 leading-relaxed", children: subtitle })), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "lg", onClick: onCtaClick, className: "self-start bg-white text-zinc-900 hover:bg-zinc-100 font-semibold shadow-lg gap-2", children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] })] }) }) }) }));
16
+ return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: CLS_CONTAINER, "data-section": "advertisementbanner-div-298", children: _jsx("div", { className: "relative overflow-hidden rounded-2xl bg-zinc-900 shadow-xl", "data-section": "advertisementbanner-div-299", children: _jsxs("div", { className: `${THEME_CONSTANTS.grid.cols2Md} min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-300", children: [_jsxs("div", { className: `relative ${THEME_CONSTANTS.card.aspectBanner} order-last md:order-first min-h-0 min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-301", children: [_jsx(MediaImage, { src: backgroundImage, alt: title, size: "banner", priority: true }), _jsx("div", { className: "hidden md:block absolute inset-y-0 right-0 w-24 bg-gradient-to-r from-transparent to-zinc-900/60 pointer-events-none" })] }), _jsxs("div", { className: "relative flex flex-col justify-center px-8 py-10 md:px-12 md:py-14", "data-section": "advertisementbanner-div-302", children: [_jsx("div", { className: "absolute top-0 right-0 w-32 h-32 opacity-10 pointer-events-none bg-[radial-gradient(circle,_white_1px,_transparent_1px)] bg-[length:12px_12px]", "aria-hidden": true }), tagLabel && (_jsxs("div", { className: "inline-flex items-center gap-1.5 self-start bg-white/10 text-white/80 text-xs font-semibold uppercase tracking-widest px-3 py-1 rounded-full mb-5 backdrop-blur-sm", "data-section": "advertisementbanner-div-303", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), tagLabel] })), _jsx(Heading, { level: 2, variant: "none", className: "text-3xl md:text-4xl lg:text-5xl font-extrabold text-white mb-4 leading-tight", children: title }), subtitle && (_jsx(Text, { variant: "none", className: "text-white/75 text-base md:text-lg mb-8 leading-relaxed", children: subtitle })), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "lg", onClick: onCtaClick, className: "self-start bg-white text-zinc-900 hover:bg-zinc-100 font-semibold shadow-lg gap-2", children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] })] }) }) }) }));
15
17
  }
16
18
  // -- Full-width gradient layout --
17
- return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: "w-full max-w-7xl mx-auto", "data-section": "advertisementbanner-div-304", children: _jsxs("div", { className: [
19
+ return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: CLS_CONTAINER, "data-section": "advertisementbanner-div-304", children: _jsxs("div", { className: [
18
20
  "relative overflow-hidden rounded-2xl flex items-center",
19
21
  compact
20
22
  ? "h-[clamp(112px,16vh,160px)]"
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
4
  import Image from "next/image";
5
5
  import Link from "next/link";
@@ -39,5 +39,5 @@ export function BrandsSection({ title = "Top Brands", subtitle, limit = 12, view
39
39
  });
40
40
  if (!isLoading && allBrands.length === 0)
41
41
  return null;
42
- return (_jsx(Section, { className: `py-12 px-4 ${themed.bgSecondary} ${className}`, children: _jsxs("div", { className: "mx-auto max-w-7xl", children: [_jsxs("div", { className: "mb-6 flex items-center justify-between", children: [_jsxs("div", { children: [_jsx(Heading, { level: 2, className: `text-2xl font-bold md:text-3xl ${themed.textPrimary}`, children: title }), subtitle && (_jsx(Text, { variant: "secondary", className: "mt-1 text-sm", children: subtitle }))] }), !cta && viewMoreHref && (_jsx(Link, { href: viewMoreHref, className: "text-sm font-medium text-[var(--appkit-color-primary)] hover:underline", children: viewMoreLabel }))] }), showFeaturedChip && !isLoading && (_jsxs("div", { className: "mb-4 flex flex-wrap gap-2", children: [_jsx(BrandFilterChip, { label: "All", active: activeFilter === "all", onClick: () => setActiveFilter("all") }), _jsx(BrandFilterChip, { label: "Featured", active: activeFilter === "featured", onClick: () => setActiveFilter(activeFilter === "featured" ? "all" : "featured") })] })), isLoading ? (_jsx("div", { className: "flex gap-3 overflow-hidden", children: Array.from({ length: 8 }).map((_, i) => (_jsx("div", { className: "h-24 w-28 flex-none animate-pulse rounded-xl bg-zinc-200 dark:bg-slate-700" }, i))) })) : (_jsx(HorizontalScroller, { items: brands, renderItem: (brand) => _jsx(BrandLogo, { brand: brand }), keyExtractor: (brand) => brand.id, gap: 12, showArrows: true, showScrollbar: false })), cta && !isLoading && (_jsx("div", { className: "mt-6 text-center", children: _jsx(Link, { href: cta.href, className: CTA_CLASSES[cta.variant], children: cta.label }) }))] }) }));
42
+ return (_jsx(Section, { className: `py-12 px-4 ${themed.bgSecondary} ${className}`, children: _jsxs("div", { className: "mx-auto max-w-7xl", children: [_jsxs("div", { className: "mb-6 flex items-center justify-between", children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 2, className: `text-2xl font-bold md:text-3xl ${themed.textPrimary}`, children: title }), subtitle && (_jsx(Text, { variant: "secondary", className: "mt-1 text-sm", children: subtitle }))] }), !cta && viewMoreHref && (_jsx(Link, { href: viewMoreHref, className: "text-sm font-medium text-[var(--appkit-color-primary)] hover:underline", children: viewMoreLabel }))] }), showFeaturedChip && !isLoading && (_jsxs("div", { className: "mb-4 flex flex-wrap gap-2", children: [_jsx(BrandFilterChip, { label: "All", active: activeFilter === "all", onClick: () => setActiveFilter("all") }), _jsx(BrandFilterChip, { label: "Featured", active: activeFilter === "featured", onClick: () => setActiveFilter(activeFilter === "featured" ? "all" : "featured") })] })), isLoading ? (_jsx("div", { className: "flex gap-3 overflow-hidden", children: Array.from({ length: 8 }).map((_, i) => (_jsx("div", { className: "h-24 w-28 flex-none animate-pulse rounded-xl bg-zinc-200 dark:bg-slate-700" }, i))) })) : (_jsx(HorizontalScroller, { items: brands, renderItem: (brand) => _jsx(BrandLogo, { brand: brand }), keyExtractor: (brand) => brand.id, gap: 12, showArrows: true, showScrollbar: false })), cta && !isLoading && (_jsx("div", { className: "mt-6 text-center", children: _jsx(Link, { href: cta.href, className: CTA_CLASSES[cta.variant], children: cta.label }) }))] }) }));
43
43
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import Link from "next/link";
3
- import { Section } from "../../../ui";
3
+ import { Heading, Section, Text } from "../../../ui";
4
4
  export function CTABannerSection({ title = "Thousands of collectibles. One marketplace.", subtitle, primaryLabel = "Shop All Products →", primaryHref = "/products", secondaryLabel = "Browse Auctions →", secondaryHref = "/auctions", className = "", }) {
5
- return (_jsx(Section, { className: `bg-gradient-to-r from-primary-600 to-primary-700 py-16 px-4 ${className}`, children: _jsxs("div", { className: "mx-auto max-w-3xl text-center", "data-section": "ctabannersection-div-313", children: [_jsx("span", { className: "mb-4 inline-block text-2xl", "aria-hidden": "true", children: "\u2728" }), _jsx("h2", { className: "text-2xl font-bold text-white md:text-3xl lg:text-4xl", children: title }), subtitle && (_jsx("p", { className: "mt-3 text-base text-white/80", children: subtitle })), _jsxs("div", { className: "mt-8 flex flex-wrap items-center justify-center gap-4", "data-section": "ctabannersection-div-314", children: [_jsx(Link, { href: primaryHref, className: "inline-flex items-center rounded-full bg-white px-8 py-3 text-sm font-semibold text-primary-700 shadow-sm transition-all hover:bg-zinc-50 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: primaryLabel }), secondaryHref && (_jsx(Link, { href: secondaryHref, className: "inline-flex items-center rounded-full border-2 border-white/80 px-8 py-3 text-sm font-semibold text-white transition-all hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: secondaryLabel }))] })] }) }));
5
+ return (_jsx(Section, { className: `bg-gradient-to-r from-primary-600 to-primary-700 py-16 px-4 ${className}`, children: _jsxs("div", { className: "mx-auto max-w-3xl text-center", "data-section": "ctabannersection-div-313", children: [_jsx("span", { className: "mb-4 inline-block text-2xl", "aria-hidden": "true", children: "\u2728" }), _jsx(Heading, { level: 2, className: "text-2xl font-bold text-white md:text-3xl lg:text-4xl", children: title }), subtitle && (_jsx(Text, { className: "mt-3 text-base text-white/80", children: subtitle })), _jsxs("div", { className: "mt-8 flex flex-wrap items-center justify-center gap-4", "data-section": "ctabannersection-div-314", children: [_jsx(Link, { href: primaryHref, className: "inline-flex items-center rounded-full bg-white px-8 py-3 text-sm font-semibold text-primary-700 shadow-sm transition-all hover:bg-zinc-50 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: primaryLabel }), secondaryHref && (_jsx(Link, { href: secondaryHref, className: "inline-flex items-center rounded-full border-2 border-white/80 px-8 py-3 text-sm font-semibold text-white transition-all hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: secondaryLabel }))] })] }) }));
6
6
  }
@@ -1,11 +1,11 @@
1
- import type { CharacterHotspotConfig, HotspotPin } from "../types";
1
+ import type { CharacterHotspotConfig, HotspotPin as HotspotPinData } from "../types";
2
2
  export interface CharacterHotspotProps {
3
3
  config?: CharacterHotspotConfig | null;
4
4
  /**
5
5
  * Override the default fallback hotspot pins shown when no config is supplied.
6
6
  * Useful for non-collectibles storefronts.
7
7
  */
8
- defaultHotspots?: HotspotPin[];
8
+ defaultHotspots?: HotspotPinData[];
9
9
  /** Universe quick-browse links shown below the panorama. */
10
10
  universeLinks?: {
11
11
  label: string;
@@ -11,6 +11,7 @@ import { Button, Div, Heading, Row, Section, Span, Text } from "../../../ui";
11
11
  ----------------------------------------------------------------- */
12
12
  const FALLBACK_IMAGE = "/animevssuperhero.jpg";
13
13
  const FALLBACK_IMAGE_ALT = "DC, Marvel and Anime characters";
14
+ const FONT_BANGERS = "var(--font-bangers, Bangers, cursive)";
14
15
  const DEFAULT_HOTSPOTS = [
15
16
  {
16
17
  id: "spiderman",
@@ -176,6 +177,120 @@ const DEFAULT_UNIVERSE_LINKS = [
176
177
  },
177
178
  { label: "BLEACH", href: "/franchise/bleach", color: "#4A90D9", icon: "⚔" },
178
179
  ];
180
+ function HotspotHeaderOverlay({ heading, subheading, shopAllHref, }) {
181
+ return (_jsx(Div, { className: "absolute top-0 left-0 right-0 z-10 pointer-events-none", style: {
182
+ background: "linear-gradient(to bottom, rgba(10,10,18,0.88) 0%, rgba(10,10,18,0.40) 50%, transparent 100%)",
183
+ }, children: _jsxs(Row, { wrap: true, align: "start", justify: "between", gap: "sm", className: "pointer-events-auto mx-auto max-w-7xl px-4 pt-4 pb-6 gap-y-3", children: [_jsxs(Div, { children: [_jsx(Text, { className: "mb-1 text-xs font-black uppercase tracking-[0.2em]", style: { color: "var(--color-red)" }, children: "Explore the Universe" }), _jsx(Heading, { level: 2, style: {
184
+ fontFamily: FONT_BANGERS,
185
+ fontSize: "clamp(1.8rem, 4.5vw, 3rem)",
186
+ letterSpacing: "0.07em",
187
+ color: "#FFFFFF",
188
+ lineHeight: 1,
189
+ }, children: heading }), subheading ? (_jsx(Text, { className: "mt-2 text-sm font-medium max-w-md", style: { color: "var(--dark-section-muted)" }, children: subheading })) : (_jsxs(Text, { className: "mt-2 text-sm font-medium max-w-md", style: { color: "var(--dark-section-muted)" }, children: ["& beyond \u2014 tap the", " ", _jsx(Span, { className: "inline-flex items-center justify-center rounded-full font-light", style: {
190
+ background: "rgba(255,255,255,0.92)",
191
+ color: "#111111",
192
+ width: 18,
193
+ height: 18,
194
+ border: "1.5px solid rgba(0,0,0,0.18)",
195
+ boxShadow: "0 1px 4px rgba(0,0,0,0.4)",
196
+ verticalAlign: "middle",
197
+ fontSize: 13,
198
+ lineHeight: 1,
199
+ }, children: "+" }), " ", "pins to get & buy each character."] }))] }), _jsx(Link, { href: shopAllHref, className: "hidden sm:inline-flex items-center gap-2 px-5 py-2 text-sm font-black uppercase tracking-widest transition-transform hover:-translate-y-0.5", style: {
200
+ fontFamily: FONT_BANGERS,
201
+ letterSpacing: "0.1em",
202
+ background: "var(--color-red)",
203
+ color: "#FFFFFF",
204
+ border: "3px solid var(--border-ink)",
205
+ boxShadow: "4px 4px 0px var(--border-ink)",
206
+ }, children: "SHOP ALL \u2192" })] }) }));
207
+ }
208
+ function HotspotImageLayer({ panoramicImage, panoramicAlt, }) {
209
+ return (_jsxs(Div, { className: "absolute inset-0 overflow-hidden", children: [_jsx(Image, { src: panoramicImage, alt: panoramicAlt, fill: true, className: "object-cover object-top", sizes: "100vw", priority: false }), _jsx(Div, { className: "absolute inset-0", style: {
210
+ background: "linear-gradient(to right, rgba(10,10,18,0.72) 0%, rgba(10,10,18,0.30) 50%, rgba(10,10,18,0.72) 100%)",
211
+ } }), _jsx(Div, { className: "absolute inset-0", style: {
212
+ background: "linear-gradient(to bottom, rgba(10,10,18,0.25) 0%, transparent 40%, rgba(10,10,18,0.65) 100%)",
213
+ } }), _jsx(Div, { className: "absolute bottom-0 left-0 right-0 h-16 pointer-events-none", style: {
214
+ background: "linear-gradient(to bottom, transparent, #0A0A12)",
215
+ } })] }));
216
+ }
217
+ function HotspotPin({ hotspot, isActive, isMobile, toggle, onClose, }) {
218
+ const popupLeft = hotspot.xPct <= 55;
219
+ const popupAbove = hotspot.yPct > 65;
220
+ return (_jsxs(Div, { className: "absolute", style: {
221
+ left: `${hotspot.xPct}%`,
222
+ top: `${hotspot.yPct}%`,
223
+ zIndex: isActive ? 30 : 10,
224
+ transform: "translate(-50%, -50%)",
225
+ }, children: [!isActive && (_jsx(Span, { className: "absolute rounded-full animate-ping", style: {
226
+ inset: -6,
227
+ background: "rgba(255,255,255,0.2)",
228
+ pointerEvents: "none",
229
+ } })), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => toggle(hotspot.id), "aria-label": `Info about ${hotspot.name}`, "aria-expanded": isActive, className: "relative flex items-center justify-center rounded-full", style: {
230
+ width: isMobile ? 18 : 38,
231
+ height: isMobile ? 18 : 38,
232
+ background: isMobile ? "none" : isActive ? "rgba(30,30,30,0.92)" : "rgba(255,255,255,0.95)",
233
+ border: isMobile ? "none" : isActive ? "2px solid rgba(255,255,255,0.25)" : "2px solid rgba(0,0,0,0.18)",
234
+ boxShadow: isMobile ? "none" : "0 2px 12px rgba(0,0,0,0.55)",
235
+ backdropFilter: isMobile ? "none" : "blur(4px)",
236
+ padding: 0,
237
+ transition: "transform 0.2s ease, opacity 0.2s ease",
238
+ transform: isActive ? "scale(1.2) rotate(45deg)" : "scale(1)",
239
+ color: isMobile ? "#FFFFFF" : isActive ? "#FFFFFF" : "#111111",
240
+ fontSize: isMobile ? 18 : 22,
241
+ fontWeight: 200,
242
+ lineHeight: 1,
243
+ cursor: "pointer",
244
+ textShadow: isMobile ? "0 1px 6px rgba(0,0,0,0.8)" : "none",
245
+ opacity: isActive ? 0.7 : 1,
246
+ }, children: "+" }), isActive && !isMobile && (_jsxs(Div, { className: "absolute", style: {
247
+ ...(popupAbove ? { bottom: "calc(100% + 12px)", top: "auto", transform: "none" } : { top: "50%", transform: "translateY(-50%)" }),
248
+ ...(popupLeft ? { left: "calc(100% + 14px)" } : { right: "calc(100% + 14px)" }),
249
+ width: 300,
250
+ background: "rgba(255,255,255,0.97)",
251
+ boxShadow: "0 12px 48px rgba(0,0,0,0.55), 0 2px 8px rgba(0,0,0,0.3)",
252
+ borderRadius: 4,
253
+ overflow: "hidden",
254
+ zIndex: 40,
255
+ animation: "fadeInUp 0.2s ease both",
256
+ }, children: [_jsx(Div, { style: { height: 4, background: hotspot.accent } }), _jsxs(Div, { className: "px-5 py-4", children: [_jsx(Text, { className: "text-[10px] font-bold uppercase tracking-[0.18em] mb-1", style: { color: hotspot.accent === "#FFE500" ? "#b08800" : hotspot.accent }, children: hotspot.universe }), _jsx(Heading, { level: 3, className: "font-black leading-tight mb-3", style: { fontFamily: FONT_BANGERS, fontSize: "1.45rem", letterSpacing: "0.06em", color: "#111111" }, children: hotspot.name }), _jsx(Text, { className: "text-xs leading-relaxed mb-4", style: { color: "#374151" }, children: hotspot.description }), _jsxs(Link, { href: hotspot.href, onClick: onClose, className: "flex items-center justify-between px-4 py-2.5 text-sm font-black uppercase transition-opacity hover:opacity-85", style: {
257
+ fontFamily: FONT_BANGERS,
258
+ letterSpacing: "0.1em",
259
+ background: hotspot.accent,
260
+ color: hotspot.accent === "#FFE500" ? "#0D0D0D" : "#FFFFFF",
261
+ borderRadius: 2,
262
+ }, children: [hotspot.buyText, _jsx(Span, { "aria-hidden": "true", children: "\u2192" })] })] })] }))] }));
263
+ }
264
+ function MobileHotspotSheet({ active, onClose, }) {
265
+ return (_jsx(Div, { className: "fixed inset-0 z-50 flex items-end", style: { background: "rgba(0,0,0,0.6)", backdropFilter: "blur(3px)" }, onClick: (e) => { if (e.target === e.currentTarget)
266
+ onClose(); }, children: _jsxs(Div, { className: "w-full", style: {
267
+ background: "var(--surface-elevated)",
268
+ borderTopLeftRadius: 16,
269
+ borderTopRightRadius: 16,
270
+ overflow: "hidden",
271
+ animation: "fadeInUp 0.22s ease both",
272
+ }, children: [_jsx(Div, { className: "flex justify-center pt-3 pb-1", children: _jsx(Div, { style: { width: 40, height: 4, borderRadius: 2, background: "#D1D5DB" } }) }), _jsx(Div, { style: { height: 4, background: active.accent } }), _jsxs(Div, { className: "px-5 pt-4 pb-10", children: [_jsx(Text, { className: "text-[10px] font-bold uppercase tracking-[0.18em] mb-1", style: { color: active.accent === "#FFE500" ? "#b08800" : active.accent }, children: active.universe }), _jsx(Heading, { level: 3, className: "font-black leading-tight mb-2", style: { fontFamily: FONT_BANGERS, fontSize: "clamp(1.5rem, 6vw, 2rem)", letterSpacing: "0.06em", color: "#111111" }, children: active.name }), _jsx(Text, { className: "text-sm leading-relaxed mb-5", style: { color: "#374151" }, children: active.description }), _jsxs(Div, { className: "flex gap-3", children: [_jsxs(Link, { href: active.href, onClick: onClose, className: "flex-1 flex items-center justify-between px-4 py-3 font-black uppercase", style: {
273
+ fontFamily: FONT_BANGERS,
274
+ letterSpacing: "0.1em",
275
+ fontSize: "0.9rem",
276
+ background: active.accent,
277
+ color: active.accent === "#FFE500" ? "#0D0D0D" : "#FFFFFF",
278
+ borderRadius: 4,
279
+ }, children: [active.buyText, _jsx(Span, { "aria-hidden": "true", children: "\u2192" })] }), _jsx(Button, { type: "button", variant: "outline", onClick: onClose, className: "px-5 py-3 text-sm font-bold rounded", style: { background: "#F1F5F9", color: "#475569" }, children: "Close" })] })] })] }) }));
280
+ }
281
+ function UniverseBrowseRow({ universeLinks, }) {
282
+ return (_jsx(Div, { className: `mx-auto max-w-7xl px-4 py-6 ${THEME_CONSTANTS.grid.cols6Lg} gap-3`, style: { borderTop: "1px solid rgba(255,255,255,0.08)" }, children: universeLinks.map(({ label, href, color, icon }) => (_jsxs(Link, { href: href, className: "group flex items-center gap-2.5 px-3 py-2.5 rounded-sm transition-all hover:-translate-y-0.5", style: {
283
+ background: "rgba(255,255,255,0.04)",
284
+ border: "1px solid rgba(255,255,255,0.08)",
285
+ transition: "all 0.15s ease",
286
+ }, onMouseEnter: (e) => {
287
+ e.currentTarget.style.borderColor = color;
288
+ e.currentTarget.style.background = `${color}18`;
289
+ }, onMouseLeave: (e) => {
290
+ e.currentTarget.style.borderColor = "rgba(255,255,255,0.08)";
291
+ e.currentTarget.style.background = "rgba(255,255,255,0.04)";
292
+ }, children: [_jsx(Span, { className: "text-base select-none", "aria-hidden": "true", children: icon }), _jsx(Span, { className: "text-xs font-black uppercase tracking-wide", style: { fontFamily: FONT_BANGERS, letterSpacing: "0.1em", color: "#E2E8F0" }, children: label }), _jsx(Span, { className: "ml-auto text-xs", style: { color: "#475569", transition: "color 0.15s" }, children: "\u2192" })] }, label))) }));
293
+ }
179
294
  function CharacterHotspotInner({ panoramicImage, panoramicAlt, hotspots, universeLinks, shopAllHref, heading, subheading, }) {
180
295
  const [activeId, setActiveId] = useState(null);
181
296
  const containerRef = useRef(null);
@@ -185,8 +300,7 @@ function CharacterHotspotInner({ panoramicImage, panoramicAlt, hotspots, univers
185
300
  }, []);
186
301
  useEffect(() => {
187
302
  function handleClick(e) {
188
- if (containerRef.current &&
189
- !containerRef.current.contains(e.target)) {
303
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
190
304
  setActiveId(null);
191
305
  }
192
306
  }
@@ -207,38 +321,7 @@ function CharacterHotspotInner({ panoramicImage, panoramicAlt, hotspots, univers
207
321
  borderTop: "3px solid var(--dark-section-bg)",
208
322
  borderBottom: "3px solid var(--dark-section-bg)",
209
323
  overflow: "hidden",
210
- }, children: [_jsxs(Div, { ref: containerRef, className: "relative w-full", style: { aspectRatio: "16/9", minHeight: "420px" }, children: [_jsx(Div, { className: "absolute top-0 left-0 right-0 z-10 pointer-events-none", style: {
211
- background: "linear-gradient(to bottom, rgba(10,10,18,0.88) 0%, rgba(10,10,18,0.40) 50%, transparent 100%)",
212
- }, children: _jsxs(Row, { wrap: true, align: "start", justify: "between", gap: "sm", className: "pointer-events-auto mx-auto max-w-7xl px-4 pt-4 pb-6 gap-y-3", children: [_jsxs(Div, { children: [_jsx(Text, { className: "mb-1 text-xs font-black uppercase tracking-[0.2em]", style: { color: "var(--color-red)" }, children: "Explore the Universe" }), _jsx(Heading, { level: 2, style: {
213
- fontFamily: "var(--font-bangers, Bangers, cursive)",
214
- fontSize: "clamp(1.8rem, 4.5vw, 3rem)",
215
- letterSpacing: "0.07em",
216
- color: "#FFFFFF",
217
- lineHeight: 1,
218
- }, children: heading }), subheading && (_jsx(Text, { className: "mt-2 text-sm font-medium max-w-md", style: { color: "var(--dark-section-muted)" }, children: subheading })), !subheading && (_jsxs(Text, { className: "mt-2 text-sm font-medium max-w-md", style: { color: "var(--dark-section-muted)" }, children: ["& beyond \u2014 tap the", " ", _jsx(Span, { className: "inline-flex items-center justify-center rounded-full font-light", style: {
219
- background: "rgba(255,255,255,0.92)",
220
- color: "#111111",
221
- width: 18,
222
- height: 18,
223
- border: "1.5px solid rgba(0,0,0,0.18)",
224
- boxShadow: "0 1px 4px rgba(0,0,0,0.4)",
225
- verticalAlign: "middle",
226
- fontSize: 13,
227
- lineHeight: 1,
228
- }, children: "+" }), " ", "pins to get & buy each character."] }))] }), _jsx(Link, { href: shopAllHref, className: "hidden sm:inline-flex items-center gap-2 px-5 py-2 text-sm font-black uppercase tracking-widest transition-transform hover:-translate-y-0.5", style: {
229
- fontFamily: "var(--font-bangers, Bangers, cursive)",
230
- letterSpacing: "0.1em",
231
- background: "var(--color-red)",
232
- color: "#FFFFFF",
233
- border: "3px solid var(--border-ink)",
234
- boxShadow: "4px 4px 0px var(--border-ink)",
235
- }, children: "SHOP ALL \u2192" })] }) }), _jsxs(Div, { className: "absolute inset-0 overflow-hidden", children: [_jsx(Image, { src: panoramicImage, alt: panoramicAlt, fill: true, className: "object-cover object-top", sizes: "100vw", priority: false }), _jsx(Div, { className: "absolute inset-0", style: {
236
- background: "linear-gradient(to right, rgba(10,10,18,0.72) 0%, rgba(10,10,18,0.30) 50%, rgba(10,10,18,0.72) 100%)",
237
- } }), _jsx(Div, { className: "absolute inset-0", style: {
238
- background: "linear-gradient(to bottom, rgba(10,10,18,0.25) 0%, transparent 40%, rgba(10,10,18,0.65) 100%)",
239
- } }), _jsx(Div, { className: "absolute bottom-0 left-0 right-0 h-16 pointer-events-none", style: {
240
- background: "linear-gradient(to bottom, transparent, #0A0A12)",
241
- } })] }), _jsx(Div, { className: "hidden sm:flex absolute left-0 right-0 justify-around items-start pointer-events-none", style: { top: "clamp(120px, 18vh, 165px)", zIndex: 5 }, children: [
324
+ }, children: [_jsxs(Div, { ref: containerRef, className: "relative w-full", style: { aspectRatio: "16/9", minHeight: "420px" }, children: [_jsx(HotspotHeaderOverlay, { heading: heading, subheading: subheading, shopAllHref: shopAllHref }), _jsx(HotspotImageLayer, { panoramicImage: panoramicImage, panoramicAlt: panoramicAlt }), _jsx(Div, { className: "hidden sm:flex absolute left-0 right-0 justify-around items-start pointer-events-none", style: { top: "clamp(120px, 18vh, 165px)", zIndex: 5 }, children: [
242
325
  { label: "MARVEL", color: "#E8001C" },
243
326
  { label: "DC COMICS", color: "#4A90D9" },
244
327
  { label: "ANIME", color: "#FFE500" },
@@ -246,128 +329,7 @@ function CharacterHotspotInner({ panoramicImage, panoramicAlt, hotspots, univers
246
329
  background: color,
247
330
  color: color === "#FFE500" ? "#0D0D0D" : "#FFFFFF",
248
331
  boxShadow: "2px 2px 0px rgba(0,0,0,0.6)",
249
- fontFamily: "var(--font-bangers, Bangers, cursive)",
332
+ fontFamily: FONT_BANGERS,
250
333
  letterSpacing: "0.16em",
251
- }, children: label }), _jsx(Div, { className: "mt-1 h-5 sm:h-8 w-px", style: { background: color, opacity: 0.5 } })] }, label))) }), hotspots.map((hotspot) => {
252
- const isActive = activeId === hotspot.id;
253
- const popupLeft = hotspot.xPct <= 55;
254
- const popupAbove = hotspot.yPct > 65;
255
- return (_jsxs(Div, { className: "absolute", style: {
256
- left: `${hotspot.xPct}%`,
257
- top: `${hotspot.yPct}%`,
258
- zIndex: isActive ? 30 : 10,
259
- transform: "translate(-50%, -50%)",
260
- }, children: [!isActive && (_jsx(Span, { className: "absolute rounded-full animate-ping", style: {
261
- inset: -6,
262
- background: "rgba(255,255,255,0.2)",
263
- pointerEvents: "none",
264
- } })), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => toggle(hotspot.id), "aria-label": `Info about ${hotspot.name}`, "aria-expanded": isActive, className: "relative flex items-center justify-center rounded-full", style: {
265
- width: isMobile ? 18 : 38,
266
- height: isMobile ? 18 : 38,
267
- background: isMobile
268
- ? "none"
269
- : isActive
270
- ? "rgba(30,30,30,0.92)"
271
- : "rgba(255,255,255,0.95)",
272
- border: isMobile
273
- ? "none"
274
- : isActive
275
- ? "2px solid rgba(255,255,255,0.25)"
276
- : "2px solid rgba(0,0,0,0.18)",
277
- boxShadow: isMobile ? "none" : "0 2px 12px rgba(0,0,0,0.55)",
278
- backdropFilter: isMobile ? "none" : "blur(4px)",
279
- padding: 0,
280
- transition: "transform 0.2s ease, opacity 0.2s ease",
281
- transform: isActive ? "scale(1.2) rotate(45deg)" : "scale(1)",
282
- color: isMobile
283
- ? "#FFFFFF"
284
- : isActive
285
- ? "#FFFFFF"
286
- : "#111111",
287
- fontSize: isMobile ? 18 : 22,
288
- fontWeight: 200,
289
- lineHeight: 1,
290
- cursor: "pointer",
291
- textShadow: isMobile ? "0 1px 6px rgba(0,0,0,0.8)" : "none",
292
- opacity: isActive ? 0.7 : 1,
293
- }, children: "+" }), isActive && !isMobile && (_jsxs(Div, { className: "absolute", style: {
294
- ...(popupAbove
295
- ? {
296
- bottom: "calc(100% + 12px)",
297
- top: "auto",
298
- transform: "none",
299
- }
300
- : { top: "50%", transform: "translateY(-50%)" }),
301
- ...(popupLeft
302
- ? { left: "calc(100% + 14px)" }
303
- : { right: "calc(100% + 14px)" }),
304
- width: 300,
305
- background: "rgba(255,255,255,0.97)",
306
- boxShadow: "0 12px 48px rgba(0,0,0,0.55), 0 2px 8px rgba(0,0,0,0.3)",
307
- borderRadius: 4,
308
- overflow: "hidden",
309
- zIndex: 40,
310
- animation: "fadeInUp 0.2s ease both",
311
- }, children: [_jsx(Div, { style: { height: 4, background: hotspot.accent } }), _jsxs(Div, { className: "px-5 py-4", children: [_jsx(Text, { className: "text-[10px] font-bold uppercase tracking-[0.18em] mb-1", style: {
312
- color: hotspot.accent === "#FFE500"
313
- ? "#b08800"
314
- : hotspot.accent,
315
- }, children: hotspot.universe }), _jsx(Heading, { level: 3, className: "font-black leading-tight mb-3", style: {
316
- fontFamily: "var(--font-bangers, Bangers, cursive)",
317
- fontSize: "1.45rem",
318
- letterSpacing: "0.06em",
319
- color: "#111111",
320
- }, children: hotspot.name }), _jsx(Text, { className: "text-xs leading-relaxed mb-4", style: { color: "#374151" }, children: hotspot.description }), _jsxs(Link, { href: hotspot.href, onClick: () => setActiveId(null), className: "flex items-center justify-between px-4 py-2.5 text-sm font-black uppercase transition-opacity hover:opacity-85", style: {
321
- fontFamily: "var(--font-bangers, Bangers, cursive)",
322
- letterSpacing: "0.1em",
323
- background: hotspot.accent,
324
- color: hotspot.accent === "#FFE500" ? "#0D0D0D" : "#FFFFFF",
325
- borderRadius: 2,
326
- }, children: [hotspot.buyText, _jsx(Span, { "aria-hidden": "true", children: "\u2192" })] })] })] }))] }, hotspot.id));
327
- })] }), isMobile && active && (_jsx(Div, { className: "fixed inset-0 z-50 flex items-end", style: { background: "rgba(0,0,0,0.6)", backdropFilter: "blur(3px)" }, onClick: (e) => {
328
- if (e.target === e.currentTarget)
329
- setActiveId(null);
330
- }, children: _jsxs(Div, { className: "w-full", style: {
331
- background: "var(--surface-elevated)",
332
- borderTopLeftRadius: 16,
333
- borderTopRightRadius: 16,
334
- overflow: "hidden",
335
- animation: "fadeInUp 0.22s ease both",
336
- }, children: [_jsx(Div, { className: "flex justify-center pt-3 pb-1", children: _jsx(Div, { style: {
337
- width: 40,
338
- height: 4,
339
- borderRadius: 2,
340
- background: "#D1D5DB",
341
- } }) }), _jsx(Div, { style: { height: 4, background: active.accent } }), _jsxs(Div, { className: "px-5 pt-4 pb-10", children: [_jsx(Text, { className: "text-[10px] font-bold uppercase tracking-[0.18em] mb-1", style: {
342
- color: active.accent === "#FFE500" ? "#b08800" : active.accent,
343
- }, children: active.universe }), _jsx(Heading, { level: 3, className: "font-black leading-tight mb-2", style: {
344
- fontFamily: "var(--font-bangers, Bangers, cursive)",
345
- fontSize: "clamp(1.5rem, 6vw, 2rem)",
346
- letterSpacing: "0.06em",
347
- color: "#111111",
348
- }, children: active.name }), _jsx(Text, { className: "text-sm leading-relaxed mb-5", style: { color: "#374151" }, children: active.description }), _jsxs(Div, { className: "flex gap-3", children: [_jsxs(Link, { href: active.href, onClick: () => setActiveId(null), className: "flex-1 flex items-center justify-between px-4 py-3 font-black uppercase", style: {
349
- fontFamily: "var(--font-bangers, Bangers, cursive)",
350
- letterSpacing: "0.1em",
351
- fontSize: "0.9rem",
352
- background: active.accent,
353
- color: active.accent === "#FFE500" ? "#0D0D0D" : "#FFFFFF",
354
- borderRadius: 4,
355
- }, children: [active.buyText, _jsx(Span, { "aria-hidden": "true", children: "\u2192" })] }), _jsx(Button, { type: "button", variant: "outline", onClick: () => setActiveId(null), className: "px-5 py-3 text-sm font-bold rounded", style: { background: "#F1F5F9", color: "#475569" }, children: "Close" })] })] })] }) })), _jsx(Div, { className: `mx-auto max-w-7xl px-4 py-6 ${THEME_CONSTANTS.grid.cols6Lg} gap-3`, style: { borderTop: "1px solid rgba(255,255,255,0.08)" }, children: universeLinks.map(({ label, href, color, icon }) => (_jsxs(Link, { href: href, className: "group flex items-center gap-2.5 px-3 py-2.5 rounded-sm transition-all hover:-translate-y-0.5", style: {
356
- background: "rgba(255,255,255,0.04)",
357
- border: "1px solid rgba(255,255,255,0.08)",
358
- transition: "all 0.15s ease",
359
- }, onMouseEnter: (e) => {
360
- e.currentTarget.style.borderColor = color;
361
- e.currentTarget.style.background =
362
- `${color}18`;
363
- }, onMouseLeave: (e) => {
364
- e.currentTarget.style.borderColor =
365
- "rgba(255,255,255,0.08)";
366
- e.currentTarget.style.background =
367
- "rgba(255,255,255,0.04)";
368
- }, children: [_jsx(Span, { className: "text-base select-none", "aria-hidden": "true", children: icon }), _jsx(Span, { className: "text-xs font-black uppercase tracking-wide", style: {
369
- fontFamily: "var(--font-bangers, Bangers, cursive)",
370
- letterSpacing: "0.1em",
371
- color: "#E2E8F0",
372
- }, children: label }), _jsx(Span, { className: "ml-auto text-xs", style: { color: "#475569", transition: "color 0.15s" }, children: "\u2192" })] }, label))) })] }));
334
+ }, children: label }), _jsx(Div, { className: "mt-1 h-5 sm:h-8 w-px", style: { background: color, opacity: 0.5 } })] }, label))) }), hotspots.map((hotspot) => (_jsx(HotspotPin, { hotspot: hotspot, isActive: activeId === hotspot.id, isMobile: isMobile, toggle: toggle, onClose: () => setActiveId(null) }, hotspot.id)))] }), isMobile && active && (_jsx(MobileHotspotSheet, { active: active, onClose: () => setActiveId(null) })), _jsx(UniverseBrowseRow, { universeLinks: universeLinks })] }));
373
335
  }