@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
@@ -0,0 +1,90 @@
1
+ import type { ReactNode } from 'react'
2
+
3
+ export interface CountChipProps {
4
+ /** The count. A string for formatted values ("2.4 GB"). */
5
+ n: number | string
6
+ label: string
7
+ /** `ok` colours the number `--suc`; `bad` the chip `--err`; `muted` the number `--muted`. */
8
+ tone?: 'ok' | 'bad' | 'muted'
9
+ /** Leading 12px icon (Script Tags' "Consent-gated" shield). */
10
+ icon?: ReactNode
11
+ href?: string
12
+ onClick?: () => void
13
+ selected?: boolean
14
+ }
15
+
16
+ /**
17
+ * Page-header count chip (SHELL.md §4 "Count chip", `.stat-pill` in
18
+ * cms-layouts.css), one look on Forms, Inbox, Media and Script Tags.
19
+ * Renders a link or button when it navigates; otherwise a static span.
20
+ */
21
+ export function CountChip({ n, label, tone, icon, href, onClick, selected }: CountChipProps) {
22
+ const interactive = Boolean(href || onClick)
23
+ const className = [
24
+ // Explicit leading: the admin base layer styles `button` at 1.5 / 500.
25
+ 'inline-flex items-center gap-[5px] rounded-pill border px-2.5 py-[3px] text-sm2 leading-[1.5] font-[450] whitespace-nowrap no-underline',
26
+ // Forced colors flatten the selected fill and border, so a selected chip
27
+ // gets an outline there (as the current nav row does).
28
+ selected
29
+ ? 'border-acc bg-acc-l text-acc forced-colors:outline-2 forced-colors:outline-offset-1 forced-colors:outline-solid'
30
+ : tone === 'bad'
31
+ ? 'border-[color-mix(in_srgb,var(--err)_35%,var(--bdr))] bg-card text-err'
32
+ : 'border-bdr bg-card text-sub',
33
+ interactive ? 'cursor-pointer hover:border-acc-m hover:text-acc' : '',
34
+ ]
35
+ .filter(Boolean)
36
+ .join(' ')
37
+
38
+ const numberClass = `font-bold tabular-nums ${
39
+ tone === 'ok'
40
+ ? 'text-suc'
41
+ : tone === 'bad'
42
+ ? 'text-err'
43
+ : tone === 'muted'
44
+ ? 'text-faint'
45
+ : selected
46
+ ? 'text-acc'
47
+ : 'text-txt'
48
+ }`
49
+
50
+ const inner: ReactNode = (
51
+ <>
52
+ {icon ? (
53
+ <span aria-hidden="true" className="flex [&>svg]:h-3 [&>svg]:w-3">
54
+ {icon}
55
+ </span>
56
+ ) : null}
57
+ <b className={numberClass}>{n}</b>
58
+ {label}
59
+ </>
60
+ )
61
+
62
+ if (href) {
63
+ return (
64
+ <a
65
+ href={href}
66
+ className={className}
67
+ aria-current={selected ? 'true' : undefined}
68
+ onClick={
69
+ onClick
70
+ ? (event) => {
71
+ if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey) return
72
+ event.preventDefault()
73
+ onClick()
74
+ }
75
+ : undefined
76
+ }
77
+ >
78
+ {inner}
79
+ </a>
80
+ )
81
+ }
82
+ if (onClick) {
83
+ return (
84
+ <button type="button" onClick={onClick} className={className} aria-pressed={selected}>
85
+ {inner}
86
+ </button>
87
+ )
88
+ }
89
+ return <span className={className}>{inner}</span>
90
+ }
@@ -5,7 +5,8 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react'
5
5
  /**
6
6
  * Design-system filter pill (`.pill` / `.pill.act`): bordered card-surface
7
7
  * chip that fills with the accent color when active. Used for status / role /
8
- * category filter rows above list views.
8
+ * category filter rows above list views. Never wraps its label ("Body start"
9
+ * stays on one line; ScriptTags.html `.filter-pill { white-space: nowrap }`).
9
10
  */
10
11
  export interface FilterPillProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {
11
12
  active?: boolean
@@ -25,9 +26,10 @@ export function FilterPill({
25
26
  <button
26
27
  type="button"
27
28
  aria-pressed={active}
28
- className={`inline-flex items-center gap-1.5 rounded-[7px] border px-3 py-1.5 text-[12.5px] font-medium transition-colors duration-[var(--motion-fast)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none ${
29
+ className={`inline-flex items-center gap-1.5 rounded-[7px] border px-3 py-1.5 text-[12.5px] font-medium whitespace-nowrap transition-colors duration-[var(--motion-fast)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none ${
29
30
  active
30
- ? 'border-[var(--acc)] bg-[var(--acc)] text-white'
31
+ ? // Forced colors drop the fill: the active pill keeps an outline.
32
+ 'border-[var(--acc)] bg-[var(--acc)] text-white forced-colors:outline-2 forced-colors:outline-offset-1 forced-colors:outline-solid'
31
33
  : 'border-[var(--bdr)] bg-[var(--card)] text-[var(--sub)] hover:border-[var(--acc-m)] hover:text-[var(--acc)]'
32
34
  } ${className ?? ''}`}
33
35
  {...rest}
@@ -1,7 +1,8 @@
1
1
  'use client'
2
2
 
3
- import type { ReactNode } from 'react'
3
+ import { useRef, type ReactNode } from 'react'
4
4
  import { X } from 'lucide-react'
5
+ import { useSheetFocus } from '../../lib/sheet-focus.js'
5
6
 
6
7
  /**
7
8
  * Design-system inline split-pane pattern: a list that shrinks while a
@@ -53,21 +54,33 @@ export function InspectorPane({
53
54
  children,
54
55
  'aria-label': ariaLabel,
55
56
  }: InspectorPaneProps) {
57
+ const regionRef = useRef<HTMLDivElement>(null)
58
+
59
+ // Below 769px the open pane is a sheet over the content column (kit
60
+ // `.sp.open`; `[data-inspector-open]` in responsive.css hides the list and
61
+ // the page header around it), so the row that opened it is no longer on
62
+ // screen: focus moves into the pane, and back to that row when it closes.
63
+ useSheetFocus(open, regionRef)
64
+
56
65
  // Cap at the split row's width (100% of the flex container) so the pane
57
- // never overflows phones/tablets. Below the cap the pane fills the row
66
+ // never overflows tablets. Below the cap the pane fills the row
58
67
  // master–detail style: the list yields, and the close button returns to
59
68
  // it. On desktop the min() resolves to the design's fixed px width, so
60
- // nothing changes there.
69
+ // nothing changes there. Below 769px it is a sheet: the whole content
70
+ // column, no gutter, border or radius.
61
71
  return (
62
72
  <div
63
- className="shrink-0 overflow-hidden bg-[var(--bg)] motion-safe:transition-[width] motion-safe:duration-200"
73
+ data-inspector-open={open ? '' : undefined}
74
+ className="mobile:motion-safe:transition-none shrink-0 overflow-hidden bg-[var(--bg)] motion-safe:transition-[width] motion-safe:duration-200"
64
75
  style={{ width: open ? `min(${width}px, 100%)` : 0 }}
65
76
  aria-hidden={!open}
66
77
  >
67
78
  <div
79
+ ref={regionRef}
68
80
  role="region"
69
81
  aria-label={ariaLabel}
70
- className="my-3 mr-3 ml-4 flex h-[calc(100%-24px)] flex-col overflow-hidden rounded-[var(--r)] border border-[var(--bdr)] bg-[var(--sb)] shadow-[var(--shd2)]"
82
+ tabIndex={-1}
83
+ className="mobile:m-0 mobile:h-full mobile:w-full! mobile:rounded-none mobile:border-0 mobile:shadow-none my-3 mr-3 ml-4 flex h-[calc(100%-24px)] flex-col overflow-hidden rounded-[var(--r)] border border-[var(--bdr)] bg-[var(--sb)] shadow-[var(--shd2)]"
71
84
  style={{ width: `min(${width - 28}px, calc(100% - 28px))` }}
72
85
  >
73
86
  {open ? children : null}
@@ -92,9 +105,10 @@ export function InspectorPaneHeader({
92
105
  type="button"
93
106
  onClick={onClose}
94
107
  aria-label={closeLabel}
95
- className="flex h-7 w-7 shrink-0 items-center justify-center rounded-[6px] text-[var(--muted)] transition-colors duration-[var(--motion-fast)] hover:bg-[var(--bg)] hover:text-[var(--txt)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none"
108
+ // The only way out of the mobile sheet: 44px there, and on touch.
109
+ className="prenta-touch-target mobile:-my-2 mobile:-mr-2 mobile:h-11 mobile:w-11 flex h-7 w-7 shrink-0 items-center justify-center rounded-[6px] text-[var(--muted)] transition-colors duration-[var(--motion-fast)] hover:bg-[var(--bg)] hover:text-[var(--txt)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none"
96
110
  >
97
- <X size={16} />
111
+ <X size={16} aria-hidden />
98
112
  </button>
99
113
  </div>
100
114
  )
@@ -12,6 +12,16 @@ const MODAL_SIZE_CLASS = {
12
12
  xl: 'flex max-h-[min(92vh,880px)] max-w-5xl flex-col',
13
13
  } as const
14
14
 
15
+ /**
16
+ * Below 769px every size is a bottom sheet (cms-layouts.css `.modal`): full
17
+ * width, at most 92dvh (the visible height, so a mobile browser's toolbar
18
+ * doesn't push it off screen), 16px top corners, the body scrolling between a fixed
19
+ * title row and footer, clear of the home indicator. Footer buttons share the
20
+ * row at 44px.
21
+ */
22
+ const SHEET_CLASS =
23
+ 'mobile:top-auto mobile:bottom-0 mobile:left-0 mobile:flex mobile:max-h-[92dvh] mobile:w-full mobile:max-w-none mobile:translate-x-0 mobile:translate-y-0 mobile:flex-col mobile:rounded-t-[16px] mobile:rounded-b-none mobile:border-x-0 mobile:border-b-0 mobile:pb-[env(safe-area-inset-bottom,0px)]'
24
+
15
25
  type ModalSize = keyof typeof MODAL_SIZE_CLASS
16
26
 
17
27
  export interface ModalProps {
@@ -98,7 +108,7 @@ export function Modal({
98
108
  <Dialog.Overlay className="fixed inset-0 z-60 bg-black/50" />
99
109
  <Dialog.Content
100
110
  ref={contentRef}
101
- className={`bg-card text-card-foreground border-border fixed top-1/2 left-1/2 z-60 w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 rounded-lg border shadow-xl focus:outline-none ${MODAL_SIZE_CLASS[size]}`}
111
+ className={`bg-card text-card-foreground border-border fixed top-1/2 left-1/2 z-60 w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 rounded-lg border shadow-xl focus:outline-none ${MODAL_SIZE_CLASS[size]} ${SHEET_CLASS}`}
102
112
  onInteractOutside={(event) => {
103
113
  // Radix dispatches this custom event on the outside target, so
104
114
  // `event.currentTarget` is not the parent Dialog.Content.
@@ -126,28 +136,32 @@ export function Modal({
126
136
  : undefined
127
137
  }
128
138
  >
129
- <div className="border-border flex items-center justify-between border-b px-6 py-4">
139
+ <div className="border-border mobile:px-4 flex shrink-0 items-center justify-between border-b px-6 py-4">
130
140
  <Dialog.Title className="text-foreground text-lg font-medium">{title}</Dialog.Title>
131
141
  <Dialog.Close asChild>
132
142
  <button
133
143
  type="button"
134
144
  aria-label="Close dialog"
135
- className="text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:ring-ring rounded-md p-1 transition-colors focus-visible:ring-2 focus-visible:outline-none"
145
+ className="text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:ring-ring prenta-touch-target mobile:h-11 mobile:w-11 flex items-center justify-center rounded-md p-1 transition-colors focus-visible:ring-2 focus-visible:outline-none"
136
146
  >
137
147
  <X className="h-4 w-4" aria-hidden />
138
148
  </button>
139
149
  </Dialog.Close>
140
150
  </div>
141
151
  {description && (
142
- <Dialog.Description className="text-muted-foreground px-6 pt-4 text-sm">
152
+ <Dialog.Description className="text-muted-foreground mobile:px-4 shrink-0 px-6 pt-4 text-sm">
143
153
  {description}
144
154
  </Dialog.Description>
145
155
  )}
146
- <div className={scrollBody ? 'min-h-0 flex-1 overflow-y-auto px-6 py-4' : 'px-6 py-4'}>
156
+ <div
157
+ className={`${scrollBody ? 'min-h-0 flex-1 overflow-y-auto' : ''} mobile:min-h-0 mobile:flex-1 mobile:overflow-y-auto mobile:px-4 px-6 py-4`}
158
+ >
147
159
  {children}
148
160
  </div>
149
161
  {actions && (
150
- <div className="border-border flex justify-end gap-2 border-t px-6 py-4">{actions}</div>
162
+ <div className="border-border mobile:px-4 mobile:py-3 mobile:[&>*]:min-h-11 mobile:[&>*]:flex-[1_1_0] flex shrink-0 justify-end gap-2 border-t px-6 py-4">
163
+ {actions}
164
+ </div>
151
165
  )}
152
166
  </Dialog.Content>
153
167
  </Dialog.Portal>
@@ -0,0 +1,63 @@
1
+ import type { ReactNode } from 'react'
2
+
3
+ export interface PageHeaderProps {
4
+ /** Page title. It equals the screen's sidebar label. */
5
+ title: string
6
+ subtitle?: ReactNode
7
+ /** Right-aligned header actions (buttons, AI button, live toggle). */
8
+ actions?: ReactNode
9
+ /** A `<Breadcrumb>`, on second-level screens only. */
10
+ breadcrumb?: ReactNode
11
+ /**
12
+ * Drop the page gutter padding, for screens whose wrapper already pads the
13
+ * content (the kit's Jobs and Appearance layouts, `padding: 22px 28px`).
14
+ */
15
+ flush?: boolean
16
+ }
17
+
18
+ /**
19
+ * Page title row (SHELL.md §4): padding 14px var(--gut) 0; title 21 / 700 /
20
+ * -0.5px; subtitle 13px --sub, max 640px; actions right-aligned, gap 8.
21
+ *
22
+ * Tiers (cms-layouts.css): the title is 19px at tablet, 18px on mobile and
23
+ * 26px at 4K; the subtitle 12.5px on mobile, 14.5px at 4K, and a plain-text
24
+ * subtitle hides below 461px. On mobile the actions wrap under the title
25
+ * (row gap 10px). The actions cluster is `data-header-actions`, so its
26
+ * buttons collapse to icons at tablet and mobile and its `data-fab` action
27
+ * floats on mobile (responsive.css).
28
+ */
29
+ export function PageHeader({
30
+ title,
31
+ subtitle,
32
+ actions,
33
+ breadcrumb,
34
+ flush = false,
35
+ }: PageHeaderProps) {
36
+ return (
37
+ <header
38
+ className={`mobile:gap-y-2.5 flex flex-wrap items-start gap-4 ${flush ? '' : 'px-[var(--gut)] pt-3.5'}`}
39
+ >
40
+ <div className="min-w-0 flex-[1_1_360px]">
41
+ {breadcrumb ? <div className="mb-1">{breadcrumb}</div> : null}
42
+ <h1 className="text-page text-txt tablet:text-[19px] mobile:text-[18px] 4k:text-[26px] m-0 leading-[normal]">
43
+ {title}
44
+ </h1>
45
+ {typeof subtitle === 'string' ? (
46
+ <p className="text-body text-sub mobile:text-[12.5px] 4k:text-[14.5px] m-0 mt-[3px] max-w-[640px] leading-[normal] text-pretty [@media(width<461px)]:hidden">
47
+ {subtitle}
48
+ </p>
49
+ ) : subtitle ? (
50
+ // Rich subtitles (status pills, presence) may hold block elements.
51
+ <div className="text-body text-sub mobile:text-[12.5px] 4k:text-[14.5px] mt-[3px] flex flex-wrap items-center gap-3 leading-[normal]">
52
+ {subtitle}
53
+ </div>
54
+ ) : null}
55
+ </div>
56
+ {actions ? (
57
+ <div data-header-actions="" className="ml-auto flex flex-wrap items-center gap-2">
58
+ {actions}
59
+ </div>
60
+ ) : null}
61
+ </header>
62
+ )
63
+ }
@@ -6,11 +6,16 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react'
6
6
  * Design-system table row actions (`.row-actions` / `.ra-icon-btn`): a
7
7
  * right-aligned cluster of 27px bordered icon buttons that fades in on row
8
8
  * hover (the row must have the `group` class) and on keyboard focus.
9
+ *
10
+ * At 1024px and below, and on screens that can't hover, the actions are
11
+ * always shown (cms-layouts.css): there is no hover to reveal them. On a
12
+ * mobile card they line up at the start of its actions row, 44px each
13
+ * (responsive.css); on touch screens they are 44px everywhere.
9
14
  */
10
15
  export function RowActions({ children, className }: { children: ReactNode; className?: string }) {
11
16
  return (
12
17
  <div
13
- className={`flex items-center justify-end gap-1 opacity-0 transition-opacity duration-[var(--motion-fast)] group-hover:opacity-100 focus-within:opacity-100 ${className ?? ''}`}
18
+ className={`narrow:opacity-100 mobile:justify-start flex items-center justify-end gap-1 opacity-0 transition-opacity duration-[var(--motion-fast)] group-hover:opacity-100 focus-within:opacity-100 [@media(hover:none)]:opacity-100 ${className ?? ''}`}
14
19
  >
15
20
  {children}
16
21
  </div>
@@ -37,7 +42,7 @@ export function RowActionButton({
37
42
  return (
38
43
  <button
39
44
  type="button"
40
- className={`flex h-[27px] w-[27px] items-center justify-center rounded-[6px] border border-[var(--bdr)] bg-[var(--card)] text-[var(--muted)] transition-colors duration-[var(--motion-fast)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 ${
45
+ className={`prenta-touch-target flex h-[27px] w-[27px] items-center justify-center rounded-[6px] border border-[var(--bdr)] bg-[var(--card)] text-[var(--muted)] transition-colors duration-[var(--motion-fast)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 ${
41
46
  danger
42
47
  ? 'hover:border-[var(--err)] hover:bg-[var(--err-l)] hover:text-[var(--err)]'
43
48
  : 'hover:border-[var(--acc-m)] hover:bg-[var(--acc-l)] hover:text-[var(--acc)]'
@@ -0,0 +1,97 @@
1
+ 'use client'
2
+
3
+ import { useRef, type KeyboardEvent } from 'react'
4
+
5
+ export interface SegmentedOption {
6
+ id: string
7
+ label: string
8
+ count?: number
9
+ }
10
+
11
+ export interface SegmentedProps {
12
+ options: SegmentedOption[]
13
+ value: string
14
+ onChange: (id: string) => void
15
+ /** Accessible name for the control. */
16
+ label: string
17
+ /** Optional counts by option id; an option's own `count` wins. */
18
+ counts?: Record<string, number | undefined>
19
+ className?: string
20
+ }
21
+
22
+ /**
23
+ * Segmented control (SHELL.md §6, `.jb-seg`). The active segment is a raised
24
+ * card, not a filled accent. Arrow keys, Home and End move between segments.
25
+ */
26
+ export function Segmented({
27
+ options,
28
+ value,
29
+ onChange,
30
+ label,
31
+ counts,
32
+ className = '',
33
+ }: SegmentedProps) {
34
+ const refs = useRef<Array<HTMLButtonElement | null>>([])
35
+ // Roving tab stop only: with no matching value no option is selected, but
36
+ // the first one still takes focus.
37
+ const selectedIndex = Math.max(
38
+ 0,
39
+ options.findIndex((option) => option.id === value),
40
+ )
41
+
42
+ function onKeyDown(event: KeyboardEvent<HTMLDivElement>) {
43
+ const last = options.length - 1
44
+ let next: number
45
+ if (event.key === 'ArrowRight' || event.key === 'ArrowDown')
46
+ next = selectedIndex === last ? 0 : selectedIndex + 1
47
+ else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp')
48
+ next = selectedIndex === 0 ? last : selectedIndex - 1
49
+ else if (event.key === 'Home') next = 0
50
+ else if (event.key === 'End') next = last
51
+ else return
52
+ event.preventDefault()
53
+ const option = options[next]
54
+ if (!option) return
55
+ onChange(option.id)
56
+ refs.current[next]?.focus()
57
+ }
58
+
59
+ return (
60
+ <div
61
+ role="tablist"
62
+ aria-label={label}
63
+ onKeyDown={onKeyDown}
64
+ className={`rounded-9 border-bdr bg-bg inline-flex w-fit max-w-full gap-0.5 overflow-x-auto border p-0.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden ${className}`}
65
+ >
66
+ {options.map((option, index) => {
67
+ const selected = option.id === value
68
+ const count = option.count ?? counts?.[option.id]
69
+ return (
70
+ <button
71
+ key={option.id}
72
+ ref={(el) => {
73
+ refs.current[index] = el
74
+ }}
75
+ type="button"
76
+ role="tab"
77
+ aria-selected={selected}
78
+ tabIndex={index === selectedIndex ? 0 : -1}
79
+ onClick={() => onChange(option.id)}
80
+ className={`rounded-7 text-sm2 flex cursor-pointer items-center gap-1.5 border-0 px-[11px] py-[5px] leading-[normal] font-semibold whitespace-nowrap ${
81
+ selected ? 'bg-card text-txt shadow-shd' : 'text-sub hover:text-txt bg-transparent'
82
+ }`}
83
+ >
84
+ {option.label}
85
+ {typeof count === 'number' ? (
86
+ <b
87
+ className={`text-micro font-bold tabular-nums ${selected ? 'text-acc' : 'text-faint'}`}
88
+ >
89
+ {count}
90
+ </b>
91
+ ) : null}
92
+ </button>
93
+ )
94
+ })}
95
+ </div>
96
+ )
97
+ }
@@ -0,0 +1,139 @@
1
+ 'use client'
2
+
3
+ import { isValidElement, useEffect } from 'react'
4
+ import { Toaster as SonnerToaster, toast } from 'sonner'
5
+
6
+ /** Kit toast lifetime (SHELL.md §7: auto-hides after 2–2.6s). */
7
+ const TOAST_DURATION_MS = 2400
8
+ /**
9
+ * Errors and warnings (the kit shows none) often carry a server message;
10
+ * 2.4s is too short to read one.
11
+ */
12
+ const ALERT_TOAST_DURATION_MS = 6000
13
+
14
+ type ToastFn = typeof toast.error
15
+ type PromiseFn = typeof toast.promise
16
+ type PromiseData = NonNullable<Parameters<PromiseFn>[1]>
17
+
18
+ /**
19
+ * `toast.promise`'s `error` option, resolved to settings with the longer
20
+ * lifetime. A `duration` the caller set, on the error result or for the whole
21
+ * promise toast, still wins.
22
+ */
23
+ function longerError(
24
+ error: PromiseData['error'],
25
+ callerDuration: number | undefined,
26
+ ): PromiseData['error'] {
27
+ const duration = callerDuration ?? ALERT_TOAST_DURATION_MS
28
+ const withDuration = (result: unknown) =>
29
+ typeof result === 'object' && result !== null && !isValidElement(result)
30
+ ? { duration, ...result }
31
+ : { message: result, duration }
32
+ if (error === undefined) return undefined
33
+ return (async (reason: unknown) =>
34
+ withDuration(
35
+ typeof error === 'function' ? await (error as (reason: unknown) => unknown)(reason) : error,
36
+ )) as PromiseData['error']
37
+ }
38
+
39
+ let installs = 0
40
+ let installed: {
41
+ originals: { error: ToastFn; warning: ToastFn; promise: PromiseFn }
42
+ wrappers: { error: ToastFn; warning: ToastFn; promise: PromiseFn }
43
+ } | null = null
44
+
45
+ /**
46
+ * Sonner has no per-type default duration, so while an admin toaster is
47
+ * mounted, `toast.error`, `toast.warning` and the error state of
48
+ * `toast.promise` default to the longer lifetime. A duration passed by the
49
+ * caller still wins. Installed once however many toasters mount, and on the
50
+ * last unmount each function is restored only if ours is still in place.
51
+ */
52
+ function useAlertDurations() {
53
+ useEffect(() => {
54
+ if (installs++ === 0) {
55
+ const originals = { error: toast.error, warning: toast.warning, promise: toast.promise }
56
+ const longer =
57
+ (fn: ToastFn): ToastFn =>
58
+ (message, data) =>
59
+ fn(message, { duration: ALERT_TOAST_DURATION_MS, ...data })
60
+ const promise = ((p, data) =>
61
+ originals.promise(
62
+ p,
63
+ data && { ...data, error: longerError(data.error, data.duration) },
64
+ )) as PromiseFn
65
+ const wrappers = {
66
+ error: longer(originals.error),
67
+ warning: longer(originals.warning),
68
+ promise,
69
+ }
70
+ Object.assign(toast, wrappers)
71
+ installed = { originals, wrappers }
72
+ }
73
+ return () => {
74
+ if (--installs > 0 || !installed) return
75
+ const { originals, wrappers } = installed
76
+ for (const key of ['error', 'warning', 'promise'] as const) {
77
+ if (toast[key] === wrappers[key]) Object.assign(toast, { [key]: originals[key] })
78
+ }
79
+ installed = null
80
+ }
81
+ }, [])
82
+ }
83
+
84
+ // Above the mobile tab bar and the home indicator. sonner switches to
85
+ // `mobileOffset` at 600px and below, where its own gap is 16px and a toast
86
+ // is as wide as the screen, so it also clears a floating action button
87
+ // (`--fab-clear`, set in responsive.css while a page has one). Wider than
88
+ // that, a centred 356px toast doesn't reach the FAB's corner.
89
+ const ABOVE_TAB_BAR = 'var(--tabbar-h) + env(safe-area-inset-bottom)'
90
+
91
+ /**
92
+ * The admin's toast host: sonner, unstyled, painted as the kit toast
93
+ * (SHELL.md §7, `.jb-toast`): fixed 24px above the bottom, centred, --txt
94
+ * background with --bg text, padding 10px 16px, radius 9, 13px / 500.
95
+ * Call sites keep using `toast()` from `sonner`.
96
+ *
97
+ * `aboveTabBar`: lift the toasts clear of the mobile tab bar.
98
+ */
99
+ export function Toaster({ aboveTabBar = false }: { aboveTabBar?: boolean } = {}) {
100
+ useAlertDurations()
101
+ return (
102
+ <SonnerToaster
103
+ position="bottom-center"
104
+ offset={aboveTabBar ? { bottom: `calc(${ABOVE_TAB_BAR} + 24px)` } : 24}
105
+ mobileOffset={
106
+ aboveTabBar
107
+ ? { bottom: `calc(${ABOVE_TAB_BAR} + 16px + var(--fab-clear, 0px))` }
108
+ : undefined
109
+ }
110
+ duration={TOAST_DURATION_MS}
111
+ // Inline, because sonner's injected stylesheet is unlayered and would beat
112
+ // utilities: the admin font (it sets a system stack) and the kit toast layer.
113
+ style={{ fontFamily: 'inherit', zIndex: 'var(--z-toast)' }}
114
+ toastOptions={{
115
+ unstyled: true,
116
+ classNames: {
117
+ // `prenta-inverse`: focus rings on the dark toast use --bg. Toasts
118
+ // stacked behind the front one hide their content, as sonner's own
119
+ // styles do for styled toasts.
120
+ toast:
121
+ 'prenta-inverse right-0 left-0 mx-auto flex w-fit max-w-[calc(100vw-32px)] items-center gap-2 rounded-9 bg-txt px-4 py-2.5 text-body leading-[normal] font-medium text-bg shadow-shd2 [&[data-expanded=false][data-front=false]>*]:opacity-0',
122
+ content: 'flex min-w-0 flex-col gap-0.5',
123
+ description: 'text-meta opacity-80',
124
+ // Unstyled sonner drops the icon slot's box; loading spinners need it.
125
+ icon: 'relative flex size-4 shrink-0 items-center justify-center text-bg',
126
+ // The kit toast is text only. Success and info drop sonner's icon;
127
+ // error and warning (which the kit doesn't show) keep theirs.
128
+ success: '[&_[data-icon]]:hidden!',
129
+ info: '[&_[data-icon]]:hidden!',
130
+ actionButton:
131
+ 'ml-1 inline-flex h-7 shrink-0 cursor-pointer items-center rounded-7 border-0 bg-acc px-2.5 text-meta font-semibold text-acc-on hover:brightness-[1.07]',
132
+ cancelButton:
133
+ 'inline-flex h-7 shrink-0 cursor-pointer items-center rounded-7 border-0 bg-transparent px-2.5 text-meta font-semibold text-bg opacity-85 hover:opacity-100 focus-visible:opacity-100',
134
+ closeButton: 'text-bg',
135
+ },
136
+ }}
137
+ />
138
+ )
139
+ }
@@ -1,21 +1,23 @@
1
1
  'use client'
2
2
 
3
- import * as Switch from '@radix-ui/react-switch'
3
+ import * as SwitchPrimitive from '@radix-ui/react-switch'
4
4
  import { cv, type VariantProps } from '../../lib/cv.js'
5
5
 
6
+ // Kit switch (SHELL.md §7, `.ap-sw`): 34×19 track, 15px knob at left 2px
7
+ // (17px when on), .15s. Radix renders role="switch" with aria-checked.
6
8
  const toggleTrack = cv(
7
- 'relative inline-block shrink-0 cursor-pointer rounded-[var(--r-pill)] border-0 p-0 transition-colors duration-[var(--motion-base)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
9
+ // `prenta-touch-hit` grows the hit area to 44px on touch without stretching the track.
10
+ 'prenta-touch-hit rounded-pill relative inline-block shrink-0 cursor-pointer border-0 p-0 transition-[background-color] duration-[var(--mo-base)] disabled:cursor-not-allowed disabled:opacity-50',
8
11
  {
9
12
  variants: {
10
13
  variant: {
11
14
  /** Design system default — accent when on. */
12
- accent: 'bg-[var(--bdr)] data-[state=checked]:bg-[var(--acc)]',
15
+ accent: 'bg-bdr data-[state=checked]:bg-acc',
13
16
  /** Semantic enable/disable — success green when on (tables, script tags). */
14
- enabled: 'bg-[var(--bdr)] data-[state=checked]:bg-[var(--suc)]',
17
+ enabled: 'bg-bdr data-[state=checked]:bg-suc',
15
18
  },
16
19
  size: {
17
- /** Matches `.tog-track` in the design system handoff (38×21). */
18
- md: 'h-[21px] w-[38px]',
20
+ md: 'h-[19px] w-[34px]',
19
21
  },
20
22
  },
21
23
  defaultVariants: {
@@ -26,12 +28,11 @@ const toggleTrack = cv(
26
28
  )
27
29
 
28
30
  const toggleThumb = cv(
29
- 'pointer-events-none absolute top-[2.5px] left-[2.5px] block rounded-full bg-[var(--toggle-thumb)] shadow-[0_1px_3px_rgba(0,0,0,0.2)] transition-[left] duration-[var(--motion-base)] data-[state=checked]:left-[19.5px]',
31
+ 'shadow-knob pointer-events-none absolute top-0.5 left-0.5 block rounded-full bg-[var(--toggle-thumb)] transition-[left] duration-[var(--mo-base)]',
30
32
  {
31
33
  variants: {
32
34
  size: {
33
- /** Matches `.tog-thumb` in the design system handoff (16×16). */
34
- md: 'h-4 w-4',
35
+ md: 'h-[15px] w-[15px] data-[state=checked]:left-[17px]',
35
36
  },
36
37
  },
37
38
  defaultVariants: {
@@ -53,8 +54,8 @@ export interface ToggleProps extends ToggleVariants {
53
54
  }
54
55
 
55
56
  /**
56
- * Design-system toggle (`.tog-track` / `.tog-thumb`). Use `variant="enabled"`
57
- * for on/off tables where green communicates active state.
57
+ * Design-system switch (`role="switch"`). Use `variant="enabled"` for on/off
58
+ * tables where green communicates active state. Also exported as `Switch`.
58
59
  */
59
60
  export function Toggle({
60
61
  checked,
@@ -68,7 +69,7 @@ export function Toggle({
68
69
  'aria-describedby': ariaDescribedBy,
69
70
  }: ToggleProps) {
70
71
  return (
71
- <Switch.Root
72
+ <SwitchPrimitive.Root
72
73
  id={id}
73
74
  checked={checked}
74
75
  onCheckedChange={onCheckedChange}
@@ -78,7 +79,10 @@ export function Toggle({
78
79
  aria-describedby={ariaDescribedBy}
79
80
  className={toggleTrack({ variant, size })}
80
81
  >
81
- <Switch.Thumb className={toggleThumb({ size })} />
82
- </Switch.Root>
82
+ <SwitchPrimitive.Thumb className={toggleThumb({ size })} />
83
+ </SwitchPrimitive.Root>
83
84
  )
84
85
  }
86
+
87
+ /** The kit's name for {@link Toggle}. */
88
+ export { Toggle as Switch }