@prenta/admin 2.6.0 → 2.7.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 (801) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/design-system/tokens.css +179 -85
  3. package/design-system/tokens.json +276 -85
  4. package/design-system/tokens.scss +148 -44
  5. package/design-system/tokens.tailwind.cjs +50 -1
  6. package/dist/AdminRoot.d.ts.map +1 -1
  7. package/dist/AdminRoot.js +42 -20
  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/job-drawer.test.d.ts +2 -0
  61. package/dist/__tests__/lib/job-drawer.test.d.ts.map +1 -0
  62. package/dist/__tests__/lib/job-drawer.test.js +393 -0
  63. package/dist/__tests__/lib/job-drawer.test.js.map +1 -0
  64. package/dist/__tests__/lib/job-view.test.d.ts +2 -0
  65. package/dist/__tests__/lib/job-view.test.d.ts.map +1 -0
  66. package/dist/__tests__/lib/job-view.test.js +387 -0
  67. package/dist/__tests__/lib/job-view.test.js.map +1 -0
  68. package/dist/__tests__/lib/jobs-service.test.d.ts +2 -0
  69. package/dist/__tests__/lib/jobs-service.test.d.ts.map +1 -0
  70. package/dist/__tests__/lib/jobs-service.test.js +88 -0
  71. package/dist/__tests__/lib/jobs-service.test.js.map +1 -0
  72. package/dist/__tests__/router/admin-route-order.test.d.ts +2 -0
  73. package/dist/__tests__/router/admin-route-order.test.d.ts.map +1 -0
  74. package/dist/__tests__/router/admin-route-order.test.js +36 -0
  75. package/dist/__tests__/router/admin-route-order.test.js.map +1 -0
  76. package/dist/__tests__/styles/ai-gradient-contrast.test.d.ts +2 -0
  77. package/dist/__tests__/styles/ai-gradient-contrast.test.d.ts.map +1 -0
  78. package/dist/__tests__/styles/ai-gradient-contrast.test.js +110 -0
  79. package/dist/__tests__/styles/ai-gradient-contrast.test.js.map +1 -0
  80. package/dist/__tests__/styles/breakpoint-order.test.d.ts +2 -0
  81. package/dist/__tests__/styles/breakpoint-order.test.d.ts.map +1 -0
  82. package/dist/__tests__/styles/breakpoint-order.test.js +52 -0
  83. package/dist/__tests__/styles/breakpoint-order.test.js.map +1 -0
  84. package/dist/__tests__/styles/responsive-layer.test.js +303 -12
  85. package/dist/__tests__/styles/responsive-layer.test.js.map +1 -1
  86. package/dist/__tests__/styles/tailwind-preset.test.d.ts +2 -0
  87. package/dist/__tests__/styles/tailwind-preset.test.d.ts.map +1 -0
  88. package/dist/__tests__/styles/tailwind-preset.test.js +147 -0
  89. package/dist/__tests__/styles/tailwind-preset.test.js.map +1 -0
  90. package/dist/__tests__/styles/theme-token-scope.test.js +9 -3
  91. package/dist/__tests__/styles/theme-token-scope.test.js.map +1 -1
  92. package/dist/__tests__/styles/tiers.test.d.ts +2 -0
  93. package/dist/__tests__/styles/tiers.test.d.ts.map +1 -0
  94. package/dist/__tests__/styles/tiers.test.js +121 -0
  95. package/dist/__tests__/styles/tiers.test.js.map +1 -0
  96. package/dist/__tests__/styles/tokens-drift.test.js +57 -6
  97. package/dist/__tests__/styles/tokens-drift.test.js.map +1 -1
  98. package/dist/__tests__/views/admin-lazy-route.render.test.js +27 -1
  99. package/dist/__tests__/views/admin-lazy-route.render.test.js.map +1 -1
  100. package/dist/__tests__/views/ai-settings.render.test.js +4 -4
  101. package/dist/__tests__/views/appearance-menus-route.render.test.d.ts +2 -0
  102. package/dist/__tests__/views/appearance-menus-route.render.test.d.ts.map +1 -0
  103. package/dist/__tests__/views/appearance-menus-route.render.test.js +50 -0
  104. package/dist/__tests__/views/appearance-menus-route.render.test.js.map +1 -0
  105. package/dist/__tests__/views/appearance-settings.render.test.js +8 -6
  106. package/dist/__tests__/views/appearance-settings.render.test.js.map +1 -1
  107. package/dist/__tests__/views/appearance-theme-provider.render.test.d.ts +2 -0
  108. package/dist/__tests__/views/appearance-theme-provider.render.test.d.ts.map +1 -0
  109. package/dist/__tests__/views/appearance-theme-provider.render.test.js +286 -0
  110. package/dist/__tests__/views/appearance-theme-provider.render.test.js.map +1 -0
  111. package/dist/__tests__/views/dashboard.test.js +37 -0
  112. package/dist/__tests__/views/dashboard.test.js.map +1 -1
  113. package/dist/__tests__/views/document-edit-navigation.render.test.d.ts +2 -0
  114. package/dist/__tests__/views/document-edit-navigation.render.test.d.ts.map +1 -0
  115. package/dist/__tests__/views/document-edit-navigation.render.test.js +101 -0
  116. package/dist/__tests__/views/document-edit-navigation.render.test.js.map +1 -0
  117. package/dist/__tests__/views/document-edit-routes.render.test.d.ts +2 -0
  118. package/dist/__tests__/views/document-edit-routes.render.test.d.ts.map +1 -0
  119. package/dist/__tests__/views/document-edit-routes.render.test.js +113 -0
  120. package/dist/__tests__/views/document-edit-routes.render.test.js.map +1 -0
  121. package/dist/__tests__/views/email-settings.render.test.js +2 -2
  122. package/dist/__tests__/views/form-entries.render.test.js +15 -0
  123. package/dist/__tests__/views/form-entries.render.test.js.map +1 -1
  124. package/dist/__tests__/views/form-submissions.render.test.js +18 -0
  125. package/dist/__tests__/views/form-submissions.render.test.js.map +1 -1
  126. package/dist/__tests__/views/forms-list.render.test.js +12 -0
  127. package/dist/__tests__/views/forms-list.render.test.js.map +1 -1
  128. package/dist/__tests__/views/general-settings.render.test.js +26 -10
  129. package/dist/__tests__/views/general-settings.render.test.js.map +1 -1
  130. package/dist/__tests__/views/jobs-drawer.render.test.d.ts +2 -0
  131. package/dist/__tests__/views/jobs-drawer.render.test.d.ts.map +1 -0
  132. package/dist/__tests__/views/jobs-drawer.render.test.js +908 -0
  133. package/dist/__tests__/views/jobs-drawer.render.test.js.map +1 -0
  134. package/dist/__tests__/views/jobs-list.render.test.d.ts +2 -0
  135. package/dist/__tests__/views/jobs-list.render.test.d.ts.map +1 -0
  136. package/dist/__tests__/views/jobs-list.render.test.js +695 -0
  137. package/dist/__tests__/views/jobs-list.render.test.js.map +1 -0
  138. package/dist/__tests__/views/kpi-grid.test.d.ts +2 -0
  139. package/dist/__tests__/views/kpi-grid.test.d.ts.map +1 -0
  140. package/dist/__tests__/views/kpi-grid.test.js +26 -0
  141. package/dist/__tests__/views/kpi-grid.test.js.map +1 -0
  142. package/dist/__tests__/views/mcp-connect.render.test.js +1 -0
  143. package/dist/__tests__/views/mcp-connect.render.test.js.map +1 -1
  144. package/dist/__tests__/views/post-section-editor.test.js +3 -1
  145. package/dist/__tests__/views/post-section-editor.test.js.map +1 -1
  146. package/dist/__tests__/views/script-tags.render.test.js +25 -0
  147. package/dist/__tests__/views/script-tags.render.test.js.map +1 -1
  148. package/dist/__tests__/views/security-settings.render.test.js +9 -8
  149. package/dist/__tests__/views/security-settings.render.test.js.map +1 -1
  150. package/dist/__tests__/views/seo-settings.render.test.js +7 -7
  151. package/dist/__tests__/views/seo-settings.render.test.js.map +1 -1
  152. package/dist/__tests__/views/settings-save-bar.render.test.d.ts +2 -0
  153. package/dist/__tests__/views/settings-save-bar.render.test.d.ts.map +1 -0
  154. package/dist/__tests__/views/settings-save-bar.render.test.js +68 -0
  155. package/dist/__tests__/views/settings-save-bar.render.test.js.map +1 -0
  156. package/dist/__tests__/views/settings-save-footer.render.test.js +23 -15
  157. package/dist/__tests__/views/settings-save-footer.render.test.js.map +1 -1
  158. package/dist/__tests__/views/settings-tabs.render.test.d.ts +2 -0
  159. package/dist/__tests__/views/settings-tabs.render.test.d.ts.map +1 -0
  160. package/dist/__tests__/views/settings-tabs.render.test.js +319 -0
  161. package/dist/__tests__/views/settings-tabs.render.test.js.map +1 -0
  162. package/dist/__tests__/views/updates-tab.render.test.js +4 -3
  163. package/dist/__tests__/views/updates-tab.render.test.js.map +1 -1
  164. package/dist/components/Breadcrumbs.d.ts +8 -1
  165. package/dist/components/Breadcrumbs.d.ts.map +1 -1
  166. package/dist/components/Breadcrumbs.js +6 -0
  167. package/dist/components/Breadcrumbs.js.map +1 -1
  168. package/dist/components/CommandPalette.d.ts.map +1 -1
  169. package/dist/components/CommandPalette.js +40 -4
  170. package/dist/components/CommandPalette.js.map +1 -1
  171. package/dist/components/LocaleSwitcher.d.ts.map +1 -1
  172. package/dist/components/LocaleSwitcher.js +1 -1
  173. package/dist/components/LocaleSwitcher.js.map +1 -1
  174. package/dist/components/NotificationBell.d.ts.map +1 -1
  175. package/dist/components/NotificationBell.js +44 -3
  176. package/dist/components/NotificationBell.js.map +1 -1
  177. package/dist/components/OfflineStatus.js +1 -1
  178. package/dist/components/OfflineStatus.js.map +1 -1
  179. package/dist/components/PresenceIndicator.d.ts.map +1 -1
  180. package/dist/components/PresenceIndicator.js +2 -1
  181. package/dist/components/PresenceIndicator.js.map +1 -1
  182. package/dist/components/ReflowMeter.js +2 -2
  183. package/dist/components/ReflowMeter.js.map +1 -1
  184. package/dist/components/SEOPanel.js +2 -2
  185. package/dist/components/SEOPanel.js.map +1 -1
  186. package/dist/components/ThemeProvider.d.ts +24 -4
  187. package/dist/components/ThemeProvider.d.ts.map +1 -1
  188. package/dist/components/ThemeProvider.js +80 -22
  189. package/dist/components/ThemeProvider.js.map +1 -1
  190. package/dist/components/TipTapEditor.d.ts.map +1 -1
  191. package/dist/components/TipTapEditor.js +3 -4
  192. package/dist/components/TipTapEditor.js.map +1 -1
  193. package/dist/components/forms/EmbedPanel.js +1 -1
  194. package/dist/components/forms/EmbedPanel.js.map +1 -1
  195. package/dist/components/forms/FormEntryDetailPane.js +6 -1
  196. package/dist/components/forms/FormEntryDetailPane.js.map +1 -1
  197. package/dist/components/forms/ShortcodeGlossary.d.ts.map +1 -1
  198. package/dist/components/forms/ShortcodeGlossary.js +6 -1
  199. package/dist/components/forms/ShortcodeGlossary.js.map +1 -1
  200. package/dist/components/forms/primitives.d.ts +15 -5
  201. package/dist/components/forms/primitives.d.ts.map +1 -1
  202. package/dist/components/forms/primitives.js +11 -11
  203. package/dist/components/forms/primitives.js.map +1 -1
  204. package/dist/components/pages/tag-badges.d.ts +2 -1
  205. package/dist/components/pages/tag-badges.d.ts.map +1 -1
  206. package/dist/components/pages/tag-badges.js +4 -3
  207. package/dist/components/pages/tag-badges.js.map +1 -1
  208. package/dist/components/seo/PageAuditPanel.js +2 -2
  209. package/dist/components/seo/PageAuditPanel.js.map +1 -1
  210. package/dist/components/seo/SerpPreview.d.ts +4 -4
  211. package/dist/components/seo/SerpPreview.js +1 -1
  212. package/dist/components/seo/SerpPreview.js.map +1 -1
  213. package/dist/components/seo/primitives.js +2 -2
  214. package/dist/components/seo/primitives.js.map +1 -1
  215. package/dist/components/ui/AuthorAvatar.d.ts +4 -4
  216. package/dist/components/ui/AuthorAvatar.d.ts.map +1 -1
  217. package/dist/components/ui/AuthorAvatar.js +11 -10
  218. package/dist/components/ui/AuthorAvatar.js.map +1 -1
  219. package/dist/components/ui/Badge.d.ts +1 -1
  220. package/dist/components/ui/Badge.js +1 -1
  221. package/dist/components/ui/Badge.js.map +1 -1
  222. package/dist/components/ui/Breadcrumb.d.ts +27 -0
  223. package/dist/components/ui/Breadcrumb.d.ts.map +1 -0
  224. package/dist/components/ui/Breadcrumb.js +41 -0
  225. package/dist/components/ui/Breadcrumb.js.map +1 -0
  226. package/dist/components/ui/Button.d.ts +2 -2
  227. package/dist/components/ui/Button.d.ts.map +1 -1
  228. package/dist/components/ui/Button.js +31 -16
  229. package/dist/components/ui/Button.js.map +1 -1
  230. package/dist/components/ui/Card.d.ts +8 -4
  231. package/dist/components/ui/Card.d.ts.map +1 -1
  232. package/dist/components/ui/Card.js +21 -13
  233. package/dist/components/ui/Card.js.map +1 -1
  234. package/dist/components/ui/CardListControls.d.ts +34 -0
  235. package/dist/components/ui/CardListControls.d.ts.map +1 -0
  236. package/dist/components/ui/CardListControls.js +25 -0
  237. package/dist/components/ui/CardListControls.js.map +1 -0
  238. package/dist/components/ui/CountChip.d.ts +20 -0
  239. package/dist/components/ui/CountChip.d.ts.map +1 -0
  240. package/dist/components/ui/CountChip.js +48 -0
  241. package/dist/components/ui/CountChip.js.map +1 -0
  242. package/dist/components/ui/FilterPill.d.ts +2 -1
  243. package/dist/components/ui/FilterPill.d.ts.map +1 -1
  244. package/dist/components/ui/FilterPill.js +3 -2
  245. package/dist/components/ui/FilterPill.js.map +1 -1
  246. package/dist/components/ui/Input.d.ts +1 -1
  247. package/dist/components/ui/InspectorPane.d.ts +1 -1
  248. package/dist/components/ui/InspectorPane.d.ts.map +1 -1
  249. package/dist/components/ui/InspectorPane.js +15 -4
  250. package/dist/components/ui/InspectorPane.js.map +1 -1
  251. package/dist/components/ui/Modal.d.ts.map +1 -1
  252. package/dist/components/ui/Modal.js +10 -2
  253. package/dist/components/ui/Modal.js.map +1 -1
  254. package/dist/components/ui/PageHeader.d.ts +28 -0
  255. package/dist/components/ui/PageHeader.d.ts.map +1 -0
  256. package/dist/components/ui/PageHeader.js +18 -0
  257. package/dist/components/ui/PageHeader.js.map +1 -0
  258. package/dist/components/ui/RowActions.d.ts +5 -0
  259. package/dist/components/ui/RowActions.d.ts.map +1 -1
  260. package/dist/components/ui/RowActions.js +7 -2
  261. package/dist/components/ui/RowActions.js.map +1 -1
  262. package/dist/components/ui/Segmented.d.ts +21 -0
  263. package/dist/components/ui/Segmented.d.ts.map +1 -0
  264. package/dist/components/ui/Segmented.js +41 -0
  265. package/dist/components/ui/Segmented.js.map +1 -0
  266. package/dist/components/ui/Toaster.d.ts +12 -0
  267. package/dist/components/ui/Toaster.d.ts.map +1 -0
  268. package/dist/components/ui/Toaster.js +103 -0
  269. package/dist/components/ui/Toaster.js.map +1 -0
  270. package/dist/components/ui/Toggle.d.ts +4 -3
  271. package/dist/components/ui/Toggle.d.ts.map +1 -1
  272. package/dist/components/ui/Toggle.js +16 -12
  273. package/dist/components/ui/Toggle.js.map +1 -1
  274. package/dist/components/ui/UnderlineTabs.d.ts +56 -0
  275. package/dist/components/ui/UnderlineTabs.d.ts.map +1 -0
  276. package/dist/components/ui/UnderlineTabs.js +205 -0
  277. package/dist/components/ui/UnderlineTabs.js.map +1 -0
  278. package/dist/components/ui/UnsavedBar.d.ts +25 -0
  279. package/dist/components/ui/UnsavedBar.d.ts.map +1 -0
  280. package/dist/components/ui/UnsavedBar.js +22 -0
  281. package/dist/components/ui/UnsavedBar.js.map +1 -0
  282. package/dist/components/ui/admin-links.d.ts +11 -0
  283. package/dist/components/ui/admin-links.d.ts.map +1 -0
  284. package/dist/components/ui/admin-links.js +10 -0
  285. package/dist/components/ui/admin-links.js.map +1 -0
  286. package/dist/components/ui/card-table.d.ts +43 -0
  287. package/dist/components/ui/card-table.d.ts.map +1 -0
  288. package/dist/components/ui/card-table.js +31 -0
  289. package/dist/components/ui/card-table.js.map +1 -0
  290. package/dist/components/virtual-window.d.ts +7 -0
  291. package/dist/components/virtual-window.d.ts.map +1 -1
  292. package/dist/components/virtual-window.js +5 -2
  293. package/dist/components/virtual-window.js.map +1 -1
  294. package/dist/fields/RelationshipField.js +1 -1
  295. package/dist/fields/RelationshipField.js.map +1 -1
  296. package/dist/files/dm-mono-latin-400-normal.woff +0 -0
  297. package/dist/files/dm-mono-latin-400-normal.woff2 +0 -0
  298. package/dist/files/dm-mono-latin-500-normal.woff +0 -0
  299. package/dist/files/dm-mono-latin-500-normal.woff2 +0 -0
  300. package/dist/files/dm-mono-latin-ext-400-normal.woff +0 -0
  301. package/dist/files/dm-mono-latin-ext-400-normal.woff2 +0 -0
  302. package/dist/files/dm-mono-latin-ext-500-normal.woff +0 -0
  303. package/dist/files/dm-mono-latin-ext-500-normal.woff2 +0 -0
  304. package/dist/files/dm-sans-latin-400-normal.woff +0 -0
  305. package/dist/files/dm-sans-latin-400-normal.woff2 +0 -0
  306. package/dist/files/dm-sans-latin-500-normal.woff +0 -0
  307. package/dist/files/dm-sans-latin-500-normal.woff2 +0 -0
  308. package/dist/files/dm-sans-latin-600-normal.woff +0 -0
  309. package/dist/files/dm-sans-latin-600-normal.woff2 +0 -0
  310. package/dist/files/dm-sans-latin-700-normal.woff +0 -0
  311. package/dist/files/dm-sans-latin-700-normal.woff2 +0 -0
  312. package/dist/files/dm-sans-latin-ext-400-normal.woff +0 -0
  313. package/dist/files/dm-sans-latin-ext-400-normal.woff2 +0 -0
  314. package/dist/files/dm-sans-latin-ext-500-normal.woff +0 -0
  315. package/dist/files/dm-sans-latin-ext-500-normal.woff2 +0 -0
  316. package/dist/files/dm-sans-latin-ext-600-normal.woff +0 -0
  317. package/dist/files/dm-sans-latin-ext-600-normal.woff2 +0 -0
  318. package/dist/files/dm-sans-latin-ext-700-normal.woff +0 -0
  319. package/dist/files/dm-sans-latin-ext-700-normal.woff2 +0 -0
  320. package/dist/hooks/useAppearanceBootstrap.d.ts.map +1 -1
  321. package/dist/hooks/useAppearanceBootstrap.js +9 -3
  322. package/dist/hooks/useAppearanceBootstrap.js.map +1 -1
  323. package/dist/index.d.ts +15 -0
  324. package/dist/index.d.ts.map +1 -1
  325. package/dist/index.js +8 -0
  326. package/dist/index.js.map +1 -1
  327. package/dist/layout/Header.d.ts +14 -5
  328. package/dist/layout/Header.d.ts.map +1 -1
  329. package/dist/layout/Header.js +78 -13
  330. package/dist/layout/Header.js.map +1 -1
  331. package/dist/layout/Layout.d.ts +5 -3
  332. package/dist/layout/Layout.d.ts.map +1 -1
  333. package/dist/layout/Layout.js +45 -54
  334. package/dist/layout/Layout.js.map +1 -1
  335. package/dist/layout/MobileTabBar.d.ts +20 -0
  336. package/dist/layout/MobileTabBar.d.ts.map +1 -0
  337. package/dist/layout/MobileTabBar.js +29 -0
  338. package/dist/layout/MobileTabBar.js.map +1 -0
  339. package/dist/layout/Sidebar.d.ts +8 -26
  340. package/dist/layout/Sidebar.d.ts.map +1 -1
  341. package/dist/layout/Sidebar.js +309 -345
  342. package/dist/layout/Sidebar.js.map +1 -1
  343. package/dist/layout/nav-config.d.ts +101 -0
  344. package/dist/layout/nav-config.d.ts.map +1 -0
  345. package/dist/layout/nav-config.js +297 -0
  346. package/dist/layout/nav-config.js.map +1 -0
  347. package/dist/layout/primitives/AdminShell.d.ts +10 -2
  348. package/dist/layout/primitives/AdminShell.d.ts.map +1 -1
  349. package/dist/layout/primitives/AdminShell.js +114 -6
  350. package/dist/layout/primitives/AdminShell.js.map +1 -1
  351. package/dist/layout/topbar-classes.d.ts +8 -0
  352. package/dist/layout/topbar-classes.d.ts.map +1 -0
  353. package/dist/layout/topbar-classes.js +8 -0
  354. package/dist/layout/topbar-classes.js.map +1 -0
  355. package/dist/layout/use-nav-items.d.ts +10 -0
  356. package/dist/layout/use-nav-items.d.ts.map +1 -0
  357. package/dist/layout/use-nav-items.js +39 -0
  358. package/dist/layout/use-nav-items.js.map +1 -0
  359. package/dist/lib/api.d.ts +6 -0
  360. package/dist/lib/api.d.ts.map +1 -1
  361. package/dist/lib/api.js +1 -1
  362. package/dist/lib/api.js.map +1 -1
  363. package/dist/lib/appearance-api.d.ts +3 -1
  364. package/dist/lib/appearance-api.d.ts.map +1 -1
  365. package/dist/lib/appearance-api.js +1 -0
  366. package/dist/lib/appearance-api.js.map +1 -1
  367. package/dist/lib/job-drawer.d.ts +128 -0
  368. package/dist/lib/job-drawer.d.ts.map +1 -0
  369. package/dist/lib/job-drawer.js +351 -0
  370. package/dist/lib/job-drawer.js.map +1 -0
  371. package/dist/lib/job-view.d.ts +187 -0
  372. package/dist/lib/job-view.d.ts.map +1 -0
  373. package/dist/lib/job-view.js +363 -0
  374. package/dist/lib/job-view.js.map +1 -0
  375. package/dist/lib/jobs-service.d.ts +134 -0
  376. package/dist/lib/jobs-service.d.ts.map +1 -0
  377. package/dist/lib/jobs-service.js +179 -0
  378. package/dist/lib/jobs-service.js.map +1 -0
  379. package/dist/lib/sheet-focus.d.ts +24 -0
  380. package/dist/lib/sheet-focus.d.ts.map +1 -0
  381. package/dist/lib/sheet-focus.js +61 -0
  382. package/dist/lib/sheet-focus.js.map +1 -0
  383. package/dist/lib/tiers.d.ts +30 -0
  384. package/dist/lib/tiers.d.ts.map +1 -0
  385. package/dist/lib/tiers.js +43 -0
  386. package/dist/lib/tiers.js.map +1 -0
  387. package/dist/prenta-admin.css +1 -1
  388. package/dist/router/admin-routes.d.ts.map +1 -1
  389. package/dist/router/admin-routes.js +8 -0
  390. package/dist/router/admin-routes.js.map +1 -1
  391. package/dist/router/index.d.ts +5 -1
  392. package/dist/router/index.d.ts.map +1 -1
  393. package/dist/router/index.js +7 -0
  394. package/dist/router/index.js.map +1 -1
  395. package/dist/views/ApiKeys.js +2 -2
  396. package/dist/views/ApiKeys.js.map +1 -1
  397. package/dist/views/AppearanceChrome.d.ts +6 -0
  398. package/dist/views/AppearanceChrome.d.ts.map +1 -0
  399. package/dist/views/AppearanceChrome.js +25 -0
  400. package/dist/views/AppearanceChrome.js.map +1 -0
  401. package/dist/views/CollectionList.d.ts.map +1 -1
  402. package/dist/views/CollectionList.js +73 -53
  403. package/dist/views/CollectionList.js.map +1 -1
  404. package/dist/views/Dashboard.d.ts.map +1 -1
  405. package/dist/views/Dashboard.js +14 -8
  406. package/dist/views/Dashboard.js.map +1 -1
  407. package/dist/views/DocumentEdit.d.ts +6 -1
  408. package/dist/views/DocumentEdit.d.ts.map +1 -1
  409. package/dist/views/DocumentEdit.js +44 -8
  410. package/dist/views/DocumentEdit.js.map +1 -1
  411. package/dist/views/FormDeliveries.d.ts.map +1 -1
  412. package/dist/views/FormDeliveries.js +7 -1
  413. package/dist/views/FormDeliveries.js.map +1 -1
  414. package/dist/views/FormEntries.d.ts.map +1 -1
  415. package/dist/views/FormEntries.js +11 -2
  416. package/dist/views/FormEntries.js.map +1 -1
  417. package/dist/views/FormSubmissions.d.ts +1 -1
  418. package/dist/views/FormSubmissions.d.ts.map +1 -1
  419. package/dist/views/FormSubmissions.js +15 -4
  420. package/dist/views/FormSubmissions.js.map +1 -1
  421. package/dist/views/Forms.d.ts.map +1 -1
  422. package/dist/views/Forms.js +6 -4
  423. package/dist/views/Forms.js.map +1 -1
  424. package/dist/views/FormsSettings.d.ts +2 -0
  425. package/dist/views/FormsSettings.d.ts.map +1 -0
  426. package/dist/views/FormsSettings.js +37 -0
  427. package/dist/views/FormsSettings.js.map +1 -0
  428. package/dist/views/Jobs/BusyButton.d.ts +15 -0
  429. package/dist/views/Jobs/BusyButton.d.ts.map +1 -0
  430. package/dist/views/Jobs/BusyButton.js +26 -0
  431. package/dist/views/Jobs/BusyButton.js.map +1 -0
  432. package/dist/views/Jobs/CancelJobDialog.d.ts +21 -0
  433. package/dist/views/Jobs/CancelJobDialog.d.ts.map +1 -0
  434. package/dist/views/Jobs/CancelJobDialog.js +66 -0
  435. package/dist/views/Jobs/CancelJobDialog.js.map +1 -0
  436. package/dist/views/Jobs/DrawerActivity.d.ts +16 -0
  437. package/dist/views/Jobs/DrawerActivity.d.ts.map +1 -0
  438. package/dist/views/Jobs/DrawerActivity.js +59 -0
  439. package/dist/views/Jobs/DrawerActivity.js.map +1 -0
  440. package/dist/views/Jobs/DrawerOverview.d.ts +28 -0
  441. package/dist/views/Jobs/DrawerOverview.d.ts.map +1 -0
  442. package/dist/views/Jobs/DrawerOverview.js +32 -0
  443. package/dist/views/Jobs/DrawerOverview.js.map +1 -0
  444. package/dist/views/Jobs/DrawerResults.d.ts +25 -0
  445. package/dist/views/Jobs/DrawerResults.d.ts.map +1 -0
  446. package/dist/views/Jobs/DrawerResults.js +50 -0
  447. package/dist/views/Jobs/DrawerResults.js.map +1 -0
  448. package/dist/views/Jobs/DrawerReview.d.ts +44 -0
  449. package/dist/views/Jobs/DrawerReview.d.ts.map +1 -0
  450. package/dist/views/Jobs/DrawerReview.js +110 -0
  451. package/dist/views/Jobs/DrawerReview.js.map +1 -0
  452. package/dist/views/Jobs/JobDrawer.d.ts +31 -0
  453. package/dist/views/Jobs/JobDrawer.d.ts.map +1 -0
  454. package/dist/views/Jobs/JobDrawer.js +353 -0
  455. package/dist/views/Jobs/JobDrawer.js.map +1 -0
  456. package/dist/views/Jobs/JobsTable.d.ts +19 -0
  457. package/dist/views/Jobs/JobsTable.d.ts.map +1 -0
  458. package/dist/views/Jobs/JobsTable.js +80 -0
  459. package/dist/views/Jobs/JobsTable.js.map +1 -0
  460. package/dist/views/Jobs/WorkerStrip.d.ts +22 -0
  461. package/dist/views/Jobs/WorkerStrip.d.ts.map +1 -0
  462. package/dist/views/Jobs/WorkerStrip.js +63 -0
  463. package/dist/views/Jobs/WorkerStrip.js.map +1 -0
  464. package/dist/views/Jobs/atoms.d.ts +19 -0
  465. package/dist/views/Jobs/atoms.d.ts.map +1 -0
  466. package/dist/views/Jobs/atoms.js +52 -0
  467. package/dist/views/Jobs/atoms.js.map +1 -0
  468. package/dist/views/Jobs/focus.d.ts +23 -0
  469. package/dist/views/Jobs/focus.d.ts.map +1 -0
  470. package/dist/views/Jobs/focus.js +54 -0
  471. package/dist/views/Jobs/focus.js.map +1 -0
  472. package/dist/views/Jobs/icons.d.ts +22 -0
  473. package/dist/views/Jobs/icons.d.ts.map +1 -0
  474. package/dist/views/Jobs/icons.js +23 -0
  475. package/dist/views/Jobs/icons.js.map +1 -0
  476. package/dist/views/Jobs/placeholders.d.ts +6 -0
  477. package/dist/views/Jobs/placeholders.d.ts.map +1 -0
  478. package/dist/views/Jobs/placeholders.js +20 -0
  479. package/dist/views/Jobs/placeholders.js.map +1 -0
  480. package/dist/views/Jobs/useJobDetail.d.ts +21 -0
  481. package/dist/views/Jobs/useJobDetail.d.ts.map +1 -0
  482. package/dist/views/Jobs/useJobDetail.js +39 -0
  483. package/dist/views/Jobs/useJobDetail.js.map +1 -0
  484. package/dist/views/Jobs/useJobsFeed.d.ts +35 -0
  485. package/dist/views/Jobs/useJobsFeed.d.ts.map +1 -0
  486. package/dist/views/Jobs/useJobsFeed.js +231 -0
  487. package/dist/views/Jobs/useJobsFeed.js.map +1 -0
  488. package/dist/views/Jobs/useReviewItems.d.ts +39 -0
  489. package/dist/views/Jobs/useReviewItems.d.ts.map +1 -0
  490. package/dist/views/Jobs/useReviewItems.js +140 -0
  491. package/dist/views/Jobs/useReviewItems.js.map +1 -0
  492. package/dist/views/Jobs.d.ts +10 -1
  493. package/dist/views/Jobs.d.ts.map +1 -1
  494. package/dist/views/Jobs.js +126 -35
  495. package/dist/views/Jobs.js.map +1 -1
  496. package/dist/views/MediaBrowser.d.ts.map +1 -1
  497. package/dist/views/MediaBrowser.js +37 -9
  498. package/dist/views/MediaBrowser.js.map +1 -1
  499. package/dist/views/Pages/PagesListView.d.ts +1 -1
  500. package/dist/views/Pages/PagesListView.d.ts.map +1 -1
  501. package/dist/views/Pages/PagesListView.js +34 -5
  502. package/dist/views/Pages/PagesListView.js.map +1 -1
  503. package/dist/views/Posts/NewPostTypeInstructions.d.ts.map +1 -1
  504. package/dist/views/Posts/NewPostTypeInstructions.js +12 -2
  505. package/dist/views/Posts/NewPostTypeInstructions.js.map +1 -1
  506. package/dist/views/Posts/PostTypesView.d.ts.map +1 -1
  507. package/dist/views/Posts/PostTypesView.js +10 -1
  508. package/dist/views/Posts/PostTypesView.js.map +1 -1
  509. package/dist/views/Posts/PostsListView.d.ts +1 -2
  510. package/dist/views/Posts/PostsListView.d.ts.map +1 -1
  511. package/dist/views/Posts/PostsListView.js +31 -3
  512. package/dist/views/Posts/PostsListView.js.map +1 -1
  513. package/dist/views/SEO.d.ts.map +1 -1
  514. package/dist/views/SEO.js +3 -3
  515. package/dist/views/SEO.js.map +1 -1
  516. package/dist/views/ScriptTags.d.ts.map +1 -1
  517. package/dist/views/ScriptTags.js +20 -15
  518. package/dist/views/ScriptTags.js.map +1 -1
  519. package/dist/views/Settings.d.ts.map +1 -1
  520. package/dist/views/Settings.js +115 -51
  521. package/dist/views/Settings.js.map +1 -1
  522. package/dist/views/SpamFolder.d.ts +2 -0
  523. package/dist/views/SpamFolder.d.ts.map +1 -0
  524. package/dist/views/SpamFolder.js +14 -0
  525. package/dist/views/SpamFolder.js.map +1 -0
  526. package/dist/views/Trash.d.ts +6 -1
  527. package/dist/views/Trash.d.ts.map +1 -1
  528. package/dist/views/Trash.js +7 -2
  529. package/dist/views/Trash.js.map +1 -1
  530. package/dist/views/Users.js +2 -2
  531. package/dist/views/Users.js.map +1 -1
  532. package/dist/views/WidgetsPlaceholder.d.ts +2 -0
  533. package/dist/views/WidgetsPlaceholder.d.ts.map +1 -0
  534. package/dist/views/WidgetsPlaceholder.js +15 -0
  535. package/dist/views/WidgetsPlaceholder.js.map +1 -0
  536. package/dist/views/dashboard/kpi-grid.d.ts +18 -0
  537. package/dist/views/dashboard/kpi-grid.d.ts.map +1 -0
  538. package/dist/views/dashboard/kpi-grid.js +36 -0
  539. package/dist/views/dashboard/kpi-grid.js.map +1 -0
  540. package/dist/views/lazy-views.d.ts +4 -0
  541. package/dist/views/lazy-views.d.ts.map +1 -1
  542. package/dist/views/lazy-views.js +4 -0
  543. package/dist/views/lazy-views.js.map +1 -1
  544. package/dist/views/page-editor/PageTab.js +1 -1
  545. package/dist/views/page-editor/PageTab.js.map +1 -1
  546. package/dist/views/page-editor/ReviewBar.js +1 -1
  547. package/dist/views/page-editor/ReviewBar.js.map +1 -1
  548. package/dist/views/page-editor/VersionHistoryPanel.js +1 -1
  549. package/dist/views/page-editor/VersionHistoryPanel.js.map +1 -1
  550. package/dist/views/seo/AuditTab.js +1 -1
  551. package/dist/views/seo/AuditTab.js.map +1 -1
  552. package/dist/views/seo/OverviewTab.d.ts.map +1 -1
  553. package/dist/views/seo/OverviewTab.js +2 -2
  554. package/dist/views/seo/OverviewTab.js.map +1 -1
  555. package/dist/views/seo/ProposalsTab.js +1 -1
  556. package/dist/views/seo/ProposalsTab.js.map +1 -1
  557. package/dist/views/settings/AISettingsTab.d.ts.map +1 -1
  558. package/dist/views/settings/AISettingsTab.js +4 -2
  559. package/dist/views/settings/AISettingsTab.js.map +1 -1
  560. package/dist/views/settings/AccessProtectionCard.js +1 -1
  561. package/dist/views/settings/AccessProtectionCard.js.map +1 -1
  562. package/dist/views/settings/AdminThemeCard.d.ts.map +1 -1
  563. package/dist/views/settings/AdminThemeCard.js +63 -15
  564. package/dist/views/settings/AdminThemeCard.js.map +1 -1
  565. package/dist/views/settings/AppearanceTab.d.ts.map +1 -1
  566. package/dist/views/settings/AppearanceTab.js +4 -2
  567. package/dist/views/settings/AppearanceTab.js.map +1 -1
  568. package/dist/views/settings/BrandPreviewCard.js +1 -1
  569. package/dist/views/settings/BrandPreviewCard.js.map +1 -1
  570. package/dist/views/settings/BrandVoiceCard.js +1 -1
  571. package/dist/views/settings/BrandVoiceCard.js.map +1 -1
  572. package/dist/views/settings/EmailSettingsTab.d.ts.map +1 -1
  573. package/dist/views/settings/EmailSettingsTab.js +5 -3
  574. package/dist/views/settings/EmailSettingsTab.js.map +1 -1
  575. package/dist/views/settings/GeneralSettingsTab.d.ts.map +1 -1
  576. package/dist/views/settings/GeneralSettingsTab.js +4 -2
  577. package/dist/views/settings/GeneralSettingsTab.js.map +1 -1
  578. package/dist/views/settings/McpConnectTab.d.ts.map +1 -1
  579. package/dist/views/settings/McpConnectTab.js +1 -1
  580. package/dist/views/settings/McpConnectTab.js.map +1 -1
  581. package/dist/views/settings/ProviderConnectionCard.js +1 -1
  582. package/dist/views/settings/ProviderConnectionCard.js.map +1 -1
  583. package/dist/views/settings/SearchDataCard.js +1 -1
  584. package/dist/views/settings/SearchDataCard.js.map +1 -1
  585. package/dist/views/settings/SecurityStatusCard.js +2 -2
  586. package/dist/views/settings/SecurityStatusCard.js.map +1 -1
  587. package/dist/views/settings/SecurityTab.d.ts.map +1 -1
  588. package/dist/views/settings/SecurityTab.js +4 -2
  589. package/dist/views/settings/SecurityTab.js.map +1 -1
  590. package/dist/views/settings/SeoAutopilotCard.js +2 -2
  591. package/dist/views/settings/SeoAutopilotCard.js.map +1 -1
  592. package/dist/views/settings/SeoSettingsTab.d.ts.map +1 -1
  593. package/dist/views/settings/SeoSettingsTab.js +5 -3
  594. package/dist/views/settings/SeoSettingsTab.js.map +1 -1
  595. package/dist/views/settings/SiteIndexStatusCard.js +1 -1
  596. package/dist/views/settings/SiteIndexStatusCard.js.map +1 -1
  597. package/dist/views/settings/SiteThemeCard.js +1 -1
  598. package/dist/views/settings/UpdatesTab.d.ts.map +1 -1
  599. package/dist/views/settings/UpdatesTab.js +6 -5
  600. package/dist/views/settings/UpdatesTab.js.map +1 -1
  601. package/dist/views/settings/components.d.ts +7 -11
  602. package/dist/views/settings/components.d.ts.map +1 -1
  603. package/dist/views/settings/components.js +18 -12
  604. package/dist/views/settings/components.js.map +1 -1
  605. package/dist/views/settings/useAppearanceSettings.d.ts +7 -1
  606. package/dist/views/settings/useAppearanceSettings.d.ts.map +1 -1
  607. package/dist/views/settings/useAppearanceSettings.js +89 -22
  608. package/dist/views/settings/useAppearanceSettings.js.map +1 -1
  609. package/dist/views/users/UserDetailDrawer.js +1 -1
  610. package/dist/views/users/UserDetailDrawer.js.map +1 -1
  611. package/package.json +11 -9
  612. package/src/AdminRoot.tsx +88 -30
  613. package/src/LoginRoot.tsx +2 -1
  614. package/src/__tests__/components/author-avatar.test.tsx +3 -20
  615. package/src/__tests__/components/notification-bell.test.tsx +146 -14
  616. package/src/__tests__/components/responsive-tiers.render.test.tsx +461 -0
  617. package/src/__tests__/components/serp-preview.render.test.tsx +6 -3
  618. package/src/__tests__/components/shell-primitives.render.test.tsx +951 -0
  619. package/src/__tests__/components/theme-provider-accent.test.tsx +83 -8
  620. package/src/__tests__/components/toggle.test.tsx +11 -3
  621. package/src/__tests__/components/ui-primitives.test.tsx +5 -8
  622. package/src/__tests__/layout/build-nav-items.test.ts +1 -1
  623. package/src/__tests__/layout/shell-nav.render.test.tsx +983 -0
  624. package/src/__tests__/layout/sidebar-forms-submenu.render.test.tsx +8 -4
  625. package/src/__tests__/layout/sidebar-groups.render.test.tsx +116 -0
  626. package/src/__tests__/layout/sidebar-menus.render.test.tsx +116 -0
  627. package/src/__tests__/layout/sidebar-plugin-nav.test.ts +1 -1
  628. package/src/__tests__/layout/sidebar-posts.test.ts +48 -40
  629. package/src/__tests__/layout/sidebar-submenu.render.test.tsx +35 -10
  630. package/src/__tests__/layout/topbar.render.test.tsx +464 -0
  631. package/src/__tests__/lib/api.test.ts +2 -0
  632. package/src/__tests__/lib/job-drawer.test.ts +493 -0
  633. package/src/__tests__/lib/job-view.test.ts +437 -0
  634. package/src/__tests__/lib/jobs-service.test.ts +98 -0
  635. package/src/__tests__/router/admin-route-order.test.ts +39 -0
  636. package/src/__tests__/styles/ai-gradient-contrast.test.ts +135 -0
  637. package/src/__tests__/styles/breakpoint-order.test.ts +68 -0
  638. package/src/__tests__/styles/responsive-layer.test.ts +367 -12
  639. package/src/__tests__/styles/tailwind-preset.test.ts +154 -0
  640. package/src/__tests__/styles/theme-token-scope.test.ts +10 -3
  641. package/src/__tests__/styles/tiers.test.ts +136 -0
  642. package/src/__tests__/styles/tokens-drift.test.ts +67 -6
  643. package/src/__tests__/views/admin-lazy-route.render.test.tsx +41 -1
  644. package/src/__tests__/views/ai-settings.render.test.tsx +4 -4
  645. package/src/__tests__/views/appearance-menus-route.render.test.tsx +58 -0
  646. package/src/__tests__/views/appearance-settings.render.test.tsx +10 -8
  647. package/src/__tests__/views/appearance-theme-provider.render.test.tsx +347 -0
  648. package/src/__tests__/views/dashboard.test.tsx +48 -0
  649. package/src/__tests__/views/document-edit-navigation.render.test.tsx +130 -0
  650. package/src/__tests__/views/document-edit-routes.render.test.tsx +130 -0
  651. package/src/__tests__/views/email-settings.render.test.tsx +2 -2
  652. package/src/__tests__/views/form-entries.render.test.tsx +22 -0
  653. package/src/__tests__/views/form-submissions.render.test.tsx +22 -0
  654. package/src/__tests__/views/forms-list.render.test.tsx +13 -0
  655. package/src/__tests__/views/general-settings.render.test.tsx +38 -11
  656. package/src/__tests__/views/jobs-drawer.render.test.tsx +1047 -0
  657. package/src/__tests__/views/jobs-list.render.test.tsx +850 -0
  658. package/src/__tests__/views/kpi-grid.test.ts +29 -0
  659. package/src/__tests__/views/mcp-connect.render.test.tsx +1 -0
  660. package/src/__tests__/views/post-section-editor.test.tsx +5 -1
  661. package/src/__tests__/views/script-tags.render.test.tsx +29 -0
  662. package/src/__tests__/views/security-settings.render.test.tsx +9 -10
  663. package/src/__tests__/views/seo-settings.render.test.tsx +7 -9
  664. package/src/__tests__/views/settings-save-bar.render.test.tsx +91 -0
  665. package/src/__tests__/views/settings-save-footer.render.test.tsx +25 -15
  666. package/src/__tests__/views/settings-tabs.render.test.tsx +371 -0
  667. package/src/__tests__/views/updates-tab.render.test.tsx +4 -3
  668. package/src/components/Breadcrumbs.tsx +7 -1
  669. package/src/components/CommandPalette.tsx +51 -3
  670. package/src/components/LocaleSwitcher.tsx +5 -6
  671. package/src/components/NotificationBell.tsx +74 -18
  672. package/src/components/OfflineStatus.tsx +1 -1
  673. package/src/components/PresenceIndicator.tsx +2 -1
  674. package/src/components/ReflowMeter.tsx +3 -3
  675. package/src/components/SEOPanel.tsx +2 -2
  676. package/src/components/ThemeProvider.tsx +122 -42
  677. package/src/components/TipTapEditor.tsx +3 -4
  678. package/src/components/forms/EmbedPanel.tsx +1 -1
  679. package/src/components/forms/FormEntryDetailPane.tsx +7 -1
  680. package/src/components/forms/ShortcodeGlossary.tsx +7 -1
  681. package/src/components/forms/primitives.tsx +37 -21
  682. package/src/components/pages/tag-badges.tsx +4 -3
  683. package/src/components/seo/PageAuditPanel.tsx +2 -2
  684. package/src/components/seo/SerpPreview.tsx +5 -5
  685. package/src/components/seo/primitives.tsx +2 -2
  686. package/src/components/ui/AuthorAvatar.tsx +11 -10
  687. package/src/components/ui/Badge.tsx +1 -1
  688. package/src/components/ui/Breadcrumb.tsx +109 -0
  689. package/src/components/ui/Button.tsx +40 -15
  690. package/src/components/ui/Card.tsx +35 -32
  691. package/src/components/ui/CardListControls.tsx +90 -0
  692. package/src/components/ui/CountChip.tsx +90 -0
  693. package/src/components/ui/FilterPill.tsx +5 -3
  694. package/src/components/ui/InspectorPane.tsx +21 -7
  695. package/src/components/ui/Modal.tsx +20 -6
  696. package/src/components/ui/PageHeader.tsx +63 -0
  697. package/src/components/ui/RowActions.tsx +7 -2
  698. package/src/components/ui/Segmented.tsx +97 -0
  699. package/src/components/ui/Toaster.tsx +139 -0
  700. package/src/components/ui/Toggle.tsx +18 -14
  701. package/src/components/ui/UnderlineTabs.tsx +373 -0
  702. package/src/components/ui/UnsavedBar.tsx +119 -0
  703. package/src/components/ui/admin-links.tsx +20 -0
  704. package/src/components/ui/card-table.ts +34 -0
  705. package/src/components/virtual-window.tsx +13 -2
  706. package/src/fields/RelationshipField.tsx +1 -1
  707. package/src/hooks/useAppearanceBootstrap.ts +9 -3
  708. package/src/index.ts +19 -0
  709. package/src/layout/Header.tsx +210 -135
  710. package/src/layout/Layout.tsx +61 -108
  711. package/src/layout/MobileTabBar.tsx +92 -0
  712. package/src/layout/Sidebar.tsx +555 -593
  713. package/src/layout/nav-config.tsx +425 -0
  714. package/src/layout/primitives/AdminShell.tsx +154 -6
  715. package/src/layout/topbar-classes.ts +8 -0
  716. package/src/layout/use-nav-items.ts +40 -0
  717. package/src/lib/api.ts +7 -1
  718. package/src/lib/appearance-api.ts +4 -0
  719. package/src/lib/job-drawer.ts +424 -0
  720. package/src/lib/job-view.ts +456 -0
  721. package/src/lib/jobs-service.ts +290 -0
  722. package/src/lib/sheet-focus.ts +71 -0
  723. package/src/lib/tiers.ts +43 -0
  724. package/src/router/admin-routes.ts +8 -0
  725. package/src/router/index.ts +9 -1
  726. package/src/styles/prenta-tokens.css +263 -82
  727. package/src/styles/responsive.css +460 -22
  728. package/src/styles/theme.css +177 -28
  729. package/src/views/ApiKeys.tsx +2 -2
  730. package/src/views/AppearanceChrome.tsx +74 -0
  731. package/src/views/CollectionList.tsx +264 -205
  732. package/src/views/Dashboard.tsx +26 -13
  733. package/src/views/DocumentEdit.tsx +111 -56
  734. package/src/views/FormDeliveries.tsx +30 -17
  735. package/src/views/FormEntries.tsx +28 -20
  736. package/src/views/FormSubmissions.tsx +32 -34
  737. package/src/views/Forms.tsx +55 -34
  738. package/src/views/FormsSettings.tsx +94 -0
  739. package/src/views/Jobs/BusyButton.tsx +56 -0
  740. package/src/views/Jobs/CancelJobDialog.tsx +127 -0
  741. package/src/views/Jobs/DrawerActivity.tsx +142 -0
  742. package/src/views/Jobs/DrawerOverview.tsx +139 -0
  743. package/src/views/Jobs/DrawerResults.tsx +155 -0
  744. package/src/views/Jobs/DrawerReview.tsx +464 -0
  745. package/src/views/Jobs/JobDrawer.tsx +556 -0
  746. package/src/views/Jobs/JobsTable.tsx +260 -0
  747. package/src/views/Jobs/WorkerStrip.tsx +144 -0
  748. package/src/views/Jobs/atoms.tsx +93 -0
  749. package/src/views/Jobs/focus.ts +56 -0
  750. package/src/views/Jobs/icons.tsx +111 -0
  751. package/src/views/Jobs/placeholders.tsx +66 -0
  752. package/src/views/Jobs/useJobDetail.ts +64 -0
  753. package/src/views/Jobs/useJobsFeed.ts +249 -0
  754. package/src/views/Jobs/useReviewItems.ts +187 -0
  755. package/src/views/Jobs.tsx +282 -105
  756. package/src/views/MediaBrowser.tsx +71 -21
  757. package/src/views/Pages/PagesListView.tsx +115 -39
  758. package/src/views/Posts/NewPostTypeInstructions.tsx +15 -10
  759. package/src/views/Posts/PostTypesView.tsx +28 -6
  760. package/src/views/Posts/PostsListView.tsx +130 -40
  761. package/src/views/SEO.tsx +23 -8
  762. package/src/views/ScriptTags.tsx +233 -153
  763. package/src/views/Settings.tsx +215 -256
  764. package/src/views/SpamFolder.tsx +32 -0
  765. package/src/views/Trash.tsx +12 -1
  766. package/src/views/Users.tsx +2 -2
  767. package/src/views/WidgetsPlaceholder.tsx +33 -0
  768. package/src/views/dashboard/kpi-grid.ts +38 -0
  769. package/src/views/lazy-views.tsx +12 -0
  770. package/src/views/page-editor/PageTab.tsx +2 -2
  771. package/src/views/page-editor/ReviewBar.tsx +1 -1
  772. package/src/views/page-editor/VersionHistoryPanel.tsx +1 -1
  773. package/src/views/seo/AuditTab.tsx +1 -1
  774. package/src/views/seo/OverviewTab.tsx +6 -5
  775. package/src/views/seo/ProposalsTab.tsx +1 -1
  776. package/src/views/settings/AISettingsTab.tsx +10 -6
  777. package/src/views/settings/AccessProtectionCard.tsx +1 -1
  778. package/src/views/settings/AdminThemeCard.tsx +228 -35
  779. package/src/views/settings/AppearanceTab.tsx +10 -6
  780. package/src/views/settings/BrandPreviewCard.tsx +1 -1
  781. package/src/views/settings/BrandVoiceCard.tsx +1 -1
  782. package/src/views/settings/EmailSettingsTab.tsx +11 -7
  783. package/src/views/settings/GeneralSettingsTab.tsx +10 -6
  784. package/src/views/settings/McpConnectTab.tsx +2 -1
  785. package/src/views/settings/ProviderConnectionCard.tsx +1 -1
  786. package/src/views/settings/SearchDataCard.tsx +1 -1
  787. package/src/views/settings/SecurityStatusCard.tsx +2 -2
  788. package/src/views/settings/SecurityTab.tsx +10 -6
  789. package/src/views/settings/SeoAutopilotCard.tsx +2 -2
  790. package/src/views/settings/SeoSettingsTab.tsx +13 -9
  791. package/src/views/settings/SiteIndexStatusCard.tsx +1 -1
  792. package/src/views/settings/SiteThemeCard.tsx +1 -1
  793. package/src/views/settings/UpdatesTab.tsx +107 -101
  794. package/src/views/settings/components.tsx +26 -62
  795. package/src/views/settings/useAppearanceSettings.ts +116 -25
  796. package/src/views/users/UserDetailDrawer.tsx +1 -1
  797. package/dist/components/ui/StatPill.d.ts +0 -18
  798. package/dist/components/ui/StatPill.d.ts.map +0 -1
  799. package/dist/components/ui/StatPill.js +0 -5
  800. package/dist/components/ui/StatPill.js.map +0 -1
  801. package/src/components/ui/StatPill.tsx +0 -37
@@ -1,6 +1,6 @@
1
1
  'use client'
2
2
 
3
- import React, { useCallback, useEffect, useRef, useState } from 'react'
3
+ import React, { useCallback, useEffect, useId, useRef, useState } from 'react'
4
4
 
5
5
  import {
6
6
  type Notification,
@@ -14,6 +14,7 @@ import {
14
14
  subscribeNotificationStream as defaultSubscribeStream,
15
15
  unreadCount as defaultUnreadCount,
16
16
  } from '../lib/notifications-client.js'
17
+ import { TOPBAR_ICON_BUTTON } from '../layout/topbar-classes.js'
17
18
 
18
19
  /**
19
20
  * Top-bar notification bell + dropdown panel. Slice 6 of Phase 3
@@ -97,6 +98,11 @@ export function NotificationBell({
97
98
  const [items, setItems] = useState<Notification[]>([])
98
99
  const [loading, setLoading] = useState(false)
99
100
  const mountedRef = useRef(true)
101
+ const rootRef = useRef<HTMLDivElement>(null)
102
+ const buttonRef = useRef<HTMLButtonElement>(null)
103
+ const panelRef = useRef<HTMLDivElement>(null)
104
+ const panelId = useId()
105
+ const titleId = useId()
100
106
  // Set of notification IDs we've already rendered. The SSE handler
101
107
  // consults this synchronously so duplicate deliveries (REST refresh
102
108
  // + SSE push, or two SSE retries) don't double-bump the badge.
@@ -113,6 +119,9 @@ export function NotificationBell({
113
119
  // SSE and REST`.
114
120
  const seenIdsRef = useRef<Set<string>>(new Set())
115
121
  useEffect(() => {
122
+ // Set on mount too: StrictMode unmounts and remounts once in development,
123
+ // and a ref left false drops every later result (no dot, no rows).
124
+ mountedRef.current = true
116
125
  return () => {
117
126
  mountedRef.current = false
118
127
  }
@@ -198,6 +207,33 @@ export function NotificationBell({
198
207
  void refreshList(false)
199
208
  }, [open, refreshList])
200
209
 
210
+ // The panel is a non-modal dialog: it takes focus when it opens, and a
211
+ // pointerdown anywhere else closes it without moving focus.
212
+ useEffect(() => {
213
+ if (!open) return
214
+ panelRef.current?.focus()
215
+ const onPointerDown = (e: PointerEvent) => {
216
+ if (!rootRef.current?.contains(e.target as Node)) setOpen(false)
217
+ }
218
+ document.addEventListener('pointerdown', onPointerDown, true)
219
+ return () => document.removeEventListener('pointerdown', onPointerDown, true)
220
+ }, [open])
221
+
222
+ const onRootKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
223
+ if (!open || e.key !== 'Escape' || e.defaultPrevented) return
224
+ e.preventDefault()
225
+ setOpen(false)
226
+ buttonRef.current?.focus()
227
+ }
228
+
229
+ // Tabbing past the panel (or back past the bell) closes it. A blur with no
230
+ // next element (a click on the page, the window losing focus) is left to
231
+ // the pointerdown listener.
232
+ const onRootBlur = (e: React.FocusEvent<HTMLDivElement>) => {
233
+ const next = e.relatedTarget as Node | null
234
+ if (open && next && !e.currentTarget.contains(next)) setOpen(false)
235
+ }
236
+
201
237
  const handleClickRow = useCallback(
202
238
  async (n: Notification) => {
203
239
  // Optimistic update: drop the unread count + tag the row read.
@@ -242,35 +278,56 @@ export function NotificationBell({
242
278
  }
243
279
  }, [api, items, onError, refreshUnread])
244
280
 
281
+ const unreadLabel = unread > 99 ? '99+' : String(unread)
282
+
245
283
  return (
246
- <div className={`relative ${className ?? ''}`} data-testid="notification-bell">
284
+ <div
285
+ ref={rootRef}
286
+ className={`relative ${className ?? ''}`}
287
+ data-testid="notification-bell"
288
+ onKeyDown={onRootKeyDown}
289
+ onBlur={onRootBlur}
290
+ >
291
+ {/* The kit's `.icbtn`. The unread count is in the name; the dot only
292
+ says that something is unread (SHELL.md §3). */}
247
293
  <button
294
+ ref={buttonRef}
248
295
  type="button"
249
- className="text-muted-foreground hover:bg-accent hover:text-foreground relative rounded p-1.5"
250
- aria-label="Notifications"
251
- aria-haspopup="menu"
296
+ className={`${TOPBAR_ICON_BUTTON} aria-expanded:bg-acc-l aria-expanded:text-acc`}
297
+ aria-label={unread > 0 ? `Notifications, ${unreadLabel} unread` : 'Notifications'}
298
+ aria-haspopup="dialog"
252
299
  aria-expanded={open}
300
+ aria-controls={open ? panelId : undefined}
253
301
  onClick={() => setOpen((v) => !v)}
254
302
  data-testid="bell-button"
255
303
  >
256
304
  <BellIcon />
257
305
  {unread > 0 && (
258
306
  <span
259
- className="bg-destructive absolute -top-0.5 -right-0.5 inline-flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-medium text-white"
307
+ aria-hidden
308
+ className="border-sb bg-notify-dot pointer-events-none absolute top-[5px] right-[5px] h-[7px] w-[7px] rounded-full border-[1.5px] forced-colors:bg-[CanvasText] forced-colors:[forced-color-adjust:none]"
260
309
  data-testid="bell-badge"
261
- >
262
- {unread > 99 ? '99+' : unread}
263
- </span>
310
+ />
264
311
  )}
265
312
  </button>
266
313
  {open && (
314
+ // Not role="menu": it holds a title, a button and a list of rows, not
315
+ // menu items.
267
316
  <div
268
- role="menu"
269
- className="border-border bg-card absolute right-0 z-50 mt-1 w-80 rounded border shadow-lg"
317
+ ref={panelRef}
318
+ id={panelId}
319
+ role="dialog"
320
+ aria-labelledby={titleId}
321
+ tabIndex={-1}
322
+ className="rounded-10 border-bdr bg-card shadow-shd2 absolute right-0 z-50 mt-1 w-80 border"
270
323
  data-testid="bell-dropdown"
271
324
  >
272
- <header className="flex items-center justify-between border-b border-gray-100 px-3 py-2">
273
- <span className="text-foreground text-sm font-medium">Notifications</span>
325
+ {/* A div, not <header>: the panel sits inside the topbar's
326
+ <header>, which may not contain another. */}
327
+ <div className="border-bdr flex items-center justify-between border-b px-3 py-2">
328
+ <span id={titleId} className="text-foreground text-sm font-medium">
329
+ Notifications
330
+ </span>
274
331
  <button
275
332
  type="button"
276
333
  className="text-muted-foreground hover:text-foreground text-xs disabled:opacity-50"
@@ -280,7 +337,7 @@ export function NotificationBell({
280
337
  >
281
338
  Mark all read
282
339
  </button>
283
- </header>
340
+ </div>
284
341
  <div className="max-h-80 overflow-y-auto" aria-busy={loading} data-testid="bell-list">
285
342
  {loading ? (
286
343
  <p className="text-muted-foreground px-3 py-2 text-xs">Loading…</p>
@@ -292,7 +349,6 @@ export function NotificationBell({
292
349
  <li key={n.id}>
293
350
  <button
294
351
  type="button"
295
- role="menuitem"
296
352
  className={`hover:bg-accent block w-full px-3 py-2 text-left text-xs ${
297
353
  n.readAt ? 'text-muted-foreground' : 'text-foreground font-medium'
298
354
  }`}
@@ -318,12 +374,12 @@ function BellIcon(): React.JSX.Element {
318
374
  return (
319
375
  <svg
320
376
  aria-hidden="true"
321
- width="18"
322
- height="18"
377
+ width="16"
378
+ height="16"
323
379
  viewBox="0 0 24 24"
324
380
  fill="none"
325
381
  stroke="currentColor"
326
- strokeWidth="2"
382
+ strokeWidth="1.75"
327
383
  strokeLinecap="round"
328
384
  strokeLinejoin="round"
329
385
  >
@@ -52,7 +52,7 @@ export type OfflineTone = 'good' | 'warn' | 'info' | 'bad'
52
52
 
53
53
  const TONE_CLASSES: Record<OfflineTone, string> = {
54
54
  good: 'bg-success/10 text-emerald-700',
55
- warn: 'bg-warning/10 text-warning',
55
+ warn: 'bg-warn-l text-warning',
56
56
  info: 'bg-info/10 text-info',
57
57
  bad: 'bg-destructive/10 text-destructive',
58
58
  }
@@ -13,7 +13,8 @@ interface PresenceIndicatorProps {
13
13
  currentUserId?: string
14
14
  }
15
15
 
16
- const COLORS = ['#3b82f6', '#ef4444', '#10b981', '#f59e0b', '#8b5cf6', '#ec4899']
16
+ /** The avatar palette (tokens.json `--avatar-*`): white initials clear 4.5:1 on each. */
17
+ const COLORS = Array.from({ length: 8 }, (_, i) => `var(--avatar-${i + 1})`)
17
18
 
18
19
  export function PresenceIndicator({ documentId, currentUserId }: PresenceIndicatorProps) {
19
20
  const [users, setUsers] = useState<PresenceUser[]>([])
@@ -16,7 +16,7 @@ export interface ReflowMeterProps {
16
16
 
17
17
  const DOT_TONE: Record<string, string> = {
18
18
  same: 'bg-success/12 text-success',
19
- grew: 'bg-warning/15 text-warning',
19
+ grew: 'bg-warn-l text-warning',
20
20
  'grew-badly': 'bg-destructive/12 text-destructive',
21
21
  }
22
22
 
@@ -104,7 +104,7 @@ export function ReflowMeter({ guard, length, device, onProof }: ReflowMeterProps
104
104
  </div>
105
105
 
106
106
  {worst && (
107
- <div className="bg-warning/10 border-warning/30 mt-1.5 grid grid-cols-[auto_1fr] gap-x-2.5 gap-y-1 rounded-lg border p-2.5">
107
+ <div className="bg-warn-l border-warning/30 mt-1.5 grid grid-cols-[auto_1fr] gap-x-2.5 gap-y-1 rounded-lg border p-2.5">
108
108
  <AlertTriangle size={14} className="text-warning mt-px shrink-0" aria-hidden />
109
109
  <p className="text-[11.5px] leading-normal">
110
110
  Wrapping changed on <b className="text-warning font-bold">{scope}</b> —{' '}
@@ -114,7 +114,7 @@ export function ReflowMeter({ guard, length, device, onProof }: ReflowMeterProps
114
114
  <button
115
115
  type="button"
116
116
  onClick={() => onProof(worst.id)}
117
- className="border-warning text-warning hover:bg-warning/15 col-start-2 mt-0.5 justify-self-start rounded-md border px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap transition-colors"
117
+ className="border-warning text-warning hover:bg-warn-l col-start-2 mt-0.5 justify-self-start rounded-md border px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap transition-colors"
118
118
  >
119
119
  Proof on {getBreakpoint(worst.id).name}
120
120
  </button>
@@ -400,7 +400,7 @@ function ScoreRing({ score }: { score: number }) {
400
400
  const radius = 28
401
401
  const circumference = 2 * Math.PI * radius
402
402
  const offset = circumference - (score / 100) * circumference
403
- const color = score >= 70 ? '#22c55e' : score >= 40 ? '#f59e0b' : '#ef4444'
403
+ const color = score >= 70 ? 'var(--suc)' : score >= 40 ? 'var(--warn)' : 'var(--err)'
404
404
 
405
405
  return (
406
406
  <div className="relative inline-flex items-center justify-center">
@@ -965,7 +965,7 @@ export function SEOPanel({
965
965
  onChange={(v) => update({ isCornerstone: v })}
966
966
  />
967
967
  {seoData.isCornerstone && (
968
- <div className="text-warning bg-warning/10 flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs">
968
+ <div className="text-warning bg-warn-l flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs">
969
969
  <Star className="h-3.5 w-3.5" />
970
970
  Cornerstone content is held to stricter SEO standards
971
971
  </div>
@@ -1,12 +1,22 @@
1
1
  'use client'
2
2
 
3
3
  import {
4
- accentTokensToCssVars,
4
+ accentPickCssVars,
5
5
  generateAdminThemeTokens,
6
+ validateAccentColor,
6
7
  type ColorMode,
8
+ type LightBase,
7
9
  type SidebarDensity,
8
10
  } from '@prenta/core/appearance'
9
- import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react'
11
+ import {
12
+ createContext,
13
+ useContext,
14
+ useState,
15
+ useEffect,
16
+ useCallback,
17
+ useRef,
18
+ type ReactNode,
19
+ } from 'react'
10
20
 
11
21
  import { getAdminRootElement } from '../lib/admin-root-element.js'
12
22
 
@@ -14,8 +24,10 @@ import { getAdminRootElement } from '../lib/admin-root-element.js'
14
24
  * Admin appearance engine.
15
25
  *
16
26
  * Owns the live, DOM-applied admin theme: color mode (light/dark/system),
17
- * accent color, sidebar density, content font, reduced motion, and the
18
- * resolved admin brand logos used by the sidebar. State is mirrored to
27
+ * light base (Porcelain/Linen), accent color, sidebar density, content font,
28
+ * reduced motion, and the resolved admin brand logos used by the sidebar.
29
+ * Together, color mode and light base are the October 2026 kit's three bases:
30
+ * Graphite is dark mode, and light mode paints Porcelain or Linen. State is mirrored to
19
31
  * localStorage so a reload paints instantly without a render-blocking fetch;
20
32
  * the Appearance tab pushes the DB-backed values in via `applyAppearance` on
21
33
  * load and save, making the database the source of truth and localStorage the
@@ -33,10 +45,17 @@ export interface AdminBrandCache {
33
45
  initials: string
34
46
  }
35
47
 
48
+ /** The kit's base names. Graphite whenever the admin resolves to dark. */
49
+ export type ThemeBase = LightBase | 'graphite'
50
+
36
51
  interface ThemeContextValue {
37
52
  theme: ColorMode
38
53
  resolvedTheme: 'light' | 'dark'
39
54
  setTheme: (theme: ColorMode) => void
55
+ lightBase: LightBase
56
+ setLightBase: (base: LightBase) => void
57
+ /** The base on screen right now. */
58
+ base: ThemeBase
40
59
  accent: string
41
60
  setAccent: (accent: string) => void
42
61
  density: SidebarDensity
@@ -53,6 +72,7 @@ interface ThemeContextValue {
53
72
 
54
73
  export interface AppearanceSnapshot {
55
74
  theme?: ColorMode
75
+ lightBase?: LightBase
56
76
  accent?: string
57
77
  density?: SidebarDensity
58
78
  font?: string
@@ -87,11 +107,14 @@ const ThemeContext = createContext<ThemeContextValue>({
87
107
  theme: 'system',
88
108
  resolvedTheme: 'light',
89
109
  setTheme: () => {},
90
- accent: 'purple',
110
+ lightBase: 'porcelain',
111
+ setLightBase: () => {},
112
+ base: 'porcelain',
113
+ accent: 'cobalt',
91
114
  setAccent: () => {},
92
115
  density: 'default',
93
116
  setDensity: () => {},
94
- font: 'System UI',
117
+ font: 'DM Sans',
95
118
  setFont: () => {},
96
119
  reduceMotion: false,
97
120
  setReduceMotion: () => {},
@@ -114,6 +137,7 @@ function resolveTheme(theme: ColorMode): 'light' | 'dark' {
114
137
  }
115
138
 
116
139
  const KEY_THEME = 'prenta-theme'
140
+ const KEY_LIGHT = 'prenta-light'
117
141
  const KEY_ACCENT = 'prenta-accent'
118
142
  const KEY_DENSITY = 'prenta-density'
119
143
  const KEY_FONT = 'prenta-font'
@@ -132,12 +156,22 @@ function applyColorMode(resolved: 'light' | 'dark') {
132
156
  el.setAttribute('data-theme', resolved)
133
157
  }
134
158
 
159
+ function readLightBase(): LightBase {
160
+ return localStorage.getItem(KEY_LIGHT) === 'linen' ? 'linen' : 'porcelain'
161
+ }
162
+
163
+ function applyLightBase(base: LightBase) {
164
+ const el = adminRootEl()
165
+ if (!el) return
166
+ // Linen's token block matches `[data-light='linen']` unless the root is dark.
167
+ el.setAttribute('data-light', base)
168
+ }
169
+
170
+ /** Writes --acc-base, --acc-lt and --acc-dk; the token CSS derives the rest per base. */
135
171
  function applyAccent(accent: string, resolved: 'light' | 'dark') {
136
172
  const el = adminRootEl()
137
173
  if (!el) return
138
- const vars = accentTokensToCssVars(
139
- generateAdminThemeTokens({ adminAccentColor: accent }, resolved),
140
- )
174
+ const vars = accentPickCssVars(generateAdminThemeTokens({ adminAccentColor: accent }, resolved))
141
175
  for (const [name, value] of Object.entries(vars)) el.style.setProperty(name, value)
142
176
  }
143
177
 
@@ -163,16 +197,46 @@ interface ThemeProviderProps {
163
197
  children: ReactNode
164
198
  /** When true, default to dark mode if the user hasn't explicitly chosen one. */
165
199
  defaultDarkMode?: boolean
200
+ /**
201
+ * Config-managed accent (`admin.branding.primaryColor`). While set, it wins
202
+ * over the cached and saved accent and is contrast-tuned like any pick.
203
+ */
204
+ accentOverride?: string
166
205
  }
167
206
 
168
- export function ThemeProvider({ children, defaultDarkMode }: ThemeProviderProps) {
207
+ /**
208
+ * A config accent must be a preset name or a color `tuneAccent` reads (hex,
209
+ * `rgb()`, `hsl()`, `oklch()`). Anything else is ignored, with a warning, and
210
+ * Settings keeps the accent editable (see useAppearanceSettings).
211
+ */
212
+ export function usableAccentOverride(value: unknown): string | undefined {
213
+ return typeof value === 'string' && validateAccentColor(value).valid ? value : undefined
214
+ }
215
+
216
+ export function ThemeProvider({ children, defaultDarkMode, accentOverride }: ThemeProviderProps) {
217
+ const override = usableAccentOverride(accentOverride)
218
+ useEffect(() => {
219
+ if (accentOverride && !override) {
220
+ console.warn(
221
+ `[Prenta CMS] admin.branding.primaryColor ${JSON.stringify(accentOverride)} isn't a color the admin can use (hex, rgb(), hsl() or oklch()). Using the saved accent instead.`,
222
+ )
223
+ }
224
+ }, [accentOverride, override])
169
225
  const [theme, setThemeState] = useState<ColorMode>('system')
170
226
  const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>('light')
171
- const [accent, setAccentState] = useState('purple')
227
+ const [lightBase, setLightBaseState] = useState<LightBase>('porcelain')
228
+ const [accent, setAccentState] = useState('cobalt')
172
229
  const [density, setDensityState] = useState<SidebarDensity>('default')
173
- const [font, setFontState] = useState('System UI')
230
+ const [font, setFontState] = useState('DM Sans')
174
231
  const [reduceMotion, setReduceMotionState] = useState(false)
175
232
  const [adminBrand, setAdminBrandState] = useState<AdminBrandCache>(DEFAULT_BRAND)
233
+ // The setters read these instead of closing over state, so every setter and
234
+ // `applyAppearance` keep one identity. Consumers load data in effects keyed
235
+ // on them; a new identity per change would refetch and undo the change.
236
+ const themeRef = useRef<ColorMode>('system')
237
+ const accentRef = useRef('cobalt')
238
+ const overrideRef = useRef(override)
239
+ overrideRef.current = override
176
240
 
177
241
  // Hydrate from localStorage on mount and apply everything to the DOM.
178
242
  useEffect(() => {
@@ -189,9 +253,10 @@ export function ThemeProvider({ children, defaultDarkMode }: ThemeProviderProps)
189
253
  }
190
254
  const resolved = resolveTheme(initialTheme)
191
255
 
192
- const storedAccent = localStorage.getItem(KEY_ACCENT) || 'purple'
256
+ const storedLightBase = readLightBase()
257
+ const storedAccent = localStorage.getItem(KEY_ACCENT) || 'cobalt'
193
258
  const storedDensity = (localStorage.getItem(KEY_DENSITY) as SidebarDensity | null) || 'default'
194
- const storedFont = localStorage.getItem(KEY_FONT) || 'System UI'
259
+ const storedFont = localStorage.getItem(KEY_FONT) || 'DM Sans'
195
260
  const storedMotion = localStorage.getItem(KEY_MOTION) === 'true'
196
261
  let storedBrand = DEFAULT_BRAND
197
262
  try {
@@ -201,8 +266,11 @@ export function ThemeProvider({ children, defaultDarkMode }: ThemeProviderProps)
201
266
  // Ignore malformed cache.
202
267
  }
203
268
 
269
+ themeRef.current = initialTheme
270
+ accentRef.current = storedAccent
204
271
  setThemeState(initialTheme)
205
272
  setResolvedTheme(resolved)
273
+ setLightBaseState(storedLightBase)
206
274
  setAccentState(storedAccent)
207
275
  setDensityState(storedDensity)
208
276
  setFontState(storedFont)
@@ -210,48 +278,56 @@ export function ThemeProvider({ children, defaultDarkMode }: ThemeProviderProps)
210
278
  setAdminBrandState(storedBrand)
211
279
 
212
280
  applyColorMode(resolved)
213
- applyAccent(storedAccent, resolved)
281
+ applyLightBase(storedLightBase)
282
+ applyAccent(overrideRef.current ?? storedAccent, resolved)
214
283
  applyDensity(storedDensity)
215
284
  applyFont(storedFont)
216
285
  applyReduceMotion(storedMotion)
217
286
  }, [defaultDarkMode])
218
287
 
219
- // Follow the OS color scheme while in `system` mode (re-applies accent too,
220
- // since presets differ between light and dark).
288
+ // A config accent arriving or changing after mount.
289
+ useEffect(() => {
290
+ applyAccent(override ?? accentRef.current, resolveTheme(themeRef.current))
291
+ }, [override])
292
+
293
+ // Follow the OS color scheme while in `system` mode.
221
294
  useEffect(() => {
222
295
  const mq = window.matchMedia('(prefers-color-scheme: dark)')
223
296
  const handler = () => {
224
- if (theme === 'system') {
297
+ if (themeRef.current === 'system') {
225
298
  const resolved = getSystemTheme()
226
299
  setResolvedTheme(resolved)
227
300
  applyColorMode(resolved)
228
- applyAccent(accent, resolved)
301
+ applyAccent(overrideRef.current ?? accentRef.current, resolved)
229
302
  }
230
303
  }
231
304
  mq.addEventListener('change', handler)
232
305
  return () => mq.removeEventListener('change', handler)
233
- }, [theme, accent])
234
-
235
- const setTheme = useCallback(
236
- (next: ColorMode) => {
237
- setThemeState(next)
238
- localStorage.setItem(KEY_THEME, next)
239
- const resolved = resolveTheme(next)
240
- setResolvedTheme(resolved)
241
- applyColorMode(resolved)
242
- applyAccent(accent, resolved)
243
- },
244
- [accent],
245
- )
306
+ }, [])
246
307
 
247
- const setAccent = useCallback(
248
- (next: string) => {
249
- setAccentState(next)
250
- localStorage.setItem(KEY_ACCENT, next)
251
- applyAccent(next, resolvedTheme)
252
- },
253
- [resolvedTheme],
254
- )
308
+ const setTheme = useCallback((next: ColorMode) => {
309
+ themeRef.current = next
310
+ setThemeState(next)
311
+ localStorage.setItem(KEY_THEME, next)
312
+ const resolved = resolveTheme(next)
313
+ setResolvedTheme(resolved)
314
+ applyColorMode(resolved)
315
+ applyAccent(overrideRef.current ?? accentRef.current, resolved)
316
+ }, [])
317
+
318
+ const setLightBase = useCallback((next: LightBase) => {
319
+ setLightBaseState(next)
320
+ localStorage.setItem(KEY_LIGHT, next)
321
+ applyLightBase(next)
322
+ }, [])
323
+
324
+ // The pick is still remembered; a config accent just keeps winning on screen.
325
+ const setAccent = useCallback((next: string) => {
326
+ accentRef.current = next
327
+ setAccentState(next)
328
+ localStorage.setItem(KEY_ACCENT, next)
329
+ applyAccent(overrideRef.current ?? next, resolveTheme(themeRef.current))
330
+ }, [])
255
331
 
256
332
  const setDensity = useCallback((next: SidebarDensity) => {
257
333
  setDensityState(next)
@@ -281,13 +357,14 @@ export function ThemeProvider({ children, defaultDarkMode }: ThemeProviderProps)
281
357
  const applyAppearance = useCallback(
282
358
  (snapshot: AppearanceSnapshot) => {
283
359
  if (snapshot.theme !== undefined) setTheme(snapshot.theme)
360
+ if (snapshot.lightBase !== undefined) setLightBase(snapshot.lightBase)
284
361
  if (snapshot.accent !== undefined) setAccent(snapshot.accent)
285
362
  if (snapshot.density !== undefined) setDensity(snapshot.density)
286
363
  if (snapshot.font !== undefined) setFont(snapshot.font)
287
364
  if (snapshot.reduceMotion !== undefined) setReduceMotion(snapshot.reduceMotion)
288
365
  if (snapshot.adminBrand !== undefined) setAdminBrand(snapshot.adminBrand)
289
366
  },
290
- [setTheme, setAccent, setDensity, setFont, setReduceMotion, setAdminBrand],
367
+ [setTheme, setLightBase, setAccent, setDensity, setFont, setReduceMotion, setAdminBrand],
291
368
  )
292
369
 
293
370
  return (
@@ -296,7 +373,10 @@ export function ThemeProvider({ children, defaultDarkMode }: ThemeProviderProps)
296
373
  theme,
297
374
  resolvedTheme,
298
375
  setTheme,
299
- accent,
376
+ lightBase,
377
+ setLightBase,
378
+ base: resolvedTheme === 'dark' ? 'graphite' : lightBase,
379
+ accent: override ?? accent,
300
380
  setAccent,
301
381
  density,
302
382
  setDensity,
@@ -175,11 +175,10 @@ const editorStyles = `
175
175
  margin: 1rem 0;
176
176
  color: var(--sub);
177
177
  }
178
- /* Code blocks use a fixed dark slate theme in both light and dark modes
179
- (standard "dark editor chrome" convention; no theme token maps to it). */
178
+ /* Code blocks use the kit's code surface, the same in every base. */
180
179
  .ProseMirror pre {
181
- background: #1e293b;
182
- color: #e2e8f0;
180
+ background: var(--code-bg);
181
+ color: var(--code-txt);
183
182
  padding: 1rem;
184
183
  border-radius: 0.5rem;
185
184
  overflow-x: auto;
@@ -85,7 +85,7 @@ export function EmbedPanel({
85
85
  return (
86
86
  <div className="space-y-5">
87
87
  {status !== 'active' && (
88
- <p className="border-warning/30 bg-warning/10 text-warning rounded-md border px-3 py-2 text-sm">
88
+ <p className="border-warning/30 bg-warn-l text-warning rounded-md border px-3 py-2 text-sm">
89
89
  This form is <span className="font-medium">{status}</span> and won&apos;t accept public
90
90
  submissions until it&apos;s set to Active.
91
91
  </p>
@@ -367,7 +367,13 @@ export function FormEntryDetailPane({
367
367
  function FieldValues({ entry, fields }: { entry: FormSubmission; fields: FormField[] }) {
368
368
  // Prefer the schema order; fall back to whatever keys exist on the data.
369
369
  const inputFields = fields.filter(
370
- (f) => f.type !== 'divider' && f.type !== 'richtext' && f.type !== 'honeypot',
370
+ (f) =>
371
+ f.type !== 'divider' &&
372
+ f.type !== 'richtext' &&
373
+ f.type !== 'honeypot' &&
374
+ f.type !== 'heading' &&
375
+ f.type !== 'content' &&
376
+ f.type !== 'pagebreak',
371
377
  )
372
378
  const rows: { key: string; label: string }[] = inputFields.length
373
379
  ? inputFields.map((f) => ({ key: f.key, label: f.label }))
@@ -40,7 +40,13 @@ async function copyText(value: string, label: string) {
40
40
 
41
41
  export function ShortcodeGlossary({ fields = [] }: { fields?: FormField[] }) {
42
42
  const fieldTokens = fields.filter(
43
- (f) => f.type !== 'honeypot' && f.type !== 'divider' && f.type !== 'richtext',
43
+ (f) =>
44
+ f.type !== 'honeypot' &&
45
+ f.type !== 'divider' &&
46
+ f.type !== 'richtext' &&
47
+ f.type !== 'heading' &&
48
+ f.type !== 'content' &&
49
+ f.type !== 'pagebreak',
44
50
  )
45
51
 
46
52
  const allTokens = [