@endora-commerce/admin-kit 0.0.0-stage → 0.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (449) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +212 -2
  3. package/dist/components/FileDropzone.d.ts +13 -0
  4. package/dist/components/FileDropzone.d.ts.map +1 -0
  5. package/dist/components/FileDropzone.js +39 -0
  6. package/dist/components/FileDropzone.js.map +1 -0
  7. package/dist/components/PaginationFooter.d.ts +25 -0
  8. package/dist/components/PaginationFooter.d.ts.map +1 -0
  9. package/dist/components/PaginationFooter.js +33 -0
  10. package/dist/components/PaginationFooter.js.map +1 -0
  11. package/dist/components/ResponsiveTable.d.ts +26 -0
  12. package/dist/components/ResponsiveTable.d.ts.map +1 -0
  13. package/dist/components/ResponsiveTable.js +34 -0
  14. package/dist/components/ResponsiveTable.js.map +1 -0
  15. package/dist/components/RowActionMenu.d.ts +40 -0
  16. package/dist/components/RowActionMenu.d.ts.map +1 -0
  17. package/dist/components/RowActionMenu.js +15 -0
  18. package/dist/components/RowActionMenu.js.map +1 -0
  19. package/dist/components/StickyFormActions.d.ts +10 -0
  20. package/dist/components/StickyFormActions.d.ts.map +1 -0
  21. package/dist/components/StickyFormActions.js +10 -0
  22. package/dist/components/StickyFormActions.js.map +1 -0
  23. package/dist/components/TouchReorderButtons.d.ts +13 -0
  24. package/dist/components/TouchReorderButtons.d.ts.map +1 -0
  25. package/dist/components/TouchReorderButtons.js +12 -0
  26. package/dist/components/TouchReorderButtons.js.map +1 -0
  27. package/dist/components/admin-user-picker/AdminUserPicker.d.ts +14 -0
  28. package/dist/components/admin-user-picker/AdminUserPicker.d.ts.map +1 -0
  29. package/dist/components/admin-user-picker/AdminUserPicker.js +68 -0
  30. package/dist/components/admin-user-picker/AdminUserPicker.js.map +1 -0
  31. package/dist/components/asset-picker/AssetFieldPicker.d.ts +32 -0
  32. package/dist/components/asset-picker/AssetFieldPicker.d.ts.map +1 -0
  33. package/dist/components/asset-picker/AssetFieldPicker.js +42 -0
  34. package/dist/components/asset-picker/AssetFieldPicker.js.map +1 -0
  35. package/dist/components/asset-picker/AssetPicker.d.ts +31 -0
  36. package/dist/components/asset-picker/AssetPicker.d.ts.map +1 -0
  37. package/dist/components/asset-picker/AssetPicker.js +68 -0
  38. package/dist/components/asset-picker/AssetPicker.js.map +1 -0
  39. package/dist/components/asset-picker/AssetUploader.d.ts +15 -0
  40. package/dist/components/asset-picker/AssetUploader.d.ts.map +1 -0
  41. package/dist/components/asset-picker/AssetUploader.js +61 -0
  42. package/dist/components/asset-picker/AssetUploader.js.map +1 -0
  43. package/dist/components/asset-picker/assets-api.d.ts +49 -0
  44. package/dist/components/asset-picker/assets-api.d.ts.map +1 -0
  45. package/dist/components/asset-picker/assets-api.js +67 -0
  46. package/dist/components/asset-picker/assets-api.js.map +1 -0
  47. package/dist/components/category-picker/CategorySelect.d.ts +14 -0
  48. package/dist/components/category-picker/CategorySelect.d.ts.map +1 -0
  49. package/dist/components/category-picker/CategorySelect.js +41 -0
  50. package/dist/components/category-picker/CategorySelect.js.map +1 -0
  51. package/dist/components/category-tree-picker/CategoryTreeNodeRow.d.ts +18 -0
  52. package/dist/components/category-tree-picker/CategoryTreeNodeRow.d.ts.map +1 -0
  53. package/dist/components/category-tree-picker/CategoryTreeNodeRow.js +19 -0
  54. package/dist/components/category-tree-picker/CategoryTreeNodeRow.js.map +1 -0
  55. package/dist/components/category-tree-picker/CategoryTreePicker.d.ts +23 -0
  56. package/dist/components/category-tree-picker/CategoryTreePicker.d.ts.map +1 -0
  57. package/dist/components/category-tree-picker/CategoryTreePicker.js +82 -0
  58. package/dist/components/category-tree-picker/CategoryTreePicker.js.map +1 -0
  59. package/dist/components/category-tree-picker/category-tree-utils.d.ts +35 -0
  60. package/dist/components/category-tree-picker/category-tree-utils.d.ts.map +1 -0
  61. package/dist/components/category-tree-picker/category-tree-utils.js +140 -0
  62. package/dist/components/category-tree-picker/category-tree-utils.js.map +1 -0
  63. package/dist/components/category-tree-picker/index.d.ts +4 -0
  64. package/dist/components/category-tree-picker/index.d.ts.map +1 -0
  65. package/dist/components/category-tree-picker/index.js +2 -0
  66. package/dist/components/category-tree-picker/index.js.map +1 -0
  67. package/dist/components/charts/echart.d.ts +17 -0
  68. package/dist/components/charts/echart.d.ts.map +1 -0
  69. package/dist/components/charts/echart.js +61 -0
  70. package/dist/components/charts/echart.js.map +1 -0
  71. package/dist/components/cms-picker/CmsBlockPicker.d.ts +14 -0
  72. package/dist/components/cms-picker/CmsBlockPicker.d.ts.map +1 -0
  73. package/dist/components/cms-picker/CmsBlockPicker.js +40 -0
  74. package/dist/components/cms-picker/CmsBlockPicker.js.map +1 -0
  75. package/dist/components/cms-picker/CmsPagePicker.d.ts +15 -0
  76. package/dist/components/cms-picker/CmsPagePicker.d.ts.map +1 -0
  77. package/dist/components/cms-picker/CmsPagePicker.js +80 -0
  78. package/dist/components/cms-picker/CmsPagePicker.js.map +1 -0
  79. package/dist/components/content-language-tabs/ContentLanguageTabs.d.ts +30 -0
  80. package/dist/components/content-language-tabs/ContentLanguageTabs.d.ts.map +1 -0
  81. package/dist/components/content-language-tabs/ContentLanguageTabs.js +14 -0
  82. package/dist/components/content-language-tabs/ContentLanguageTabs.js.map +1 -0
  83. package/dist/components/country-select/CountrySelect.d.ts +29 -0
  84. package/dist/components/country-select/CountrySelect.d.ts.map +1 -0
  85. package/dist/components/country-select/CountrySelect.js +40 -0
  86. package/dist/components/country-select/CountrySelect.js.map +1 -0
  87. package/dist/components/country-select/index.d.ts +3 -0
  88. package/dist/components/country-select/index.d.ts.map +1 -0
  89. package/dist/components/country-select/index.js +3 -0
  90. package/dist/components/country-select/index.js.map +1 -0
  91. package/dist/components/country-select/useCountriesQuery.d.ts +12 -0
  92. package/dist/components/country-select/useCountriesQuery.d.ts.map +1 -0
  93. package/dist/components/country-select/useCountriesQuery.js +69 -0
  94. package/dist/components/country-select/useCountriesQuery.js.map +1 -0
  95. package/dist/components/custom-field-values/CustomFieldValuesPanel.d.ts +48 -0
  96. package/dist/components/custom-field-values/CustomFieldValuesPanel.d.ts.map +1 -0
  97. package/dist/components/custom-field-values/CustomFieldValuesPanel.js +122 -0
  98. package/dist/components/custom-field-values/CustomFieldValuesPanel.js.map +1 -0
  99. package/dist/components/customer-group-picker/CustomerGroupPicker.d.ts +14 -0
  100. package/dist/components/customer-group-picker/CustomerGroupPicker.d.ts.map +1 -0
  101. package/dist/components/customer-group-picker/CustomerGroupPicker.js +36 -0
  102. package/dist/components/customer-group-picker/CustomerGroupPicker.js.map +1 -0
  103. package/dist/components/customer-picker/CustomerPicker.d.ts +18 -0
  104. package/dist/components/customer-picker/CustomerPicker.d.ts.map +1 -0
  105. package/dist/components/customer-picker/CustomerPicker.js +85 -0
  106. package/dist/components/customer-picker/CustomerPicker.js.map +1 -0
  107. package/dist/components/dictionary-picker/CountryPicker.d.ts +26 -0
  108. package/dist/components/dictionary-picker/CountryPicker.d.ts.map +1 -0
  109. package/dist/components/dictionary-picker/CountryPicker.js +29 -0
  110. package/dist/components/dictionary-picker/CountryPicker.js.map +1 -0
  111. package/dist/components/dictionary-picker/CurrencyPicker.d.ts +17 -0
  112. package/dist/components/dictionary-picker/CurrencyPicker.d.ts.map +1 -0
  113. package/dist/components/dictionary-picker/CurrencyPicker.js +29 -0
  114. package/dist/components/dictionary-picker/CurrencyPicker.js.map +1 -0
  115. package/dist/components/dictionary-picker/dictionary-api.d.ts +21 -0
  116. package/dist/components/dictionary-picker/dictionary-api.d.ts.map +1 -0
  117. package/dist/components/dictionary-picker/dictionary-api.js +26 -0
  118. package/dist/components/dictionary-picker/dictionary-api.js.map +1 -0
  119. package/dist/components/dictionary-picker/index.d.ts +4 -0
  120. package/dist/components/dictionary-picker/index.d.ts.map +1 -0
  121. package/dist/components/dictionary-picker/index.js +4 -0
  122. package/dist/components/dictionary-picker/index.js.map +1 -0
  123. package/dist/components/fulfilment-strategy-picker/FulfilmentStrategyPicker.d.ts +49 -0
  124. package/dist/components/fulfilment-strategy-picker/FulfilmentStrategyPicker.d.ts.map +1 -0
  125. package/dist/components/fulfilment-strategy-picker/FulfilmentStrategyPicker.js +43 -0
  126. package/dist/components/fulfilment-strategy-picker/FulfilmentStrategyPicker.js.map +1 -0
  127. package/dist/components/hooks/useFocusTrap.d.ts +6 -0
  128. package/dist/components/hooks/useFocusTrap.d.ts.map +1 -0
  129. package/dist/components/hooks/useFocusTrap.js +41 -0
  130. package/dist/components/hooks/useFocusTrap.js.map +1 -0
  131. package/dist/components/hooks/useViewportTier.d.ts +7 -0
  132. package/dist/components/hooks/useViewportTier.d.ts.map +1 -0
  133. package/dist/components/hooks/useViewportTier.js +23 -0
  134. package/dist/components/hooks/useViewportTier.js.map +1 -0
  135. package/dist/components/index.d.ts +101 -0
  136. package/dist/components/index.d.ts.map +1 -0
  137. package/dist/components/index.js +63 -0
  138. package/dist/components/index.js.map +1 -0
  139. package/dist/components/organization-picker/OrganizationPicker.d.ts +28 -0
  140. package/dist/components/organization-picker/OrganizationPicker.d.ts.map +1 -0
  141. package/dist/components/organization-picker/OrganizationPicker.js +35 -0
  142. package/dist/components/organization-picker/OrganizationPicker.js.map +1 -0
  143. package/dist/components/organization-picker/OrganizationPickerMulti.d.ts +32 -0
  144. package/dist/components/organization-picker/OrganizationPickerMulti.d.ts.map +1 -0
  145. package/dist/components/organization-picker/OrganizationPickerMulti.js +55 -0
  146. package/dist/components/organization-picker/OrganizationPickerMulti.js.map +1 -0
  147. package/dist/components/organization-picker/OrganizationStatusBadge.d.ts +7 -0
  148. package/dist/components/organization-picker/OrganizationStatusBadge.d.ts.map +1 -0
  149. package/dist/components/organization-picker/OrganizationStatusBadge.js +33 -0
  150. package/dist/components/organization-picker/OrganizationStatusBadge.js.map +1 -0
  151. package/dist/components/organization-picker/useOrganizationsQuery.d.ts +33 -0
  152. package/dist/components/organization-picker/useOrganizationsQuery.d.ts.map +1 -0
  153. package/dist/components/organization-picker/useOrganizationsQuery.js +92 -0
  154. package/dist/components/organization-picker/useOrganizationsQuery.js.map +1 -0
  155. package/dist/components/payment-method-availability/MethodAvailabilityCell.d.ts +38 -0
  156. package/dist/components/payment-method-availability/MethodAvailabilityCell.d.ts.map +1 -0
  157. package/dist/components/payment-method-availability/MethodAvailabilityCell.js +50 -0
  158. package/dist/components/payment-method-availability/MethodAvailabilityCell.js.map +1 -0
  159. package/dist/components/product-picker/ProductPicker.d.ts +22 -0
  160. package/dist/components/product-picker/ProductPicker.d.ts.map +1 -0
  161. package/dist/components/product-picker/ProductPicker.js +143 -0
  162. package/dist/components/product-picker/ProductPicker.js.map +1 -0
  163. package/dist/components/reorder/ReorderAnnouncer.d.ts +29 -0
  164. package/dist/components/reorder/ReorderAnnouncer.d.ts.map +1 -0
  165. package/dist/components/reorder/ReorderAnnouncer.js +6 -0
  166. package/dist/components/reorder/ReorderAnnouncer.js.map +1 -0
  167. package/dist/components/reorder/useReorderList.d.ts +121 -0
  168. package/dist/components/reorder/useReorderList.d.ts.map +1 -0
  169. package/dist/components/reorder/useReorderList.js +241 -0
  170. package/dist/components/reorder/useReorderList.js.map +1 -0
  171. package/dist/components/rule-builder/RuleBuilder.d.ts +105 -0
  172. package/dist/components/rule-builder/RuleBuilder.d.ts.map +1 -0
  173. package/dist/components/rule-builder/RuleBuilder.js +138 -0
  174. package/dist/components/rule-builder/RuleBuilder.js.map +1 -0
  175. package/dist/components/sales-channel-picker/SalesChannelPicker.d.ts +15 -0
  176. package/dist/components/sales-channel-picker/SalesChannelPicker.d.ts.map +1 -0
  177. package/dist/components/sales-channel-picker/SalesChannelPicker.js +79 -0
  178. package/dist/components/sales-channel-picker/SalesChannelPicker.js.map +1 -0
  179. package/dist/components/scope-notice/ScopeNotice.d.ts +33 -0
  180. package/dist/components/scope-notice/ScopeNotice.d.ts.map +1 -0
  181. package/dist/components/scope-notice/ScopeNotice.js +11 -0
  182. package/dist/components/scope-notice/ScopeNotice.js.map +1 -0
  183. package/dist/components/scope-picker/ScopePicker.d.ts +28 -0
  184. package/dist/components/scope-picker/ScopePicker.d.ts.map +1 -0
  185. package/dist/components/scope-picker/ScopePicker.js +114 -0
  186. package/dist/components/scope-picker/ScopePicker.js.map +1 -0
  187. package/dist/components/scope-picker/sales-channels-api.d.ts +19 -0
  188. package/dist/components/scope-picker/sales-channels-api.d.ts.map +1 -0
  189. package/dist/components/scope-picker/sales-channels-api.js +30 -0
  190. package/dist/components/scope-picker/sales-channels-api.js.map +1 -0
  191. package/dist/components/status-transition-graph/StatusTransitionGraph.d.ts +26 -0
  192. package/dist/components/status-transition-graph/StatusTransitionGraph.d.ts.map +1 -0
  193. package/dist/components/status-transition-graph/StatusTransitionGraph.js +241 -0
  194. package/dist/components/status-transition-graph/StatusTransitionGraph.js.map +1 -0
  195. package/dist/components/status-transition-graph/index.d.ts +3 -0
  196. package/dist/components/status-transition-graph/index.d.ts.map +1 -0
  197. package/dist/components/status-transition-graph/index.js +2 -0
  198. package/dist/components/status-transition-graph/index.js.map +1 -0
  199. package/dist/contributions/index.d.ts +44 -0
  200. package/dist/contributions/index.d.ts.map +1 -0
  201. package/dist/contributions/index.js +42 -0
  202. package/dist/contributions/index.js.map +1 -0
  203. package/dist/contributions/zone-component.d.ts +70 -0
  204. package/dist/contributions/zone-component.d.ts.map +1 -0
  205. package/dist/contributions/zone-component.js +26 -0
  206. package/dist/contributions/zone-component.js.map +1 -0
  207. package/dist/field-protection/FieldProtectionPricePanel.d.ts +26 -0
  208. package/dist/field-protection/FieldProtectionPricePanel.d.ts.map +1 -0
  209. package/dist/field-protection/FieldProtectionPricePanel.js +14 -0
  210. package/dist/field-protection/FieldProtectionPricePanel.js.map +1 -0
  211. package/dist/field-protection/FieldProtectionSummary.d.ts +18 -0
  212. package/dist/field-protection/FieldProtectionSummary.d.ts.map +1 -0
  213. package/dist/field-protection/FieldProtectionSummary.js +18 -0
  214. package/dist/field-protection/FieldProtectionSummary.js.map +1 -0
  215. package/dist/field-protection/FieldProtectionToggle.d.ts +36 -0
  216. package/dist/field-protection/FieldProtectionToggle.d.ts.map +1 -0
  217. package/dist/field-protection/FieldProtectionToggle.js +30 -0
  218. package/dist/field-protection/FieldProtectionToggle.js.map +1 -0
  219. package/dist/field-protection/describe-path.d.ts +27 -0
  220. package/dist/field-protection/describe-path.d.ts.map +1 -0
  221. package/dist/field-protection/describe-path.js +28 -0
  222. package/dist/field-protection/describe-path.js.map +1 -0
  223. package/dist/field-protection/index.d.ts +46 -0
  224. package/dist/field-protection/index.d.ts.map +1 -0
  225. package/dist/field-protection/index.js +41 -0
  226. package/dist/field-protection/index.js.map +1 -0
  227. package/dist/field-protection/types.d.ts +93 -0
  228. package/dist/field-protection/types.d.ts.map +1 -0
  229. package/dist/field-protection/types.js +2 -0
  230. package/dist/field-protection/types.js.map +1 -0
  231. package/dist/field-protection/use-field-protection.d.ts +27 -0
  232. package/dist/field-protection/use-field-protection.d.ts.map +1 -0
  233. package/dist/field-protection/use-field-protection.js +149 -0
  234. package/dist/field-protection/use-field-protection.js.map +1 -0
  235. package/dist/i18n/TranslationProvider.d.ts +27 -0
  236. package/dist/i18n/TranslationProvider.d.ts.map +1 -0
  237. package/dist/i18n/TranslationProvider.js +130 -0
  238. package/dist/i18n/TranslationProvider.js.map +1 -0
  239. package/dist/i18n/app-language-context.d.ts +8 -0
  240. package/dist/i18n/app-language-context.d.ts.map +1 -0
  241. package/dist/i18n/app-language-context.js +13 -0
  242. package/dist/i18n/app-language-context.js.map +1 -0
  243. package/dist/i18n/index.d.ts +29 -0
  244. package/dist/i18n/index.d.ts.map +1 -0
  245. package/dist/i18n/index.js +25 -0
  246. package/dist/i18n/index.js.map +1 -0
  247. package/dist/i18n/interpolate.d.ts +2 -0
  248. package/dist/i18n/interpolate.d.ts.map +1 -0
  249. package/dist/i18n/interpolate.js +10 -0
  250. package/dist/i18n/interpolate.js.map +1 -0
  251. package/dist/i18n/language-storage.d.ts +16 -0
  252. package/dist/i18n/language-storage.d.ts.map +1 -0
  253. package/dist/i18n/language-storage.js +26 -0
  254. package/dist/i18n/language-storage.js.map +1 -0
  255. package/dist/i18n/resolver.d.ts +19 -0
  256. package/dist/i18n/resolver.d.ts.map +1 -0
  257. package/dist/i18n/resolver.js +23 -0
  258. package/dist/i18n/resolver.js.map +1 -0
  259. package/dist/i18n/types.d.ts +12 -0
  260. package/dist/i18n/types.d.ts.map +1 -0
  261. package/dist/i18n/types.js +7 -0
  262. package/dist/i18n/types.js.map +1 -0
  263. package/dist/i18n/useTranslation.d.ts +2 -0
  264. package/dist/i18n/useTranslation.d.ts.map +1 -0
  265. package/dist/i18n/useTranslation.js +16 -0
  266. package/dist/i18n/useTranslation.js.map +1 -0
  267. package/dist/lib/admin-actions/icon-map.d.ts +3 -0
  268. package/dist/lib/admin-actions/icon-map.d.ts.map +1 -0
  269. package/dist/lib/admin-actions/icon-map.js +115 -0
  270. package/dist/lib/admin-actions/icon-map.js.map +1 -0
  271. package/dist/lib/api-client.d.ts +55 -0
  272. package/dist/lib/api-client.d.ts.map +1 -0
  273. package/dist/lib/api-client.js +89 -0
  274. package/dist/lib/api-client.js.map +1 -0
  275. package/dist/lib/asset-url.d.ts +32 -0
  276. package/dist/lib/asset-url.d.ts.map +1 -0
  277. package/dist/lib/asset-url.js +42 -0
  278. package/dist/lib/asset-url.js.map +1 -0
  279. package/dist/lib/auth.d.ts +92 -0
  280. package/dist/lib/auth.d.ts.map +1 -0
  281. package/dist/lib/auth.js +133 -0
  282. package/dist/lib/auth.js.map +1 -0
  283. package/dist/lib/format.d.ts +2 -0
  284. package/dist/lib/format.d.ts.map +1 -0
  285. package/dist/lib/format.js +9 -0
  286. package/dist/lib/format.js.map +1 -0
  287. package/dist/lib/index.d.ts +46 -0
  288. package/dist/lib/index.d.ts.map +1 -0
  289. package/dist/lib/index.js +41 -0
  290. package/dist/lib/index.js.map +1 -0
  291. package/dist/lib/invoice-email-outcome.d.ts +53 -0
  292. package/dist/lib/invoice-email-outcome.d.ts.map +1 -0
  293. package/dist/lib/invoice-email-outcome.js +43 -0
  294. package/dist/lib/invoice-email-outcome.js.map +1 -0
  295. package/dist/lib/module-presence/ModulePresenceProvider.d.ts +49 -0
  296. package/dist/lib/module-presence/ModulePresenceProvider.d.ts.map +1 -0
  297. package/dist/lib/module-presence/ModulePresenceProvider.js +73 -0
  298. package/dist/lib/module-presence/ModulePresenceProvider.js.map +1 -0
  299. package/dist/lib/module-presence/api.d.ts +15 -0
  300. package/dist/lib/module-presence/api.d.ts.map +1 -0
  301. package/dist/lib/module-presence/api.js +25 -0
  302. package/dist/lib/module-presence/api.js.map +1 -0
  303. package/dist/lib/module-presence/index.d.ts +3 -0
  304. package/dist/lib/module-presence/index.d.ts.map +1 -0
  305. package/dist/lib/module-presence/index.js +3 -0
  306. package/dist/lib/module-presence/index.js.map +1 -0
  307. package/dist/lib/money.d.ts +22 -0
  308. package/dist/lib/money.d.ts.map +1 -0
  309. package/dist/lib/money.js +51 -0
  310. package/dist/lib/money.js.map +1 -0
  311. package/dist/lib/page-size-options.d.ts +15 -0
  312. package/dist/lib/page-size-options.d.ts.map +1 -0
  313. package/dist/lib/page-size-options.js +14 -0
  314. package/dist/lib/page-size-options.js.map +1 -0
  315. package/dist/lib/status-color.d.ts +32 -0
  316. package/dist/lib/status-color.d.ts.map +1 -0
  317. package/dist/lib/status-color.js +24 -0
  318. package/dist/lib/status-color.js.map +1 -0
  319. package/dist/lib/surface-visibility.d.ts +70 -0
  320. package/dist/lib/surface-visibility.d.ts.map +1 -0
  321. package/dist/lib/surface-visibility.js +37 -0
  322. package/dist/lib/surface-visibility.js.map +1 -0
  323. package/dist/lib/text-normalization.d.ts +56 -0
  324. package/dist/lib/text-normalization.d.ts.map +1 -0
  325. package/dist/lib/text-normalization.js +59 -0
  326. package/dist/lib/text-normalization.js.map +1 -0
  327. package/dist/lib/use-page-size-preference.d.ts +29 -0
  328. package/dist/lib/use-page-size-preference.d.ts.map +1 -0
  329. package/dist/lib/use-page-size-preference.js +61 -0
  330. package/dist/lib/use-page-size-preference.js.map +1 -0
  331. package/dist/lib/use-unsaved-changes-prompt.d.ts +23 -0
  332. package/dist/lib/use-unsaved-changes-prompt.d.ts.map +1 -0
  333. package/dist/lib/use-unsaved-changes-prompt.js +75 -0
  334. package/dist/lib/use-unsaved-changes-prompt.js.map +1 -0
  335. package/dist/lib/utils.d.ts +9 -0
  336. package/dist/lib/utils.d.ts.map +1 -0
  337. package/dist/lib/utils.js +12 -0
  338. package/dist/lib/utils.js.map +1 -0
  339. package/dist/lib/uuid.d.ts +8 -0
  340. package/dist/lib/uuid.d.ts.map +1 -0
  341. package/dist/lib/uuid.js +18 -0
  342. package/dist/lib/uuid.js.map +1 -0
  343. package/dist/ui/alert.d.ts +12 -0
  344. package/dist/ui/alert.d.ts.map +1 -0
  345. package/dist/ui/alert.js +22 -0
  346. package/dist/ui/alert.js.map +1 -0
  347. package/dist/ui/badge.d.ts +10 -0
  348. package/dist/ui/badge.d.ts.map +1 -0
  349. package/dist/ui/badge.js +21 -0
  350. package/dist/ui/badge.js.map +1 -0
  351. package/dist/ui/button.d.ts +12 -0
  352. package/dist/ui/button.d.ts.map +1 -0
  353. package/dist/ui/button.js +31 -0
  354. package/dist/ui/button.js.map +1 -0
  355. package/dist/ui/card.d.ts +8 -0
  356. package/dist/ui/card.d.ts.map +1 -0
  357. package/dist/ui/card.js +16 -0
  358. package/dist/ui/card.js.map +1 -0
  359. package/dist/ui/checkbox.d.ts +8 -0
  360. package/dist/ui/checkbox.d.ts.map +1 -0
  361. package/dist/ui/checkbox.js +11 -0
  362. package/dist/ui/checkbox.js.map +1 -0
  363. package/dist/ui/color-picker.d.ts +23 -0
  364. package/dist/ui/color-picker.d.ts.map +1 -0
  365. package/dist/ui/color-picker.js +76 -0
  366. package/dist/ui/color-picker.js.map +1 -0
  367. package/dist/ui/combobox.d.ts +68 -0
  368. package/dist/ui/combobox.d.ts.map +1 -0
  369. package/dist/ui/combobox.js +182 -0
  370. package/dist/ui/combobox.js.map +1 -0
  371. package/dist/ui/dropdown-menu.d.ts +26 -0
  372. package/dist/ui/dropdown-menu.d.ts.map +1 -0
  373. package/dist/ui/dropdown-menu.js +38 -0
  374. package/dist/ui/dropdown-menu.js.map +1 -0
  375. package/dist/ui/index.d.ts +47 -0
  376. package/dist/ui/index.d.ts.map +1 -0
  377. package/dist/ui/index.js +38 -0
  378. package/dist/ui/index.js.map +1 -0
  379. package/dist/ui/input.d.ts +3 -0
  380. package/dist/ui/input.d.ts.map +1 -0
  381. package/dist/ui/input.js +8 -0
  382. package/dist/ui/input.js.map +1 -0
  383. package/dist/ui/label.d.ts +4 -0
  384. package/dist/ui/label.d.ts.map +1 -0
  385. package/dist/ui/label.js +9 -0
  386. package/dist/ui/label.js.map +1 -0
  387. package/dist/ui/multi-select.d.ts +32 -0
  388. package/dist/ui/multi-select.d.ts.map +1 -0
  389. package/dist/ui/multi-select.js +63 -0
  390. package/dist/ui/multi-select.js.map +1 -0
  391. package/dist/ui/page-header.d.ts +21 -0
  392. package/dist/ui/page-header.d.ts.map +1 -0
  393. package/dist/ui/page-header.js +9 -0
  394. package/dist/ui/page-header.js.map +1 -0
  395. package/dist/ui/route-tabs.d.ts +58 -0
  396. package/dist/ui/route-tabs.d.ts.map +1 -0
  397. package/dist/ui/route-tabs.js +34 -0
  398. package/dist/ui/route-tabs.js.map +1 -0
  399. package/dist/ui/save-button-group.d.ts +27 -0
  400. package/dist/ui/save-button-group.d.ts.map +1 -0
  401. package/dist/ui/save-button-group.js +44 -0
  402. package/dist/ui/save-button-group.js.map +1 -0
  403. package/dist/ui/section.d.ts +20 -0
  404. package/dist/ui/section.d.ts.map +1 -0
  405. package/dist/ui/section.js +7 -0
  406. package/dist/ui/section.js.map +1 -0
  407. package/dist/ui/select.d.ts +10 -0
  408. package/dist/ui/select.d.ts.map +1 -0
  409. package/dist/ui/select.js +15 -0
  410. package/dist/ui/select.js.map +1 -0
  411. package/dist/ui/separator.d.ts +3 -0
  412. package/dist/ui/separator.d.ts.map +1 -0
  413. package/dist/ui/separator.js +7 -0
  414. package/dist/ui/separator.js.map +1 -0
  415. package/dist/ui/table.d.ts +10 -0
  416. package/dist/ui/table.d.ts.map +1 -0
  417. package/dist/ui/table.js +20 -0
  418. package/dist/ui/table.js.map +1 -0
  419. package/dist/ui/textarea.d.ts +3 -0
  420. package/dist/ui/textarea.d.ts.map +1 -0
  421. package/dist/ui/textarea.js +8 -0
  422. package/dist/ui/textarea.js.map +1 -0
  423. package/dist/zones/AdminContributionsProvider.d.ts +72 -0
  424. package/dist/zones/AdminContributionsProvider.d.ts.map +1 -0
  425. package/dist/zones/AdminContributionsProvider.js +63 -0
  426. package/dist/zones/AdminContributionsProvider.js.map +1 -0
  427. package/dist/zones/AdminZone.d.ts +30 -0
  428. package/dist/zones/AdminZone.d.ts.map +1 -0
  429. package/dist/zones/AdminZone.js +59 -0
  430. package/dist/zones/AdminZone.js.map +1 -0
  431. package/dist/zones/RouteTabsZone.d.ts +62 -0
  432. package/dist/zones/RouteTabsZone.d.ts.map +1 -0
  433. package/dist/zones/RouteTabsZone.js +25 -0
  434. package/dist/zones/RouteTabsZone.js.map +1 -0
  435. package/dist/zones/ZoneErrorBoundary.d.ts +36 -0
  436. package/dist/zones/ZoneErrorBoundary.d.ts.map +1 -0
  437. package/dist/zones/ZoneErrorBoundary.js +44 -0
  438. package/dist/zones/ZoneErrorBoundary.js.map +1 -0
  439. package/dist/zones/index.d.ts +31 -0
  440. package/dist/zones/index.d.ts.map +1 -0
  441. package/dist/zones/index.js +27 -0
  442. package/dist/zones/index.js.map +1 -0
  443. package/dist/zones/use-admin-zone.d.ts +32 -0
  444. package/dist/zones/use-admin-zone.d.ts.map +1 -0
  445. package/dist/zones/use-admin-zone.js +96 -0
  446. package/dist/zones/use-admin-zone.js.map +1 -0
  447. package/package.json +94 -3
  448. package/tailwind.css +14 -0
  449. package/theme.css +2056 -0
package/theme.css ADDED
@@ -0,0 +1,2056 @@
1
+ /*
2
+ * **The admin's design system** — its custom-property vocabulary and its class
3
+ * vocabulary, published by the package every renderer already declares (feature
4
+ * 110, T129; owner ruling **D-219**;
5
+ * `specs/110-instance-repository/contracts/admin-stylesheet-composition.md`
6
+ * R3–R4). An instance imports this file and holds none of it.
7
+ *
8
+ * ## Why the kit, and not the shell where T126 put the first third of it
9
+ *
10
+ * 55 module packages declare `@endora-commerce/admin-kit` in their manifest and
11
+ * **none** declares `@endora-commerce/admin-shell`, while the shell peer-depends
12
+ * on the kit and the kit declares no `dependencies` at all. Published from the
13
+ * shell, 11 module packages would render classes defined by a package they
14
+ * cannot name and cannot put a version range on — a coupling with nowhere to be
15
+ * declared. Published from here, every renderer's edge already exists and the
16
+ * shell reaches the vocabulary through one it already has.
17
+ *
18
+ * It is *the package every renderer already declares* rather than the name
19
+ * `admin-kit`: if the open structure question folds the kit family into
20
+ * `packages/admin-shell`, the derivation answers `admin-shell` in the same run
21
+ * and the rule needs no edit (D-100).
22
+ *
23
+ * ## Why it is not the client's, even though it is their look
24
+ *
25
+ * Every consumer is a package. 70 files under `packages/` render a class this
26
+ * file defines and 30 read a custom property it declares through `var()`; **no
27
+ * file under `admin/src` does either**. A client holding these declarations
28
+ * holds a fork frozen on their scaffolding day, so a module release adding one
29
+ * class renders unstyled in every existing instance, silently, and the client
30
+ * cannot fix it.
31
+ *
32
+ * The half of that objection which is right is already delivered: the values are
33
+ * the client's, the **names** are not, and a value is one line in the override
34
+ * slot rather than a 5 036 B fork.
35
+ *
36
+ * ## How a client changes it — by redeclaring after the import, never by editing
37
+ *
38
+ * @import "tailwindcss";
39
+ * @import "@endora-commerce/admin-kit/theme.css";
40
+ * @import "./tailwind.generated.css";
41
+ *
42
+ * :root { --accent-h: 262; }
43
+ * .b2b-btn { border-radius: 2px; }
44
+ *
45
+ * The token half works because every semantic token in the mapping block below
46
+ * is an indirection — `--color-primary: hsl(var(--primary))` — so a utility this
47
+ * package built without ever seeing that instance still resolves against the
48
+ * client's `:root` (R3.2). The class half works by cascade order: their rule is
49
+ * later. What a redeclaration cannot change is a value baked as a literal — the
50
+ * palette here is overridable, Tailwind's own spacing scale is not. A client who
51
+ * needs a different spacing scale is asking for a different design system, and
52
+ * the answer to that is the escalation ladder rather than this seam.
53
+ *
54
+ * ## Two kinds in one subpath, and the name is under-descriptive on purpose
55
+ *
56
+ * R4.3 (**host tokens**) and R4.4 (**host class vocabulary**) are two kinds and
57
+ * they ship together, at the one subpath T126 published. Nothing a client
58
+ * legitimately does requires reaching the vocabulary separately — an override is
59
+ * a later rule in the slot they already have — so a second subpath would be a
60
+ * seam with no user and a second import to forget (R3.4). The name stayed
61
+ * `./theme.css` rather than being changed in the merge request that doubled its
62
+ * content; R4.3a is where that trade is written down.
63
+ *
64
+ * It is a **separate** subpath from `./tailwind.css` beside it for the reason
65
+ * R3.3 gives: `@source` order is irrelevant, while `@theme` and `:root` order
66
+ * decides which declaration wins, so merging the two would put a client\'s
67
+ * override before or after these tokens depending on where the generated
68
+ * enumeration happened to sort this package.
69
+ *
70
+ * ## What was reconciled, and what a scaffolded client now sees
71
+ *
72
+ * Three files became this one. The shell\'s `theme.css` declared 42 custom
73
+ * properties, `admin/src/styles/design-tokens.css` **redeclared 20 of them**,
74
+ * and `admin/src/styles/components.css` is the 200-token class vocabulary those
75
+ * 70 files render. So the merge is a **reconciliation, not a concatenation**
76
+ * (R3.5): the old arrangement had the package declaring a shadcn slate palette
77
+ * that every instance overwrote in full, on every load, in every deployment. One
78
+ * palette is declared here, and it is the one that has actually rendered since
79
+ * feature 010\'s rebrand — D-219\'s first consequence, accepted by the owner in
80
+ * those terms. A client who wants slate redeclares it; a client who wants their
81
+ * own always had to.
82
+ *
83
+ * ## Hand-written, unlike the `./tailwind.css` beside it
84
+ *
85
+ * That file\'s content is derived from the layer inventory and is generated
86
+ * precisely because a mistyped `@source` is silent (R1.4). These are
87
+ * declarations, and there is nothing to derive them from. What holds *them*
88
+ * honest is `check:class-vocabulary`, in both directions: a class a package
89
+ * renders that no published design system defines, and a class defined here that
90
+ * no file renders.
91
+ */
92
+
93
+ /* Feature 029 — prevent accidental horizontal page scroll on narrow viewports */
94
+ html,
95
+ body,
96
+ #root {
97
+ max-width: 100%;
98
+ overflow-x: clip;
99
+ }
100
+
101
+ /*
102
+ * Tailwind's own namespace: the `@theme inline` mapping that binds the utility
103
+ * names (`bg-primary`, `rounded-lg`, …) to the semantic tokens below. Every one
104
+ * is an indirection, and that is R3.2's whole mechanism — these 22 properties
105
+ * are read by no package through `var()` and are not part of the palette a
106
+ * client overrides.
107
+ */
108
+ @theme inline {
109
+ --color-border: hsl(var(--border));
110
+ --color-input: hsl(var(--input));
111
+ --color-ring: hsl(var(--ring));
112
+ --color-background: hsl(var(--background));
113
+ --color-foreground: hsl(var(--foreground));
114
+ --color-primary: hsl(var(--primary));
115
+ --color-primary-foreground: hsl(var(--primary-foreground));
116
+ --color-secondary: hsl(var(--secondary));
117
+ --color-secondary-foreground: hsl(var(--secondary-foreground));
118
+ --color-destructive: hsl(var(--destructive));
119
+ --color-destructive-foreground: hsl(var(--destructive-foreground));
120
+ --color-muted: hsl(var(--muted));
121
+ --color-muted-foreground: hsl(var(--muted-foreground));
122
+ --color-accent: hsl(var(--accent));
123
+ --color-accent-foreground: hsl(var(--accent-foreground));
124
+ --color-popover: hsl(var(--popover));
125
+ --color-popover-foreground: hsl(var(--popover-foreground));
126
+ --color-card: hsl(var(--card));
127
+ --color-card-foreground: hsl(var(--card-foreground));
128
+ --radius-sm: calc(var(--radius) - 4px);
129
+ --radius-md: calc(var(--radius) - 2px);
130
+ --radius-lg: var(--radius);
131
+ }
132
+
133
+ /*
134
+ * The palette — 79 custom properties, one declaration each (R3.5).
135
+ *
136
+ * The first group is the design system's own vocabulary; the second re-tones the
137
+ * shadcn semantic tokens onto it, so every shadcn primitive in the admin
138
+ * inherits the accent and the neutrals through a single hop. Before T129 those
139
+ * 20 shadcn declarations sat in the instance and overwrote this package's own
140
+ * copy of them on every load, in every deployment; now there is one copy and it
141
+ * is this one.
142
+ */
143
+ :root {
144
+ /* ---------- Layout breakpoints (feature 029 — mobile admin shell) ---------- */
145
+ --breakpoint-lg: 1024px;
146
+
147
+ /* ---------- Brand / accent (#6754e2 — feature 010 rebrand) ---------- */
148
+ --accent-h: 248;
149
+ --accent-s: 71%;
150
+ --accent-l: 61%;
151
+
152
+ --primary-color: hsl(var(--accent-h) var(--accent-s) var(--accent-l));
153
+ --primary-hover: hsl(var(--accent-h) var(--accent-s) calc(var(--accent-l) - 4%));
154
+ --primary-active: hsl(var(--accent-h) var(--accent-s) calc(var(--accent-l) - 8%));
155
+ --primary-fg: #ffffff;
156
+ --primary-soft: hsl(var(--accent-h) calc(var(--accent-s) - 10%) 96%);
157
+ --primary-soft-fg: hsl(var(--accent-h) calc(var(--accent-s) + 4%) 22%);
158
+ --ring-color: hsla(var(--accent-h), 70%, 38%, 0.35);
159
+
160
+ /* ---------- Neutrals (warm-ish gray, Shopify-leaning) ---------- */
161
+ --bg: #f6f6f7;
162
+ --bg-elevated: #ffffff;
163
+ --bg-sidebar: #1a1c1e;
164
+ --bg-sidebar-hover: #25282b;
165
+ --bg-sidebar-active: #2f3337;
166
+ --sidebar-fg: #d7d9dc;
167
+ --sidebar-fg-muted: #8b9097;
168
+ --sidebar-fg-active: #ffffff;
169
+
170
+ --surface: #ffffff;
171
+ --surface-muted: #fafbfb;
172
+ --surface-sunken: #f1f2f4;
173
+
174
+ --fg: #1a1c1e;
175
+ --fg-muted: #5b636d;
176
+ --fg-subtle: #8a9099;
177
+ --fg-disabled: #b5bac1;
178
+
179
+ --border-color: #e3e5e8;
180
+ --border-strong: #d3d6da;
181
+ --border-subtle: #ecedef;
182
+
183
+ /* ---------- Status colors (cards, badges, alerts) ---------- */
184
+ --success: #008060;
185
+ --success-soft: #e3f1df;
186
+ --success-soft-fg: #0c5132;
187
+
188
+ --warn: #b54708;
189
+ --warn-soft: #fff1e6;
190
+ --warn-soft-fg: #8a4a06;
191
+
192
+ --danger: #d72c0d;
193
+ --danger-soft: #fee9e7;
194
+ --danger-soft-fg: #8e1f0b;
195
+
196
+ --info: #1f6feb;
197
+ --info-soft: #e7f0ff;
198
+ --info-soft-fg: #134397;
199
+
200
+ --neutral-soft: #ebedef;
201
+ --neutral-soft-fg: #4a525c;
202
+
203
+ /* ---------- Radii ---------- */
204
+ --r-xs: 4px;
205
+ --r-sm: 6px;
206
+ --r-md: 8px;
207
+ --r-lg: 10px;
208
+ --r-xl: 14px;
209
+ --r-pill: 999px;
210
+
211
+ /* ---------- Shadows ---------- */
212
+ --sh-1: 0 1px 0 rgba(0, 0, 0, 0.05);
213
+ --sh-2: 0 1px 2px rgba(13, 16, 19, 0.08), 0 0 0 1px rgba(13, 16, 19, 0.04);
214
+ --sh-3: 0 4px 12px rgba(13, 16, 19, 0.10), 0 0 0 1px rgba(13, 16, 19, 0.04);
215
+ --sh-pop: 0 12px 32px rgba(13, 16, 19, 0.18), 0 0 0 1px rgba(13, 16, 19, 0.08);
216
+
217
+ /* ---------- Density (regular default) ---------- */
218
+ --row-h: 44px;
219
+ --row-pad: 12px;
220
+ --field-h: 36px;
221
+ --field-pad: 10px;
222
+
223
+ /* ---------- Typography ---------- */
224
+ --ff: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
225
+ --ff-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
226
+
227
+ /* ---------- shadcn semantic tokens, re-toned onto the palette above ---------- */
228
+ --background: 220 9% 97%; /* matches --bg */
229
+ --foreground: 220 7% 11%; /* matches --fg */
230
+ --card: 0 0% 100%; /* matches --surface */
231
+ --card-foreground: 220 7% 11%;
232
+ --popover: 0 0% 100%;
233
+ --popover-foreground: 220 7% 11%;
234
+
235
+ --primary: var(--accent-h) var(--accent-s) var(--accent-l);
236
+ --primary-foreground: 0 0% 100%;
237
+
238
+ --secondary: 220 7% 95%; /* matches --surface-sunken */
239
+ --secondary-foreground: 220 7% 11%;
240
+ --muted: 220 7% 97%; /* matches --surface-muted */
241
+ --muted-foreground: 218 8% 39%; /* matches --fg-muted */
242
+ --accent: 220 7% 95%;
243
+ --accent-foreground: 220 7% 11%;
244
+
245
+ --destructive: 8 89% 45%; /* matches --danger */
246
+ --destructive-foreground: 0 0% 100%;
247
+
248
+ --border: 220 7% 90%; /* matches --border-color */
249
+ --input: 220 7% 90%;
250
+ --ring: var(--accent-h) 70% 38%;
251
+ --radius: 0.5rem;
252
+ }
253
+
254
+ .dark {
255
+ --background: 222.2 47.4% 11.2%;
256
+ --foreground: 210 40% 98%;
257
+ --card: 222.2 47.4% 11.2%;
258
+ --card-foreground: 210 40% 98%;
259
+ --popover: 222.2 47.4% 11.2%;
260
+ --popover-foreground: 210 40% 98%;
261
+ --primary: 210 40% 98%;
262
+ --primary-foreground: 222.2 47.4% 11.2%;
263
+ --secondary: 217.2 32.6% 17.5%;
264
+ --secondary-foreground: 210 40% 98%;
265
+ --muted: 217.2 32.6% 17.5%;
266
+ --muted-foreground: 215 20.2% 65.1%;
267
+ --accent: 217.2 32.6% 17.5%;
268
+ --accent-foreground: 210 40% 98%;
269
+ --destructive: 0 62.8% 30.6%;
270
+ --destructive-foreground: 210 40% 98%;
271
+ --border: 217.2 32.6% 17.5%;
272
+ --input: 217.2 32.6% 17.5%;
273
+ --ring: 212.7 26.8% 83.9%;
274
+ }
275
+
276
+ [data-density="compact"] {
277
+ --row-h: 36px;
278
+ --row-pad: 8px;
279
+ --field-h: 32px;
280
+ --field-pad: 8px;
281
+ }
282
+
283
+ /*
284
+ * `@layer base` — and `design-tokens.css`' unlayered `body` and scrollbar rules
285
+ * are merged into it, after the rules they used to win against (R3.5).
286
+ *
287
+ * They used to win by being **unlayered**, which is why this package's own
288
+ * `@layer base` `body` never rendered. Inside one layer they win by being last,
289
+ * so the cascade result is unchanged and the layering is now honest.
290
+ */
291
+ @layer base {
292
+ * {
293
+ @apply border-border;
294
+ }
295
+ body {
296
+ @apply bg-background text-foreground;
297
+ font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
298
+ }
299
+ html,
300
+ body,
301
+ #root {
302
+ margin: 0;
303
+ height: 100%;
304
+ }
305
+
306
+ /* The design background, font stack and text rendering (feature 008). */
307
+
308
+ body {
309
+ font-family: var(--ff);
310
+ background: var(--bg);
311
+ color: var(--fg);
312
+ -webkit-font-smoothing: antialiased;
313
+ -moz-osx-font-smoothing: grayscale;
314
+ text-rendering: optimizeLegibility;
315
+ }
316
+
317
+ /* Custom scrollbars across the app — small, matches Shopify-style admin. */
318
+ ::-webkit-scrollbar { width: 10px; height: 10px; }
319
+ ::-webkit-scrollbar-thumb {
320
+ background: #c8ccd1; border-radius: 999px;
321
+ border: 2px solid transparent; background-clip: padding-box;
322
+ }
323
+ ::-webkit-scrollbar-thumb:hover {
324
+ background: #a9aeb5; background-clip: padding-box;
325
+ border: 2px solid transparent;
326
+ }
327
+ ::-webkit-scrollbar-track { background: transparent; }
328
+ }
329
+
330
+ /* ============================================================
331
+ The class vocabulary (R4.4) — feature 008, moved here by T129
332
+ ============================================================
333
+ BEM-style component classes co-existing with the shadcn/Tailwind
334
+ primitives `@endora-commerce/admin-kit/ui` publishes. 70 files in
335
+ `packages/` render them by name; a client overrides one by writing a
336
+ later rule in their own stylesheet, never by editing this file.
337
+
338
+ Whether this vocabulary is eventually retired in favour of the `ui/`
339
+ primitives is an open question and is the owner's — D-219 says so in
340
+ those words, and notes that whoever owns the vocabulary owns the
341
+ retirement. It is orthogonal to where the vocabulary lives.
342
+ ============================================================ */
343
+ /* ============================================================
344
+ Sidebar (dark, grouped, collapsible)
345
+ ============================================================ */
346
+ .b2b-sidebar {
347
+ background: var(--bg-sidebar);
348
+ color: var(--sidebar-fg);
349
+ display: flex; flex-direction: column;
350
+ height: 100vh;
351
+ position: sticky; top: 0;
352
+ border-right: 1px solid #000;
353
+ width: 248px;
354
+ }
355
+ .b2b-sidebar--rail { width: 64px; }
356
+
357
+ /* Rail (icon-only) mode — hide everything that has running text and
358
+ center the remaining icons. The popover handles labels on demand. */
359
+ .b2b-sidebar--rail .b2b-sidebar__brand {
360
+ padding: 14px 0;
361
+ justify-content: center;
362
+ }
363
+ .b2b-sidebar--rail .b2b-sidebar__brand-text { display: none; }
364
+ .b2b-sidebar--rail .b2b-sidebar__search { padding: 8px 0; display: flex; justify-content: center; }
365
+ .b2b-sidebar__search-rail {
366
+ width: 36px; height: 36px;
367
+ background: rgba(255,255,255,0.06);
368
+ border: 1px solid rgba(255,255,255,0.10);
369
+ border-radius: var(--r-sm);
370
+ color: var(--sidebar-fg-muted);
371
+ display: grid; place-items: center;
372
+ cursor: pointer;
373
+ }
374
+ .b2b-sidebar__search-rail:hover { background: rgba(255,255,255,0.12); color: #fff; }
375
+ .b2b-sidebar--rail .b2b-sidebar__nav { padding: 4px 6px 8px; }
376
+ .b2b-sidebar--rail .b2b-sidebar__group { padding: 4px 0; }
377
+ .b2b-sidebar--rail .b2b-sidebar__group-label { display: none; }
378
+ .b2b-sidebar__rail-row { display: flex; justify-content: center; padding: 2px 0; }
379
+ .b2b-nav-item--rail {
380
+ width: 40px; height: 40px;
381
+ display: grid; place-items: center;
382
+ padding: 0;
383
+ border-radius: var(--r-sm);
384
+ background: transparent;
385
+ border: none;
386
+ cursor: pointer;
387
+ color: var(--sidebar-fg);
388
+ }
389
+ .b2b-nav-item--rail svg { width: 18px; height: 18px; color: var(--sidebar-fg-muted); }
390
+ .b2b-nav-item--rail:hover { background: var(--bg-sidebar-hover); }
391
+ .b2b-nav-item--rail:hover svg { color: var(--sidebar-fg-active); }
392
+ .b2b-nav-item--rail.is-active { background: var(--bg-sidebar-active); }
393
+ .b2b-nav-item--rail.is-active svg { color: hsl(var(--accent-h) 90% 75%); }
394
+ .b2b-nav-item--rail.is-open { background: var(--bg-sidebar-hover); }
395
+ .b2b-nav-item--rail:focus-visible {
396
+ outline: 2px solid var(--ring-color);
397
+ outline-offset: 1px;
398
+ }
399
+
400
+ /* Floating popover that appears next to a rail icon on hover or click. */
401
+ .b2b-sidebar__rail-popover {
402
+ position: absolute;
403
+ left: 60px;
404
+ margin-top: -36px;
405
+ min-width: 200px;
406
+ max-width: 260px;
407
+ background: var(--surface);
408
+ color: var(--fg);
409
+ border: 1px solid var(--border-color);
410
+ border-radius: var(--r-md);
411
+ box-shadow: 0 10px 30px rgba(0,0,0,0.35);
412
+ padding: 4px;
413
+ z-index: 60;
414
+ }
415
+ .b2b-sidebar__rail-popover-header {
416
+ font-size: 11px;
417
+ font-weight: 600;
418
+ color: var(--fg-muted);
419
+ text-transform: uppercase;
420
+ letter-spacing: 0.06em;
421
+ padding: 6px 10px 4px;
422
+ }
423
+ .b2b-sidebar__rail-popover-item {
424
+ display: flex; align-items: center; gap: 8px;
425
+ padding: 6px 10px;
426
+ font-size: 13px;
427
+ color: var(--fg);
428
+ border-radius: var(--r-sm);
429
+ text-decoration: none;
430
+ }
431
+ .b2b-sidebar__rail-popover-item svg {
432
+ width: 14px; height: 14px;
433
+ color: var(--fg-muted);
434
+ flex-shrink: 0;
435
+ }
436
+ .b2b-sidebar__rail-popover-item:hover {
437
+ background: var(--bg-muted);
438
+ color: var(--fg);
439
+ }
440
+ .b2b-sidebar__rail-popover-item.is-active {
441
+ background: hsl(var(--accent-h) 70% 50% / 0.12);
442
+ color: hsl(var(--accent-h) 70% 30%);
443
+ font-weight: 500;
444
+ }
445
+ .b2b-sidebar__rail-popover-item.is-active svg {
446
+ color: hsl(var(--accent-h) 70% 45%);
447
+ }
448
+
449
+ .b2b-sidebar__rail-toggle {
450
+ display: flex; align-items: center; gap: 8px;
451
+ padding: 8px 12px;
452
+ font-size: 11px;
453
+ color: var(--sidebar-fg-muted);
454
+ background: transparent;
455
+ border: none;
456
+ border-top: 1px solid rgba(255,255,255,0.06);
457
+ cursor: pointer;
458
+ text-align: left;
459
+ width: 100%;
460
+ }
461
+ .b2b-sidebar__rail-toggle:hover { color: #fff; background: rgba(255,255,255,0.04); }
462
+ .b2b-sidebar__rail-toggle svg { flex-shrink: 0; }
463
+ .b2b-sidebar--rail .b2b-sidebar__rail-toggle { justify-content: center; padding: 10px 0; }
464
+ .b2b-sidebar__rail-toggle-label { line-height: 1; }
465
+
466
+ /* Foot — hide identity text in rail mode, keep the avatar + sign-out
467
+ icon stacked vertically so they don't overflow the 64px column. */
468
+ .b2b-sidebar--rail .b2b-sidebar__foot {
469
+ flex-direction: column;
470
+ gap: 6px;
471
+ padding: 8px 0;
472
+ align-items: center;
473
+ }
474
+ .b2b-sidebar--rail .b2b-sidebar__foot-identity {
475
+ margin: 0;
476
+ padding: 0;
477
+ }
478
+ .b2b-sidebar--rail .b2b-sidebar__foot .meta { display: none; }
479
+
480
+ .b2b-sidebar__brand {
481
+ display: flex; align-items: center; gap: 10px;
482
+ padding: 14px 16px;
483
+ font-weight: 600; font-size: 14px; color: #fff;
484
+ border-bottom: 1px solid rgba(255,255,255,0.06);
485
+ transition: background 80ms ease;
486
+ }
487
+ .b2b-sidebar__brand:hover { background: var(--bg-sidebar-hover); }
488
+ .b2b-sidebar__brand:focus-visible {
489
+ outline: 2px solid var(--ring-color);
490
+ outline-offset: -2px;
491
+ }
492
+ .b2b-sidebar__brand-logo {
493
+ width: 28px; height: 28px;
494
+ border-radius: 7px;
495
+ /* A light ground, not the accent gradient it replaced. The mark is wine
496
+ (#8A1C5C) and the accent hue is indigo (248), so the gradient fought it;
497
+ and on the sidebar's own #1a1c1e the mark measures 1.95:1, which is
498
+ invisible. On this tint it is 8.37:1, and the tile itself sits at
499
+ 16.35:1 against the sidebar. #fbf9ff rather than plain white because it
500
+ is the palette's own near-white. */
501
+ background: #fbf9ff;
502
+ display: grid; place-items: center;
503
+ padding: 3px;
504
+ box-shadow: 0 1px 0 rgba(255,255,255,0.15) inset;
505
+ flex-shrink: 0;
506
+ }
507
+ .b2b-sidebar__brand-logo svg {
508
+ width: 100%; height: 100%;
509
+ display: block;
510
+ object-fit: contain;
511
+ }
512
+ /* #9f67ff, not the palette's #7c3aed: this is 14px/600 text, so WCAG AA asks
513
+ 4.5:1 and measured against #1a1c1e the darker violet gives 3.00:1 while this
514
+ one gives 4.77:1. #6322c8 is 2.11:1 and #c4b5fd is 9.26:1 but reads as
515
+ lavender rather than as the brand's violet. */
516
+ .b2b-sidebar__brand-text-accent { color: #9f67ff; }
517
+
518
+ .b2b-sidebar__search {
519
+ padding: 10px 12px;
520
+ position: relative;
521
+ }
522
+ .b2b-sidebar__search-input {
523
+ width: 100%;
524
+ height: 32px;
525
+ background: rgba(255,255,255,0.06);
526
+ border: 1px solid rgba(255,255,255,0.10);
527
+ border-radius: var(--r-sm);
528
+ color: #fff;
529
+ font-size: 12px;
530
+ padding: 0 36px 0 32px;
531
+ font-family: inherit;
532
+ cursor: pointer;
533
+ }
534
+ .b2b-sidebar__search-input::placeholder { color: var(--sidebar-fg-muted); }
535
+ .b2b-sidebar__search-input:focus {
536
+ outline: none;
537
+ background: rgba(255,255,255,0.12);
538
+ border-color: rgba(255,255,255,0.25);
539
+ }
540
+ .b2b-sidebar__search-icon {
541
+ position: absolute; left: 22px; top: 50%; transform: translateY(-50%);
542
+ color: var(--sidebar-fg-muted); pointer-events: none;
543
+ }
544
+ .b2b-sidebar__search-kbd {
545
+ position: absolute; right: 22px; top: 50%; transform: translateY(-50%);
546
+ font-size: 10px; padding: 2px 5px;
547
+ background: rgba(255,255,255,0.08);
548
+ border-radius: 3px; color: var(--sidebar-fg-muted);
549
+ font-family: var(--ff-mono);
550
+ }
551
+
552
+ .b2b-sidebar__nav {
553
+ flex: 1;
554
+ overflow-y: auto;
555
+ padding: 4px 8px 16px;
556
+ }
557
+
558
+ .b2b-sidebar__group { padding: 8px 4px 4px; }
559
+ .b2b-sidebar__group-label {
560
+ display: flex; align-items: center; gap: 6px;
561
+ padding: 4px 8px;
562
+ font-size: 11px; font-weight: 600;
563
+ color: var(--sidebar-fg-muted);
564
+ text-transform: uppercase;
565
+ letter-spacing: 0.06em;
566
+ cursor: pointer;
567
+ user-select: none;
568
+ border-radius: var(--r-xs);
569
+ background: transparent;
570
+ border: none;
571
+ width: 100%;
572
+ text-align: left;
573
+ }
574
+ .b2b-sidebar__group-label:hover { color: var(--sidebar-fg); }
575
+ .b2b-sidebar__group-label svg { transition: transform .12s; }
576
+ .b2b-sidebar__group--collapsed .b2b-sidebar__group-label svg { transform: rotate(-90deg); }
577
+ .b2b-sidebar__group--collapsed .b2b-sidebar__items { display: none; }
578
+ .b2b-sidebar__items { display: flex; flex-direction: column; gap: 1px; margin-top: 2px; }
579
+
580
+ .b2b-nav-item {
581
+ display: flex; align-items: center; gap: 10px;
582
+ padding: 6px 10px;
583
+ font-size: 13px;
584
+ color: var(--sidebar-fg);
585
+ border-radius: var(--r-sm);
586
+ transition: background .1s, color .1s;
587
+ position: relative;
588
+ text-decoration: none;
589
+ }
590
+ .b2b-nav-item svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--sidebar-fg-muted); }
591
+ .b2b-nav-item:hover { background: var(--bg-sidebar-hover); color: var(--sidebar-fg-active); }
592
+ .b2b-nav-item:hover svg { color: var(--sidebar-fg-active); }
593
+ .b2b-nav-item.is-active {
594
+ background: var(--bg-sidebar-active);
595
+ color: var(--sidebar-fg-active);
596
+ font-weight: 500;
597
+ }
598
+ .b2b-nav-item.is-active svg { color: hsl(var(--accent-h) 90% 75%); }
599
+ .b2b-nav-badge {
600
+ margin-left: auto;
601
+ font-size: 10px; padding: 1px 6px; border-radius: 999px;
602
+ background: rgba(255,255,255,0.10); color: var(--sidebar-fg);
603
+ }
604
+ .b2b-nav-item.is-active .b2b-nav-badge {
605
+ background: hsl(var(--accent-h) 70% 50%); color: #fff;
606
+ }
607
+
608
+ .b2b-sidebar__foot {
609
+ padding: 12px;
610
+ border-top: 1px solid rgba(255,255,255,0.06);
611
+ display: flex; align-items: center; gap: 10px;
612
+ }
613
+ .b2b-sidebar__foot-identity {
614
+ flex: 1; min-width: 0;
615
+ display: flex; align-items: center; gap: 10px;
616
+ padding: 4px 6px;
617
+ margin: -4px -6px;
618
+ border-radius: var(--r-sm);
619
+ text-decoration: none; color: inherit; cursor: pointer;
620
+ transition: background 80ms ease;
621
+ }
622
+ .b2b-sidebar__foot-identity:hover { background: var(--bg-sidebar-hover); }
623
+ .b2b-sidebar__foot-identity:focus-visible {
624
+ outline: 2px solid var(--ring-color);
625
+ outline-offset: -2px;
626
+ }
627
+ .b2b-avatar {
628
+ width: 28px; height: 28px;
629
+ border-radius: 50%;
630
+ background: linear-gradient(135deg, #6366f1, #ec4899);
631
+ color: #fff;
632
+ font-size: 11px; font-weight: 600;
633
+ display: grid; place-items: center;
634
+ flex-shrink: 0;
635
+ }
636
+ .b2b-sidebar__foot .meta { flex: 1; min-width: 0; }
637
+ .b2b-sidebar__foot .meta .name {
638
+ font-size: 12px; font-weight: 500; color: #fff;
639
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
640
+ }
641
+ .b2b-sidebar__foot .meta .role {
642
+ font-size: 11px; color: var(--sidebar-fg-muted);
643
+ }
644
+ .b2b-sidebar__foot .icon-btn {
645
+ width: 28px; height: 28px; border-radius: var(--r-sm);
646
+ background: transparent; border: none;
647
+ color: var(--sidebar-fg-muted);
648
+ display: grid; place-items: center; cursor: pointer;
649
+ }
650
+ .b2b-sidebar__foot .icon-btn:hover {
651
+ background: rgba(255,255,255,0.08); color: #fff;
652
+ }
653
+
654
+ /* ============================================================
655
+ Topbar (sticky breadcrumb header)
656
+ ============================================================ */
657
+ .b2b-topbar {
658
+ height: 56px;
659
+ background: var(--surface);
660
+ border-bottom: 1px solid var(--border-color);
661
+ display: flex; align-items: center;
662
+ padding: 0 24px;
663
+ gap: 16px;
664
+ /* Sits above all in-page content — incl. the sticky form-action bar
665
+ (z-index 30) — so topbar popovers (e.g. the notification bell dropdown)
666
+ are not painted behind page buttons. Stays below the mobile nav backdrop
667
+ (40) and drawers/modals/scrim (50/60). */
668
+ position: sticky; top: 0; z-index: 35;
669
+ }
670
+ .b2b-topbar__crumbs {
671
+ display: flex; align-items: center; gap: 6px;
672
+ font-size: 13px; color: var(--fg-muted);
673
+ flex: 1; min-width: 0;
674
+ }
675
+ .b2b-topbar__crumbs-inner {
676
+ display: flex;
677
+ align-items: center;
678
+ gap: 6px;
679
+ flex: 1;
680
+ min-width: 0;
681
+ width: 100%;
682
+ }
683
+ .b2b-topbar__crumbs .crumb-sep { color: var(--fg-disabled); }
684
+ .b2b-topbar__crumbs .crumb-cur { color: var(--fg); font-weight: 500; }
685
+ .b2b-topbar__crumbs .crumb-link {
686
+ color: var(--fg-muted);
687
+ text-decoration: none;
688
+ border-radius: 2px;
689
+ transition: color 80ms ease;
690
+ }
691
+ .b2b-topbar__crumbs .crumb-link:hover { color: var(--primary-color); text-decoration: underline; }
692
+ .b2b-topbar__crumbs .crumb-link:focus-visible {
693
+ outline: 2px solid var(--ring-color);
694
+ outline-offset: 2px;
695
+ }
696
+ .b2b-topbar__actions { display: flex; align-items: center; gap: 8px; }
697
+ .b2b-topbar__icon-btn {
698
+ width: 34px; height: 34px;
699
+ border-radius: var(--r-sm);
700
+ border: 1px solid transparent;
701
+ background: transparent;
702
+ color: var(--fg-muted);
703
+ display: grid; place-items: center;
704
+ position: relative;
705
+ cursor: pointer;
706
+ transition: background .12s, color .12s;
707
+ }
708
+ .b2b-topbar__icon-btn:hover { background: var(--surface-sunken); color: var(--fg); }
709
+ .b2b-topbar__icon-btn .dot {
710
+ position: absolute; top: 6px; right: 6px;
711
+ width: 7px; height: 7px; border-radius: 50%;
712
+ background: var(--danger);
713
+ box-shadow: 0 0 0 2px var(--surface);
714
+ }
715
+
716
+ /* ============================================================
717
+ Page header
718
+ ============================================================
719
+ The outer gutter (24/28/64px) lives on `.b2b-main` so every page
720
+ inside the AppShell — both in-scope redesigned pages (Home,
721
+ Products, Product editor, Inventory, Price lists) and adapted
722
+ pages that still render shadcn primitives without a `.b2b-page`
723
+ wrapper — gets the same spacing. `.b2b-page` only re-centers the
724
+ content and caps its width. */
725
+ .b2b-main {
726
+ padding: 24px 28px 64px;
727
+ max-width: 100%;
728
+ }
729
+ .b2b-page {
730
+ max-width: 1400px;
731
+ margin: 0 auto;
732
+ }
733
+ .b2b-page--wide { max-width: 1600px; }
734
+
735
+ /* CMS content editors — settings above, page builder in its own row below */
736
+ .cms-content-editor__builder {
737
+ width: 100%;
738
+ min-width: 0;
739
+ }
740
+ .cms-content-editor__builder .cms-page-builder {
741
+ min-height: calc(100vh - 320px);
742
+ }
743
+ /* While filtering the component drawer, force all category sections open. */
744
+ .cms-page-builder [data-pb-drawer-filtering] [class*="ComponentList-content"] {
745
+ display: block !important;
746
+ }
747
+ .cms-page-builder .cms-pb-header-shell,
748
+ .email-builder-pane .cms-pb-header-shell {
749
+ display: contents;
750
+ }
751
+ /* Left column: sidebar toggles + template actions, flush start. */
752
+ .cms-page-builder .cms-pb-header-left,
753
+ .email-builder-pane .cms-pb-header-left {
754
+ align-items: center;
755
+ gap: 0.5rem;
756
+ flex-wrap: nowrap;
757
+ min-width: 0;
758
+ }
759
+ .cms-page-builder .cms-pb-header-leading,
760
+ .email-builder-pane .cms-pb-header-leading {
761
+ display: inline-flex;
762
+ align-items: center;
763
+ min-width: 0;
764
+ /* Puck's left toggle column sets a muted `color` — reset so our buttons match. */
765
+ color: hsl(var(--foreground));
766
+ }
767
+ .cms-page-builder .cms-pb-header-actions,
768
+ .email-builder-pane .cms-pb-header-actions {
769
+ display: flex;
770
+ flex-wrap: nowrap;
771
+ align-items: center;
772
+ gap: 0.5rem;
773
+ color: hsl(var(--foreground));
774
+ }
775
+ /* Keep the center title as a single centered label (Puck 1fr / auto / 1fr grid). */
776
+ .cms-page-builder [class*="PuckHeader-title"],
777
+ .email-builder-pane [class*="PuckHeader-title"] {
778
+ justify-self: center;
779
+ text-align: center;
780
+ }
781
+ /* Right tools: never wrap onto a second row. */
782
+ .cms-page-builder [class*="PuckHeader-tools"],
783
+ .email-builder-pane [class*="PuckHeader-tools"] {
784
+ align-items: center;
785
+ min-width: 0;
786
+ }
787
+ .cms-page-builder [class*="MenuBar-inner"],
788
+ .email-builder-pane [class*="MenuBar-inner"] {
789
+ flex-wrap: nowrap !important;
790
+ gap: 0.5rem !important;
791
+ }
792
+ /* Prefer compact icon buttons on the right; show labels when there is room. */
793
+ .cms-page-builder [class*="PuckHeader-tools"] .cms-pb-header-actions__label,
794
+ .email-builder-pane [class*="PuckHeader-tools"] .cms-pb-header-actions__label {
795
+ display: none;
796
+ margin-inline-start: 0.25rem;
797
+ }
798
+ @media (min-width: 1280px) {
799
+ .cms-page-builder [class*="PuckHeader-tools"] .cms-pb-header-actions__label,
800
+ .email-builder-pane [class*="PuckHeader-tools"] .cms-pb-header-actions__label {
801
+ display: inline;
802
+ }
803
+ }
804
+ /* Left template actions keep their labels. */
805
+ .cms-page-builder .cms-pb-header-leading .cms-pb-header-actions__label,
806
+ .email-builder-pane .cms-pb-header-leading .cms-pb-header-actions__label {
807
+ display: inline;
808
+ }
809
+ /* Email header: Preview sits beside Clear/Fullscreen from PageBuilderHeaderActions. */
810
+ .email-builder-pane [class*="PuckHeader-tools"] > .cms-pb-header-actions > .cms-pb-header-actions {
811
+ display: contents;
812
+ }
813
+ @media (max-width: 1023px) {
814
+ .cms-content-editor__builder .cms-page-builder {
815
+ min-height: min(70vh, 640px);
816
+ }
817
+ }
818
+
819
+ .b2b-page-head {
820
+ display: flex; align-items: flex-start; gap: 16px;
821
+ margin-bottom: 20px;
822
+ }
823
+ .b2b-page-head__back {
824
+ display: inline-flex; align-items: center; gap: 4px;
825
+ font-size: 12px; color: var(--fg-muted);
826
+ margin-bottom: 6px;
827
+ background: transparent; border: none; cursor: pointer; padding: 0;
828
+ text-decoration: none;
829
+ }
830
+ .b2b-page-head__back:hover { color: var(--fg); }
831
+ .b2b-page-head__title {
832
+ display: flex; align-items: center; gap: 10px;
833
+ font-size: 22px; font-weight: 600; letter-spacing: -0.01em;
834
+ color: var(--fg);
835
+ }
836
+ .b2b-page-head__sub {
837
+ color: var(--fg-muted); font-size: 13px; margin-top: 4px;
838
+ }
839
+ .b2b-page-head__actions {
840
+ display: flex; gap: 8px; margin-left: auto;
841
+ flex-shrink: 0;
842
+ }
843
+
844
+ /* ============================================================
845
+ Buttons (used inside in-scope pages alongside shadcn ones)
846
+ ============================================================ */
847
+ .b2b-btn {
848
+ display: inline-flex; align-items: center; justify-content: center;
849
+ gap: 6px;
850
+ height: var(--field-h);
851
+ padding: 0 14px;
852
+ border-radius: var(--r-sm);
853
+ font-weight: 500; font-size: 13px;
854
+ white-space: nowrap;
855
+ border: 1px solid transparent;
856
+ background: var(--surface);
857
+ color: var(--fg);
858
+ font-family: inherit;
859
+ cursor: pointer;
860
+ user-select: none;
861
+ transition: background .12s ease, border-color .12s ease, box-shadow .12s ease, color .12s ease;
862
+ }
863
+ .b2b-btn:focus-visible {
864
+ outline: none; box-shadow: 0 0 0 3px var(--ring-color);
865
+ }
866
+ .b2b-btn[disabled] { opacity: .5; cursor: not-allowed; pointer-events: none; }
867
+
868
+ .b2b-btn--primary {
869
+ background: var(--primary-color); color: var(--primary-fg);
870
+ border-color: hsl(var(--accent-h) var(--accent-s) calc(var(--accent-l) - 8%));
871
+ box-shadow: var(--sh-1), inset 0 1px 0 rgba(255,255,255,0.18);
872
+ }
873
+ .b2b-btn--primary:hover { background: var(--primary-hover); }
874
+ .b2b-btn--primary:active { background: var(--primary-active); }
875
+
876
+ .b2b-btn--default {
877
+ background: var(--surface);
878
+ border-color: var(--border-strong);
879
+ color: var(--fg);
880
+ box-shadow: var(--sh-1);
881
+ }
882
+ .b2b-btn--default:hover { background: var(--surface-sunken); }
883
+
884
+ .b2b-btn--ghost {
885
+ background: transparent; border-color: transparent; color: var(--fg-muted);
886
+ }
887
+ .b2b-btn--ghost:hover { background: var(--surface-sunken); color: var(--fg); }
888
+
889
+ .b2b-btn--danger {
890
+ background: var(--surface);
891
+ border-color: var(--border-strong);
892
+ color: var(--danger);
893
+ box-shadow: var(--sh-1);
894
+ }
895
+ .b2b-btn--danger:hover { background: var(--danger-soft); border-color: var(--danger); }
896
+
897
+ .b2b-btn--sm { height: 28px; padding: 0 10px; font-size: 12px; border-radius: var(--r-xs); }
898
+ .b2b-btn--lg { height: 40px; padding: 0 18px; font-size: 14px; }
899
+ .b2b-btn--icon { width: var(--field-h); padding: 0; }
900
+ .b2b-btn--sm.b2b-btn--icon { width: 28px; }
901
+
902
+ /* ============================================================
903
+ Field / Input
904
+ ============================================================ */
905
+ .b2b-field {
906
+ display: block;
907
+ width: 100%;
908
+ height: var(--field-h);
909
+ padding: 0 var(--field-pad);
910
+ background: var(--surface);
911
+ border: 1px solid var(--border-strong);
912
+ border-radius: var(--r-sm);
913
+ color: var(--fg);
914
+ font-family: inherit;
915
+ font-size: 13px;
916
+ transition: border-color .12s, box-shadow .12s;
917
+ }
918
+ textarea.b2b-field {
919
+ height: auto; padding: 8px var(--field-pad);
920
+ resize: vertical; min-height: 80px; line-height: 1.5;
921
+ }
922
+ .b2b-field:hover { border-color: var(--fg-subtle); }
923
+ .b2b-field:focus {
924
+ outline: none; border-color: var(--primary-color);
925
+ box-shadow: 0 0 0 3px var(--ring-color);
926
+ }
927
+ .b2b-field::placeholder { color: var(--fg-subtle); }
928
+ .b2b-field--mono { font-family: var(--ff-mono); font-size: 12px; }
929
+ .b2b-field--addon { padding-left: 32px; }
930
+
931
+ .b2b-input-wrap { position: relative; }
932
+ .b2b-input-wrap > svg.lead, .b2b-input-wrap > svg.trail {
933
+ position: absolute; top: 50%; transform: translateY(-50%);
934
+ width: 16px; height: 16px; color: var(--fg-subtle); pointer-events: none;
935
+ }
936
+ .b2b-input-wrap > svg.lead { left: 10px; }
937
+ .b2b-input-wrap > svg.trail { right: 10px; }
938
+
939
+ .b2b-label {
940
+ display: block;
941
+ font-size: 12px; font-weight: 500;
942
+ color: var(--fg);
943
+ margin-bottom: 6px;
944
+ }
945
+ .b2b-help {
946
+ font-size: 12px; color: var(--fg-muted); margin-top: 4px;
947
+ }
948
+
949
+ /* Select (native, restyled).
950
+ MODIFIER ONLY — it strips the browser chrome and draws the chevron, but every
951
+ visible property (height, border, radius, background, focus ring) comes from
952
+ `.b2b-field`. Applied alone it yields a borderless control that reads as
953
+ plain text, so always pair the two: `class="b2b-field b2b-select"`.
954
+ React code should reach for the `Select` primitive instead
955
+ (`admin/src/components/ui/select.tsx`), which bundles both. */
956
+ .b2b-select {
957
+ appearance: none;
958
+ background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%235b636d' stroke-width='2'><polyline points='6 9 12 15 18 9'/></svg>");
959
+ background-repeat: no-repeat;
960
+ background-position: right 10px center;
961
+ padding-right: 30px;
962
+ }
963
+
964
+ /* Checkbox */
965
+ .b2b-cbx {
966
+ appearance: none; width: 16px; height: 16px;
967
+ border: 1.5px solid var(--border-strong); border-radius: 4px;
968
+ background: var(--surface);
969
+ display: inline-grid; place-content: center;
970
+ transition: background .12s, border-color .12s;
971
+ cursor: pointer; flex-shrink: 0;
972
+ }
973
+ .b2b-cbx:hover { border-color: var(--fg-subtle); }
974
+ .b2b-cbx:checked { background: var(--primary-color); border-color: var(--primary-color); }
975
+ .b2b-cbx:checked::after {
976
+ content: "";
977
+ width: 10px; height: 10px;
978
+ background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>") center/contain no-repeat;
979
+ }
980
+ .b2b-cbx:indeterminate { background: var(--primary-color); border-color: var(--primary-color); }
981
+ .b2b-cbx:indeterminate::after {
982
+ content: ""; width: 8px; height: 2px; background: #fff; border-radius: 1px;
983
+ }
984
+
985
+ /* Switch */
986
+ .b2b-switch {
987
+ position: relative; display: inline-block; width: 32px; height: 18px;
988
+ flex-shrink: 0;
989
+ }
990
+ .b2b-switch input { display: none; }
991
+ .b2b-switch i {
992
+ position: absolute; inset: 0;
993
+ background: var(--border-strong); border-radius: 999px;
994
+ transition: background .15s;
995
+ }
996
+ .b2b-switch i::before {
997
+ content: ""; position: absolute;
998
+ top: 2px; left: 2px; width: 14px; height: 14px;
999
+ background: #fff; border-radius: 50%;
1000
+ box-shadow: 0 1px 2px rgba(0,0,0,.2);
1001
+ transition: transform .15s;
1002
+ }
1003
+ .b2b-switch input:checked + i { background: var(--primary-color); }
1004
+ .b2b-switch input:checked + i::before { transform: translateX(14px); }
1005
+
1006
+ /* ============================================================
1007
+ Card / surface
1008
+ ============================================================ */
1009
+ .b2b-card {
1010
+ background: var(--surface);
1011
+ border: 1px solid var(--border-color);
1012
+ border-radius: var(--r-lg);
1013
+ box-shadow: var(--sh-1);
1014
+ }
1015
+ .b2b-card--clickable {
1016
+ display: block;
1017
+ cursor: pointer;
1018
+ transition: box-shadow 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
1019
+ }
1020
+ .b2b-card--clickable:hover {
1021
+ border-color: var(--border-strong, var(--fg-muted));
1022
+ box-shadow: var(--sh-2, var(--sh-1));
1023
+ transform: translateY(-1px);
1024
+ }
1025
+ .b2b-card__head {
1026
+ padding: 14px 16px;
1027
+ border-bottom: 1px solid var(--border-subtle);
1028
+ display: flex; align-items: center; justify-content: space-between; gap: 12px;
1029
+ }
1030
+ .b2b-card__title { font-size: 14px; font-weight: 600; color: var(--fg); }
1031
+ .b2b-card__sub { font-size: 12px; color: var(--fg-muted); margin-top: 2px; }
1032
+ .b2b-card__body { padding: 16px; }
1033
+ .b2b-card__body--flush { padding: 0; }
1034
+ .b2b-card__foot {
1035
+ padding: 12px 16px; border-top: 1px solid var(--border-subtle);
1036
+ background: var(--surface-muted); border-radius: 0 0 var(--r-lg) var(--r-lg);
1037
+ display: flex; align-items: center; justify-content: space-between;
1038
+ }
1039
+
1040
+ /* ============================================================
1041
+ Badge / Pill / Status
1042
+ ============================================================ */
1043
+ .b2b-badge {
1044
+ display: inline-flex; align-items: center; gap: 4px;
1045
+ padding: 2px 8px;
1046
+ font-size: 11px; font-weight: 500;
1047
+ border-radius: var(--r-pill);
1048
+ background: var(--neutral-soft); color: var(--neutral-soft-fg);
1049
+ white-space: nowrap;
1050
+ line-height: 1.4;
1051
+ }
1052
+ .b2b-badge--success { background: var(--success-soft); color: var(--success-soft-fg); }
1053
+ .b2b-badge--warn { background: var(--warn-soft); color: var(--warn-soft-fg); }
1054
+ .b2b-badge--danger { background: var(--danger-soft); color: var(--danger-soft-fg); }
1055
+ .b2b-badge--info { background: var(--info-soft); color: var(--info-soft-fg); }
1056
+ .b2b-badge--outline {
1057
+ background: transparent;
1058
+ border: 1px solid var(--border-strong);
1059
+ color: var(--fg-muted);
1060
+ }
1061
+ .b2b-badge--solid { background: var(--fg); color: #fff; }
1062
+ .b2b-badge--dot::before {
1063
+ content: ""; width: 6px; height: 6px; border-radius: 50%;
1064
+ background: currentColor; flex-shrink: 0;
1065
+ }
1066
+
1067
+ /* ============================================================
1068
+ Table
1069
+ ============================================================ */
1070
+ .b2b-tbl { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
1071
+ .b2b-tbl thead th {
1072
+ position: sticky; top: 0;
1073
+ text-align: left;
1074
+ font-size: 11px;
1075
+ font-weight: 600;
1076
+ text-transform: uppercase;
1077
+ letter-spacing: 0.04em;
1078
+ color: var(--fg-muted);
1079
+ background: var(--surface-muted);
1080
+ padding: 10px 12px;
1081
+ border-bottom: 1px solid var(--border-color);
1082
+ height: 36px;
1083
+ white-space: nowrap;
1084
+ z-index: 2;
1085
+ }
1086
+ .b2b-tbl tbody td {
1087
+ padding: 0 12px;
1088
+ height: var(--row-h);
1089
+ border-bottom: 1px solid var(--border-subtle);
1090
+ color: var(--fg);
1091
+ vertical-align: middle;
1092
+ }
1093
+ .b2b-tbl tbody tr { transition: background .08s; }
1094
+ .b2b-tbl tbody tr:hover { background: var(--surface-muted); }
1095
+ .b2b-tbl tbody tr.is-selected { background: var(--primary-soft); }
1096
+ .b2b-tbl tbody tr.is-selected:hover {
1097
+ background: hsl(var(--accent-h) calc(var(--accent-s) - 10%) 92%);
1098
+ }
1099
+ .b2b-tbl tbody tr:last-child td { border-bottom: none; }
1100
+ .b2b-tbl tbody td.num { text-align: right; font-variant-numeric: tabular-nums; }
1101
+ .b2b-tbl thead th.num { text-align: right; }
1102
+ .b2b-tbl tbody td.actions { width: 1%; white-space: nowrap; }
1103
+ .b2b-tbl .col-cb { width: 32px; padding-left: 14px; padding-right: 0; }
1104
+ .b2b-tbl tbody tr.is-clickable { cursor: pointer; }
1105
+
1106
+ /* Empty state */
1107
+ .b2b-empty {
1108
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
1109
+ padding: 48px 16px; text-align: center; color: var(--fg-muted);
1110
+ gap: 10px;
1111
+ }
1112
+ .b2b-empty__icon {
1113
+ width: 48px; height: 48px; border-radius: 50%;
1114
+ background: var(--surface-sunken);
1115
+ display: grid; place-items: center;
1116
+ color: var(--fg-subtle);
1117
+ }
1118
+ .b2b-empty__title { font-size: 14px; font-weight: 600; color: var(--fg); }
1119
+ .b2b-empty__sub { font-size: 13px; color: var(--fg-muted); max-width: 360px; }
1120
+
1121
+ /* ============================================================
1122
+ Tabs
1123
+ ============================================================ */
1124
+ .b2b-tabs-scroll {
1125
+ max-width: 100%;
1126
+ overflow-x: auto;
1127
+ overflow-y: hidden;
1128
+ -webkit-overflow-scrolling: touch;
1129
+ scrollbar-width: none;
1130
+ }
1131
+ .b2b-tabs-scroll::-webkit-scrollbar {
1132
+ display: none;
1133
+ }
1134
+ .b2b-tabs {
1135
+ display: flex; gap: 4px;
1136
+ border-bottom: 1px solid var(--border-color);
1137
+ padding: 0 4px;
1138
+ width: max-content;
1139
+ min-width: 100%;
1140
+ }
1141
+ .b2b-tab {
1142
+ background: transparent; border: none;
1143
+ padding: 10px 12px;
1144
+ font-size: 13px; font-weight: 500;
1145
+ color: var(--fg-muted);
1146
+ border-bottom: 2px solid transparent;
1147
+ display: inline-flex; align-items: center; gap: 6px;
1148
+ flex-shrink: 0;
1149
+ margin-bottom: -1px;
1150
+ cursor: pointer;
1151
+ font-family: inherit;
1152
+ transition: color .12s, border-color .12s;
1153
+ }
1154
+ .b2b-tab:hover { color: var(--fg); }
1155
+ .b2b-tab.is-active { color: var(--fg); border-bottom-color: var(--primary-color); }
1156
+ .b2b-tab .b2b-badge { font-size: 10px; padding: 0 6px; }
1157
+
1158
+ /* ============================================================
1159
+ Filterbar / chips
1160
+ ============================================================ */
1161
+ .b2b-filterbar {
1162
+ display: flex; align-items: center; gap: 8px;
1163
+ padding: 10px 12px;
1164
+ background: var(--surface);
1165
+ border-bottom: 1px solid var(--border-subtle);
1166
+ flex-wrap: wrap;
1167
+ }
1168
+ .b2b-filterbar__search {
1169
+ flex: 1; min-width: 220px; max-width: 360px;
1170
+ }
1171
+ .b2b-filterchip {
1172
+ display: inline-flex; align-items: center; gap: 6px;
1173
+ padding: 0 10px;
1174
+ height: 30px;
1175
+ border-radius: var(--r-sm);
1176
+ border: 1px dashed var(--border-strong);
1177
+ background: transparent;
1178
+ font-size: 12px; color: var(--fg-muted);
1179
+ white-space: nowrap;
1180
+ cursor: pointer;
1181
+ font-family: inherit;
1182
+ transition: all .12s;
1183
+ }
1184
+ .b2b-filterchip:hover {
1185
+ border-color: var(--fg-subtle); color: var(--fg);
1186
+ border-style: solid;
1187
+ }
1188
+ .b2b-filterchip.is-on {
1189
+ background: var(--primary-soft); color: var(--primary-soft-fg);
1190
+ border: 1px solid hsl(var(--accent-h) 30% 80%);
1191
+ }
1192
+ .b2b-filterchip svg { width: 12px; height: 12px; }
1193
+
1194
+ /* ============================================================
1195
+ Bulk action bar
1196
+ ============================================================ */
1197
+ .b2b-bulkbar {
1198
+ background: var(--fg);
1199
+ color: #fff;
1200
+ border-radius: var(--r-md);
1201
+ padding: 8px 12px 8px 16px;
1202
+ display: flex; align-items: center; gap: 12px;
1203
+ font-size: 13px;
1204
+ margin: 0 12px 12px;
1205
+ box-shadow: var(--sh-2);
1206
+ }
1207
+ .b2b-bulkbar .count { font-weight: 500; }
1208
+ .b2b-bulkbar .actions { margin-left: auto; display: flex; gap: 6px; }
1209
+ .b2b-bulkbar .b2b-btn {
1210
+ height: 28px; font-size: 12px;
1211
+ background: rgba(255,255,255,0.10);
1212
+ border-color: rgba(255,255,255,0.15);
1213
+ color: #fff;
1214
+ }
1215
+ .b2b-bulkbar .b2b-btn:hover { background: rgba(255,255,255,0.18); }
1216
+ .b2b-bulkbar .b2b-btn--danger {
1217
+ background: rgba(255,255,255,0.10);
1218
+ color: #ffb4ab;
1219
+ border-color: rgba(255,255,255,0.15);
1220
+ }
1221
+
1222
+ /* ============================================================
1223
+ Save bar (sticky)
1224
+ ============================================================ */
1225
+ .b2b-savebar {
1226
+ position: sticky; bottom: 16px;
1227
+ margin: 16px 0 0;
1228
+ padding: 10px 16px;
1229
+ background: #1f2225;
1230
+ color: #fff;
1231
+ border-radius: var(--r-lg);
1232
+ display: flex; align-items: center; gap: 12px;
1233
+ box-shadow: var(--sh-pop);
1234
+ z-index: 10;
1235
+ animation: b2b-slide-up .2s ease both;
1236
+ }
1237
+ .b2b-savebar__msg { font-size: 13px; flex: 1; }
1238
+ .b2b-savebar__msg b { color: #fff; }
1239
+ .b2b-savebar .b2b-btn--ghost { color: #d7d9dc; }
1240
+ .b2b-savebar .b2b-btn--ghost:hover { background: rgba(255,255,255,.06); color: #fff; }
1241
+ @keyframes b2b-slide-up {
1242
+ from { transform: translateY(8px); opacity: 0; }
1243
+ to { transform: translateY(0); opacity: 1; }
1244
+ }
1245
+
1246
+ /* ============================================================
1247
+ Drawer / Modal / Palette
1248
+ ============================================================ */
1249
+ .b2b-scrim {
1250
+ position: fixed; inset: 0;
1251
+ background: rgba(13,16,19,0.45);
1252
+ z-index: 50;
1253
+ animation: b2b-fade-in .18s ease both;
1254
+ }
1255
+ @keyframes b2b-fade-in { from { opacity: 0 } to { opacity: 1 } }
1256
+
1257
+ .b2b-drawer {
1258
+ position: fixed; right: 0; top: 0; bottom: 0;
1259
+ width: min(560px, 90vw);
1260
+ background: var(--surface);
1261
+ z-index: 60;
1262
+ display: flex; flex-direction: column;
1263
+ box-shadow: var(--sh-pop);
1264
+ animation: b2b-slide-left .22s ease both;
1265
+ }
1266
+ .b2b-drawer--wide { width: min(720px, 92vw); }
1267
+ @keyframes b2b-slide-left {
1268
+ from { transform: translateX(20px); opacity: 0 }
1269
+ to { transform: translateX(0); opacity: 1 }
1270
+ }
1271
+ .b2b-drawer__head {
1272
+ padding: 14px 18px;
1273
+ border-bottom: 1px solid var(--border-color);
1274
+ display: flex; align-items: center; gap: 10px;
1275
+ }
1276
+ .b2b-drawer__title { font-size: 15px; font-weight: 600; flex: 1; }
1277
+ .b2b-drawer__body { flex: 1; overflow-y: auto; padding: 18px; }
1278
+ .b2b-drawer__foot {
1279
+ padding: 12px 18px; border-top: 1px solid var(--border-color);
1280
+ display: flex; gap: 8px; justify-content: flex-end;
1281
+ background: var(--surface-muted);
1282
+ }
1283
+
1284
+ .b2b-palette {
1285
+ position: fixed; top: 12vh; left: 50%; transform: translateX(-50%);
1286
+ width: min(620px, 92vw);
1287
+ background: var(--surface);
1288
+ border-radius: var(--r-xl);
1289
+ box-shadow: var(--sh-pop);
1290
+ z-index: 60;
1291
+ overflow: hidden;
1292
+ animation: b2b-pop-in .14s ease both;
1293
+ display: flex; flex-direction: column;
1294
+ max-height: 70vh;
1295
+ }
1296
+ @keyframes b2b-pop-in {
1297
+ from { transform: translate(-50%, -4px) scale(0.96); opacity: 0 }
1298
+ to { transform: translate(-50%, 0) scale(1); opacity: 1 }
1299
+ }
1300
+ .b2b-palette__input {
1301
+ display: flex; align-items: center; gap: 10px;
1302
+ padding: 14px 18px;
1303
+ border-bottom: 1px solid var(--border-color);
1304
+ }
1305
+ .b2b-palette__input input {
1306
+ flex: 1; border: none; outline: none; background: transparent;
1307
+ font-size: 15px; color: var(--fg);
1308
+ font-family: inherit;
1309
+ }
1310
+ .b2b-palette__list { overflow-y: auto; padding: 8px; }
1311
+ .b2b-palette__group {
1312
+ font-size: 10px; font-weight: 600; color: var(--fg-muted);
1313
+ text-transform: uppercase; letter-spacing: 0.06em;
1314
+ padding: 8px 10px 4px;
1315
+ }
1316
+ .b2b-palette__item {
1317
+ display: flex; align-items: center; gap: 10px;
1318
+ padding: 8px 10px;
1319
+ border-radius: var(--r-sm);
1320
+ font-size: 13px; cursor: pointer;
1321
+ }
1322
+ .b2b-palette__item:hover, .b2b-palette__item.is-cur { background: var(--surface-sunken); }
1323
+ .b2b-palette__item svg { width: 16px; height: 16px; color: var(--fg-muted); }
1324
+ .b2b-palette__item .meta { color: var(--fg-muted); font-size: 11px; margin-left: auto; }
1325
+ .b2b-kbd-sm {
1326
+ display: inline-block; padding: 1px 5px;
1327
+ font-size: 10px; font-family: var(--ff-mono);
1328
+ background: var(--surface-sunken);
1329
+ border: 1px solid var(--border-color);
1330
+ border-radius: 3px;
1331
+ color: var(--fg-muted);
1332
+ }
1333
+
1334
+ /* ============================================================
1335
+ Stock pill
1336
+ ============================================================ */
1337
+ .b2b-stock-pill {
1338
+ display: inline-flex; align-items: center; gap: 6px;
1339
+ font-variant-numeric: tabular-nums;
1340
+ font-weight: 500;
1341
+ }
1342
+ .b2b-stock-pill .bar {
1343
+ width: 56px; height: 4px;
1344
+ background: var(--surface-sunken); border-radius: 2px; overflow: hidden;
1345
+ }
1346
+ .b2b-stock-pill .bar > i {
1347
+ display: block; height: 100%;
1348
+ background: var(--success); border-radius: 2px;
1349
+ }
1350
+ .b2b-stock-pill.lo .bar > i { background: var(--warn); }
1351
+ .b2b-stock-pill.zero .bar > i { background: var(--danger); }
1352
+
1353
+ /* ============================================================
1354
+ Variant matrix
1355
+ ============================================================ */
1356
+ .b2b-matrix-wrap { overflow: auto; }
1357
+ .b2b-matrix {
1358
+ width: 100%;
1359
+ border-collapse: separate;
1360
+ border-spacing: 0;
1361
+ font-size: 13px;
1362
+ }
1363
+ .b2b-matrix th, .b2b-matrix td {
1364
+ border-right: 1px solid var(--border-subtle);
1365
+ border-bottom: 1px solid var(--border-subtle);
1366
+ padding: 0;
1367
+ background: var(--surface);
1368
+ vertical-align: middle;
1369
+ }
1370
+ .b2b-matrix th {
1371
+ background: var(--surface-muted);
1372
+ font-size: 11px;
1373
+ font-weight: 600;
1374
+ color: var(--fg-muted);
1375
+ text-transform: uppercase;
1376
+ letter-spacing: 0.04em;
1377
+ padding: 8px 12px;
1378
+ white-space: nowrap;
1379
+ }
1380
+ .b2b-matrix th.row-h, .b2b-matrix td.row-h {
1381
+ background: var(--surface-sunken);
1382
+ position: sticky; left: 0; z-index: 1;
1383
+ text-align: left;
1384
+ }
1385
+ .b2b-matrix td.row-h { padding: 10px 12px; font-weight: 500; }
1386
+ .b2b-matrix .cell-input {
1387
+ width: 100%; height: 36px;
1388
+ border: none; outline: none;
1389
+ padding: 0 10px;
1390
+ background: transparent;
1391
+ font-variant-numeric: tabular-nums;
1392
+ font-size: 13px;
1393
+ font-family: inherit;
1394
+ }
1395
+ .b2b-matrix .cell-input:focus {
1396
+ background: var(--primary-soft);
1397
+ box-shadow: inset 0 0 0 2px var(--primary-color);
1398
+ }
1399
+ .b2b-matrix .cell--num { text-align: right; }
1400
+ .b2b-matrix tr:hover td { background: var(--surface-muted); }
1401
+ .b2b-matrix tr:hover td.row-h { background: var(--surface-sunken); }
1402
+
1403
+ /* ============================================================
1404
+ Mini list / mini row (activity feed, alerts, etc.)
1405
+ ============================================================ */
1406
+ .b2b-minilist { display: flex; flex-direction: column; gap: 1px; }
1407
+ .b2b-minirow {
1408
+ display: flex; align-items: center; gap: 12px;
1409
+ padding: 10px 12px;
1410
+ border-radius: var(--r-sm);
1411
+ transition: background .1s;
1412
+ }
1413
+ .b2b-minirow:hover { background: var(--surface-sunken); }
1414
+
1415
+ /* ============================================================
1416
+ Locale strip (EN/PL toggle)
1417
+ ============================================================ */
1418
+ .b2b-locale-strip {
1419
+ display: inline-flex; align-items: center;
1420
+ background: var(--surface-sunken);
1421
+ padding: 2px;
1422
+ border-radius: var(--r-sm);
1423
+ gap: 0;
1424
+ }
1425
+ .b2b-locale-strip button {
1426
+ border: none;
1427
+ background: transparent;
1428
+ font-family: inherit;
1429
+ font-size: 12px; font-weight: 500;
1430
+ color: var(--fg-muted);
1431
+ padding: 4px 10px;
1432
+ border-radius: var(--r-xs);
1433
+ display: inline-flex; align-items: center; gap: 6px;
1434
+ cursor: pointer;
1435
+ }
1436
+ .b2b-locale-strip button.is-active {
1437
+ background: var(--surface);
1438
+ color: var(--fg);
1439
+ box-shadow: var(--sh-1), 0 0 0 1px var(--border-color);
1440
+ }
1441
+
1442
+ /* ============================================================
1443
+ Misc helpers (used by in-scope pages)
1444
+ ============================================================ */
1445
+ .b2b-row { display: flex; align-items: center; gap: 12px; }
1446
+ .b2b-col { display: flex; flex-direction: column; gap: 8px; }
1447
+ .b2b-grow { flex: 1; }
1448
+ .b2b-muted { color: var(--fg-muted); }
1449
+ .b2b-mono { font-family: var(--ff-mono); }
1450
+ .b2b-tabular { font-variant-numeric: tabular-nums; }
1451
+ .b2b-hr { height: 1px; background: var(--border-subtle); border: none; margin: 0; }
1452
+
1453
+ .b2b-thumb {
1454
+ border-radius: var(--r-sm);
1455
+ flex-shrink: 0;
1456
+ overflow: hidden;
1457
+ position: relative;
1458
+ display: grid; place-items: center;
1459
+ color: rgba(255,255,255,0.92);
1460
+ font-weight: 600;
1461
+ box-shadow: inset 0 0 0 1px rgba(0,0,0,0.06);
1462
+ }
1463
+
1464
+ .b2b-tag-pill {
1465
+ display: inline-flex; align-items: center; gap: 6px;
1466
+ background: var(--surface-sunken);
1467
+ border: 1px solid var(--border-color);
1468
+ border-radius: var(--r-pill);
1469
+ padding: 2px 8px 2px 4px;
1470
+ font-size: 11px;
1471
+ color: var(--fg);
1472
+ }
1473
+ .b2b-tag-pill .x {
1474
+ width: 14px; height: 14px; border-radius: 50%;
1475
+ display: grid; place-items: center;
1476
+ cursor: pointer; color: var(--fg-muted);
1477
+ background: transparent; border: none;
1478
+ }
1479
+ .b2b-tag-pill .x:hover { background: var(--border-color); color: var(--fg); }
1480
+
1481
+ /* ============================================================
1482
+ Mobile admin shell (feature 029)
1483
+ ============================================================ */
1484
+ .b2b-app-layout {
1485
+ display: grid;
1486
+ min-height: 100vh;
1487
+ }
1488
+
1489
+ @media (min-width: 1024px) {
1490
+ .b2b-app-layout--rail {
1491
+ grid-template-columns: 64px 1fr;
1492
+ }
1493
+ .b2b-app-layout--expanded {
1494
+ grid-template-columns: 248px 1fr;
1495
+ }
1496
+ }
1497
+
1498
+ @media (max-width: 1023px) {
1499
+ .b2b-app-layout {
1500
+ grid-template-columns: 1fr;
1501
+ }
1502
+ .b2b-sidebar {
1503
+ position: fixed;
1504
+ inset: 0 auto 0 0;
1505
+ z-index: 50;
1506
+ width: min(280px, 85vw);
1507
+ transform: translateX(-100%);
1508
+ transition: transform 0.2s ease;
1509
+ box-shadow: none;
1510
+ }
1511
+ .b2b-sidebar.b2b-sidebar--drawer-open {
1512
+ transform: translateX(0);
1513
+ box-shadow: 4px 0 24px rgba(0, 0, 0, 0.25);
1514
+ }
1515
+ .b2b-nav-drawer-backdrop {
1516
+ position: fixed;
1517
+ inset: 0;
1518
+ z-index: 40;
1519
+ background: rgba(0, 0, 0, 0.45);
1520
+ border: none;
1521
+ padding: 0;
1522
+ cursor: pointer;
1523
+ }
1524
+ .b2b-topbar__menu-btn {
1525
+ width: 44px;
1526
+ height: 44px;
1527
+ flex-shrink: 0;
1528
+ border-radius: var(--r-sm);
1529
+ border: 1px solid transparent;
1530
+ background: transparent;
1531
+ color: var(--fg-muted);
1532
+ display: grid;
1533
+ place-items: center;
1534
+ cursor: pointer;
1535
+ }
1536
+ .b2b-topbar__menu-btn:hover {
1537
+ background: var(--surface-sunken);
1538
+ color: var(--fg);
1539
+ }
1540
+ .b2b-topbar {
1541
+ padding: 0 12px;
1542
+ gap: 8px;
1543
+ }
1544
+ .b2b-topbar__crumbs {
1545
+ overflow: hidden;
1546
+ text-overflow: ellipsis;
1547
+ white-space: nowrap;
1548
+ }
1549
+ .b2b-main {
1550
+ padding: 16px 16px 48px;
1551
+ }
1552
+ .b2b-page-head {
1553
+ flex-direction: column;
1554
+ align-items: stretch;
1555
+ gap: 12px;
1556
+ margin-bottom: 16px;
1557
+ }
1558
+ .b2b-page-head__title {
1559
+ font-size: 18px;
1560
+ flex-wrap: wrap;
1561
+ gap: 8px;
1562
+ }
1563
+ .b2b-page-head__actions {
1564
+ margin-left: 0;
1565
+ width: 100%;
1566
+ flex-wrap: wrap;
1567
+ }
1568
+ .b2b-page:has(.b2b-sticky-form-actions) {
1569
+ padding-bottom: calc(88px + env(safe-area-inset-bottom, 0px));
1570
+ }
1571
+ .b2b-tabs-scroll {
1572
+ margin: 0 -4px;
1573
+ padding: 0 4px;
1574
+ mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
1575
+ }
1576
+ .b2b-tab {
1577
+ min-height: 44px;
1578
+ padding: 10px 14px;
1579
+ }
1580
+ .b2b-topbar__actions {
1581
+ flex-shrink: 0;
1582
+ gap: 4px;
1583
+ }
1584
+ .b2b-topbar__hide-mobile {
1585
+ display: none !important;
1586
+ }
1587
+ .b2b-lang-picker__label {
1588
+ display: none;
1589
+ }
1590
+ .b2b-main button.b2b-btn,
1591
+ .b2b-main .b2b-topbar__icon-btn,
1592
+ .b2b-main button[type="submit"],
1593
+ .b2b-main a.b2b-btn {
1594
+ min-height: 44px;
1595
+ min-width: 44px;
1596
+ }
1597
+ /* Combine both classes so this beats the unconditional `.b2b-sticky-form-actions`
1598
+ flex rule below (equal specificity would otherwise let the later flex rule win,
1599
+ stacking every button onto its own row via flex-wrap + width:100%). */
1600
+ .b2b-page-head__actions.b2b-sticky-form-actions {
1601
+ display: grid;
1602
+ grid-template-columns: repeat(3, minmax(0, 1fr));
1603
+ gap: 8px;
1604
+ justify-items: stretch;
1605
+ }
1606
+ .b2b-page-head__actions.b2b-sticky-form-actions .b2b-btn {
1607
+ min-width: 0;
1608
+ width: 100%;
1609
+ white-space: nowrap;
1610
+ overflow: hidden;
1611
+ text-overflow: ellipsis;
1612
+ }
1613
+ /* Primary (Save) spans the full width on its own row — also keeps it full-width
1614
+ when it's the only button (new-product create view). */
1615
+ .b2b-page-head__actions.b2b-sticky-form-actions .b2b-btn--primary {
1616
+ grid-column: 1 / -1;
1617
+ }
1618
+ .b2b-palette {
1619
+ top: 8vh;
1620
+ left: 12px;
1621
+ right: 12px;
1622
+ width: auto;
1623
+ max-width: none;
1624
+ transform: none;
1625
+ animation: b2b-fade-in .14s ease both;
1626
+ }
1627
+ @keyframes b2b-pop-in-mobile {
1628
+ from { opacity: 0; transform: scale(0.98); }
1629
+ to { opacity: 1; transform: scale(1); }
1630
+ }
1631
+ .b2b-palette { animation-name: b2b-pop-in-mobile; }
1632
+ .b2b-main .grid,
1633
+ .b2b-main [class*="grid-cols"]:not([class*="md:"]):not([class*="lg:"]) {
1634
+ grid-template-columns: 1fr !important;
1635
+ }
1636
+ .b2b-kpi-grid {
1637
+ display: grid !important;
1638
+ grid-template-columns: 1fr 1fr !important;
1639
+ }
1640
+ .b2b-home-dashboard-grid {
1641
+ grid-template-columns: 1fr !important;
1642
+ }
1643
+ .b2b-grid--cols-2 {
1644
+ grid-template-columns: 1fr !important;
1645
+ }
1646
+ .b2b-page .b2b-row:not(.b2b-kpi-grid) {
1647
+ flex-direction: column;
1648
+ align-items: stretch;
1649
+ }
1650
+ .b2b-page .b2b-row .b2b-field,
1651
+ .b2b-page .b2b-row select.b2b-field {
1652
+ max-width: none !important;
1653
+ width: 100%;
1654
+ }
1655
+ .b2b-impersonation-slot {
1656
+ flex-shrink: 0;
1657
+ }
1658
+ .b2b-reorder-desktop-only {
1659
+ display: none !important;
1660
+ }
1661
+ .b2b-touch-reorder {
1662
+ display: flex;
1663
+ }
1664
+ .b2b-table,
1665
+ .b2b-table-wrap,
1666
+ .b2b-tbl {
1667
+ display: block;
1668
+ overflow-x: auto;
1669
+ -webkit-overflow-scrolling: touch;
1670
+ max-width: 100%;
1671
+ }
1672
+ .puck-root,
1673
+ [class*='Puck'] {
1674
+ max-width: 100%;
1675
+ overflow-x: auto;
1676
+ }
1677
+ }
1678
+
1679
+ .b2b-table-scroll {
1680
+ width: 100%;
1681
+ max-width: 100%;
1682
+ overflow-x: auto;
1683
+ -webkit-overflow-scrolling: touch;
1684
+ border: 1px solid var(--border-color);
1685
+ border-radius: var(--r-md);
1686
+ }
1687
+ .b2b-table-scroll::after {
1688
+ content: '';
1689
+ display: block;
1690
+ height: 0;
1691
+ }
1692
+ @media (max-width: 1023px) {
1693
+ .b2b-table-scroll {
1694
+ background: linear-gradient(to right, var(--surface) 90%, rgba(255, 255, 255, 0));
1695
+ }
1696
+ }
1697
+
1698
+ .b2b-responsive-card {
1699
+ border: 1px solid var(--border-color);
1700
+ border-radius: var(--r-md);
1701
+ padding: 12px 14px;
1702
+ background: var(--surface);
1703
+ display: flex;
1704
+ flex-direction: column;
1705
+ gap: 8px;
1706
+ }
1707
+ .b2b-responsive-card__headline {
1708
+ font-weight: 600;
1709
+ font-size: 14px;
1710
+ color: var(--fg);
1711
+ display: flex;
1712
+ flex-wrap: wrap;
1713
+ gap: 8px;
1714
+ align-items: center;
1715
+ }
1716
+ .b2b-responsive-card__meta {
1717
+ font-size: 12px;
1718
+ color: var(--fg-muted);
1719
+ }
1720
+ .b2b-responsive-card__actions {
1721
+ display: flex;
1722
+ flex-wrap: wrap;
1723
+ gap: 8px;
1724
+ margin-top: 4px;
1725
+ }
1726
+ .b2b-responsive-card__actions .b2b-btn,
1727
+ .b2b-responsive-card__actions button {
1728
+ min-height: 44px;
1729
+ min-width: 44px;
1730
+ }
1731
+
1732
+ .b2b-sticky-form-actions {
1733
+ position: fixed;
1734
+ inset: auto 0 0 0;
1735
+ z-index: 30;
1736
+ display: flex;
1737
+ justify-content: flex-end;
1738
+ gap: 8px;
1739
+ padding: 12px 16px;
1740
+ padding-bottom: max(12px, env(safe-area-inset-bottom));
1741
+ border-top: 1px solid var(--border-color);
1742
+ background: color-mix(in srgb, var(--surface) 95%, transparent);
1743
+ backdrop-filter: blur(8px);
1744
+ }
1745
+ @media (min-width: 1024px) {
1746
+ .b2b-sticky-form-actions {
1747
+ position: static;
1748
+ border-top: none;
1749
+ padding: 0;
1750
+ background: transparent;
1751
+ backdrop-filter: none;
1752
+ }
1753
+ }
1754
+
1755
+ .b2b-touch-reorder {
1756
+ display: none;
1757
+ flex-direction: column;
1758
+ gap: 2px;
1759
+ }
1760
+ @media (max-width: 1023px) {
1761
+ .b2b-touch-reorder {
1762
+ display: inline-flex;
1763
+ }
1764
+ .b2b-reorder-desktop-only {
1765
+ display: none !important;
1766
+ }
1767
+ }
1768
+ @media (min-width: 1024px) {
1769
+ .b2b-reorder-desktop-only {
1770
+ display: inline-flex;
1771
+ }
1772
+ }
1773
+ .b2b-touch-reorder__btn {
1774
+ width: 44px;
1775
+ height: 44px;
1776
+ display: grid;
1777
+ place-items: center;
1778
+ border: 1px solid var(--border-color);
1779
+ border-radius: var(--r-sm);
1780
+ background: var(--surface);
1781
+ color: var(--fg-muted);
1782
+ cursor: pointer;
1783
+ }
1784
+ .b2b-touch-reorder__btn:disabled {
1785
+ opacity: 0.35;
1786
+ cursor: not-allowed;
1787
+ }
1788
+ .b2b-touch-reorder__btn:not(:disabled):hover {
1789
+ background: var(--surface-sunken);
1790
+ color: var(--fg);
1791
+ }
1792
+
1793
+ .pb-action-bar-handle {
1794
+ display: inline-flex;
1795
+ align-items: center;
1796
+ justify-content: center;
1797
+ cursor: grab;
1798
+ touch-action: none;
1799
+ }
1800
+
1801
+ .pb-action-bar-handle:active {
1802
+ cursor: grabbing;
1803
+ }
1804
+
1805
+ [data-puck-entry] [class*='DropZone-hitbox'] {
1806
+ height: 36px;
1807
+ bottom: -18px;
1808
+ z-index: 2;
1809
+ }
1810
+
1811
+ [data-puck-entry] [class*='DropZone--isDestination'] {
1812
+ outline: 2px solid var(--puck-color-azure-04, #0158ad) !important;
1813
+ outline-offset: 2px !important;
1814
+ }
1815
+
1816
+ [data-puck-entry] [data-dnd-placeholder] {
1817
+ opacity: 0.55 !important;
1818
+ min-height: 52px !important;
1819
+ border-radius: 6px !important;
1820
+ }
1821
+
1822
+ .pb-component-overlay {
1823
+ position: relative;
1824
+ width: 100%;
1825
+ height: 100%;
1826
+ }
1827
+
1828
+ .pb-component-overlay__label {
1829
+ position: absolute;
1830
+ top: 4px;
1831
+ left: 4px;
1832
+ z-index: 4;
1833
+ max-width: calc(100% - 8px);
1834
+ overflow: hidden;
1835
+ text-overflow: ellipsis;
1836
+ white-space: nowrap;
1837
+ padding: 2px 8px;
1838
+ border-radius: 4px;
1839
+ font-size: 10px;
1840
+ font-weight: 600;
1841
+ line-height: 1.4;
1842
+ letter-spacing: 0.02em;
1843
+ color: #fff;
1844
+ background: var(--puck-color-azure-04, #0158ad);
1845
+ pointer-events: none;
1846
+ box-shadow: 0 1px 2px rgb(0 0 0 / 12%);
1847
+ }
1848
+
1849
+ [data-puck-entry]:has([data-puck-dragging]) [class*='DropZone--isEnabled'] {
1850
+ outline: 1px dashed var(--puck-color-azure-06, #6499cf);
1851
+ outline-offset: 1px;
1852
+ }
1853
+
1854
+ .pb-outline-list {
1855
+ margin: 0;
1856
+ padding: 0;
1857
+ list-style: none;
1858
+ }
1859
+
1860
+ .pb-outline-list--root {
1861
+ padding: 4px 0;
1862
+ }
1863
+
1864
+ .pb-outline-empty {
1865
+ padding: 4px 8px;
1866
+ font-size: 12px;
1867
+ opacity: 0.6;
1868
+ }
1869
+
1870
+ .pb-outline-item {
1871
+ list-style: none;
1872
+ }
1873
+
1874
+ .pb-outline-item__row {
1875
+ display: flex;
1876
+ align-items: center;
1877
+ gap: 2px;
1878
+ border-left: 2px solid transparent;
1879
+ padding-left: calc(6px + (var(--pb-outline-depth, 0) * 12px));
1880
+ cursor: grab;
1881
+ user-select: none;
1882
+ }
1883
+
1884
+ .pb-outline-item--dragging .pb-outline-item__row {
1885
+ opacity: 0.45;
1886
+ cursor: grabbing;
1887
+ }
1888
+
1889
+ .pb-outline-item--drop-before::before {
1890
+ content: '';
1891
+ display: block;
1892
+ height: 2px;
1893
+ margin: 0 8px 2px calc(6px + (var(--pb-outline-depth, 0) * 12px));
1894
+ background: var(--puck-color-azure-04, #0158ad);
1895
+ border-radius: 1px;
1896
+ }
1897
+
1898
+ .pb-outline-item--selected .pb-outline-item__row {
1899
+ border-left-color: var(--puck-color-azure-04, #0158ad);
1900
+ background: var(--puck-color-grey-09, #e8eef3);
1901
+ }
1902
+
1903
+ .pb-outline-item__row:hover {
1904
+ background: var(--puck-color-grey-10, #f3f6f9);
1905
+ }
1906
+
1907
+ .pb-outline-item__drag {
1908
+ padding: 6px 2px;
1909
+ opacity: 0.45;
1910
+ pointer-events: none;
1911
+ }
1912
+
1913
+ .pb-outline-item__label,
1914
+ .pb-outline-item__action {
1915
+ display: inline-flex;
1916
+ align-items: center;
1917
+ border: none;
1918
+ background: transparent;
1919
+ cursor: pointer;
1920
+ color: inherit;
1921
+ }
1922
+
1923
+ .pb-outline-item__label {
1924
+ flex: 1;
1925
+ min-width: 0;
1926
+ gap: 6px;
1927
+ padding: 6px 4px;
1928
+ text-align: left;
1929
+ font-size: 13px;
1930
+ }
1931
+
1932
+ .pb-outline-item__icon {
1933
+ width: 14px;
1934
+ flex-shrink: 0;
1935
+ opacity: 0.7;
1936
+ font-size: 11px;
1937
+ }
1938
+
1939
+ .pb-outline-item__text {
1940
+ overflow: hidden;
1941
+ text-overflow: ellipsis;
1942
+ white-space: nowrap;
1943
+ font-variant-numeric: tabular-nums;
1944
+ }
1945
+
1946
+ .pb-outline-item--column .pb-outline-item__text {
1947
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1948
+ font-size: 12px;
1949
+ }
1950
+
1951
+ .pb-outline-item__actions {
1952
+ display: inline-flex;
1953
+ opacity: 0;
1954
+ transition: opacity 120ms ease;
1955
+ }
1956
+
1957
+ .pb-outline-item__row:hover .pb-outline-item__actions,
1958
+ .pb-outline-item--selected .pb-outline-item__actions {
1959
+ opacity: 1;
1960
+ }
1961
+
1962
+ .pb-outline-item__action {
1963
+ padding: 4px;
1964
+ border-radius: 4px;
1965
+ }
1966
+
1967
+ .pb-outline-item__action:hover {
1968
+ background: rgb(0 0 0 / 6%);
1969
+ }
1970
+
1971
+ .pb-row-action-bar__layout-anchor {
1972
+ display: inline-flex;
1973
+ }
1974
+
1975
+ .pb-row-action-flyout {
1976
+ min-width: 180px;
1977
+ padding: 6px;
1978
+ border: 1px solid #d9e0e7;
1979
+ border-radius: 8px;
1980
+ background: #ffffff;
1981
+ color: #0f172a;
1982
+ box-shadow:
1983
+ 0 10px 28px rgb(15 23 42 / 18%),
1984
+ 0 0 0 1px rgb(15 23 42 / 4%);
1985
+ }
1986
+
1987
+ .pb-row-action-flyout__heading {
1988
+ margin: 4px 8px;
1989
+ font-size: 10px;
1990
+ font-weight: 600;
1991
+ letter-spacing: 0.06em;
1992
+ text-transform: uppercase;
1993
+ color: #64748b;
1994
+ }
1995
+
1996
+ .pb-row-action-flyout__item {
1997
+ display: block;
1998
+ width: 100%;
1999
+ padding: 8px 10px;
2000
+ border: none;
2001
+ border-radius: 6px;
2002
+ background: #ffffff;
2003
+ color: #0f172a;
2004
+ text-align: left;
2005
+ font-size: 13px;
2006
+ cursor: pointer;
2007
+ }
2008
+
2009
+ .pb-row-action-flyout__item:hover {
2010
+ background: #f1f5f9;
2011
+ }
2012
+
2013
+ .pb-quick-tooltip-host {
2014
+ position: relative;
2015
+ display: inline-flex;
2016
+ }
2017
+
2018
+ .pb-quick-tooltip {
2019
+ position: absolute;
2020
+ bottom: calc(100% + 6px);
2021
+ left: 50%;
2022
+ z-index: 120;
2023
+ transform: translateX(-50%);
2024
+ padding: 4px 8px;
2025
+ border-radius: 4px;
2026
+ background: #1e293b;
2027
+ color: #ffffff;
2028
+ font-size: 11px;
2029
+ font-weight: 500;
2030
+ line-height: 1.3;
2031
+ white-space: nowrap;
2032
+ pointer-events: none;
2033
+ box-shadow: 0 4px 12px rgb(15 23 42 / 20%);
2034
+ }
2035
+
2036
+ /* Email builder — mail canvas width (600 / 320), not CMS breakpoints */
2037
+ .email-builder-pane [class*='PuckLayout-canvas'] {
2038
+ overflow-x: auto;
2039
+ }
2040
+
2041
+ .email-builder-pane[data-preview-width='600'] [class*='PuckLayout-canvas'] > div,
2042
+ .email-builder-pane[data-preview-width='320'] [class*='PuckLayout-canvas'] > div {
2043
+ margin-inline: auto;
2044
+ max-width: var(--email-preview-width, 600px);
2045
+ }
2046
+
2047
+ /* Only constrain the root canvas dropzone — nested Row/Column slots must stay fluid. */
2048
+ .email-builder-pane[data-preview-width='600'] [class*='PuckLayout-canvas'] > div > [class*='DropZone'],
2049
+ .email-builder-pane[data-preview-width='320'] [class*='PuckLayout-canvas'] > div > [class*='DropZone'] {
2050
+ max-width: var(--email-preview-width, 600px);
2051
+ }
2052
+
2053
+ .email-builder-pane [class*='DropZone'] [class*='DropZone'] {
2054
+ max-width: none;
2055
+ }
2056
+