@prenta/admin 2.6.1 → 2.8.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 (864) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/design-system/tokens.css +196 -85
  3. package/design-system/tokens.json +310 -85
  4. package/design-system/tokens.scss +163 -44
  5. package/design-system/tokens.tailwind.cjs +64 -1
  6. package/dist/AdminRoot.d.ts.map +1 -1
  7. package/dist/AdminRoot.js +43 -21
  8. package/dist/AdminRoot.js.map +1 -1
  9. package/dist/LoginRoot.d.ts.map +1 -1
  10. package/dist/LoginRoot.js +2 -1
  11. package/dist/LoginRoot.js.map +1 -1
  12. package/dist/__tests__/components/author-avatar.test.js +3 -17
  13. package/dist/__tests__/components/author-avatar.test.js.map +1 -1
  14. package/dist/__tests__/components/notification-bell.test.js +86 -15
  15. package/dist/__tests__/components/notification-bell.test.js.map +1 -1
  16. package/dist/__tests__/components/responsive-tiers.render.test.d.ts +2 -0
  17. package/dist/__tests__/components/responsive-tiers.render.test.d.ts.map +1 -0
  18. package/dist/__tests__/components/responsive-tiers.render.test.js +313 -0
  19. package/dist/__tests__/components/responsive-tiers.render.test.js.map +1 -0
  20. package/dist/__tests__/components/serp-preview.render.test.js +6 -3
  21. package/dist/__tests__/components/serp-preview.render.test.js.map +1 -1
  22. package/dist/__tests__/components/shell-primitives.render.test.d.ts +2 -0
  23. package/dist/__tests__/components/shell-primitives.render.test.d.ts.map +1 -0
  24. package/dist/__tests__/components/shell-primitives.render.test.js +716 -0
  25. package/dist/__tests__/components/shell-primitives.render.test.js.map +1 -0
  26. package/dist/__tests__/components/theme-provider-accent.test.js +49 -7
  27. package/dist/__tests__/components/theme-provider-accent.test.js.map +1 -1
  28. package/dist/__tests__/components/toggle.test.js +10 -3
  29. package/dist/__tests__/components/toggle.test.js.map +1 -1
  30. package/dist/__tests__/components/ui-primitives.test.js +3 -7
  31. package/dist/__tests__/components/ui-primitives.test.js.map +1 -1
  32. package/dist/__tests__/layout/build-nav-items.test.js +1 -1
  33. package/dist/__tests__/layout/build-nav-items.test.js.map +1 -1
  34. package/dist/__tests__/layout/shell-nav.render.test.d.ts +2 -0
  35. package/dist/__tests__/layout/shell-nav.render.test.d.ts.map +1 -0
  36. package/dist/__tests__/layout/shell-nav.render.test.js +736 -0
  37. package/dist/__tests__/layout/shell-nav.render.test.js.map +1 -0
  38. package/dist/__tests__/layout/sidebar-forms-submenu.render.test.js +8 -4
  39. package/dist/__tests__/layout/sidebar-forms-submenu.render.test.js.map +1 -1
  40. package/dist/__tests__/layout/sidebar-groups.render.test.d.ts +2 -0
  41. package/dist/__tests__/layout/sidebar-groups.render.test.d.ts.map +1 -0
  42. package/dist/__tests__/layout/sidebar-groups.render.test.js +56 -0
  43. package/dist/__tests__/layout/sidebar-groups.render.test.js.map +1 -0
  44. package/dist/__tests__/layout/sidebar-menus.render.test.d.ts +2 -0
  45. package/dist/__tests__/layout/sidebar-menus.render.test.d.ts.map +1 -0
  46. package/dist/__tests__/layout/sidebar-menus.render.test.js +82 -0
  47. package/dist/__tests__/layout/sidebar-menus.render.test.js.map +1 -0
  48. package/dist/__tests__/layout/sidebar-plugin-nav.test.js +1 -1
  49. package/dist/__tests__/layout/sidebar-plugin-nav.test.js.map +1 -1
  50. package/dist/__tests__/layout/sidebar-posts.test.js +48 -38
  51. package/dist/__tests__/layout/sidebar-posts.test.js.map +1 -1
  52. package/dist/__tests__/layout/sidebar-submenu.render.test.js +26 -10
  53. package/dist/__tests__/layout/sidebar-submenu.render.test.js.map +1 -1
  54. package/dist/__tests__/layout/topbar.render.test.d.ts +2 -0
  55. package/dist/__tests__/layout/topbar.render.test.d.ts.map +1 -0
  56. package/dist/__tests__/layout/topbar.render.test.js +406 -0
  57. package/dist/__tests__/layout/topbar.render.test.js.map +1 -0
  58. package/dist/__tests__/lib/api.test.js +2 -0
  59. package/dist/__tests__/lib/api.test.js.map +1 -1
  60. package/dist/__tests__/lib/batch-wizard.test.d.ts +2 -0
  61. package/dist/__tests__/lib/batch-wizard.test.d.ts.map +1 -0
  62. package/dist/__tests__/lib/batch-wizard.test.js +144 -0
  63. package/dist/__tests__/lib/batch-wizard.test.js.map +1 -0
  64. package/dist/__tests__/lib/job-drawer.test.d.ts +2 -0
  65. package/dist/__tests__/lib/job-drawer.test.d.ts.map +1 -0
  66. package/dist/__tests__/lib/job-drawer.test.js +395 -0
  67. package/dist/__tests__/lib/job-drawer.test.js.map +1 -0
  68. package/dist/__tests__/lib/job-view.test.d.ts +2 -0
  69. package/dist/__tests__/lib/job-view.test.d.ts.map +1 -0
  70. package/dist/__tests__/lib/job-view.test.js +484 -0
  71. package/dist/__tests__/lib/job-view.test.js.map +1 -0
  72. package/dist/__tests__/lib/jobs-service.test.d.ts +2 -0
  73. package/dist/__tests__/lib/jobs-service.test.d.ts.map +1 -0
  74. package/dist/__tests__/lib/jobs-service.test.js +142 -0
  75. package/dist/__tests__/lib/jobs-service.test.js.map +1 -0
  76. package/dist/__tests__/router/admin-route-order.test.d.ts +2 -0
  77. package/dist/__tests__/router/admin-route-order.test.d.ts.map +1 -0
  78. package/dist/__tests__/router/admin-route-order.test.js +36 -0
  79. package/dist/__tests__/router/admin-route-order.test.js.map +1 -0
  80. package/dist/__tests__/styles/ai-gradient-contrast.test.d.ts +2 -0
  81. package/dist/__tests__/styles/ai-gradient-contrast.test.d.ts.map +1 -0
  82. package/dist/__tests__/styles/ai-gradient-contrast.test.js +110 -0
  83. package/dist/__tests__/styles/ai-gradient-contrast.test.js.map +1 -0
  84. package/dist/__tests__/styles/breakpoint-order.test.d.ts +2 -0
  85. package/dist/__tests__/styles/breakpoint-order.test.d.ts.map +1 -0
  86. package/dist/__tests__/styles/breakpoint-order.test.js +52 -0
  87. package/dist/__tests__/styles/breakpoint-order.test.js.map +1 -0
  88. package/dist/__tests__/styles/responsive-layer.test.js +303 -12
  89. package/dist/__tests__/styles/responsive-layer.test.js.map +1 -1
  90. package/dist/__tests__/styles/tailwind-preset.test.d.ts +2 -0
  91. package/dist/__tests__/styles/tailwind-preset.test.d.ts.map +1 -0
  92. package/dist/__tests__/styles/tailwind-preset.test.js +147 -0
  93. package/dist/__tests__/styles/tailwind-preset.test.js.map +1 -0
  94. package/dist/__tests__/styles/theme-token-scope.test.js +9 -3
  95. package/dist/__tests__/styles/theme-token-scope.test.js.map +1 -1
  96. package/dist/__tests__/styles/tiers.test.d.ts +2 -0
  97. package/dist/__tests__/styles/tiers.test.d.ts.map +1 -0
  98. package/dist/__tests__/styles/tiers.test.js +121 -0
  99. package/dist/__tests__/styles/tiers.test.js.map +1 -0
  100. package/dist/__tests__/styles/tokens-drift.test.js +57 -6
  101. package/dist/__tests__/styles/tokens-drift.test.js.map +1 -1
  102. package/dist/__tests__/views/admin-lazy-route.render.test.js +27 -1
  103. package/dist/__tests__/views/admin-lazy-route.render.test.js.map +1 -1
  104. package/dist/__tests__/views/ai-settings.render.test.js +4 -4
  105. package/dist/__tests__/views/appearance-chrome.render.test.d.ts +2 -0
  106. package/dist/__tests__/views/appearance-chrome.render.test.d.ts.map +1 -0
  107. package/dist/__tests__/views/appearance-chrome.render.test.js +688 -0
  108. package/dist/__tests__/views/appearance-chrome.render.test.js.map +1 -0
  109. package/dist/__tests__/views/appearance-menus-route.render.test.d.ts +2 -0
  110. package/dist/__tests__/views/appearance-menus-route.render.test.d.ts.map +1 -0
  111. package/dist/__tests__/views/appearance-menus-route.render.test.js +50 -0
  112. package/dist/__tests__/views/appearance-menus-route.render.test.js.map +1 -0
  113. package/dist/__tests__/views/appearance-settings.render.test.js +8 -6
  114. package/dist/__tests__/views/appearance-settings.render.test.js.map +1 -1
  115. package/dist/__tests__/views/appearance-theme-provider.render.test.d.ts +2 -0
  116. package/dist/__tests__/views/appearance-theme-provider.render.test.d.ts.map +1 -0
  117. package/dist/__tests__/views/appearance-theme-provider.render.test.js +286 -0
  118. package/dist/__tests__/views/appearance-theme-provider.render.test.js.map +1 -0
  119. package/dist/__tests__/views/dashboard.test.js +37 -0
  120. package/dist/__tests__/views/dashboard.test.js.map +1 -1
  121. package/dist/__tests__/views/document-edit-navigation.render.test.d.ts +2 -0
  122. package/dist/__tests__/views/document-edit-navigation.render.test.d.ts.map +1 -0
  123. package/dist/__tests__/views/document-edit-navigation.render.test.js +101 -0
  124. package/dist/__tests__/views/document-edit-navigation.render.test.js.map +1 -0
  125. package/dist/__tests__/views/document-edit-routes.render.test.d.ts +2 -0
  126. package/dist/__tests__/views/document-edit-routes.render.test.d.ts.map +1 -0
  127. package/dist/__tests__/views/document-edit-routes.render.test.js +113 -0
  128. package/dist/__tests__/views/document-edit-routes.render.test.js.map +1 -0
  129. package/dist/__tests__/views/email-settings.render.test.js +2 -2
  130. package/dist/__tests__/views/form-entries.render.test.js +15 -0
  131. package/dist/__tests__/views/form-entries.render.test.js.map +1 -1
  132. package/dist/__tests__/views/form-submissions.render.test.js +18 -0
  133. package/dist/__tests__/views/form-submissions.render.test.js.map +1 -1
  134. package/dist/__tests__/views/forms-list.render.test.js +12 -0
  135. package/dist/__tests__/views/forms-list.render.test.js.map +1 -1
  136. package/dist/__tests__/views/general-settings.render.test.js +26 -10
  137. package/dist/__tests__/views/general-settings.render.test.js.map +1 -1
  138. package/dist/__tests__/views/header-footer-form.test.d.ts +2 -0
  139. package/dist/__tests__/views/header-footer-form.test.d.ts.map +1 -0
  140. package/dist/__tests__/views/header-footer-form.test.js +266 -0
  141. package/dist/__tests__/views/header-footer-form.test.js.map +1 -0
  142. package/dist/__tests__/views/jobs-drawer.render.test.d.ts +2 -0
  143. package/dist/__tests__/views/jobs-drawer.render.test.d.ts.map +1 -0
  144. package/dist/__tests__/views/jobs-drawer.render.test.js +1348 -0
  145. package/dist/__tests__/views/jobs-drawer.render.test.js.map +1 -0
  146. package/dist/__tests__/views/jobs-list.render.test.d.ts +2 -0
  147. package/dist/__tests__/views/jobs-list.render.test.d.ts.map +1 -0
  148. package/dist/__tests__/views/jobs-list.render.test.js +697 -0
  149. package/dist/__tests__/views/jobs-list.render.test.js.map +1 -0
  150. package/dist/__tests__/views/jobs-wizard.render.test.d.ts +2 -0
  151. package/dist/__tests__/views/jobs-wizard.render.test.d.ts.map +1 -0
  152. package/dist/__tests__/views/jobs-wizard.render.test.js +588 -0
  153. package/dist/__tests__/views/jobs-wizard.render.test.js.map +1 -0
  154. package/dist/__tests__/views/kpi-grid.test.d.ts +2 -0
  155. package/dist/__tests__/views/kpi-grid.test.d.ts.map +1 -0
  156. package/dist/__tests__/views/kpi-grid.test.js +26 -0
  157. package/dist/__tests__/views/kpi-grid.test.js.map +1 -0
  158. package/dist/__tests__/views/post-section-editor.test.js +3 -1
  159. package/dist/__tests__/views/post-section-editor.test.js.map +1 -1
  160. package/dist/__tests__/views/script-tags.render.test.js +25 -0
  161. package/dist/__tests__/views/script-tags.render.test.js.map +1 -1
  162. package/dist/__tests__/views/security-settings.render.test.js +9 -8
  163. package/dist/__tests__/views/security-settings.render.test.js.map +1 -1
  164. package/dist/__tests__/views/seo-settings.render.test.js +7 -7
  165. package/dist/__tests__/views/seo-settings.render.test.js.map +1 -1
  166. package/dist/__tests__/views/settings-save-bar.render.test.d.ts +2 -0
  167. package/dist/__tests__/views/settings-save-bar.render.test.d.ts.map +1 -0
  168. package/dist/__tests__/views/settings-save-bar.render.test.js +68 -0
  169. package/dist/__tests__/views/settings-save-bar.render.test.js.map +1 -0
  170. package/dist/__tests__/views/settings-save-footer.render.test.js +23 -15
  171. package/dist/__tests__/views/settings-save-footer.render.test.js.map +1 -1
  172. package/dist/__tests__/views/settings-tabs.render.test.d.ts +2 -0
  173. package/dist/__tests__/views/settings-tabs.render.test.d.ts.map +1 -0
  174. package/dist/__tests__/views/settings-tabs.render.test.js +319 -0
  175. package/dist/__tests__/views/settings-tabs.render.test.js.map +1 -0
  176. package/dist/__tests__/views/updates-tab.render.test.js +4 -3
  177. package/dist/__tests__/views/updates-tab.render.test.js.map +1 -1
  178. package/dist/components/Breadcrumbs.d.ts +8 -1
  179. package/dist/components/Breadcrumbs.d.ts.map +1 -1
  180. package/dist/components/Breadcrumbs.js +6 -0
  181. package/dist/components/Breadcrumbs.js.map +1 -1
  182. package/dist/components/CommandPalette.d.ts.map +1 -1
  183. package/dist/components/CommandPalette.js +40 -4
  184. package/dist/components/CommandPalette.js.map +1 -1
  185. package/dist/components/LocaleSwitcher.d.ts.map +1 -1
  186. package/dist/components/LocaleSwitcher.js +1 -1
  187. package/dist/components/LocaleSwitcher.js.map +1 -1
  188. package/dist/components/NotificationBell.d.ts.map +1 -1
  189. package/dist/components/NotificationBell.js +44 -3
  190. package/dist/components/NotificationBell.js.map +1 -1
  191. package/dist/components/OfflineStatus.js +1 -1
  192. package/dist/components/OfflineStatus.js.map +1 -1
  193. package/dist/components/PresenceIndicator.d.ts.map +1 -1
  194. package/dist/components/PresenceIndicator.js +2 -1
  195. package/dist/components/PresenceIndicator.js.map +1 -1
  196. package/dist/components/ReflowMeter.js +2 -2
  197. package/dist/components/ReflowMeter.js.map +1 -1
  198. package/dist/components/SEOPanel.js +2 -2
  199. package/dist/components/SEOPanel.js.map +1 -1
  200. package/dist/components/ThemeProvider.d.ts +24 -4
  201. package/dist/components/ThemeProvider.d.ts.map +1 -1
  202. package/dist/components/ThemeProvider.js +80 -22
  203. package/dist/components/ThemeProvider.js.map +1 -1
  204. package/dist/components/TipTapEditor.d.ts.map +1 -1
  205. package/dist/components/TipTapEditor.js +3 -4
  206. package/dist/components/TipTapEditor.js.map +1 -1
  207. package/dist/components/forms/EmbedPanel.js +1 -1
  208. package/dist/components/forms/EmbedPanel.js.map +1 -1
  209. package/dist/components/forms/FormEntryDetailPane.js +6 -1
  210. package/dist/components/forms/FormEntryDetailPane.js.map +1 -1
  211. package/dist/components/forms/ShortcodeGlossary.d.ts.map +1 -1
  212. package/dist/components/forms/ShortcodeGlossary.js +6 -1
  213. package/dist/components/forms/ShortcodeGlossary.js.map +1 -1
  214. package/dist/components/forms/primitives.d.ts +15 -5
  215. package/dist/components/forms/primitives.d.ts.map +1 -1
  216. package/dist/components/forms/primitives.js +11 -11
  217. package/dist/components/forms/primitives.js.map +1 -1
  218. package/dist/components/pages/tag-badges.d.ts +2 -1
  219. package/dist/components/pages/tag-badges.d.ts.map +1 -1
  220. package/dist/components/pages/tag-badges.js +4 -3
  221. package/dist/components/pages/tag-badges.js.map +1 -1
  222. package/dist/components/seo/PageAuditPanel.js +2 -2
  223. package/dist/components/seo/PageAuditPanel.js.map +1 -1
  224. package/dist/components/seo/SerpPreview.d.ts +4 -4
  225. package/dist/components/seo/SerpPreview.js +1 -1
  226. package/dist/components/seo/SerpPreview.js.map +1 -1
  227. package/dist/components/seo/primitives.js +2 -2
  228. package/dist/components/seo/primitives.js.map +1 -1
  229. package/dist/components/ui/AuthorAvatar.d.ts +4 -4
  230. package/dist/components/ui/AuthorAvatar.d.ts.map +1 -1
  231. package/dist/components/ui/AuthorAvatar.js +11 -10
  232. package/dist/components/ui/AuthorAvatar.js.map +1 -1
  233. package/dist/components/ui/Badge.d.ts +1 -1
  234. package/dist/components/ui/Badge.js +1 -1
  235. package/dist/components/ui/Badge.js.map +1 -1
  236. package/dist/components/ui/Breadcrumb.d.ts +27 -0
  237. package/dist/components/ui/Breadcrumb.d.ts.map +1 -0
  238. package/dist/components/ui/Breadcrumb.js +41 -0
  239. package/dist/components/ui/Breadcrumb.js.map +1 -0
  240. package/dist/components/ui/Button.d.ts +2 -2
  241. package/dist/components/ui/Button.d.ts.map +1 -1
  242. package/dist/components/ui/Button.js +31 -16
  243. package/dist/components/ui/Button.js.map +1 -1
  244. package/dist/components/ui/Card.d.ts +8 -4
  245. package/dist/components/ui/Card.d.ts.map +1 -1
  246. package/dist/components/ui/Card.js +21 -13
  247. package/dist/components/ui/Card.js.map +1 -1
  248. package/dist/components/ui/CardListControls.d.ts +34 -0
  249. package/dist/components/ui/CardListControls.d.ts.map +1 -0
  250. package/dist/components/ui/CardListControls.js +25 -0
  251. package/dist/components/ui/CardListControls.js.map +1 -0
  252. package/dist/components/ui/CountChip.d.ts +20 -0
  253. package/dist/components/ui/CountChip.d.ts.map +1 -0
  254. package/dist/components/ui/CountChip.js +48 -0
  255. package/dist/components/ui/CountChip.js.map +1 -0
  256. package/dist/components/ui/FilterPill.d.ts +2 -1
  257. package/dist/components/ui/FilterPill.d.ts.map +1 -1
  258. package/dist/components/ui/FilterPill.js +3 -2
  259. package/dist/components/ui/FilterPill.js.map +1 -1
  260. package/dist/components/ui/Input.d.ts +1 -1
  261. package/dist/components/ui/InspectorPane.d.ts +1 -1
  262. package/dist/components/ui/InspectorPane.d.ts.map +1 -1
  263. package/dist/components/ui/InspectorPane.js +15 -4
  264. package/dist/components/ui/InspectorPane.js.map +1 -1
  265. package/dist/components/ui/Modal.d.ts.map +1 -1
  266. package/dist/components/ui/Modal.js +10 -2
  267. package/dist/components/ui/Modal.js.map +1 -1
  268. package/dist/components/ui/PageHeader.d.ts +28 -0
  269. package/dist/components/ui/PageHeader.d.ts.map +1 -0
  270. package/dist/components/ui/PageHeader.js +18 -0
  271. package/dist/components/ui/PageHeader.js.map +1 -0
  272. package/dist/components/ui/RowActions.d.ts +5 -0
  273. package/dist/components/ui/RowActions.d.ts.map +1 -1
  274. package/dist/components/ui/RowActions.js +7 -2
  275. package/dist/components/ui/RowActions.js.map +1 -1
  276. package/dist/components/ui/Segmented.d.ts +21 -0
  277. package/dist/components/ui/Segmented.d.ts.map +1 -0
  278. package/dist/components/ui/Segmented.js +41 -0
  279. package/dist/components/ui/Segmented.js.map +1 -0
  280. package/dist/components/ui/Toaster.d.ts +12 -0
  281. package/dist/components/ui/Toaster.d.ts.map +1 -0
  282. package/dist/components/ui/Toaster.js +103 -0
  283. package/dist/components/ui/Toaster.js.map +1 -0
  284. package/dist/components/ui/Toggle.d.ts +4 -3
  285. package/dist/components/ui/Toggle.d.ts.map +1 -1
  286. package/dist/components/ui/Toggle.js +16 -12
  287. package/dist/components/ui/Toggle.js.map +1 -1
  288. package/dist/components/ui/UnderlineTabs.d.ts +56 -0
  289. package/dist/components/ui/UnderlineTabs.d.ts.map +1 -0
  290. package/dist/components/ui/UnderlineTabs.js +205 -0
  291. package/dist/components/ui/UnderlineTabs.js.map +1 -0
  292. package/dist/components/ui/UnsavedBar.d.ts +25 -0
  293. package/dist/components/ui/UnsavedBar.d.ts.map +1 -0
  294. package/dist/components/ui/UnsavedBar.js +22 -0
  295. package/dist/components/ui/UnsavedBar.js.map +1 -0
  296. package/dist/components/ui/admin-links.d.ts +11 -0
  297. package/dist/components/ui/admin-links.d.ts.map +1 -0
  298. package/dist/components/ui/admin-links.js +10 -0
  299. package/dist/components/ui/admin-links.js.map +1 -0
  300. package/dist/components/ui/card-table.d.ts +43 -0
  301. package/dist/components/ui/card-table.d.ts.map +1 -0
  302. package/dist/components/ui/card-table.js +31 -0
  303. package/dist/components/ui/card-table.js.map +1 -0
  304. package/dist/components/virtual-window.d.ts +7 -0
  305. package/dist/components/virtual-window.d.ts.map +1 -1
  306. package/dist/components/virtual-window.js +5 -2
  307. package/dist/components/virtual-window.js.map +1 -1
  308. package/dist/fields/RelationshipField.js +1 -1
  309. package/dist/fields/RelationshipField.js.map +1 -1
  310. package/dist/files/dm-mono-latin-400-normal.woff +0 -0
  311. package/dist/files/dm-mono-latin-400-normal.woff2 +0 -0
  312. package/dist/files/dm-mono-latin-500-normal.woff +0 -0
  313. package/dist/files/dm-mono-latin-500-normal.woff2 +0 -0
  314. package/dist/files/dm-mono-latin-ext-400-normal.woff +0 -0
  315. package/dist/files/dm-mono-latin-ext-400-normal.woff2 +0 -0
  316. package/dist/files/dm-mono-latin-ext-500-normal.woff +0 -0
  317. package/dist/files/dm-mono-latin-ext-500-normal.woff2 +0 -0
  318. package/dist/files/dm-sans-latin-400-normal.woff +0 -0
  319. package/dist/files/dm-sans-latin-400-normal.woff2 +0 -0
  320. package/dist/files/dm-sans-latin-500-normal.woff +0 -0
  321. package/dist/files/dm-sans-latin-500-normal.woff2 +0 -0
  322. package/dist/files/dm-sans-latin-600-normal.woff +0 -0
  323. package/dist/files/dm-sans-latin-600-normal.woff2 +0 -0
  324. package/dist/files/dm-sans-latin-700-normal.woff +0 -0
  325. package/dist/files/dm-sans-latin-700-normal.woff2 +0 -0
  326. package/dist/files/dm-sans-latin-ext-400-normal.woff +0 -0
  327. package/dist/files/dm-sans-latin-ext-400-normal.woff2 +0 -0
  328. package/dist/files/dm-sans-latin-ext-500-normal.woff +0 -0
  329. package/dist/files/dm-sans-latin-ext-500-normal.woff2 +0 -0
  330. package/dist/files/dm-sans-latin-ext-600-normal.woff +0 -0
  331. package/dist/files/dm-sans-latin-ext-600-normal.woff2 +0 -0
  332. package/dist/files/dm-sans-latin-ext-700-normal.woff +0 -0
  333. package/dist/files/dm-sans-latin-ext-700-normal.woff2 +0 -0
  334. package/dist/hooks/useAppearanceBootstrap.d.ts.map +1 -1
  335. package/dist/hooks/useAppearanceBootstrap.js +9 -3
  336. package/dist/hooks/useAppearanceBootstrap.js.map +1 -1
  337. package/dist/index.d.ts +15 -0
  338. package/dist/index.d.ts.map +1 -1
  339. package/dist/index.js +8 -0
  340. package/dist/index.js.map +1 -1
  341. package/dist/layout/Header.d.ts +14 -5
  342. package/dist/layout/Header.d.ts.map +1 -1
  343. package/dist/layout/Header.js +78 -13
  344. package/dist/layout/Header.js.map +1 -1
  345. package/dist/layout/Layout.d.ts +5 -3
  346. package/dist/layout/Layout.d.ts.map +1 -1
  347. package/dist/layout/Layout.js +45 -54
  348. package/dist/layout/Layout.js.map +1 -1
  349. package/dist/layout/MobileTabBar.d.ts +20 -0
  350. package/dist/layout/MobileTabBar.d.ts.map +1 -0
  351. package/dist/layout/MobileTabBar.js +29 -0
  352. package/dist/layout/MobileTabBar.js.map +1 -0
  353. package/dist/layout/Sidebar.d.ts +8 -26
  354. package/dist/layout/Sidebar.d.ts.map +1 -1
  355. package/dist/layout/Sidebar.js +309 -345
  356. package/dist/layout/Sidebar.js.map +1 -1
  357. package/dist/layout/nav-config.d.ts +101 -0
  358. package/dist/layout/nav-config.d.ts.map +1 -0
  359. package/dist/layout/nav-config.js +297 -0
  360. package/dist/layout/nav-config.js.map +1 -0
  361. package/dist/layout/primitives/AdminShell.d.ts +10 -2
  362. package/dist/layout/primitives/AdminShell.d.ts.map +1 -1
  363. package/dist/layout/primitives/AdminShell.js +114 -6
  364. package/dist/layout/primitives/AdminShell.js.map +1 -1
  365. package/dist/layout/topbar-classes.d.ts +8 -0
  366. package/dist/layout/topbar-classes.d.ts.map +1 -0
  367. package/dist/layout/topbar-classes.js +8 -0
  368. package/dist/layout/topbar-classes.js.map +1 -0
  369. package/dist/layout/use-nav-items.d.ts +10 -0
  370. package/dist/layout/use-nav-items.d.ts.map +1 -0
  371. package/dist/layout/use-nav-items.js +39 -0
  372. package/dist/layout/use-nav-items.js.map +1 -0
  373. package/dist/lib/api.d.ts +8 -0
  374. package/dist/lib/api.d.ts.map +1 -1
  375. package/dist/lib/api.js +8 -1
  376. package/dist/lib/api.js.map +1 -1
  377. package/dist/lib/appearance-api.d.ts +3 -1
  378. package/dist/lib/appearance-api.d.ts.map +1 -1
  379. package/dist/lib/appearance-api.js +1 -0
  380. package/dist/lib/appearance-api.js.map +1 -1
  381. package/dist/lib/batch-wizard.d.ts +84 -0
  382. package/dist/lib/batch-wizard.d.ts.map +1 -0
  383. package/dist/lib/batch-wizard.js +122 -0
  384. package/dist/lib/batch-wizard.js.map +1 -0
  385. package/dist/lib/chrome-service.d.ts +69 -0
  386. package/dist/lib/chrome-service.d.ts.map +1 -0
  387. package/dist/lib/chrome-service.js +108 -0
  388. package/dist/lib/chrome-service.js.map +1 -0
  389. package/dist/lib/job-drawer.d.ts +128 -0
  390. package/dist/lib/job-drawer.d.ts.map +1 -0
  391. package/dist/lib/job-drawer.js +351 -0
  392. package/dist/lib/job-drawer.js.map +1 -0
  393. package/dist/lib/job-view.d.ts +230 -0
  394. package/dist/lib/job-view.d.ts.map +1 -0
  395. package/dist/lib/job-view.js +419 -0
  396. package/dist/lib/job-view.js.map +1 -0
  397. package/dist/lib/jobs-service.d.ts +152 -0
  398. package/dist/lib/jobs-service.d.ts.map +1 -0
  399. package/dist/lib/jobs-service.js +220 -0
  400. package/dist/lib/jobs-service.js.map +1 -0
  401. package/dist/lib/sheet-focus.d.ts +24 -0
  402. package/dist/lib/sheet-focus.d.ts.map +1 -0
  403. package/dist/lib/sheet-focus.js +61 -0
  404. package/dist/lib/sheet-focus.js.map +1 -0
  405. package/dist/lib/tiers.d.ts +30 -0
  406. package/dist/lib/tiers.d.ts.map +1 -0
  407. package/dist/lib/tiers.js +43 -0
  408. package/dist/lib/tiers.js.map +1 -0
  409. package/dist/prenta-admin.css +1 -1
  410. package/dist/router/admin-routes.d.ts.map +1 -1
  411. package/dist/router/admin-routes.js +8 -0
  412. package/dist/router/admin-routes.js.map +1 -1
  413. package/dist/router/index.d.ts +5 -1
  414. package/dist/router/index.d.ts.map +1 -1
  415. package/dist/router/index.js +7 -0
  416. package/dist/router/index.js.map +1 -1
  417. package/dist/views/ApiKeys.js +2 -2
  418. package/dist/views/ApiKeys.js.map +1 -1
  419. package/dist/views/AppearanceChrome.d.ts +24 -0
  420. package/dist/views/AppearanceChrome.d.ts.map +1 -0
  421. package/dist/views/AppearanceChrome.js +461 -0
  422. package/dist/views/AppearanceChrome.js.map +1 -0
  423. package/dist/views/CollectionList.d.ts.map +1 -1
  424. package/dist/views/CollectionList.js +73 -53
  425. package/dist/views/CollectionList.js.map +1 -1
  426. package/dist/views/Dashboard.d.ts.map +1 -1
  427. package/dist/views/Dashboard.js +14 -8
  428. package/dist/views/Dashboard.js.map +1 -1
  429. package/dist/views/DocumentEdit.d.ts +6 -1
  430. package/dist/views/DocumentEdit.d.ts.map +1 -1
  431. package/dist/views/DocumentEdit.js +44 -8
  432. package/dist/views/DocumentEdit.js.map +1 -1
  433. package/dist/views/FormDeliveries.d.ts.map +1 -1
  434. package/dist/views/FormDeliveries.js +7 -1
  435. package/dist/views/FormDeliveries.js.map +1 -1
  436. package/dist/views/FormEntries.d.ts.map +1 -1
  437. package/dist/views/FormEntries.js +11 -2
  438. package/dist/views/FormEntries.js.map +1 -1
  439. package/dist/views/FormSubmissions.d.ts +1 -1
  440. package/dist/views/FormSubmissions.d.ts.map +1 -1
  441. package/dist/views/FormSubmissions.js +15 -4
  442. package/dist/views/FormSubmissions.js.map +1 -1
  443. package/dist/views/Forms.d.ts.map +1 -1
  444. package/dist/views/Forms.js +6 -4
  445. package/dist/views/Forms.js.map +1 -1
  446. package/dist/views/FormsSettings.d.ts +2 -0
  447. package/dist/views/FormsSettings.d.ts.map +1 -0
  448. package/dist/views/FormsSettings.js +37 -0
  449. package/dist/views/FormsSettings.js.map +1 -0
  450. package/dist/views/Jobs/BusyButton.d.ts +15 -0
  451. package/dist/views/Jobs/BusyButton.d.ts.map +1 -0
  452. package/dist/views/Jobs/BusyButton.js +26 -0
  453. package/dist/views/Jobs/BusyButton.js.map +1 -0
  454. package/dist/views/Jobs/CancelJobDialog.d.ts +27 -0
  455. package/dist/views/Jobs/CancelJobDialog.d.ts.map +1 -0
  456. package/dist/views/Jobs/CancelJobDialog.js +76 -0
  457. package/dist/views/Jobs/CancelJobDialog.js.map +1 -0
  458. package/dist/views/Jobs/DrawerActivity.d.ts +16 -0
  459. package/dist/views/Jobs/DrawerActivity.d.ts.map +1 -0
  460. package/dist/views/Jobs/DrawerActivity.js +59 -0
  461. package/dist/views/Jobs/DrawerActivity.js.map +1 -0
  462. package/dist/views/Jobs/DrawerOverview.d.ts +28 -0
  463. package/dist/views/Jobs/DrawerOverview.d.ts.map +1 -0
  464. package/dist/views/Jobs/DrawerOverview.js +32 -0
  465. package/dist/views/Jobs/DrawerOverview.js.map +1 -0
  466. package/dist/views/Jobs/DrawerResults.d.ts +25 -0
  467. package/dist/views/Jobs/DrawerResults.d.ts.map +1 -0
  468. package/dist/views/Jobs/DrawerResults.js +50 -0
  469. package/dist/views/Jobs/DrawerResults.js.map +1 -0
  470. package/dist/views/Jobs/DrawerReview.d.ts +51 -0
  471. package/dist/views/Jobs/DrawerReview.d.ts.map +1 -0
  472. package/dist/views/Jobs/DrawerReview.js +110 -0
  473. package/dist/views/Jobs/DrawerReview.js.map +1 -0
  474. package/dist/views/Jobs/JobDrawer.d.ts +51 -0
  475. package/dist/views/Jobs/JobDrawer.d.ts.map +1 -0
  476. package/dist/views/Jobs/JobDrawer.js +378 -0
  477. package/dist/views/Jobs/JobDrawer.js.map +1 -0
  478. package/dist/views/Jobs/JobsTable.d.ts +21 -0
  479. package/dist/views/Jobs/JobsTable.d.ts.map +1 -0
  480. package/dist/views/Jobs/JobsTable.js +81 -0
  481. package/dist/views/Jobs/JobsTable.js.map +1 -0
  482. package/dist/views/Jobs/NewBatchJob.d.ts +34 -0
  483. package/dist/views/Jobs/NewBatchJob.d.ts.map +1 -0
  484. package/dist/views/Jobs/NewBatchJob.js +282 -0
  485. package/dist/views/Jobs/NewBatchJob.js.map +1 -0
  486. package/dist/views/Jobs/WorkerStrip.d.ts +24 -0
  487. package/dist/views/Jobs/WorkerStrip.d.ts.map +1 -0
  488. package/dist/views/Jobs/WorkerStrip.js +63 -0
  489. package/dist/views/Jobs/WorkerStrip.js.map +1 -0
  490. package/dist/views/Jobs/atoms.d.ts +19 -0
  491. package/dist/views/Jobs/atoms.d.ts.map +1 -0
  492. package/dist/views/Jobs/atoms.js +52 -0
  493. package/dist/views/Jobs/atoms.js.map +1 -0
  494. package/dist/views/Jobs/focus.d.ts +29 -0
  495. package/dist/views/Jobs/focus.d.ts.map +1 -0
  496. package/dist/views/Jobs/focus.js +64 -0
  497. package/dist/views/Jobs/focus.js.map +1 -0
  498. package/dist/views/Jobs/icons.d.ts +22 -0
  499. package/dist/views/Jobs/icons.d.ts.map +1 -0
  500. package/dist/views/Jobs/icons.js +23 -0
  501. package/dist/views/Jobs/icons.js.map +1 -0
  502. package/dist/views/Jobs/useJobDetail.d.ts +21 -0
  503. package/dist/views/Jobs/useJobDetail.d.ts.map +1 -0
  504. package/dist/views/Jobs/useJobDetail.js +39 -0
  505. package/dist/views/Jobs/useJobDetail.js.map +1 -0
  506. package/dist/views/Jobs/useJobsFeed.d.ts +35 -0
  507. package/dist/views/Jobs/useJobsFeed.d.ts.map +1 -0
  508. package/dist/views/Jobs/useJobsFeed.js +231 -0
  509. package/dist/views/Jobs/useJobsFeed.js.map +1 -0
  510. package/dist/views/Jobs/useReviewItems.d.ts +39 -0
  511. package/dist/views/Jobs/useReviewItems.d.ts.map +1 -0
  512. package/dist/views/Jobs/useReviewItems.js +140 -0
  513. package/dist/views/Jobs/useReviewItems.js.map +1 -0
  514. package/dist/views/Jobs.d.ts +19 -1
  515. package/dist/views/Jobs.d.ts.map +1 -1
  516. package/dist/views/Jobs.js +204 -35
  517. package/dist/views/Jobs.js.map +1 -1
  518. package/dist/views/MediaBrowser.d.ts.map +1 -1
  519. package/dist/views/MediaBrowser.js +37 -9
  520. package/dist/views/MediaBrowser.js.map +1 -1
  521. package/dist/views/Pages/PagesListView.d.ts +1 -1
  522. package/dist/views/Pages/PagesListView.d.ts.map +1 -1
  523. package/dist/views/Pages/PagesListView.js +34 -5
  524. package/dist/views/Pages/PagesListView.js.map +1 -1
  525. package/dist/views/Posts/NewPostTypeInstructions.d.ts.map +1 -1
  526. package/dist/views/Posts/NewPostTypeInstructions.js +12 -2
  527. package/dist/views/Posts/NewPostTypeInstructions.js.map +1 -1
  528. package/dist/views/Posts/PostTypesView.d.ts.map +1 -1
  529. package/dist/views/Posts/PostTypesView.js +10 -1
  530. package/dist/views/Posts/PostTypesView.js.map +1 -1
  531. package/dist/views/Posts/PostsListView.d.ts +1 -2
  532. package/dist/views/Posts/PostsListView.d.ts.map +1 -1
  533. package/dist/views/Posts/PostsListView.js +31 -3
  534. package/dist/views/Posts/PostsListView.js.map +1 -1
  535. package/dist/views/SEO.d.ts.map +1 -1
  536. package/dist/views/SEO.js +3 -3
  537. package/dist/views/SEO.js.map +1 -1
  538. package/dist/views/ScriptTags.d.ts.map +1 -1
  539. package/dist/views/ScriptTags.js +20 -15
  540. package/dist/views/ScriptTags.js.map +1 -1
  541. package/dist/views/Settings.d.ts.map +1 -1
  542. package/dist/views/Settings.js +115 -51
  543. package/dist/views/Settings.js.map +1 -1
  544. package/dist/views/SpamFolder.d.ts +2 -0
  545. package/dist/views/SpamFolder.d.ts.map +1 -0
  546. package/dist/views/SpamFolder.js +14 -0
  547. package/dist/views/SpamFolder.js.map +1 -0
  548. package/dist/views/Trash.d.ts +6 -1
  549. package/dist/views/Trash.d.ts.map +1 -1
  550. package/dist/views/Trash.js +7 -2
  551. package/dist/views/Trash.js.map +1 -1
  552. package/dist/views/Users.js +2 -2
  553. package/dist/views/Users.js.map +1 -1
  554. package/dist/views/WidgetsPlaceholder.d.ts +2 -0
  555. package/dist/views/WidgetsPlaceholder.d.ts.map +1 -0
  556. package/dist/views/WidgetsPlaceholder.js +15 -0
  557. package/dist/views/WidgetsPlaceholder.js.map +1 -0
  558. package/dist/views/dashboard/kpi-grid.d.ts +18 -0
  559. package/dist/views/dashboard/kpi-grid.d.ts.map +1 -0
  560. package/dist/views/dashboard/kpi-grid.js +36 -0
  561. package/dist/views/dashboard/kpi-grid.js.map +1 -0
  562. package/dist/views/header-footer/AnnouncementTab.d.ts +15 -0
  563. package/dist/views/header-footer/AnnouncementTab.d.ts.map +1 -0
  564. package/dist/views/header-footer/AnnouncementTab.js +43 -0
  565. package/dist/views/header-footer/AnnouncementTab.js.map +1 -0
  566. package/dist/views/header-footer/ChromeField.d.ts +25 -0
  567. package/dist/views/header-footer/ChromeField.d.ts.map +1 -0
  568. package/dist/views/header-footer/ChromeField.js +99 -0
  569. package/dist/views/header-footer/ChromeField.js.map +1 -0
  570. package/dist/views/header-footer/ChromePreview.d.ts +31 -0
  571. package/dist/views/header-footer/ChromePreview.d.ts.map +1 -0
  572. package/dist/views/header-footer/ChromePreview.js +195 -0
  573. package/dist/views/header-footer/ChromePreview.js.map +1 -0
  574. package/dist/views/header-footer/DeveloperTab.d.ts +17 -0
  575. package/dist/views/header-footer/DeveloperTab.d.ts.map +1 -0
  576. package/dist/views/header-footer/DeveloperTab.js +98 -0
  577. package/dist/views/header-footer/DeveloperTab.js.map +1 -0
  578. package/dist/views/header-footer/RegionTab.d.ts +27 -0
  579. package/dist/views/header-footer/RegionTab.d.ts.map +1 -0
  580. package/dist/views/header-footer/RegionTab.js +80 -0
  581. package/dist/views/header-footer/RegionTab.js.map +1 -0
  582. package/dist/views/header-footer/chrome-form.d.ts +137 -0
  583. package/dist/views/header-footer/chrome-form.d.ts.map +1 -0
  584. package/dist/views/header-footer/chrome-form.js +518 -0
  585. package/dist/views/header-footer/chrome-form.js.map +1 -0
  586. package/dist/views/header-footer/code-samples.d.ts +30 -0
  587. package/dist/views/header-footer/code-samples.d.ts.map +1 -0
  588. package/dist/views/header-footer/code-samples.js +127 -0
  589. package/dist/views/header-footer/code-samples.js.map +1 -0
  590. package/dist/views/header-footer/controls.d.ts +57 -0
  591. package/dist/views/header-footer/controls.d.ts.map +1 -0
  592. package/dist/views/header-footer/controls.js +43 -0
  593. package/dist/views/header-footer/controls.js.map +1 -0
  594. package/dist/views/lazy-views.d.ts +4 -0
  595. package/dist/views/lazy-views.d.ts.map +1 -1
  596. package/dist/views/lazy-views.js +4 -0
  597. package/dist/views/lazy-views.js.map +1 -1
  598. package/dist/views/page-editor/PageTab.js +1 -1
  599. package/dist/views/page-editor/PageTab.js.map +1 -1
  600. package/dist/views/page-editor/ReviewBar.js +1 -1
  601. package/dist/views/page-editor/ReviewBar.js.map +1 -1
  602. package/dist/views/page-editor/VersionHistoryPanel.js +1 -1
  603. package/dist/views/page-editor/VersionHistoryPanel.js.map +1 -1
  604. package/dist/views/seo/AuditTab.js +1 -1
  605. package/dist/views/seo/AuditTab.js.map +1 -1
  606. package/dist/views/seo/OverviewTab.d.ts.map +1 -1
  607. package/dist/views/seo/OverviewTab.js +2 -2
  608. package/dist/views/seo/OverviewTab.js.map +1 -1
  609. package/dist/views/seo/ProposalsTab.js +1 -1
  610. package/dist/views/seo/ProposalsTab.js.map +1 -1
  611. package/dist/views/settings/AISettingsTab.d.ts.map +1 -1
  612. package/dist/views/settings/AISettingsTab.js +4 -2
  613. package/dist/views/settings/AISettingsTab.js.map +1 -1
  614. package/dist/views/settings/AccessProtectionCard.js +1 -1
  615. package/dist/views/settings/AccessProtectionCard.js.map +1 -1
  616. package/dist/views/settings/AdminThemeCard.d.ts.map +1 -1
  617. package/dist/views/settings/AdminThemeCard.js +63 -15
  618. package/dist/views/settings/AdminThemeCard.js.map +1 -1
  619. package/dist/views/settings/AppearanceTab.d.ts.map +1 -1
  620. package/dist/views/settings/AppearanceTab.js +4 -2
  621. package/dist/views/settings/AppearanceTab.js.map +1 -1
  622. package/dist/views/settings/BrandPreviewCard.js +1 -1
  623. package/dist/views/settings/BrandPreviewCard.js.map +1 -1
  624. package/dist/views/settings/BrandVoiceCard.js +1 -1
  625. package/dist/views/settings/BrandVoiceCard.js.map +1 -1
  626. package/dist/views/settings/EmailSettingsTab.d.ts.map +1 -1
  627. package/dist/views/settings/EmailSettingsTab.js +5 -3
  628. package/dist/views/settings/EmailSettingsTab.js.map +1 -1
  629. package/dist/views/settings/GeneralSettingsTab.d.ts.map +1 -1
  630. package/dist/views/settings/GeneralSettingsTab.js +4 -2
  631. package/dist/views/settings/GeneralSettingsTab.js.map +1 -1
  632. package/dist/views/settings/ProviderConnectionCard.js +1 -1
  633. package/dist/views/settings/ProviderConnectionCard.js.map +1 -1
  634. package/dist/views/settings/SearchDataCard.js +1 -1
  635. package/dist/views/settings/SearchDataCard.js.map +1 -1
  636. package/dist/views/settings/SecurityStatusCard.js +2 -2
  637. package/dist/views/settings/SecurityStatusCard.js.map +1 -1
  638. package/dist/views/settings/SecurityTab.d.ts.map +1 -1
  639. package/dist/views/settings/SecurityTab.js +4 -2
  640. package/dist/views/settings/SecurityTab.js.map +1 -1
  641. package/dist/views/settings/SeoAutopilotCard.js +2 -2
  642. package/dist/views/settings/SeoAutopilotCard.js.map +1 -1
  643. package/dist/views/settings/SeoSettingsTab.d.ts.map +1 -1
  644. package/dist/views/settings/SeoSettingsTab.js +5 -3
  645. package/dist/views/settings/SeoSettingsTab.js.map +1 -1
  646. package/dist/views/settings/SiteIndexStatusCard.js +1 -1
  647. package/dist/views/settings/SiteIndexStatusCard.js.map +1 -1
  648. package/dist/views/settings/SiteThemeCard.js +1 -1
  649. package/dist/views/settings/UpdatesTab.d.ts.map +1 -1
  650. package/dist/views/settings/UpdatesTab.js +6 -5
  651. package/dist/views/settings/UpdatesTab.js.map +1 -1
  652. package/dist/views/settings/components.d.ts +7 -11
  653. package/dist/views/settings/components.d.ts.map +1 -1
  654. package/dist/views/settings/components.js +18 -12
  655. package/dist/views/settings/components.js.map +1 -1
  656. package/dist/views/settings/useAppearanceSettings.d.ts +7 -1
  657. package/dist/views/settings/useAppearanceSettings.d.ts.map +1 -1
  658. package/dist/views/settings/useAppearanceSettings.js +89 -22
  659. package/dist/views/settings/useAppearanceSettings.js.map +1 -1
  660. package/dist/views/users/UserDetailDrawer.js +1 -1
  661. package/dist/views/users/UserDetailDrawer.js.map +1 -1
  662. package/package.json +10 -8
  663. package/src/AdminRoot.tsx +103 -31
  664. package/src/LoginRoot.tsx +2 -1
  665. package/src/__tests__/components/author-avatar.test.tsx +3 -20
  666. package/src/__tests__/components/notification-bell.test.tsx +146 -14
  667. package/src/__tests__/components/responsive-tiers.render.test.tsx +461 -0
  668. package/src/__tests__/components/serp-preview.render.test.tsx +6 -3
  669. package/src/__tests__/components/shell-primitives.render.test.tsx +951 -0
  670. package/src/__tests__/components/theme-provider-accent.test.tsx +83 -8
  671. package/src/__tests__/components/toggle.test.tsx +11 -3
  672. package/src/__tests__/components/ui-primitives.test.tsx +5 -8
  673. package/src/__tests__/layout/build-nav-items.test.ts +1 -1
  674. package/src/__tests__/layout/shell-nav.render.test.tsx +983 -0
  675. package/src/__tests__/layout/sidebar-forms-submenu.render.test.tsx +8 -4
  676. package/src/__tests__/layout/sidebar-groups.render.test.tsx +116 -0
  677. package/src/__tests__/layout/sidebar-menus.render.test.tsx +116 -0
  678. package/src/__tests__/layout/sidebar-plugin-nav.test.ts +1 -1
  679. package/src/__tests__/layout/sidebar-posts.test.ts +48 -40
  680. package/src/__tests__/layout/sidebar-submenu.render.test.tsx +35 -10
  681. package/src/__tests__/layout/topbar.render.test.tsx +464 -0
  682. package/src/__tests__/lib/api.test.ts +2 -0
  683. package/src/__tests__/lib/batch-wizard.test.ts +199 -0
  684. package/src/__tests__/lib/job-drawer.test.ts +495 -0
  685. package/src/__tests__/lib/job-view.test.ts +558 -0
  686. package/src/__tests__/lib/jobs-service.test.ts +167 -0
  687. package/src/__tests__/router/admin-route-order.test.ts +39 -0
  688. package/src/__tests__/styles/ai-gradient-contrast.test.ts +135 -0
  689. package/src/__tests__/styles/breakpoint-order.test.ts +68 -0
  690. package/src/__tests__/styles/responsive-layer.test.ts +367 -12
  691. package/src/__tests__/styles/tailwind-preset.test.ts +154 -0
  692. package/src/__tests__/styles/theme-token-scope.test.ts +10 -3
  693. package/src/__tests__/styles/tiers.test.ts +136 -0
  694. package/src/__tests__/styles/tokens-drift.test.ts +67 -6
  695. package/src/__tests__/views/admin-lazy-route.render.test.tsx +41 -1
  696. package/src/__tests__/views/ai-settings.render.test.tsx +4 -4
  697. package/src/__tests__/views/appearance-chrome.render.test.tsx +818 -0
  698. package/src/__tests__/views/appearance-menus-route.render.test.tsx +58 -0
  699. package/src/__tests__/views/appearance-settings.render.test.tsx +10 -8
  700. package/src/__tests__/views/appearance-theme-provider.render.test.tsx +347 -0
  701. package/src/__tests__/views/dashboard.test.tsx +48 -0
  702. package/src/__tests__/views/document-edit-navigation.render.test.tsx +130 -0
  703. package/src/__tests__/views/document-edit-routes.render.test.tsx +130 -0
  704. package/src/__tests__/views/email-settings.render.test.tsx +2 -2
  705. package/src/__tests__/views/form-entries.render.test.tsx +22 -0
  706. package/src/__tests__/views/form-submissions.render.test.tsx +22 -0
  707. package/src/__tests__/views/forms-list.render.test.tsx +13 -0
  708. package/src/__tests__/views/general-settings.render.test.tsx +38 -11
  709. package/src/__tests__/views/header-footer-form.test.ts +333 -0
  710. package/src/__tests__/views/jobs-drawer.render.test.tsx +1553 -0
  711. package/src/__tests__/views/jobs-list.render.test.tsx +853 -0
  712. package/src/__tests__/views/jobs-wizard.render.test.tsx +707 -0
  713. package/src/__tests__/views/kpi-grid.test.ts +29 -0
  714. package/src/__tests__/views/post-section-editor.test.tsx +5 -1
  715. package/src/__tests__/views/script-tags.render.test.tsx +29 -0
  716. package/src/__tests__/views/security-settings.render.test.tsx +9 -10
  717. package/src/__tests__/views/seo-settings.render.test.tsx +7 -9
  718. package/src/__tests__/views/settings-save-bar.render.test.tsx +91 -0
  719. package/src/__tests__/views/settings-save-footer.render.test.tsx +25 -15
  720. package/src/__tests__/views/settings-tabs.render.test.tsx +371 -0
  721. package/src/__tests__/views/updates-tab.render.test.tsx +4 -3
  722. package/src/components/Breadcrumbs.tsx +7 -1
  723. package/src/components/CommandPalette.tsx +51 -3
  724. package/src/components/LocaleSwitcher.tsx +5 -6
  725. package/src/components/NotificationBell.tsx +74 -18
  726. package/src/components/OfflineStatus.tsx +1 -1
  727. package/src/components/PresenceIndicator.tsx +2 -1
  728. package/src/components/ReflowMeter.tsx +3 -3
  729. package/src/components/SEOPanel.tsx +2 -2
  730. package/src/components/ThemeProvider.tsx +122 -42
  731. package/src/components/TipTapEditor.tsx +3 -4
  732. package/src/components/forms/EmbedPanel.tsx +1 -1
  733. package/src/components/forms/FormEntryDetailPane.tsx +7 -1
  734. package/src/components/forms/ShortcodeGlossary.tsx +7 -1
  735. package/src/components/forms/primitives.tsx +37 -21
  736. package/src/components/pages/tag-badges.tsx +4 -3
  737. package/src/components/seo/PageAuditPanel.tsx +2 -2
  738. package/src/components/seo/SerpPreview.tsx +5 -5
  739. package/src/components/seo/primitives.tsx +2 -2
  740. package/src/components/ui/AuthorAvatar.tsx +11 -10
  741. package/src/components/ui/Badge.tsx +1 -1
  742. package/src/components/ui/Breadcrumb.tsx +109 -0
  743. package/src/components/ui/Button.tsx +40 -15
  744. package/src/components/ui/Card.tsx +35 -32
  745. package/src/components/ui/CardListControls.tsx +90 -0
  746. package/src/components/ui/CountChip.tsx +90 -0
  747. package/src/components/ui/FilterPill.tsx +5 -3
  748. package/src/components/ui/InspectorPane.tsx +21 -7
  749. package/src/components/ui/Modal.tsx +20 -6
  750. package/src/components/ui/PageHeader.tsx +63 -0
  751. package/src/components/ui/RowActions.tsx +7 -2
  752. package/src/components/ui/Segmented.tsx +97 -0
  753. package/src/components/ui/Toaster.tsx +139 -0
  754. package/src/components/ui/Toggle.tsx +18 -14
  755. package/src/components/ui/UnderlineTabs.tsx +373 -0
  756. package/src/components/ui/UnsavedBar.tsx +119 -0
  757. package/src/components/ui/admin-links.tsx +20 -0
  758. package/src/components/ui/card-table.ts +34 -0
  759. package/src/components/virtual-window.tsx +13 -2
  760. package/src/fields/RelationshipField.tsx +1 -1
  761. package/src/hooks/useAppearanceBootstrap.ts +9 -3
  762. package/src/index.ts +19 -0
  763. package/src/layout/Header.tsx +210 -135
  764. package/src/layout/Layout.tsx +61 -108
  765. package/src/layout/MobileTabBar.tsx +92 -0
  766. package/src/layout/Sidebar.tsx +555 -593
  767. package/src/layout/nav-config.tsx +425 -0
  768. package/src/layout/primitives/AdminShell.tsx +154 -6
  769. package/src/layout/topbar-classes.ts +8 -0
  770. package/src/layout/use-nav-items.ts +40 -0
  771. package/src/lib/api.ts +18 -1
  772. package/src/lib/appearance-api.ts +4 -0
  773. package/src/lib/batch-wizard.ts +188 -0
  774. package/src/lib/chrome-service.ts +200 -0
  775. package/src/lib/job-drawer.ts +424 -0
  776. package/src/lib/job-view.ts +550 -0
  777. package/src/lib/jobs-service.ts +345 -0
  778. package/src/lib/sheet-focus.ts +71 -0
  779. package/src/lib/tiers.ts +43 -0
  780. package/src/router/admin-routes.ts +8 -0
  781. package/src/router/index.ts +9 -1
  782. package/src/styles/prenta-tokens.css +280 -82
  783. package/src/styles/responsive.css +460 -22
  784. package/src/styles/theme.css +192 -28
  785. package/src/views/ApiKeys.tsx +2 -2
  786. package/src/views/AppearanceChrome.tsx +732 -0
  787. package/src/views/CollectionList.tsx +264 -205
  788. package/src/views/Dashboard.tsx +26 -13
  789. package/src/views/DocumentEdit.tsx +111 -56
  790. package/src/views/FormDeliveries.tsx +30 -17
  791. package/src/views/FormEntries.tsx +28 -20
  792. package/src/views/FormSubmissions.tsx +32 -34
  793. package/src/views/Forms.tsx +55 -34
  794. package/src/views/FormsSettings.tsx +94 -0
  795. package/src/views/Jobs/BusyButton.tsx +56 -0
  796. package/src/views/Jobs/CancelJobDialog.tsx +145 -0
  797. package/src/views/Jobs/DrawerActivity.tsx +142 -0
  798. package/src/views/Jobs/DrawerOverview.tsx +139 -0
  799. package/src/views/Jobs/DrawerResults.tsx +155 -0
  800. package/src/views/Jobs/DrawerReview.tsx +464 -0
  801. package/src/views/Jobs/JobDrawer.tsx +636 -0
  802. package/src/views/Jobs/JobsTable.tsx +267 -0
  803. package/src/views/Jobs/NewBatchJob.tsx +857 -0
  804. package/src/views/Jobs/WorkerStrip.tsx +149 -0
  805. package/src/views/Jobs/atoms.tsx +93 -0
  806. package/src/views/Jobs/focus.ts +67 -0
  807. package/src/views/Jobs/icons.tsx +111 -0
  808. package/src/views/Jobs/useJobDetail.ts +64 -0
  809. package/src/views/Jobs/useJobsFeed.ts +249 -0
  810. package/src/views/Jobs/useReviewItems.ts +187 -0
  811. package/src/views/Jobs.tsx +396 -105
  812. package/src/views/MediaBrowser.tsx +71 -21
  813. package/src/views/Pages/PagesListView.tsx +115 -39
  814. package/src/views/Posts/NewPostTypeInstructions.tsx +15 -10
  815. package/src/views/Posts/PostTypesView.tsx +28 -6
  816. package/src/views/Posts/PostsListView.tsx +130 -40
  817. package/src/views/SEO.tsx +23 -8
  818. package/src/views/ScriptTags.tsx +233 -153
  819. package/src/views/Settings.tsx +215 -256
  820. package/src/views/SpamFolder.tsx +32 -0
  821. package/src/views/Trash.tsx +12 -1
  822. package/src/views/Users.tsx +2 -2
  823. package/src/views/WidgetsPlaceholder.tsx +33 -0
  824. package/src/views/dashboard/kpi-grid.ts +38 -0
  825. package/src/views/header-footer/AnnouncementTab.tsx +231 -0
  826. package/src/views/header-footer/ChromeField.tsx +358 -0
  827. package/src/views/header-footer/ChromePreview.tsx +497 -0
  828. package/src/views/header-footer/DeveloperTab.tsx +331 -0
  829. package/src/views/header-footer/RegionTab.tsx +398 -0
  830. package/src/views/header-footer/chrome-form.ts +603 -0
  831. package/src/views/header-footer/code-samples.ts +146 -0
  832. package/src/views/header-footer/controls.tsx +166 -0
  833. package/src/views/lazy-views.tsx +12 -0
  834. package/src/views/page-editor/PageTab.tsx +2 -2
  835. package/src/views/page-editor/ReviewBar.tsx +1 -1
  836. package/src/views/page-editor/VersionHistoryPanel.tsx +1 -1
  837. package/src/views/seo/AuditTab.tsx +1 -1
  838. package/src/views/seo/OverviewTab.tsx +6 -5
  839. package/src/views/seo/ProposalsTab.tsx +1 -1
  840. package/src/views/settings/AISettingsTab.tsx +10 -6
  841. package/src/views/settings/AccessProtectionCard.tsx +1 -1
  842. package/src/views/settings/AdminThemeCard.tsx +228 -35
  843. package/src/views/settings/AppearanceTab.tsx +10 -6
  844. package/src/views/settings/BrandPreviewCard.tsx +1 -1
  845. package/src/views/settings/BrandVoiceCard.tsx +1 -1
  846. package/src/views/settings/EmailSettingsTab.tsx +11 -7
  847. package/src/views/settings/GeneralSettingsTab.tsx +10 -6
  848. package/src/views/settings/ProviderConnectionCard.tsx +1 -1
  849. package/src/views/settings/SearchDataCard.tsx +1 -1
  850. package/src/views/settings/SecurityStatusCard.tsx +2 -2
  851. package/src/views/settings/SecurityTab.tsx +10 -6
  852. package/src/views/settings/SeoAutopilotCard.tsx +2 -2
  853. package/src/views/settings/SeoSettingsTab.tsx +13 -9
  854. package/src/views/settings/SiteIndexStatusCard.tsx +1 -1
  855. package/src/views/settings/SiteThemeCard.tsx +1 -1
  856. package/src/views/settings/UpdatesTab.tsx +107 -101
  857. package/src/views/settings/components.tsx +26 -62
  858. package/src/views/settings/useAppearanceSettings.ts +116 -25
  859. package/src/views/users/UserDetailDrawer.tsx +1 -1
  860. package/dist/components/ui/StatPill.d.ts +0 -18
  861. package/dist/components/ui/StatPill.d.ts.map +0 -1
  862. package/dist/components/ui/StatPill.js +0 -5
  863. package/dist/components/ui/StatPill.js.map +0 -1
  864. package/src/components/ui/StatPill.tsx +0 -37
@@ -1,18 +1,44 @@
1
1
  'use client'
2
2
 
3
- import { ACCENT_PRESET_LIST } from '@prenta/core/appearance'
4
- import type { ColorMode, SidebarDensity } from '@prenta/core/appearance'
5
- import { Check, Monitor, Moon, Sun } from 'lucide-react'
3
+ import {
4
+ ACCENT_PRESETS,
5
+ ACCENT_PRESET_LIST,
6
+ isAccentPreset,
7
+ toHex,
8
+ type SidebarDensity,
9
+ } from '@prenta/core/appearance'
10
+ import { Check } from 'lucide-react'
11
+ import { useState } from 'react'
6
12
 
13
+ import type { ThemeBase } from '../../components/ThemeProvider.js'
14
+ import { inputVariants } from '../../components/ui/Input.js'
15
+ import { Toggle } from '../../components/ui/Toggle.js'
7
16
  import { SettingsSourceBadge } from './components.js'
8
17
  import type { UseAppearanceSettings } from './useAppearanceSettings.js'
9
18
 
10
- const COLOR_MODES: { value: ColorMode; label: string; Icon: typeof Sun }[] = [
11
- { value: 'light', label: 'Light', Icon: Sun },
12
- { value: 'dark', label: 'Dark', Icon: Moon },
13
- { value: 'system', label: 'System', Icon: Monitor },
19
+ /** The kit's three bases (prototype/design-system/theme.js `BASES`). */
20
+ const BASES: { id: ThemeBase; name: string; desc: string }[] = [
21
+ { id: 'porcelain', name: 'Porcelain', desc: 'Cool neutral light' },
22
+ { id: 'linen', name: 'Linen', desc: 'Warm neutral light' },
23
+ { id: 'graphite', name: 'Graphite', desc: 'Neutral dark' },
14
24
  ]
15
25
 
26
+ const DEFAULT_ACCENT = ACCENT_PRESET_LIST[0]!
27
+
28
+ /** A typed or picked hex that equals a preset swatch is stored as that preset. */
29
+ function accentFromHex(hex: string): string {
30
+ return ACCENT_PRESET_LIST.find((p) => p.swatch.toLowerCase() === hex)?.name ?? hex
31
+ }
32
+
33
+ /**
34
+ * Rainbow behind the custom-color swatch, built from the preset picks so it
35
+ * stays tied to the palette instead of carrying its own hex values.
36
+ */
37
+ const CUSTOM_SWATCH_BG = `conic-gradient(from 0deg, ${[
38
+ ...[2, 3, 1, 0, 4].map((i) => ACCENT_PRESET_LIST[i]!.swatch),
39
+ ACCENT_PRESET_LIST[2]!.swatch,
40
+ ].join(', ')})`
41
+
16
42
  const DENSITIES: { value: SidebarDensity; label: string }[] = [
17
43
  { value: 'default', label: 'Default' },
18
44
  { value: 'compact', label: 'Compact' },
@@ -27,7 +53,7 @@ function SegmentedGroup<T extends string>({
27
53
  }: {
28
54
  label: string
29
55
  value: T
30
- options: { value: T; label: string; Icon?: typeof Sun }[]
56
+ options: { value: T; label: string }[]
31
57
  canEdit: boolean
32
58
  onChange: (v: T) => void
33
59
  }) {
@@ -37,7 +63,7 @@ function SegmentedGroup<T extends string>({
37
63
  aria-label={label}
38
64
  className="border-border bg-muted inline-flex flex-wrap rounded-md border p-0.5"
39
65
  >
40
- {options.map(({ value: v, label: text, Icon }) => {
66
+ {options.map(({ value: v, label: text }) => {
41
67
  const active = value === v
42
68
  return (
43
69
  <button
@@ -53,7 +79,6 @@ function SegmentedGroup<T extends string>({
53
79
  : 'text-muted-foreground hover:text-foreground'
54
80
  }`}
55
81
  >
56
- {Icon && <Icon size={14} aria-hidden="true" />}
57
82
  {text}
58
83
  </button>
59
84
  )
@@ -62,7 +87,86 @@ function SegmentedGroup<T extends string>({
62
87
  )
63
88
  }
64
89
 
90
+ /**
91
+ * A base card. The preview paints with that base's real tokens
92
+ * (`.prenta-base-preview[data-base]` in prenta-tokens.css) and the picked
93
+ * accent, so it can't drift from what the admin renders.
94
+ */
95
+ function BaseCard({
96
+ base,
97
+ checked,
98
+ disabled,
99
+ onPick,
100
+ }: {
101
+ base: (typeof BASES)[number]
102
+ checked: boolean
103
+ disabled: boolean
104
+ onPick: () => void
105
+ }) {
106
+ return (
107
+ <button
108
+ type="button"
109
+ role="radio"
110
+ aria-checked={checked}
111
+ disabled={disabled}
112
+ onClick={onPick}
113
+ className={`bg-card focus-visible:shadow-ring flex flex-col overflow-hidden rounded-[11px] border-[1.5px] text-left transition-colors duration-[var(--mo-fast)] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 ${
114
+ checked ? 'border-acc shadow-[0_0_0_3px_var(--acc-l)]' : 'border-bdr hover:border-faint'
115
+ }`}
116
+ >
117
+ <div aria-hidden="true" className="prenta-base-preview w-full" data-base={base.id}>
118
+ <div className="border-bdr bg-bg flex h-[92px] gap-[7px] border-b p-[9px]">
119
+ <div className="border-bdr bg-card rounded-5 flex w-[30%] flex-col gap-[5px] border p-1.5">
120
+ <i className="bg-acc block h-[5px] rounded-[3px]" />
121
+ <i className="bg-bdr block h-[5px] rounded-[3px]" />
122
+ <i className="bg-bdr block h-[5px] rounded-[3px]" />
123
+ </div>
124
+ <div className="flex flex-1">
125
+ <div className="border-bdr bg-card rounded-5 flex flex-1 flex-col gap-1.5 border p-2">
126
+ <i className="bg-txt block h-[5px] w-[46%] rounded-[3px]" />
127
+ <i className="bg-bdr block h-[5px] w-[78%] rounded-[3px]" />
128
+ <span className="bg-acc rounded-4 mt-auto h-3 w-[38px]" />
129
+ </div>
130
+ </div>
131
+ </div>
132
+ </div>
133
+ <div className="relative flex items-baseline gap-2 px-3 py-2.5">
134
+ <span className="text-body text-txt font-semibold">{base.name}</span>
135
+ <span className="text-hint text-sub">{base.desc}</span>
136
+ {checked && (
137
+ <span className="bg-acc text-acc-on absolute top-[9px] right-2.5 flex h-5 w-5 items-center justify-center rounded-full">
138
+ <Check size={13} aria-hidden="true" />
139
+ </span>
140
+ )}
141
+ </div>
142
+ </button>
143
+ )
144
+ }
145
+
65
146
  export function AdminThemeCard({ s, canEdit }: { s: UseAppearanceSettings; canEdit: boolean }) {
147
+ const { colorMode, lightBase, accent } = s.appearance
148
+ const matchSystem = colorMode === 'system'
149
+ const current: ThemeBase = colorMode === 'dark' ? 'graphite' : lightBase
150
+ const accentEditable = canEdit && s.sources.accent?.editable !== false
151
+
152
+ // Legacy names (`purple`, `blue`, …) are stored aliases of a picker preset.
153
+ const preset = isAccentPreset(accent)
154
+ ? ACCENT_PRESET_LIST.find((p) => p.swatch === ACCENT_PRESETS[accent].swatch)
155
+ : undefined
156
+ const accentHex = preset?.swatch ?? toHex(accent) ?? DEFAULT_ACCENT.swatch
157
+ // What the hex field shows while a value is half-typed; null shows the accent.
158
+ const [hexDraft, setHexDraft] = useState<string | null>(null)
159
+
160
+ const onHex = (raw: string) => {
161
+ const v = raw.startsWith('#') ? raw : `#${raw}`
162
+ if (/^#[0-9a-f]{6}$/i.test(v)) {
163
+ setHexDraft(null)
164
+ s.setAccent(accentFromHex(v.toLowerCase()))
165
+ } else {
166
+ setHexDraft(v)
167
+ }
168
+ }
169
+
66
170
  return (
67
171
  <section className="border-border bg-card rounded-lg border p-6">
68
172
  <header className="mb-4">
@@ -75,61 +179,150 @@ export function AdminThemeCard({ s, canEdit }: { s: UseAppearanceSettings; canEd
75
179
  <div className="space-y-5">
76
180
  <div>
77
181
  <div className="mb-2 flex items-center gap-2">
78
- <span className="text-foreground text-base font-medium">Color mode</span>
182
+ <span id="admin-theme-base" className="text-sm2 text-txt font-semibold">
183
+ Base theme
184
+ </span>
79
185
  <SettingsSourceBadge meta={s.sources.colorMode} />
80
186
  </div>
81
- <SegmentedGroup
82
- label="Color mode"
83
- value={s.appearance.colorMode}
84
- options={COLOR_MODES}
85
- canEdit={canEdit}
86
- onChange={s.setColorMode}
187
+ <div
188
+ role="radiogroup"
189
+ aria-labelledby="admin-theme-base"
190
+ className="grid grid-cols-[repeat(auto-fill,minmax(180px,1fr))] gap-3"
191
+ >
192
+ {BASES.map((base) => (
193
+ <BaseCard
194
+ key={base.id}
195
+ base={base}
196
+ checked={!matchSystem && current === base.id}
197
+ disabled={!canEdit}
198
+ onPick={() => s.setBase(base.id)}
199
+ />
200
+ ))}
201
+ </div>
202
+ </div>
203
+
204
+ <div className="flex items-center justify-between gap-5">
205
+ <div>
206
+ <div id="admin-theme-system" className="text-body text-txt font-semibold">
207
+ Match operating system
208
+ </div>
209
+ <div id="admin-theme-system-hint" className="text-hint text-sub mt-[3px]">
210
+ Uses {lightBase === 'linen' ? 'Linen' : 'Porcelain'} by day and Graphite when your OS
211
+ is in dark mode.
212
+ </div>
213
+ </div>
214
+ <Toggle
215
+ checked={matchSystem}
216
+ onCheckedChange={s.setMatchSystem}
217
+ disabled={!canEdit}
218
+ aria-labelledby="admin-theme-system"
219
+ aria-describedby="admin-theme-system-hint"
87
220
  />
88
221
  </div>
89
222
 
90
223
  <div>
91
224
  <div className="mb-2 flex items-center gap-2">
92
- <span className="text-foreground text-base font-medium">Accent color</span>
225
+ <span id="admin-theme-accent" className="text-sm2 text-txt font-semibold">
226
+ Accent color
227
+ </span>
93
228
  <SettingsSourceBadge meta={s.sources.accent} />
94
229
  </div>
95
230
  <div
96
231
  role="radiogroup"
97
- aria-label="Accent color"
232
+ aria-labelledby="admin-theme-accent"
98
233
  className="flex flex-wrap items-center gap-3"
99
234
  >
100
- {ACCENT_PRESET_LIST.map((preset) => {
101
- const active = s.appearance.accent === preset.name
102
- const editable = s.sources.accent?.editable !== false
235
+ {ACCENT_PRESET_LIST.map((p) => {
236
+ const active = preset === p
103
237
  return (
104
238
  <button
105
- key={preset.name}
239
+ key={p.name}
106
240
  type="button"
107
241
  role="radio"
108
242
  aria-checked={active}
109
- aria-label={preset.label}
110
- title={preset.label}
111
- disabled={!canEdit || !editable}
112
- onClick={() => s.setAccent(preset.name)}
113
- className={`focus-visible:ring-ring relative flex h-9 w-9 items-center justify-center rounded-full transition-transform focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 ${
114
- active ? 'ring-foreground ring-2 ring-offset-2' : ''
243
+ aria-label={p.label}
244
+ title={p.label}
245
+ disabled={!accentEditable}
246
+ onClick={() => s.setAccent(p.name)}
247
+ className={`border-card text-acc-on focus-visible:shadow-ring relative flex h-[30px] w-[30px] items-center justify-center rounded-full border-2 transition-transform hover:scale-110 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 ${
248
+ active
249
+ ? 'shadow-[0_0_0_2px_var(--card),0_0_0_4px_var(--txt)]'
250
+ : 'shadow-[0_0_0_1px_var(--bdr)]'
115
251
  }`}
116
- style={{ backgroundColor: preset.swatch }}
252
+ style={{ backgroundColor: p.swatch }}
117
253
  >
118
- {active && <Check size={16} className="text-white" aria-hidden="true" />}
254
+ {active && <Check size={15} className="text-white" aria-hidden="true" />}
119
255
  </button>
120
256
  )
121
257
  })}
258
+ <label
259
+ title="Custom color"
260
+ className={`border-card has-[:focus-visible]:shadow-ring relative flex h-[30px] w-[30px] cursor-pointer items-center justify-center overflow-hidden rounded-full border-2 transition-transform hover:scale-110 ${
261
+ preset
262
+ ? 'shadow-[0_0_0_1px_var(--bdr)]'
263
+ : 'shadow-[0_0_0_2px_var(--card),0_0_0_4px_var(--txt)]'
264
+ } ${accentEditable ? '' : 'pointer-events-none opacity-50'}`}
265
+ style={{ background: preset ? CUSTOM_SWATCH_BG : accentHex }}
266
+ >
267
+ <input
268
+ type="color"
269
+ aria-label="Custom accent"
270
+ value={toHex(accentHex)!}
271
+ disabled={!accentEditable}
272
+ onChange={(e) => s.setAccent(accentFromHex(e.target.value.toLowerCase()))}
273
+ className="absolute inset-0 h-full w-full cursor-pointer border-0 p-0 opacity-0"
274
+ />
275
+ {preset ? (
276
+ <span
277
+ aria-hidden="true"
278
+ className="pointer-events-none text-[15px] font-bold text-white [text-shadow:0_1px_2px_rgba(0,0,0,0.35)]"
279
+ >
280
+ +
281
+ </span>
282
+ ) : (
283
+ <Check size={15} className="pointer-events-none text-white" aria-hidden="true" />
284
+ )}
285
+ </label>
122
286
  {/* Text label so accent is not communicated by color alone. */}
123
- <span className="text-muted-foreground text-sm">
124
- {ACCENT_PRESET_LIST.find((p) => p.name === s.appearance.accent)?.label ??
125
- s.appearance.accent}
287
+ <span className="text-body text-txt ml-1 font-semibold">
288
+ {preset?.label ?? 'Custom'}
126
289
  </span>
127
290
  </div>
291
+ <div className="mt-3 flex items-center gap-2">
292
+ <span
293
+ aria-hidden="true"
294
+ className="rounded-5 h-[18px] w-[18px] shrink-0 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.1)]"
295
+ style={{ background: accentHex }}
296
+ />
297
+ <input
298
+ aria-label="Accent hex value"
299
+ value={(hexDraft ?? accentHex).toUpperCase()}
300
+ spellCheck={false}
301
+ maxLength={7}
302
+ disabled={!accentEditable}
303
+ onChange={(e) => onHex(e.target.value)}
304
+ onBlur={() => setHexDraft(null)}
305
+ className={`${inputVariants({ size: 'sm' })} max-w-[120px] font-mono uppercase`}
306
+ />
307
+ {preset !== DEFAULT_ACCENT && accentEditable && (
308
+ <button
309
+ type="button"
310
+ onClick={() => s.setAccent(DEFAULT_ACCENT.name)}
311
+ className="text-sm2 text-sub hover:bg-acc-l hover:text-acc rounded-7 px-2.5 py-1.5 whitespace-nowrap transition-colors"
312
+ >
313
+ Reset to Cobalt
314
+ </button>
315
+ )}
316
+ </div>
317
+ <p className="text-hint text-faint mt-2 leading-[1.45]">
318
+ Tints, focus rings and the dark-mode variant are derived automatically. Pick a mid-tone
319
+ so white button text stays legible.
320
+ </p>
128
321
  </div>
129
322
 
130
323
  <div>
131
324
  <div className="mb-2 flex items-center gap-2">
132
- <span className="text-foreground text-base font-medium">Sidebar density</span>
325
+ <span className="text-sm2 text-txt font-semibold">Sidebar density</span>
133
326
  </div>
134
327
  <SegmentedGroup
135
328
  label="Sidebar density"
@@ -6,7 +6,8 @@ import { AdminThemeCard } from './AdminThemeCard.js'
6
6
  import { SiteThemeCard } from './SiteThemeCard.js'
7
7
  import { BrandPreviewCard } from './BrandPreviewCard.js'
8
8
  import { BrandingCard } from './BrandingCard.js'
9
- import { SettingsSaveBar, SettingsValidationSummary } from './components.js'
9
+ import { UnsavedBar } from '../../components/ui/UnsavedBar.js'
10
+ import { SettingsValidationSummary, useSavedToast } from './components.js'
10
11
  import { TypographyMotionCard } from './TypographyMotionCard.js'
11
12
  import { useAppearanceSettings } from './useAppearanceSettings.js'
12
13
 
@@ -23,6 +24,7 @@ function CardSkeleton() {
23
24
  export function AppearanceTab({ role, config }: AppearanceTabProps) {
24
25
  const canEdit = role === 'ADMIN'
25
26
  const s = useAppearanceSettings(canEdit, config)
27
+ useSavedToast(s.saveState)
26
28
 
27
29
  if (s.loading) {
28
30
  return (
@@ -70,13 +72,15 @@ export function AppearanceTab({ role, config }: AppearanceTabProps) {
70
72
  <TypographyMotionCard s={s} canEdit={canEdit} />
71
73
  <BrandPreviewCard s={s} />
72
74
 
73
- <SettingsSaveBar
75
+ <UnsavedBar
74
76
  dirty={s.dirty}
75
- canEdit={canEdit}
76
- hasErrors={s.issues.some((i) => i.severity === 'error')}
77
- saveState={s.saveState}
77
+ saving={s.saveState === 'saving'}
78
+ saveDisabled={!canEdit || s.issues.some((i) => i.severity === 'error')}
78
79
  onSave={s.save}
79
- onReset={s.reset}
80
+ onDiscard={s.reset}
81
+ discardLabel="Reset"
82
+ saveLabel="Save changes"
83
+ variant="card"
80
84
  />
81
85
  </div>
82
86
  )
@@ -66,7 +66,7 @@ export function BrandPreviewCard({ s }: { s: UseAppearanceSettings }) {
66
66
  </p>
67
67
  </div>
68
68
  {s.dirty && (
69
- <span className="text-warning bg-warning/10 border-warning/30 rounded-md border px-2 py-0.5 text-xs">
69
+ <span className="text-warning bg-warn-l border-warning/30 rounded-md border px-2 py-0.5 text-xs">
70
70
  Unsaved
71
71
  </span>
72
72
  )}
@@ -344,7 +344,7 @@ export function BrandVoiceCard({
344
344
  {aiReadiness && !aiReadiness.ready && aiReadiness.message && (
345
345
  <div
346
346
  role="status"
347
- className="border-warning/40 bg-warning/10 text-foreground flex items-start gap-3 rounded-lg border p-4 text-sm"
347
+ className="border-warning/40 bg-warn-l text-foreground flex items-start gap-3 rounded-lg border p-4 text-sm"
348
348
  >
349
349
  <AlertTriangle size={16} className="text-warning mt-0.5 shrink-0" aria-hidden="true" />
350
350
  <p>{aiReadiness.message}</p>
@@ -3,7 +3,8 @@
3
3
  import { AlertTriangle, CheckCircle2, Info, KeyRound, Loader2, Send } from 'lucide-react'
4
4
  import { useId } from 'react'
5
5
 
6
- import { SettingsCard, SettingsSaveBar, SettingsToggleRow } from './components.js'
6
+ import { UnsavedBar } from '../../components/ui/UnsavedBar.js'
7
+ import { SettingsCard, SettingsToggleRow, useSavedToast } from './components.js'
7
8
  import {
8
9
  EMAIL_PROVIDER_OPTIONS,
9
10
  useEmailSettings,
@@ -104,7 +105,7 @@ function Notice({
104
105
  }) {
105
106
  const toneClass =
106
107
  tone === 'warning'
107
- ? 'border-warning/30 bg-warning/10 text-warning'
108
+ ? 'border-warning/30 bg-warn-l text-warning'
108
109
  : tone === 'success'
109
110
  ? 'border-success/30 bg-success/10 text-success'
110
111
  : tone === 'error'
@@ -280,6 +281,7 @@ function ProviderFields({ s, canEdit }: { s: UseEmailSettings; canEdit: boolean
280
281
  export function EmailSettingsTab({ role }: { role?: string }) {
281
282
  const canEdit = String(role ?? '').toUpperCase() === 'ADMIN'
282
283
  const s = useEmailSettings(canEdit)
284
+ useSavedToast(s.saveState)
283
285
  const providerGroupId = useId()
284
286
 
285
287
  if (s.loading) {
@@ -423,13 +425,15 @@ export function EmailSettingsTab({ role }: { role?: string }) {
423
425
  )}
424
426
  </SettingsCard>
425
427
 
426
- <SettingsSaveBar
428
+ <UnsavedBar
427
429
  dirty={s.dirty}
428
- canEdit={canEdit}
429
- hasErrors={false}
430
- saveState={s.saveState}
430
+ saving={s.saveState === 'saving'}
431
+ saveDisabled={!canEdit}
431
432
  onSave={() => void s.save()}
432
- onReset={s.reset}
433
+ onDiscard={s.reset}
434
+ discardLabel="Reset"
435
+ saveLabel="Save changes"
436
+ variant="card"
433
437
  />
434
438
  </div>
435
439
  )
@@ -2,7 +2,8 @@
2
2
 
3
3
  import { AlertTriangle, Info } from 'lucide-react'
4
4
  import { useGeneralSettings } from './useGeneralSettings.js'
5
- import { SettingsSaveBar, SettingsValidationSummary } from './components.js'
5
+ import { UnsavedBar } from '../../components/ui/UnsavedBar.js'
6
+ import { SettingsValidationSummary, useSavedToast } from './components.js'
6
7
  import { SiteIndexStatusCard } from './SiteIndexStatusCard.js'
7
8
  import { SiteInformationCard } from './SiteInformationCard.js'
8
9
  import { LanguageRegionCard } from './LanguageRegionCard.js'
@@ -17,6 +18,7 @@ export interface GeneralSettingsTabProps {
17
18
  export function GeneralSettingsTab({ onNavigate, role }: GeneralSettingsTabProps) {
18
19
  const canEdit = role === 'ADMIN'
19
20
  const settings = useGeneralSettings(canEdit)
21
+ useSavedToast(settings.saveState)
20
22
 
21
23
  const runAudit = () => onNavigate?.('/seo?tab=audit')
22
24
 
@@ -113,13 +115,15 @@ export function GeneralSettingsTab({ onNavigate, role }: GeneralSettingsTabProps
113
115
  </div>
114
116
  )}
115
117
 
116
- <SettingsSaveBar
118
+ <UnsavedBar
117
119
  dirty={settings.dirty}
118
- canEdit={canEdit}
119
- hasErrors={settings.hasErrors}
120
- saveState={settings.saveState}
120
+ saving={settings.saveState === 'saving'}
121
+ saveDisabled={!canEdit || settings.hasErrors}
121
122
  onSave={settings.save}
122
- onReset={settings.reset}
123
+ onDiscard={settings.reset}
124
+ discardLabel="Reset"
125
+ saveLabel="Save changes"
126
+ variant="card"
123
127
  />
124
128
  </div>
125
129
  )
@@ -38,7 +38,7 @@ function StatusPill({ status }: { status: AiConnectionStatus }) {
38
38
  : meta.tone === 'error'
39
39
  ? 'border-destructive/30 bg-destructive/10 text-destructive'
40
40
  : meta.tone === 'warn'
41
- ? 'border-warning/30 bg-warning/10 text-warning'
41
+ ? 'border-warning/30 bg-warn-l text-warning'
42
42
  : 'border-border bg-muted text-muted-foreground'
43
43
  return (
44
44
  <span
@@ -376,7 +376,7 @@ export function SearchDataCard({ canEdit }: { canEdit: boolean }) {
376
376
  className={
377
377
  status.syncStatus.state === 'error'
378
378
  ? 'border-destructive/30 bg-destructive/10 text-destructive flex items-start gap-2 rounded-md border p-3'
379
- : 'border-warning/30 bg-warning/10 text-warning flex items-start gap-2 rounded-md border p-3'
379
+ : 'border-warning/30 bg-warn-l text-warning flex items-start gap-2 rounded-md border p-3'
380
380
  }
381
381
  >
382
382
  <AlertTriangle size={14} className="mt-0.5 shrink-0" aria-hidden="true" />
@@ -15,7 +15,7 @@ const LEVEL_STYLES: Record<
15
15
  word: 'Secure',
16
16
  },
17
17
  needs_attention: {
18
- pill: 'bg-warning/15 text-warning border-warning/30',
18
+ pill: 'bg-warn-l text-warning border-warning/30',
19
19
  Icon: ShieldAlert,
20
20
  word: 'Needs attention',
21
21
  },
@@ -29,7 +29,7 @@ const LEVEL_STYLES: Record<
29
29
 
30
30
  const SEVERITY_STYLES: Record<SecurityWarning['severity'], string> = {
31
31
  critical: 'border-destructive/30 bg-destructive/10 text-destructive',
32
- warning: 'border-warning/30 bg-warning/10 text-warning',
32
+ warning: 'border-warning/30 bg-warn-l text-warning',
33
33
  info: 'border-border bg-muted text-muted-foreground',
34
34
  }
35
35
 
@@ -3,10 +3,11 @@
3
3
  import { useEffect } from 'react'
4
4
  import { Loader2, ShieldAlert } from 'lucide-react'
5
5
  import { parseRouteQuery } from '../../router/index.js'
6
+ import { UnsavedBar } from '../../components/ui/UnsavedBar.js'
6
7
  import {
7
8
  ConfirmDangerousSettingDialog,
8
- SettingsSaveBar,
9
9
  SettingsValidationSummary,
10
+ useSavedToast,
10
11
  } from './components.js'
11
12
  import { AccessProtectionCard } from './AccessProtectionCard.js'
12
13
  import { AuthMfaCard } from './AuthMfaCard.js'
@@ -56,6 +57,7 @@ export function SecurityTab({
56
57
  revokeState,
57
58
  revokeAllOtherSessions,
58
59
  } = useSecuritySettings(canEdit)
60
+ useSavedToast(saveState)
59
61
 
60
62
  // Deep-link support: /settings?tab=security&section=sessions|ip-allowlist|audit
61
63
  useEffect(() => {
@@ -180,13 +182,15 @@ export function SecurityTab({
180
182
  onCancel={dismissLockoutPrompt}
181
183
  />
182
184
 
183
- <SettingsSaveBar
185
+ <UnsavedBar
184
186
  dirty={dirty}
185
- canEdit={canEdit}
186
- hasErrors={hasErrors}
187
- saveState={saveState}
187
+ saving={saveState === 'saving'}
188
+ saveDisabled={!canEdit || hasErrors}
188
189
  onSave={() => void save()}
189
- onReset={reset}
190
+ onDiscard={reset}
191
+ discardLabel="Reset"
192
+ saveLabel="Save changes"
193
+ variant="card"
190
194
  />
191
195
  </div>
192
196
  )
@@ -516,7 +516,7 @@ export function SeoAutopilotCard({
516
516
 
517
517
  {paused ? (
518
518
  <section
519
- className="border-warning/30 bg-warning/10 flex flex-wrap items-center justify-between gap-3 rounded-lg border px-4 py-3"
519
+ className="border-warning/30 bg-warn-l flex flex-wrap items-center justify-between gap-3 rounded-lg border px-4 py-3"
520
520
  aria-label="Autopilot is paused"
521
521
  >
522
522
  <p className="text-foreground flex items-start gap-2 text-sm">
@@ -725,7 +725,7 @@ export function SeoAutopilotCard({
725
725
 
726
726
  {vetoed.length > 0 ? (
727
727
  <section
728
- className="border-warning/30 bg-warning/10 flex items-start gap-2 rounded-lg border px-4 py-3 text-sm"
728
+ className="border-warning/30 bg-warn-l flex items-start gap-2 rounded-lg border px-4 py-3 text-sm"
729
729
  aria-label="Governance warning"
730
730
  >
731
731
  <AlertTriangle size={16} className="text-warning mt-0.5 shrink-0" aria-hidden="true" />
@@ -23,11 +23,12 @@ import { SeoGeoSettingsCard } from './SeoGeoSettingsCard.js'
23
23
  import {
24
24
  ConfirmDangerousSettingDialog,
25
25
  SettingsCard,
26
- SettingsSaveBar,
27
26
  SettingsSourceBadge,
28
27
  SettingsToggleRow,
29
28
  SettingsValidationSummary,
29
+ useSavedToast,
30
30
  } from './components.js'
31
+ import { UnsavedBar } from '../../components/ui/UnsavedBar.js'
31
32
  import {
32
33
  META_DESCRIPTION_MAX,
33
34
  META_DESCRIPTION_MIN,
@@ -82,6 +83,7 @@ export interface SeoSettingsTabProps {
82
83
  export function SeoSettingsTab({ onNavigate, role }: SeoSettingsTabProps) {
83
84
  const canEdit = role === 'ADMIN'
84
85
  const seo = useSeoSettings(canEdit)
86
+ useSavedToast(seo.saveState)
85
87
 
86
88
  if (seo.loading) {
87
89
  return (
@@ -133,7 +135,7 @@ export function SeoSettingsTab({ onNavigate, role }: SeoSettingsTabProps) {
133
135
  {!seo.siteUrl ? (
134
136
  <div
135
137
  role="status"
136
- className="border-warning/30 bg-warning/10 text-warning flex items-start gap-2 rounded-lg border p-4 text-sm"
138
+ className="border-warning/30 bg-warn-l text-warning flex items-start gap-2 rounded-lg border p-4 text-sm"
137
139
  >
138
140
  <AlertTriangle size={16} className="mt-0.5 shrink-0" aria-hidden="true" />
139
141
  Set the public site URL in Settings → General. View site and Share stay disabled until it
@@ -142,7 +144,7 @@ export function SeoSettingsTab({ onNavigate, role }: SeoSettingsTabProps) {
142
144
  ) : siteUrlMatchesAdminOrigin(seo.siteUrl) ? (
143
145
  <div
144
146
  role="status"
145
- className="border-warning/30 bg-warning/10 text-warning flex items-start gap-2 rounded-lg border p-4 text-sm"
147
+ className="border-warning/30 bg-warn-l text-warning flex items-start gap-2 rounded-lg border p-4 text-sm"
146
148
  >
147
149
  <AlertTriangle size={16} className="mt-0.5 shrink-0" aria-hidden="true" />
148
150
  This origin is the admin, not the public site. Set the public site URL to the live apex —
@@ -193,13 +195,15 @@ export function SeoSettingsTab({ onNavigate, role }: SeoSettingsTabProps) {
193
195
  </div>
194
196
  )}
195
197
 
196
- <SettingsSaveBar
198
+ <UnsavedBar
197
199
  dirty={seo.dirty}
198
- canEdit={canEdit}
199
- hasErrors={seo.hasErrors}
200
- saveState={seo.saveState}
200
+ saving={seo.saveState === 'saving'}
201
+ saveDisabled={!canEdit || seo.hasErrors}
201
202
  onSave={seo.save}
202
- onReset={seo.reset}
203
+ onDiscard={seo.reset}
204
+ discardLabel="Reset"
205
+ saveLabel="Save changes"
206
+ variant="card"
203
207
  />
204
208
  </div>
205
209
  )
@@ -729,7 +733,7 @@ function SitemapDefaultsCard({
729
733
  description="Control XML sitemap generation and whether search engines are pinged on publish."
730
734
  >
731
735
  {!siteUrl && (
732
- <div className="border-warning/30 bg-warning/10 text-warning mb-4 flex items-start gap-2 rounded-md border p-4 text-sm">
736
+ <div className="border-warning/30 bg-warn-l text-warning mb-4 flex items-start gap-2 rounded-md border p-4 text-sm">
733
737
  <AlertTriangle size={16} className="mt-0.5 shrink-0" aria-hidden="true" />
734
738
  Site URL is not set — sitemap URLs may be incorrect. Set it in Settings → General.
735
739
  </div>